ccxt 4.0.88 → 4.0.90

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 (45) hide show
  1. package/CHANGELOG.md +139 -0
  2. package/README.md +3 -3
  3. package/dist/ccxt.browser.js +1014 -49
  4. package/dist/ccxt.browser.min.js +10 -10
  5. package/dist/cjs/ccxt.js +1 -1
  6. package/dist/cjs/src/base/Exchange.js +62 -0
  7. package/dist/cjs/src/bingx.js +1 -1
  8. package/dist/cjs/src/bitmex.js +1 -0
  9. package/dist/cjs/src/pro/binance.js +190 -15
  10. package/dist/cjs/src/pro/bitget.js +127 -0
  11. package/dist/cjs/src/pro/bitmex.js +46 -0
  12. package/dist/cjs/src/pro/bybit.js +130 -3
  13. package/dist/cjs/src/pro/coinbasepro.js +70 -0
  14. package/dist/cjs/src/pro/cryptocom.js +71 -0
  15. package/dist/cjs/src/pro/gate.js +29 -0
  16. package/dist/cjs/src/pro/kucoin.js +92 -3
  17. package/dist/cjs/src/pro/kucoinfutures.js +91 -5
  18. package/dist/cjs/src/pro/okx.js +82 -0
  19. package/js/ccxt.d.ts +1 -1
  20. package/js/ccxt.js +1 -1
  21. package/js/src/base/Exchange.d.ts +17 -0
  22. package/js/src/base/Exchange.js +62 -0
  23. package/js/src/bingx.js +1 -1
  24. package/js/src/bitmex.js +1 -0
  25. package/js/src/pro/binance.d.ts +3 -0
  26. package/js/src/pro/binance.js +190 -15
  27. package/js/src/pro/bitget.d.ts +4 -0
  28. package/js/src/pro/bitget.js +127 -0
  29. package/js/src/pro/bitmex.d.ts +1 -0
  30. package/js/src/pro/bitmex.js +46 -0
  31. package/js/src/pro/bybit.d.ts +3 -0
  32. package/js/src/pro/bybit.js +131 -4
  33. package/js/src/pro/coinbasepro.d.ts +2 -0
  34. package/js/src/pro/coinbasepro.js +71 -1
  35. package/js/src/pro/cryptocom.d.ts +3 -0
  36. package/js/src/pro/cryptocom.js +71 -0
  37. package/js/src/pro/gate.d.ts +1 -0
  38. package/js/src/pro/gate.js +29 -0
  39. package/js/src/pro/kucoin.d.ts +2 -0
  40. package/js/src/pro/kucoin.js +93 -4
  41. package/js/src/pro/kucoinfutures.d.ts +2 -0
  42. package/js/src/pro/kucoinfutures.js +92 -6
  43. package/js/src/pro/okx.d.ts +2 -0
  44. package/js/src/pro/okx.js +83 -1
  45. package/package.json +1 -1
@@ -6965,6 +6965,17 @@ class Exchange {
6965
6965
  'signIn': undefined,
6966
6966
  'transfer': undefined,
6967
6967
  'withdraw': undefined,
6968
+ 'watchOrderBook': undefined,
6969
+ 'watchOrders': undefined,
6970
+ 'watchMyTrades': undefined,
6971
+ 'watchTickers': undefined,
6972
+ 'watchTicker': undefined,
6973
+ 'watchTrades': undefined,
6974
+ 'watchTradesForSymbols': undefined,
6975
+ 'watchOrderBookForSymbols': undefined,
6976
+ 'watchOHLCVForSymbols': undefined,
6977
+ 'watchBalance': undefined,
6978
+ 'watchOHLCV': undefined,
6968
6979
  },
6969
6980
  'urls': {
6970
6981
  'logo': undefined,
@@ -7835,6 +7846,15 @@ class Exchange {
7835
7846
  async watchTrades(symbol, since = undefined, limit = undefined, params = {}) {
7836
7847
  throw new _errors_js__WEBPACK_IMPORTED_MODULE_1__.NotSupported(this.id + ' watchTrades() is not supported yet');
7837
7848
  }
7849
+ async watchTradesForSymbols(symbols, since = undefined, limit = undefined, params = {}) {
7850
+ throw new _errors_js__WEBPACK_IMPORTED_MODULE_1__.NotSupported(this.id + ' watchTradesForSymbols() is not supported yet');
7851
+ }
7852
+ async watchOHLCVForSymbols(symbolsAndTimeframes, since = undefined, limit = undefined, params = {}) {
7853
+ throw new _errors_js__WEBPACK_IMPORTED_MODULE_1__.NotSupported(this.id + ' watchOHLCVForSymbols() is not supported yet');
7854
+ }
7855
+ async watchOrderBookForSymbols(symbols, limit = undefined, params = {}) {
7856
+ throw new _errors_js__WEBPACK_IMPORTED_MODULE_1__.NotSupported(this.id + ' watchOrderBookForSymbols() is not supported yet');
7857
+ }
7838
7858
  async fetchDepositAddresses(codes = undefined, params = {}) {
7839
7859
  throw new _errors_js__WEBPACK_IMPORTED_MODULE_1__.NotSupported(this.id + ' fetchDepositAddresses() is not supported yet');
7840
7860
  }
@@ -9090,6 +9110,17 @@ class Exchange {
9090
9110
  const percentageString = _Precise_js__WEBPACK_IMPORTED_MODULE_5__/* .Precise.stringMul */ .O.stringMul(_Precise_js__WEBPACK_IMPORTED_MODULE_5__/* .Precise.stringDiv */ .O.stringDiv(unrealizedPnlString, initialMarginString, 4), '100');
9091
9111
  position['percentage'] = this.parseNumber(percentageString);
9092
9112
  }
9113
+ // if contractSize is undefined get from market
9114
+ let contractSize = this.safeNumber(position, 'contractSize');
9115
+ const symbol = this.safeString(position, 'symbol');
9116
+ let market = undefined;
9117
+ if (symbol !== undefined) {
9118
+ market = this.market(symbol);
9119
+ }
9120
+ if (contractSize === undefined && market !== undefined) {
9121
+ contractSize = this.safeNumber(market, 'contractSize');
9122
+ position['contractSize'] = contractSize;
9123
+ }
9093
9124
  return position;
9094
9125
  }
9095
9126
  parsePositions(positions, symbols = undefined, params = {}) {
@@ -10553,6 +10584,37 @@ class Exchange {
10553
10584
  */
10554
10585
  return this.filterByArray(objects, key, values, indexed);
10555
10586
  }
10587
+ resolvePromiseIfMessagehashMatches(client, prefix, symbol, data) {
10588
+ const messageHashes = this.findMessageHashes(client, prefix);
10589
+ for (let i = 0; i < messageHashes.length; i++) {
10590
+ const messageHash = messageHashes[i];
10591
+ const parts = messageHash.split('::');
10592
+ const symbolsString = parts[1];
10593
+ const symbols = symbolsString.split(',');
10594
+ if (this.inArray(symbol, symbols)) {
10595
+ client.resolve(data, messageHash);
10596
+ }
10597
+ }
10598
+ }
10599
+ resolveMultipleOHLCV(client, prefix, symbol, timeframe, data) {
10600
+ const messageHashes = this.findMessageHashes(client, 'multipleOHLCV::');
10601
+ for (let i = 0; i < messageHashes.length; i++) {
10602
+ const messageHash = messageHashes[i];
10603
+ const parts = messageHash.split('::');
10604
+ const symbolsAndTimeframes = parts[1];
10605
+ const splitted = symbolsAndTimeframes.split(',');
10606
+ const id = symbol + '#' + timeframe;
10607
+ if (this.inArray(id, splitted)) {
10608
+ client.resolve([symbol, timeframe, data], messageHash);
10609
+ }
10610
+ }
10611
+ }
10612
+ createOHLCVObject(symbol, timeframe, data) {
10613
+ const res = {};
10614
+ res[symbol] = {};
10615
+ res[symbol][timeframe] = data;
10616
+ return res;
10617
+ }
10556
10618
  }
10557
10619
 
10558
10620
 
@@ -25276,7 +25338,7 @@ class bingx extends _abstract_bingx_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"
25276
25338
  'symbol': market['id'],
25277
25339
  };
25278
25340
  if (limit !== undefined) {
25279
- request['limit'] = limit;
25341
+ request['limit'] = Math.min(limit, 100); // avoid API exception "limit should less than 100"
25280
25342
  }
25281
25343
  let response = undefined;
25282
25344
  let marketType = undefined;
@@ -48892,6 +48954,7 @@ class bitmex extends _abstract_bitmex_js__WEBPACK_IMPORTED_MODULE_0__/* ["defaul
48892
48954
  if (until !== undefined) {
48893
48955
  request['endTime'] = this.iso8601(until);
48894
48956
  }
48957
+ request['reverse'] = true;
48895
48958
  const response = await this.publicGetFunding(this.extend(request, params));
48896
48959
  //
48897
48960
  // [
@@ -195075,11 +195138,14 @@ class binance extends _binance_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */
195075
195138
  'watchBalance': true,
195076
195139
  'watchMyTrades': true,
195077
195140
  'watchOHLCV': true,
195141
+ 'watchOHLCVForSymbols': true,
195078
195142
  'watchOrderBook': true,
195143
+ 'watchOrderBookForSymbols': true,
195079
195144
  'watchOrders': true,
195080
195145
  'watchTicker': true,
195081
195146
  'watchTickers': true,
195082
195147
  'watchTrades': true,
195148
+ 'watchTradesForSymbols': true,
195083
195149
  'createOrderWs': true,
195084
195150
  'editOrderWs': true,
195085
195151
  'cancelOrderWs': true,
@@ -195266,6 +195332,60 @@ class binance extends _binance_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */
195266
195332
  const orderbook = await this.watch(url, messageHash, message, messageHash, subscription);
195267
195333
  return orderbook.limit();
195268
195334
  }
195335
+ async watchOrderBookForSymbols(symbols, limit = undefined, params = {}) {
195336
+ /**
195337
+ * @method
195338
+ * @name binance#watchOrderBookForSymbols
195339
+ * @description watches information on open orders with bid (buy) and ask (sell) prices, volumes and other data
195340
+ * @param {string[]} symbols unified array of symbols
195341
+ * @param {int} [limit] the maximum amount of order book entries to return
195342
+ * @param {object} [params] extra parameters specific to the binance api endpoint
195343
+ * @returns {object} A dictionary of [order book structures]{@link https://docs.ccxt.com/#/?id=order-book-structure} indexed by market symbols
195344
+ */
195345
+ if (limit !== undefined) {
195346
+ if ((limit !== 5) && (limit !== 10) && (limit !== 20) && (limit !== 50) && (limit !== 100) && (limit !== 500) && (limit !== 1000)) {
195347
+ throw new _base_errors_js__WEBPACK_IMPORTED_MODULE_1__.ExchangeError(this.id + ' watchOrderBook limit argument must be undefined, 5, 10, 20, 50, 100, 500 or 1000');
195348
+ }
195349
+ }
195350
+ //
195351
+ await this.loadMarkets();
195352
+ symbols = this.marketSymbols(symbols);
195353
+ const firstMarket = this.market(symbols[0]);
195354
+ let type = firstMarket['type'];
195355
+ if (firstMarket['contract']) {
195356
+ type = firstMarket['linear'] ? 'future' : 'delivery';
195357
+ }
195358
+ const name = 'depth';
195359
+ const messageHash = 'multipleOrderbook::' + symbols.join(',');
195360
+ const url = this.urls['api']['ws'][type] + '/' + this.stream(type, 'multipleOrderbook');
195361
+ const requestId = this.requestId(url);
195362
+ const watchOrderBookRate = this.safeString(this.options, 'watchOrderBookRate', '100');
195363
+ const subParams = [];
195364
+ for (let i = 0; i < symbols.length; i++) {
195365
+ const symbol = symbols[i];
195366
+ const market = this.market(symbol);
195367
+ const messageHash = market['lowercaseId'] + '@' + name + '@' + watchOrderBookRate + 'ms';
195368
+ subParams.push(messageHash);
195369
+ }
195370
+ const request = {
195371
+ 'method': 'SUBSCRIBE',
195372
+ 'params': subParams,
195373
+ 'id': requestId,
195374
+ };
195375
+ const subscription = {
195376
+ 'id': requestId.toString(),
195377
+ 'messageHash': messageHash,
195378
+ 'name': name,
195379
+ 'symbols': symbols,
195380
+ 'method': this.handleOrderBookSubscription,
195381
+ 'limit': limit,
195382
+ 'type': type,
195383
+ 'params': params,
195384
+ };
195385
+ const message = this.extend(request, params);
195386
+ const orderbook = await this.watch(url, messageHash, message, messageHash, subscription);
195387
+ return orderbook.limit();
195388
+ }
195269
195389
  async fetchOrderBookSnapshot(client, message, subscription) {
195270
195390
  const messageHash = this.safeString(subscription, 'messageHash');
195271
195391
  const symbol = this.safeString(subscription, 'symbol');
@@ -195408,6 +195528,8 @@ class binance extends _binance_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */
195408
195528
  this.handleOrderBookMessage(client, message, orderbook);
195409
195529
  if (nonce < orderbook['nonce']) {
195410
195530
  client.resolve(orderbook, messageHash);
195531
+ // watchOrderBookForSymbols part (dry logic)
195532
+ this.resolvePromiseIfMessagehashMatches(client, 'multipleOrderbook::', symbol, orderbook);
195411
195533
  }
195412
195534
  }
