ccxt 4.2.83 → 4.2.85

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 (166) hide show
  1. package/README.md +3 -3
  2. package/build.sh +1 -1
  3. package/dist/ccxt.browser.js +896 -941
  4. package/dist/ccxt.browser.min.js +4 -4
  5. package/dist/cjs/ccxt.js +1 -1
  6. package/dist/cjs/src/ace.js +5 -5
  7. package/dist/cjs/src/ascendex.js +8 -8
  8. package/dist/cjs/src/base/Exchange.js +76 -14
  9. package/dist/cjs/src/bigone.js +12 -12
  10. package/dist/cjs/src/binance.js +23 -35
  11. package/dist/cjs/src/bingx.js +13 -9
  12. package/dist/cjs/src/bit2c.js +1 -1
  13. package/dist/cjs/src/bitbank.js +8 -8
  14. package/dist/cjs/src/bitbns.js +5 -5
  15. package/dist/cjs/src/bitfinex.js +1 -1
  16. package/dist/cjs/src/bitfinex2.js +1 -1
  17. package/dist/cjs/src/bitget.js +40 -28
  18. package/dist/cjs/src/bithumb.js +5 -5
  19. package/dist/cjs/src/bitmart.js +16 -16
  20. package/dist/cjs/src/bitopro.js +1 -1
  21. package/dist/cjs/src/bitrue.js +4 -4
  22. package/dist/cjs/src/bitso.js +5 -5
  23. package/dist/cjs/src/bitstamp.js +1 -1
  24. package/dist/cjs/src/bitteam.js +8 -8
  25. package/dist/cjs/src/bl3p.js +1 -1
  26. package/dist/cjs/src/btcturk.js +6 -6
  27. package/dist/cjs/src/bybit.js +34 -98
  28. package/dist/cjs/src/coincheck.js +4 -4
  29. package/dist/cjs/src/coinex.js +12 -13
  30. package/dist/cjs/src/coinlist.js +7 -7
  31. package/dist/cjs/src/coinmate.js +4 -4
  32. package/dist/cjs/src/coinmetro.js +3 -3
  33. package/dist/cjs/src/coinone.js +5 -5
  34. package/dist/cjs/src/coinspot.js +2 -2
  35. package/dist/cjs/src/cryptocom.js +17 -17
  36. package/dist/cjs/src/currencycom.js +1 -1
  37. package/dist/cjs/src/delta.js +0 -8
  38. package/dist/cjs/src/deribit.js +16 -92
  39. package/dist/cjs/src/digifinex.js +8 -8
  40. package/dist/cjs/src/exmo.js +8 -8
  41. package/dist/cjs/src/gate.js +0 -8
  42. package/dist/cjs/src/hitbtc.js +5 -4
  43. package/dist/cjs/src/hollaex.js +7 -7
  44. package/dist/cjs/src/htx.js +12 -34
  45. package/dist/cjs/src/huobijp.js +3 -3
  46. package/dist/cjs/src/idex.js +2 -2
  47. package/dist/cjs/src/independentreserve.js +2 -2
  48. package/dist/cjs/src/indodax.js +2 -2
  49. package/dist/cjs/src/kraken.js +8 -8
  50. package/dist/cjs/src/krakenfutures.js +6 -6
  51. package/dist/cjs/src/kucoin.js +15 -2
  52. package/dist/cjs/src/kucoinfutures.js +8 -8
  53. package/dist/cjs/src/kuna.js +16 -16
  54. package/dist/cjs/src/latoken.js +2 -2
  55. package/dist/cjs/src/lbank.js +10 -10
  56. package/dist/cjs/src/luno.js +4 -4
  57. package/dist/cjs/src/mercado.js +5 -5
  58. package/dist/cjs/src/mexc.js +6 -6
  59. package/dist/cjs/src/ndax.js +1 -1
  60. package/dist/cjs/src/novadax.js +9 -9
  61. package/dist/cjs/src/oceanex.js +7 -7
  62. package/dist/cjs/src/okcoin.js +13 -13
  63. package/dist/cjs/src/okx.js +23 -31
  64. package/dist/cjs/src/onetrading.js +4 -4
  65. package/dist/cjs/src/p2b.js +7 -7
  66. package/dist/cjs/src/phemex.js +12 -12
  67. package/dist/cjs/src/poloniexfutures.js +5 -5
  68. package/dist/cjs/src/pro/binance.js +167 -121
  69. package/dist/cjs/src/pro/kucoin.js +6 -7
  70. package/dist/cjs/src/pro/okx.js +19 -2
  71. package/dist/cjs/src/probit.js +11 -11
  72. package/dist/cjs/src/timex.js +7 -7
  73. package/dist/cjs/src/tokocrypto.js +9 -9
  74. package/dist/cjs/src/wavesexchange.js +3 -3
  75. package/dist/cjs/src/whitebit.js +5 -5
  76. package/dist/cjs/src/woo.js +1 -1
  77. package/dist/cjs/src/zaif.js +1 -1
  78. package/dist/cjs/src/zonda.js +7 -7
  79. package/examples/js/cli.js +0 -1
  80. package/examples/ts/cli.ts +0 -1
  81. package/js/ccxt.d.ts +1 -1
  82. package/js/ccxt.js +1 -1
  83. package/js/src/ace.js +5 -5
  84. package/js/src/ascendex.js +8 -8
  85. package/js/src/base/Exchange.d.ts +4 -3
  86. package/js/src/base/Exchange.js +76 -14
  87. package/js/src/bigone.js +12 -12
  88. package/js/src/binance.d.ts +0 -1
  89. package/js/src/binance.js +23 -35
  90. package/js/src/bingx.js +13 -9
  91. package/js/src/bit2c.js +1 -1
  92. package/js/src/bitbank.js +8 -8
  93. package/js/src/bitbns.js +5 -5
  94. package/js/src/bitfinex.js +1 -1
  95. package/js/src/bitfinex2.js +1 -1
  96. package/js/src/bitget.js +40 -28
  97. package/js/src/bithumb.js +5 -5
  98. package/js/src/bitmart.js +16 -16
  99. package/js/src/bitopro.js +1 -1
  100. package/js/src/bitrue.js +4 -4
  101. package/js/src/bitso.js +5 -5
  102. package/js/src/bitstamp.js +1 -1
  103. package/js/src/bitteam.js +8 -8
  104. package/js/src/bl3p.js +1 -1
  105. package/js/src/btcturk.js +6 -6
  106. package/js/src/bybit.d.ts +0 -3
  107. package/js/src/bybit.js +34 -98
  108. package/js/src/coincheck.js +4 -4
  109. package/js/src/coinex.js +12 -13
  110. package/js/src/coinlist.js +7 -7
  111. package/js/src/coinmate.js +4 -4
  112. package/js/src/coinmetro.js +3 -3
  113. package/js/src/coinone.js +5 -5
  114. package/js/src/coinspot.js +2 -2
  115. package/js/src/cryptocom.js +17 -17
  116. package/js/src/currencycom.js +1 -1
  117. package/js/src/delta.d.ts +0 -1
  118. package/js/src/delta.js +0 -8
  119. package/js/src/deribit.d.ts +0 -3
  120. package/js/src/deribit.js +16 -92
  121. package/js/src/digifinex.js +8 -8
  122. package/js/src/exmo.js +8 -8
  123. package/js/src/gate.d.ts +0 -1
  124. package/js/src/gate.js +0 -8
  125. package/js/src/hitbtc.js +5 -4
  126. package/js/src/hollaex.js +7 -7
  127. package/js/src/htx.js +12 -34
  128. package/js/src/huobijp.js +3 -3
  129. package/js/src/idex.js +2 -2
  130. package/js/src/independentreserve.js +2 -2
  131. package/js/src/indodax.js +2 -2
  132. package/js/src/kraken.js +8 -8
  133. package/js/src/krakenfutures.js +6 -6
  134. package/js/src/kucoin.d.ts +1 -0
  135. package/js/src/kucoin.js +16 -3
  136. package/js/src/kucoinfutures.js +8 -8
  137. package/js/src/kuna.js +16 -16
  138. package/js/src/latoken.js +2 -2
  139. package/js/src/lbank.js +10 -10
  140. package/js/src/luno.js +4 -4
  141. package/js/src/mercado.js +5 -5
  142. package/js/src/mexc.js +6 -6
  143. package/js/src/ndax.js +1 -1
  144. package/js/src/novadax.js +9 -9
  145. package/js/src/oceanex.js +7 -7
  146. package/js/src/okcoin.js +13 -13
  147. package/js/src/okx.d.ts +0 -1
  148. package/js/src/okx.js +23 -31
  149. package/js/src/onetrading.js +4 -4
  150. package/js/src/p2b.js +7 -7
  151. package/js/src/phemex.js +12 -12
  152. package/js/src/poloniexfutures.js +5 -5
  153. package/js/src/pro/binance.d.ts +5 -1
  154. package/js/src/pro/binance.js +168 -122
  155. package/js/src/pro/kucoin.js +6 -7
  156. package/js/src/pro/okx.js +19 -2
  157. package/js/src/probit.js +11 -11
  158. package/js/src/static_dependencies/jsencrypt/lib/jsbn/jsbn.d.ts +1 -1
  159. package/js/src/timex.js +7 -7
  160. package/js/src/tokocrypto.js +9 -9
  161. package/js/src/wavesexchange.js +3 -3
  162. package/js/src/whitebit.js +5 -5
  163. package/js/src/woo.js +1 -1
  164. package/js/src/zaif.js +1 -1
  165. package/js/src/zonda.js +7 -7
  166. package/package.json +1 -1
