ccxt 4.5.6 → 4.5.7

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 (84) hide show
  1. package/README.md +3 -3
  2. package/dist/ccxt.browser.min.js +3 -3
  3. package/dist/cjs/ccxt.js +1 -1
  4. package/dist/cjs/src/apex.js +2 -2
  5. package/dist/cjs/src/binance.js +3 -0
  6. package/dist/cjs/src/bitbank.js +1 -0
  7. package/dist/cjs/src/bitbns.js +1 -0
  8. package/dist/cjs/src/bitflyer.js +1 -0
  9. package/dist/cjs/src/bithumb.js +1 -0
  10. package/dist/cjs/src/bitso.js +1 -0
  11. package/dist/cjs/src/bitvavo.js +26 -40
  12. package/dist/cjs/src/blockchaincom.js +1 -0
  13. package/dist/cjs/src/btcalpha.js +1 -0
  14. package/dist/cjs/src/btcbox.js +1 -0
  15. package/dist/cjs/src/btcmarkets.js +1 -0
  16. package/dist/cjs/src/btcturk.js +1 -0
  17. package/dist/cjs/src/deribit.js +3 -2
  18. package/dist/cjs/src/digifinex.js +1 -1
  19. package/dist/cjs/src/gate.js +8 -12
  20. package/dist/cjs/src/gemini.js +3 -3
  21. package/dist/cjs/src/htx.js +11 -1
  22. package/dist/cjs/src/independentreserve.js +1 -0
  23. package/dist/cjs/src/indodax.js +17 -6
  24. package/dist/cjs/src/kraken.js +25 -6
  25. package/dist/cjs/src/krakenfutures.js +1 -0
  26. package/dist/cjs/src/mercado.js +1 -0
  27. package/dist/cjs/src/mexc.js +80 -36
  28. package/dist/cjs/src/novadax.js +1 -0
  29. package/dist/cjs/src/oceanex.js +1 -0
  30. package/dist/cjs/src/okx.js +18 -5
  31. package/dist/cjs/src/pro/apex.js +7 -4
  32. package/dist/cjs/src/pro/backpack.js +6 -4
  33. package/dist/cjs/src/pro/bingx.js +206 -220
  34. package/dist/cjs/src/pro/htx.js +1 -1
  35. package/dist/cjs/src/upbit.js +1 -0
  36. package/dist/cjs/src/wavesexchange.js +1 -0
  37. package/dist/cjs/src/yobit.js +1 -0
  38. package/dist/cjs/src/zaif.js +1 -0
  39. package/dist/cjs/src/zonda.js +1 -0
  40. package/js/ccxt.d.ts +1 -1
  41. package/js/ccxt.js +1 -1
  42. package/js/src/abstract/mexc.d.ts +1 -0
  43. package/js/src/apex.js +2 -2
  44. package/js/src/binance.js +3 -0
  45. package/js/src/bitbank.js +1 -0
  46. package/js/src/bitbns.js +1 -0
  47. package/js/src/bitflyer.js +1 -0
  48. package/js/src/bithumb.js +1 -0
  49. package/js/src/bitso.js +1 -0
  50. package/js/src/bitvavo.d.ts +0 -2
  51. package/js/src/bitvavo.js +27 -41
  52. package/js/src/blockchaincom.js +1 -0
  53. package/js/src/btcalpha.js +1 -0
  54. package/js/src/btcbox.js +1 -0
  55. package/js/src/btcmarkets.js +1 -0
  56. package/js/src/btcturk.js +1 -0
  57. package/js/src/deribit.js +3 -2
  58. package/js/src/digifinex.js +1 -1
  59. package/js/src/gate.d.ts +2 -2
  60. package/js/src/gate.js +8 -12
  61. package/js/src/gemini.js +3 -3
  62. package/js/src/htx.js +11 -1
  63. package/js/src/independentreserve.js +1 -0
  64. package/js/src/indodax.js +17 -6
  65. package/js/src/kraken.d.ts +1 -1
  66. package/js/src/kraken.js +25 -6
  67. package/js/src/krakenfutures.js +1 -0
  68. package/js/src/mercado.js +1 -0
  69. package/js/src/mexc.d.ts +4 -1
  70. package/js/src/mexc.js +80 -36
  71. package/js/src/novadax.js +1 -0
  72. package/js/src/oceanex.js +1 -0
  73. package/js/src/okx.js +18 -5
  74. package/js/src/pro/apex.js +7 -4
  75. package/js/src/pro/backpack.js +6 -4
  76. package/js/src/pro/bingx.d.ts +53 -33
  77. package/js/src/pro/bingx.js +207 -221
  78. package/js/src/pro/htx.js +1 -1
  79. package/js/src/upbit.js +1 -0
  80. package/js/src/wavesexchange.js +1 -0
  81. package/js/src/yobit.js +1 -0
  82. package/js/src/zaif.js +1 -0
  83. package/js/src/zonda.js +1 -0
  84. package/package.json +1 -1