195413
195535
  else {
@@ -195426,6 +195548,8 @@ class binance extends _binance_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */
195426
195548
  this.handleOrderBookMessage(client, message, orderbook);
195427
195549
  if (nonce <= orderbook['nonce']) {
195428
195550
  client.resolve(orderbook, messageHash);
195551
+ // watchOrderBookForSymbols part (dry logic)
195552
+ this.resolvePromiseIfMessagehashMatches(client, 'multipleOrderbook::', symbol, orderbook);
195429
195553
  }
195430
195554
  }
195431
195555
  else {
@@ -195444,14 +195568,21 @@ class binance extends _binance_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */
195444
195568
  }
195445
195569
  handleOrderBookSubscription(client, message, subscription) {
195446
195570
  const defaultLimit = this.safeInteger(this.options, 'watchOrderBookLimit', 1000);
195447
- const symbol = this.safeString(subscription, 'symbol');
195571
+ // const messageHash = this.safeString (subscription, 'messageHash');
195572
+ const symbol = this.safeString(subscription, 'symbol'); // watchOrderBook
195573
+ const symbols = this.safeValue(subscription, 'symbols', [symbol]); // watchOrderBookForSymbols
195448
195574
  const limit = this.safeInteger(subscription, 'limit', defaultLimit);
195449
- if (symbol in this.orderbooks) {
195450
- delete this.orderbooks[symbol];
195575
+ // handle list of symbols
195576
+ for (let i = 0; i < symbols.length; i++) {
195577
+ const symbol = symbols[i];
195578
+ if (symbol in this.orderbooks) {
195579
+ delete this.orderbooks[symbol];
195580
+ }
195581
+ this.orderbooks[symbol] = this.orderBook({}, limit);
195582
+ subscription['symbol'] = symbol;
195583
+ // fetch the snapshot in a separate async call
195584
+ this.spawn(this.fetchOrderBookSnapshot, client, message, subscription);
195451
195585
  }
195452
- this.orderbooks[symbol] = this.orderBook({}, limit);
195453
- // fetch the snapshot in a separate async call
195454
- this.spawn(this.fetchOrderBookSnapshot, client, message, subscription);
195455
195586
  }
195456
195587
  handleSubscriptionStatus(client, message) {
195457
195588
  //
@@ -195469,6 +195600,53 @@ class binance extends _binance_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */
195469
195600
  }
195470
195601
  return message;
195471
195602
  }
195603
+ async watchTradesForSymbols(symbols, since = undefined, limit = undefined, params = {}) {
195604
+ /**
195605
+ * @method
195606
+ * @name binance#watchTradesForSymbols
195607
+ * @description get the list of most recent trades for a list of symbols
195608
+ * @param {string[]} symbols unified symbol of the market to fetch trades for
195609
+ * @param {int} [since] timestamp in ms of the earliest trade to fetch
195610
+ * @param {int} [limit] the maximum amount of trades to fetch
195611
+ * @param {object} [params] extra parameters specific to the binance api endpoint
195612
+ * @returns {object[]} a list of [trade structures]{@link https://docs.ccxt.com/en/latest/manual.html?#public-trades}
195613
+ */
195614
+ await this.loadMarkets();
195615
+ symbols = this.marketSymbols(symbols);
195616
+ const options = this.safeValue(this.options, 'watchTradesForSymbols', {});
195617
+ const name = this.safeString(options, 'name', 'trade');
195618
+ const firstMarket = this.market(symbols[0]);
195619
+ let type = firstMarket['type'];
195620
+ if (firstMarket['contract']) {
195621
+ type = firstMarket['linear'] ? 'future' : 'delivery';
195622
+ }
195623
+ const subParams = [];
195624
+ for (let i = 0; i < symbols.length; i++) {
195625
+ const symbol = symbols[i];
195626
+ const market = this.market(symbol);
195627
+ const messageHash = market['lowercaseId'] + '@' + name;
195628
+ subParams.push(messageHash);
195629
+ }
195630
+ const messageHash = 'multipleTrades::' + symbols.join(',');
195631
+ const query = this.omit(params, 'type');
195632
+ const url = this.urls['api']['ws'][type] + '/' + this.stream(type, messageHash);
195633
+ const requestId = this.requestId(url);
195634
+ const request = {
195635
+ 'method': 'SUBSCRIBE',
195636
+ 'params': subParams,
195637
+ 'id': requestId,
195638
+ };
195639
+ const subscribe = {
195640
+ 'id': requestId,
195641
+ };
195642
+ const trades = await this.watch(url, messageHash, this.extend(request, query), messageHash, subscribe);
195643
+ if (this.newUpdates) {
195644
+ const first = this.safeValue(trades, 0);
195645
+ const tradeSymbol = this.safeString(first, 'symbol');
195646
+ limit = trades.getLimit(tradeSymbol, limit);
195647
+ }
195648
+ return this.filterBySinceLimit(trades, since, limit, 'timestamp', true);
195649
+ }
195472
195650
  async watchTrades(symbol, since = undefined, limit = undefined, params = {}) {
195473
195651
  /**
195474
195652
  * @method
@@ -195673,8 +195851,8 @@ class binance extends _binance_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */
195673
195851
  handleTrade(client, message) {
195674
195852
  // the trade streams push raw trade information in real-time
195675
195853
  // each trade has a unique buyer and seller
195676
- const index = client.url.indexOf('/stream');
195677
- const marketType = (index >= 0) ? 'spot' : 'contract';
195854
+ const isSpot = ((client.url.indexOf('/stream') > -1) || (client.url.indexOf('/testnet.binance') > -1));
195855
+ const marketType = (isSpot) ? 'spot' : 'contract';
195678
195856
  const marketId = this.safeString(message, 's');
195679
195857
  const market = this.safeMarket(marketId, undefined, undefined, marketType);
195680
195858
  const symbol = market['symbol'];
@@ -195690,6 +195868,8 @@ class binance extends _binance_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */
195690
195868
  tradesArray.append(trade);
195691
195869
  this.trades[symbol] = tradesArray;
195692
195870
  client.resolve(tradesArray, messageHash);
195871
+ // watchTradesForSymbols part
195872
+ this.resolvePromiseIfMessagehashMatches(client, 'multipleTrades::', symbol, tradesArray);
195693
195873
  }
195694
195874
  async watchOHLCV(symbol, timeframe = '1m', since = undefined, limit = undefined, params = {}) {
195695
195875
  /**
@@ -195711,8 +195891,8 @@ class binance extends _binance_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */
195711
195891
  const nameOption = this.safeString(options, 'name', 'kline');
195712
195892
  const name = this.safeString(params, 'name', nameOption);
195713
195893
  if (name === 'indexPriceKline') {
195714
- // weird behavior for index price kline we can't use the perp suffix
195715
195894
  marketId = marketId.replace('_perp', '');
195895
+ // weird behavior for index price kline we can't use the perp suffix
195716
195896
  }
195717
195897
  params = this.omit(params, 'name');
195718
195898
  const messageHash = marketId + '@' + name + '_' + interval;
@@ -195738,6 +195918,62 @@ class binance extends _binance_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */
195738
195918
  }
195739
195919
  return this.filterBySinceLimit(ohlcv, since, limit, 0, true);
195740
195920
  }
195921
+ async watchOHLCVForSymbols(symbolsAndTimeframes, since = undefined, limit = undefined, params = {}) {
195922
+ /**
195923
+ * @method
195924
+ * @name binance#watchOHLCVForSymbols
195925
+ * @description watches historical candlestick data containing the open, high, low, and close price, and the volume of a market
195926
+ * @param {string[][]} symbolsAndTimeframes array of arrays containing unified symbols and timeframes to fetch OHLCV data for, example [['BTC/USDT', '1m'], ['LTC/USDT', '5m']]
195927
+ * @param {int} [since] timestamp in ms of the earliest candle to fetch
195928
+ * @param {int} [limit] the maximum amount of candles to fetch
195929
+ * @param {object} [params] extra parameters specific to the binance api endpoint
195930
+ * @returns {int[][]} A list of candles ordered as timestamp, open, high, low, close, volume
195931
+ */
195932
+ await this.loadMarkets();
195933
+ const options = this.safeValue(this.options, 'watchOHLCV', {});
195934
+ const nameOption = this.safeString(options, 'name', 'kline');
195935
+ const name = this.safeString(params, 'name', nameOption);
195936
+ params = this.omit(params, 'name');
195937
+ const firstMarket = this.market(symbolsAndTimeframes[0][0]);
195938
+ let type = firstMarket['type'];
195939
+ if (firstMarket['contract']) {
195940
+ type = firstMarket['linear'] ? 'future' : 'delivery';
195941
+ }
195942
+ const subParams = [];
195943
+ const hashes = [];
195944
+ for (let i = 0; i < symbolsAndTimeframes.length; i++) {
195945
+ const data = symbolsAndTimeframes[i];
195946
+ const symbol = data[0];
195947
+ const timeframe = data[1];
195948
+ const interval = this.safeString(this.timeframes, timeframe, timeframe);
195949
+ const market = this.market(symbol);
195950
+ let marketId = market['lowercaseId'];
195951
+ if (name === 'indexPriceKline') {
195952
+ // weird behavior for index price kline we can't use the perp suffix
195953
+ marketId = marketId.replace('_perp', '');
195954
+ }
195955
+ const topic = marketId + '@' + name + '_' + interval;
195956
+ subParams.push(topic);
195957
+ hashes.push(symbol + '#' + timeframe);
195958
+ }
195959
+ const messageHash = 'multipleOHLCV::' + hashes.join(',');
195960
+ const url = this.urls['api']['ws'][type] + '/' + this.stream(type, messageHash);
195961
+ const requestId = this.requestId(url);
195962
+ const request = {
195963
+ 'method': 'SUBSCRIBE',
195964
+ 'params': subParams,
195965
+ 'id': requestId,
195966
+ };
195967
+ const subscribe = {
195968
+ 'id': requestId,
195969
+ };
195970
+ const [symbol, timeframe, stored] = await this.watch(url, messageHash, this.extend(request, params), messageHash, subscribe);
195971
+ if (this.newUpdates) {
195972
+ limit = stored.getLimit(symbol, limit);
195973
+ }
195974
+ const filtered = this.filterBySinceLimit(stored, since, limit, 0, true);
195975
+ return this.createOHLCVObject(symbol, timeframe, filtered);
195976
+ }
195741
195977
  handleOHLCV(client, message) {
195742
195978
  //
195743
195979
  // {
@@ -195790,8 +196026,8 @@ class binance extends _binance_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */
195790
196026
  this.safeFloat(kline, 'c'),
195791
196027
  this.safeFloat(kline, 'v'),
195792
196028
  ];
195793
- const index = client.url.indexOf('/stream');
195794
- const marketType = (index >= 0) ? 'spot' : 'contract';
196029
+ const isSpot = ((client.url.indexOf('/stream') > -1) || (client.url.indexOf('/testnet.binance') > -1));
196030
+ const marketType = (isSpot) ? 'spot' : 'contract';
195795
196031
  const symbol = this.safeSymbol(marketId, undefined, undefined, marketType);
195796
196032
  this.ohlcvs[symbol] = this.safeValue(this.ohlcvs, symbol, {});
195797
196033
  let stored = this.safeValue(this.ohlcvs[symbol], timeframe);
@@ -195802,6 +196038,8 @@ class binance extends _binance_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */
195802
196038
  }
195803
196039
  stored.append(parsed);
195804
196040
  client.resolve(stored, messageHash);
196041
+ // watchOHLCVForSymbols part
196042
+ this.resolveMultipleOHLCV(client, 'multipleOHLCV::', symbol, timeframe, stored);
195805
196043
  }
195806
196044
  async watchTicker(symbol, params = {}) {
195807
196045
  /**
@@ -196028,8 +196266,8 @@ class binance extends _binance_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */
196028
196266
  }
196029
196267
  const wsMarketId = this.safeStringLower(message, 's');
196030
196268
  const messageHash = wsMarketId + '@' + event;
196031
- const index = client.url.indexOf('/stream');
196032
- const marketType = (index >= 0) ? 'spot' : 'contract';
196269
+ const isSpot = ((client.url.indexOf('/stream') > -1) || (client.url.indexOf('/testnet.binance') > -1));
196270
+ const marketType = (isSpot) ? 'spot' : 'contract';
196033
196271
  const result = this.parseWsTicker(message, marketType);
196034
196272
  const symbol = result['symbol'];
196035
196273
  this.tickers[symbol] = result;
@@ -196050,8 +196288,8 @@ class binance extends _binance_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */
196050
196288
  }
196051
196289
  }
