ccxt 4.4.1 → 4.4.3

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 (67) hide show
  1. package/README.md +4 -4
  2. package/dist/ccxt.browser.min.js +3 -3
  3. package/dist/cjs/ccxt.js +1 -1
  4. package/dist/cjs/src/base/Exchange.js +69 -0
  5. package/dist/cjs/src/binance.js +88 -18
  6. package/dist/cjs/src/bitmart.js +3 -1
  7. package/dist/cjs/src/bitstamp.js +24 -36
  8. package/dist/cjs/src/bybit.js +1 -0
  9. package/dist/cjs/src/cryptocom.js +3 -2
  10. package/dist/cjs/src/currencycom.js +1 -2
  11. package/dist/cjs/src/htx.js +1 -1
  12. package/dist/cjs/src/mexc.js +88 -1
  13. package/dist/cjs/src/pro/binance.js +3 -63
  14. package/dist/cjs/src/pro/bitget.js +1 -9
  15. package/dist/cjs/src/pro/bitmex.js +11 -1
  16. package/dist/cjs/src/pro/bybit.js +2 -54
  17. package/dist/cjs/src/pro/cryptocom.js +193 -61
  18. package/dist/cjs/src/pro/gate.js +1 -9
  19. package/dist/cjs/src/pro/hyperliquid.js +4 -36
  20. package/dist/cjs/src/pro/kucoin.js +2 -59
  21. package/dist/cjs/src/pro/kucoinfutures.js +139 -1
  22. package/dist/cjs/src/pro/mexc.js +82 -3
  23. package/dist/cjs/src/pro/okx.js +14 -39
  24. package/dist/cjs/src/pro/oxfun.js +75 -0
  25. package/dist/cjs/src/pro/phemex.js +45 -1
  26. package/dist/cjs/src/pro/woofipro.js +67 -0
  27. package/dist/cjs/src/xt.js +7 -2
  28. package/examples/js/cli.js +8 -4
  29. package/js/ccxt.d.ts +3 -3
  30. package/js/ccxt.js +1 -1
  31. package/js/src/abstract/bitmart.d.ts +1 -0
  32. package/js/src/base/Exchange.d.ts +2 -0
  33. package/js/src/base/Exchange.js +70 -1
  34. package/js/src/base/types.d.ts +5 -4
  35. package/js/src/binance.js +88 -18
  36. package/js/src/bitmart.js +3 -1
  37. package/js/src/bitstamp.js +24 -36
  38. package/js/src/bybit.js +2 -1
  39. package/js/src/cryptocom.js +3 -2
  40. package/js/src/currencycom.js +1 -2
  41. package/js/src/htx.js +1 -1
  42. package/js/src/mexc.js +88 -1
  43. package/js/src/pro/binance.d.ts +0 -1
  44. package/js/src/pro/binance.js +4 -64
  45. package/js/src/pro/bitget.js +1 -9
  46. package/js/src/pro/bitmex.js +11 -1
  47. package/js/src/pro/bybit.d.ts +1 -2
  48. package/js/src/pro/bybit.js +3 -55
  49. package/js/src/pro/cryptocom.d.ts +7 -2
  50. package/js/src/pro/cryptocom.js +194 -62
  51. package/js/src/pro/gate.js +2 -10
  52. package/js/src/pro/hyperliquid.js +5 -37
  53. package/js/src/pro/kucoin.d.ts +0 -1
  54. package/js/src/pro/kucoin.js +3 -60
  55. package/js/src/pro/kucoinfutures.d.ts +7 -1
  56. package/js/src/pro/kucoinfutures.js +139 -1
  57. package/js/src/pro/mexc.d.ts +3 -1
  58. package/js/src/pro/mexc.js +82 -3
  59. package/js/src/pro/okx.js +15 -40
  60. package/js/src/pro/oxfun.d.ts +3 -0
  61. package/js/src/pro/oxfun.js +75 -0
  62. package/js/src/pro/phemex.d.ts +2 -1
  63. package/js/src/pro/phemex.js +45 -1
  64. package/js/src/pro/woofipro.d.ts +3 -0
  65. package/js/src/pro/woofipro.js +67 -0
  66. package/js/src/xt.js +7 -2
  67. package/package.json +1 -1
@@ -27,7 +27,7 @@ class mexc extends mexc$1 {
27
27
  'watchOrderBook': true,
28
28
  'watchOrders': true,
29
29
  'watchTicker': true,
30
- 'watchTickers': false,
30
+ 'watchTickers': true,
31
31
  'watchTrades': true,
32
32
  'watchTradesForSymbols': false,
33
33
  },
@@ -125,6 +125,84 @@ class mexc extends mexc$1 {
125
125
  const messageHash = 'ticker:' + symbol;
126
126
  client.resolve(ticker, messageHash);
127
127
  }
