ccxt 4.4.20 → 4.4.22

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 (77) hide show
  1. package/README.md +4 -4
  2. package/dist/ccxt.browser.min.js +5 -5
  3. package/dist/cjs/ccxt.js +1 -1
  4. package/dist/cjs/src/alpaca.js +1 -0
  5. package/dist/cjs/src/base/Exchange.js +34 -0
  6. package/dist/cjs/src/base/ws/Future.js +3 -1
  7. package/dist/cjs/src/bigone.js +3 -0
  8. package/dist/cjs/src/binance.js +103 -10
  9. package/dist/cjs/src/bingx.js +6 -1
  10. package/dist/cjs/src/bitflyer.js +57 -0
  11. package/dist/cjs/src/bitget.js +77 -0
  12. package/dist/cjs/src/bybit.js +143 -3
  13. package/dist/cjs/src/cex.js +1307 -1385
  14. package/dist/cjs/src/cryptocom.js +1 -1
  15. package/dist/cjs/src/gate.js +103 -3
  16. package/dist/cjs/src/htx.js +29 -7
  17. package/dist/cjs/src/hyperliquid.js +15 -12
  18. package/dist/cjs/src/kucoin.js +43 -95
  19. package/dist/cjs/src/kucoinfutures.js +2 -2
  20. package/dist/cjs/src/okx.js +82 -10
  21. package/dist/cjs/src/paradex.js +1 -2
  22. package/dist/cjs/src/static_dependencies/noble-hashes/_sha2.js +1 -1
  23. package/dist/cjs/src/static_dependencies/noble-hashes/hmac.js +1 -1
  24. package/dist/cjs/src/static_dependencies/noble-hashes/sha3.js +1 -1
  25. package/dist/cjs/src/static_dependencies/watchable/src/unpromise.js +298 -0
  26. package/js/ccxt.d.ts +3 -3
  27. package/js/ccxt.js +1 -1
  28. package/js/src/abstract/bitflyer.d.ts +1 -0
  29. package/js/src/abstract/bitget.d.ts +3 -0
  30. package/js/src/abstract/bybit.d.ts +1 -0
  31. package/js/src/abstract/cex.d.ts +28 -29
  32. package/js/src/abstract/gate.d.ts +5 -0
  33. package/js/src/abstract/gateio.d.ts +5 -0
  34. package/js/src/abstract/kucoin.d.ts +2 -0
  35. package/js/src/abstract/kucoinfutures.d.ts +2 -0
  36. package/js/src/abstract/okx.d.ts +4 -0
  37. package/js/src/alpaca.js +1 -0
  38. package/js/src/base/Exchange.d.ts +11 -3
  39. package/js/src/base/Exchange.js +34 -0
  40. package/js/src/base/types.d.ts +8 -0
  41. package/js/src/base/ws/Future.js +2 -1
  42. package/js/src/bigone.js +3 -0
  43. package/js/src/binance.d.ts +3 -2
  44. package/js/src/binance.js +103 -10
  45. package/js/src/bingx.js +6 -1
  46. package/js/src/bitflyer.d.ts +3 -1
  47. package/js/src/bitflyer.js +57 -0
  48. package/js/src/bitget.d.ts +3 -1
  49. package/js/src/bitget.js +77 -0
  50. package/js/src/bybit.d.ts +4 -1
  51. package/js/src/bybit.js +143 -3
  52. package/js/src/cex.d.ts +34 -20
  53. package/js/src/cex.js +1308 -1386
  54. package/js/src/cryptocom.js +1 -1
  55. package/js/src/gate.d.ts +2 -0
  56. package/js/src/gate.js +103 -3
  57. package/js/src/htx.d.ts +2 -2
  58. package/js/src/htx.js +29 -7
  59. package/js/src/hyperliquid.js +15 -12
  60. package/js/src/kucoin.d.ts +0 -2
  61. package/js/src/kucoin.js +43 -95
  62. package/js/src/kucoinfutures.js +2 -2
  63. package/js/src/okx.d.ts +3 -2
  64. package/js/src/okx.js +83 -11
  65. package/js/src/paradex.js +1 -1
  66. package/js/src/static_dependencies/noble-hashes/_blake2.js +1 -1
  67. package/js/src/static_dependencies/noble-hashes/_sha2.js +1 -1
  68. package/js/src/static_dependencies/noble-hashes/hmac.js +1 -1
  69. package/js/src/static_dependencies/noble-hashes/sha3-addons.js +5 -5
  70. package/js/src/static_dependencies/noble-hashes/sha3.js +1 -1
  71. package/js/src/static_dependencies/watchable/src/index.d.ts +2 -0
  72. package/js/src/static_dependencies/watchable/src/index.js +7 -0
  73. package/js/src/static_dependencies/watchable/src/types.d.ts +28 -0
  74. package/js/src/static_dependencies/watchable/src/types.js +8 -0
  75. package/js/src/static_dependencies/watchable/src/unpromise.d.ts +120 -0
  76. package/js/src/static_dependencies/watchable/src/unpromise.js +297 -0
  77. package/package.json +1 -1