196052
196290
  handleTickers(client, message) {
196053
- const index = client.url.indexOf('/stream');
196054
- const marketType = (index >= 0) ? 'spot' : 'contract';
196291
+ const isSpot = ((client.url.indexOf('/stream') > -1) || (client.url.indexOf('/testnet.binance') > -1));
196292
+ const marketType = (isSpot) ? 'spot' : 'contract';
196055
196293
  let rawTickers = [];
196056
196294
  const newTickers = [];
196057
196295
  if (Array.isArray(message)) {
@@ -199536,11 +199774,14 @@ class bitget extends _bitget_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z
199536
199774
  'watchBalance': true,
199537
199775
  'watchMyTrades': true,
199538
199776
  'watchOHLCV': true,
199777
+ 'watchOHLCVForSymbols': true,
199539
199778
  'watchOrderBook': true,
199779
+ 'watchOrderBookForSymbols': true,
199540
199780
  'watchOrders': true,
199541
199781
  'watchTicker': true,
199542
199782
  'watchTickers': false,
199543
199783
  'watchTrades': true,
199784
+ 'watchTradesForSymbols': true,
199544
199785
  },
199545
199786
  'urls': {
199546
199787
  'api': {
@@ -199794,6 +200035,43 @@ class bitget extends _bitget_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z
199794
200035
  }
199795
200036
  return this.filterBySinceLimit(ohlcv, since, limit, 0, true);
199796
200037
  }
200038
+ async watchOHLCVForSymbols(symbolsAndTimeframes, since = undefined, limit = undefined, params = {}) {
200039
+ /**
200040
+ * @method
200041
+ * @name bitget#watchOHLCVForSymbols
200042
+ * @description watches historical candlestick data containing the open, high, low, and close price, and the volume of a market
200043
+ * @param {string[][]} symbolsAndTimeframes array of arrays containing unified symbols and timeframes to fetch OHLCV data for, example [['BTC/USDT', '1m'], ['LTC/USDT', '5m']]
200044
+ * @param {int} [since] timestamp in ms of the earliest candle to fetch
200045
+ * @param {int} [limit] the maximum amount of candles to fetch
200046
+ * @param {object} [params] extra parameters specific to the bitget api endpoint
200047
+ * @returns {object} A list of candles ordered as timestamp, open, high, low, close, volume
200048
+ */
200049
+ await this.loadMarkets();
200050
+ const topics = [];
200051
+ const hashes = [];
200052
+ for (let i = 0; i < symbolsAndTimeframes.length; i++) {
200053
+ const data = symbolsAndTimeframes[i];
200054
+ const symbol = this.safeString(data, 0);
200055
+ const timeframe = this.safeString(data, 1);
200056
+ const market = this.market(symbol);
200057
+ const interval = this.safeString(this.options['timeframes'], timeframe);
200058
+ const instType = market['spot'] ? 'sp' : 'mc';
200059
+ const args = {
200060
+ 'instType': instType,
200061
+ 'channel': 'candle' + interval,
200062
+ 'instId': this.getWsMarketId(market),
200063
+ };
200064
+ topics.push(args);
200065
+ hashes.push(symbol + '#' + timeframe);
200066
+ }
200067
+ const messageHash = 'multipleOHLCV::' + hashes.join(',');
200068
+ const [symbol, timeframe, stored] = await this.watchPublicMultiple(messageHash, topics, params);
200069
+ if (this.newUpdates) {
200070
+ limit = stored.getLimit(symbol, limit);
200071
+ }
200072
+ const filtered = this.filterBySinceLimit(stored, since, limit, 0, true);
200073
+ return this.createOHLCVObject(symbol, timeframe, filtered);
200074
+ }
199797
200075
  handleOHLCV(client, message) {
199798
200076
  //
199799
200077
  // {
@@ -199845,6 +200123,7 @@ class bitget extends _bitget_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z
199845
200123
  }
199846
200124
  const messageHash = 'candles:' + timeframe + ':' + symbol;
199847
200125
  client.resolve(stored, messageHash);
200126
+ this.resolveMultipleOHLCV(client, 'multipleOHLCV::', symbol, timeframe, stored);
199848
200127
  }
199849
200128
  parseWsOHLCV(ohlcv, market = undefined) {
199850
200129
  //
@@ -199900,6 +200179,44 @@ class bitget extends _bitget_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z
199900
200179
  return orderbook;
199901
200180
  }
199902
200181
  }
200182
+ async watchOrderBookForSymbols(symbols, limit = undefined, params = {}) {
200183
+ /**
200184
+ * @method
200185
+ * @name bitget#watchOrderBookForSymbols
200186
+ * @description watches information on open orders with bid (buy) and ask (sell) prices, volumes and other data
200187
+ * @param {string[]} symbols unified array of symbols
200188
+ * @param {int} [limit] the maximum amount of order book entries to return
200189
+ * @param {object} [params] extra parameters specific to the bitget api endpoint
200190
+ * @returns {object} A dictionary of [order book structures]{@link https://docs.ccxt.com/#/?id=order-book-structure} indexed by market symbols
200191
+ */
200192
+ await this.loadMarkets();
200193
+ symbols = this.marketSymbols(symbols);
200194
+ let channel = 'books';
200195
+ let incrementalFeed = true;
200196
+ if ((limit === 5) || (limit === 15)) {
200197
+ channel += limit.toString();
200198
+ incrementalFeed = false;
200199
+ }
200200
+ const topics = [];
200201
+ for (let i = 0; i < symbols.length; i++) {
200202
+ const market = this.market(symbols[i]);
200203
+ const instType = market['spot'] ? 'sp' : 'mc';
200204
+ const args = {
200205
+ 'instType': instType,
200206
+ 'channel': channel,
200207
+ 'instId': this.getWsMarketId(market),
200208
+ };
200209
+ topics.push(args);
200210
+ }
200211
+ const messageHash = 'multipleOrderbooks::' + symbols.join(',');
200212
+ const orderbook = await this.watchPublicMultiple(messageHash, topics, params);
200213
+ if (incrementalFeed) {
200214
+ return orderbook.limit();
200215
+ }
200216
+ else {
200217
+ return orderbook;
200218
+ }
200219
+ }
199903
200220
  handleOrderBook(client, message) {
199904
200221
  //
199905
200222
  // {
@@ -199985,6 +200302,7 @@ class bitget extends _bitget_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z
199985
200302
  }
199986
200303
  this.orderbooks[symbol] = storedOrderBook;
199987
200304
  client.resolve(storedOrderBook, messageHash);
200305
+ this.resolvePromiseIfMessagehashMatches(client, 'multipleOrderbooks::', symbol, storedOrderBook);
199988
200306
  }
199989
200307
  handleDelta(bookside, delta) {
199990
200308
  const bidAsk = this.parseBidAsk(delta, 0, 1);
@@ -200025,6 +200343,43 @@ class bitget extends _bitget_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z
200025
200343
  }
200026
200344
  return this.filterBySinceLimit(trades, since, limit, 'timestamp', true);
200027
200345
  }
200346
+ async watchTradesForSymbols(symbols, since = undefined, limit = undefined, params = {}) {
200347
+ /**
200348
+ * @method
200349
+ * @name bitget#watchTradesForSymbols
200350
+ * @description get the list of most recent trades for a particular symbol
200351
+ * @param {string} symbol unified symbol of the market to fetch trades for
200352
+ * @param {int} [since] timestamp in ms of the earliest trade to fetch
200353
+ * @param {int} [limit] the maximum amount of trades to fetch
200354
+ * @param {object} [params] extra parameters specific to the bitget api endpoint
200355
+ * @returns {object[]} a list of [trade structures]{@link https://docs.ccxt.com/en/latest/manual.html?#public-trades}
200356
+ */
200357
+ const symbolsLength = symbols.length;
200358
+ if (symbolsLength === 0) {
200359
+ throw new _base_errors_js__WEBPACK_IMPORTED_MODULE_1__.ArgumentsRequired(this.id + ' watchTradesForSymbols() requires a non-empty array of symbols');
200360
+ }
200361
+ await this.loadMarkets();
200362
+ symbols = this.marketSymbols(symbols);
200363
+ const topics = [];
200364
+ for (let i = 0; i < symbols.length; i++) {
200365
+ const market = this.market(symbols[i]);
200366
+ const instType = market['spot'] ? 'sp' : 'mc';
200367
+ const args = {
200368
+ 'instType': instType,
200369
+ 'channel': 'trade',
200370
+ 'instId': this.getWsMarketId(market),
200371
+ };
200372
+ topics.push(args);
200373
+ }
200374
+ const messageHash = 'multipleTrades::' + symbols.join(',');
200375
+ const trades = await this.watchPublicMultiple(messageHash, topics, params);
200376
+ if (this.newUpdates) {
200377
+ const first = this.safeValue(trades, 0);
200378
+ const tradeSymbol = this.safeString(first, 'symbol');
200379
+ limit = trades.getLimit(tradeSymbol, limit);
200380
+ }
200381
+ return this.filterBySinceLimit(trades, since, limit, 'timestamp', true);
200382
+ }
200028
200383
  handleTrades(client, message) {
200029
200384
  //
200030
200385
  // {
@@ -200060,6 +200415,7 @@ class bitget extends _bitget_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z
200060
200415
  }
200061
200416
  const messageHash = 'trade:' + symbol;
200062
200417
  client.resolve(stored, messageHash);
200418
+ this.resolvePromiseIfMessagehashMatches(client, 'multipleTrades::', symbol, stored);
200063
200419
  }
200064
200420
  parseWsTrade(trade, market = undefined) {
200065
200421
  //
@@ -200616,6 +200972,15 @@ class bitget extends _bitget_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z
200616
200972
  const message = this.extend(request, params);
200617
200973
  return await this.watch(url, messageHash, message, messageHash);
200618
200974
  }
200975
+ async watchPublicMultiple(messageHash, argsArray, params = {}) {
200976
+ const url = this.urls['api']['ws'];
200977
+ const request = {
200978
+ 'op': 'subscribe',
200979
+ 'args': argsArray,
200980
+ };
200981
+ const message = this.extend(request, params);
200982
+ return await this.watch(url, messageHash, message, messageHash);
200983
+ }
200619
200984
  async authenticate(params = {}) {
200620
200985
  this.checkRequiredCredentials();
200621
200986
  const url = this.urls['api']['ws'];
@@ -201456,10 +201821,12 @@ class bitmex extends _bitmex_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z
201456
201821
  'watchMyTrades': true,
201457
201822
  'watchOHLCV': true,
201458
201823
  'watchOrderBook': true,
201824
+ 'watchOrderBookForSymbols': true,
201459
201825
  'watchOrders': true,
201460
201826
  'watchTicker': true,
201461
201827
  'watchTickers': false,
201462
201828
  'watchTrades': true,
201829
+ 'watchTradesForSymbols': true,
201463
201830
  },
201464
201831
  'urls': {
201465
201832
  'test': {
@@ -201957,6 +202324,7 @@ class bitmex extends _bitmex_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z
201957
202324
  stored.append(trades[j]);
201958
202325
  }
201959
202326
  client.resolve(stored, messageHash);
202327
+ this.resolvePromiseIfMessagehashMatches(client, 'multipleTrades::', symbol, stored);
201960
202328
  }
201961
202329
  }
201962
202330
  async watchTrades(symbol, since = undefined, limit = undefined, params = {}) {
@@ -202396,6 +202764,47 @@ class bitmex extends _bitmex_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z
202396
202764
  const orderbook = await this.watch(url, messageHash, this.deepExtend(request, params), messageHash);
202397
202765
  return orderbook.limit();
202398
202766
  }