@@ -1,6 +1,6 @@
1
1
  // ---------------------------------------------------------------------------
2
2
  import bingxRest from '../bingx.js';
3
- import { BadRequest, NetworkError, NotSupported, ArgumentsRequired } from '../base/errors.js';
3
+ import { BadRequest, NetworkError, NotSupported } from '../base/errors.js';
4
4
  import { ArrayCache, ArrayCacheByTimestamp, ArrayCacheBySymbolById } from '../base/ws/Cache.js';
5
5
  // ---------------------------------------------------------------------------
6
6
  export default class bingx extends bingxRest {
@@ -11,14 +11,18 @@ export default class bingx extends bingxRest {
11
11
  'watchTrades': true,
12
12
  'watchTradesForSymbols': false,
13
13
  'watchOrderBook': true,
14
- 'watchOrderBookForSymbols': true,
14
+ 'watchOrderBookForSymbols': false,
15
15
  'watchOHLCV': true,
16
- 'watchOHLCVForSymbols': true,
16
+ 'watchOHLCVForSymbols': false,
17
17
  'watchOrders': true,
18
18
  'watchMyTrades': true,
19
19
  'watchTicker': true,
20
- 'watchTickers': true,
20
+ 'watchTickers': false,
21
21
  'watchBalance': true,
22
+ 'unWatchOHLCV': true,
23
+ 'unWatchOrderBook': true,
24
+ 'unWatchTicker': true,
25
+ 'unWatchTrades': true,
22
26
  },
23
27
  'urls': {
24
28
  'api': {
@@ -67,12 +71,8 @@ export default class bingx extends bingxRest {
67
71
  'awaitBalanceSnapshot': false, // whether to wait for the balance snapshot before providing updates
68
72
  },
69
73
  'watchOrderBook': {
70
- 'depth': 100,
71
- 'interval': 500, // 100, 200, 500, 1000
72
- },
73
- 'watchOrderBookForSymbols': {
74
- 'depth': 100,
75
- 'interval': 500, // 100, 200, 500, 1000
74
+ 'depth': 100, // 5, 10, 20, 50, 100
75
+ // 'interval': 500, // 100, 200, 500, 1000
76
76
  },
77
77
  'watchTrades': {
78
78
  'ignoreDuplicates': true,
@@ -83,6 +83,43 @@ export default class bingx extends bingxRest {
83
83
  },
84
84
  });
85
85
  }
86
+ async unWatch(messageHash, subMessageHash, subscribeHash, dataType, topic, market, methodName, params = {}) {
87
+ let marketType = undefined;
88
+ let subType = undefined;
89
+ let url = undefined;
90
+ [marketType, params] = this.handleMarketTypeAndParams(methodName, market, params);
91
+ [subType, params] = this.handleSubTypeAndParams(methodName, market, params, 'linear');
92
+ if (marketType === 'swap') {
93
+ url = this.safeString(this.urls['api']['ws'], subType);
94
+ }
95
+ else {
96
+ url = this.safeString(this.urls['api']['ws'], marketType);
97
+ }
98
+ const id = this.uuid();
99
+ const request = {
100
+ 'id': id,
101
+ 'dataType': dataType,
102
+ 'reqType': 'unsub',
103
+ };
104
+ const symbols = [];
105
+ if (market !== undefined) {
106
+ symbols.push(market['symbol']);
107
+ }
108
+ const subscription = {
109
+ 'unsubscribe': true,
110
+ 'id': id,
111
+ 'subMessageHashes': [subMessageHash],
112
+ 'messageHashes': [messageHash],
113
+ 'symbols': symbols,
114
+ 'topic': topic,
115
+ };
116
+ const symbolsAndTimeframes = this.safeList(params, 'symbolsAndTimeframes');
117
+ if (symbolsAndTimeframes !== undefined) {
118
+ subscription['symbolsAndTimeframes'] = symbolsAndTimeframes;
119
+ params = this.omit(params, 'symbolsAndTimeframes');
120
+ }
121
+ return await this.watch(url, messageHash, this.extend(request, params), subscribeHash, subscription);
122
+ }
86
123
  /**
87
124
  * @method
88
125
  * @name bingx#watchTicker
@@ -108,17 +145,42 @@ export default class bingx extends bingxRest {
108
145
  else {
109
146
  url = this.safeString(this.urls['api']['ws'], marketType);
110
147
  }
111
- const subscriptionHash = market['id'] + '@ticker';
148
+ const dataType = market['id'] + '@ticker';
112
149
  const messageHash = this.getMessageHash('ticker', market['symbol']);
113
150
  const uuid = this.uuid();
114
151
  const request = {
115
152
  'id': uuid,
116
- 'dataType': subscriptionHash,
153
+ 'dataType': dataType,
117
154
  };
118
155
  if (marketType === 'swap') {
119
156
  request['reqType'] = 'sub';
120
157
  }
121
- return await this.watch(url, messageHash, this.extend(request, params), subscriptionHash);
158
+ const subscription = {
159
+ 'unsubscribe': false,
160
+ 'id': uuid,
161
+ };
162
+ return await this.watch(url, messageHash, this.extend(request, params), messageHash, subscription);
163
+ }
164
+ /**
165
+ * @method
166
+ * @name bingx#unWatchTicker
167
+ * @description unWatches a price ticker, a statistical calculation with the information calculated over the past 24 hours for all markets of a specific list
168
+ * @see https://bingx-api.github.io/docs/#/en-us/spot/socket/market.html#Subscribe%20to%2024-hour%20Price%20Change
169
+ * @see https://bingx-api.github.io/docs/#/en-us/swapV2/socket/market.html#Subscribe%20to%2024-hour%20price%20changes
170
+ * @see https://bingx-api.github.io/docs/#/en-us/cswap/socket/market.html#Subscribe%20to%2024-Hour%20Price%20Change
171
+ * @param {string} symbol unified symbol of the market to fetch the ticker for
172
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
173
+ * @returns {object} a [ticker structure]{@link https://docs.ccxt.com/#/?id=ticker-structure}
174
+ */
175
+ async unWatchTicker(symbol, params = {}) {
176
+ await this.loadMarkets();
177
+ const market = this.market(symbol);
178
+ const dataType = market['id'] + '@ticker';
179
+ const subMessageHash = this.getMessageHash('ticker', market['symbol']);
180
+ const messageHash = 'unsubscribe::' + subMessageHash;
181
+ const topic = 'ticker';
182
+ const methodName = 'unWatchTicker';
183
+ return await this.unWatch(messageHash, subMessageHash, messageHash, dataType, topic, market, methodName, params);
122
184
  }
123
185
  handleTicker(client, message) {
124
186
  //
@@ -239,196 +301,6 @@ export default class bingx extends bingxRest {
239
301
  'info': message,
240
302
  }, market);
241
303
  }