package/js/src/phemex.js CHANGED
@@ -1298,7 +1298,7 @@ export default class phemex extends Exchange {
1298
1298
  // }
1299
1299
  //
1300
1300
  const data = this.safeValue(response, 'data', {});
1301
- const rows = this.safeValue(data, 'rows', []);
1301
+ const rows = this.safeList(data, 'rows', []);
1302
1302
  return this.parseOHLCVs(rows, market, timeframe, since, userLimit);
1303
1303
  }
1304
1304
  parseTicker(ticker, market = undefined) {
@@ -1461,7 +1461,7 @@ export default class phemex extends Exchange {
1461
1461
  // }
1462
1462
  // }
1463
1463
  //
1464
- const result = this.safeValue(response, 'result', {});
1464
+ const result = this.safeDict(response, 'result', {});
1465
1465
  return this.parseTicker(result, market);
1466
1466
  }
1467
1467
  async fetchTickers(symbols = undefined, params = {}) {
@@ -1497,7 +1497,7 @@ export default class phemex extends Exchange {
1497
1497
  else {
1498
1498
  response = await this.v2GetMdV2Ticker24hrAll(query);
1499
1499
  }
1500
- const result = this.safeValue(response, 'result', []);
1500
+ const result = this.safeList(response, 'result', []);
1501
1501
  return this.parseTickers(result, symbols);
1502
1502
  }
1503
1503
  async fetchTrades(symbol, since = undefined, limit = undefined, params = {}) {
@@ -2726,7 +2726,7 @@ export default class phemex extends Exchange {
2726
2726
  // }
2727
2727
  // }
2728
2728
  //
2729
- const data = this.safeValue(response, 'data', {});
2729
+ const data = this.safeDict(response, 'data', {});
2730
2730
  return this.parseOrder(data, market);
2731
2731
  }
2732
2732
  async editOrder(id, symbol, type = undefined, side = undefined, amount = undefined, price = undefined, params = {}) {
@@ -2805,7 +2805,7 @@ export default class phemex extends Exchange {
2805
2805
  else {
2806
2806
  response = await this.privatePutSpotOrders(this.extend(request, params));
2807
2807
  }
2808
- const data = this.safeValue(response, 'data', {});
2808
+ const data = this.safeDict(response, 'data', {});
2809
2809
  return this.parseOrder(data, market);
2810
2810
  }
2811
2811
  async cancelOrder(id, symbol = undefined, params = {}) {
@@ -2850,7 +2850,7 @@ export default class phemex extends Exchange {
2850
2850
  else {
2851
2851
  response = await this.privateDeleteSpotOrders(this.extend(request, params));
2852
2852
  }
2853
- const data = this.safeValue(response, 'data', {});
2853
+ const data = this.safeDict(response, 'data', {});
2854
2854
  return this.parseOrder(data, market);
2855
2855
  }
2856
2856
  async cancelAllOrders(symbol = undefined, params = {}) {
@@ -2974,7 +2974,7 @@ export default class phemex extends Exchange {
2974
2974
  response = await this.privateGetSpotOrders(this.extend(request, params));
2975
2975
  }
2976
2976
  const data = this.safeValue(response, 'data', {});
2977
- const rows = this.safeValue(data, 'rows', data);
2977
+ const rows = this.safeList(data, 'rows', data);
2978
2978
  return this.parseOrders(rows, market, since, limit);
2979
2979
  }
2980
2980
  async fetchOpenOrders(symbol = undefined, since = undefined, limit = undefined, params = {}) {
@@ -3023,7 +3023,7 @@ export default class phemex extends Exchange {
3023
3023
  return this.parseOrders(data, market, since, limit);
3024
3024
  }
3025
3025
  else {
3026
- const rows = this.safeValue(data, 'rows', []);
3026
+ const rows = this.safeList(data, 'rows', []);
3027
3027
  return this.parseOrders(rows, market, since, limit);
3028
3028
  }
3029
3029
  }
@@ -3110,7 +3110,7 @@ export default class phemex extends Exchange {
3110
3110
  return this.parseOrders(data, market, since, limit);
3111
3111
  }
3112
3112
  else {
3113
- const rows = this.safeValue(data, 'rows', []);
3113
+ const rows = this.safeList(data, 'rows', []);
3114
3114
  return this.parseOrders(rows, market, since, limit);
3115
3115
  }
3116
3116
  }
@@ -4231,7 +4231,7 @@ export default class phemex extends Exchange {
4231
4231
  //
4232
4232
  //
4233
4233
  const data = this.safeValue(response, 'data', {});
4234
- const riskLimits = this.safeValue(data, 'riskLimits');
4234
+ const riskLimits = this.safeList(data, 'riskLimits');
4235
4235
  return this.parseLeverageTiers(riskLimits, symbols, 'symbol');
4236
4236
  }
4237
4237
  parseMarketLeverageTiers(info, market = undefined) {
@@ -4493,7 +4493,7 @@ export default class phemex extends Exchange {
4493
4493
  // }
4494
4494
  //
4495
4495
  const data = this.safeValue(response, 'data', {});
4496
- const transfers = this.safeValue(data, 'rows', []);
4496
+ const transfers = this.safeList(data, 'rows', []);
4497
4497
  return this.parseTransfers(transfers, currency, since, limit);
4498
4498
  }
4499
4499
  parseTransfer(transfer, currency = undefined) {
@@ -4716,7 +4716,7 @@ export default class phemex extends Exchange {
4716
4716
  // }
4717
4717
  // }
4718
4718
  //
4719
- const data = this.safeValue(response, 'data', {});
4719
+ const data = this.safeDict(response, 'data', {});
4720
4720
  return this.parseTransaction(data, currency);
4721
4721
  }
4722
4722
  handleErrors(httpCode, reason, url, method, headers, body, response, requestHeaders, requestBody) {
@@ -679,7 +679,7 @@ export default class poloniexfutures extends Exchange {
679
679
  // },
680
680
  // }
681
681
  //
682
- const trades = this.safeValue(response, 'data', []);
682
+ const trades = this.safeList(response, 'data', []);
683
683
  return this.parseTrades(trades, market, since, limit);
684
684
  }
685
685
  async fetchTime(params = {}) {
@@ -752,7 +752,7 @@ export default class poloniexfutures extends Exchange {
752
752
  // ]
753
753
  // }
754
754
  //
755
- const data = this.safeValue(response, 'data', []);
755
+ const data = this.safeList(response, 'data', []);
756
756
  return this.parseOHLCVs(data, market, timeframe, since, limit);
757
757
  }
758
758
  parseBalance(response) {
@@ -1012,7 +1012,7 @@ export default class poloniexfutures extends Exchange {
1012
1012
  // ]
1013
1013
  // }
1014
1014
  //
1015
- const data = this.safeValue(response, 'data');
1015
+ const data = this.safeList(response, 'data');
1016
1016
  return this.parsePositions(data, symbols);
1017
1017
  }
1018
1018
  parsePosition(position, market = undefined) {
@@ -1466,7 +1466,7 @@ export default class poloniexfutures extends Exchange {
1466
1466
  // }
1467
1467
  //
1468
1468
  const market = (symbol !== undefined) ? this.market(symbol) : undefined;
1469
- const responseData = this.safeValue(response, 'data');
1469
+ const responseData = this.safeDict(response, 'data');
1470
1470
  return this.parseOrder(responseData, market);
1471
1471
  }
1472
1472
  parseOrder(order, market = undefined) {
@@ -1702,7 +1702,7 @@ export default class poloniexfutures extends Exchange {
1702
1702
  // }
1703
1703
  //
1704
1704
  const data = this.safeValue(response, 'data', {});
1705
- const trades = this.safeValue(data, 'items', {});
1705
+ const trades = this.safeList(data, 'items', []);
1706
1706
  return this.parseTrades(trades, market, since, limit);
1707
1707
  }
1708
1708
  async setMarginMode(marginMode, symbol = undefined, params = {}) {
@@ -24,9 +24,13 @@ export default class binance extends binanceRest {
24
24
  handleFetchOHLCV(client: Client, message: any): void;
25
25
  watchTicker(symbol: string, params?: {}): Promise<Ticker>;
26
26
  watchTickers(symbols?: Strings, params?: {}): Promise<Tickers>;
27
+ watchBidsAsks(symbols?: Strings, params?: {}): Promise<Tickers>;
28
+ watchMultiTickerHelper(methodName: any, channelName: string, symbols?: Strings, params?: {}): Promise<any>;
27
29
  parseWsTicker(message: any, marketType: any): Ticker;
28
- handleTicker(client: Client, message: any): void;
30
+ handleBidsAsks(client: Client, message: any): void;
29
31
  handleTickers(client: Client, message: any): void;
32
+ handleTickersAndBidsAsks(client: Client, message: any, methodType: any): void;
33
+ getMessageHash(channelName: string, symbol: Str, isBidAsk: boolean): string;
30
34
  signParams(params?: {}): any;
31
35
  authenticate(params?: {}): Promise<void>;
32
36
  keepAliveListenKey(params?: {}): Promise<void>;
@@ -7,7 +7,7 @@
7
7
  // ----------------------------------------------------------------------------
8
8
  import binanceRest from '../binance.js';
9
9
  import { Precise } from '../base/Precise.js';
10
- import { ExchangeError, ArgumentsRequired, BadRequest } from '../base/errors.js';
10
+ import { ExchangeError, ArgumentsRequired, BadRequest, NotSupported } from '../base/errors.js';
11
11
  import { ArrayCache, ArrayCacheByTimestamp, ArrayCacheBySymbolById, ArrayCacheBySymbolBySide } from '../base/ws/Cache.js';
12
12
  import { sha256 } from '../static_dependencies/noble-hashes/sha256.js';
13
13
  import { rsa } from '../base/functions/rsa.js';
@@ -20,6 +20,7 @@ export default class binance extends binanceRest {
20
20
  'has': {
21
21
  'ws': true,
22
22
  'watchBalance': true,
23
+ 'watchBidsAsks': true,
23
24
  'watchMyTrades': true,
24
25
  'watchOHLCV': true,
25
26
  'watchOHLCVForSymbols': false,
@@ -101,10 +102,10 @@ export default class binance extends binanceRest {
101
102
  'name': 'trade', // 'trade' or 'aggTrade'
102
103
  },
103
104
  'watchTicker': {
104
- 'name': 'ticker', // ticker = 1000ms L1+OHLCV, bookTicker = real-time L1
105
+ 'name': 'ticker', // ticker or miniTicker or ticker_<window_size>
105
106
  },
106
107
  'watchTickers': {
107
- 'name': 'ticker', // ticker or miniTicker or bookTicker
108
+ 'name': 'ticker', // ticker or miniTicker or ticker_<window_size>
108
109
  },
109
110
  'watchOHLCV': {
110
111
  'name': 'kline', // or indexPriceKline or markPriceKline (coin-m futures)
@@ -125,6 +126,15 @@ export default class binance extends binanceRest {
125
126
  'ws': {
126
127
  'cost': 5,
127
128
  },
129
+ 'tickerChannelsMap': {
130
+ '24hrTicker': 'ticker',
131
+ '24hrMiniTicker': 'miniTicker',
132
+ // rolling window tickers
133
+ '1hTicker': 'ticker_1h',
134
+ '4hTicker': 'ticker_4h',
135
+ '1dTicker': 'ticker_1d',
136
+ 'bookTicker': 'bookTicker',
137
+ },
128
138
  },
129
139
  });
130
140
  }
@@ -938,34 +948,13 @@ export default class binance extends binanceRest {
938
948
  * @description watches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
939
949
  * @param {string} symbol unified symbol of the market to fetch the ticker for
940
950
  * @param {object} [params] extra parameters specific to the exchange API endpoint
941
- * @param {string} [params.name] stream to use can be ticker or bookTicker
951
+ * @param {string} [params.name] stream to use can be ticker or miniTicker
942
952
  * @returns {object} a [ticker structure]{@link https://docs.ccxt.com/#/?id=ticker-structure}
943
953
  */
944
954
  await this.loadMarkets();
945
- const market = this.market(symbol);
946
- const marketId = market['lowercaseId'];
947
- let type = market['type'];
948
- if (market['contract']) {
949
- type = market['linear'] ? 'future' : 'delivery';
950
- }
951
- const options = this.safeValue(this.options, 'watchTicker', {});
952
- let name = this.safeString(options, 'name', 'ticker');
953
- name = this.safeString(params, 'name', name);
954
- params = this.omit(params, 'name');
955
- const messageHash = marketId + '@' + name;
956
- const url = this.urls['api']['ws'][type] + '/' + this.stream(type, messageHash);
957
- const requestId = this.requestId(url);
958
- const request = {
959
- 'method': 'SUBSCRIBE',
960
- 'params': [
961
- messageHash,
962
- ],
963
- 'id': requestId,
964
- };
965
- const subscribe = {
966
- 'id': requestId,
967
- };
968
- return await this.watch(url, messageHash, this.extend(request, params), messageHash, subscribe);
955
+ symbol = this.symbol(symbol);
956
+ const tickers = await this.watchTickers([symbol], this.extend(params, { 'callerMethodName': 'watchTicker' }));
957
+ return tickers[symbol];
969
958
  }
970
959
  async watchTickers(symbols = undefined, params = {}) {
971
960
  /**
@@ -976,61 +965,108 @@ export default class binance extends binanceRest {
976
965
  * @param {object} [params] extra parameters specific to the exchange API endpoint
977
966
  * @returns {object} a [ticker structure]{@link https://docs.ccxt.com/#/?id=ticker-structure}
978
967
  */
979
- await this.loadMarkets();
980
- symbols = this.marketSymbols(symbols, undefined, true, true, true);
981
- const marketIds = this.marketIds(symbols);
982
- let market = undefined;
983
- let type = undefined;
984
- if (symbols !== undefined) {
985
- market = this.market(symbols[0]);
968
+ let channelName = undefined;
969
+ [channelName, params] = this.handleOptionAndParams(params, 'watchTickers', 'name', 'ticker');
970
+ if (channelName === 'bookTicker') {
971
+ throw new BadRequest(this.id + ' deprecation notice - to subscribe for bids-asks, use watch_bids_asks() method instead');
986
972
  }
987
- [type, params] = this.handleMarketTypeAndParams('watchTickers', market, params);
973
+ const newTickers = await this.watchMultiTickerHelper('watchTickers', channelName, symbols, params);
974
+ if (this.newUpdates) {
975
+ return newTickers;
976
+ }
977
+ return this.filterByArray(this.tickers, 'symbol', symbols);
978
+ }
979
+ async watchBidsAsks(symbols = undefined, params = {}) {
980
+ /**
981
+ * @method
982
+ * @name binance#watchBidsAsks
983
+ * @see https://binance-docs.github.io/apidocs/spot/en/#individual-symbol-book-ticker-streams
984
+ * @see https://binance-docs.github.io/apidocs/futures/en/#all-book-tickers-stream
985
+ * @see https://binance-docs.github.io/apidocs/delivery/en/#all-book-tickers-stream
986
+ * @description watches best bid & ask for symbols
987
+ * @param {string[]} symbols unified symbol of the market to fetch the ticker for
988
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
989
+ * @returns {object} a [ticker structure]{@link https://docs.ccxt.com/#/?id=ticker-structure}
990
+ */
991
+ const result = await this.watchMultiTickerHelper('watchBidsAsks', 'bookTicker', symbols, params);
992
+ if (this.newUpdates) {
993
+ return result;
994
+ }
995
+ return this.filterByArray(this.tickers, 'symbol', symbols);
996
+ }
997
+ async watchMultiTickerHelper(methodName, channelName, symbols = undefined, params = {}) {
998
+ await this.loadMarkets();
999
+ symbols = this.marketSymbols(symbols, undefined, true, false, true);
1000
+ let firstMarket = undefined;
1001
+ let marketType = undefined;
1002
+ const symbolsDefined = (symbols !== undefined);
1003
+ if (symbolsDefined) {
1004
+ firstMarket = this.market(symbols[0]);
1005
+ }
1006
+ [marketType, params] = this.handleMarketTypeAndParams(methodName, firstMarket, params);
988
1007
  let subType = undefined;
989
- [subType, params] = this.handleSubTypeAndParams('watchTickers', market, params);
990
- if (this.isLinear(type, subType)) {
991
- type = 'future';
1008
+ [subType, params] = this.handleSubTypeAndParams(methodName, firstMarket, params);
1009
+ let rawMarketType = undefined;
1010
+ if (this.isLinear(marketType, subType)) {
1011
+ rawMarketType = 'future';
992
1012
  }
993
- else if (this.isInverse(type, subType)) {
994
- type = 'delivery';
1013
+ else if (this.isInverse(marketType, subType)) {
1014
+ rawMarketType = 'delivery';
995
1015
  }
996
- const options = this.safeValue(this.options, 'watchTickers', {});
997
- let name = this.safeString(options, 'name', 'ticker');
998
- name = this.safeString(params, 'name', name);
999
- params = this.omit(params, 'name');
1000
- let wsParams = [];
1001
- let messageHash = 'tickers';
1002
- if (symbols !== undefined) {
1003
- messageHash = 'tickers::' + symbols.join(',');
1016
+ else if (marketType === 'spot') {
1017
+ rawMarketType = marketType;
1004
1018
  }
1005
- if (name === 'bookTicker') {
1006
- if (marketIds === undefined) {
1007
- throw new ArgumentsRequired(this.id + ' watchTickers() requires symbols for bookTicker');
1008
- }
1009
- // simulate watchTickers with subscribe multiple individual bookTicker topic
1010
- for (let i = 0; i < marketIds.length; i++) {
1011
- wsParams.push(marketIds[i].toLowerCase() + '@bookTicker');
1019
+ else {
1020
+ throw new NotSupported(this.id + ' ' + methodName + '() does not support options markets');
1021
+ }
1022
+ const isBidAsk = (channelName === 'bookTicker');
1023
+ const subscriptionArgs = [];
1024
+ const messageHashes = [];
1025
+ if (symbolsDefined) {
1026
+ for (let i = 0; i < symbols.length; i++) {
1027
+ const symbol = symbols[i];
1028
+ const market = this.market(symbol);
1029
+ subscriptionArgs.push(market['lowercaseId'] + '@' + channelName);
1030
+ messageHashes.push(this.getMessageHash(channelName, market['symbol'], isBidAsk));
1012
1031
  }
1013
1032
  }
1014
1033
  else {
1015
- wsParams = [
1016
- '!' + name + '@arr',
1017
- ];
1034
+ if (isBidAsk) {
1035
+ if (marketType === 'spot') {
1036
+ throw new ArgumentsRequired(this.id + ' ' + methodName + '() requires symbols for this channel for spot markets');
1037
+ }
1038
+ subscriptionArgs.push('!' + channelName);
1039
+ }
1040
+ else {
1041
+ subscriptionArgs.push('!' + channelName + '@arr');
1042
+ }
1043
+ messageHashes.push(this.getMessageHash(channelName, undefined, isBidAsk));
1018
1044
  }
1019
- const url = this.urls['api']['ws'][type] + '/' + this.stream(type, messageHash);
1045
+ let streamHash = channelName;
1046
+ if (symbolsDefined) {
1047
+ streamHash = channelName + '::' + symbols.join(',');
1048
+ }
1049
+ const url = this.urls['api']['ws'][rawMarketType] + '/' + this.stream(rawMarketType, streamHash);
1020
1050
  const requestId = this.requestId(url);
1021
1051
  const request = {
1022
1052
  'method': 'SUBSCRIBE',
1023
- 'params': wsParams,
1053
+ 'params': subscriptionArgs,
1024
1054
  'id': requestId,
1025
1055
  };
1026
1056
  const subscribe = {
1027
1057
  'id': requestId,
1028
1058
  };
1029
- const newTickers = await this.watch(url, messageHash, this.extend(request, params), messageHash, subscribe);
1030
- if (this.newUpdates) {
1031
- return newTickers;
1059
+ const result = await this.watchMultiple(url, messageHashes, this.deepExtend(request, params), subscriptionArgs, subscribe);
1060
+ // for efficiency, we have two type of returned structure here - if symbols array was provided, then individual
1061
+ // ticker dict comes in, otherwise all-tickers dict comes in
1062
+ if (!symbolsDefined) {
1063
+ return result;
1064
+ }
1065
+ else {
1066
+ const newDict = {};
1067
+ newDict[result['symbol']] = result;
1068
+ return newDict;
1032
1069
  }
1033
- return this.filterByArray(this.tickers, 'symbol', symbols);
1034
1070
  }
1035
1071
  parseWsTicker(message, marketType) {
1036
1072
  //
@@ -1114,11 +1150,24 @@ export default class binance extends binanceRest {
1114
1150
  'info': message,
1115
1151
  }, market);
1116
1152
  }
1117
- handleTicker(client, message) {
1153
+ handleBidsAsks(client, message) {
1154
+ //
1155
+ // arrives one symbol dict or array of symbol dicts
1156
+ //
1157
+ // {
1158
+ // "u": 7488717758,
1159
+ // "s": "BTCUSDT",
1160
+ // "b": "28621.74000000",
1161
+ // "B": "1.43278800",
1162
+ // "a": "28621.75000000",
1163
+ // "A": "2.52500800"
1164
+ // }
1165
+ //
1166
+ this.handleTickersAndBidsAsks(client, message, 'bidasks');
1167
+ }
1168
+ handleTickers(client, message) {
1118
1169
  //
1119
- // 24hr rolling window ticker statistics for a single symbol
1120
- // These are NOT the statistics of the UTC day, but a 24hr rolling window for the previous 24hrs
1121
- // Update Speed 1000ms
1170
+ // arrives one symbol dict or array of symbol dicts
1122
1171
  //
1123
1172
  // {
1124
1173
  // "e": "24hrTicker", // event type
@@ -1146,39 +1195,14 @@ export default class binance extends binanceRest {
1146
1195
  // "n": 163222, // total number of trades
1147
1196
  // }
1148
1197
  //
1149
- let event = this.safeString(message, 'e', 'bookTicker');
1150
- if (event === '24hrTicker') {
1151
- event = 'ticker';
1152
- }
1153
- else if (event === '24hrMiniTicker') {
1154
- event = 'miniTicker';
1155
- }
1156
- const wsMarketId = this.safeStringLower(message, 's');
1157
- const messageHash = wsMarketId + '@' + event;
1158
- const isSpot = ((client.url.indexOf('/stream') > -1) || (client.url.indexOf('/testnet.binance') > -1));
1159
- const marketType = (isSpot) ? 'spot' : 'contract';
1160
- const result = this.parseWsTicker(message, marketType);
1161
- const symbol = result['symbol'];
1162
- this.tickers[symbol] = result;
1163
- client.resolve(result, messageHash);
1164
- if (event === 'bookTicker') {
1165
- // watch bookTickers
1166
- client.resolve(result, '!' + 'bookTicker@arr');
1167
- const messageHashes = this.findMessageHashes(client, 'tickers::');
1168
- for (let i = 0; i < messageHashes.length; i++) {
1169
- const currentMessageHash = messageHashes[i];
1170
- const parts = currentMessageHash.split('::');
1171
- const symbolsString = parts[1];
1172
- const symbols = symbolsString.split(',');
1173
- if (this.inArray(symbol, symbols)) {
1174
- client.resolve(result, currentMessageHash);
1175
- }
1176
- }
1177
- }
1198
+ this.handleTickersAndBidsAsks(client, message, 'tickers');
1178
1199
  }
1179
- handleTickers(client, message) {
1200
+ handleTickersAndBidsAsks(client, message, methodType) {
1180
1201
  const isSpot = ((client.url.indexOf('/stream') > -1) || (client.url.indexOf('/testnet.binance') > -1));
1181
1202
  const marketType = (isSpot) ? 'spot' : 'contract';
1203
+ const isBidAsk = (methodType === 'bidasks');
1204
+ let channelName = undefined;
1205
+ const resolvedMessageHashes = [];
1182
1206
  let rawTickers = [];
1183
1207
  const newTickers = {};
1184
1208
  if (Array.isArray(message)) {
@@ -1189,25 +1213,42 @@ export default class binance extends binanceRest {
1189
1213
  }
1190
1214
  for (let i = 0; i < rawTickers.length; i++) {
1191
1215
  const ticker = rawTickers[i];
1192
- const result = this.parseWsTicker(ticker, marketType);
1193
- const symbol = result['symbol'];
1194
- this.tickers[symbol] = result;
1195
- newTickers[symbol] = result;
1196
- }
1197
- const messageHashes = this.findMessageHashes(client, 'tickers::');
1198
- for (let i = 0; i < messageHashes.length; i++) {
1199
- const messageHash = messageHashes[i];
1200
- const parts = messageHash.split('::');
1201
- const symbolsString = parts[1];
1202
- const symbols = symbolsString.split(',');
1203
- const tickers = this.filterByArray(newTickers, 'symbol', symbols);
1204
- const tickersSymbols = Object.keys(tickers);
1205
- const numTickers = tickersSymbols.length;
1206
- if (numTickers > 0) {
1207
- client.resolve(tickers, messageHash);
1216
+ let event = this.safeString(ticker, 'e');
1217
+ if (isBidAsk) {
1218
+ event = 'bookTicker'; // as noted in `handleMessage`, bookTicker doesn't have identifier, so manually set here
1219
+ }
1220
+ channelName = this.safeString(this.options['tickerChannelsMap'], event, event);
1221
+ if (channelName === undefined) {
1222
+ continue;
1223
+ }
1224
+ const parsedTicker = this.parseWsTicker(ticker, marketType);
1225
+ const symbol = parsedTicker['symbol'];
1226
+ newTickers[symbol] = parsedTicker;
1227
+ if (isBidAsk) {
1228
+ this.bidsasks[symbol] = parsedTicker;
1229
+ }
1230
+ else {
1231
+ this.tickers[symbol] = parsedTicker;
1208
1232
  }
1233
+ const messageHash = this.getMessageHash(channelName, symbol, isBidAsk);
1234
+ resolvedMessageHashes.push(messageHash);
1235
+ client.resolve(parsedTicker, messageHash);
1236
+ }
1237
+ // resolve batch endpoint
1238
+ const length = resolvedMessageHashes.length;
1239
+ if (length > 0) {
1240
+ const batchMessageHash = this.getMessageHash(channelName, undefined, isBidAsk);
1241
+ client.resolve(newTickers, batchMessageHash);
1242
+ }
1243
+ }
1244
+ getMessageHash(channelName, symbol, isBidAsk) {
1245
+ const prefix = isBidAsk ? 'bidask' : 'ticker';
1246
+ if (symbol !== undefined) {
1247
+ return prefix + ':' + channelName + '@' + symbol;
1248
+ }
1249
+ else {
1250
+ return prefix + 's' + ':' + channelName;
1209
1251
  }
1210
- client.resolve(newTickers, 'tickers');
1211
1252
  }
1212
1253
  signParams(params = {}) {
1213
1254
  this.checkRequiredCredentials();
@@ -3012,11 +3053,17 @@ export default class binance extends binanceRest {
3012
3053
  'kline': this.handleOHLCV,
3013
3054
  'markPrice_kline': this.handleOHLCV,
3014
3055
  'indexPrice_kline': this.handleOHLCV,
3056
+ '1hTicker@arr': this.handleTickers,
3057
+ '4hTicker@arr': this.handleTickers,
3058
+ '1dTicker@arr': this.handleTickers,
3015
3059
  '24hrTicker@arr': this.handleTickers,
3016
3060
  '24hrMiniTicker@arr': this.handleTickers,
3017
- '24hrTicker': this.handleTicker,
3018
- '24hrMiniTicker': this.handleTicker,
3019
- 'bookTicker': this.handleTicker,
3061
+ '1hTicker': this.handleTickers,
3062
+ '4hTicker': this.handleTickers,
3063
+ '1dTicker': this.handleTickers,
3064
+ '24hrTicker': this.handleTickers,
3065
+ '24hrMiniTicker': this.handleTickers,
3066
+ 'bookTicker': this.handleBidsAsks,
3020
3067
  'outboundAccountPosition': this.handleBalance,
3021
3068
  'balanceUpdate': this.handleBalance,
3022
3069
  'ACCOUNT_UPDATE': this.handleAcountUpdate,
@@ -3046,9 +3093,8 @@ export default class binance extends binanceRest {
3046
3093
  // "A": "2.52500800"
3047
3094
  // }
3048
3095
  //
3049
- if (event === undefined) {
3050
- this.handleTicker(client, message);
3051
- this.handleTickers(client, message);
3096
+ if (event === undefined && ('a' in message) && ('b' in message)) {
3097
+ this.handleBidsAsks(client, message);
3052
3098
  }
3053
3099
  }
3054
3100
  else {
@@ -890,18 +890,17 @@ export default class kucoin extends kucoinRest {
890
890
  return this.filterBySymbolSinceLimit(trades, symbol, since, limit, true);
891
891
  }
892
892
  handleMyTrade(client, message) {
893
- let trades = this.myTrades;
894
- if (trades === undefined) {
893
+ if (this.myTrades === undefined) {
895
894
  const limit = this.safeInteger(this.options, 'tradesLimit', 1000);
896
- trades = new ArrayCacheBySymbolById(limit);
895
+ this.myTrades = new ArrayCacheBySymbolById(limit);
897
896
  }
898
- const data = this.safeValue(message, 'data');
897
+ const data = this.safeDict(message, 'data');
899
898
  const parsed = this.parseWsTrade(data);
900
- trades.append(parsed);
899
+ this.myTrades.append(parsed);
901
900
  const messageHash = 'myTrades';
902
- client.resolve(trades, messageHash);
901
+ client.resolve(this.myTrades, messageHash);
903
902
  const symbolSpecificMessageHash = messageHash + ':' + parsed['symbol'];
904
- client.resolve(trades, symbolSpecificMessageHash);
903
+ client.resolve(this.myTrades, symbolSpecificMessageHash);
905
904
  }
906
905
  parseWsTrade(trade, market = undefined) {
907
906
  //
package/js/src/pro/okx.js CHANGED
@@ -490,14 +490,31 @@ export default class okx extends okxRest {
490
490
  * @name okx#watchOrderBookForSymbols
491
491
  * @description watches information on open orders with bid (buy) and ask (sell) prices, volumes and other data
492
492
  * @param {string[]} symbols unified array of symbols
493
- * @param {int} [limit] the maximum amount of order book entries to return
493
+ * @param {int} [limit] 1,5, 400, 50 (l2-tbt, vip4+) or 40000 (vip5+) the maximum amount of order book entries to return
494
494
  * @param {object} [params] extra parameters specific to the exchange API endpoint
495
495
  * @returns {object} A dictionary of [order book structures]{@link https://docs.ccxt.com/#/?id=order-book-structure} indexed by market symbols
496
496
  */
497
497
  await this.loadMarkets();
498
498
  symbols = this.marketSymbols(symbols);
499
499
  const options = this.safeValue(this.options, 'watchOrderBook', {});
500
- const depth = this.safeString(options, 'depth', 'books');
500
+ let depth = this.safeString(options, 'depth', 'books');
501
+ if (limit !== undefined) {
502
+ if (limit === 1) {
503
+ depth = 'bbo-tbt';
504
+ }
505
+ else if (limit > 1 && limit <= 5) {
506
+ depth = 'books5';
507
+ }
508
+ else if (limit === 400) {
509
+ depth = 'books';
510
+ }
511
+ else if (limit === 50) {
512
+ depth = 'books50-l2-tbt'; // Make sure you have VIP4 and above
513
+ }
514
+ else if (limit === 4000) {
515
+ depth = 'books-l2-tbt'; // Make sure you have VIP5 and above
516
+ }
517
+ }
501
518
  if ((depth === 'books-l2-tbt') || (depth === 'books50-l2-tbt')) {
502
519
  await this.authenticate({ 'access': 'public' });
503
520
  }