202767
+ async watchOrderBookForSymbols(symbols, limit = undefined, params = {}) {
202768
+ /**
202769
+ * @method
202770
+ * @name bitmex#watchOrderBookForSymbols
202771
+ * @description watches information on open orders with bid (buy) and ask (sell) prices, volumes and other data
202772
+ * @param {string[]} symbols unified array of symbols
202773
+ * @param {int} [limit] the maximum amount of order book entries to return
202774
+ * @param {object} [params] extra parameters specific to the bitmex api endpoint
202775
+ * @returns {object} A dictionary of [order book structures]{@link https://docs.ccxt.com/#/?id=order-book-structure} indexed by market symbols
202776
+ */
202777
+ let table = undefined;
202778
+ if (limit === undefined) {
202779
+ table = this.safeString(this.options, 'watchOrderBookLevel', 'orderBookL2');
202780
+ }
202781
+ else if (limit === 25) {
202782
+ table = 'orderBookL2_25';
202783
+ }
202784
+ else if (limit === 10) {
202785
+ table = 'orderBookL10';
202786
+ }
202787
+ else {
202788
+ throw new _base_errors_js__WEBPACK_IMPORTED_MODULE_1__.ExchangeError(this.id + ' watchOrderBookForSymbols limit argument must be undefined (L2), 25 (L2) or 10 (L3)');
202789
+ }
202790
+ await this.loadMarkets();
202791
+ symbols = this.marketSymbols(symbols);
202792
+ const topics = [];
202793
+ for (let i = 0; i < symbols.length; i++) {
202794
+ const symbol = symbols[i];
202795
+ const market = this.market(symbol);
202796
+ const messageHash = table + ':' + market['id'];
202797
+ topics.push(messageHash);
202798
+ }
202799
+ const messageHash = 'multipleOrderbook::' + symbols.join(',');
202800
+ const url = this.urls['api']['ws'];
202801
+ const request = {
202802
+ 'op': 'subscribe',
202803
+ 'args': topics,
202804
+ };
202805
+ const orderbook = await this.watch(url, messageHash, this.deepExtend(request, params), messageHash);
202806
+ return orderbook.limit();
202807
+ }
202399
202808
  async watchOHLCV(symbol, timeframe = '1m', since = undefined, limit = undefined, params = {}) {
202400
202809
  /**
202401
202810
  * @method
@@ -202618,6 +203027,7 @@ class bitmex extends _bitmex_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z
202618
203027
  }
202619
203028
  const messageHash = table + ':' + marketId;
202620
203029
  client.resolve(orderbook, messageHash);
203030
+ this.resolvePromiseIfMessagehashMatches(client, 'multipleOrderbook::', symbol, orderbook);
202621
203031
  }
202622
203032
  else {
202623
203033
  const numUpdatesByMarketId = {};
@@ -202649,6 +203059,7 @@ class bitmex extends _bitmex_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z
202649
203059
  const symbol = market['symbol'];
202650
203060
  const orderbook = this.orderbooks[symbol];
202651
203061
  client.resolve(orderbook, messageHash);
203062
+ this.resolvePromiseIfMessagehashMatches(client, 'multipleOrderbook::', symbol, orderbook);
202652
203063
  }
202653
203064
  }
202654
203065
  }
@@ -207953,11 +208364,14 @@ class bybit extends _bybit_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z {
207953
208364
  'watchBalance': true,
207954
208365
  'watchMyTrades': true,
207955
208366
  'watchOHLCV': true,
208367
+ 'watchOHLCVForSymbols': true,
207956
208368
  'watchOrderBook': true,
208369
+ 'watchOrderBookForSymbols': true,
207957
208370
  'watchOrders': true,
207958
208371
  'watchTicker': true,
207959
208372
  'watchTickers': false,
207960
208373
  'watchTrades': true,
208374
+ 'watchTradesForSymbols': true,
207961
208375
  'watchPosition': undefined,
207962
208376
  },
207963
208377
  'urls': {
@@ -208277,6 +208691,46 @@ class bybit extends _bybit_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z {
208277
208691
  }
208278
208692
  return this.filterBySinceLimit(ohlcv, since, limit, 0, true);
208279
208693
  }
208694
+ async watchOHLCVForSymbols(symbolsAndTimeframes, since = undefined, limit = undefined, params = {}) {
208695
+ /**
208696
+ * @method
208697
+ * @name bybit#watchOHLCVForSymbols
208698
+ * @description watches historical candlestick data containing the open, high, low, and close price, and the volume of a market
208699
+ * @see https://bybit-exchange.github.io/docs/v5/websocket/public/kline
208700
+ * @see https://bybit-exchange.github.io/docs/v5/websocket/public/etp-kline
208701
+ * @param {string[][]} symbolsAndTimeframes array of arrays containing unified symbols and timeframes to fetch OHLCV data for, example [['BTC/USDT', '1m'], ['LTC/USDT', '5m']]
208702
+ * @param {int} [since] timestamp in ms of the earliest candle to fetch
208703
+ * @param {int} [limit] the maximum amount of candles to fetch
208704
+ * @param {object} [params] extra parameters specific to the bybit api endpoint
208705
+ * @returns {object} A list of candles ordered as timestamp, open, high, low, close, volume
208706
+ */
208707
+ await this.loadMarkets();
208708
+ const topics = [];
208709
+ const hashes = [];
208710
+ let firstSymbol = undefined;
208711
+ for (let i = 0; i < symbolsAndTimeframes.length; i++) {
208712
+ const data = symbolsAndTimeframes[i];
208713
+ let symbol = this.safeString(data, 0);
208714
+ const timeframe = this.safeString(data, 1);
208715
+ const market = this.market(symbol);
208716
+ symbol = market['symbol'];
208717
+ if (i === 0) {
208718
+ firstSymbol = market['symbol'];
208719
+ }
208720
+ const timeframeId = this.safeString(this.timeframes, timeframe, timeframe);
208721
+ const topic = 'kline.' + timeframeId + '.' + market['id'];
208722
+ topics.push(topic);
208723
+ hashes.push(symbol + '#' + timeframe);
208724
+ }
208725
+ const messageHash = 'multipleOHLCV::' + hashes.join(',');
208726
+ const url = this.getUrlByMarketType(firstSymbol, false, params);
208727
+ const [symbol, timeframe, stored] = await this.watchTopics(url, messageHash, topics, params);
208728
+ if (this.newUpdates) {
208729
+ limit = stored.getLimit(symbol, limit);
208730
+ }
208731
+ const filtered = this.filterBySinceLimit(stored, since, limit, 0, true);
208732
+ return this.createOHLCVObject(symbol, timeframe, filtered);
208733
+ }
208280
208734
  handleOHLCV(client, message) {
208281
208735
  //
208282
208736
  // {
@@ -208305,6 +208759,7 @@ class bybit extends _bybit_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z {
208305
208759
  const topicParts = topic.split('.');
208306
208760
  const topicLength = topicParts.length;
208307
208761
  const timeframeId = this.safeString(topicParts, 1);
208762
+ const timeframe = this.findTimeframe(timeframeId);
208308
208763
  const marketId = this.safeString(topicParts, topicLength - 1);
208309
208764
  const isSpot = client.url.indexOf('spot') > -1;
208310
208765
  const marketType = isSpot ? 'spot' : 'contract';
@@ -208314,11 +208769,11 @@ class bybit extends _bybit_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z {
208314
208769
  if (ohlcvsByTimeframe === undefined) {
208315
208770
  this.ohlcvs[symbol] = {};
208316
208771
  }
208317
- let stored = this.safeValue(ohlcvsByTimeframe, timeframeId);
208772
+ let stored = this.safeValue(ohlcvsByTimeframe, timeframe);
208318
208773
  if (stored === undefined) {
208319
208774
  const limit = this.safeInteger(this.options, 'OHLCVLimit', 1000);
208320
208775
  stored = new _base_ws_Cache_js__WEBPACK_IMPORTED_MODULE_2__/* .ArrayCacheByTimestamp */ .Py(limit);
208321
- this.ohlcvs[symbol][timeframeId] = stored;
208776
+ this.ohlcvs[symbol][timeframe] = stored;
208322
208777
  }
208323
208778
  for (let i = 0; i < data.length; i++) {
208324
208779
  const parsed = this.parseWsOHLCV(data[i]);
@@ -208326,6 +208781,7 @@ class bybit extends _bybit_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z {
208326
208781
  }
208327
208782
  const messageHash = 'kline' + ':' + timeframeId + ':' + symbol;
208328
208783
  client.resolve(stored, messageHash);
208784
+ this.resolveMultipleOHLCV(client, 'multipleOHLCV::', symbol, timeframe, stored);
208329
208785
  }
208330
208786
  parseWsOHLCV(ohlcv, market = undefined) {
208331
208787
  //
@@ -208389,6 +208845,48 @@ class bybit extends _bybit_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z {
208389
208845
  const orderbook = await this.watchTopics(url, messageHash, topics, params);
208390
208846
  return orderbook.limit();
208391
208847
  }
208848
+ async watchOrderBookForSymbols(symbols, limit = undefined, params = {}) {
208849
+ /**
208850
+ * @method
208851
+ * @name bybit#watchOrderBook
208852
+ * @description watches information on open orders with bid (buy) and ask (sell) prices, volumes and other data
208853
+ * @see https://bybit-exchange.github.io/docs/v5/websocket/public/orderbook
208854
+ * @param {string[]} symbols unified array of symbols
208855
+ * @param {int} [limit] the maximum amount of order book entries to return.
208856
+ * @param {object} [params] extra parameters specific to the bybit api endpoint
208857
+ * @returns {object} A dictionary of [order book structures]{@link https://docs.ccxt.com/#/?id=order-book-structure} indexed by market symbols
208858
+ */
208859
+ await this.loadMarkets();
208860
+ const symbolsLength = symbols.length;
208861
+ if (symbolsLength === 0) {
208862
+ throw new _base_errors_js__WEBPACK_IMPORTED_MODULE_1__.ArgumentsRequired(this.id + ' watchOrderBookForSymbols() requires a non-empty array of symbols');
208863
+ }
208864
+ symbols = this.marketSymbols(symbols);
208865
+ const url = this.getUrlByMarketType(symbols[0], false, params);
208866
+ params = this.cleanParams(params);
208867
+ const market = this.market(symbols[0]);
208868
+ if (limit === undefined) {
208869
+ limit = (market['spot']) ? 50 : 500;
208870
+ }
208871
+ else {
208872
+ if (!market['spot']) {
208873
+ // bybit only support limit 1, 50, 200, 500 for contract
208874
+ if ((limit !== 1) && (limit !== 50) && (limit !== 200) && (limit !== 500)) {
208875
+ throw new _base_errors_js__WEBPACK_IMPORTED_MODULE_1__.BadRequest(this.id + ' watchOrderBookForSymbols() can only use limit 1, 50, 200 and 500.');
208876
+ }
208877
+ }
208878
+ }
208879
+ const topics = [];
208880
+ for (let i = 0; i < symbols.length; i++) {
208881
+ const symbol = symbols[i];
208882
+ const market = this.market(symbol);
208883
+ const topic = 'orderbook.' + limit.toString() + '.' + market['id'];
208884
+ topics.push(topic);
208885
+ }
208886
+ const messageHash = 'multipleOrderbook::' + symbols.join(',');
208887
+ const orderbook = await this.watchTopics(url, messageHash, topics, params);
208888
+ return orderbook.limit();
208889
+ }
208392
208890
  handleOrderBook(client, message) {
208393
208891
  //
208394
208892
  // {
@@ -208451,6 +208949,8 @@ class bybit extends _bybit_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z {
208451
208949
  const messageHash = 'orderbook' + ':' + symbol;
208452
208950
  this.orderbooks[symbol] = orderbook;
208453
208951
  client.resolve(orderbook, messageHash);
208952
+ // handle watchOrderBookForSymbols
208953
+ this.resolvePromiseIfMessagehashMatches(client, 'multipleOrderbook::', symbol, orderbook);
208454
208954
  }
208455
208955
  handleDelta(bookside, delta) {
208456
208956
  const bidAsk = this.parseBidAsk(delta, 0, 1);
@@ -208486,6 +208986,42 @@ class bybit extends _bybit_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z {
208486
208986
  }
208487
208987
  return this.filterBySinceLimit(trades, since, limit, 'timestamp', true);
208488
208988
  }
208989
+ async watchTradesForSymbols(symbols, since = undefined, limit = undefined, params = {}) {
208990
+ /**
208991
+ * @method
208992
+ * @name bybit#watchTradesForSymbols
208993
+ * @description get the list of most recent trades for a list of symbols
208994
+ * @see https://bybit-exchange.github.io/docs/v5/websocket/public/trade
208995
+ * @param {string[]} symbols unified symbol of the market to fetch trades for
208996
+ * @param {int} [since] timestamp in ms of the earliest trade to fetch
208997
+ * @param {int} [limit] the maximum amount of trades to fetch
208998
+ * @param {object} [params] extra parameters specific to the bybit api endpoint
208999
+ * @returns {object[]} a list of [trade structures]{@link https://docs.ccxt.com/en/latest/manual.html?#public-trades}
209000
+ */
209001
+ await this.loadMarkets();
209002
+ symbols = this.marketSymbols(symbols);
209003
+ const symbolsLength = symbols.length;
209004
+ if (symbolsLength === 0) {
209005
+ throw new _base_errors_js__WEBPACK_IMPORTED_MODULE_1__.ArgumentsRequired(this.id + ' watchTradesForSymbols() requires a non-empty array of symbols');
209006
+ }
209007
+ const url = this.getUrlByMarketType(symbols[0], false, params);
209008
+ const topics = [];
209009
+ params = this.cleanParams(params);
209010
+ for (let i = 0; i < symbols.length; i++) {
209011
+ const symbol = symbols[i];
209012
+ const market = this.market(symbol);
209013
+ const topic = 'publicTrade.' + market['id'];
209014
+ topics.push(topic);
209015
+ }
209016
+ const messageHash = 'multipleTrades::' + symbols.join(',');
209017
+ const trades = await this.watchTopics(url, messageHash, topics, params);
209018
+ if (this.newUpdates) {
209019
+ const first = this.safeValue(trades, 0);
209020
+ const tradeSymbol = this.safeString(first, 'symbol');
209021
+ limit = trades.getLimit(tradeSymbol, limit);
209022
+ }
209023
+ return this.filterBySinceLimit(trades, since, limit, 'timestamp', true);
209024
+ }
208489
209025
  handleTrades(client, message) {
208490
209026
  //
208491
209027
  // {
@@ -208527,6 +209063,8 @@ class bybit extends _bybit_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z {
208527
209063
  }
208528
209064
  const messageHash = 'trade' + ':' + symbol;
208529
209065
  client.resolve(stored, messageHash);
209066
+ // handle watchTradesForSymbols part
209067
+ this.resolvePromiseIfMessagehashMatches(client, 'multipleTrades::', symbol, stored);
208530
209068
  }
208531
209069
  parseWsTrade(trade, market = undefined) {
208532
209070
  //
@@ -208642,7 +209180,7 @@ class bybit extends _bybit_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z {
208642
209180
  if (this.newUpdates) {
208643
209181
  limit = trades.getLimit(symbol, limit);
208644
209182
  }
208645
- return this.filterBySinceLimit(trades, since, limit, 'timestamp', true);
209183
+ return this.filterBySymbolSinceLimit(trades, symbol, since, limit, true);
208646
209184
  }
208647
209185
  handleMyTrades(client, message) {
208648
209186
  //
@@ -211371,9 +211909,11 @@ class coinbasepro extends _coinbasepro_js__WEBPACK_IMPORTED_MODULE_0__/* ["defau
211371
211909
  'ws': true,
211372
211910
  'watchOHLCV': false,
211373
211911
  'watchOrderBook': true,
211912
+ 'watchOrderBookForSymbols': true,
211374
211913
  'watchTicker': true,
211375
211914
  'watchTickers': true,
211376
211915
  'watchTrades': true,
211916
+ 'watchTradesForSymbols': true,
211377
211917
  'watchBalance': false,
211378
211918
  'watchStatus': false,
211379
211919
  'watchOrders': true,
@@ -211514,6 +212054,33 @@ class coinbasepro extends _coinbasepro_js__WEBPACK_IMPORTED_MODULE_0__/* ["defau
211514
212054
  }
211515
212055
  return this.filterBySinceLimit(trades, since, limit, 'timestamp', true);
211516
212056
  }
212057
+ async watchTradesForSymbols(symbols, since = undefined, limit = undefined, params = {}) {
212058
+ /**
212059
+ * @method
212060
+ * @name coinbase#watchTradesForSymbols
212061
+ * @description get the list of most recent trades for a particular symbol
212062
+ * @param {string} symbol unified symbol of the market to fetch trades for
212063
+ * @param {int} [since] timestamp in ms of the earliest trade to fetch
212064
+ * @param {int} [limit] the maximum amount of trades to fetch
212065
+ * @param {object} [params] extra parameters specific to the coinbase api endpoint
212066
+ * @returns {object[]} a list of [trade structures]{@link https://docs.ccxt.com/en/latest/manual.html?#public-trades}
212067
+ */
212068
+ const symbolsLength = symbols.length;
212069
+ if (symbolsLength === 0) {
212070
+ throw new _base_errors_js__WEBPACK_IMPORTED_MODULE_2__.BadRequest(this.id + ' watchTradesForSymbols() requires a non-empty array of symbols');
212071
+ }
212072
+ await this.loadMarkets();
212073
+ symbols = this.marketSymbols(symbols);
212074
+ const name = 'matches';
212075
+ const messageHash = 'multipleTrades::';
212076
+ const trades = await this.subscribeMultiple(name, symbols, messageHash, params);
212077
+ if (this.newUpdates) {
212078
+ const first = this.safeValue(trades, 0);
212079
+ const tradeSymbol = this.safeString(first, 'symbol');
212080
+ limit = trades.getLimit(tradeSymbol, limit);
212081
+ }
212082
+ return this.filterBySinceLimit(trades, since, limit, 'timestamp', true);
212083
+ }
211517
212084
  async watchMyTrades(symbol = undefined, since = undefined, limit = undefined, params = {}) {
211518
212085
  /**
211519
212086
  * @method
@@ -211598,6 +212165,44 @@ class coinbasepro extends _coinbasepro_js__WEBPACK_IMPORTED_MODULE_0__/* ["defau
211598
212165
  const orderbook = await this.watch(url, messageHash, this.extend(request, authentication), messageHash, subscription);
211599
212166
  return orderbook.limit();
211600
212167
  }
212168
+ async watchOrderBookForSymbols(symbols, limit = undefined, params = {}) {
212169
+ /**
212170
+ * @method
212171
+ * @name coinbasepro#watchOrderBookForSymbols
212172
+ * @description watches information on open orders with bid (buy) and ask (sell) prices, volumes and other data
212173
+ * @param {string[]} symbols unified array of symbols
212174
+ * @param {int} [limit] the maximum amount of order book entries to return
212175
+ * @param {object} [params] extra parameters specific to the coinbasepro api endpoint
212176
+ * @returns {object} A dictionary of [order book structures]{@link https://docs.ccxt.com/#/?id=order-book-structure} indexed by market symbols
212177
+ */
212178
+ const symbolsLength = symbols.length;
212179
+ if (symbolsLength === 0) {
212180
+ throw new _base_errors_js__WEBPACK_IMPORTED_MODULE_2__.BadRequest(this.id + ' watchOrderBookForSymbols() requires a non-empty array of symbols');
212181
+ }
212182
+ const name = 'level2';
212183
+ await this.loadMarkets();
212184
+ symbols = this.marketSymbols(symbols);
212185
+ const marketIds = this.marketIds(symbols);
212186
+ const messageHash = 'multipleOrderbooks' + '::' + symbols.join(',');
212187
+ const url = this.urls['api']['ws'];
212188
+ const subscribe = {
212189
+ 'type': 'subscribe',
212190
+ 'product_ids': marketIds,
212191
+ 'channels': [
212192
+ name,
212193
+ ],
212194
+ };
212195
+ const request = this.extend(subscribe, params);
212196
+ const subscription = {
212197
+ 'messageHash': messageHash,
212198
+ 'symbols': symbols,
212199
+ 'marketIds': marketIds,
212200
+ 'limit': limit,
212201
+ };
212202
+ const authentication = this.authenticate();
212203
+ const orderbook = await this.watch(url, messageHash, this.extend(request, authentication), messageHash, subscription);
212204
+ return orderbook.limit();
212205
+ }
211601
212206
  handleTrade(client, message) {
211602
212207
  //
211603
212208
  // {
@@ -211630,6 +212235,7 @@ class coinbasepro extends _coinbasepro_js__WEBPACK_IMPORTED_MODULE_0__/* ["defau
211630
212235
  }
211631
212236
  tradesArray.append(trade);
211632
212237
  client.resolve(tradesArray, messageHash);
212238
+ this.resolvePromiseIfMessagehashMatches(client, 'multipleTrades::', symbol, tradesArray);
211633
212239
  }
211634
212240
  return message;
211635
212241
  }
@@ -212100,6 +212706,7 @@ class coinbasepro extends _coinbasepro_js__WEBPACK_IMPORTED_MODULE_0__/* ["defau
212100
212706
  orderbook['datetime'] = undefined;
212101
212707
  orderbook['symbol'] = symbol;
212102
212708
  client.resolve(orderbook, messageHash);
212709
+ this.resolvePromiseIfMessagehashMatches(client, 'multipleOrderbooks::', symbol, orderbook);
212103
212710
  }
212104
212711
  else if (type === 'l2update') {
212105
212712
  const orderbook = this.orderbooks[symbol];
@@ -212121,6 +212728,7 @@ class coinbasepro extends _coinbasepro_js__WEBPACK_IMPORTED_MODULE_0__/* ["defau
212121
212728
  orderbook['timestamp'] = timestamp;
212122
212729
  orderbook['datetime'] = this.iso8601(timestamp);
212123
212730
  client.resolve(orderbook, messageHash);
212731
+ this.resolvePromiseIfMessagehashMatches(client, 'multipleOrderbooks::', symbol, orderbook);
212124
212732
  }
212125
212733
  }
212126
212734
  handleSubscriptionStatus(client, message) {
@@ -213337,7 +213945,9 @@ class cryptocom extends _cryptocom_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"]
213337
213945
  'watchTickers': false,
213338
213946
  'watchMyTrades': true,
213339
213947
  'watchTrades': true,
213948
+ 'watchTradesForSymbols': true,
213340
213949
  'watchOrderBook': true,
213950
+ 'watchOrderBookForSymbols': true,
213341
213951
  'watchOrders': true,
213342
213952
  'watchOHLCV': true,
213343
213953
  'createOrderWs': true,
@@ -213391,6 +214001,30 @@ class cryptocom extends _cryptocom_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"]
213391
214001
  const orderbook = await this.watchPublic(messageHash, params);
213392
214002
  return orderbook.limit();
213393
214003
  }
214004
+ async watchOrderBookForSymbols(symbols, limit = undefined, params = {}) {
214005
+ /**
214006
+ * @method
214007
+ * @name cryptocom#watchOrderBook
214008
+ * @description watches information on open orders with bid (buy) and ask (sell) prices, volumes and other data
214009
+ * @see https://exchange-docs.crypto.com/exchange/v1/rest-ws/index.html#book-instrument_name
214010
+ * @param {string[]} symbols unified array of symbols
214011
+ * @param {int} [limit] the maximum amount of order book entries to return
214012
+ * @param {object} [params] extra parameters specific to the cryptocom api endpoint
214013
+ * @returns {object} A dictionary of [order book structures]{@link https://docs.ccxt.com/#/?id=order-book-structure} indexed by market symbols
214014
+ */
214015
+ await this.loadMarkets();
214016
+ symbols = this.marketSymbols(symbols);
214017
+ const topics = [];
214018
+ for (let i = 0; i < symbols.length; i++) {
214019
+ const symbol = symbols[i];
214020
+ const market = this.market(symbol);
214021
+ const messageHash = 'book' + '.' + market['id'];
214022
+ topics.push(messageHash);
214023
+ }
214024
+ const messageHash = 'multipleOrderbooks::' + symbols.join(',');
214025
+ const orderbook = await this.watchPublicMultiple(messageHash, topics, params);
214026
+ return orderbook.limit();
214027
+ }
213394
214028
  handleOrderBookSnapshot(client, message) {
213395
214029
  // full snapshot
213396
214030
  //
@@ -213430,6 +214064,7 @@ class cryptocom extends _cryptocom_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"]
213430
214064
  orderbook.reset(snapshot);
213431
214065
  this.orderbooks[symbol] = orderbook;
213432
214066
  client.resolve(orderbook, messageHash);
214067
+ this.resolvePromiseIfMessagehashMatches(client, 'multipleOrderbooks::', symbol, orderbook);
213433
214068
  }
213434
214069
  async watchTrades(symbol, since = undefined, limit = undefined, params = {}) {
213435
214070
  /**
@@ -213453,6 +214088,36 @@ class cryptocom extends _cryptocom_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"]
213453
214088
  }
213454
214089
  return this.filterBySinceLimit(trades, since, limit, 'timestamp', true);
213455
214090
  }
214091
+ async watchTradesForSymbols(symbols, since = undefined, limit = undefined, params = {}) {
214092
+ /**
214093
+ * @method
214094
+ * @name cryptocom#watchTradesForSymbols
214095
+ * @description get the list of most recent trades for a particular symbol
214096
+ * @see https://exchange-docs.crypto.com/exchange/v1/rest-ws/index.html#trade-instrument_name
214097
+ * @param {string} symbol unified symbol of the market to fetch trades for
214098
+ * @param {int} [since] timestamp in ms of the earliest trade to fetch
214099
+ * @param {int} [limit] the maximum amount of trades to fetch
214100
+ * @param {object} [params] extra parameters specific to the cryptocom api endpoint
214101
+ * @returns {object[]} a list of [trade structures]{@link https://docs.ccxt.com/en/latest/manual.html?#public-trades}
214102
+ */
214103
+ await this.loadMarkets();
214104
+ symbols = this.marketSymbols(symbols);
214105
+ const topics = [];
214106
+ for (let i = 0; i < symbols.length; i++) {
214107
+ const symbol = symbols[i];
214108
+ const market = this.market(symbol);
214109
+ const messageHash = 'trade' + '.' + market['id'];
214110
+ topics.push(messageHash);
214111
+ }
214112
+ const messageHash = 'multipleTrades::' + symbols.join(',');
214113
+ const trades = await this.watchPublicMultiple(messageHash, topics, params);
214114
+ if (this.newUpdates) {
214115
+ const first = this.safeValue(trades, 0);
214116
+ const tradeSymbol = this.safeString(first, 'symbol');
214117
+ limit = trades.getLimit(tradeSymbol, limit);
214118
+ }
214119
+ return this.filterBySinceLimit(trades, since, limit, 'timestamp', true);
214120
+ }
213456
214121
  handleTrades(client, message) {
213457
214122
  //
213458
214123
  // {
@@ -213499,6 +214164,7 @@ class cryptocom extends _cryptocom_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"]
213499
214164
  const channelReplaced = channel.replace('.' + marketId, '');
213500
214165
  client.resolve(stored, symbolSpecificMessageHash);
213501
214166
  client.resolve(stored, channelReplaced);
214167
+ this.resolvePromiseIfMessagehashMatches(client, 'multipleTrades::', symbol, stored);
213502
214168
  }
213503
214169
  async watchMyTrades(symbol = undefined, since = undefined, limit = undefined, params = {}) {
213504
214170
  /**
@@ -213894,6 +214560,19 @@ class cryptocom extends _cryptocom_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"]
213894
214560
  const message = this.extend(request, params);
213895
214561
  return await this.watch(url, messageHash, message, messageHash);
213896
214562
  }
214563
+ async watchPublicMultiple(messageHash, topics, params = {}) {
214564
+ const url = this.urls['api']['ws']['public'];
214565
+ const id = this.nonce();
214566
+ const request = {
214567
+ 'method': 'subscribe',
214568
+ 'params': {
214569
+ 'channels': topics,
214570
+ },
214571
+ 'nonce': id,
214572
+ };
214573
+ const message = this.extend(request, params);
214574
+ return await this.watch(url, messageHash, message, messageHash);
214575
+ }
213897
214576
  async watchPrivateRequest(nonce, params = {}) {
213898
214577
  await this.authenticate();
213899
214578
  const url = this.urls['api']['ws']['private'];
@@ -216169,6 +216848,7 @@ class gate extends _gate_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z {
216169
216848
  'watchTicker': true,
216170
216849
  'watchTickers': true,
216171
216850
  'watchTrades': true,
216851
+ 'watchTradesForSymbols': true,
216172
216852
  'watchMyTrades': true,
216173
216853
  'watchOHLCV': true,
216174
216854
  'watchBalance': true,
@@ -216547,6 +217227,33 @@ class gate extends _gate_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z {
216547
217227
  }
216548
217228
  return this.filterBySinceLimit(trades, since, limit, 'timestamp', true);
216549
217229
  }
217230
+ async watchTradesForSymbols(symbols, since = undefined, limit = undefined, params = {}) {
217231
+ /**
217232
+ * @method
217233
+ * @name gate#watchTradesForSymbols
217234
+ * @description get the list of most recent trades for a particular symbol
217235
+ * @param {string} symbol unified symbol of the market to fetch trades for
217236
+ * @param {int} [since] timestamp in ms of the earliest trade to fetch
217237
+ * @param {int} [limit] the maximum amount of trades to fetch
217238
+ * @param {object} [params] extra parameters specific to the gate api endpoint
217239
+ * @returns {object[]} a list of [trade structures]{@link https://docs.ccxt.com/en/latest/manual.html?#public-trades}
217240
+ */
217241
+ await this.loadMarkets();
217242
+ symbols = this.marketSymbols(symbols);
217243
+ const marketIds = this.marketIds(symbols);
217244
+ const market = this.market(symbols[0]);
217245
+ const messageType = this.getTypeByMarket(market);
217246
+ const channel = messageType + '.trades';
217247
+ const messageHash = 'multipleTrades::' + symbols.join(',');
217248
+ const url = this.getUrlByMarket(market);
217249
+ const trades = await this.subscribePublic(url, messageHash, marketIds, channel, params);
217250
+ if (this.newUpdates) {
217251
+ const first = this.safeValue(trades, 0);
217252
+ const tradeSymbol = this.safeString(first, 'symbol');
217253
+ limit = trades.getLimit(tradeSymbol, limit);
217254
+ }
217255
+ return this.filterBySinceLimit(trades, since, limit, 'timestamp', true);
217256
+ }
216550
217257
  handleTrades(client, message) {
216551
217258
  //
216552
217259
  // {
@@ -216581,6 +217288,7 @@ class gate extends _gate_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z {
216581
217288
  cachedTrades.append(trade);
216582
217289
  const hash = 'trades:' + symbol;
216583
217290
  client.resolve(cachedTrades, hash);
217291
+ this.resolvePromiseIfMessagehashMatches(client, 'multipleTrades::', symbol, cachedTrades);
216584
217292
  }
216585
217293
  }
216586
217294
  async watchOHLCV(symbol, timeframe = '1m', since = undefined, limit = undefined, params = {}) {
@@ -225514,6 +226222,8 @@ class kucoin extends _kucoin_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z
225514
226222
  'watchTickers': false,
225515
226223
  'watchTicker': true,
225516
226224
  'watchTrades': true,
226225
+ 'watchTradesForSymbols': true,
226226
+ 'watchOrderBookForSymbols': true,
225517
226227
  'watchBalance': true,
225518
226228
  'watchOHLCV': true,
225519
226229
  },
@@ -225788,6 +226498,36 @@ class kucoin extends _kucoin_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z
225788
226498
  }
225789
226499
  return this.filterBySinceLimit(trades, since, limit, 'timestamp', true);
225790
226500
  }
226501
+ async watchTradesForSymbols(symbols, since = undefined, limit = undefined, params = {}) {
226502
+ /**
226503
+ * @method
226504
+ * @name kucoin#watchTrades
226505
+ * @description get the list of most recent trades for a particular symbol
226506
+ * @param {string} symbol unified symbol of the market to fetch trades for
226507
+ * @param {int} [since] timestamp in ms of the earliest trade to fetch
226508
+ * @param {int} [limit] the maximum amount of trades to fetch
226509
+ * @param {object} [params] extra parameters specific to the kucoin api endpoint
226510
+ * @returns {object[]} a list of [trade structures]{@link https://docs.ccxt.com/en/latest/manual.html?#public-trades}
226511
+ */
226512
+ const symbolsLength = symbols.length;
226513
+ if (symbolsLength === 0) {
226514
+ throw new _base_errors_js__WEBPACK_IMPORTED_MODULE_2__.ArgumentsRequired(this.id + ' watchTradesForSymbols() requires a non-empty array of symbols');
226515
+ }
226516
+ await this.loadMarkets();
226517
+ symbols = this.marketSymbols(symbols);
226518
+ const url = await this.negotiate(false);
226519
+ symbols = this.marketSymbols(symbols);
226520
+ const marketIds = this.marketIds(symbols);
226521
+ const topic = '/market/match:' + marketIds.join(',');
226522
+ const messageHash = 'multipleTrades::' + symbols.join(',');
226523
+ const trades = await this.subscribe(url, messageHash, topic, params);
226524
+ if (this.newUpdates) {
226525
+ const first = this.safeValue(trades, 0);
226526
+ const tradeSymbol = this.safeString(first, 'symbol');
226527
+ limit = trades.getLimit(tradeSymbol, limit);
226528
+ }
226529
+ return this.filterBySinceLimit(trades, since, limit, 'timestamp', true);
226530
+ }
225791
226531
  handleTrade(client, message) {
225792
226532
  //
225793
226533
  // {
@@ -225820,6 +226560,8 @@ class kucoin extends _kucoin_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z
225820
226560
  }
225821
226561
  trades.append(trade);
225822
226562
  client.resolve(trades, messageHash);
226563
+ // watchMultipleTrades
226564
+ this.resolvePromiseIfMessagehashMatches(client, 'multipleTrades::', symbol, trades);
225823
226565
  }
225824
226566
  async watchOrderBook(symbol, limit = undefined, params = {}) {
225825
226567
  /**
@@ -225865,6 +226607,39 @@ class kucoin extends _kucoin_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z
225865
226607
  const orderbook = await this.subscribe(url, messageHash, topic, params, subscription);
225866
226608
  return orderbook.limit();
225867
226609
  }
226610
+ async watchOrderBookForSymbols(symbols, limit = undefined, params = {}) {
226611
+ /**
226612
+ * @method
226613
+ * @name kucoin#watchOrderBookForSymbols
226614
+ * @description watches information on open orders with bid (buy) and ask (sell) prices, volumes and other data
226615
+ * @param {string[]} symbols unified array of symbols
226616
+ * @param {int} [limit] the maximum amount of order book entries to return
226617
+ * @param {object} [params] extra parameters specific to the kucoin api endpoint
226618
+ * @returns {object} A dictionary of [order book structures]{@link https://docs.ccxt.com/#/?id=order-book-structure} indexed by market symbols
226619
+ */
226620
+ const symbolsLength = symbols.length;
226621
+ if (symbolsLength === 0) {
226622
+ throw new _base_errors_js__WEBPACK_IMPORTED_MODULE_2__.ArgumentsRequired(this.id + ' watchOrderBookForSymbols() requires a non-empty array of symbols');
226623
+ }
226624
+ if (limit !== undefined) {
226625
+ if ((limit !== 20) && (limit !== 100)) {
226626
+ throw new _base_errors_js__WEBPACK_IMPORTED_MODULE_2__.ExchangeError(this.id + " watchOrderBook 'limit' argument must be undefined, 20 or 100");
226627
+ }
226628
+ }
226629
+ await this.loadMarkets();
226630
+ symbols = this.marketSymbols(symbols);
226631
+ const marketIds = this.marketIds(symbols);
226632
+ const url = await this.negotiate(false);
226633
+ const topic = '/market/level2:' + marketIds.join(',');
226634
+ const messageHash = 'multipleOrderbook::' + symbols.join(',');
226635
+ const subscription = {
226636
+ 'method': this.handleOrderBookSubscription,
226637
+ 'symbols': symbols,
226638
+ 'limit': limit,
226639
+ };
226640
+ const orderbook = await this.subscribe(url, messageHash, topic, params, subscription);
226641
+ return orderbook.limit();
226642
+ }
225868
226643
  handleOrderBook(client, message) {
225869
226644
  //
225870
226645
  // initial snapshot is fetched with ccxt's fetchOrderBook
@@ -225895,7 +226670,18 @@ class kucoin extends _kucoin_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z
225895
226670
  if (nonce === undefined) {
225896
226671
  const cacheLength = storedOrderBook.cache.length;
225897
226672
  const topic = this.safeString(message, 'topic');
225898
- const subscription = client.subscriptions[topic];
226673
+ const topicParts = topic.split(':');
226674
+ const topicSymbol = this.safeString(topicParts, 1);
226675
+ const topicChannel = this.safeString(topicParts, 0);
226676
+ const subscriptions = Object.keys(client.subscriptions);
226677
+ let subscription = undefined;
226678
+ for (let i = 0; i < subscriptions.length; i++) {
226679
+ const key = subscriptions[i];
226680
+ if ((key.indexOf(topicSymbol) >= 0) && (key.indexOf(topicChannel) >= 0)) {
226681
+ subscription = client.subscriptions[key];
226682
+ break;
226683
+ }
226684
+ }
225899
226685
  const limit = this.safeInteger(subscription, 'limit');
225900
226686
  const snapshotDelay = this.handleOption('watchOrderBook', 'snapshotDelay', 5);
225901
226687
  if (cacheLength === snapshotDelay) {
@@ -225909,6 +226695,8 @@ class kucoin extends _kucoin_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z
225909
226695
  }
225910
226696
  this.handleDelta(storedOrderBook, data);
225911
226697
  client.resolve(storedOrderBook, messageHash);
226698
+ // watchMultipleOrderBook
226699
+ this.resolvePromiseIfMessagehashMatches(client, 'multipleOrderbook::', symbol, storedOrderBook);
225912
226700
  }
225913
226701
  getCacheIndex(orderbook, cache) {
225914
226702
  const firstDelta = this.safeValue(cache, 0);
@@ -225947,9 +226735,18 @@ class kucoin extends _kucoin_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z
225947
226735
  }
225948
226736
  }
225949
226737
  handleOrderBookSubscription(client, message, subscription) {
225950
- const symbol = this.safeString(subscription, 'symbol');
225951
226738
  const limit = this.safeInteger(subscription, 'limit');
225952
- this.orderbooks[symbol] = this.orderBook({}, limit);
226739
+ const symbols = this.safeValue(subscription, 'symbols');
226740
+ if (symbols === undefined) {
226741
+ const symbol = this.safeString(subscription, 'symbol');
226742
+ this.orderbooks[symbol] = this.orderBook({}, limit);
226743
+ }
226744
+ else {
226745
+ for (let i = 0; i < symbols.length; i++) {
226746
+ const symbol = symbols[i];
226747
+ this.orderbooks[symbol] = this.orderBook({}, limit);
226748
+ }
226749
+ }
225953
226750
  // moved snapshot initialization to handleOrderBook to fix
225954
226751
  // https://github.com/ccxt/ccxt/issues/6820
225955
226752
  // the general idea is to fetch the snapshot after the first delta
@@ -226360,8 +227157,8 @@ class kucoin extends _kucoin_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z
226360
227157
  /* harmony export */ "Z": () => (/* binding */ kucoinfutures)
226361
227158
  /* harmony export */ });
226362
227159
  /* harmony import */ var _kucoinfutures_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1924);
226363
- /* harmony import */ var _base_errors_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(6689);
226364
- /* harmony import */ var _base_ws_Cache_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(3020);
227160
+ /* harmony import */ var _base_errors_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(6689);
227161
+ /* harmony import */ var _base_ws_Cache_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(3020);
226365
227162
  // ---------------------------------------------------------------------------
226366
227163
 
226367
227164
 
@@ -226377,6 +227174,8 @@ class kucoinfutures extends _kucoinfutures_js__WEBPACK_IMPORTED_MODULE_0__/* ["d
226377
227174
  'watchOrderBook': true,
226378
227175
  'watchOrders': true,
226379
227176
  'watchBalance': true,
227177
+ 'watchTradesForSymbols': true,
227178
+ 'watchOrderBookForSymbols': true,
226380
227179
  },
226381
227180
  'options': {
226382
227181
  'accountsByType': {
@@ -226560,6 +227359,36 @@ class kucoinfutures extends _kucoinfutures_js__WEBPACK_IMPORTED_MODULE_0__/* ["d
226560
227359
  }
226561
227360
  return this.filterBySinceLimit(trades, since, limit, 'timestamp', true);
226562
227361
  }
227362
+ async watchTradesForSymbols(symbols, since = undefined, limit = undefined, params = {}) {
227363
+ /**
227364
+ * @method
227365
+ * @name kucoinfutures#watchTrades
227366
+ * @description get the list of most recent trades for a particular symbol
227367
+ * @param {string} symbol unified symbol of the market to fetch trades for
227368
+ * @param {int} [since] timestamp in ms of the earliest trade to fetch
227369
+ * @param {int} [limit] the maximum amount of trades to fetch
227370
+ * @param {object} [params] extra parameters specific to the kucoinfutures api endpoint
227371
+ * @returns {object[]} a list of [trade structures]{@link https://docs.ccxt.com/en/latest/manual.html?#public-trades}
227372
+ */
227373
+ const symbolsLength = symbols.length;
227374
+ if (symbolsLength === 0) {
227375
+ throw new _base_errors_js__WEBPACK_IMPORTED_MODULE_1__.ArgumentsRequired(this.id + ' watchTradesForSymbols() requires a non-empty array of symbols');
227376
+ }
227377
+ await this.loadMarkets();
227378
+ symbols = this.marketSymbols(symbols);
227379
+ const url = await this.negotiate(false);
227380
+ symbols = this.marketSymbols(symbols);
227381
+ const marketIds = this.marketIds(symbols);
227382
+ const topic = '/contractMarket/execution:' + marketIds.join(',');
227383
+ const messageHash = 'multipleTrades::' + symbols.join(',');
227384
+ const trades = await this.subscribe(url, messageHash, topic, params);
227385
+ if (this.newUpdates) {
227386
+ const first = this.safeValue(trades, 0);
227387
+ const tradeSymbol = this.safeString(first, 'symbol');
227388
+ limit = trades.getLimit(tradeSymbol, limit);
227389
+ }
227390
+ return this.filterBySinceLimit(trades, since, limit, 'timestamp', true);
227391
+ }
226563
227392
  handleTrade(client, message) {
226564
227393
  //
226565
227394
  // {
@@ -226587,12 +227416,13 @@ class kucoinfutures extends _kucoinfutures_js__WEBPACK_IMPORTED_MODULE_0__/* ["d
226587
227416
  let trades = this.safeValue(this.trades, symbol);
226588
227417
  if (trades === undefined) {
226589
227418
  const limit = this.safeInteger(this.options, 'tradesLimit', 1000);
226590
- trades = new _base_ws_Cache_js__WEBPACK_IMPORTED_MODULE_1__/* .ArrayCache */ .ZL(limit);
227419
+ trades = new _base_ws_Cache_js__WEBPACK_IMPORTED_MODULE_2__/* .ArrayCache */ .ZL(limit);
226591
227420
  this.trades[symbol] = trades;
226592
227421
  }
