ccxt 4.1.24 → 4.1.26

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (54) hide show
  1. package/README.md +3 -3
  2. package/dist/ccxt.browser.js +1368 -201
  3. package/dist/ccxt.browser.min.js +4 -4
  4. package/dist/cjs/ccxt.js +1 -1
  5. package/dist/cjs/src/ace.js +1 -1
  6. package/dist/cjs/src/base/Exchange.js +7 -3
  7. package/dist/cjs/src/base/functions/crypto.js +11 -2
  8. package/dist/cjs/src/base/functions/generic.js +5 -3
  9. package/dist/cjs/src/base/functions.js +1 -0
  10. package/dist/cjs/src/binance.js +108 -5
  11. package/dist/cjs/src/bitget.js +485 -22
  12. package/dist/cjs/src/bybit.js +132 -15
  13. package/dist/cjs/src/cryptocom.js +262 -15
  14. package/dist/cjs/src/gate.js +191 -88
  15. package/dist/cjs/src/krakenfutures.js +86 -20
  16. package/dist/cjs/src/oceanex.js +0 -12
  17. package/dist/cjs/src/okx.js +60 -1
  18. package/dist/cjs/src/pro/bybit.js +1 -1
  19. package/dist/cjs/src/static_dependencies/noble-curves/abstract/edwards.js +8 -6
  20. package/dist/cjs/src/wavesexchange.js +6 -6
  21. package/js/ccxt.d.ts +1 -1
  22. package/js/ccxt.js +1 -1
  23. package/js/src/abstract/gate.d.ts +2 -7
  24. package/js/src/abstract/gateio.d.ts +2 -7
  25. package/js/src/ace.js +1 -1
  26. package/js/src/base/Exchange.d.ts +4 -2
  27. package/js/src/base/Exchange.js +7 -3
  28. package/js/src/base/functions/crypto.d.ts +3 -2
  29. package/js/src/base/functions/crypto.js +11 -3
  30. package/js/src/base/functions/generic.d.ts +1 -1
  31. package/js/src/base/functions/generic.js +5 -3
  32. package/js/src/base/types.d.ts +8 -0
  33. package/js/src/binance.d.ts +2 -1
  34. package/js/src/binance.js +108 -5
  35. package/js/src/bitget.d.ts +31 -1
  36. package/js/src/bitget.js +485 -22
  37. package/js/src/bybit.d.ts +4 -2
  38. package/js/src/bybit.js +132 -15
  39. package/js/src/cryptocom.d.ts +4 -1
  40. package/js/src/cryptocom.js +262 -15
  41. package/js/src/gate.d.ts +3 -1
  42. package/js/src/gate.js +191 -88
  43. package/js/src/krakenfutures.d.ts +3 -1
  44. package/js/src/krakenfutures.js +86 -20
  45. package/js/src/oceanex.d.ts +0 -1
  46. package/js/src/oceanex.js +0 -12
  47. package/js/src/okx.d.ts +2 -1
  48. package/js/src/okx.js +60 -1
  49. package/js/src/pro/bybit.js +1 -1
  50. package/js/src/static_dependencies/noble-curves/abstract/edwards.d.ts +1 -0
  51. package/js/src/static_dependencies/noble-curves/abstract/edwards.js +5 -3
  52. package/js/src/wavesexchange.js +7 -7
  53. package/package.json +1 -1
  54. package/skip-tests.json +2 -3