package/dist/cjs/ccxt.js CHANGED
@@ -195,7 +195,7 @@ var xt$1 = require('./src/pro/xt.js');
195
195
 
196
196
  //-----------------------------------------------------------------------------
197
197
  // this is updated by vss.js when building
198
- const version = '4.4.20';
198
+ const version = '4.4.22';
199
199
  Exchange["default"].ccxtVersion = version;
200
200
  const exchanges = {
201
201
  'ace': ace,
@@ -60,6 +60,7 @@ class alpaca extends alpaca$1 {
60
60
  'fetchDepositsWithdrawals': false,
61
61
  'fetchFundingHistory': false,
62
62
  'fetchFundingRate': false,
63
+ 'fetchFundingRateHistory': false,
63
64
  'fetchFundingRates': false,
64
65
  'fetchL1OrderBook': true,
65
66
  'fetchL2OrderBook': false,
@@ -1419,6 +1419,8 @@ class Exchange {
1419
1419
  'fetchLeverages': undefined,
1420
1420
  'fetchLeverageTiers': undefined,
1421
1421
  'fetchLiquidations': undefined,
1422
+ 'fetchLongShortRatio': undefined,
1423
+ 'fetchLongShortRatioHistory': undefined,
1422
1424
  'fetchMarginMode': undefined,
1423
1425
  'fetchMarginModes': undefined,
1424
1426
  'fetchMarketLeverageTiers': undefined,
@@ -2212,6 +2214,12 @@ class Exchange {
2212
2214
  async setMargin(symbol, amount, params = {}) {
2213
2215
  throw new errors.NotSupported(this.id + ' setMargin() is not supported yet');
2214
2216
  }
2217
+ async fetchLongShortRatio(symbol, timeframe = undefined, params = {}) {
2218
+ throw new errors.NotSupported(this.id + ' fetchLongShortRatio() is not supported yet');
2219
+ }
2220
+ async fetchLongShortRatioHistory(symbol = undefined, timeframe = undefined, since = undefined, limit = undefined, params = {}) {
2221
+ throw new errors.NotSupported(this.id + ' fetchLongShortRatioHistory() is not supported yet');
2222
+ }
2215
2223
  async fetchMarginAdjustmentHistory(symbol = undefined, type = undefined, since = undefined, limit = undefined, params = {}) {
2216
2224
  /**
2217
2225
  * @method
@@ -5524,6 +5532,19 @@ class Exchange {
5524
5532
  }
5525
5533
  return interests;
5526
5534
  }
5535
+ parseBorrowRate(info, currency = undefined) {
5536
+ throw new errors.NotSupported(this.id + ' parseBorrowRate() is not supported yet');
5537
+ }
5538
+ parseBorrowRateHistory(response, code, since, limit) {
5539
+ const result = [];
5540
+ for (let i = 0; i < response.length; i++) {
5541
+ const item = response[i];
5542
+ const borrowRate = this.parseBorrowRate(item);
5543
+ result.push(borrowRate);
5544
+ }
5545
+ const sorted = this.sortBy(result, 'timestamp');
5546
+ return this.filterByCurrencySinceLimit(sorted, code, since, limit);
5547
+ }
5527
5548
  parseIsolatedBorrowRates(info) {
5528
5549
  const result = {};
5529
5550
  for (let i = 0; i < info.length; i++) {
@@ -5559,6 +5580,19 @@ class Exchange {
5559
5580
  }
5560
5581
  return result;
5561
5582
  }
5583
+ parseLongShortRatio(info, market = undefined) {
5584
+ throw new errors.NotSupported(this.id + ' parseLongShortRatio() is not supported yet');
5585
+ }
5586
+ parseLongShortRatioHistory(response, market = undefined, since = undefined, limit = undefined) {
5587
+ const rates = [];
5588
+ for (let i = 0; i < response.length; i++) {
5589
+ const entry = response[i];
5590
+ rates.push(this.parseLongShortRatio(entry, market));
5591
+ }
5592
+ const sorted = this.sortBy(rates, 'timestamp');
5593
+ const symbol = (market === undefined) ? undefined : market['symbol'];
5594
+ return this.filterBySymbolSinceLimit(sorted, symbol, since, limit);
5595
+ }
5562
5596
  handleTriggerAndParams(params) {
5563
5597
  const isTrigger = this.safeBool2(params, 'trigger', 'stop');
5564
5598
  if (isTrigger) {
@@ -2,6 +2,8 @@
2
2
 
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
+ var unpromise = require('../../static_dependencies/watchable/src/unpromise.js');
6
+
5
7
  // @ts-nocheck
6
8
  function Future() {
7
9
  let resolve = undefined, reject = undefined;
@@ -29,6 +31,6 @@ function wrapFuture(aggregatePromise) {
29
31
  aggregatePromise.then(p.resolve, p.reject);
30
32
  return p;
31
33
  }
32
- Future.race = (futures) => wrapFuture(Promise.race(futures));
34
+ Future.race = (futures) => wrapFuture(unpromise.Unpromise.race(futures));
33
35
 
34
36
  exports.Future = Future;
@@ -45,7 +45,10 @@ class bigone extends bigone$1 {
45
45
  'fetchDepositAddresses': false,
46
46
  'fetchDepositAddressesByNetwork': false,
47
47
  'fetchDeposits': true,
48
+ 'fetchFundingHistory': false,
48
49
  'fetchFundingRate': false,
50
+ 'fetchFundingRateHistory': false,
51
+ 'fetchFundingRates': false,
49
52
  'fetchMarkets': true,
50
53
  'fetchMyTrades': true,
51
54
  'fetchOHLCV': true,
@@ -105,6 +105,8 @@ class binance extends binance$1 {
105
105
  'fetchLeverages': true,
106
106
  'fetchLeverageTiers': true,
107
107
  'fetchLiquidations': false,
108
+ 'fetchLongShortRatio': false,
109
+ 'fetchLongShortRatioHistory': true,
108
110
  'fetchMarginAdjustmentHistory': true,
109
111
  'fetchMarginMode': 'emulated',
110
112
  'fetchMarginModes': true,
@@ -12115,16 +12117,6 @@ class binance extends binance$1 {
12115
12117
  //
12116
12118
  return this.parseBorrowRateHistory(response, code, since, limit);
12117
12119
  }
12118
- parseBorrowRateHistory(response, code, since, limit) {
12119
- const result = [];
12120
- for (let i = 0; i < response.length; i++) {
12121
- const item = response[i];
12122
- const borrowRate = this.parseBorrowRate(item);
12123
- result.push(borrowRate);
12124
- }
12125
- const sorted = this.sortBy(result, 'timestamp');
12126
- return this.filterByCurrencySinceLimit(sorted, code, since, limit);
12127
- }
12128
12120
  parseBorrowRate(info, currency = undefined) {
12129
12121
  //
12130
12122
  // {
@@ -13828,6 +13820,107 @@ class binance extends binance$1 {
13828
13820
  const result = this.parseFundingRates(response, market);
13829
13821
  return this.filterByArray(result, 'symbol', symbols);
13830
13822
  }
13823
+ async fetchLongShortRatioHistory(symbol = undefined, timeframe = undefined, since = undefined, limit = undefined, params = {}) {
13824
+ /**
13825
+ * @method
13826
+ * @name binance#fetchLongShortRatioHistory
13827
+ * @description fetches the long short ratio history for a unified market symbol
13828
+ * @see https://developers.binance.com/docs/derivatives/usds-margined-futures/market-data/rest-api/Long-Short-Ratio
13829
+ * @see https://developers.binance.com/docs/derivatives/coin-margined-futures/market-data/Long-Short-Ratio
13830
+ * @param {string} symbol unified symbol of the market to fetch the long short ratio for
13831
+ * @param {string} [timeframe] the period for the ratio, default is 24 hours
13832
+ * @param {int} [since] the earliest time in ms to fetch ratios for
13833
+ * @param {int} [limit] the maximum number of long short ratio structures to retrieve
13834
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
13835
+ * @param {int} [params.until] timestamp in ms of the latest ratio to fetch
13836
+ * @returns {object[]} an array of [long short ratio structures]{@link https://docs.ccxt.com/#/?id=long-short-ratio-structure}
13837
+ */
13838
+ await this.loadMarkets();
13839
+ const market = this.market(symbol);
13840
+ if (timeframe === undefined) {
13841
+ timeframe = '1d';
13842
+ }
13843
+ let request = {
13844
+ 'period': timeframe,
13845
+ };
13846
+ [request, params] = this.handleUntilOption('endTime', request, params);
13847
+ if (since !== undefined) {
13848
+ request['startTime'] = since;
13849
+ }
13850
+ if (limit !== undefined) {
13851
+ request['limit'] = limit;
13852
+ }
13853
+ let subType = undefined;
13854
+ [subType, params] = this.handleSubTypeAndParams('fetchLongShortRatioHistory', market, params);
13855
+ let response = undefined;
13856
+ if (subType === 'linear') {
13857
+ request['symbol'] = market['id'];
13858
+ response = await this.fapiDataGetGlobalLongShortAccountRatio(this.extend(request, params));
13859
+ //
13860
+ // [
13861
+ // {
13862
+ // "symbol": "BTCUSDT",
13863
+ // "longAccount": "0.4558",
13864
+ // "longShortRatio": "0.8376",
13865
+ // "shortAccount": "0.5442",
13866
+ // "timestamp": 1726790400000
13867
+ // },
13868
+ // ]
13869
+ //
13870
+ }
13871
+ else if (subType === 'inverse') {
13872
+ request['pair'] = market['info']['pair'];
13873
+ response = await this.dapiDataGetGlobalLongShortAccountRatio(this.extend(request, params));
13874
+ //
13875
+ // [
13876
+ // {
13877
+ // "longAccount": "0.7262",
13878
+ // "longShortRatio": "2.6523",
13879
+ // "shortAccount": "0.2738",
13880
+ // "pair": "BTCUSD",
13881
+ // "timestamp": 1726790400000
13882
+ // },
13883
+ // ]
13884
+ //
13885
+ }
13886
+ else {
13887
+ throw new errors.BadRequest(this.id + ' fetchLongShortRatioHistory() supports linear and inverse subTypes only');
13888
+ }
13889
+ return this.parseLongShortRatioHistory(response, market);
13890
+ }
13891
+ parseLongShortRatio(info, market = undefined) {
13892
+ //
13893
+ // linear
13894
+ //
13895
+ // {
13896
+ // "symbol": "BTCUSDT",
13897
+ // "longAccount": "0.4558",
13898
+ // "longShortRatio": "0.8376",
13899
+ // "shortAccount": "0.5442",
13900
+ // "timestamp": 1726790400000
13901
+ // }
13902
+ //
13903
+ // inverse
13904
+ //
13905
+ // {
13906
+ // "longAccount": "0.7262",
13907
+ // "longShortRatio": "2.6523",
13908
+ // "shortAccount": "0.2738",
13909
+ // "pair": "BTCUSD",
13910
+ // "timestamp": 1726790400000
13911
+ // }
13912
+ //
13913
+ const marketId = this.safeString(info, 'symbol');
13914
+ const timestamp = this.safeIntegerOmitZero(info, 'timestamp');
13915
+ return {
13916
+ 'info': info,
13917
+ 'symbol': this.safeSymbol(marketId, market, undefined, 'contract'),
13918
+ 'timestamp': timestamp,
13919
+ 'datetime': this.iso8601(timestamp),
13920
+ 'timeframe': undefined,
13921
+ 'longShortRatio': this.safeNumber(info, 'longShortRatio'),
13922
+ };
13923
+ }
13831
13924
  }
13832
13925
 
13833
13926
  module.exports = binance;
@@ -5316,7 +5316,7 @@ class bingx extends bingx$1 {
5316
5316
  * @method
5317
5317
  * @name bingx#withdraw
5318
5318
  * @description make a withdrawal
5319
- * @see https://bingx-api.github.io/docs/#/common/account-api.html#Withdraw
5319
+ * @see https://bingx-api.github.io/docs/#/en-us/spot/wallet-api.html#Withdraw
5320
5320
  * @param {string} code unified currency code
5321
5321
  * @param {float} amount the amount to withdraw
5322
5322
  * @param {string} address the address to withdraw to
@@ -5325,6 +5325,8 @@ class bingx extends bingx$1 {
5325
5325
  * @param {int} [params.walletType] 1 fund account, 2 standard account, 3 perpetual account
5326
5326
  * @returns {object} a [transaction structure]{@link https://docs.ccxt.com/#/?id=transaction-structure}
5327
5327
  */
5328
+ [tag, params] = this.handleWithdrawTagAndParams(tag, params);
5329
+ this.checkAddress(address);
5328
5330
  await this.loadMarkets();
5329
5331
  const currency = this.currency(code);
5330
5332
  let walletType = this.safeInteger(params, 'walletType');
@@ -5344,6 +5346,9 @@ class bingx extends bingx$1 {
5344
5346
  if (network !== undefined) {
5345
5347
  request['network'] = this.networkCodeToId(network);
5346
5348
  }
5349
+ if (tag !== undefined) {
5350
+ request['addressTag'] = tag;
5351
+ }
5347
5352
  params = this.omit(params, ['walletType', 'network']);
5348
5353
  const response = await this.walletsV1PrivatePostCapitalWithdrawApply(this.extend(request, params));
5349
5354
  const data = this.safeValue(response, 'data');
@@ -34,6 +34,8 @@ class bitflyer extends bitflyer$1 {
34
34
  'fetchBalance': true,
35
35
  'fetchClosedOrders': 'emulated',
36
36
  'fetchDeposits': true,
37
+ 'fetchFundingRate': true,
38
+ 'fetchFundingRateHistory': false,
37
39
  'fetchMarginMode': false,
38
40
  'fetchMarkets': true,
39
41
  'fetchMyTrades': true,
@@ -73,6 +75,7 @@ class bitflyer extends bitflyer$1 {
73
75
  'gethealth',
74
76
  'getboardstate',
75
77
  'getchats',
78
+ 'getfundingrate',
76
79
  ],
77
80
  },
78
81
  'private': {
@@ -1023,6 +1026,60 @@ class bitflyer extends bitflyer$1 {
1023
1026
  'fee': fee,
1024
1027
  };
1025
1028
  }
1029
+ async fetchFundingRate(symbol, params = {}) {
1030
+ /**
1031
+ * @method
1032
+ * @name bitflyer#fetchFundingRate
1033
+ * @description fetch the current funding rate
1034
+ * @see https://lightning.bitflyer.com/docs#funding-rate
1035
+ * @param {string} symbol unified market symbol
1036
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
1037
+ * @returns {object} a [funding rate structure]{@link https://docs.ccxt.com/#/?id=funding-rate-structure}
1038
+ */
1039
+ await this.loadMarkets();
1040
+ const market = this.market(symbol);
1041
+ const request = {
1042
+ 'product_code': market['id'],
1043
+ };
1044
+ const response = await this.publicGetGetfundingrate(this.extend(request, params));
1045
+ //
1046
+ // {
1047
+ // "current_funding_rate": -0.003750000000
1048
+ // "next_funding_rate_settledate": "2024-04-15T13:00:00"
1049
+ // }
1050
+ //
1051
+ return this.parseFundingRate(response, market);
1052
+ }
1053
+ parseFundingRate(contract, market = undefined) {
1054
+ //
1055
+ // {
1056
+ // "current_funding_rate": -0.003750000000
1057
+ // "next_funding_rate_settledate": "2024-04-15T13:00:00"
1058
+ // }
1059
+ //
1060
+ const nextFundingDatetime = this.safeString(contract, 'next_funding_rate_settledate');
1061
+ const nextFundingTimestamp = this.parse8601(nextFundingDatetime);
1062
+ return {
1063
+ 'info': contract,
1064
+ 'symbol': this.safeString(market, 'symbol'),
1065
+ 'markPrice': undefined,
1066
+ 'indexPrice': undefined,
1067
+ 'interestRate': undefined,
1068
+ 'estimatedSettlePrice': undefined,
1069
+ 'timestamp': undefined,
1070
+ 'datetime': undefined,
1071
+ 'fundingRate': undefined,
1072
+ 'fundingTimestamp': undefined,
1073
+ 'fundingDatetime': undefined,
1074
+ 'nextFundingRate': this.safeNumber(contract, 'current_funding_rate'),
1075
+ 'nextFundingTimestamp': nextFundingTimestamp,
1076
+ 'nextFundingDatetime': this.iso8601(nextFundingTimestamp),
1077
+ 'previousFundingRate': undefined,
1078
+ 'previousFundingTimestamp': undefined,
1079
+ 'previousFundingDatetime': undefined,
1080
+ 'interval': undefined,
1081
+ };
1082
+ }
1026
1083
  sign(path, api = 'public', method = 'GET', params = {}, headers = undefined, body = undefined) {
1027
1084
  let request = '/' + this.version + '/';
1028
1085
  if (api === 'private') {
@@ -92,6 +92,8 @@ class bitget extends bitget$1 {
92
92
  'fetchLeverage': true,
93
93
  'fetchLeverageTiers': false,
94
94
  'fetchLiquidations': false,
95
+ 'fetchLongShortRatio': false,
96
+ 'fetchLongShortRatioHistory': true,
95
97
  'fetchMarginAdjustmentHistory': false,
96
98
  'fetchMarginMode': true,
97
99
  'fetchMarketLeverageTiers': true,
@@ -267,6 +269,7 @@ class bitget extends bitget$1 {
267
269
  'v2/mix/market/current-fund-rate': 1,
268
270
  'v2/mix/market/contracts': 1,
269
271
  'v2/mix/market/query-position-lever': 2,
272
+ 'v2/mix/market/account-long-short': 20,
270
273
  },
271
274
  },
272
275
  'margin': {
@@ -277,6 +280,7 @@ class bitget extends bitget$1 {
277
280
  'margin/v1/isolated/public/tierData': 2,
278
281
  'margin/v1/public/currencies': 1,
279
282
  'v2/margin/currencies': 2,
283
+ 'v2/margin/market/long-short-ratio': 20,
280
284
  },
281
285
  },
282
286
  'earn': {
@@ -439,6 +443,7 @@ class bitget extends bitget$1 {
439
443
  'v2/mix/order/orders-history': 2,
440
444
  'v2/mix/order/orders-plan-pending': 2,
441
445
  'v2/mix/order/orders-plan-history': 2,
446
+ 'v2/mix/market/position-long-short': 20,
442
447
  },
443
448
  'post': {
444
449
  'mix/v1/account/sub-account-contract-assets': 200,
@@ -8900,6 +8905,78 @@ class bitget extends bitget$1 {
8900
8905
  const first = this.safeDict(data, 0, {});
8901
8906
  return this.parseFundingRate(first, market);
8902
8907
  }
8908
+ async fetchLongShortRatioHistory(symbol = undefined, timeframe = undefined, since = undefined, limit = undefined, params = {}) {
8909
+ /**
8910
+ * @method
8911
+ * @name bitget#fetchLongShortRatioHistory
8912
+ * @description fetches the long short ratio history for a unified market symbol
8913
+ * @see https://www.bitget.com/api-doc/common/apidata/Margin-Ls-Ratio
8914
+ * @see https://www.bitget.com/api-doc/common/apidata/Account-Long-Short
8915
+ * @param {string} symbol unified symbol of the market to fetch the long short ratio for
8916
+ * @param {string} [timeframe] the period for the ratio
8917
+ * @param {int} [since] the earliest time in ms to fetch ratios for
8918
+ * @param {int} [limit] the maximum number of long short ratio structures to retrieve
8919
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
8920
+ * @returns {object[]} an array of [long short ratio structures]{@link https://docs.ccxt.com/#/?id=long-short-ratio-structure}
8921
+ */
8922
+ await this.loadMarkets();
8923
+ const market = this.market(symbol);
8924
+ const request = {
8925
+ 'symbol': market['id'],
8926
+ };
8927
+ if (timeframe !== undefined) {
8928
+ request['period'] = timeframe;
8929
+ }
8930
+ let response = undefined;
8931
+ if (market['swap'] || market['future']) {
8932
+ response = await this.publicMixGetV2MixMarketAccountLongShort(this.extend(request, params));
8933
+ //
8934
+ // {
8935
+ // "code": "00000",
8936
+ // "msg": "success",
8937
+ // "requestTime": 1729321233281,
8938
+ // "data": [
8939
+ // {
8940
+ // "longAccountRatio": "0.58",
8941
+ // "shortAccountRatio": "0.42",
8942
+ // "longShortAccountRatio": "0.0138",
8943
+ // "ts": "1729312200000"
8944
+ // },
8945
+ // ]
8946
+ // }
8947
+ //
8948
+ }
8949
+ else {
8950
+ response = await this.publicMarginGetV2MarginMarketLongShortRatio(this.extend(request, params));
8951
+ //
8952
+ // {
8953
+ // "code": "00000",
8954
+ // "msg": "success",
8955
+ // "requestTime": 1729306974712,
8956
+ // "data": [
8957
+ // {
8958
+ // "longShortRatio": "40.66",
8959
+ // "ts": "1729306800000"
8960
+ // },
8961
+ // ]
8962
+ // }
8963
+ //
8964
+ }
8965
+ const data = this.safeList(response, 'data', []);
8966
+ return this.parseLongShortRatioHistory(data, market);
8967
+ }
8968
+ parseLongShortRatio(info, market = undefined) {
8969
+ const marketId = this.safeString(info, 'symbol');
8970
+ const timestamp = this.safeIntegerOmitZero(info, 'ts');
8971
+ return {
8972
+ 'info': info,
8973
+ 'symbol': this.safeSymbol(marketId, market, undefined, 'contract'),
8974
+ 'timestamp': timestamp,
8975
+ 'datetime': this.iso8601(timestamp),
8976
+ 'timeframe': undefined,
8977
+ 'longShortRatio': this.safeNumber2(info, 'longShortRatio', 'longShortAccountRatio'),
8978
+ };
8979
+ }
8903
8980
  handleErrors(code, reason, url, method, headers, body, response, requestHeaders, requestBody) {
8904
8981
  if (!response) {
8905
8982
  return undefined; // fallback to default error handler
@@ -89,6 +89,8 @@ class bybit extends bybit$1 {
89
89
  'fetchLedger': true,
90
90
  'fetchLeverage': true,
91
91
  'fetchLeverageTiers': true,
92
+ 'fetchLongShortRatio': false,
93
+ 'fetchLongShortRatioHistory': true,
92
94
  'fetchMarginAdjustmentHistory': false,
93
95
  'fetchMarketLeverageTiers': true,
94
96
  'fetchMarkets': true,
@@ -368,6 +370,7 @@ class bybit extends bybit$1 {
368
370
  // spot leverage token
369
371
  'v5/spot-lever-token/order-record': 1,
370
372
  // spot margin trade
373
+ 'v5/spot-margin-trade/interest-rate-history': 5,
371
374
  'v5/spot-margin-trade/state': 5,
372
375
  'v5/spot-cross-margin-trade/loan-info': 1,
373
376
  'v5/spot-cross-margin-trade/account': 1,
@@ -7314,12 +7317,22 @@ class bybit extends bybit$1 {
7314
7317
  // "timestamp": 1666734490778
7315
7318
  // }
7316
7319
  //
7320
+ // fetchBorrowRateHistory
7321
+ // {
7322
+ // "timestamp": 1721469600000,
7323
+ // "currency": "USDC",
7324
+ // "hourlyBorrowRate": "0.000014621596",
7325
+ // "vipLevel": "No VIP"
7326
+ // }
7327
+ //
7317
7328
  const timestamp = this.safeInteger(info, 'timestamp');
7318
- const currencyId = this.safeString(info, 'coin');
7329
+ const currencyId = this.safeString2(info, 'coin', 'currency');
7330
+ const hourlyBorrowRate = this.safeNumber(info, 'hourlyBorrowRate');
7331
+ const period = (hourlyBorrowRate !== undefined) ? 3600000 : 86400000; // 1h or 1d
7319
7332
  return {
7320
7333
  'currency': this.safeCurrencyCode(currencyId, currency),
7321
- 'rate': this.safeNumber(info, 'interestRate'),
7322
- 'period': 86400000,
7334
+ 'rate': this.safeNumber(info, 'interestRate', hourlyBorrowRate),
7335
+ 'period': period,
7323
7336
  'timestamp': timestamp,
7324
7337
  'datetime': this.iso8601(timestamp),
7325
7338
  'info': info,
@@ -7371,6 +7384,57 @@ class bybit extends bybit$1 {
7371
7384
  const interest = this.parseBorrowInterests(rows, undefined);
7372
7385
  return this.filterByCurrencySinceLimit(interest, code, since, limit);
7373
7386
  }
7387
+ async fetchBorrowRateHistory(code, since = undefined, limit = undefined, params = {}) {
7388
+ /**
7389
+ * @method
7390
+ * @name bybit#fetchBorrowRateHistory
7391
+ * @description retrieves a history of a currencies borrow interest rate at specific time slots
7392
+ * @see https://bybit-exchange.github.io/docs/v5/spot-margin-uta/historical-interest
7393
+ * @param {string} code unified currency code
7394
+ * @param {int} [since] timestamp for the earliest borrow rate
7395
+ * @param {int} [limit] the maximum number of [borrow rate structures]{@link https://docs.ccxt.com/#/?id=borrow-rate-structure} to retrieve
7396
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
7397
+ * @param {int} [params.until] the latest time in ms to fetch entries for
7398
+ * @returns {object[]} an array of [borrow rate structures]{@link https://docs.ccxt.com/#/?id=borrow-rate-structure}
7399
+ */
7400
+ await this.loadMarkets();
7401
+ const currency = this.currency(code);
7402
+ const request = {
7403
+ 'currency': currency['id'],
7404
+ };
7405
+ if (since === undefined) {
7406
+ since = this.milliseconds() - 86400000 * 30; // last 30 days
7407
+ }
7408
+ request['startTime'] = since;
7409
+ let endTime = this.safeInteger2(params, 'until', 'endTime');
7410
+ params = this.omit(params, ['until']);
7411
+ if (endTime === undefined) {
7412
+ endTime = since + 86400000 * 30; // since + 30 days
7413
+ }
7414
+ request['endTime'] = endTime;
7415
+ const response = await this.privateGetV5SpotMarginTradeInterestRateHistory(this.extend(request, params));
7416
+ //
7417
+ // {
7418
+ // "retCode": 0,
7419
+ // "retMsg": "OK",
7420
+ // "result": {
7421
+ // "list": [
7422
+ // {
7423
+ // "timestamp": 1721469600000,
7424
+ // "currency": "USDC",
7425
+ // "hourlyBorrowRate": "0.000014621596",
7426
+ // "vipLevel": "No VIP"
7427
+ // }
7428
+ // ]
7429
+ // },
7430
+ // "retExtInfo": "{}",
7431
+ // "time": 1721899048991
7432
+ // }
7433
+ //
7434
+ const data = this.safeDict(response, 'result');
7435
+ const rows = this.safeList(data, 'list', []);
7436
+ return this.parseBorrowRateHistory(rows, code, since, limit);
7437
+ }
7374
7438
  parseBorrowInterest(info, market = undefined) {
7375
7439
  //
7376
7440
  // {
@@ -9245,6 +9309,82 @@ class bybit extends bybit$1 {
9245
9309
  'fee': undefined,
9246
9310
  };
9247
9311
  }
9312
+ async fetchLongShortRatioHistory(symbol = undefined, timeframe = undefined, since = undefined, limit = undefined, params = {}) {
9313
+ /**
9314
+ * @method
9315
+ * @name bybit#fetchLongShortRatioHistory
9316
+ * @description fetches the long short ratio history for a unified market symbol
9317
+ * @see https://bybit-exchange.github.io/docs/v5/market/long-short-ratio
9318
+ * @param {string} symbol unified symbol of the market to fetch the long short ratio for
9319
+ * @param {string} [timeframe] the period for the ratio, default is 24 hours
9320
+ * @param {int} [since] the earliest time in ms to fetch ratios for
9321
+ * @param {int} [limit] the maximum number of long short ratio structures to retrieve
9322
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
9323
+ * @returns {object[]} an array of [long short ratio structures]{@link https://docs.ccxt.com/#/?id=long-short-ratio-structure}
9324
+ */
9325
+ await this.loadMarkets();
9326
+ const market = this.market(symbol);
9327
+ let type = undefined;
9328
+ [type, params] = this.getBybitType('fetchLongShortRatioHistory', market, params);
9329
+ if (type === 'spot' || type === 'option') {
9330
+ throw new errors.NotSupported(this.id + ' fetchLongShortRatioHistory() only support linear and inverse markets');
9331
+ }
9332
+ if (timeframe === undefined) {
9333
+ timeframe = '1d';
9334
+ }
9335
+ const request = {
9336
+ 'symbol': market['id'],
9337
+ 'period': timeframe,
9338
+ 'category': type,
9339
+ };
9340
+ if (limit !== undefined) {
9341
+ request['limit'] = limit;
9342
+ }
9343
+ const response = await this.publicGetV5MarketAccountRatio(this.extend(request, params));
9344
+ //
9345
+ // {
9346
+ // "retCode": 0,
9347
+ // "retMsg": "OK",
9348
+ // "result": {
9349
+ // "list": [
9350
+ // {
9351
+ // "symbol": "BTCUSDT",
9352
+ // "buyRatio": "0.5707",
9353
+ // "sellRatio": "0.4293",
9354
+ // "timestamp": "1729123200000"
9355
+ // },
9356
+ // ]
9357
+ // },
9358
+ // "retExtInfo": {},
9359
+ // "time": 1729147842516
9360
+ // }
9361
+ //
9362
+ const result = this.safeDict(response, 'result', {});
9363
+ const data = this.safeList(result, 'list', []);
9364
+ return this.parseLongShortRatioHistory(data, market);
9365
+ }
9366
+ parseLongShortRatio(info, market = undefined) {
9367
+ //
9368
+ // {
9369
+ // "symbol": "BTCUSDT",
9370
+ // "buyRatio": "0.5707",
9371
+ // "sellRatio": "0.4293",
9372
+ // "timestamp": "1729123200000"
9373
+ // }
9374
+ //
9375
+ const marketId = this.safeString(info, 'symbol');
9376
+ const timestamp = this.safeIntegerOmitZero(info, 'timestamp');
9377
+ const longString = this.safeString(info, 'buyRatio');
9378
+ const shortString = this.safeString(info, 'sellRatio');
9379
+ return {
9380
+ 'info': info,
9381
+ 'symbol': this.safeSymbol(marketId, market, undefined, 'contract'),
9382
+ 'timestamp': timestamp,
9383
+ 'datetime': this.iso8601(timestamp),
9384
+ 'timeframe': undefined,
9385
+ 'longShortRatio': this.parseToNumeric(Precise["default"].stringDiv(longString, shortString)),
9386
+ };
9387
+ }
9248
9388
  sign(path, api = 'public', method = 'GET', params = {}, headers = undefined, body = undefined) {
9249
9389
  let url = this.implodeHostname(this.urls['api'][api]) + '/' + path;
9250
9390
  if (api === 'public') {