ccxt 4.1.87 → 4.1.89

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 (101) hide show
  1. package/CHANGELOG.md +8309 -5710
  2. package/README.md +10 -9
  3. package/changelog.js +101 -0
  4. package/dist/ccxt.browser.js +8628 -4849
  5. package/dist/ccxt.browser.min.js +3 -3
  6. package/dist/cjs/ccxt.js +6 -1
  7. package/dist/cjs/src/base/Exchange.js +95 -27
  8. package/dist/cjs/src/base/ws/Client.js +3 -3
  9. package/dist/cjs/src/base/ws/Future.js +9 -2
  10. package/dist/cjs/src/base/ws/WsClient.js +1 -1
  11. package/dist/cjs/src/bigone.js +8 -1
  12. package/dist/cjs/src/binance.js +4 -105
  13. package/dist/cjs/src/bit2c.js +8 -2
  14. package/dist/cjs/src/bitget.js +3455 -2480
  15. package/dist/cjs/src/bitmart.js +35 -9
  16. package/dist/cjs/src/coinbase.js +2 -0
  17. package/dist/cjs/src/coinbasepro.js +0 -43
  18. package/dist/cjs/src/coinex.js +14 -1
  19. package/dist/cjs/src/coinsph.js +0 -29
  20. package/dist/cjs/src/cryptocom.js +22 -10
  21. package/dist/cjs/src/gate.js +37 -39
  22. package/dist/cjs/src/gemini.js +1 -0
  23. package/dist/cjs/src/novadax.js +28 -16
  24. package/dist/cjs/src/okcoin.js +80 -21
  25. package/dist/cjs/src/phemex.js +105 -29
  26. package/dist/cjs/src/pro/binance.js +18 -215
  27. package/dist/cjs/src/pro/bitget.js +780 -736
  28. package/dist/cjs/src/pro/bitmart.js +8 -10
  29. package/dist/cjs/src/pro/bitmex.js +9 -34
  30. package/dist/cjs/src/pro/bitpanda.js +4 -4
  31. package/dist/cjs/src/pro/bybit.js +21 -97
  32. package/dist/cjs/src/pro/coinbasepro.js +36 -40
  33. package/dist/cjs/src/pro/cryptocom.js +10 -26
  34. package/dist/cjs/src/pro/gate.js +20 -17
  35. package/dist/cjs/src/pro/kucoin.js +39 -39
  36. package/dist/cjs/src/pro/kucoinfutures.js +40 -36
  37. package/dist/cjs/src/pro/okx.js +16 -29
  38. package/dist/cjs/src/tokocrypto.js +28 -14
  39. package/dist/cjs/src/woo.js +41 -14
  40. package/js/ccxt.d.ts +8 -2
  41. package/js/ccxt.js +6 -2
  42. package/js/src/abstract/bitget.d.ts +1 -1
  43. package/js/src/abstract/coinbasepro.d.ts +69 -0
  44. package/js/src/abstract/coinbasepro.js +11 -0
  45. package/js/src/abstract/phemex.d.ts +1 -0
  46. package/js/src/base/Exchange.d.ts +2 -3
  47. package/js/src/base/Exchange.js +96 -28
  48. package/js/src/base/ws/Client.d.ts +2 -2
  49. package/js/src/base/ws/Client.js +4 -4
  50. package/js/src/base/ws/Future.d.ts +5 -2
  51. package/js/src/base/ws/Future.js +8 -2
  52. package/js/src/base/ws/WsClient.d.ts +1 -1
  53. package/js/src/base/ws/WsClient.js +2 -2
  54. package/js/src/bigone.js +9 -2
  55. package/js/src/binance.d.ts +0 -9
  56. package/js/src/binance.js +4 -105
  57. package/js/src/bit2c.js +8 -2
  58. package/js/src/bitget.d.ts +13 -11
  59. package/js/src/bitget.js +3455 -2480
  60. package/js/src/bitmart.js +35 -9
  61. package/js/src/coinbase.js +2 -0
  62. package/js/src/coinbasepro.d.ts +0 -4
  63. package/js/src/coinbasepro.js +1 -44
  64. package/js/src/coinex.js +14 -1
  65. package/js/src/coinsph.d.ts +0 -1
  66. package/js/src/coinsph.js +0 -29
  67. package/js/src/cryptocom.js +22 -10
  68. package/js/src/gate.js +37 -39
  69. package/js/src/gemini.js +1 -0
  70. package/js/src/novadax.js +28 -16
  71. package/js/src/okcoin.d.ts +1 -0
  72. package/js/src/okcoin.js +81 -22
  73. package/js/src/phemex.d.ts +2 -108
  74. package/js/src/phemex.js +105 -29
  75. package/js/src/pro/binance.d.ts +0 -2
  76. package/js/src/pro/binance.js +19 -216
  77. package/js/src/pro/bitget.d.ts +3 -5
  78. package/js/src/pro/bitget.js +780 -736
  79. package/js/src/pro/bitmart.js +8 -10
  80. package/js/src/pro/bitmex.js +9 -34
  81. package/js/src/pro/bitpanda.d.ts +1 -1
  82. package/js/src/pro/bitpanda.js +4 -4
  83. package/js/src/pro/bybit.d.ts +1 -2
  84. package/js/src/pro/bybit.js +21 -97
  85. package/js/src/pro/coinbasepro.d.ts +2 -2
  86. package/js/src/pro/coinbasepro.js +36 -40
  87. package/js/src/pro/cryptocom.d.ts +1 -1
  88. package/js/src/pro/cryptocom.js +10 -26
  89. package/js/src/pro/gate.d.ts +1 -0
  90. package/js/src/pro/gate.js +20 -17
  91. package/js/src/pro/kucoin.d.ts +1 -0
  92. package/js/src/pro/kucoin.js +39 -39
  93. package/js/src/pro/kucoinfutures.d.ts +2 -1
  94. package/js/src/pro/kucoinfutures.js +40 -36
  95. package/js/src/pro/okx.d.ts +1 -1
  96. package/js/src/pro/okx.js +16 -29
  97. package/js/src/tokocrypto.js +28 -14
  98. package/js/src/woo.d.ts +1 -0
  99. package/js/src/woo.js +42 -15
  100. package/package.json +2 -2
  101. package/skip-tests.json +3 -14