@@ -35,11 +35,12 @@ class bitget extends bitget$1 {
35
35
  'cancelOrder': true,
36
36
  'cancelOrders': true,
37
37
  'createOrder': true,
38
+ 'createOrders': true,
38
39
  'createReduceOnlyOrder': false,
39
40
  'editOrder': true,
40
41
  'fetchAccounts': false,
41
42
  'fetchBalance': true,
42
- 'fetchBorrowRate': false,
43
+ 'fetchBorrowRate': true,
43
44
  'fetchBorrowRateHistories': false,
44
45
  'fetchBorrowRateHistory': false,
45
46
  'fetchBorrowRates': false,
@@ -60,10 +61,12 @@ class bitget extends bitget$1 {
60
61
  'fetchLedger': true,
61
62
  'fetchLeverage': true,
62
63
  'fetchLeverageTiers': false,
64
+ 'fetchLiquidations': false,
63
65
  'fetchMarginMode': undefined,
64
66
  'fetchMarketLeverageTiers': true,
65
67
  'fetchMarkets': true,
66
68
  'fetchMarkOHLCV': true,
69
+ 'fetchMyLiquidations': true,
67
70
  'fetchMyTrades': true,
68
71
  'fetchOHLCV': true,
69
72
  'fetchOpenInterest': true,
@@ -2981,7 +2984,23 @@ class bitget extends bitget$1 {
2981
2984
  // "fillTotalAmount": "0",
2982
2985
  // "ctime": "1697773902588"
2983
2986
  // }
2987
+ // cancelOrders failing
2984
2988
  //
2989
+ // {
2990
+ // "orderId": "1627293504611",
2991
+ // "clientOid": "BITGET#1627293504611",
2992
+ // "errorMsg":"Duplicate clientOid"
2993
+ // }
2994
+ //
2995
+ const errorMessage = this.safeString(order, 'errorMsg');
2996
+ if (errorMessage !== undefined) {
2997
+ return this.safeOrder({
2998
+ 'info': order,
2999
+ 'id': this.safeString(order, 'orderId'),
3000
+ 'clientOrderId': this.safeString(order, 'clientOrderId'),
3001
+ 'status': 'rejected',
3002
+ }, market);
3003
+ }
2985
3004
  const marketId = this.safeString(order, 'symbol');
2986
3005
  market = this.safeMarket(marketId, market);
2987
3006
  const timestamp = this.safeInteger2(order, 'cTime', 'ctime');
@@ -3072,9 +3091,60 @@ class bitget extends bitget$1 {
3072
3091
  */
3073
3092
  await this.loadMarkets();
3074
3093
  const market = this.market(symbol);
3075
- let marketType = undefined;
3076
3094
  let marginMode = undefined;
3095
+ [marginMode, params] = this.handleMarginModeAndParams('createOrder', params);
3096
+ const triggerPrice = this.safeValue2(params, 'stopPrice', 'triggerPrice');
3097
+ const stopLossTriggerPrice = this.safeValue(params, 'stopLossPrice');
3098
+ const takeProfitTriggerPrice = this.safeValue(params, 'takeProfitPrice');
3099
+ const isTriggerOrder = triggerPrice !== undefined;
3100
+ const isStopLossTriggerOrder = stopLossTriggerPrice !== undefined;
3101
+ const isTakeProfitTriggerOrder = takeProfitTriggerPrice !== undefined;
3102
+ const isStopLossOrTakeProfitTrigger = isStopLossTriggerOrder || isTakeProfitTriggerOrder;
3103
+ const request = this.createOrderRequest(symbol, type, side, amount, price, params);
3077
3104
  let response = undefined;
3105
+ if (market['spot']) {
3106
+ if (isTriggerOrder) {
3107
+ response = await this.privateSpotPostPlanPlacePlan(request);
3108
+ }
3109
+ else if (marginMode === 'isolated') {
3110
+ response = await this.privateMarginPostIsolatedOrderPlaceOrder(request);
3111
+ }
3112
+ else if (marginMode === 'cross') {
3113
+ response = await this.privateMarginPostCrossOrderPlaceOrder(request);
3114
+ }
3115
+ else {
3116
+ response = await this.privateSpotPostTradeOrders(request);
3117
+ }
3118
+ }
3119
+ else {
3120
+ if (isTriggerOrder) {
3121
+ response = await this.privateMixPostPlanPlacePlan(request);
3122
+ }
3123
+ else if (isStopLossOrTakeProfitTrigger) {
3124
+ response = await this.privateMixPostPlanPlacePositionsTPSL(request);
3125
+ }
3126
+ else {
3127
+ response = await this.privateMixPostOrderPlaceOrder(request);
3128
+ }
3129
+ }
3130
+ //
3131
+ // {
3132
+ // "code": "00000",
3133
+ // "msg": "success",
3134
+ // "requestTime": 1645932209602,
3135
+ // "data": {
3136
+ // "orderId": "881669078313766912",
3137
+ // "clientOrderId": "iauIBf#a45b595f96474d888d0ada"
3138
+ // }
3139
+ // }
3140
+ //
3141
+ const data = this.safeValue(response, 'data', {});
3142
+ return this.parseOrder(data, market);
3143
+ }
3144
+ createOrderRequest(symbol, type, side, amount, price = undefined, params = {}) {
3145
+ const market = this.market(symbol);
3146
+ let marketType = undefined;
3147
+ let marginMode = undefined;
3078
3148
  [marketType, params] = this.handleMarketTypeAndParams('createOrder', market, params);
3079
3149
  [marginMode, params] = this.handleMarginModeAndParams('createOrder', params);
3080
3150
  const marketId = market['id'];
@@ -3172,7 +3242,6 @@ class bitget extends bitget$1 {
3172
3242
  if (price !== undefined) {
3173
3243
  request['executePrice'] = this.priceToPrecision(symbol, price);
3174
3244
  }
3175
- response = await this.privateMixPostPlanPlacePlan(this.extend(request, params));
3176
3245
  }
3177
3246
  else if (isStopLossOrTakeProfitTrigger) {
3178
3247
  if (isStopLossTriggerOrder) {
@@ -3183,7 +3252,6 @@ class bitget extends bitget$1 {
3183
3252
  request['triggerPrice'] = this.priceToPrecision(symbol, takeProfitTriggerPrice);
3184
3253
  request['planType'] = 'pos_profit';
3185
3254
  }
3186
- response = await this.privateMixPostPlanPlacePositionsTPSL(this.extend(request, params));
3187
3255
  }
3188
3256
  else {
3189
3257
  if (isStopLoss) {
@@ -3194,7 +3262,6 @@ class bitget extends bitget$1 {
3194
3262
  const tpTriggerPrice = this.safeValue2(takeProfit, 'triggerPrice', 'stopPrice');
3195
3263
  request['presetTakeProfitPrice'] = this.priceToPrecision(symbol, tpTriggerPrice);
3196
3264
  }
3197
- response = await this.privateMixPostOrderPlaceOrder(this.extend(request, params));
3198
3265
  }
3199
3266
  }
3200
3267
  else if (marketType === 'spot') {
@@ -3230,7 +3297,6 @@ class bitget extends bitget$1 {
3230
3297
  if (clientOrderId !== undefined) {
3231
3298
  request['clientOrderId'] = clientOrderId;
3232
3299
  }
3233
- response = await this.privateSpotPostPlanPlacePlan(this.extend(request, params));
3234
3300
  }
3235
3301
  else if (marginMode !== undefined) {
3236
3302
  request['loanType'] = 'normal';
@@ -3243,12 +3309,6 @@ class bitget extends bitget$1 {
3243
3309
  else {
3244
3310
  request['baseQuantity'] = quantity;
3245
3311
  }
3246
- if (marginMode === 'isolated') {
3247
- response = await this.privateMarginPostIsolatedOrderPlaceOrder(this.extend(request, params));
3248
- }
3249
- else if (marginMode === 'cross') {
3250
- response = await this.privateMarginPostCrossOrderPlaceOrder(this.extend(request, params));
3251
- }
3252
3312
  }
3253
3313
  else {
3254
3314
  if (clientOrderId !== undefined) {
@@ -3257,25 +3317,86 @@ class bitget extends bitget$1 {
3257
3317
  if (quantity !== undefined) {
3258
3318
  request['quantity'] = quantity;
3259
3319
  }
3260
- response = await this.privateSpotPostTradeOrders(this.extend(request, params));
3261
3320
  }
3262
3321
  }
3263
3322
  else {
3264
3323
  throw new errors.NotSupported(this.id + ' createOrder() does not support ' + marketType + ' orders');
3265
3324
  }
3325
+ return this.extend(request, params);
3326
+ }
3327
+ async createOrders(orders, params = {}) {
3328
+ /**
3329
+ * @method
3330
+ * @name bitget#createOrders
3331
+ * @description create a list of trade orders (all orders should be of the same symbol)
3332
+ * @see https://bitgetlimited.github.io/apidoc/en/spot/#batch-order
3333
+ * @see https://bitgetlimited.github.io/apidoc/en/mix/#batch-order
3334
+ * @param {array} orders list of orders to create, each object should contain the parameters required by createOrder, namely symbol, type, side, amount, price and params
3335
+ * @returns {object} an [order structure]{@link https://github.com/ccxt/ccxt/wiki/Manual#order-structure}
3336
+ */
3337
+ await this.loadMarkets();
3338
+ const ordersRequests = [];
3339
+ let symbol = undefined;
3340
+ for (let i = 0; i < orders.length; i++) {
3341
+ const rawOrder = orders[i];
3342
+ const marketId = this.safeString(rawOrder, 'symbol');
3343
+ if (symbol === undefined) {
3344
+ symbol = marketId;
3345
+ }
3346
+ else {
3347
+ if (symbol !== marketId) {
3348
+ throw new errors.BadRequest(this.id + ' createOrders() requires all orders to have the same symbol');
3349
+ }
3350
+ }
3351
+ const type = this.safeString(rawOrder, 'type');
3352
+ const side = this.safeString(rawOrder, 'side');
3353
+ const amount = this.safeValue(rawOrder, 'amount');
3354
+ const price = this.safeValue(rawOrder, 'price');
3355
+ const orderParams = this.safeValue(rawOrder, 'params', {});
3356
+ const orderRequest = this.createOrderRequest(marketId, type, side, amount, price, orderParams);
3357
+ ordersRequests.push(orderRequest);
3358
+ }
3359
+ const market = this.market(symbol);
3360
+ const request = {
3361
+ 'symbol': market['id'],
3362
+ };
3363
+ let response = undefined;
3364
+ if (market['spot']) {
3365
+ request['orderList'] = ordersRequests;
3366
+ response = await this.privateSpotPostTradeBatchOrders(request);
3367
+ }
3368
+ else {
3369
+ request['orderDataList'] = ordersRequests;
3370
+ request['marginCoin'] = market['settleId'];
3371
+ response = await this.privateMixPostOrderBatchOrders(request);
3372
+ }
3266
3373
  //
3267
- // {
3268
- // "code": "00000",
3269
- // "msg": "success",
3270
- // "requestTime": 1645932209602,
3271
- // "data": {
3272
- // "orderId": "881669078313766912",
3273
- // "clientOrderId": "iauIBf#a45b595f96474d888d0ada"
3374
+ // {
3375
+ // "code": "00000",
3376
+ // "data": {
3377
+ // "orderInfo": [
3378
+ // {
3379
+ // "orderId": "1627293504612",
3380
+ // "clientOid": "BITGET#1627293504612"
3274
3381
  // }
3275
- // }
3382
+ // ],
3383
+ // "failure":[
3384
+ // {
3385
+ // "orderId": "1627293504611",
3386
+ // "clientOid": "BITGET#1627293504611",
3387
+ // "errorMsg":"Duplicate clientOid"
3388
+ // }
3389
+ // ]
3390
+ // },
3391
+ // "msg": "success",
3392
+ // "requestTime": 1627293504612
3393
+ // }
3276
3394
  //
3277
3395
  const data = this.safeValue(response, 'data', {});
3278
- return this.parseOrder(data, market);
3396
+ const failure = this.safeValue(data, 'failure', []);
3397
+ const orderInfo = this.safeValue2(data, 'orderInfo', 'resultList', []);
3398
+ const both = this.arrayConcat(orderInfo, failure);
3399
+ return this.parseOrders(both);
3279
3400
  }
3280
3401
  async editOrder(id, symbol, type, side, amount = undefined, price = undefined, params = {}) {
3281
3402
  /**
@@ -5911,6 +6032,348 @@ class bitget extends bitget$1 {
5911
6032
  'info': info,
5912
6033
  };
5913
6034
  }
6035
+ async fetchMyLiquidations(symbol = undefined, since = undefined, limit = undefined, params = {}) {
6036
+ /**
6037
+ * @method
6038
+ * @name bitget#fetchMyLiquidations
6039
+ * @description retrieves the users liquidated positions
6040
+ * @see https://bitgetlimited.github.io/apidoc/en/margin/#get-isolated-liquidation-records
6041
+ * @see https://bitgetlimited.github.io/apidoc/en/margin/#get-cross-liquidation-records
6042
+ * @param {string} [symbol] unified CCXT market symbol
6043
+ * @param {int} [since] the earliest time in ms to fetch liquidations for
6044
+ * @param {int} [limit] the maximum number of liquidation structures to retrieve
6045
+ * @param {object} [params] exchange specific parameters for the bitget api endpoint
6046
+ * @param {int} [params.until] timestamp in ms of the latest liquidation
6047
+ * @param {string} [params.marginMode] 'cross' or 'isolated' default value is 'cross'
6048
+ * @returns {object} an array of [liquidation structures]{@link https://github.com/ccxt/ccxt/wiki/Manual#liquidation-structure}
6049
+ */
6050
+ await this.loadMarkets();
6051
+ let market = undefined;
6052
+ if (symbol !== undefined) {
6053
+ market = this.market(symbol);
6054
+ }
6055
+ let type = undefined;
6056
+ [type, params] = this.handleMarketTypeAndParams('fetchMyLiquidations', market, params);
6057
+ if (type !== 'spot') {
6058
+ throw new errors.NotSupported(this.id + ' fetchMyLiquidations() supports spot margin markets only');
6059
+ }
6060
+ let request = {};
6061
+ [request, params] = this.handleUntilOption('endTime', request, params);
6062
+ if (since !== undefined) {
6063
+ request['startTime'] = since;
6064
+ }
6065
+ else {
6066
+ request['startTime'] = this.milliseconds() - 7776000000;
6067
+ }
6068
+ if (limit !== undefined) {
6069
+ request['pageSize'] = limit;
6070
+ }
6071
+ let response = undefined;
6072
+ let marginMode = undefined;
6073
+ [marginMode, params] = this.handleMarginModeAndParams('fetchMyLiquidations', params, 'cross');
6074
+ if (marginMode === 'isolated') {
6075
+ this.checkRequiredSymbol('fetchMyLiquidations', symbol);
6076
+ request['symbol'] = market['info']['symbolName'];
6077
+ response = await this.privateMarginGetIsolatedLiquidationList(this.extend(request, params));
6078
+ }
6079
+ else if (marginMode === 'cross') {
6080
+ response = await this.privateMarginGetCrossLiquidationList(this.extend(request, params));
6081
+ }
6082
+ //
6083
+ // isolated
6084
+ //
6085
+ // {
6086
+ // "code": "00000",
6087
+ // "msg": "success",
6088
+ // "requestTime": 1698114119193,
6089
+ // "data": {
6090
+ // "resultList": [
6091
+ // {
6092
+ // "liqId": "123",
6093
+ // "symbol": "BTCUSDT",
6094
+ // "liqStartTime": "1653453245342",
6095
+ // "liqEndTime": "16312423423432",
6096
+ // "liqRisk": "1.01",
6097
+ // "totalAssets": "1242.34",
6098
+ // "totalDebt": "1100",
6099
+ // "LiqFee": "1.2",
6100
+ // "cTime": "1653453245342"
6101
+ // }
6102
+ // ],
6103
+ // "maxId": "0",
6104
+ // "minId": "0"
6105
+ // }
6106
+ // }
6107
+ //
6108
+ // cross
6109
+ //
6110
+ // {
6111
+ // "code": "00000",
6112
+ // "msg": "success",
6113
+ // "requestTime": 1698114119193,
6114
+ // "data": {
6115
+ // "resultList": [
6116
+ // {
6117
+ // "liqId": "123",
6118
+ // "liqStartTime": "1653453245342",
6119
+ // "liqEndTime": "16312423423432",
6120
+ // "liqRisk": "1.01",
6121
+ // "totalAssets": "1242.34",
6122
+ // "totalDebt": "1100",
6123
+ // "LiqFee": "1.2",
6124
+ // "cTime": "1653453245342"
6125
+ // }
6126
+ // ],
6127
+ // "maxId": "0",
6128
+ // "minId": "0"
6129
+ // }
6130
+ // }
6131
+ //
6132
+ const data = this.safeValue(response, 'data', {});
6133
+ const liquidations = this.safeValue(data, 'resultList', []);
6134
+ return this.parseLiquidations(liquidations, market, since, limit);
6135
+ }
6136
+ parseLiquidation(liquidation, market = undefined) {
6137
+ //
6138
+ // isolated
6139
+ //
6140
+ // {
6141
+ // "liqId": "123",
6142
+ // "symbol": "BTCUSDT",
6143
+ // "liqStartTime": "1653453245342",
6144
+ // "liqEndTime": "16312423423432",
6145
+ // "liqRisk": "1.01",
6146
+ // "totalAssets": "1242.34",
6147
+ // "totalDebt": "1100",
6148
+ // "LiqFee": "1.2",
6149
+ // "cTime": "1653453245342"
6150
+ // }
6151
+ //
6152
+ // cross
6153
+ //
6154
+ // {
6155
+ // "liqId": "123",
6156
+ // "liqStartTime": "1653453245342",
6157
+ // "liqEndTime": "16312423423432",
6158
+ // "liqRisk": "1.01",
6159
+ // "totalAssets": "1242.34",
6160
+ // "totalDebt": "1100",
6161
+ // "LiqFee": "1.2",
6162
+ // "cTime": "1653453245342"
6163
+ // }
6164
+ //
6165
+ const marketId = this.safeString(liquidation, 'symbol');
6166
+ const timestamp = this.safeInteger(liquidation, 'liqEndTime');
6167
+ const liquidationFee = this.safeString(liquidation, 'LiqFee');
6168
+ const totalDebt = this.safeString(liquidation, 'totalDebt');
6169
+ const quoteValueString = Precise["default"].stringAdd(liquidationFee, totalDebt);
6170
+ return {
6171
+ 'info': liquidation,
6172
+ 'symbol': this.safeSymbol(marketId, market),
6173
+ 'contracts': undefined,
6174
+ 'contractSize': undefined,
6175
+ 'price': undefined,
6176
+ 'baseValue': undefined,
6177
+ 'quoteValue': this.parseNumber(quoteValueString),
6178
+ 'timestamp': timestamp,
6179
+ 'datetime': this.iso8601(timestamp),
6180
+ };
6181
+ }
6182
+ async fetchBorrowRate(code, params = {}) {
6183
+ /**
6184
+ * @method
6185
+ * @name bitget#fetchBorrowRate
6186
+ * @description fetch the rate of interest to borrow a currency for margin trading
6187
+ * @see https://bitgetlimited.github.io/apidoc/en/margin/#get-isolated-margin-interest-rate-and-max-borrowable-amount
6188
+ * @see https://bitgetlimited.github.io/apidoc/en/margin/#get-cross-margin-interest-rate-and-borrowable
6189
+ * @param {string} code unified currency code
6190
+ * @param {object} [params] extra parameters specific to the bitget api endpoint
6191
+ * @param {string} [params.symbol] required for isolated margin
6192
+ * @returns {object} a [borrow rate structure]{@link https://github.com/ccxt/ccxt/wiki/Manual#borrow-rate-structure}
6193
+ */
6194
+ await this.loadMarkets();
6195
+ const currency = this.currency(code);
6196
+ let market = undefined;
6197
+ const symbol = this.safeString(params, 'symbol');
6198
+ params = this.omit(params, 'symbol');
6199
+ if (symbol !== undefined) {
6200
+ market = this.market(symbol);
6201
+ }
6202
+ const request = {};
6203
+ let response = undefined;
6204
+ let marginMode = undefined;
6205
+ [marginMode, params] = this.handleMarginModeAndParams('fetchBorrowRate', params, 'cross');
6206
+ if ((symbol !== undefined) || (marginMode === 'isolated')) {
6207
+ this.checkRequiredSymbol('fetchBorrowRate', symbol);
6208
+ request['symbol'] = market['info']['symbolName'];
6209
+ response = await this.publicMarginGetIsolatedPublicInterestRateAndLimit(this.extend(request, params));
6210
+ }
6211
+ else if (marginMode === 'cross') {
6212
+ request['coin'] = currency['code'];
6213
+ response = await this.publicMarginGetCrossPublicInterestRateAndLimit(this.extend(request, params));
6214
+ }
6215
+ //
6216
+ // isolated
6217
+ //
6218
+ // {
6219
+ // "code": "00000",
6220
+ // "msg": "success",
6221
+ // "requestTime": 1698208075332,
6222
+ // "data": [
6223
+ // {
6224
+ // "symbol": "BTCUSDT",
6225
+ // "leverage": "10",
6226
+ // "baseCoin": "BTC",
6227
+ // "baseTransferInAble": true,
6228
+ // "baseBorrowAble": true,
6229
+ // "baseDailyInterestRate": "0.00007",
6230
+ // "baseYearlyInterestRate": "0.02555",
6231
+ // "baseMaxBorrowableAmount": "35",
6232
+ // "baseVips": [
6233
+ // {
6234
+ // "level": "0",
6235
+ // "dailyInterestRate": "0.00007",
6236
+ // "yearlyInterestRate": "0.02555",
6237
+ // "discountRate": "1"
6238
+ // },
6239
+ // ],
6240
+ // "quoteCoin": "USDT",
6241
+ // "quoteTransferInAble": true,
6242
+ // "quoteBorrowAble": true,
6243
+ // "quoteDailyInterestRate": "0.00012627",
6244
+ // "quoteYearlyInterestRate": "0.04608855",
6245
+ // "quoteMaxBorrowableAmount": "300000",
6246
+ // "quoteVips": [
6247
+ // {
6248
+ // "level": "0",
6249
+ // "dailyInterestRate": "0.000126279",
6250
+ // "yearlyInterestRate": "0.046091835",
6251
+ // "discountRate": "1"
6252
+ // },
6253
+ // ]
6254
+ // }
6255
+ // ]
6256
+ // }
6257
+ //
6258
+ // cross
6259
+ //
6260
+ // {
6261
+ // "code": "00000",
6262
+ // "msg": "success",
6263
+ // "requestTime": 1698208150986,
6264
+ // "data": [
6265
+ // {
6266
+ // "coin": "BTC",
6267
+ // "leverage": "3",
6268
+ // "transferInAble": true,
6269
+ // "borrowAble": true,
6270
+ // "dailyInterestRate": "0.00007",
6271
+ // "yearlyInterestRate": "0.02555",
6272
+ // "maxBorrowableAmount": "26",
6273
+ // "vips": [
6274
+ // {
6275
+ // "level": "0",
6276
+ // "dailyInterestRate": "0.00007",
6277
+ // "yearlyInterestRate": "0.02555",
6278
+ // "discountRate": "1"
6279
+ // },
6280
+ // ]
6281
+ // }
6282
+ // ]
6283
+ // }
6284
+ //
6285
+ const timestamp = this.safeInteger(response, 'requestTime');
6286
+ const data = this.safeValue(response, 'data', []);
6287
+ const first = this.safeValue(data, 0, {});
6288
+ first['timestamp'] = timestamp;
6289
+ return this.parseBorrowRate(first, currency);
6290
+ }
6291
+ parseBorrowRate(info, currency = undefined) {
6292
+ //
6293
+ // isolated
6294
+ //
6295
+ // {
6296
+ // "symbol": "BTCUSDT",
6297
+ // "leverage": "10",
6298
+ // "baseCoin": "BTC",
6299
+ // "baseTransferInAble": true,
6300
+ // "baseBorrowAble": true,
6301
+ // "baseDailyInterestRate": "0.00007",
6302
+ // "baseYearlyInterestRate": "0.02555",
6303
+ // "baseMaxBorrowableAmount": "35",
6304
+ // "baseVips": [
6305
+ // {
6306
+ // "level": "0",
6307
+ // "dailyInterestRate": "0.00007",
6308
+ // "yearlyInterestRate": "0.02555",
6309
+ // "discountRate": "1"
6310
+ // },
6311
+ // ],
6312
+ // "quoteCoin": "USDT",
6313
+ // "quoteTransferInAble": true,
6314
+ // "quoteBorrowAble": true,
6315
+ // "quoteDailyInterestRate": "0.00012627",
6316
+ // "quoteYearlyInterestRate": "0.04608855",
6317
+ // "quoteMaxBorrowableAmount": "300000",
6318
+ // "quoteVips": [
6319
+ // {
6320
+ // "level": "0",
6321
+ // "dailyInterestRate": "0.000126279",
6322
+ // "yearlyInterestRate": "0.046091835",
6323
+ // "discountRate": "1"
6324
+ // },
6325
+ // ]
6326
+ // }
6327
+ //
6328
+ // cross
6329
+ //
6330
+ // {
6331
+ // "coin": "BTC",
6332
+ // "leverage": "3",
6333
+ // "transferInAble": true,
6334
+ // "borrowAble": true,
6335
+ // "dailyInterestRate": "0.00007",
6336
+ // "yearlyInterestRate": "0.02555",
6337
+ // "maxBorrowableAmount": "26",
6338
+ // "vips": [
6339
+ // {
6340
+ // "level": "0",
6341
+ // "dailyInterestRate": "0.00007",
6342
+ // "yearlyInterestRate": "0.02555",
6343
+ // "discountRate": "1"
6344
+ // },
6345
+ // ]
6346
+ // }
6347
+ //
6348
+ const code = currency['code'];
6349
+ const baseCoin = this.safeString(info, 'baseCoin');
6350
+ const quoteCoin = this.safeString(info, 'quoteCoin');
6351
+ let currencyId = undefined;
6352
+ let interestRate = undefined;
6353
+ if (baseCoin !== undefined) {
6354
+ if (code === baseCoin) {
6355
+ currencyId = baseCoin;
6356
+ interestRate = this.safeNumber(info, 'baseDailyInterestRate');
6357
+ }
6358
+ else if (code === quoteCoin) {
6359
+ currencyId = quoteCoin;
6360
+ interestRate = this.safeNumber(info, 'quoteDailyInterestRate');
6361
+ }
6362
+ }
6363
+ else {
6364
+ currencyId = this.safeString(info, 'coin');
6365
+ interestRate = this.safeNumber(info, 'dailyInterestRate');
6366
+ }
6367
+ const timestamp = this.safeInteger(info, 'timestamp');
6368
+ return {
6369
+ 'currency': this.safeCurrencyCode(currencyId, currency),
6370
+ 'rate': interestRate,
6371
+ 'period': 86400000,
6372
+ 'timestamp': timestamp,
6373
+ 'datetime': this.iso8601(timestamp),
6374
+ 'info': info,
6375
+ };
6376
+ }
5914
6377
  handleErrors(code, reason, url, method, headers, body, response, requestHeaders, requestBody) {
5915
6378
  if (!response) {
5916
6379
  return undefined; // fallback to default error handler