ccxt 4.3.94 → 4.3.96

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 (63) hide show
  1. package/README.md +4 -4
  2. package/dist/ccxt.browser.min.js +8 -8
  3. package/dist/cjs/ccxt.js +1 -7
  4. package/dist/cjs/src/ascendex.js +8 -6
  5. package/dist/cjs/src/base/Exchange.js +3 -7
  6. package/dist/cjs/src/bingx.js +2 -1
  7. package/dist/cjs/src/bitfinex.js +3 -2
  8. package/dist/cjs/src/bitfinex2.js +6 -5
  9. package/dist/cjs/src/blofin.js +0 -1
  10. package/dist/cjs/src/btcturk.js +2 -2
  11. package/dist/cjs/src/bybit.js +8 -2
  12. package/dist/cjs/src/gate.js +3 -2
  13. package/dist/cjs/src/gemini.js +3 -2
  14. package/dist/cjs/src/hyperliquid.js +337 -42
  15. package/dist/cjs/src/independentreserve.js +4 -3
  16. package/dist/cjs/src/indodax.js +3 -0
  17. package/dist/cjs/src/kucoin.js +12 -12
  18. package/dist/cjs/src/mexc.js +78 -154
  19. package/dist/cjs/src/okx.js +2 -1
  20. package/dist/cjs/src/p2b.js +0 -1
  21. package/dist/cjs/src/pro/binance.js +100 -2
  22. package/dist/cjs/src/pro/bybit.js +65 -4
  23. package/dist/cjs/src/pro/cryptocom.js +224 -0
  24. package/dist/cjs/src/pro/okx.js +264 -35
  25. package/dist/cjs/src/tradeogre.js +0 -1
  26. package/js/ccxt.d.ts +2 -8
  27. package/js/ccxt.js +2 -6
  28. package/js/src/abstract/okx.d.ts +2 -0
  29. package/js/src/ascendex.js +8 -6
  30. package/js/src/base/Exchange.d.ts +1 -3
  31. package/js/src/base/Exchange.js +3 -7
  32. package/js/src/bingx.js +2 -1
  33. package/js/src/bitfinex.js +3 -2
  34. package/js/src/bitfinex2.js +6 -5
  35. package/js/src/blofin.js +0 -1
  36. package/js/src/btcturk.d.ts +2 -2
  37. package/js/src/btcturk.js +2 -2
  38. package/js/src/bybit.js +8 -2
  39. package/js/src/gate.js +3 -2
  40. package/js/src/gemini.js +3 -2
  41. package/js/src/hyperliquid.d.ts +25 -0
  42. package/js/src/hyperliquid.js +337 -42
  43. package/js/src/independentreserve.js +4 -3
  44. package/js/src/indodax.js +3 -0
  45. package/js/src/kucoin.d.ts +1 -1
  46. package/js/src/kucoin.js +12 -12
  47. package/js/src/mexc.js +78 -154
  48. package/js/src/okx.js +2 -1
  49. package/js/src/p2b.js +0 -1
  50. package/js/src/pro/binance.d.ts +2 -0
  51. package/js/src/pro/binance.js +100 -2
  52. package/js/src/pro/bybit.d.ts +3 -1
  53. package/js/src/pro/bybit.js +65 -4
  54. package/js/src/pro/cryptocom.d.ts +10 -1
  55. package/js/src/pro/cryptocom.js +225 -1
  56. package/js/src/pro/okx.d.ts +10 -1
  57. package/js/src/pro/okx.js +264 -35
  58. package/js/src/tradeogre.js +0 -1
  59. package/package.json +1 -1
  60. package/js/src/abstract/bitbay.d.ts +0 -56
  61. package/js/src/abstract/bitbay.js +0 -11
  62. package/js/src/abstract/hitbtc3.d.ts +0 -118
  63. package/js/src/abstract/hitbtc3.js +0 -11
@@ -448,164 +448,82 @@ class mexc extends mexc$1 {
448
448
  'LTC': 'LTC',
449
449
  },