226593
227422
  trades.append(trade);
226594
227423
  const messageHash = 'trades:' + symbol;
226595
227424
  client.resolve(trades, messageHash);
227425
+ this.resolvePromiseIfMessagehashMatches(client, 'multipleTrades::', symbol, trades);
226596
227426
  return message;
226597
227427
  }
226598
227428
  async watchOrderBook(symbol, limit = undefined, params = {}) {
@@ -226614,7 +227444,7 @@ class kucoinfutures extends _kucoinfutures_js__WEBPACK_IMPORTED_MODULE_0__/* ["d
226614
227444
  */
226615
227445
  if (limit !== undefined) {
226616
227446
  if ((limit !== 20) && (limit !== 100)) {
226617
- throw new _base_errors_js__WEBPACK_IMPORTED_MODULE_2__.ExchangeError(this.id + " watchOrderBook 'limit' argument must be undefined, 20 or 100");
227447
+ throw new _base_errors_js__WEBPACK_IMPORTED_MODULE_1__.ExchangeError(this.id + " watchOrderBook 'limit' argument must be undefined, 20 or 100");
226618
227448
  }
226619
227449
  }
226620
227450
  await this.loadMarkets();
@@ -226631,6 +227461,39 @@ class kucoinfutures extends _kucoinfutures_js__WEBPACK_IMPORTED_MODULE_0__/* ["d
226631
227461
  const orderbook = await this.subscribe(url, messageHash, topic, subscription, params);
226632
227462
  return orderbook.limit();
226633
227463
  }
227464
+ async watchOrderBookForSymbols(symbols, limit = undefined, params = {}) {
227465
+ /**
227466
+ * @method
227467
+ * @name kucoinfutures#watchOrderBookForSymbols
227468
+ * @description watches information on open orders with bid (buy) and ask (sell) prices, volumes and other data
227469
+ * @param {string[]} symbols unified array of symbols
227470
+ * @param {int} [limit] the maximum amount of order book entries to return
227471
+ * @param {object} [params] extra parameters specific to the kucoinfutures api endpoint
227472
+ * @returns {object} A dictionary of [order book structures]{@link https://docs.ccxt.com/#/?id=order-book-structure} indexed by market symbols
227473
+ */
227474
+ const symbolsLength = symbols.length;
227475
+ if (symbolsLength === 0) {
227476
+ throw new _base_errors_js__WEBPACK_IMPORTED_MODULE_1__.ArgumentsRequired(this.id + ' watchOrderBookForSymbols() requires a non-empty array of symbols');
227477
+ }
227478
+ if (limit !== undefined) {
227479
+ if ((limit !== 20) && (limit !== 100)) {
227480
+ throw new _base_errors_js__WEBPACK_IMPORTED_MODULE_1__.ExchangeError(this.id + " watchOrderBook 'limit' argument must be undefined, 20 or 100");
227481
+ }
227482
+ }
227483
+ await this.loadMarkets();
227484
+ symbols = this.marketSymbols(symbols);
227485
+ const marketIds = this.marketIds(symbols);
227486
+ const url = await this.negotiate(false);
227487
+ const topic = '/contractMarket/level2:' + marketIds.join(',');
227488
+ const messageHash = 'multipleOrderbook::' + symbols.join(',');
227489
+ const subscription = {
227490
+ 'method': this.handleOrderBookSubscription,
227491
+ 'symbols': symbols,
227492
+ 'limit': limit,
227493
+ };
227494
+ const orderbook = await this.subscribe(url, messageHash, topic, subscription, params);
227495
+ return orderbook.limit();
227496
+ }
226634
227497
  handleDelta(orderbook, delta) {
226635
227498
  orderbook['nonce'] = this.safeInteger(delta, 'sequence');
226636
227499
  const timestamp = this.safeInteger(delta, 'timestamp');
@@ -226679,13 +227542,23 @@ class kucoinfutures extends _kucoinfutures_js__WEBPACK_IMPORTED_MODULE_0__/* ["d
226679
227542
  const marketId = this.safeString(topicParts, 1);
226680
227543
  const symbol = this.safeSymbol(marketId, undefined, '-');
226681
227544
  const messageHash = 'orderbook:' + symbol;
226682
- const storedOrderBook = this.orderbooks[symbol];
227545
+ const storedOrderBook = this.safeValue(this.orderbooks, symbol);
226683
227546
  const nonce = this.safeInteger(storedOrderBook, 'nonce');
226684
227547
  const deltaEnd = this.safeInteger(data, 'sequence');
226685
227548
  if (nonce === undefined) {
226686
227549
  const cacheLength = storedOrderBook.cache.length;
226687
- const topic = this.safeString(message, 'topic');
226688
- const subscription = client.subscriptions[topic];
227550
+ const topicParts = topic.split(':');
227551
+ const topicSymbol = this.safeString(topicParts, 1);
227552
+ const topicChannel = this.safeString(topicParts, 0);
227553
+ const subscriptions = Object.keys(client.subscriptions);
227554
+ let subscription = undefined;
227555
+ for (let i = 0; i < subscriptions.length; i++) {
227556
+ const key = subscriptions[i];
227557
+ if ((key.indexOf(topicSymbol) >= 0) && (key.indexOf(topicChannel) >= 0)) {
227558
+ subscription = client.subscriptions[key];
227559
+ break;
227560
+ }
227561
+ }
226689
227562
  const limit = this.safeInteger(subscription, 'limit');
226690
227563
  const snapshotDelay = this.handleOption('watchOrderBook', 'snapshotDelay', 5);
226691
227564
  if (cacheLength === snapshotDelay) {
@@ -226699,6 +227572,7 @@ class kucoinfutures extends _kucoinfutures_js__WEBPACK_IMPORTED_MODULE_0__/* ["d
226699
227572
  }
226700
227573
  this.handleDelta(storedOrderBook, data);
226701
227574
  client.resolve(storedOrderBook, messageHash);
227575
+ this.resolvePromiseIfMessagehashMatches(client, 'multipleOrderbook::', symbol, storedOrderBook);
226702
227576
  }
226703
227577
  getCacheIndex(orderbook, cache) {
226704
227578
  const firstDelta = this.safeValue(cache, 0);
@@ -226717,9 +227591,18 @@ class kucoinfutures extends _kucoinfutures_js__WEBPACK_IMPORTED_MODULE_0__/* ["d
226717
227591
  return cache.length;
226718
227592
  }
226719
227593
  handleOrderBookSubscription(client, message, subscription) {
226720
- const symbol = this.safeString(subscription, 'symbol');
226721
227594
  const limit = this.safeInteger(subscription, 'limit');
226722
- this.orderbooks[symbol] = this.orderBook({}, limit);
227595
+ const symbols = this.safeValue(subscription, 'symbols');
227596
+ if (symbols === undefined) {
227597
+ const symbol = this.safeString(subscription, 'symbol');
227598
+ this.orderbooks[symbol] = this.orderBook({}, limit);
227599
+ }
227600
+ else {
227601
+ for (let i = 0; i < symbols.length; i++) {
227602
+ const symbol = symbols[i];
227603
+ this.orderbooks[symbol] = this.orderBook({}, limit);
227604
+ }
227605
+ }
226723
227606
  // moved snapshot initialization to handleOrderBook to fix
226724
227607
  // https://github.com/ccxt/ccxt/issues/6820
226725
227608
  // the general idea is to fetch the snapshot after the first delta
@@ -226858,7 +227741,7 @@ class kucoinfutures extends _kucoinfutures_js__WEBPACK_IMPORTED_MODULE_0__/* ["d
226858
227741
  if (symbol !== undefined) {
226859
227742
  if (this.orders === undefined) {
226860
227743
  const limit = this.safeInteger(this.options, 'ordersLimit', 1000);
226861
- this.orders = new _base_ws_Cache_js__WEBPACK_IMPORTED_MODULE_1__/* .ArrayCacheBySymbolById */ .hl(limit);
227744
+ this.orders = new _base_ws_Cache_js__WEBPACK_IMPORTED_MODULE_2__/* .ArrayCacheBySymbolById */ .hl(limit);
226862
227745
  }