@@ -149,24 +149,6 @@ class binance extends binance$1 {
149
149
  // valid <levels> are 5, 10, or 20
150
150
  //
151
151
  // default 100, max 1000, valid limits 5, 10, 20, 50, 100, 500, 1000
152
- await this.loadMarkets();
153
- const market = this.market(symbol);
154
- if (limit !== undefined) {
155
- if (market['contract']) {
156
- if ((limit !== 5) && (limit !== 10) && (limit !== 20) && (limit !== 50) && (limit !== 100) && (limit !== 500) && (limit !== 1000)) {
157
- throw new errors.ExchangeError(this.id + ' watchOrderBook limit argument must be undefined, 5, 10, 20, 50, 100, 500 or 1000');
158
- }
159
- }
160
- else {
161
- if (limit > 5000) {
162
- throw new errors.ExchangeError(this.id + ' watchOrderBook limit argument must be less than or equal to 5000');
163
- }
164
- }
165
- }
166
- let type = market['type'];
167
- if (market['contract']) {
168
- type = market['linear'] ? 'future' : 'delivery';
169
- }
170
152
  //
171
153
  // notice the differences between trading futures and spot trading
172
154
  // the algorithms use different urls in step 1
@@ -198,32 +180,7 @@ class binance extends binance$1 {
198
180
  // 8. If the quantity is 0, remove the price level.
199
181
  // 9. Receiving an event that removes a price level that is not in your local order book can happen and is normal.
200
182
  //
201
- const name = 'depth';
202
- const messageHash = market['lowercaseId'] + '@' + name;
203
- const url = this.urls['api']['ws'][type] + '/' + this.stream(type, messageHash);
204
- const requestId = this.requestId(url);
205
- const watchOrderBookRate = this.safeString(this.options, 'watchOrderBookRate', '100');
206
- const request = {
207
- 'method': 'SUBSCRIBE',
208
- 'params': [
209
- messageHash + '@' + watchOrderBookRate + 'ms',
210
- ],
211
- 'id': requestId,
212
- };
213
- const subscription = {
214
- 'id': requestId.toString(),
215
- 'messageHash': messageHash,
216
- 'name': name,
217
- 'symbol': market['symbol'],
218
- 'method': this.handleOrderBookSubscription,
219
- 'limit': limit,
220
- 'type': type,
221
- 'params': params,
222
- };
223
- const message = this.extend(request, params);
224
- // 1. Open a stream to wss://stream.binance.com:9443/ws/bnbbtc@depth.
225
- const orderbook = await this.watch(url, messageHash, message, messageHash, subscription);
226
- return orderbook.limit();
183
+ return await this.watchOrderBookForSymbols([symbol], limit, params);
227
184
  }
228
185
  async watchOrderBookForSymbols(symbols, limit = undefined, params = {}) {
229
186
  /**
@@ -243,15 +200,17 @@ class binance extends binance$1 {
243
200
  type = firstMarket['linear'] ? 'future' : 'delivery';
244
201
  }
245
202
  const name = 'depth';
246
- const messageHash = 'multipleOrderbook::' + symbols.join(',');
247
203
  const url = this.urls['api']['ws'][type] + '/' + this.stream(type, 'multipleOrderbook');
248
204
  const requestId = this.requestId(url);
249
205
  const watchOrderBookRate = this.safeString(this.options, 'watchOrderBookRate', '100');
250
206
  const subParams = [];
207
+ const messageHashes = [];
251
208
  for (let i = 0; i < symbols.length; i++) {
252
209
  const symbol = symbols[i];
253
210
  const market = this.market(symbol);
254
- const symbolHash = market['lowercaseId'] + '@' + name + '@' + watchOrderBookRate + 'ms';
211
+ const messageHash = market['lowercaseId'] + '@' + name;
212
+ messageHashes.push(messageHash);
213
+ const symbolHash = messageHash + '@' + watchOrderBookRate + 'ms';
255
214
  subParams.push(symbolHash);
256
215
  }
257
216
  const request = {
@@ -261,7 +220,6 @@ class binance extends binance$1 {
261
220
  };
262
221
  const subscription = {
263
222
  'id': requestId.toString(),
264
- 'messageHash': messageHash,
265
223
  'name': name,
266
224
  'symbols': symbols,
267
225
  'method': this.handleOrderBookSubscription,
@@ -270,12 +228,14 @@ class binance extends binance$1 {
270
228
  'params': params,
271
229
  };
272
230
  const message = this.extend(request, params);
273
- const orderbook = await this.watch(url, messageHash, message, messageHash, subscription);
231
+ const orderbook = await this.watchMultiple(url, messageHashes, message, messageHashes, subscription);
274
232
  return orderbook.limit();
275
233
  }
276
234
  async fetchOrderBookSnapshot(client, message, subscription) {
277
- const messageHash = this.safeString(subscription, 'messageHash');
235
+ const name = this.safeString(subscription, 'name');
278
236
  const symbol = this.safeString(subscription, 'symbol');
237
+ const market = this.market(symbol);
238
+ const messageHash = market['lowercaseId'] + '@' + name;
279
239
  try {
280
240
  const defaultLimit = this.safeInteger(this.options, 'watchOrderBookLimit', 1000);
281
241
  const type = this.safeValue(subscription, 'type');
@@ -415,8 +375,6 @@ class binance extends binance$1 {
415
375
  this.handleOrderBookMessage(client, message, orderbook);
416
376
  if (nonce < orderbook['nonce']) {
417
377
  client.resolve(orderbook, messageHash);
418
- // watchOrderBookForSymbols part (dry logic)
419
- this.resolvePromiseIfMessagehashMatches(client, 'multipleOrderbook::', symbol, orderbook);
420
378
  }
421
379
  }
422
380
  else {
@@ -435,8 +393,6 @@ class binance extends binance$1 {
435
393
  this.handleOrderBookMessage(client, message, orderbook);
436
394
  if (nonce <= orderbook['nonce']) {
437
395
  client.resolve(orderbook, messageHash);
438
- // watchOrderBookForSymbols part (dry logic)
439
- this.resolvePromiseIfMessagehashMatches(client, 'multipleOrderbook::', symbol, orderbook);
440
396
  }
441
397
  }
442
398
  else {
@@ -514,9 +470,8 @@ class binance extends binance$1 {
514
470
  const currentMessageHash = market['lowercaseId'] + '@' + name;
515
471
  subParams.push(currentMessageHash);
516
472
  }
517
- const messageHash = 'multipleTrades::' + symbols.join(',');
518
473
  const query = this.omit(params, 'type');
519
- const url = this.urls['api']['ws'][type] + '/' + this.stream(type, messageHash);
474
+ const url = this.urls['api']['ws'][type] + '/' + this.stream(type, 'multipleTrades');
520
475
  const requestId = this.requestId(url);
521
476
  const request = {
522
477
  'method': 'SUBSCRIBE',
@@ -526,7 +481,7 @@ class binance extends binance$1 {
526
481
  const subscribe = {
527
482
  'id': requestId,
528
483
  };
529
- const trades = await this.watch(url, messageHash, this.extend(request, query), messageHash, subscribe);
484
+ const trades = await this.watch(url, subParams, this.extend(request, query), subParams, subscribe);
530
485
  if (this.newUpdates) {
531
486
  const first = this.safeValue(trades, 0);
532
487
  const tradeSymbol = this.safeString(first, 'symbol');
@@ -545,33 +500,7 @@ class binance extends binance$1 {
545
500
  * @param {object} [params] extra parameters specific to the exchange API endpoint
546
501
  * @returns {object[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=public-trades}
547
502
  */
548
- await this.loadMarkets();
549
- const market = this.market(symbol);
550
- const options = this.safeValue(this.options, 'watchTrades', {});
551
- const name = this.safeString(options, 'name', 'trade');
552
- const messageHash = market['lowercaseId'] + '@' + name;
553
- let type = market['type'];
554
- if (market['contract']) {
555
- type = market['linear'] ? 'future' : 'delivery';
556
- }
557
- const query = this.omit(params, 'type');
558
- const url = this.urls['api']['ws'][type] + '/' + this.stream(type, messageHash);
559
- const requestId = this.requestId(url);
560
- const request = {
561
- 'method': 'SUBSCRIBE',
562
- 'params': [
563
- messageHash,
564
- ],
565
- 'id': requestId,
566
- };
567
- const subscribe = {
568
- 'id': requestId,
569
- };
570
- const trades = await this.watch(url, messageHash, this.extend(request, query), messageHash, subscribe);
571
- if (this.newUpdates) {
572
- limit = trades.getLimit(market['symbol'], limit);
573
- }
574
- return this.filterBySinceLimit(trades, since, limit, 'timestamp', true);
503
+ return await this.watchTradesForSymbols([symbol], since, limit, params);
575
504
  }
576
505
  parseTrade(trade, market = undefined) {
577
506
  //
@@ -755,8 +684,6 @@ class binance extends binance$1 {
755
684
  tradesArray.append(trade);
756
685
  this.trades[symbol] = tradesArray;
757
686
  client.resolve(tradesArray, messageHash);
758
- // watchTradesForSymbols part
759
- this.resolvePromiseIfMessagehashMatches(client, 'multipleTrades::', symbol, tradesArray);
760
687
  }
761
688
  async watchOHLCV(symbol, timeframe = '1m', since = undefined, limit = undefined, params = {}) {
762
689
  /**
@@ -805,62 +732,6 @@ class binance extends binance$1 {
805
732
  }
806
733
  return this.filterBySinceLimit(ohlcv, since, limit, 0, true);
807
734
  }
808
- async watchOHLCVForSymbols(symbolsAndTimeframes, since = undefined, limit = undefined, params = {}) {
809
- /**
810
- * @method
811
- * @name binance#watchOHLCVForSymbols
812
- * @description watches historical candlestick data containing the open, high, low, and close price, and the volume of a market
813
- * @param {string[][]} symbolsAndTimeframes array of arrays containing unified symbols and timeframes to fetch OHLCV data for, example [['BTC/USDT', '1m'], ['LTC/USDT', '5m']]
814
- * @param {int} [since] timestamp in ms of the earliest candle to fetch
815
- * @param {int} [limit] the maximum amount of candles to fetch
816
- * @param {object} [params] extra parameters specific to the exchange API endpoint
817
- * @returns {int[][]} A list of candles ordered as timestamp, open, high, low, close, volume
818
- */
819
- await this.loadMarkets();
820
- const options = this.safeValue(this.options, 'watchOHLCV', {});
821
- const nameOption = this.safeString(options, 'name', 'kline');
822
- const name = this.safeString(params, 'name', nameOption);
823
- params = this.omit(params, 'name');
824
- const firstMarket = this.market(symbolsAndTimeframes[0][0]);
825
- let type = firstMarket['type'];
826
- if (firstMarket['contract']) {
827
- type = firstMarket['linear'] ? 'future' : 'delivery';
828
- }
829
- const subParams = [];
830
- const hashes = [];
831
- for (let i = 0; i < symbolsAndTimeframes.length; i++) {
832
- const data = symbolsAndTimeframes[i];
833
- const symbolString = data[0];
834
- const timeframeString = data[1];
835
- const interval = this.safeString(this.timeframes, timeframeString, timeframeString);
836
- const market = this.market(symbolString);
837
- let marketId = market['lowercaseId'];
838
- if (name === 'indexPriceKline') {
839
- // weird behavior for index price kline we can't use the perp suffix
840
- marketId = marketId.replace('_perp', '');
841
- }
842
- const topic = marketId + '@' + name + '_' + interval;
843
- subParams.push(topic);
844
- hashes.push(symbolString + '#' + timeframeString);
845
- }
846
- const messageHash = 'multipleOHLCV::' + hashes.join(',');
847
- const url = this.urls['api']['ws'][type] + '/' + this.stream(type, messageHash);
848
- const requestId = this.requestId(url);
849
- const request = {
850
- 'method': 'SUBSCRIBE',
851
- 'params': subParams,
852
- 'id': requestId,
853
- };
854
- const subscribe = {
855
- 'id': requestId,
856
- };
857
- const [symbol, timeframe, stored] = await this.watch(url, messageHash, this.extend(request, params), messageHash, subscribe);
858
- if (this.newUpdates) {
859
- limit = stored.getLimit(symbol, limit);
860
- }
861
- const filtered = this.filterBySinceLimit(stored, since, limit, 0, true);
862
- return this.createOHLCVObject(symbol, timeframe, filtered);
863
- }
864
735
  handleOHLCV(client, message) {
865
736
  //
866
737
  // {
@@ -925,8 +796,6 @@ class binance extends binance$1 {
925
796
  }
926
797
  stored.append(parsed);
927
798
  client.resolve(stored, messageHash);
928
- // watchOHLCVForSymbols part
929
- this.resolveMultipleOHLCV(client, 'multipleOHLCV::', symbol, timeframe, stored);
930
799
  }
931
800
  async watchTicker(symbol, params = {}) {
932
801
  /**
@@ -995,10 +864,7 @@ class binance extends binance$1 {
995
864
  name = this.safeString(params, 'name', name);
996
865
  params = this.omit(params, 'name');
997
866
  let wsParams = [];
998
- let messageHash = 'tickers';
999
- if (symbols !== undefined) {
1000
- messageHash = 'tickers::' + symbols.join(',');
1001
- }
867
+ const messageHash = 'tickers';
1002
868
  if (name === 'bookTicker') {
1003
869
  if (marketIds === undefined) {
1004
870
  throw new errors.ArgumentsRequired(this.id + ' watchTickers() requires symbols for bookTicker');
@@ -1192,19 +1058,6 @@ class binance extends binance$1 {
1192
1058
  this.tickers[symbol] = result;
1193
1059
  newTickers.push(result);
1194
1060
  }
1195
- const messageHashes = this.findMessageHashes(client, 'tickers::');
1196
- for (let i = 0; i < messageHashes.length; i++) {
1197
- const messageHash = messageHashes[i];
1198
- const parts = messageHash.split('::');
1199
- const symbolsString = parts[1];
1200
- const symbols = symbolsString.split(',');
1201
- const tickers = this.filterByArray(newTickers, 'symbol', symbols);
1202
- const tickersSymbols = Object.keys(tickers);
1203
- const numTickers = tickersSymbols.length;
1204
- if (numTickers > 0) {
1205
- client.resolve(tickers, messageHash);
1206
- }
1207
- }
1208
1061
  client.resolve(newTickers, 'tickers');
1209
1062
  }
1210
1063
  signParams(params = {}) {
@@ -2085,7 +1938,7 @@ class binance extends binance$1 {
2085
1938
  if (symbol !== undefined) {
2086
1939
  market = this.market(symbol);
2087
1940
  symbol = market['symbol'];
2088
- messageHash += '::' + symbol;
1941
+ messageHash += ':' + symbol;
2089
1942
  }
2090
1943
  let type = undefined;
2091
1944
  [type, params] = this.handleMarketTypeAndParams('watchOrders', market, params);
@@ -2114,58 +1967,6 @@ class binance extends binance$1 {
2114
1967
  }
2115
1968
  return this.filterBySymbolSinceLimit(this.orders, symbol, since, limit, true);
2116
1969
  }
2117
- async watchOrdersForSymbols(symbols = undefined, since = undefined, limit = undefined, params = {}) {
2118
- /**
2119
- * @method
2120
- * @name binance#watchOrdersForSymbols
2121
- * @see https://binance-docs.github.io/apidocs/spot/en/#payload-order-update
2122
- * @description watches information on multiple orders made by the user
2123
- * @param {string[]} symbols unified symbol of the market to fetch orders for
2124
- * @param {int} [since] the earliest time in ms to fetch orders for
2125
- * @param {int} [limit] the maximum number of trade structures to retrieve
2126
- * @param {object} [params] extra parameters specific to the exchange API endpoint
2127
- * @returns {object[]} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
2128
- */
2129
- let marginMode = undefined;
2130
- [marginMode, params] = this.handleMarginModeAndParams('authenticate', params);
2131
- const isIsolatedMargin = (marginMode === 'isolated');
2132
- if (isIsolatedMargin) {
2133
- throw new errors.NotSupported(this.id + ' watchOrdersForSymbols does not support isolated margin markets, use watchOrders instead');
2134
- }
2135
- await this.loadMarkets();
2136
- let type = undefined;
2137
- const market = this.getMarketFromSymbols(symbols);
2138
- [type, params] = this.handleMarketTypeAndParams('watchOrdersForSymbols', market, params);
2139
- symbols = this.marketSymbols(symbols, type, true, true, true);
2140
- let messageHash = 'orders';
2141
- if (symbols !== undefined) {
2142
- messageHash = messageHash + '::' + symbols.join(',');
2143
- }
2144
- let subType = undefined;
2145
- [subType, params] = this.handleSubTypeAndParams('watchOrdersForSymbols', market, params);
2146
- if (this.isLinear(type, subType)) {
2147
- type = 'future';
2148
- }
2149
- else if (this.isInverse(type, subType)) {
2150
- type = 'delivery';
2151
- }
2152
- params = this.extend(params, { 'type': type });
2153
- await this.authenticate(params);
2154
- let urlType = type;
2155
- if (type === 'margin') {
2156
- urlType = 'spot'; // spot-margin shares the same stream as regular spot
2157
- }
2158
- const url = this.urls['api']['ws'][urlType] + '/' + this.options[type]['listenKey'];
2159
- const client = this.client(url);
2160
- this.setBalanceCache(client, type);
2161
- this.setPositionsCache(client, type);
2162
- const message = undefined;
2163
- const newOrders = await this.watch(url, messageHash, message, type);
2164
- if (this.newUpdates) {
2165
- return newOrders;
2166
- }
2167
- return this.filterBySymbolsSinceLimit(this.orders, symbols, since, limit, true);
2168
- }
2169
1970
  parseWsOrder(order, market = undefined) {
2170
1971
  //
2171
1972
  // spot
@@ -2823,8 +2624,10 @@ class binance extends binance$1 {
2823
2624
  }
2824
2625
  }
2825
2626
  cachedOrders.append(parsed);
2826
- this.resolvePromiseIfMessagehashMatches(client, 'orders::', symbol, parsed);
2827
- client.resolve(parsed, 'orders');
2627
+ const messageHash = 'orders';
2628
+ const symbolSpecificMessageHash = 'orders:' + symbol;
2629
+ client.resolve(parsed, messageHash);
2630
+ client.resolve(parsed, symbolSpecificMessageHash);
2828
2631
  }
2829
2632
  }
2830
2633
  handleAcountUpdate(client, message) {