242
- /**
243
- * @method
244
- * @name bingx#watchTickers
245
- * @description watches a price ticker, a statistical calculation with the information calculated over the past 24 hours for all markets of a specific list
246
- * @see https://bingx-api.github.io/docs/#/en-us/swapV2/socket/market.html#Subscribe%20to%2024-hour%20price%20changes%20of%20all%20trading%20pairs
247
- * @param {string[]} symbols unified symbol of the market to watch the tickers for
248
- * @param {object} [params] extra parameters specific to the exchange API endpoint
249
- * @returns {object} a [ticker structure]{@link https://docs.ccxt.com/#/?id=ticker-structure}
250
- */
251
- async watchTickers(symbols = undefined, params = {}) {
252
- await this.loadMarkets();
253
- symbols = this.marketSymbols(symbols, undefined, true, true, false);
254
- let firstMarket = undefined;
255
- let marketType = undefined;
256
- let subType = undefined;
257
- const symbolsDefined = (symbols !== undefined);
258
- if (symbolsDefined) {
259
- firstMarket = this.market(symbols[0]);
260
- }
261
- [marketType, params] = this.handleMarketTypeAndParams('watchTickers', firstMarket, params);
262
- [subType, params] = this.handleSubTypeAndParams('watchTickers', firstMarket, params, 'linear');
263
- if (marketType === 'spot') {
264
- throw new NotSupported(this.id + ' watchTickers is not supported for spot markets yet');
265
- }
266
- if (subType === 'inverse') {
267
- throw new NotSupported(this.id + ' watchTickers is not supported for inverse markets yet');
268
- }
269
- const messageHashes = [];
270
- const subscriptionHashes = ['all@ticker'];
271
- if (symbolsDefined) {
272
- for (let i = 0; i < symbols.length; i++) {
273
- const symbol = symbols[i];
274
- const market = this.market(symbol);
275
- messageHashes.push(this.getMessageHash('ticker', market['symbol']));
276
- }
277
- }
278
- else {
279
- messageHashes.push(this.getMessageHash('ticker'));
280
- }
281
- const url = this.safeString(this.urls['api']['ws'], subType);
282
- const uuid = this.uuid();
283
- const request = {
284
- 'id': uuid,
285
- 'dataType': 'all@ticker',
286
- };
287
- if (marketType === 'swap') {
288
- request['reqType'] = 'sub';
289
- }
290
- const result = await this.watchMultiple(url, messageHashes, this.deepExtend(request, params), subscriptionHashes);
291
- if (this.newUpdates) {
292
- const newDict = {};
293
- newDict[result['symbol']] = result;
294
- return newDict;
295
- }
296
- return this.tickers;
297
- }
298
- /**
299
- * @method
300
- * @name bingx#watchOrderBookForSymbols
301
- * @description watches information on open orders with bid (buy) and ask (sell) prices, volumes and other data
302
- * @see https://bingx-api.github.io/docs/#/en-us/swapV2/socket/market.html#Subscribe%20Market%20Depth%20Data%20of%20all%20trading%20pairs
303
- * @param {string[]} symbols unified array of symbols
304
- * @param {int} [limit] the maximum amount of order book entries to return
305
- * @param {object} [params] extra parameters specific to the exchange API endpoint
306
- * @returns {object} A dictionary of [order book structures]{@link https://docs.ccxt.com/#/?id=order-book-structure} indexed by market symbols
307
- */
308
- async watchOrderBookForSymbols(symbols, limit = undefined, params = {}) {
309
- symbols = this.marketSymbols(symbols, undefined, true, true, false);
310
- let firstMarket = undefined;
311
- let marketType = undefined;
312
- let subType = undefined;
313
- const symbolsDefined = (symbols !== undefined);
314
- if (symbolsDefined) {
315
- firstMarket = this.market(symbols[0]);
316
- }
317
- [marketType, params] = this.handleMarketTypeAndParams('watchOrderBookForSymbols', firstMarket, params);
318
- [subType, params] = this.handleSubTypeAndParams('watchOrderBookForSymbols', firstMarket, params, 'linear');
319
- if (marketType === 'spot') {
320
- throw new NotSupported(this.id + ' watchOrderBookForSymbols is not supported for spot markets yet');
321
- }
322
- if (subType === 'inverse') {
323
- throw new NotSupported(this.id + ' watchOrderBookForSymbols is not supported for inverse markets yet');
324
- }
325
- limit = this.getOrderBookLimitByMarketType(marketType, limit);
326
- let interval = undefined;
327
- [interval, params] = this.handleOptionAndParams(params, 'watchOrderBookForSymbols', 'interval', 500);
328
- this.checkRequiredArgument('watchOrderBookForSymbols', interval, 'interval', [100, 200, 500, 1000]);
329
- const channelName = 'depth' + limit.toString() + '@' + interval.toString() + 'ms';
330
- const subscriptionHash = 'all@' + channelName;
331
- const messageHashes = [];
332
- if (symbolsDefined) {
333
- for (let i = 0; i < symbols.length; i++) {
334
- const symbol = symbols[i];
335
- const market = this.market(symbol);
336
- messageHashes.push(this.getMessageHash('orderbook', market['symbol']));
337
- }
338
- }
339
- else {
340
- messageHashes.push(this.getMessageHash('orderbook'));
341
- }
342
- const url = this.safeString(this.urls['api']['ws'], subType);
343
- const uuid = this.uuid();
344
- const request = {
345
- 'id': uuid,
346
- 'dataType': subscriptionHash,
347
- };
348
- if (marketType === 'swap') {
349
- request['reqType'] = 'sub';
350
- }
351
- const subscriptionArgs = {
352
- 'symbols': symbols,
353
- 'limit': limit,
354
- 'interval': interval,
355
- 'params': params,
356
- };
357
- const orderbook = await this.watchMultiple(url, messageHashes, this.deepExtend(request, params), [subscriptionHash], subscriptionArgs);
358
- return orderbook.limit();
359
- }
360
- /**
361
- * @method
362
- * @name bingx#watchOHLCVForSymbols
363
- * @description watches historical candlestick data containing the open, high, low, and close price, and the volume of a market
364
- * @see https://bingx-api.github.io/docs/#/en-us/swapV2/socket/market.html#Subscribe%20K-Line%20Data%20of%20all%20trading%20pairs
365
- * @param {string[][]} symbolsAndTimeframes array of arrays containing unified symbols and timeframes to fetch OHLCV data for, example [['BTC/USDT', '1m'], ['LTC/USDT', '5m']]
366
- * @param {int} [since] timestamp in ms of the earliest candle to fetch
367
- * @param {int} [limit] the maximum amount of candles to fetch
368
- * @param {object} [params] extra parameters specific to the exchange API endpoint
369
- * @returns {int[][]} A list of candles ordered as timestamp, open, high, low, close, volume
370
- */
371
- async watchOHLCVForSymbols(symbolsAndTimeframes, since = undefined, limit = undefined, params = {}) {
372
- const symbolsLength = symbolsAndTimeframes.length;
373
- if (symbolsLength !== 0 && !Array.isArray(symbolsAndTimeframes[0])) {
374
- throw new ArgumentsRequired(this.id + " watchOHLCVForSymbols() requires a an array like [['BTC/USDT:USDT', '1m'], ['LTC/USDT:USDT', '5m']]");
375
- }
376
- await this.loadMarkets();
377
- const messageHashes = [];
378
- let marketType = undefined;
379
- let subType = undefined;
380
- let chosenTimeframe = undefined;
381
- let firstMarket = undefined;
382
- if (symbolsLength !== 0) {
383
- let symbols = this.getListFromObjectValues(symbolsAndTimeframes, 0);
384
- symbols = this.marketSymbols(symbols, undefined, true, true, false);
385
- firstMarket = this.market(symbols[0]);
386
- }
387
- [marketType, params] = this.handleMarketTypeAndParams('watchOHLCVForSymbols', firstMarket, params);
388
- [subType, params] = this.handleSubTypeAndParams('watchOHLCVForSymbols', firstMarket, params, 'linear');
389
- if (marketType === 'spot') {
390
- throw new NotSupported(this.id + ' watchOHLCVForSymbols is not supported for spot markets yet');
391
- }
392
- if (subType === 'inverse') {
393
- throw new NotSupported(this.id + ' watchOHLCVForSymbols is not supported for inverse markets yet');
394
- }
395
- const marketOptions = this.safeDict(this.options, marketType);
396
- const timeframes = this.safeDict(marketOptions, 'timeframes', {});
397
- for (let i = 0; i < symbolsAndTimeframes.length; i++) {
398
- const symbolAndTimeframe = symbolsAndTimeframes[i];
399
- const sym = symbolAndTimeframe[0];
400
- const tf = symbolAndTimeframe[1];
401
- const market = this.market(sym);
402
- const rawTimeframe = this.safeString(timeframes, tf, tf);
403
- if (chosenTimeframe === undefined) {
404
- chosenTimeframe = rawTimeframe;
405
- }
406
- else if (chosenTimeframe !== rawTimeframe) {
407
- throw new BadRequest(this.id + ' watchOHLCVForSymbols requires all timeframes to be the same');
408
- }
409
- messageHashes.push(this.getMessageHash('ohlcv', market['symbol'], chosenTimeframe));
410
- }
411
- const subscriptionHash = 'all@kline_' + chosenTimeframe;
412
- const url = this.safeString(this.urls['api']['ws'], subType);
413
- const uuid = this.uuid();
414
- const request = {
415
- 'id': uuid,
416
- 'dataType': subscriptionHash,
417
- };
418
- if (marketType === 'swap') {
419
- request['reqType'] = 'sub';
420
- }
421
- const subscriptionArgs = {
422
- 'limit': limit,
423
- 'params': params,
424
- };
425
- const [symbol, timeframe, candles] = await this.watchMultiple(url, messageHashes, request, [subscriptionHash], subscriptionArgs);
426
- if (this.newUpdates) {
427
- limit = candles.getLimit(symbol, limit);
428
- }
429
- const filtered = this.filterBySinceLimit(candles, since, limit, 0, true);
430
- return this.createOHLCVObject(symbol, timeframe, filtered);
431
- }
432
304
  getOrderBookLimitByMarketType(marketType, limit = undefined) {
433
305
  if (limit === undefined) {
434
306
  limit = 100;
@@ -460,8 +332,8 @@ export default class bingx extends bingxRest {
460
332
  * @method
461
333
  * @name bingx#watchTrades
462
334
  * @description watches information on multiple trades made in a market
463
- * @see https://bingx-api.github.io/docs/#/spot/socket/market.html#Subscribe%20to%20tick-by-tick
464
- * @see https://bingx-api.github.io/docs/#/swapV2/socket/market.html#Subscribe%20the%20Latest%20Trade%20Detail
335
+ * @see https://bingx-api.github.io/docs/#/en-us/spot/socket/market.html#Subscription%20transaction%20by%20transaction
336
+ * @see https://bingx-api.github.io/docs/#/en-us/swapV2/socket/market.html#Subscribe%20the%20Latest%20Trade%20Detail
465
337
  * @see https://bingx-api.github.io/docs/#/en-us/cswap/socket/market.html#Subscription%20transaction%20by%20transaction
466
338
  * @param {string} symbol unified market symbol of the market orders were made in
467
339
  * @param {int} [since] the earliest time in ms to fetch orders for
@@ -494,7 +366,11 @@ export default class bingx extends bingxRest {
494
366
  if (marketType === 'swap') {
495
367
  request['reqType'] = 'sub';
496
368
  }
497
- const trades = await this.watch(url, messageHash, this.extend(request, params), messageHash);
369
+ const subscription = {
370
+ 'unsubscribe': false,
371
+ 'id': uuid,
372
+ };
373
+ const trades = await this.watch(url, messageHash, this.extend(request, params), messageHash, subscription);
498
374
  if (this.newUpdates) {
499
375
  limit = trades.getLimit(symbol, limit);
500
376
  }
@@ -506,6 +382,28 @@ export default class bingx extends bingxRest {
506
382
  }
507
383
  return result;
508
384
  }
385
+ /**
386
+ * @method
387
+ * @name bingx#unWatchTrades
388
+ * @description unsubscribes from the trades channel
389
+ * @see https://bingx-api.github.io/docs/#/en-us/spot/socket/market.html#Subscription%20transaction%20by%20transaction
390
+ * @see https://bingx-api.github.io/docs/#/en-us/swapV2/socket/market.html#Subscribe%20the%20Latest%20Trade%20Detail
391
+ * @see https://bingx-api.github.io/docs/#/en-us/cswap/socket/market.html#Subscription%20transaction%20by%20transaction
392
+ * @param {string} symbol unified symbol of the market to fetch trades for
393
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
394
+ * @param {string} [params.name] the name of the method to call, 'trade' or 'aggTrade', default is 'trade'
395
+ * @returns {object[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=public-trades}
396
+ */
397
+ async unWatchTrades(symbol, params = {}) {
398
+ await this.loadMarkets();
399
+ const market = this.market(symbol);
400
+ const dataType = market['id'] + '@trade';
401
+ const subMessageHash = this.getMessageHash('trade', market['symbol']);
402
+ const messageHash = 'unsubscribe::' + subMessageHash;
403
+ const topic = 'trades';
404
+ const methodName = 'unWatchTrades';
405
+ return await this.unWatch(messageHash, subMessageHash, messageHash, dataType, topic, market, methodName, params);
406
+ }
509
407
  handleTrades(client, message) {
510
408
  //
511
409
  // spot: first snapshot
@@ -640,17 +538,9 @@ export default class bingx extends bingxRest {
640
538
  else {
641
539
  url = this.safeString(this.urls['api']['ws'], marketType);
642
540
  }
643
- limit = this.getOrderBookLimitByMarketType(marketType, limit);
644
- let channelName = 'depth' + limit.toString();
645
- let interval = undefined;
646
- if (marketType !== 'spot') {
647
- if (!market['inverse']) {
648
- [interval, params] = this.handleOptionAndParams(params, 'watchOrderBook', 'interval', 500);
649
- this.checkRequiredArgument('watchOrderBook', interval, 'interval', [100, 200, 500, 1000]);
650
- channelName = channelName + '@' + interval.toString() + 'ms';
651
- }
652
- }
653
- const subscriptionHash = market['id'] + '@' + channelName;
541
+ const options = this.safeDict(this.options, 'watchOrderBook', {});
542
+ const depth = this.safeInteger(options, 'depth', 100);
543
+ const subscriptionHash = market['id'] + '@' + 'depth' + this.numberToString(depth);
654
544
  const messageHash = this.getMessageHash('orderbook', market['symbol']);
655
545
  const uuid = this.uuid();
656
546
  const request = {
@@ -663,20 +553,45 @@ export default class bingx extends bingxRest {
663
553
  let subscriptionArgs = {};
664
554
  if (market['inverse']) {
665
555
  subscriptionArgs = {
556
+ 'id': uuid,
557
+ 'unsubscribe': false,
666
558
  'count': limit,
667
559
  'params': params,
668
560
  };
669
561
  }
670
562
  else {
671
563
  subscriptionArgs = {
564
+ 'id': uuid,
565
+ 'unsubscribe': false,
672
566
  'level': limit,
673
- 'interval': interval,
674
567
  'params': params,
675
568
  };
676
569
  }
677
570
  const orderbook = await this.watch(url, messageHash, this.deepExtend(request, params), subscriptionHash, subscriptionArgs);
678
571
  return orderbook.limit();
679
572
  }
573
+ /**
574
+ * @method
575
+ * @name bingx#unWatchOrderBook
576
+ * @description unWatches information on open orders with bid (buy) and ask (sell) prices, volumes and other data
577
+ * @see https://bingx-api.github.io/docs/#/en-us/spot/socket/market.html#Subscribe%20Market%20Depth%20Data
578
+ * @see https://bingx-api.github.io/docs/#/en-us/swapV2/socket/market.html#Subscribe%20Market%20Depth%20Data
579
+ * @see https://bingx-api.github.io/docs/#/en-us/cswap/socket/market.html#Subscribe%20to%20Limited%20Depth
580
+ * @param {string} symbol unified symbol of the market
581
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
582
+ * @returns {object} A dictionary of [order book structures]{@link https://docs.ccxt.com/#/?id=order-book-structure} indexed by market symbols
583
+ */
584
+ async unWatchOrderBook(symbol, params = {}) {
585
+ await this.loadMarkets();
586
+ const market = this.market(symbol);
587
+ const options = this.safeDict(this.options, 'watchOrderBook', {});
588
+ const depth = this.safeInteger(options, 'depth', 100);
589
+ const subMessageHash = market['id'] + '@' + 'depth' + this.numberToString(depth);
590
+ const messageHash = 'unsubscribe::' + subMessageHash;
591
+ const topic = 'orderbook';
592
+ const methodName = 'unWatchOrderBook';
593
+ return await this.unWatch(messageHash, subMessageHash, messageHash, subMessageHash, topic, market, methodName, params);
594
+ }
680
595
  handleDelta(bookside, delta) {
681
596
  const price = this.safeFloat2(delta, 0, 'p');
682
597
  const amount = this.safeFloat2(delta, 1, 'a');
@@ -974,6 +889,8 @@ export default class bingx extends bingxRest {
974
889
  request['reqType'] = 'sub';
975
890
  }
976
891
  const subscriptionArgs = {
892
+ 'id': uuid,
893
+ 'unsubscribe': false,
977
894
  'interval': rawTimeframe,
978
895
  'params': params,
979
896
  };
@@ -984,6 +901,32 @@ export default class bingx extends bingxRest {
984
901
  }
985
902
  return this.filterBySinceLimit(ohlcv, since, limit, 0, true);
986
903
  }
904
+ /**
905
+ * @method
906
+ * @name bingx#unWatchOHLCV
907
+ * @description unWatches historical candlestick data containing the open, high, low, and close price, and the volume of a market
908
+ * @see https://bingx-api.github.io/docs/#/en-us/spot/socket/market.html#K-line%20Streams
909
+ * @see https://bingx-api.github.io/docs/#/en-us/swapV2/socket/market.html#Subscribe%20K-Line%20Data
910
+ * @see https://bingx-api.github.io/docs/#/en-us/cswap/socket/market.html#Subscribe%20to%20Latest%20Trading%20Pair%20K-Line
911
+ * @param {string} symbol unified symbol of the market to fetch OHLCV data for
912
+ * @param {string} timeframe the length of time each candle represents
913
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
914
+ * @returns {int[][]} A list of candles ordered as timestamp, open, high, low, close, volume
915
+ */
916
+ async unWatchOHLCV(symbol, timeframe = '1m', params = {}) {
917
+ await this.loadMarkets();
918
+ const market = this.market(symbol);
919
+ const options = this.safeValue(this.options, market['type'], {});
920
+ const timeframes = this.safeValue(options, 'timeframes', {});
921
+ const rawTimeframe = this.safeString(timeframes, timeframe, timeframe);
922
+ const subMessageHash = market['id'] + '@kline_' + rawTimeframe;
923
+ const messageHash = 'unsubscribe::' + subMessageHash;
924
+ const topic = 'ohlcv';
925
+ const methodName = 'unWatchOHLCV';
926
+ const symbolsAndTimeframes = [[market['symbol'], timeframe]];
927
+ params['symbolsAndTimeframes'] = symbolsAndTimeframes;
928
+ return await this.unWatch(messageHash, subMessageHash, messageHash, subMessageHash, topic, market, methodName, params);
929
+ }
987
930
  /**
988
931
  * @method
989
932
  * @name bingx#watchOrders
@@ -1037,7 +980,11 @@ export default class bingx extends bingxRest {
1037
980
  };
1038
981
  }
1039
982
  const url = baseUrl + '?listenKey=' + this.options['listenKey'];
1040
- const orders = await this.watch(url, messageHash, request, subscriptionHash);
983
+ const subscription = {
984
+ 'unsubscribe': false,
985
+ 'id': uuid,
986
+ };
987
+ const orders = await this.watch(url, messageHash, request, subscriptionHash, subscription);
1041
988
  if (this.newUpdates) {
1042
989
  limit = orders.getLimit(symbol, limit);
1043
990
  }
@@ -1096,7 +1043,11 @@ export default class bingx extends bingxRest {
1096
1043
  };
1097
1044
  }
1098
1045
  const url = baseUrl + '?listenKey=' + this.options['listenKey'];
1099
- const trades = await this.watch(url, messageHash, request, subscriptionHash);
1046
+ const subscription = {
1047
+ 'unsubscribe': false,
1048
+ 'id': uuid,
1049
+ };
1050
+ const trades = await this.watch(url, messageHash, request, subscriptionHash, subscription);
1100
1051
  if (this.newUpdates) {
1101
1052
  limit = trades.getLimit(symbol, limit);
1102
1053
  }
@@ -1152,7 +1103,11 @@ export default class bingx extends bingxRest {
1152
1103
  if (fetchBalanceSnapshot && awaitBalanceSnapshot) {
1153
1104
  await client.future(type + ':fetchBalanceSnapshot');
1154
1105
  }
1155
- return await this.watch(url, messageHash, request, subscriptionHash);
1106
+ const subscription = {
1107
+ 'unsubscribe': false,
1108
+ 'id': uuid,
1109
+ };
1110
+ return await this.watch(url, messageHash, request, subscriptionHash, subscription);
1156
1111
  }
1157
1112
  setBalanceCache(client, type, subType, subscriptionHash, params) {
1158
1113
  if (subscriptionHash in client.subscriptions) {
@@ -1558,5 +1513,36 @@ export default class bingx extends bingxRest {
1558
1513
  if (msgEvent === '24hTicker') {
1559
1514
  this.handleTicker(client, message);
1560
1515
  }
1516
+ if (dataType === '' && msgEvent === undefined && e === undefined) {
1517
+ this.handleSubscriptionStatus(client, message);
1518
+ }
1519
+ }
1520
+ handleSubscriptionStatus(client, message) {
1521
+ //
1522
+ // {
1523
+ // "code": 0,
1524
+ // "id": "b6ed9cb4-f3d0-4641-ac3f-f59eb47a3abd",
1525
+ // "msg": "SUCCESS",
1526
+ // "timestamp": 1759225965363
1527
+ // }
1528
+ //
1529
+ const id = this.safeString(message, 'id');
1530
+ const subscriptionsById = this.indexBy(client.subscriptions, 'id');
1531
+ const subscription = this.safeDict(subscriptionsById, id, {});
1532
+ const isUnSubMessage = this.safeBool(subscription, 'unsubscribe', false);
1533
+ if (isUnSubMessage) {
1534
+ this.handleUnSubscription(client, subscription);
1535
+ }
1536
+ return message;
1537
+ }
1538
+ handleUnSubscription(client, subscription) {
1539
+ const messageHashes = this.safeList(subscription, 'messageHashes', []);
1540
+ const subMessageHashes = this.safeList(subscription, 'subMessageHashes', []);
1541
+ for (let i = 0; i < messageHashes.length; i++) {
1542
+ const unsubHash = messageHashes[i];
1543
+ const subHash = subMessageHashes[i];
1544
+ this.cleanUnsubscription(client, subHash, unsubHash);
1545
+ }
1546
+ this.cleanCache(subscription);
1561
1547
  }
1562
1548
  }
package/js/src/pro/htx.js CHANGED
@@ -964,7 +964,7 @@ export default class htx extends htxRest {
964
964
  else {
965
965
  // contract branch
966
966
  parsedOrder = this.parseWsOrder(message, market);
967
- const rawTrades = this.safeValue(message, 'trade', []);
967
+ const rawTrades = this.safeList(message, 'trade', []);
968
968
  const tradesLength = rawTrades.length;
969
969
  if (tradesLength > 0) {
970
970
  const tradesObject = {
package/js/src/upbit.js CHANGED
@@ -39,6 +39,7 @@ export default class upbit extends Exchange {
39
39
  'fetchBalance': true,
40
40
  'fetchCanceledOrders': true,
41
41
  'fetchClosedOrders': true,
42
+ 'fetchCurrencies': false,
42
43
  'fetchDeposit': true,
43
44
  'fetchDepositAddress': true,
44
45
  'fetchDepositAddresses': true,
@@ -49,6 +49,7 @@ export default class wavesexchange extends Exchange {
49
49
  'fetchClosedOrders': true,
50
50
  'fetchCrossBorrowRate': false,
51
51
  'fetchCrossBorrowRates': false,
52
+ 'fetchCurrencies': false,
52
53
  'fetchDepositAddress': true,
53
54
  'fetchDepositAddresses': undefined,
54
55
  'fetchDepositAddressesByNetwork': undefined,
package/js/src/yobit.js CHANGED
@@ -49,6 +49,7 @@ export default class yobit extends Exchange {
49
49
  'fetchBorrowRatesPerSymbol': false,
50
50
  'fetchCrossBorrowRate': false,
51
51
  'fetchCrossBorrowRates': false,
52
+ 'fetchCurrencies': false,
52
53
  'fetchDepositAddress': true,
53
54
  'fetchDepositAddresses': false,
54
55
  'fetchDepositAddressesByNetwork': false,
package/js/src/zaif.js CHANGED
@@ -30,6 +30,7 @@ export default class zaif extends Exchange {
30
30
  'createOrder': true,
31
31
  'fetchBalance': true,
32
32
  'fetchClosedOrders': true,
33
+ 'fetchCurrencies': false,
33
34
  'fetchFundingHistory': false,
34
35
  'fetchFundingRate': false,
35
36
  'fetchFundingRateHistory': false,
package/js/src/zonda.js CHANGED
@@ -45,6 +45,7 @@ export default class zonda extends Exchange {
45
45
  'fetchBorrowRatesPerSymbol': false,
46
46
  'fetchCrossBorrowRate': false,
47
47
  'fetchCrossBorrowRates': false,
48
+ 'fetchCurrencies': false,
48
49
  'fetchDeposit': false,
49
50
  'fetchDepositAddress': true,
50
51
  'fetchDepositAddresses': true,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ccxt",
3
- "version": "4.5.6",
3
+ "version": "4.5.7",
4
4
  "description": "A cryptocurrency trading API with more than 100 exchanges in JavaScript / TypeScript / Python / C# / PHP / Go",
5
5
  "unpkg": "dist/ccxt.browser.min.js",
6
6
  "type": "module",