226863
227746
  const cachedOrders = this.orders;
226864
227747
  const orders = this.safeValue(cachedOrders.hashmap, symbol, {});
@@ -229931,8 +230814,8 @@ class okex extends _okx_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z {
229931
230814
  /* harmony export */ "Z": () => (/* binding */ okx)
229932
230815
  /* harmony export */ });
229933
230816
  /* harmony import */ var _okx_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(4042);
229934
- /* harmony import */ var _base_errors_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(6689);
229935
- /* harmony import */ var _base_ws_Cache_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(3020);
230817
+ /* harmony import */ var _base_errors_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(6689);
230818
+ /* harmony import */ var _base_ws_Cache_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(3020);
229936
230819
  /* harmony import */ var _static_dependencies_noble_hashes_sha256_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(1372);
229937
230820
  // ---------------------------------------------------------------------------
229938
230821
 
@@ -229949,6 +230832,8 @@ class okx extends _okx_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z {
229949
230832
  'watchTickers': true,
229950
230833
  'watchOrderBook': true,
229951
230834
  'watchTrades': true,
230835
+ 'watchTradesForSymbols': true,
230836
+ 'watchOrderBookForSymbols': true,
229952
230837
  'watchBalance': true,
229953
230838
  'watchOHLCV': true,
229954
230839
  'watchOrders': true,
@@ -230102,6 +230987,47 @@ class okx extends _okx_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z {
230102
230987
  }
230103
230988
  return this.filterBySinceLimit(trades, since, limit, 'timestamp', true);
230104
230989
  }