128
+ async watchTickers(symbols = undefined, params = {}) {
129
+ /**
130
+ * @method
131
+ * @name mexc#watchTickers
132
+ * @description watches a price ticker, a statistical calculation with the information calculated over the past 24 hours for all markets of a specific list
133
+ * @see https://mexcdevelop.github.io/apidocs/spot_v3_en/#individual-symbol-book-ticker-streams
134
+ * @see https://mexcdevelop.github.io/apidocs/contract_v1_en/#public-channels
135
+ * @param {string[]} symbols unified symbol of the market to fetch the ticker for
136
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
137
+ * @returns {object} a [ticker structure]{@link https://docs.ccxt.com/#/?id=ticker-structure}
138
+ */
139
+ await this.loadMarkets();
140
+ symbols = this.marketSymbols(symbols, undefined, false);
141
+ const messageHashes = [];
142
+ const marketIds = this.marketIds(symbols);
143
+ const firstMarket = this.market(symbols[0]);
144
+ const isSpot = firstMarket['spot'];
145
+ const url = (isSpot) ? this.urls['api']['ws']['spot'] : this.urls['api']['ws']['swap'];
146
+ const request = {};
147
+ if (isSpot) {
148
+ const topics = [];
149
+ for (let i = 0; i < marketIds.length; i++) {
150
+ const marketId = marketIds[i];
151
+ messageHashes.push('ticker:' + symbols[i]);
152
+ topics.push('spot@public.bookTicker.v3.api@' + marketId);
153
+ }
154
+ request['method'] = 'SUBSCRIPTION';
155
+ request['params'] = topics;
156
+ }
157
+ else {
158
+ request['method'] = 'sub.tickers';
159
+ request['params'] = {};
160
+ messageHashes.push('ticker');
161
+ }
162
+ const ticker = await this.watchMultiple(url, messageHashes, this.extend(request, params), messageHashes);
163
+ if (isSpot && this.newUpdates) {
164
+ const result = {};
165
+ result[ticker['symbol']] = ticker;
166
+ return result;
167
+ }
168
+ return this.filterByArray(this.tickers, 'symbol', symbols);
169
+ }
170
+ handleTickers(client, message) {
171
+ //
172
+ // {
173
+ // "channel": "push.tickers",
174
+ // "data": [
175
+ // {
176
+ // "symbol": "ETH_USDT",
177
+ // "lastPrice": 2324.5,
178
+ // "riseFallRate": 0.0356,
179
+ // "fairPrice": 2324.32,
180
+ // "indexPrice": 2325.44,
181
+ // "volume24": 25868309,
182
+ // "amount24": 591752573.9792,
183
+ // "maxBidPrice": 2557.98,
184
+ // "minAskPrice": 2092.89,
185
+ // "lower24Price": 2239.39,
186
+ // "high24Price": 2332.59,
187
+ // "timestamp": 1725872514111
188
+ // }
189
+ // ],
190
+ // "ts": 1725872514111
191
+ // }
192
+ //
193
+ const data = this.safeList(message, 'data');
194
+ const topic = 'ticker';
195
+ const result = [];
196
+ for (let i = 0; i < data.length; i++) {
197
+ const ticker = this.parseTicker(data[i]);
198
+ const symbol = ticker['symbol'];
199
+ this.tickers[symbol] = ticker;
200
+ result.push(ticker);
201
+ const messageHash = topic + ':' + symbol;
202
+ client.resolve(ticker, messageHash);
203
+ }
204
+ client.resolve(result, topic);
205
+ }
128
206
  parseWsTicker(ticker, market = undefined) {
129
207
  //
130
208
  // spot
@@ -1132,8 +1210,8 @@ class mexc extends mexc$1 {
1132
1210
  // "code": 0,
1133
1211
  // "msg": "spot@public.increase.depth.v3.api@BTCUSDT"
1134
1212
  // }
1135
- //
1136
- const msg = this.safeString(message, 'msg');
1213
+ // Set the default to an empty string if the message is empty during the test.
1214
+ const msg = this.safeString(message, 'msg', '');
1137
1215
  if (msg === 'PONG') {
1138
1216
  this.handlePong(client, message);
1139
1217
  }
@@ -1177,6 +1255,7 @@ class mexc extends mexc$1 {
1177
1255
  'push.kline': this.handleOHLCV,
1178
1256
  'public.bookTicker.v3.api': this.handleTicker,
1179
1257
  'push.ticker': this.handleTicker,
1258
+ 'push.tickers': this.handleTickers,
1180
1259
  'public.increase.depth.v3.api': this.handleOrderBook,
1181
1260
  'push.depth': this.handleOrderBook,
1182
1261
  'private.orders.v3.api': this.handleOrder,
@@ -1440,8 +1440,11 @@ class okx extends okx$1 {
1440
1440
  },
1441
1441
  ],
1442
1442
  };
1443
- const message = this.extend(request, params);
1444
- this.watch(url, messageHash, message, messageHash);
1443
+ // Only add params['access'] to prevent sending custom parameters, such as extraParams.
1444
+ if ('access' in params) {
1445
+ request['access'] = params['access'];
1446
+ }
1447
+ this.watch(url, messageHash, request, messageHash);
1445
1448
  }
1446
1449
  return await future;
1447
1450
  }
@@ -1611,7 +1614,7 @@ class okx extends okx$1 {
1611
1614
  'channel': 'positions',
1612
1615
  'instType': 'ANY',
1613
1616
  };