450
450
  'networks': {
451
- 'ABBC': 'ABBC',
451
+ 'TRC20': 'TRX',
452
+ 'TON': 'TONCOIN',
453
+ 'AVAXC': 'AVAX_CCHAIN',
454
+ 'ERC20': 'ETH',
452
455
  'ACA': 'ACALA',
453
- 'ADA': 'Cardano(ADA)',
454
- 'AE': 'AE',
455
- 'ALGO': 'Algorand(ALGO)',
456
- 'ALPH': 'Alephium(ALPH)',
457
- 'AME': 'AME',
458
- 'AOK': 'AOK',
459
- 'APT': 'APTOS(APT)',
460
- 'AR': 'AR',
461
- 'ARB': 'Arbitrum One(ARB)',
462
- 'ARBNOVA': 'ARBNOVA',
463
- 'ARBONE': 'ArbitrumOne(ARB)',
464
- 'ARK': 'ARK',
456
+ // 'ADA': 'Cardano(ADA)',
457
+ // 'AE': 'AE',
458
+ // 'ALGO': 'Algorand(ALGO)',
459
+ // 'ALPH': 'Alephium(ALPH)',
460
+ // 'ARB': 'Arbitrum One(ARB)',
461
+ // 'ARBONE': 'ArbitrumOne(ARB)',
465
462
  'ASTR': 'ASTAR',
466
- 'ATOM': 'Cosmos(ATOM)',
467
- 'AVAXC': 'Avalanche C Chain(AVAX CCHAIN)',
468
- 'AVAXX': 'Avalanche X Chain(AVAX XCHAIN)',
469
- 'AZERO': 'Aleph Zero(AZERO)',
470
- 'BCH': 'Bitcoin Cash(BCH)',
471
- 'BDX': 'BDX',
472
- 'BEAM': 'BEAM',
473
- 'BEP2': 'BNB Beacon Chain(BEP2)',
474
- 'BEP20': 'BNB Smart Chain(BEP20)',
475
- 'BITCI': 'BITCI',
476
- 'BNC': 'BNC',
477
- 'BNCDOT': 'BNCPOLKA',
478
- 'BOBA': 'BOBA',
479
- 'BSC': 'BEP20(BSC)',
480
- 'BSV': 'Bitcoin SV(BSV)',
481
- 'BTC': 'Bitcoin(BTC)',
463
+ // 'ATOM': 'Cosmos(ATOM)',
464
+ // 'AVAXC': 'Avalanche C Chain(AVAX CCHAIN)',
465
+ // 'AVAXX': 'Avalanche X Chain(AVAX XCHAIN)',
466
+ // 'AZERO': 'Aleph Zero(AZERO)',
467
+ // 'BCH': 'Bitcoin Cash(BCH)',
468
+ // 'BNCDOT': 'BNCPOLKA',
469
+ // 'BSV': 'Bitcoin SV(BSV)',
470
+ // 'BTC': 'Bitcoin(BTC)',
482
471
  'BTM': 'BTM2',
483
- 'CELO': 'CELO',
484
- 'CFX': 'CFX',
485
- 'CHZ': 'Chiliz Legacy Chain(CHZ)',
486
- 'CHZ2': 'Chiliz Chain(CHZ2)',
487
- 'CKB': 'CKB',
488
- 'CLORE': 'Clore.ai(CLORE)',
472
+ // 'CHZ': 'Chiliz Legacy Chain(CHZ)',
473
+ // 'CHZ2': 'Chiliz Chain(CHZ2)',
474
+ // 'CLORE': 'Clore.ai(CLORE)',
489
475
  'CRC20': 'CRONOS',
490
- 'CSPR': 'CSPR',
491
- 'DASH': 'DASH',
492
- 'DC': 'Dogechain(DC)',
493
- 'DCR': 'DCR',
494
- 'DNX': 'Dynex(DNX)',
495
- 'DOGE': 'Dogecoin(DOGE)',
496
- 'DOT': 'Polkadot(DOT)',
497
- 'DYM': 'Dymension(DYM)',
498
- 'EDG': 'EDG',
499
- 'EGLD': 'EGLD',
500
- 'EOS': 'EOS',
501
- 'ERC20': 'Ethereum(ERC20)',
502
- 'ETC': 'Ethereum Classic(ETC)',
476
+ // 'DC': 'Dogechain(DC)',
477
+ // 'DNX': 'Dynex(DNX)',
478
+ // 'DOGE': 'Dogecoin(DOGE)',
479
+ // 'DOT': 'Polkadot(DOT)',
480
+ // 'DYM': 'Dymension(DYM)',
503
481
  'ETHF': 'ETF',
504
- 'ETHW': 'ETHW',
505
- 'EVER': 'EVER',
506
- 'FET': 'FET',
507
- 'FIL': 'FIL',
508
- 'FIO': 'FIO',
509
- 'FLOW': 'FLOW',
510
- 'FSN': 'FSN',
511
- 'FTM': 'Fantom(FTM)',
512
- 'FUSE': 'FUSE',
513
- 'GLMR': 'GLMR',
514
- 'GRIN': 'GRIN',
515
- 'HBAR': 'Hedera(HBAR)',
516
- 'HIVE': 'HIVE',
517
482
  'HRC20': 'HECO',
518
- 'HYDRA': 'HYDRA',
519
- 'ICP': 'Internet Computer(ICP)',
520
- 'INDEX': 'Index Chain',
521
- 'IOST': 'IOST',
522
- 'IOTA': 'IOTA',
523
- 'IOTX': 'IOTX',
524
- 'IRIS': 'IRIS',
525
- 'KAR': 'KAR',
526
- 'KAS': 'Kaspa(KAS)',
527
- 'KAVA': 'KAVA',
528
- 'KDA': 'KDA',
529
- 'KILT': 'KILT',
530
- 'KLAY': 'Klaytn(KLAY)',
531
- 'KMA': 'KMA',
532
- 'KSM': 'KSM',
533
- 'LAT': 'LAT',
534
- 'LAVA': 'Elysium(LAVA)',
535
- 'LTC': 'Litecoin(LTC)',
536
- 'LUNA': 'Terra(LUNA)',
537
- 'MASS': 'MASS',
538
- 'MATIC': 'Polygon(MATIC)',
539
- 'MCOIN': 'Mcoin Network',
540
- 'METIS': 'METIS',
541
- 'MINA': 'MINA',
542
- 'MNT': 'Mantle(MNT)',
543
- 'MOVR': 'MOVR',
544
- 'MTRG': 'Meter(MTRG)',
545
- 'NAS': 'NAS',
546
- 'NEAR': 'NEAR Protocol(NEAR)',
547
- 'NEBL': 'NEBL',
548
- 'NEM': 'NEM',
549
- 'NEO': 'NEO',
550
- 'NEO3': 'NEO3',
551
- 'NEOXA': 'Neoxa Network',
552
- 'NULS': 'NULS',
483
+ // 'KLAY': 'Klaytn(KLAY)',
553
484
  'OASIS': 'ROSE',
554
- 'OASYS': 'OASYS',
555
485
  'OKC': 'OKT',
556
- 'OMN': 'Omega Network(OMN)',
557
- 'OMNI': 'OMNI',
558
- 'ONE': 'ONE',
559
- 'ONT': 'ONT',
560
- 'OPTIMISM': 'Optimism(OP)',
561
- 'OSMO': 'OSMO',
562
- 'PLCU': 'PLCU',
563
- 'POKT': 'POKT',
564
- 'QKC': 'QKC',
565
- 'QTUM': 'QTUM',
566
- 'RAP20': 'RAP20' + ' ' + '(Rangers Mainnet)',
567
- 'REI': 'REI',
568
486
  'RSK': 'RBTC',
569
- 'RVN': 'Ravencoin(RVN)',
570
- 'SATOX': 'Satoxcoin(SATOX)',
571
- 'SC': 'SC',
572
- 'SCRT': 'SCRT',
573
- 'SDN': 'SDN',
574
- 'SGB': 'SGB',
575
- 'SOL': 'Solana(SOL)',
576
- 'STAR': 'STAR',
577
- 'STARK': 'Starknet(STARK)',
578
- 'STEEM': 'STEEM',
579
- 'SYS': 'SYS',
580
- 'TAO': 'Bittensor(TAO)',
581
- 'TIA': 'Celestia(TIA)',
582
- 'TOMO': 'TOMO',
583
- 'TON': 'Toncoin(TON)',
584
- 'TRC10': 'TRC10',
585
- 'TRC20': 'Tron(TRC20)',
586
- 'UGAS': 'UGAS(Ultrain)',
587
- 'VET': 'VeChain(VET)',
588
- 'VEX': 'Vexanium(VEX)',
589
- 'VSYS': 'VSYS',
590
- 'WAVES': 'WAVES',
591
- 'WAX': 'WAX',
592
- 'WEMIX': 'WEMIX',
593
- 'XCH': 'Chia(XCH)',
594
- 'XDC': 'XDC',
595
- 'XEC': 'XEC',
596
- 'XLM': 'Stellar(XLM)',
597
- 'XMR': 'Monero(XMR)',
598
- 'XNA': 'Neurai(XNA)',
599
- 'XPR': 'XPR Network',
600
- 'XRD': 'XRD',
601
- 'XRP': 'Ripple(XRP)',
602
- 'XTZ': 'XTZ',
603
- 'XVG': 'XVG',
604
- 'XYM': 'XYM',
605
- 'ZEC': 'ZEC',
606
- 'ZEN': 'ZEN',
607
- 'ZIL': 'Zilliqa(ZIL)',
608
- 'ZTG': 'ZTG',
487
+ // 'RVN': 'Ravencoin(RVN)',
488
+ // 'SATOX': 'Satoxcoin(SATOX)',
489
+ // 'SC': 'SC',
490
+ // 'SCRT': 'SCRT',
491
+ // 'SDN': 'SDN',
492
+ // 'SGB': 'SGB',
493
+ // 'SOL': 'Solana(SOL)',
494
+ // 'STAR': 'STAR',
495
+ // 'STARK': 'Starknet(STARK)',
496
+ // 'STEEM': 'STEEM',
497
+ // 'SYS': 'SYS',
498
+ // 'TAO': 'Bittensor(TAO)',
499
+ // 'TIA': 'Celestia(TIA)',
500
+ // 'TOMO': 'TOMO',
501
+ // 'TON': 'Toncoin(TON)',
502
+ // 'TRC10': 'TRC10',
503
+ // 'TRC20': 'Tron(TRC20)',
504
+ // 'UGAS': 'UGAS(Ultrain)',
505
+ // 'VET': 'VeChain(VET)',
506
+ // 'VEX': 'Vexanium(VEX)',
507
+ // 'VSYS': 'VSYS',
508
+ // 'WAVES': 'WAVES',
509
+ // 'WAX': 'WAX',
510
+ // 'WEMIX': 'WEMIX',
511
+ // 'XCH': 'Chia(XCH)',
512
+ // 'XDC': 'XDC',
513
+ // 'XEC': 'XEC',
514
+ // 'XLM': 'Stellar(XLM)',
515
+ // 'XMR': 'Monero(XMR)',
516
+ // 'XNA': 'Neurai(XNA)',
517
+ // 'XPR': 'XPR Network',
518
+ // 'XRD': 'XRD',
519
+ // 'XRP': 'Ripple(XRP)',
520
+ // 'XTZ': 'XTZ',
521
+ // 'XVG': 'XVG',
522
+ // 'XYM': 'XYM',
523
+ // 'ZEC': 'ZEC',
524
+ // 'ZEN': 'ZEN',
525
+ // 'ZIL': 'Zilliqa(ZIL)',
526
+ // 'ZTG': 'ZTG',
609
527
  // todo: uncomment below after concensus
610
528
  // 'ALAYA': 'ATP',
611
529
  // 'ANDUSCHAIN': 'DEB',
@@ -879,6 +797,8 @@ class mexc extends mexc$1 {
879
797
  * @method
880
798
  * @name mexc#fetchStatus
881
799
  * @description the latest known information on the availability of the exchange API
800
+ * @see https://mexcdevelop.github.io/apidocs/spot_v3_en/#test-connectivity
801
+ * @see https://mexcdevelop.github.io/apidocs/contract_v1_en/#get-the-server-time
882
802
  * @param {object} [params] extra parameters specific to the exchange API endpoint
883
803
  * @returns {object} a [status structure]{@link https://docs.ccxt.com/#/?id=exchange-status-structure}
884
804
  */
@@ -916,6 +836,8 @@ class mexc extends mexc$1 {
916
836
  * @method
917
837
  * @name mexc#fetchTime
918
838
  * @description fetches the current integer timestamp in milliseconds from the exchange server
839
+ * @see https://mexcdevelop.github.io/apidocs/spot_v3_en/#check-server-time
840
+ * @see https://mexcdevelop.github.io/apidocs/contract_v1_en/#get-the-server-time
919
841
  * @param {object} [params] extra parameters specific to the exchange API endpoint
920
842
  * @returns {int} the current integer timestamp in milliseconds from the exchange server
921
843
  */
@@ -1008,7 +930,7 @@ class mexc extends mexc$1 {
1008
930
  const chains = this.safeValue(currency, 'networkList', []);
1009
931
  for (let j = 0; j < chains.length; j++) {
1010
932
  const chain = chains[j];
1011
- const networkId = this.safeString2(chain, 'network', 'netWork');
933
+ const networkId = this.safeString2(chain, 'netWork', 'network');
1012
934
  const network = this.networkIdToCode(networkId);
1013
935
  const isDepositEnabled = this.safeBool(chain, 'depositEnable', false);
1014
936
  const isWithdrawEnabled = this.safeBool(chain, 'withdrawEnable', false);
@@ -1087,6 +1009,8 @@ class mexc extends mexc$1 {
1087
1009
  * @method
1088
1010
  * @name mexc#fetchMarkets
1089
1011
  * @description retrieves data on all markets for mexc
1012
+ * @see https://mexcdevelop.github.io/apidocs/spot_v3_en/#exchange-information
1013
+ * @see https://mexcdevelop.github.io/apidocs/contract_v1_en/#get-the-contract-information
1090
1014
  * @param {object} [params] extra parameters specific to the exchange API endpoint
1091
1015
  * @returns {object[]} an array of objects representing market data
1092
1016
  */
@@ -4390,7 +4314,7 @@ class mexc extends mexc$1 {
4390
4314
  //
4391
4315
  const address = this.safeString(depositAddress, 'address');
4392
4316
  const currencyId = this.safeString(depositAddress, 'coin');
4393
- const networkId = this.safeString(depositAddress, 'network');
4317
+ const networkId = this.safeString(depositAddress, 'netWork');
4394
4318
  this.checkAddress(address);
4395
4319
  return {
4396
4320
  'currency': this.safeCurrencyCode(currencyId, currency),
@@ -5171,14 +5095,14 @@ class mexc extends mexc$1 {
5171
5095
  * @param {object} [params] extra parameters specific to the exchange API endpoint
5172
5096
  * @returns {object} a [transaction structure]{@link https://docs.ccxt.com/#/?id=transaction-structure}
5173
5097
  */
5098
+ await this.loadMarkets();
5099
+ const currency = this.currency(code);
5174
5100
  [tag, params] = this.handleWithdrawTagAndParams(tag, params);
5175
5101
  const networks = this.safeDict(this.options, 'networks', {});
5176
5102
  let network = this.safeString2(params, 'network', 'netWork'); // this line allows the user to specify either ERC20 or ETH
5177
5103
  network = this.safeString(networks, network, network); // handle ETH > ERC-20 alias
5178
- network = this.networkIdToCode(network);
5104
+ network = this.networkCodeToId(network, currency['code']);
5179
5105
  this.checkAddress(address);
5180
- await this.loadMarkets();
5181
- const currency = this.currency(code);
5182
5106
  const request = {
5183
5107
  'coin': currency['id'],
5184
5108
  'address': address,
@@ -109,7 +109,6 @@ class okx extends okx$1 {
109
109
  'fetchOrderBooks': false,
110
110
  'fetchOrders': false,
111
111
  'fetchOrderTrades': true,
112
- 'fetchPermissions': undefined,
113
112
  'fetchPosition': true,
114
113
  'fetchPositionHistory': 'emulated',
115
114
  'fetchPositions': true,
@@ -324,6 +323,7 @@ class okx extends okx$1 {
324
323
  'account/account-position-risk': 2,
325
324
  'account/bills': 5 / 3,
326
325
  'account/bills-archive': 5 / 3,
326
+ 'account/bills-history-archive': 2,
327
327
  'account/config': 4,
328
328
  'account/max-size': 1,
329
329
  'account/max-avail-size': 1,
@@ -478,6 +478,7 @@ class okx extends okx$1 {
478
478
  'account/fixed-loan/amend-borrowing-order': 5,
479
479
  'account/fixed-loan/manual-reborrow': 5,
480
480
  'account/fixed-loan/repay-borrowing-order': 5,
481
+ 'account/bills-history-archive': 72000,
481
482
  // subaccount
482
483
  'users/subaccount/modify-apikey': 10,
483
484
  'asset/subaccount/transfer': 10,
@@ -77,7 +77,6 @@ class p2b extends p2b$1 {
77
77
  'fetchOrderBooks': false,
78
78
  'fetchOrders': true,
79
79
  'fetchOrderTrades': true,
80
- 'fetchPermissions': false,
81
80
  'fetchPosition': false,
82
81
  'fetchPositionHistory': false,
83
82
  'fetchPositionMode': false,
@@ -1032,14 +1032,25 @@ class binance extends binance$1 {
1032
1032
  const error = new errors.UnsubscribeError(this.id + ' ' + subHash);
1033
1033
  client.reject(error, subHash);
1034
1034
  client.resolve(true, unsubHash);
1035
- this.cleanCache(subscription);
1036
1035
  }
1036
+ this.cleanCache(subscription);
1037
1037
  }
1038
1038
  cleanCache(subscription) {
1039
1039
  const topic = this.safeString(subscription, 'topic');
1040
1040
  const symbols = this.safeList(subscription, 'symbols', []);
1041
1041
  const symbolsLength = symbols.length;
1042
- if (symbolsLength > 0) {
1042
+ if (topic === 'ohlcv') {
1043
+ const symbolsAndTimeFrames = this.safeList(subscription, 'symbolsAndTimeframes', []);
1044
+ for (let i = 0; i < symbolsAndTimeFrames.length; i++) {
1045
+ const symbolAndTimeFrame = symbolsAndTimeFrames[i];
1046
+ const symbol = this.safeString(symbolAndTimeFrame, 0);
1047
+ const timeframe = this.safeString(symbolAndTimeFrame, 1);
1048
+ if (timeframe in this.ohlcvs[symbol]) {
1049
+ delete this.ohlcvs[symbol][timeframe];
1050
+ }
1051
+ }
1052
+ }
1053
+ else if (symbolsLength > 0) {
1043
1054
  for (let i = 0; i < symbols.length; i++) {
1044
1055
  const symbol = symbols[i];
1045
1056
  if (topic === 'trade') {
@@ -1507,6 +1518,93 @@ class binance extends binance$1 {
1507
1518
  const filtered = this.filterBySinceLimit(candles, since, limit, 0, true);
1508
1519
  return this.createOHLCVObject(symbol, timeframe, filtered);
1509
1520
  }
1521
+ async unWatchOHLCVForSymbols(symbolsAndTimeframes, params = {}) {
1522
+ /**
1523
+ * @method
1524
+ * @name binance#unWatchOHLCVForSymbols
1525
+ * @description unWatches historical candlestick data containing the open, high, low, and close price, and the volume of a market
1526
+ * @see https://binance-docs.github.io/apidocs/spot/en/#kline-candlestick-data
1527
+ * @see https://binance-docs.github.io/apidocs/futures/en/#kline-candlestick-data
1528
+ * @see https://binance-docs.github.io/apidocs/delivery/en/#kline-candlestick-data
1529
+ * @param {string[][]} symbolsAndTimeframes array of arrays containing unified symbols and timeframes to fetch OHLCV data for, example [['BTC/USDT', '1m'], ['LTC/USDT', '5m']]
1530
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
1531
+ * @param {object} [params.timezone] if provided, kline intervals are interpreted in that timezone instead of UTC, example '+08:00'
1532
+ * @returns {int[][]} A list of candles ordered as timestamp, open, high, low, close, volume
1533
+ */
1534
+ await this.loadMarkets();
1535
+ let klineType = undefined;
1536
+ [klineType, params] = this.handleParamString2(params, 'channel', 'name', 'kline');
1537
+ const symbols = this.getListFromObjectValues(symbolsAndTimeframes, 0);
1538
+ const marketSymbols = this.marketSymbols(symbols, undefined, false, false, true);
1539
+ const firstMarket = this.market(marketSymbols[0]);
1540
+ let type = firstMarket['type'];
1541
+ if (firstMarket['contract']) {
1542
+ type = firstMarket['linear'] ? 'future' : 'delivery';
1543
+ }
1544
+ const isSpot = (type === 'spot');
1545
+ let timezone = undefined;
1546
+ [timezone, params] = this.handleParamString(params, 'timezone', undefined);
1547
+ const isUtc8 = (timezone !== undefined) && ((timezone === '+08:00') || Precise["default"].stringEq(timezone, '8'));
1548
+ const rawHashes = [];
1549
+ const subMessageHashes = [];
1550
+ const messageHashes = [];
1551
+ for (let i = 0; i < symbolsAndTimeframes.length; i++) {
1552
+ const symAndTf = symbolsAndTimeframes[i];
1553
+ const symbolString = symAndTf[0];
1554
+ const timeframeString = symAndTf[1];
1555
+ const interval = this.safeString(this.timeframes, timeframeString, timeframeString);
1556
+ const market = this.market(symbolString);
1557
+ let marketId = market['lowercaseId'];
1558
+ if (klineType === 'indexPriceKline') {
1559
+ // weird behavior for index price kline we can't use the perp suffix
1560
+ marketId = marketId.replace('_perp', '');
1561
+ }
1562
+ const shouldUseUTC8 = (isUtc8 && isSpot);
1563
+ const suffix = '@+08:00';
1564
+ const utcSuffix = shouldUseUTC8 ? suffix : '';
1565
+ rawHashes.push(marketId + '@' + klineType + '_' + interval + utcSuffix);
1566
+ subMessageHashes.push('ohlcv::' + market['symbol'] + '::' + timeframeString);
1567
+ messageHashes.push('unsubscribe::ohlcv::' + market['symbol'] + '::' + timeframeString);
1568
+ }
1569
+ const url = this.urls['api']['ws'][type] + '/' + this.stream(type, 'multipleOHLCV');
1570
+ const requestId = this.requestId(url);
1571
+ const request = {
1572
+ 'method': 'UNSUBSCRIBE',
1573
+ 'params': rawHashes,
1574
+ 'id': requestId,
1575
+ };
1576
+ const subscribe = {
1577
+ 'unsubscribe': true,
1578
+ 'id': requestId.toString(),
1579
+ 'symbols': symbols,
1580
+ 'symbolsAndTimeframes': symbolsAndTimeframes,
1581
+ 'subMessageHashes': subMessageHashes,
1582
+ 'messageHashes': messageHashes,
1583
+ 'topic': 'ohlcv',
1584
+ };
1585
+ params = this.omit(params, 'callerMethodName');
1586
+ return await this.watchMultiple(url, messageHashes, this.extend(request, params), messageHashes, subscribe);
1587
+ }
1588
+ async unWatchOHLCV(symbol, timeframe = '1m', params = {}) {
1589
+ /**
1590
+ * @method
1591
+ * @name binance#unWatchOHLCV
1592
+ * @description unWatches historical candlestick data containing the open, high, low, and close price, and the volume of a market
1593
+ * @see https://binance-docs.github.io/apidocs/spot/en/#kline-candlestick-data
1594
+ * @see https://binance-docs.github.io/apidocs/futures/en/#kline-candlestick-data
1595
+ * @see https://binance-docs.github.io/apidocs/delivery/en/#kline-candlestick-data
1596
+ * @param {string} symbol unified symbol of the market to fetch OHLCV data for
1597
+ * @param {string} timeframe the length of time each candle represents
1598
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
1599
+ * @param {object} [params.timezone] if provided, kline intervals are interpreted in that timezone instead of UTC, example '+08:00'
1600
+ * @returns {int[][]} A list of candles ordered as timestamp, open, high, low, close, volume
1601
+ */
1602
+ await this.loadMarkets();
1603
+ const market = this.market(symbol);
1604
+ symbol = market['symbol'];
1605
+ params['callerMethodName'] = 'watchOHLCV';
1606
+ return await this.unWatchOHLCVForSymbols([[symbol, timeframe]], params);
1607
+ }
1510
1608
  handleOHLCV(client, message) {
1511
1609
  //
1512
1610
  // {
@@ -633,6 +633,58 @@ class bybit extends bybit$1 {
633
633
  const filtered = this.filterBySinceLimit(stored, since, limit, 0, true);
634
634
  return this.createOHLCVObject(symbol, timeframe, filtered);
635
635
  }
636
+ async unWatchOHLCVForSymbols(symbolsAndTimeframes, params = {}) {
637
+ /**
638
+ * @method
639
+ * @name bybit#unWatchOHLCVForSymbols
640
+ * @description unWatches historical candlestick data containing the open, high, low, and close price, and the volume of a market
641
+ * @see https://bybit-exchange.github.io/docs/v5/websocket/public/kline
642
+ * @see https://bybit-exchange.github.io/docs/v5/websocket/public/etp-kline
643
+ * @param {string[][]} symbolsAndTimeframes array of arrays containing unified symbols and timeframes to fetch OHLCV data for, example [['BTC/USDT', '1m'], ['LTC/USDT', '5m']]
644
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
645
+ * @returns {object} A list of candles ordered as timestamp, open, high, low, close, volume
646
+ */
647
+ await this.loadMarkets();
648
+ const symbols = this.getListFromObjectValues(symbolsAndTimeframes, 0);
649
+ const marketSymbols = this.marketSymbols(symbols, undefined, false, true, true);
650
+ const firstSymbol = marketSymbols[0];
651
+ const url = await this.getUrlByMarketType(firstSymbol, false, 'watchOHLCVForSymbols', params);
652
+ const rawHashes = [];
653
+ const subMessageHashes = [];
654
+ const messageHashes = [];
655
+ for (let i = 0; i < symbolsAndTimeframes.length; i++) {
656
+ const data = symbolsAndTimeframes[i];
657
+ let symbolString = this.safeString(data, 0);
658
+ const market = this.market(symbolString);
659
+ symbolString = market['symbol'];
660
+ const unfiedTimeframe = this.safeString(data, 1);
661
+ const timeframeId = this.safeString(this.timeframes, unfiedTimeframe, unfiedTimeframe);
662
+ rawHashes.push('kline.' + timeframeId + '.' + market['id']);
663
+ subMessageHashes.push('ohlcv::' + symbolString + '::' + unfiedTimeframe);
664
+ messageHashes.push('unsubscribe::ohlcv::' + symbolString + '::' + unfiedTimeframe);
665
+ }
666
+ const subExtension = {
667
+ 'symbolsAndTimeframes': symbolsAndTimeframes,
668
+ };
669
+ return await this.unWatchTopics(url, 'ohlcv', symbols, messageHashes, subMessageHashes, rawHashes, params, subExtension);
670
+ }
671
+ async unWatchOHLCV(symbol, timeframe = '1m', params = {}) {
672
+ /**
673
+ * @method
674
+ * @name bybit#unWatchOHLCV
675
+ * @description unWatches historical candlestick data containing the open, high, low, and close price, and the volume of a market
676
+ * @see https://bybit-exchange.github.io/docs/v5/websocket/public/kline
677
+ * @see https://bybit-exchange.github.io/docs/v5/websocket/public/etp-kline
678
+ * @param {string} symbol unified symbol of the market to fetch OHLCV data for
679
+ * @param {string} timeframe the length of time each candle represents
680
+ * @param {int} [since] timestamp in ms of the earliest candle to fetch
681
+ * @param {int} [limit] the maximum amount of candles to fetch
682
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
683
+ * @returns {int[][]} A list of candles ordered as timestamp, open, high, low, close, volume
684
+ */
685
+ params['callerMethodName'] = 'watchOHLCV';
686
+ return await this.unWatchOHLCVForSymbols([[symbol, timeframe]], params);
687
+ }
636
688
  handleOHLCV(client, message) {
637
689
  //
638
690
  // {
@@ -2142,7 +2194,7 @@ class bybit extends bybit$1 {
2142
2194
  const message = this.extend(request, params);
2143
2195
  return await this.watchMultiple(url, messageHashes, message, messageHashes);
2144
2196
  }
2145
- async unWatchTopics(url, topic, symbols, messageHashes, subMessageHashes, topics, params = {}) {
2197
+ async unWatchTopics(url, topic, symbols, messageHashes, subMessageHashes, topics, params = {}, subExtension = {}) {
2146
2198
  const reqId = this.requestId();
2147
2199
  const request = {
2148
2200
  'op': 'unsubscribe',
@@ -2157,7 +2209,7 @@ class bybit extends bybit$1 {
2157
2209
  'symbols': symbols,
2158
2210
  };
2159
2211
  const message = this.extend(request, params);
2160
- return await this.watchMultiple(url, messageHashes, message, messageHashes, subscription);
2212
+ return await this.watchMultiple(url, messageHashes, message, messageHashes, this.extend(subscription, subExtension));
2161
2213
  }
2162
2214
  async authenticate(url, params = {}) {
2163
2215
  this.checkRequiredCredentials();
@@ -2440,8 +2492,8 @@ class bybit extends bybit$1 {
2440
2492
  const error = new errors.UnsubscribeError(this.id + ' ' + messageHash);
2441
2493
  client.reject(error, subHash);
2442
2494
  client.resolve(true, unsubHash);
2443
- this.cleanCache(subscription);
2444
2495
  }
2496
+ this.cleanCache(subscription);
2445
2497
  }
2446
2498
  }
2447
2499
  return message;
@@ -2450,7 +2502,16 @@ class bybit extends bybit$1 {
2450
2502
  const topic = this.safeString(subscription, 'topic');
2451
2503
  const symbols = this.safeList(subscription, 'symbols', []);
2452
2504
  const symbolsLength = symbols.length;
2453
- if (symbolsLength > 0) {
2505
+ if (topic === 'ohlcv') {
2506
+ const symbolsAndTimeFrames = this.safeList(subscription, 'symbolsAndTimeframes', []);
2507
+ for (let i = 0; i < symbolsAndTimeFrames.length; i++) {
2508
+ const symbolAndTimeFrame = symbolsAndTimeFrames[i];
2509
+ const symbol = this.safeString(symbolAndTimeFrame, 0);
2510
+ const timeframe = this.safeString(symbolAndTimeFrame, 1);
2511
+ delete this.ohlcvs[symbol][timeframe];
2512
+ }
2513
+ }
2514
+ else if (symbolsLength > 0) {
2454
2515
  for (let i = 0; i < symbols.length; i++) {
2455
2516
  const symbol = symbols[i];
2456
2517
  if (topic === 'trade') {