230990
+ async watchTradesForSymbols(symbols, since = undefined, limit = undefined, params = {}) {
230991
+ /**
230992
+ * @method
230993
+ * @name okx#watchTradesForSymbols
230994
+ * @description get the list of most recent trades for a particular symbol
230995
+ * @param {string} symbol unified symbol of the market to fetch trades for
230996
+ * @param {int} [since] timestamp in ms of the earliest trade to fetch
230997
+ * @param {int} [limit] the maximum amount of trades to fetch
230998
+ * @param {object} [params] extra parameters specific to the okx api endpoint
230999
+ * @returns {object[]} a list of [trade structures]{@link https://docs.ccxt.com/en/latest/manual.html?#public-trades}
231000
+ */
231001
+ const symbolsLength = symbols.length;
231002
+ if (symbolsLength === 0) {
231003
+ throw new _base_errors_js__WEBPACK_IMPORTED_MODULE_1__.ArgumentsRequired(this.id + ' watchTradesForSymbols() requires a non-empty array of symbols');
231004
+ }
231005
+ await this.loadMarkets();
231006
+ symbols = this.marketSymbols(symbols);
231007
+ const channel = 'trades';
231008
+ const topics = [];
231009
+ for (let i = 0; i < symbols.length; i++) {
231010
+ const marketId = this.marketId(symbols[i]);
231011
+ const topic = {
231012
+ 'channel': channel,
231013
+ 'instId': marketId,
231014
+ };
231015
+ topics.push(topic);
231016
+ }
231017
+ const request = {
231018
+ 'op': 'subscribe',
231019
+ 'args': topics,
231020
+ };
231021
+ const messageHash = 'multipleTrades::' + symbols.join(',');
231022
+ const url = this.getUrl(channel, 'public');
231023
+ const trades = await this.watch(url, messageHash, request, messageHash);
231024
+ if (this.newUpdates) {
231025
+ const first = this.safeValue(trades, 0);
231026
+ const tradeSymbol = this.safeString(first, 'symbol');
231027
+ limit = trades.getLimit(tradeSymbol, limit);
231028
+ }
231029
+ return this.filterBySinceLimit(trades, since, limit, 'timestamp', true);
231030
+ }
230105
231031
  handleTrades(client, message) {
230106
231032
  //
230107
231033
  // {
@@ -230129,11 +231055,12 @@ class okx extends _okx_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z {
230129
231055
  const messageHash = channel + ':' + marketId;
230130
231056
  let stored = this.safeValue(this.trades, symbol);
230131
231057
  if (stored === undefined) {
230132
- stored = new _base_ws_Cache_js__WEBPACK_IMPORTED_MODULE_1__/* .ArrayCache */ .ZL(tradesLimit);
231058
+ stored = new _base_ws_Cache_js__WEBPACK_IMPORTED_MODULE_2__/* .ArrayCache */ .ZL(tradesLimit);
230133
231059
  this.trades[symbol] = stored;
230134
231060
  }
230135
231061
  stored.append(trade);
230136
231062
  client.resolve(stored, messageHash);
231063
+ this.resolvePromiseIfMessagehashMatches(client, 'multipleTrades::', symbol, stored);
230137
231064
  }
230138
231065
  return message;
230139
231066
  }