1614
- const args = [arg];
1617
+ const args = [this.extend(arg, params)];
1615
1618
  const nonSymbolRequest = {
1616
1619
  'op': 'subscribe',
1617
1620
  'args': args,
@@ -2331,64 +2334,36 @@ class okx extends okx$1 {
2331
2334
  handleUnSubscriptionTrades(client, symbol) {
2332
2335
  const subMessageHash = 'trades:' + symbol;
2333
2336
  const messageHash = 'unsubscribe:trades:' + symbol;
2334
- if (subMessageHash in client.subscriptions) {
2335
- delete client.subscriptions[subMessageHash];
2336
- }
2337
- if (messageHash in client.subscriptions) {
2338
- delete client.subscriptions[messageHash];
2337
+ this.cleanUnsubscription(client, subMessageHash, messageHash);
2338
+ if (symbol in this.trades) {
2339
+ delete this.trades[symbol];
2339
2340
  }
2340
- delete this.trades[symbol];
2341
- const error = new errors.UnsubscribeError(this.id + ' ' + subMessageHash);
2342
- client.reject(error, subMessageHash);
2343
- client.resolve(true, messageHash);
2344
2341
  }
2345
2342
  handleUnsubscriptionOrderBook(client, symbol, channel) {
2346
2343
  const subMessageHash = channel + ':' + symbol;
2347
2344
  const messageHash = 'unsubscribe:orderbook:' + symbol;
2348
- if (subMessageHash in client.subscriptions) {
2349
- delete client.subscriptions[subMessageHash];
2345
+ this.cleanUnsubscription(client, subMessageHash, messageHash);
2346
+ if (symbol in this.orderbooks) {
2347
+ delete this.orderbooks[symbol];
2350
2348
  }
2351
- if (messageHash in client.subscriptions) {
2352
- delete client.subscriptions[messageHash];
2353
- }
2354
- delete this.orderbooks[symbol];
2355
- const error = new errors.UnsubscribeError(this.id + ' ' + subMessageHash);
2356
- client.reject(error, subMessageHash);
2357
- client.resolve(true, messageHash);
2358
2349
  }
2359
2350
  handleUnsubscriptionOHLCV(client, symbol, channel) {
2360
2351
  const tf = channel.replace('candle', '');
2361
2352
  const timeframe = this.findTimeframe(tf);
2362
2353
  const subMessageHash = 'multi:' + channel + ':' + symbol;
2363
2354
  const messageHash = 'unsubscribe:' + subMessageHash;
2364
- if (subMessageHash in client.subscriptions) {
2365
- delete client.subscriptions[subMessageHash];
2366
- }
2367
- if (messageHash in client.subscriptions) {
2368
- delete client.subscriptions[messageHash];
2369
- }
2355
+ this.cleanUnsubscription(client, subMessageHash, messageHash);
2370
2356
  if (timeframe in this.ohlcvs[symbol]) {
2371
2357
  delete this.ohlcvs[symbol][timeframe];
2372
2358
  }
2373
- const error = new errors.UnsubscribeError(this.id + ' ' + subMessageHash);
2374
- client.reject(error, subMessageHash);
2375
- client.resolve(true, messageHash);
2376
2359
  }
2377
2360
  handleUnsubscriptionTicker(client, symbol, channel) {
2378
2361
  const subMessageHash = channel + '::' + symbol;
2379
2362
  const messageHash = 'unsubscribe:ticker:' + symbol;
2380
- if (subMessageHash in client.subscriptions) {
2381
- delete client.subscriptions[subMessageHash];
2382
- }
2383
- if (messageHash in client.subscriptions) {
2384
- delete client.subscriptions[messageHash];
2385
- }
2363
+ this.cleanUnsubscription(client, subMessageHash, messageHash);
2386
2364
  if (symbol in this.tickers) {
2387
2365
  delete this.tickers[symbol];
2388
2366
  }
2389
- const error = new errors.UnsubscribeError(this.id + ' ' + subMessageHash);
2390
- client.reject(error, subMessageHash);
2391
- client.resolve(true, messageHash);
2392
2367
  }
2393
2368
  handleUnsubscription(client, message) {
2394
2369
  //
@@ -22,6 +22,7 @@ class oxfun extends oxfun$1 {
22
22
  'watchMyTrades': false,
23
23
  'watchTicker': true,
24
24
  'watchTickers': true,
25
+ 'watchBidsAsks': true,
25
26
  'watchBalance': true,
26
27
  'createOrderWs': true,
27
28
  'editOrderWs': true,
@@ -496,6 +497,77 @@ class oxfun extends oxfun$1 {
496
497
  client.resolve(ticker, messageHash);
497
498
  }
498
499
  }
500
+ async watchBidsAsks(symbols = undefined, params = {}) {
501
+ /**
502
+ * @method
503
+ * @name oxfun#watchBidsAsks
504
+ * @see https://docs.ox.fun/?json#best-bid-ask
505
+ * @description watches best bid & ask for symbols
506
+ * @param {string[]} symbols unified symbol of the market to fetch the ticker for
507
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
508
+ * @returns {object} a [ticker structure]{@link https://docs.ccxt.com/#/?id=ticker-structure}
509
+ */
510
+ await this.loadMarkets();
511
+ symbols = this.marketSymbols(symbols, undefined, false);
512
+ const messageHashes = [];
513
+ const args = [];
514
+ for (let i = 0; i < symbols.length; i++) {
515
+ const market = this.market(symbols[i]);
516
+ args.push('bestBidAsk:' + market['id']);
517
+ messageHashes.push('bidask:' + market['symbol']);
518
+ }
519
+ const newTickers = await this.subscribeMultiple(messageHashes, args, params);
520
+ if (this.newUpdates) {
521
+ const tickers = {};
522
+ tickers[newTickers['symbol']] = newTickers;
523
+ return tickers;
524
+ }
525
+ return this.filterByArray(this.bidsasks, 'symbol', symbols);
526
+ }
527
+ handleBidAsk(client, message) {
528
+ //
529
+ // {
530
+ // "table": "bestBidAsk",
531
+ // "data": {
532
+ // "ask": [
533
+ // 19045.0,
534
+ // 1.0
535
+ // ],
536
+ // "checksum": 3790706311,
537
+ // "marketCode": "BTC-USD-SWAP-LIN",
538
+ // "bid": [
539
+ // 19015.0,
540
+ // 1.0
541
+ // ],
542
+ // "timestamp": "1665456882928"
543
+ // }
544
+ // }
545
+ //
546
+ const data = this.safeDict(message, 'data', {});
547
+ const parsedTicker = this.parseWsBidAsk(data);
548
+ const symbol = parsedTicker['symbol'];
549
+ this.bidsasks[symbol] = parsedTicker;
550
+ const messageHash = 'bidask:' + symbol;
551
+ client.resolve(parsedTicker, messageHash);
552
+ }
553
+ parseWsBidAsk(ticker, market = undefined) {
554
+ const marketId = this.safeString(ticker, 'marketCode');
555
+ market = this.safeMarket(marketId, market);
556
+ const symbol = this.safeString(market, 'symbol');
557
+ const timestamp = this.safeInteger(ticker, 'timestamp');
558
+ const ask = this.safeList(ticker, 'ask', []);
559
+ const bid = this.safeList(ticker, 'bid', []);
560
+ return this.safeTicker({
561
+ 'symbol': symbol,
562
+ 'timestamp': timestamp,
563
+ 'datetime': this.iso8601(timestamp),
564
+ 'ask': this.safeNumber(ask, 0),
565
+ 'askVolume': this.safeNumber(ask, 1),
566
+ 'bid': this.safeNumber(bid, 0),
567
+ 'bidVolume': this.safeNumber(bid, 1),
568
+ 'info': ticker,
569
+ }, market);
570
+ }
499
571
  async watchBalance(params = {}) {
500
572
  /**
501
573
  * @method
@@ -1019,6 +1091,9 @@ class oxfun extends oxfun$1 {
1019
1091
  if (table.indexOf('order') > -1) {
1020
1092
  this.handleOrders(client, message);
1021
1093
  }
1094
+ if (table === 'bestBidAsk') {
1095
+ this.handleBidAsk(client, message);
1096
+ }
1022
1097
  }
1023
1098
  else {
1024
1099
  if (event === 'login') {
@@ -14,7 +14,7 @@ class phemex extends phemex$1 {
14
14
  'has': {
15
15
  'ws': true,
16
16
  'watchTicker': true,
17
- 'watchTickers': false,
17
+ 'watchTickers': true,
18
18
  'watchTrades': true,
19
19
  'watchMyTrades': true,
20
20
  'watchOrders': true,
@@ -523,6 +523,50 @@ class phemex extends phemex$1 {
523
523
  const request = this.deepExtend(subscribe, params);
524
524
  return await this.watch(url, messageHash, request, subscriptionHash);
525
525
  }
526
+ async watchTickers(symbols = undefined, params = {}) {
527
+ /**
528
+ * @method
529
+ * @name phemex#watchTickers
530
+ * @see https://github.com/phemex/phemex-api-docs/blob/master/Public-Hedged-Perpetual-API.md#subscribe-24-hours-ticker
531
+ * @see https://github.com/phemex/phemex-api-docs/blob/master/Public-Contract-API-en.md#subscribe-24-hours-ticker
532
+ * @see https://github.com/phemex/phemex-api-docs/blob/master/Public-Spot-API-en.md#subscribe-24-hours-ticker
533
+ * @description watches a price ticker, a statistical calculation with the information calculated over the past 24 hours for all markets of a specific list
534
+ * @param {string[]} [symbols] unified symbol of the market to fetch the ticker for
535
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
536
+ * @param {string} [params.channel] the channel to subscribe to, tickers by default. Can be tickers, sprd-tickers, index-tickers, block-tickers
537
+ * @returns {object} a [ticker structure]{@link https://docs.ccxt.com/#/?id=ticker-structure}
538
+ */
539
+ await this.loadMarkets();
540
+ symbols = this.marketSymbols(symbols, undefined, false);
541
+ const first = symbols[0];
542
+ const market = this.market(first);
543
+ const isSwap = market['swap'];
544
+ const settleIsUSDT = market['settle'] === 'USDT';
545
+ let name = 'spot_market24h';
546
+ if (isSwap) {
547
+ name = settleIsUSDT ? 'perp_market24h_pack_p' : 'market24h';
548
+ }
549
+ const url = this.urls['api']['ws'];
550
+ const requestId = this.requestId();
551
+ const subscriptionHash = name + '.subscribe';
552
+ const messageHashes = [];
553
+ for (let i = 0; i < symbols.length; i++) {
554
+ messageHashes.push('ticker:' + symbols[i]);
555
+ }
556
+ const subscribe = {
557
+ 'method': subscriptionHash,
558
+ 'id': requestId,
559
+ 'params': [],
560
+ };
561
+ const request = this.deepExtend(subscribe, params);
562
+ const ticker = await this.watchMultiple(url, messageHashes, request, messageHashes);
563
+ if (this.newUpdates) {
564
+ const result = {};
565
+ result[ticker['symbol']] = ticker;
566
+ return result;
567
+ }
568
+ return this.filterByArray(this.tickers, 'symbol', symbols);
569
+ }
526
570
  async watchTrades(symbol, since = undefined, limit = undefined, params = {}) {
527
571
  /**
528
572
  * @method
@@ -21,6 +21,7 @@ class woofipro extends woofipro$1 {
21
21
  'watchOrders': true,
22
22
  'watchTicker': true,
23
23
  'watchTickers': true,
24
+ 'watchBidsAsks': true,
24
25
  'watchTrades': true,
25
26
  'watchTradesForSymbols': false,
26
27
  'watchPositions': true,
@@ -288,6 +289,71 @@ class woofipro extends woofipro$1 {
288
289
  }
289
290
  client.resolve(result, topic);
290
291
  }
292
+ async watchBidsAsks(symbols = undefined, params = {}) {
293
+ /**
294
+ * @method
295
+ * @name woofipro#watchBidsAsks
296
+ * @see https://orderly.network/docs/build-on-evm/evm-api/websocket-api/public/bbos
297
+ * @description watches best bid & ask for symbols
298
+ * @param {string[]} symbols unified symbol of the market to fetch the ticker for
299
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
300
+ * @returns {object} a [ticker structure]{@link https://docs.ccxt.com/#/?id=ticker-structure}
301
+ */
302
+ await this.loadMarkets();
303
+ symbols = this.marketSymbols(symbols);
304
+ const name = 'bbos';
305
+ const topic = name;
306
+ const request = {
307
+ 'event': 'subscribe',
308
+ 'topic': topic,
309
+ };
310
+ const message = this.extend(request, params);
311
+ const tickers = await this.watchPublic(topic, message);
312
+ return this.filterByArray(tickers, 'symbol', symbols);
313
+ }
314
+ handleBidAsk(client, message) {
315
+ //
316
+ // {
317
+ // "topic": "bbos",
318
+ // "ts": 1726212495000,
319
+ // "data": [
320
+ // {
321
+ // "symbol": "PERP_WOO_USDC",
322
+ // "ask": 0.16570,
323
+ // "askSize": 4224,
324
+ // "bid": 0.16553,
325
+ // "bidSize": 6645
326
+ // }
327
+ // ]
328
+ // }
329
+ //
330
+ const topic = this.safeString(message, 'topic');
331
+ const data = this.safeList(message, 'data', []);
332
+ const timestamp = this.safeInteger(message, 'ts');
333
+ const result = [];
334
+ for (let i = 0; i < data.length; i++) {
335
+ const ticker = this.parseWsBidAsk(this.extend(data[i], { 'ts': timestamp }));
336
+ this.tickers[ticker['symbol']] = ticker;
337
+ result.push(ticker);
338
+ }
339
+ client.resolve(result, topic);
340
+ }
341
+ parseWsBidAsk(ticker, market = undefined) {
342
+ const marketId = this.safeString(ticker, 'symbol');
343
+ market = this.safeMarket(marketId, market);
344
+ const symbol = this.safeString(market, 'symbol');
345
+ const timestamp = this.safeInteger(ticker, 'ts');
346
+ return this.safeTicker({
347
+ 'symbol': symbol,
348
+ 'timestamp': timestamp,
349
+ 'datetime': this.iso8601(timestamp),
350
+ 'ask': this.safeString(ticker, 'ask'),
351
+ 'askVolume': this.safeString(ticker, 'askSize'),
352
+ 'bid': this.safeString(ticker, 'bid'),
353
+ 'bidVolume': this.safeString(ticker, 'bidSize'),
354
+ 'info': ticker,
355
+ }, market);
356
+ }
291
357
  async watchOHLCV(symbol, timeframe = '1m', since = undefined, limit = undefined, params = {}) {
292
358
  /**
293
359
  * @method
@@ -1202,6 +1268,7 @@ class woofipro extends woofipro$1 {
1202
1268
  'algoexecutionreport': this.handleOrderUpdate,
1203
1269
  'position': this.handlePositions,
1204
1270
  'balance': this.handleBalance,
1271
+ 'bbos': this.handleBidAsk,
1205
1272
  };
1206
1273
  const event = this.safeString(message, 'event');
1207
1274
  let method = this.safeValue(methods, event);
@@ -1135,12 +1135,14 @@ class xt extends xt$1 {
1135
1135
  let maxCost = undefined;
1136
1136
  let minPrice = undefined;
1137
1137
  let maxPrice = undefined;
1138
+ let amountPrecision = undefined;
1138
1139
  for (let i = 0; i < filters.length; i++) {
1139
1140
  const entry = filters[i];
1140
1141
  const filter = this.safeString(entry, 'filter');
1141
1142
  if (filter === 'QUANTITY') {
1142
1143
  minAmount = this.safeNumber(entry, 'min');
1143
1144
  maxAmount = this.safeNumber(entry, 'max');
1145
+ amountPrecision = this.safeNumber(entry, 'tickSize');
1144
1146
  }
1145
1147
  if (filter === 'QUOTE_QTY') {
1146
1148
  minCost = this.safeNumber(entry, 'min');
@@ -1150,6 +1152,9 @@ class xt extends xt$1 {
1150
1152
  maxPrice = this.safeNumber(entry, 'max');
1151
1153
  }
1152
1154
  }
1155
+ if (amountPrecision === undefined) {
1156
+ amountPrecision = this.parseNumber(this.parsePrecision(this.safeString(market, 'quantityPrecision')));
1157
+ }
1153
1158
  const underlyingType = this.safeString(market, 'underlyingType');
1154
1159
  let linear = undefined;
1155
1160
  let inverse = undefined;
@@ -1232,7 +1237,7 @@ class xt extends xt$1 {
1232
1237
  'optionType': undefined,
1233
1238
  'precision': {
1234
1239
  'price': this.parseNumber(this.parsePrecision(this.safeString(market, 'pricePrecision'))),
1235
- 'amount': this.parseNumber(this.parsePrecision(this.safeString(market, 'quantityPrecision'))),
1240
+ 'amount': amountPrecision,
1236
1241
  'base': this.parseNumber(this.parsePrecision(this.safeString(market, 'baseCoinPrecision'))),
1237
1242
  'quote': this.parseNumber(this.parsePrecision(this.safeString(market, 'quoteCoinPrecision'))),
1238
1243
  },
@@ -1372,7 +1377,7 @@ class xt extends xt$1 {
1372
1377
  this.safeNumber(ohlcv, 'h'),
1373
1378
  this.safeNumber(ohlcv, 'l'),
1374
1379
  this.safeNumber(ohlcv, 'c'),
1375
- this.safeNumber2(ohlcv, volumeIndex, 'v'),
1380
+ this.safeNumber2(ohlcv, 'q', volumeIndex),
1376
1381
  ];
1377
1382
  }
1378
1383
  async fetchOrderBook(symbol, limit = undefined, params = {}) {
@@ -11,6 +11,10 @@ const fsPromises = fs.promises;
11
11
  ansi.nice
12
12
  const log = ololog.configure ({ locate: false }).unlimited
13
13
  const { ExchangeError , NetworkError} = ccxt
14
+
15
+ function jsonStringify (obj, indent = undefined) {
16
+ return JSON.stringify (obj, function(k, v) { return v === undefined ? null : v; }, indent);
17
+ }
14
18
  //-----------------------------------------------------------------------------
15
19
 
16
20
  let [processPath, , exchangeId, methodName, ... params] = process.argv.filter (x => !x.startsWith ('--'))
@@ -164,7 +168,7 @@ function createResponseTemplate(exchange, methodName, args, result) {
164
168
  }
165
169
  log('Report: (paste inside static/response/' + exchange.id + '.json ->' + methodName + ')')
166
170
  log.green('-------------------------------------------')
167
- log (JSON.stringify (final, function(k, v) { return v === undefined ? null : v; }, 2))
171
+ log (jsonStringify (final, 2))
168
172
  log.green('-------------------------------------------')
169
173
  }
170
174
 
@@ -206,7 +210,7 @@ function printUsage () {
206
210
 
207
211
  const printHumanReadable = (exchange, result) => {
208
212
  if (raw) {
209
- return log (JSON.stringify(result))
213
+ return log (jsonStringify (result))
210
214
  }
211
215
  if (!no_table && Array.isArray (result) || table) {
212
216
  result = Object.values (result)
@@ -227,7 +231,7 @@ const printHumanReadable = (exchange, result) => {
227
231
  dash: '-'.lightGray.dim,
228
232
  print: x => {
229
233
  if (typeof x === 'object') {
230
- const j = JSON.stringify (x).trim ()
234
+ const j = jsonStringify (x).trim ()
231
235
  if (j.length < 100) return j
232
236
  }
233
237
  return String (x)
@@ -302,7 +306,7 @@ async function run () {
302
306
  } catch {
303
307
  await exchange.loadMarkets ()
304
308
  if (cache_markets) {
305
- await fsPromises.writeFile (path, JSON.stringify (exchange.markets))
309
+ await fsPromises.writeFile (path, jsonStringify (exchange.markets))
306
310
  }
307
311
  }
308
312
  }
package/js/ccxt.d.ts CHANGED
@@ -2,9 +2,9 @@ import { Exchange } from './src/base/Exchange.js';
2
2
  import { Precise } from './src/base/Precise.js';
3
3
  import * as functions from './src/base/functions.js';
4
4
  import * as errors from './src/base/errors.js';
5
- import type { Int, int, Str, Strings, Num, Bool, IndexType, OrderSide, OrderType, MarketType, SubType, Dict, NullableDict, List, NullableList, Fee, OHLCV, OHLCVC, implicitReturnType, Market, Currency, Dictionary, MinMax, FeeInterface, TradingFeeInterface, MarketInterface, Trade, Order, OrderBook, Ticker, Transaction, Tickers, CurrencyInterface, Balance, BalanceAccount, Account, PartialBalances, Balances, DepositAddress, WithdrawalResponse, DepositAddressResponse, FundingRate, FundingRates, Position, BorrowInterest, LeverageTier, LedgerEntry, DepositWithdrawFeeNetwork, DepositWithdrawFee, TransferEntry, CrossBorrowRate, IsolatedBorrowRate, FundingRateHistory, OpenInterest, Liquidation, OrderRequest, CancellationRequest, FundingHistory, MarginMode, Greeks, Conversion, Option, LastPrice, Leverage, MarginModification, Leverages, LastPrices, Currencies, TradingFees, MarginModes, OptionChain, IsolatedBorrowRates, CrossBorrowRates, LeverageTiers } from './src/base/types.js';
5
+ import type { Int, int, Str, Strings, Num, Bool, IndexType, OrderSide, OrderType, MarketType, SubType, Dict, NullableDict, List, NullableList, Fee, OHLCV, OHLCVC, implicitReturnType, Market, Currency, Dictionary, MinMax, FeeInterface, TradingFeeInterface, MarketInterface, Trade, Order, OrderBook, Ticker, Transaction, Tickers, CurrencyInterface, Balance, BalanceAccount, Account, PartialBalances, Balances, DepositAddress, WithdrawalResponse, DepositAddressResponse, FundingRate, FundingRates, Position, BorrowInterest, LeverageTier, LedgerEntry, DepositWithdrawFeeNetwork, DepositWithdrawFee, TransferEntry, CrossBorrowRate, IsolatedBorrowRate, FundingRateHistory, OpenInterest, Liquidation, OrderRequest, CancellationRequest, FundingHistory, MarketMarginModes, MarginMode, Greeks, Conversion, Option, LastPrice, Leverage, MarginModification, Leverages, LastPrices, Currencies, TradingFees, MarginModes, OptionChain, IsolatedBorrowRates, CrossBorrowRates, LeverageTiers } from './src/base/types.js';
6
6
  import { BaseError, ExchangeError, AuthenticationError, PermissionDenied, AccountNotEnabled, AccountSuspended, ArgumentsRequired, BadRequest, BadSymbol, OperationRejected, NoChange, MarginModeAlreadySet, MarketClosed, ManualInteractionNeeded, InsufficientFunds, InvalidAddress, AddressPending, InvalidOrder, OrderNotFound, OrderNotCached, OrderImmediatelyFillable, OrderNotFillable, DuplicateOrderId, ContractUnavailable, NotSupported, InvalidProxySettings, ExchangeClosedByUser, OperationFailed, NetworkError, DDoSProtection, RateLimitExceeded, ExchangeNotAvailable, OnMaintenance, InvalidNonce, ChecksumError, RequestTimeout, BadResponse, NullResponse, CancelPending, UnsubscribeError } from './src/base/errors.js';
7
- declare const version = "4.4.0";
7
+ declare const version = "4.4.2";
8
8
  import ace from './src/ace.js';
9
9
  import alpaca from './src/alpaca.js';
10
10
  import ascendex from './src/ascendex.js';
@@ -555,5 +555,5 @@ declare const ccxt: {
555
555
  zaif: typeof zaif;
556
556
  zonda: typeof zonda;
557
557
  } & typeof functions & typeof errors;
558
- export { version, Exchange, exchanges, pro, Precise, functions, errors, BaseError, ExchangeError, AuthenticationError, PermissionDenied, AccountNotEnabled, AccountSuspended, ArgumentsRequired, BadRequest, BadSymbol, OperationRejected, NoChange, MarginModeAlreadySet, MarketClosed, ManualInteractionNeeded, InsufficientFunds, InvalidAddress, AddressPending, InvalidOrder, OrderNotFound, OrderNotCached, OrderImmediatelyFillable, OrderNotFillable, DuplicateOrderId, ContractUnavailable, NotSupported, InvalidProxySettings, ExchangeClosedByUser, OperationFailed, NetworkError, DDoSProtection, RateLimitExceeded, ExchangeNotAvailable, OnMaintenance, InvalidNonce, ChecksumError, RequestTimeout, BadResponse, NullResponse, CancelPending, UnsubscribeError, Int, int, Str, Strings, Num, Bool, IndexType, OrderSide, OrderType, MarketType, SubType, Dict, NullableDict, List, NullableList, Fee, OHLCV, OHLCVC, implicitReturnType, Market, Currency, Dictionary, MinMax, FeeInterface, TradingFeeInterface, MarketInterface, Trade, Order, OrderBook, Ticker, Transaction, Tickers, CurrencyInterface, Balance, BalanceAccount, Account, PartialBalances, Balances, DepositAddress, WithdrawalResponse, DepositAddressResponse, FundingRate, FundingRates, Position, BorrowInterest, LeverageTier, LedgerEntry, DepositWithdrawFeeNetwork, DepositWithdrawFee, TransferEntry, CrossBorrowRate, IsolatedBorrowRate, FundingRateHistory, OpenInterest, Liquidation, OrderRequest, CancellationRequest, FundingHistory, MarginMode, Greeks, Conversion, Option, LastPrice, Leverage, MarginModification, Leverages, LastPrices, Currencies, TradingFees, MarginModes, OptionChain, IsolatedBorrowRates, CrossBorrowRates, LeverageTiers, ace, alpaca, ascendex, bequant, bigone, binance, binancecoinm, binanceus, binanceusdm, bingx, bit2c, bitbank, bitbns, bitcoincom, bitfinex, bitfinex2, bitflyer, bitget, bithumb, bitmart, bitmex, bitopro, bitpanda, bitrue, bitso, bitstamp, bitteam, bitvavo, bl3p, blockchaincom, blofin, btcalpha, btcbox, btcmarkets, btcturk, bybit, cex, coinbase, coinbaseadvanced, coinbaseexchange, coinbaseinternational, coincheck, coinex, coinlist, coinmate, coinmetro, coinone, coinsph, coinspot, cryptocom, currencycom, delta, deribit, digifinex, exmo, fmfwio, gate, gateio, gemini, hashkey, hitbtc, hollaex, htx, huobi, huobijp, hyperliquid, idex, independentreserve, indodax, kraken, krakenfutures, kucoin, kucoinfutures, kuna, latoken, lbank, luno, lykke, mercado, mexc, ndax, novadax, oceanex, okcoin, okx, onetrading, oxfun, p2b, paradex, paymium, phemex, poloniex, poloniexfutures, probit, timex, tokocrypto, tradeogre, upbit, vertex, wavesexchange, wazirx, whitebit, woo, woofipro, xt, yobit, zaif, zonda, };
558
+ export { version, Exchange, exchanges, pro, Precise, functions, errors, BaseError, ExchangeError, AuthenticationError, PermissionDenied, AccountNotEnabled, AccountSuspended, ArgumentsRequired, BadRequest, BadSymbol, OperationRejected, NoChange, MarginModeAlreadySet, MarketClosed, ManualInteractionNeeded, InsufficientFunds, InvalidAddress, AddressPending, InvalidOrder, OrderNotFound, OrderNotCached, OrderImmediatelyFillable, OrderNotFillable, DuplicateOrderId, ContractUnavailable, NotSupported, InvalidProxySettings, ExchangeClosedByUser, OperationFailed, NetworkError, DDoSProtection, RateLimitExceeded, ExchangeNotAvailable, OnMaintenance, InvalidNonce, ChecksumError, RequestTimeout, BadResponse, NullResponse, CancelPending, UnsubscribeError, Int, int, Str, Strings, Num, Bool, IndexType, OrderSide, OrderType, MarketType, SubType, Dict, NullableDict, List, NullableList, Fee, OHLCV, OHLCVC, implicitReturnType, Market, Currency, Dictionary, MinMax, FeeInterface, TradingFeeInterface, MarketMarginModes, MarketInterface, Trade, Order, OrderBook, Ticker, Transaction, Tickers, CurrencyInterface, Balance, BalanceAccount, Account, PartialBalances, Balances, DepositAddress, WithdrawalResponse, DepositAddressResponse, FundingRate, FundingRates, Position, BorrowInterest, LeverageTier, LedgerEntry, DepositWithdrawFeeNetwork, DepositWithdrawFee, TransferEntry, CrossBorrowRate, IsolatedBorrowRate, FundingRateHistory, OpenInterest, Liquidation, OrderRequest, CancellationRequest, FundingHistory, MarginMode, Greeks, Conversion, Option, LastPrice, Leverage, MarginModification, Leverages, LastPrices, Currencies, TradingFees, MarginModes, OptionChain, IsolatedBorrowRates, CrossBorrowRates, LeverageTiers, ace, alpaca, ascendex, bequant, bigone, binance, binancecoinm, binanceus, binanceusdm, bingx, bit2c, bitbank, bitbns, bitcoincom, bitfinex, bitfinex2, bitflyer, bitget, bithumb, bitmart, bitmex, bitopro, bitpanda, bitrue, bitso, bitstamp, bitteam, bitvavo, bl3p, blockchaincom, blofin, btcalpha, btcbox, btcmarkets, btcturk, bybit, cex, coinbase, coinbaseadvanced, coinbaseexchange, coinbaseinternational, coincheck, coinex, coinlist, coinmate, coinmetro, coinone, coinsph, coinspot, cryptocom, currencycom, delta, deribit, digifinex, exmo, fmfwio, gate, gateio, gemini, hashkey, hitbtc, hollaex, htx, huobi, huobijp, hyperliquid, idex, independentreserve, indodax, kraken, krakenfutures, kucoin, kucoinfutures, kuna, latoken, lbank, luno, lykke, mercado, mexc, ndax, novadax, oceanex, okcoin, okx, onetrading, oxfun, p2b, paradex, paymium, phemex, poloniex, poloniexfutures, probit, timex, tokocrypto, tradeogre, upbit, vertex, wavesexchange, wazirx, whitebit, woo, woofipro, xt, yobit, zaif, zonda, };
559
559
  export default ccxt;
package/js/ccxt.js CHANGED
@@ -38,7 +38,7 @@ import * as errors from './src/base/errors.js';
38
38
  import { BaseError, ExchangeError, AuthenticationError, PermissionDenied, AccountNotEnabled, AccountSuspended, ArgumentsRequired, BadRequest, BadSymbol, OperationRejected, NoChange, MarginModeAlreadySet, MarketClosed, ManualInteractionNeeded, InsufficientFunds, InvalidAddress, AddressPending, InvalidOrder, OrderNotFound, OrderNotCached, OrderImmediatelyFillable, OrderNotFillable, DuplicateOrderId, ContractUnavailable, NotSupported, InvalidProxySettings, ExchangeClosedByUser, OperationFailed, NetworkError, DDoSProtection, RateLimitExceeded, ExchangeNotAvailable, OnMaintenance, InvalidNonce, ChecksumError, RequestTimeout, BadResponse, NullResponse, CancelPending, UnsubscribeError } from './src/base/errors.js';
39
39
  //-----------------------------------------------------------------------------
40
40
  // this is updated by vss.js when building
41
- const version = '4.4.1';
41
+ const version = '4.4.3';
42
42
  Exchange.ccxtVersion = version;
43
43
  //-----------------------------------------------------------------------------
44
44
  import ace from './src/ace.js';
@@ -83,6 +83,7 @@ interface Exchange {
83
83
  privatePostSpotV4QueryTrades(params?: {}): Promise<implicitReturnType>;
84
84
  privatePostSpotV4QueryOrderTrades(params?: {}): Promise<implicitReturnType>;
85
85
  privatePostSpotV4CancelOrders(params?: {}): Promise<implicitReturnType>;
86
+ privatePostSpotV4CancelAll(params?: {}): Promise<implicitReturnType>;
86
87
  privatePostSpotV4BatchOrders(params?: {}): Promise<implicitReturnType>;
87
88
  privatePostSpotV3CancelOrder(params?: {}): Promise<implicitReturnType>;
88
89
  privatePostSpotV2BatchOrders(params?: {}): Promise<implicitReturnType>;
@@ -1147,5 +1147,7 @@ export default class Exchange {
1147
1147
  parseMarginModifications(response: object[], symbols?: Strings, symbolKey?: Str, marketType?: MarketType): MarginModification[];
1148
1148
  fetchTransfer(id: string, code?: Str, params?: {}): Promise<TransferEntry>;
1149
1149
  fetchTransfers(code?: Str, since?: Int, limit?: Int, params?: {}): Promise<TransferEntry[]>;
1150
+ cleanUnsubscription(client: any, subHash: string, unsubHash: string): void;
1151
+ cleanCache(subscription: Dict): void;
1150
1152
  }
1151
1153
  export { Exchange, };