@@ -230166,7 +231093,7 @@ class okx extends _okx_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z {
230166
231093
  * @returns {object} a [ticker structure]{@link https://github.com/ccxt/ccxt/wiki/Manual#ticker-structure}
230167
231094
  */
230168
231095
  if (this.isEmpty(symbols)) {
230169
- throw new _base_errors_js__WEBPACK_IMPORTED_MODULE_2__.ArgumentsRequired(this.id + ' watchTickers requires a list of symbols');
231096
+ throw new _base_errors_js__WEBPACK_IMPORTED_MODULE_1__.ArgumentsRequired(this.id + ' watchTickers requires a list of symbols');
230170
231097
  }
230171
231098
  let channel = undefined;
230172
231099
  [channel, params] = this.handleOptionAndParams(params, 'watchTickers', 'channel', 'tickers');
@@ -230281,7 +231208,7 @@ class okx extends _okx_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z {
230281
231208
  let stored = this.safeValue(this.ohlcvs[symbol], timeframe);
230282
231209
  if (stored === undefined) {
230283
231210
  const limit = this.safeInteger(this.options, 'OHLCVLimit', 1000);
230284
- stored = new _base_ws_Cache_js__WEBPACK_IMPORTED_MODULE_1__/* .ArrayCacheByTimestamp */ .Py(limit);
231211
+ stored = new _base_ws_Cache_js__WEBPACK_IMPORTED_MODULE_2__/* .ArrayCacheByTimestamp */ .Py(limit);
230285
231212
  this.ohlcvs[symbol][timeframe] = stored;
230286
231213
  }
230287
231214
  stored.append(parsed);
@@ -230330,6 +231257,41 @@ class okx extends _okx_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z {
230330
231257
  const orderbook = await this.subscribe('public', depth, depth, symbol, params);
230331
231258
  return orderbook.limit();
230332
231259
  }
231260
+ async watchOrderBookForSymbols(symbols, limit = undefined, params = {}) {
231261
+ /**
231262
+ * @method
231263
+ * @name okx#watchOrderBookForSymbols
231264
+ * @description watches information on open orders with bid (buy) and ask (sell) prices, volumes and other data
231265
+ * @param {string[]} symbols unified array of symbols
231266
+ * @param {int} [limit] the maximum amount of order book entries to return
231267
+ * @param {object} [params] extra parameters specific to the okx api endpoint
231268
+ * @returns {object} A dictionary of [order book structures]{@link https://docs.ccxt.com/#/?id=order-book-structure} indexed by market symbols
231269
+ */
231270
+ await this.loadMarkets();
231271
+ symbols = this.marketSymbols(symbols);
231272
+ const options = this.safeValue(this.options, 'watchOrderBook', {});
231273
+ const depth = this.safeString(options, 'depth', 'books');
231274
+ if ((depth === 'books-l2-tbt') || (depth === 'books50-l2-tbt')) {
231275
+ await this.authenticate({ 'access': 'public' });
231276
+ }
231277
+ const topics = [];
231278
+ for (let i = 0; i < symbols.length; i++) {
231279
+ const marketId = this.marketId(symbols[i]);
231280
+ const topic = {
231281
+ 'channel': depth,
231282
+ 'instId': marketId,
231283
+ };
231284
+ topics.push(topic);
231285
+ }
231286
+ const request = {
231287
+ 'op': 'subscribe',
231288
+ 'args': topics,
231289
+ };
231290
+ const url = this.getUrl(depth, 'public');
231291
+ const messageHash = 'multipleOrderbooks::' + symbols.join(',');
231292
+ const orderbook = await this.watch(url, messageHash, request, messageHash);
231293
+ return orderbook.limit();
231294
+ }
230333
231295
  handleDelta(bookside, delta) {
230334
231296
  //
230335
231297
  // [
@@ -230390,7 +231352,7 @@ class okx extends _okx_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z {
230390
231352
  const responseChecksum = this.safeInteger(message, 'checksum');
230391
231353
  const localChecksum = this.crc32(payload, true);
230392
231354
  if (responseChecksum !== localChecksum) {
230393
- const error = new _base_errors_js__WEBPACK_IMPORTED_MODULE_2__.InvalidNonce(this.id + ' invalid checksum');
231355
+ const error = new _base_errors_js__WEBPACK_IMPORTED_MODULE_1__.InvalidNonce(this.id + ' invalid checksum');
230394
231356
  client.reject(error, messageHash);
230395
231357
  }
230396
231358
  }
@@ -230509,6 +231471,7 @@ class okx extends _okx_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z {
230509
231471
  orderbook['symbol'] = symbol;
230510
231472
  this.handleOrderBookMessage(client, update, orderbook, messageHash);
230511
231473
  client.resolve(orderbook, messageHash);
231474
+ this.resolvePromiseIfMessagehashMatches(client, 'multipleOrderbooks::', symbol, orderbook);
230512
231475
  }
230513
231476
  }
230514
231477
  else if (action === 'update') {
@@ -230518,6 +231481,7 @@ class okx extends _okx_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z {
230518
231481
  const update = data[i];
230519
231482
  this.handleOrderBookMessage(client, update, orderbook, messageHash);
230520
231483
  client.resolve(orderbook, messageHash);
231484
+ this.resolvePromiseIfMessagehashMatches(client, 'multipleOrderbooks::', symbol, orderbook);
230521
231485
  }
230522
231486
  }
230523
231487
  }
@@ -230533,6 +231497,7 @@ class okx extends _okx_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z {
230533
231497
  const snapshot = this.parseOrderBook(update, symbol, timestamp, 'bids', 'asks', 0, 1);
230534
231498
  orderbook.reset(snapshot);
230535
231499
  client.resolve(orderbook, messageHash);
231500
+ this.resolvePromiseIfMessagehashMatches(client, 'multipleOrderbooks::', symbol, orderbook);
230536
231501
  }
230537
231502
  }
230538
231503
  return message;
@@ -230803,7 +231768,7 @@ class okx extends _okx_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z {
230803
231768
  if (ordersLength > 0) {
230804
231769
  const limit = this.safeInteger(this.options, 'ordersLimit', 1000);
230805
231770
  if (this.orders === undefined) {
230806
- this.orders = new _base_ws_Cache_js__WEBPACK_IMPORTED_MODULE_1__/* .ArrayCacheBySymbolById */ .hl(limit);
231771
+ this.orders = new _base_ws_Cache_js__WEBPACK_IMPORTED_MODULE_2__/* .ArrayCacheBySymbolById */ .hl(limit);
230807
231772
  }
230808
231773
  const stored = this.orders;
230809
231774
  const marketIds = [];
@@ -230896,7 +231861,7 @@ class okx extends _okx_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z {
230896
231861
  }
230897
231862
  if (this.myTrades === undefined) {
230898
231863
  const limit = this.safeInteger(this.options, 'tradesLimit', 1000);
230899
- this.myTrades = new _base_ws_Cache_js__WEBPACK_IMPORTED_MODULE_1__/* .ArrayCacheBySymbolById */ .hl(limit);
231864
+ this.myTrades = new _base_ws_Cache_js__WEBPACK_IMPORTED_MODULE_2__/* .ArrayCacheBySymbolById */ .hl(limit);
230900
231865
  }
230901
231866
  const myTrades = this.myTrades;
230902
231867
  const symbols = {};
@@ -230939,10 +231904,10 @@ class okx extends _okx_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z {
230939
231904
  const args = this.createOrderRequest(symbol, type, side, amount, price, params);
230940
231905
  const ordType = this.safeString(args, 'ordType');
230941
231906
  if ((ordType === 'trigger') || (ordType === 'conditional') || (type === 'oco') || (type === 'move_order_stop') || (type === 'iceberg') || (type === 'twap')) {
230942
- throw new _base_errors_js__WEBPACK_IMPORTED_MODULE_2__.BadRequest(this.id + ' createOrderWs() does not support algo trading. this.options["createOrderWs"]["op"] must be either order or batch-order');
231907
+ throw new _base_errors_js__WEBPACK_IMPORTED_MODULE_1__.BadRequest(this.id + ' createOrderWs() does not support algo trading. this.options["createOrderWs"]["op"] must be either order or batch-order');
230943
231908
  }
230944
231909
  if ((op !== 'order') && (op !== 'batch-orders')) {
230945
- throw new _base_errors_js__WEBPACK_IMPORTED_MODULE_2__.BadRequest(this.id + ' createOrderWs() does not support algo trading. this.options["createOrderWs"]["op"] must be either order or privatePostTradeOrder or privatePostTradeOrderAlgo');
231910
+ throw new _base_errors_js__WEBPACK_IMPORTED_MODULE_1__.BadRequest(this.id + ' createOrderWs() does not support algo trading. this.options["createOrderWs"]["op"] must be either order or privatePostTradeOrder or privatePostTradeOrderAlgo');
230946
231911
  }
230947
231912
  const request = {
230948
231913
  'id': messageHash,
@@ -231026,7 +231991,7 @@ class okx extends _okx_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z {
231026
231991
  * @returns {object} an list of [order structures]{@link https://github.com/ccxt/ccxt/wiki/Manual#order-structure}
231027
231992
  */
231028
231993
  if (symbol === undefined) {
231029
- throw new _base_errors_js__WEBPACK_IMPORTED_MODULE_2__.BadRequest(this.id + ' cancelOrderWs() requires a symbol argument');
231994
+ throw new _base_errors_js__WEBPACK_IMPORTED_MODULE_1__.BadRequest(this.id + ' cancelOrderWs() requires a symbol argument');
231030
231995
  }
231031
231996
  await this.loadMarkets();
231032
231997
  await this.authenticate();
@@ -231063,10 +232028,10 @@ class okx extends _okx_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z {
231063
232028
  */
231064
232029
  const idsLength = ids.length;
231065
232030
  if (idsLength > 20) {
231066
- throw new _base_errors_js__WEBPACK_IMPORTED_MODULE_2__.BadRequest(this.id + ' cancelOrdersWs() accepts up to 20 ids at a time');
232031
+ throw new _base_errors_js__WEBPACK_IMPORTED_MODULE_1__.BadRequest(this.id + ' cancelOrdersWs() accepts up to 20 ids at a time');
231067
232032
  }
231068
232033
  if (symbol === undefined) {
231069
- throw new _base_errors_js__WEBPACK_IMPORTED_MODULE_2__.BadRequest(this.id + ' cancelOrdersWs() requires a symbol argument');
232034
+ throw new _base_errors_js__WEBPACK_IMPORTED_MODULE_1__.BadRequest(this.id + ' cancelOrdersWs() requires a symbol argument');
231070
232035
  }
231071
232036
  await this.loadMarkets();
231072
232037
  await this.authenticate();
@@ -231098,13 +232063,13 @@ class okx extends _okx_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z {
231098
232063
  * @returns {object[]} a list of [order structures]{@link https://github.com/ccxt/ccxt/wiki/Manual#order-structure}
231099
232064
  */
231100
232065
  if (symbol === undefined) {
231101
- throw new _base_errors_js__WEBPACK_IMPORTED_MODULE_2__.BadRequest(this.id + ' cancelAllOrdersWs() requires a symbol argument');
232066
+ throw new _base_errors_js__WEBPACK_IMPORTED_MODULE_1__.BadRequest(this.id + ' cancelAllOrdersWs() requires a symbol argument');
231102
232067
  }
231103
232068
  await this.loadMarkets();
231104
232069
  await this.authenticate();
231105
232070
  const market = this.market(symbol);
231106
232071
  if (market['type'] !== 'option') {
231107
- throw new _base_errors_js__WEBPACK_IMPORTED_MODULE_2__.BadRequest(this.id + 'cancelAllOrdersWs is only applicable to Option in Portfolio Margin mode, and MMP privilege is required.');
232072
+ throw new _base_errors_js__WEBPACK_IMPORTED_MODULE_1__.BadRequest(this.id + 'cancelAllOrdersWs is only applicable to Option in Portfolio Margin mode, and MMP privilege is required.');
231108
232073
  }
231109
232074
  const url = this.getUrl('private', 'private');
231110
232075
  const messageHash = this.nonce().toString();
@@ -231177,7 +232142,7 @@ class okx extends _okx_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z {
231177
232142
  }
231178
232143
  }
231179
232144
  catch (e) {
231180
- if (e instanceof _base_errors_js__WEBPACK_IMPORTED_MODULE_2__.AuthenticationError) {
232145
+ if (e instanceof _base_errors_js__WEBPACK_IMPORTED_MODULE_1__.AuthenticationError) {
231181
232146
  const messageHash = 'authenticated';
231182
232147
  client.reject(e, messageHash);
231183
232148
  if (messageHash in client.subscriptions) {
@@ -273892,7 +274857,7 @@ SOFTWARE.
273892
274857
 
273893
274858
  //-----------------------------------------------------------------------------
273894
274859
  // this is updated by vss.js when building
273895
- const version = '4.0.88';
274860
+ const version = '4.0.90';
273896
274861
  _src_base_Exchange_js__WEBPACK_IMPORTED_MODULE_0__/* .Exchange.ccxtVersion */ .e.ccxtVersion = version;
273897
274862
  //-----------------------------------------------------------------------------
273898
274863