ccxt 4.3.89 → 4.3.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 (57) 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/alpaca.js +2 -2
  5. package/dist/cjs/src/ascendex.js +95 -97
  6. package/dist/cjs/src/bingx.js +31 -17
  7. package/dist/cjs/src/bitfinex2.js +21 -22
  8. package/dist/cjs/src/bitget.js +2 -2
  9. package/dist/cjs/src/bitmart.js +6 -9
  10. package/dist/cjs/src/coinbaseinternational.js +2 -1
  11. package/dist/cjs/src/coinex.js +1 -17
  12. package/dist/cjs/src/hitbtc.js +1 -0
  13. package/dist/cjs/src/htx.js +49 -49
  14. package/dist/cjs/src/huobijp.js +0 -9
  15. package/dist/cjs/src/latoken.js +1 -0
  16. package/dist/cjs/src/okx.js +1 -8
  17. package/dist/cjs/src/pro/binance.js +323 -0
  18. package/dist/cjs/src/pro/bingx.js +263 -91
  19. package/dist/cjs/src/pro/bithumb.js +5 -1
  20. package/dist/cjs/src/pro/bybit.js +1 -1
  21. package/dist/cjs/src/pro/coinex.js +994 -679
  22. package/dist/cjs/src/pro/lbank.js +2 -3
  23. package/dist/cjs/src/pro/okx.js +159 -3
  24. package/dist/cjs/src/whitebit.js +5 -3
  25. package/js/ccxt.d.ts +1 -1
  26. package/js/ccxt.js +1 -1
  27. package/js/src/alpaca.js +2 -2
  28. package/js/src/ascendex.js +95 -97
  29. package/js/src/bingx.js +31 -17
  30. package/js/src/bitfinex2.d.ts +0 -1
  31. package/js/src/bitfinex2.js +21 -22
  32. package/js/src/bitget.js +2 -2
  33. package/js/src/bitmart.d.ts +0 -1
  34. package/js/src/bitmart.js +6 -9
  35. package/js/src/coinbaseinternational.js +2 -1
  36. package/js/src/coinex.d.ts +0 -2
  37. package/js/src/coinex.js +1 -17
  38. package/js/src/hitbtc.js +1 -0
  39. package/js/src/htx.js +49 -49
  40. package/js/src/huobijp.d.ts +0 -1
  41. package/js/src/huobijp.js +0 -9
  42. package/js/src/latoken.js +1 -0
  43. package/js/src/okx.d.ts +0 -1
  44. package/js/src/okx.js +1 -8
  45. package/js/src/pro/binance.d.ts +9 -1
  46. package/js/src/pro/binance.js +327 -1
  47. package/js/src/pro/bingx.d.ts +2 -2
  48. package/js/src/pro/bingx.js +263 -91
  49. package/js/src/pro/bithumb.js +5 -1
  50. package/js/src/pro/bybit.js +1 -1
  51. package/js/src/pro/coinex.d.ts +12 -6
  52. package/js/src/pro/coinex.js +996 -681
  53. package/js/src/pro/lbank.js +2 -3
  54. package/js/src/pro/okx.d.ts +7 -0
  55. package/js/src/pro/okx.js +162 -4
  56. package/js/src/whitebit.js +5 -3
  57. package/package.json +1 -1
@@ -28,7 +28,8 @@ class bingx extends bingx$1 {
28
28
  'api': {
29
29
  'ws': {
30
30
  'spot': 'wss://open-api-ws.bingx.com/market',
31
- 'swap': 'wss://open-api-swap.bingx.com/swap-market',
31
+ 'linear': 'wss://open-api-swap.bingx.com/swap-market',
32
+ 'inverse': 'wss://open-api-cswap-ws.bingx.com/market',
32
33
  },
33
34
  },
34
35
  },
@@ -88,17 +89,25 @@ class bingx extends bingx$1 {
88
89
  * @method
89
90
  * @name bingx#watchTicker
90
91
  * @description watches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
92
+ * @see https://bingx-api.github.io/docs/#/en-us/spot/socket/market.html#Subscribe%20to%2024-hour%20Price%20Change
91
93
  * @see https://bingx-api.github.io/docs/#/en-us/swapV2/socket/market.html#Subscribe%20to%2024-hour%20price%20changes
94
+ * @see https://bingx-api.github.io/docs/#/en-us/cswap/socket/market.html#Subscribe%20to%2024-Hour%20Price%20Change
92
95
  * @param {string} symbol unified symbol of the market to fetch the ticker for
93
96
  * @param {object} [params] extra parameters specific to the exchange API endpoint
94
97
  * @returns {object} a [ticker structure]{@link https://docs.ccxt.com/#/?id=ticker-structure}
95
98
  */
96
99
  await this.loadMarkets();
97
100
  const market = this.market(symbol);
98
- const [marketType, query] = this.handleMarketTypeAndParams('watchTicker', market, params);
99
- const url = this.safeValue(this.urls['api']['ws'], marketType);
100
- if (url === undefined) {
101
- throw new errors.BadRequest(this.id + ' watchTicker is not supported for ' + marketType + ' markets.');
101
+ let marketType = undefined;
102
+ let subType = undefined;
103
+ let url = undefined;
104
+ [marketType, params] = this.handleMarketTypeAndParams('watchTicker', market, params);
105
+ [subType, params] = this.handleSubTypeAndParams('watchTicker', market, params, 'linear');
106
+ if (marketType === 'swap') {
107
+ url = this.safeString(this.urls['api']['ws'], subType);
108
+ }
109
+ else {
110
+ url = this.safeString(this.urls['api']['ws'], marketType);
102
111
  }
103
112
  const subscriptionHash = market['id'] + '@ticker';
104
113
  const messageHash = this.getMessageHash('ticker', market['symbol']);
@@ -110,7 +119,7 @@ class bingx extends bingx$1 {
110
119
  if (marketType === 'swap') {
111
120
  request['reqType'] = 'sub';
112
121
  }
113
- return await this.watch(url, messageHash, this.extend(request, query), subscriptionHash);
122
+ return await this.watch(url, messageHash, this.extend(request, params), subscriptionHash);
114
123
  }
115
124
  handleTicker(client, message) {
116
125
  //
@@ -245,14 +254,19 @@ class bingx extends bingx$1 {
245
254
  symbols = this.marketSymbols(symbols, undefined, true, true, false);
246
255
  let firstMarket = undefined;
247
256
  let marketType = undefined;
257
+ let subType = undefined;
248
258
  const symbolsDefined = (symbols !== undefined);
249
259
  if (symbolsDefined) {
250
260
  firstMarket = this.market(symbols[0]);
251
261
  }
252
262
  [marketType, params] = this.handleMarketTypeAndParams('watchTickers', firstMarket, params);
263
+ [subType, params] = this.handleSubTypeAndParams('watchTickers', firstMarket, params, 'linear');
253
264
  if (marketType === 'spot') {
254
265
  throw new errors.NotSupported(this.id + ' watchTickers is not supported for spot markets yet');
255
266
  }
267
+ if (subType === 'inverse') {
268
+ throw new errors.NotSupported(this.id + ' watchTickers is not supported for inverse markets yet');
269
+ }
256
270
  const messageHashes = [];
257
271
  const subscriptionHashes = ['all@ticker'];
258
272
  if (symbolsDefined) {
@@ -265,7 +279,7 @@ class bingx extends bingx$1 {
265
279
  else {
266
280
  messageHashes.push(this.getMessageHash('ticker'));
267
281
  }
268
- const url = this.safeString(this.urls['api']['ws'], marketType);
282
+ const url = this.safeString(this.urls['api']['ws'], subType);
269
283
  const uuid = this.uuid();
270
284
  const request = {
271
285
  'id': uuid,
@@ -296,14 +310,19 @@ class bingx extends bingx$1 {
296
310
  symbols = this.marketSymbols(symbols, undefined, true, true, false);
297
311
  let firstMarket = undefined;
298
312
  let marketType = undefined;
313
+ let subType = undefined;
299
314
  const symbolsDefined = (symbols !== undefined);
300
315
  if (symbolsDefined) {
301
316
  firstMarket = this.market(symbols[0]);
302
317
  }
303
318
  [marketType, params] = this.handleMarketTypeAndParams('watchOrderBookForSymbols', firstMarket, params);
319
+ [subType, params] = this.handleSubTypeAndParams('watchOrderBookForSymbols', firstMarket, params, 'linear');
304
320
  if (marketType === 'spot') {
305
321
  throw new errors.NotSupported(this.id + ' watchOrderBookForSymbols is not supported for spot markets yet');
306
322
  }
323
+ if (subType === 'inverse') {
324
+ throw new errors.NotSupported(this.id + ' watchOrderBookForSymbols is not supported for inverse markets yet');
325
+ }
307
326
  limit = this.getOrderBookLimitByMarketType(marketType, limit);
308
327
  let interval = undefined;
309
328
  [interval, params] = this.handleOptionAndParams(params, 'watchOrderBookForSymbols', 'interval', 500);
@@ -321,7 +340,7 @@ class bingx extends bingx$1 {
321
340
  else {
322
341
  messageHashes.push(this.getMessageHash('orderbook'));
323
342
  }
324
- const url = this.safeString(this.urls['api']['ws'], marketType);
343
+ const url = this.safeString(this.urls['api']['ws'], subType);
325
344
  const uuid = this.uuid();
326
345
  const request = {
327
346
  'id': uuid,
@@ -344,6 +363,7 @@ class bingx extends bingx$1 {
344
363
  * @method
345
364
  * @name bingx#watchOHLCVForSymbols
346
365
  * @description watches historical candlestick data containing the open, high, low, and close price, and the volume of a market
366
+ * @see https://bingx-api.github.io/docs/#/en-us/swapV2/socket/market.html#Subscribe%20K-Line%20Data%20of%20all%20trading%20pairs
347
367
  * @param {string[][]} symbolsAndTimeframes array of arrays containing unified symbols and timeframes to fetch OHLCV data for, example [['BTC/USDT', '1m'], ['LTC/USDT', '5m']]
348
368
  * @param {int} [since] timestamp in ms of the earliest candle to fetch
349
369
  * @param {int} [limit] the maximum amount of candles to fetch
@@ -357,15 +377,21 @@ class bingx extends bingx$1 {
357
377
  await this.loadMarkets();
358
378
  const messageHashes = [];
359
379
  let marketType = undefined;
380
+ let subType = undefined;
360
381
  let chosenTimeframe = undefined;
382
+ let firstMarket = undefined;
361
383
  if (symbolsLength !== 0) {
362
384
  let symbols = this.getListFromObjectValues(symbolsAndTimeframes, 0);
363
385
  symbols = this.marketSymbols(symbols, undefined, true, true, false);
364
- const firstMarket = this.market(symbols[0]);
365
- [marketType, params] = this.handleMarketTypeAndParams('watchOrderBookForSymbols', firstMarket, params);
366
- if (marketType === 'spot') {
367
- throw new errors.NotSupported(this.id + ' watchOrderBookForSymbols is not supported for spot markets yet');
368
- }
386
+ firstMarket = this.market(symbols[0]);
387
+ }
388
+ [marketType, params] = this.handleMarketTypeAndParams('watchOHLCVForSymbols', firstMarket, params);
389
+ [subType, params] = this.handleSubTypeAndParams('watchOHLCVForSymbols', firstMarket, params, 'linear');
390
+ if (marketType === 'spot') {
391
+ throw new errors.NotSupported(this.id + ' watchOHLCVForSymbols is not supported for spot markets yet');
392
+ }
393
+ if (subType === 'inverse') {
394
+ throw new errors.NotSupported(this.id + ' watchOHLCVForSymbols is not supported for inverse markets yet');
369
395
  }
370
396
  const marketOptions = this.safeDict(this.options, marketType);
371
397
  const timeframes = this.safeDict(marketOptions, 'timeframes', {});
@@ -384,7 +410,7 @@ class bingx extends bingx$1 {
384
410
  messageHashes.push(this.getMessageHash('ohlcv', market['symbol'], chosenTimeframe));
385
411
  }
386
412
  const subscriptionHash = 'all@kline_' + chosenTimeframe;
387
- const url = this.safeString(this.urls['api']['ws'], marketType);
413
+ const url = this.safeString(this.urls['api']['ws'], subType);
388
414
  const uuid = this.uuid();
389
415
  const request = {
390
416
  'id': uuid,
@@ -436,8 +462,9 @@ class bingx extends bingx$1 {
436
462
  * @method
437
463
  * @name bingx#watchTrades
438
464
  * @description watches information on multiple trades made in a market
439
- * @see https://bingx-api.github.io/docs/#/en-us/spot/socket/market.html#Subscription%20transaction%20by%20transaction
440
- * @see https://bingx-api.github.io/docs/#/en-us/swapV2/socket/market.html#Subscribe%20the%20Latest%20Trade%20Detail
465
+ * @see https://bingx-api.github.io/docs/#/spot/socket/market.html#Subscribe%20to%20tick-by-tick
466
+ * @see https://bingx-api.github.io/docs/#/swapV2/socket/market.html#Subscribe%20the%20Latest%20Trade%20Detail
467
+ * @see https://bingx-api.github.io/docs/#/en-us/cswap/socket/market.html#Subscription%20transaction%20by%20transaction
441
468
  * @param {string} symbol unified market symbol of the market orders were made in
442
469
  * @param {int} [since] the earliest time in ms to fetch orders for
443
470
  * @param {int} [limit] the maximum number of order structures to retrieve
@@ -446,11 +473,17 @@ class bingx extends bingx$1 {
446
473
  */
447
474
  await this.loadMarkets();
448
475
  const market = this.market(symbol);
476
+ symbol = market['symbol'];
449
477
  let marketType = undefined;
478
+ let subType = undefined;
479
+ let url = undefined;
450
480
  [marketType, params] = this.handleMarketTypeAndParams('watchTrades', market, params);
451
- const url = this.safeValue(this.urls['api']['ws'], marketType);
452
- if (url === undefined) {
453
- throw new errors.BadRequest(this.id + ' watchTrades is not supported for ' + marketType + ' markets.');
481
+ [subType, params] = this.handleSubTypeAndParams('watchTrades', market, params, 'linear');
482
+ if (marketType === 'swap') {
483
+ url = this.safeString(this.urls['api']['ws'], subType);
484
+ }
485
+ else {
486
+ url = this.safeString(this.urls['api']['ws'], marketType);
454
487
  }
455
488
  const rawHash = market['id'] + '@trade';
456
489
  const messageHash = 'trade::' + symbol;
@@ -470,8 +503,7 @@ class bingx extends bingx$1 {
470
503
  }
471
504
  handleTrades(client, message) {
472
505
  //
473
- // spot
474
- // first snapshot
506
+ // spot: first snapshot
475
507
  //
476
508
  // {
477
509
  // "id": "d83b78ce-98be-4dc2-b847-12fe471b5bc5",
@@ -480,7 +512,7 @@ class bingx extends bingx$1 {
480
512
  // "timestamp": 1690214699854
481
513
  // }
482
514
  //
483
- // subsequent updates
515
+ // spot: subsequent updates
484
516
  //
485
517
  // {
486
518
  // "code": 0,
@@ -498,9 +530,7 @@ class bingx extends bingx$1 {
498
530
  // "success": true
499
531
  // }
500
532
  //
501
- //
502
- // swap
503
- // first snapshot
533
+ // linear swap: first snapshot
504
534
  //
505
535
  // {
506
536
  // "id": "2aed93b1-6e1e-4038-aeba-f5eeaec2ca48",
@@ -510,8 +540,7 @@ class bingx extends bingx$1 {
510
540
  // "data": null
511
541
  // }
512
542
  //
513
- // subsequent updates
514
- //
543
+ // linear swap: subsequent updates
515
544
  //
516
545
  // {
517
546
  // "code": 0,
@@ -528,6 +557,32 @@ class bingx extends bingx$1 {
528
557
  // ]
529
558
  // }
530
559
  //
560
+ // inverse swap: first snapshot
561
+ //
562
+ // {
563
+ // "code": 0,
564
+ // "id": "a2e482ca-f71b-42f8-a83a-8ff85a713e64",
565
+ // "msg": "SUCCESS",
566
+ // "timestamp": 1722920589426
567
+ // }
568
+ //
569
+ // inverse swap: subsequent updates
570
+ //
571
+ // {
572
+ // "code": 0,
573
+ // "dataType": "BTC-USD@trade",
574
+ // "data": {
575
+ // "e": "trade",
576
+ // "E": 1722920589665,
577
+ // "s": "BTC-USD",
578
+ // "t": "39125001",
579
+ // "p": "55360.0",
580
+ // "q": "1",
581
+ // "T": 1722920589582,
582
+ // "m": false
583
+ // }
584
+ // }
585
+ //
531
586
  const data = this.safeValue(message, 'data', []);
532
587
  const rawHash = this.safeString(message, 'dataType');
533
588
  const marketId = rawHash.split('@')[0];
@@ -561,6 +616,7 @@ class bingx extends bingx$1 {
561
616
  * @description watches information on open orders with bid (buy) and ask (sell) prices, volumes and other data
562
617
  * @see https://bingx-api.github.io/docs/#/en-us/spot/socket/market.html#Subscribe%20Market%20Depth%20Data
563
618
  * @see https://bingx-api.github.io/docs/#/en-us/swapV2/socket/market.html#Subscribe%20Market%20Depth%20Data
619
+ * @see https://bingx-api.github.io/docs/#/en-us/cswap/socket/market.html#Subscribe%20to%20Limited%20Depth
564
620
  * @param {string} symbol unified symbol of the market to fetch the order book for
565
621
  * @param {int} [limit] the maximum amount of order book entries to return
566
622
  * @param {object} [params] extra parameters specific to the exchange API endpoint
@@ -568,18 +624,26 @@ class bingx extends bingx$1 {
568
624
  */
569
625
  await this.loadMarkets();
570
626
  const market = this.market(symbol);
571
- const [marketType, query] = this.handleMarketTypeAndParams('watchOrderBook', market, params);
627
+ let marketType = undefined;
628
+ let subType = undefined;
629
+ let url = undefined;
630
+ [marketType, params] = this.handleMarketTypeAndParams('watchOrderBook', market, params);
631
+ [subType, params] = this.handleSubTypeAndParams('watchOrderBook', market, params, 'linear');
632
+ if (marketType === 'swap') {
633
+ url = this.safeString(this.urls['api']['ws'], subType);
634
+ }
635
+ else {
636
+ url = this.safeString(this.urls['api']['ws'], marketType);
637
+ }
572
638
  limit = this.getOrderBookLimitByMarketType(marketType, limit);
573
639
  let channelName = 'depth' + limit.toString();
574
- const url = this.safeValue(this.urls['api']['ws'], marketType);
575
- if (url === undefined) {
576
- throw new errors.BadRequest(this.id + ' watchOrderBook is not supported for ' + marketType + ' markets.');
577
- }
578
640
  let interval = undefined;
579
641
  if (marketType !== 'spot') {
580
- [interval, params] = this.handleOptionAndParams(params, 'watchOrderBook', 'interval', 500);
581
- this.checkRequiredArgument('watchOrderBook', interval, 'interval', [100, 200, 500, 1000]);
582
- channelName = channelName + '@' + interval.toString() + 'ms';
642
+ if (!market['inverse']) {
643
+ [interval, params] = this.handleOptionAndParams(params, 'watchOrderBook', 'interval', 500);
644
+ this.checkRequiredArgument('watchOrderBook', interval, 'interval', [100, 200, 500, 1000]);
645
+ channelName = channelName + '@' + interval.toString() + 'ms';
646
+ }
583
647
  }
584
648
  const subscriptionHash = market['id'] + '@' + channelName;
585
649
  const messageHash = this.getMessageHash('orderbook', market['symbol']);
@@ -591,24 +655,32 @@ class bingx extends bingx$1 {
591
655
  if (marketType === 'swap') {
592
656
  request['reqType'] = 'sub';
593
657
  }
594
- const subscriptionArgs = {
595
- 'limit': limit,
596
- 'interval': interval,
597
- 'params': params,
598
- };
599
- const orderbook = await this.watch(url, messageHash, this.deepExtend(request, query), subscriptionHash, subscriptionArgs);
658
+ let subscriptionArgs = {};
659
+ if (market['inverse']) {
660
+ subscriptionArgs = {
661
+ 'count': limit,
662
+ 'params': params,
663
+ };
664
+ }
665
+ else {
666
+ subscriptionArgs = {
667
+ 'level': limit,
668
+ 'interval': interval,
669
+ 'params': params,
670
+ };
671
+ }
672
+ const orderbook = await this.watch(url, messageHash, this.deepExtend(request, params), subscriptionHash, subscriptionArgs);
600
673
  return orderbook.limit();
601
674
  }
602
675
  handleDelta(bookside, delta) {
603
- const price = this.safeFloat(delta, 0);
604
- const amount = this.safeFloat(delta, 1);
676
+ const price = this.safeFloat2(delta, 0, 'p');
677
+ const amount = this.safeFloat2(delta, 1, 'a');
605
678
  bookside.store(price, amount);
606
679
  }
607
680
  handleOrderBook(client, message) {
608
681
  //
609
682
  // spot
610
683
  //
611
- //
612
684
  // {
613
685
  // "code": 0,
614
686
  // "dataType": "BTC-USDT@depth20",
@@ -626,8 +698,7 @@ class bingx extends bingx$1 {
626
698
  // "success": true
627
699
  // }
628
700
  //
629
- // swap
630
- //
701
+ // linear swap
631
702
  //
632
703
  // {
633
704
  // "code": 0,
@@ -645,6 +716,28 @@ class bingx extends bingx$1 {
645
716
  // }
646
717
  // }
647
718
  //
719
+ // inverse swap
720
+ //
721
+ // {
722
+ // "code": 0,
723
+ // "dataType": "BTC-USD@depth100",
724
+ // "data": {
725
+ // {
726
+ // "symbol": "BTC-USD",
727
+ // "bids": [
728
+ // { "p": "58074.2", "a": "1.422318", "v": "826.0" },
729
+ // ...
730
+ // ],
731
+ // "asks": [
732
+ // { "p": "62878.0", "a": "0.001590", "v": "1.0" },
733
+ // ...
734
+ // ],
735
+ // "aggPrecision": "0.1",
736
+ // "timestamp": 1723705093529
737
+ // }
738
+ // }
739
+ // }
740
+ //
648
741
  const data = this.safeDict(message, 'data', {});
649
742
  const dataType = this.safeString(message, 'dataType');
650
743
  const parts = dataType.split('@');
@@ -663,7 +756,13 @@ class bingx extends bingx$1 {
663
756
  this.orderbooks[symbol] = this.orderBook({}, limit);
664
757
  }
665
758
  const orderbook = this.orderbooks[symbol];
666
- const snapshot = this.parseOrderBook(data, symbol, undefined, 'bids', 'asks', 0, 1);
759
+ let snapshot = undefined;
760
+ if (market['inverse']) {
761
+ snapshot = this.parseOrderBook(data, symbol, undefined, 'bids', 'asks', 'p', 'a');
762
+ }
763
+ else {
764
+ snapshot = this.parseOrderBook(data, symbol, undefined, 'bids', 'asks', 0, 1);
765
+ }
667
766
  orderbook.reset(snapshot);
668
767
  this.orderbooks[symbol] = orderbook;
669
768
  const messageHash = this.getMessageHash('orderbook', symbol);
@@ -687,8 +786,11 @@ class bingx extends bingx$1 {
687
786
  // }
688
787
  //
689
788
  // for spot, opening-time (t) is used instead of closing-time (T), to be compatible with fetchOHLCV
690
- // for swap, (T) is the opening time
691
- const timestamp = (market['spot']) ? 't' : 'T';
789
+ // for linear swap, (T) is the opening time
790
+ let timestamp = (market['spot']) ? 't' : 'T';
791
+ if (market['swap']) {
792
+ timestamp = (market['inverse']) ? 't' : 'T';
793
+ }
692
794
  return [
693
795
  this.safeInteger(ohlcv, timestamp),
694
796
  this.safeNumber(ohlcv, 'o'),
@@ -700,7 +802,7 @@ class bingx extends bingx$1 {
700
802
  }
701
803
  handleOHLCV(client, message) {
702
804
  //
703
- // spot
805
+ // spot:
704
806
  //
705
807
  // {
706
808
  // "code": 0,
@@ -726,7 +828,8 @@ class bingx extends bingx$1 {
726
828
  // "success": true
727
829
  // }
728
830
  //
729
- // swap
831
+ // linear swap:
832
+ //
730
833
  // {
731
834
  // "code": 0,
732
835
  // "dataType": "BTC-USDT@kline_1m",
@@ -743,15 +846,26 @@ class bingx extends bingx$1 {
743
846
  // ]
744
847
  // }
745
848
  //
849
+ // inverse swap:
850
+ //
851
+ // {
852
+ // "code": 0,
853
+ // "timestamp": 1723769354547,
854
+ // "dataType": "BTC-USD@kline_1m",
855
+ // "data": {
856
+ // "t": 1723769340000,
857
+ // "o": 57485.1,
858
+ // "c": 57468,
859
+ // "l": 57464.9,
860
+ // "h": 57485.1,
861
+ // "a": 0.189663,
862
+ // "v": 109,
863
+ // "u": 92,
864
+ // "s": "BTC-USD"
865
+ // }
866
+ // }
867
+ //
746
868
  const isSwap = client.url.indexOf('swap') >= 0;
747
- let candles = undefined;
748
- if (isSwap) {
749
- candles = this.safeList(message, 'data', []);
750
- }
751
- else {
752
- const data = this.safeDict(message, 'data', {});
753
- candles = [this.safeDict(data, 'K', {})];
754
- }
755
869
  const dataType = this.safeString(message, 'dataType');
756
870
  const parts = dataType.split('@');
757
871
  const firstPart = parts[0];
@@ -759,6 +873,19 @@ class bingx extends bingx$1 {
759
873
  const marketId = this.safeString(message, 's', firstPart);
760
874
  const marketType = isSwap ? 'swap' : 'spot';
761
875
  const market = this.safeMarket(marketId, undefined, undefined, marketType);
876
+ let candles = undefined;
877
+ if (isSwap) {
878
+ if (market['inverse']) {
879
+ candles = [this.safeDict(message, 'data', {})];
880
+ }
881
+ else {
882
+ candles = this.safeList(message, 'data', []);
883
+ }
884
+ }
885
+ else {
886
+ const data = this.safeDict(message, 'data', {});
887
+ candles = [this.safeDict(data, 'K', {})];
888
+ }
762
889
  const symbol = market['symbol'];
763
890
  this.ohlcvs[symbol] = this.safeValue(this.ohlcvs, symbol, {});
764
891
  const rawTimeframe = dataType.split('_')[1];
@@ -793,6 +920,7 @@ class bingx extends bingx$1 {
793
920
  * @description watches historical candlestick data containing the open, high, low, and close price, and the volume of a market
794
921
  * @see https://bingx-api.github.io/docs/#/en-us/spot/socket/market.html#K-line%20Streams
795
922
  * @see https://bingx-api.github.io/docs/#/en-us/swapV2/socket/market.html#Subscribe%20K-Line%20Data
923
+ * @see https://bingx-api.github.io/docs/#/en-us/cswap/socket/market.html#Subscribe%20to%20Latest%20Trading%20Pair%20K-Line
796
924
  * @param {string} symbol unified symbol of the market to fetch OHLCV data for
797
925
  * @param {string} timeframe the length of time each candle represents
798
926
  * @param {int} [since] timestamp in ms of the earliest candle to fetch
@@ -802,8 +930,17 @@ class bingx extends bingx$1 {
802
930
  */
803
931
  await this.loadMarkets();
804
932
  const market = this.market(symbol);
805
- const [marketType, query] = this.handleMarketTypeAndParams('watchOHLCV', market, params);
806
- const url = this.safeValue(this.urls['api']['ws'], marketType);
933
+ let marketType = undefined;
934
+ let subType = undefined;
935
+ let url = undefined;
936
+ [marketType, params] = this.handleMarketTypeAndParams('watchOHLCV', market, params);
937
+ [subType, params] = this.handleSubTypeAndParams('watchOHLCV', market, params, 'linear');
938
+ if (marketType === 'swap') {
939
+ url = this.safeString(this.urls['api']['ws'], subType);
940
+ }
941
+ else {
942
+ url = this.safeString(this.urls['api']['ws'], marketType);
943
+ }
807
944
  if (url === undefined) {
808
945
  throw new errors.BadRequest(this.id + ' watchOHLCV is not supported for ' + marketType + ' markets.');
809
946
  }
@@ -821,10 +958,10 @@ class bingx extends bingx$1 {
821
958
  request['reqType'] = 'sub';
822
959
  }
823
960
  const subscriptionArgs = {
824
- 'limit': limit,
961
+ 'interval': rawTimeframe,
825
962
  'params': params,
826
963
  };
827
- const result = await this.watch(url, messageHash, this.extend(request, query), subscriptionHash, subscriptionArgs);
964
+ const result = await this.watch(url, messageHash, this.extend(request, params), subscriptionHash, subscriptionArgs);
828
965
  const ohlcv = result[2];
829
966
  if (this.newUpdates) {
830
967
  limit = ohlcv.getLimit(symbol, limit);
@@ -835,11 +972,12 @@ class bingx extends bingx$1 {
835
972
  /**
836
973
  * @method
837
974
  * @name bingx#watchOrders
838
- * @see https://bingx-api.github.io/docs/#/en-us/spot/socket/account.html#Subscription%20order%20update%20data
839
- * @see https://bingx-api.github.io/docs/#/en-us/swapV2/socket/account.html#Account%20balance%20and%20position%20update%20push
840
975
  * @description watches information on multiple orders made by the user
841
- * @param {string} symbol unified market symbol of the market orders were made in
842
- * @param {int} [since] the earliest time in ms to fetch orders for
976
+ * @see https://bingx-api.github.io/docs/#/en-us/spot/socket/account.html#Subscription%20order%20update%20data
977
+ * @see https://bingx-api.github.io/docs/#/en-us/swapV2/socket/account.html#Order%20update%20push
978
+ * @see https://bingx-api.github.io/docs/#/en-us/cswap/socket/account.html#Order%20update%20push
979
+ * @param {string} [symbol] unified market symbol of the market orders are made in
980
+ * @param {int} [since] the earliest time in ms to watch orders for
843
981
  * @param {int} [limit] the maximum number of order structures to retrieve
844
982
  * @param {object} [params] extra parameters specific to the exchange API endpoint
845
983
  * @returns {object[]} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
@@ -847,12 +985,14 @@ class bingx extends bingx$1 {
847
985
  await this.loadMarkets();
848
986
  await this.authenticate();
849
987
  let type = undefined;
988
+ let subType = undefined;
850
989
  let market = undefined;
851
990
  if (symbol !== undefined) {
852
991
  market = this.market(symbol);
853
992
  symbol = market['symbol'];
854
993
  }
855
994
  [type, params] = this.handleMarketTypeAndParams('watchOrders', market, params);
995
+ [subType, params] = this.handleSubTypeAndParams('watchOrders', market, params, 'linear');
856
996
  const isSpot = (type === 'spot');
857
997
  const spotHash = 'spot:private';
858
998
  const swapHash = 'swap:private';
@@ -863,15 +1003,24 @@ class bingx extends bingx$1 {
863
1003
  if (market !== undefined) {
864
1004
  messageHash += ':' + symbol;
865
1005
  }
866
- const url = this.urls['api']['ws'][type] + '?listenKey=' + this.options['listenKey'];
867
- let request = undefined;
868
1006
  const uuid = this.uuid();
869
- if (isSpot) {
1007
+ let baseUrl = undefined;
1008
+ let request = undefined;
1009
+ if (type === 'swap') {
1010
+ if (subType === 'inverse') {
1011
+ throw new errors.NotSupported(this.id + ' watchOrders is not supported for inverse swap markets yet');
1012
+ }
1013
+ baseUrl = this.safeString(this.urls['api']['ws'], subType);
1014
+ }
1015
+ else {
1016
+ baseUrl = this.safeString(this.urls['api']['ws'], type);
870
1017
  request = {
871
1018
  'id': uuid,
1019
+ 'reqType': 'sub',
872
1020
  'dataType': 'spot.executionReport',
873
1021
  };
874
1022
  }
1023
+ const url = baseUrl + '?listenKey=' + this.options['listenKey'];
875
1024
  const orders = await this.watch(url, messageHash, request, subscriptionHash);
876
1025
  if (this.newUpdates) {
877
1026
  limit = orders.getLimit(symbol, limit);
@@ -882,43 +1031,55 @@ class bingx extends bingx$1 {
882
1031
  /**
883
1032
  * @method
884
1033
  * @name bingx#watchMyTrades
885
- * @see https://bingx-api.github.io/docs/#/en-us/spot/socket/account.html#Subscription%20order%20update%20data
886
- * @see https://bingx-api.github.io/docs/#/en-us/swapV2/socket/account.html#Account%20balance%20and%20position%20update%20push
887
1034
  * @description watches information on multiple trades made by the user
888
- * @param {string} symbol unified market symbol of the market trades were made in
889
- * @param {int} [since] the earliest time in ms to trades orders for
890
- * @param {int} [limit] the maximum number of trades structures to retrieve
1035
+ * @see https://bingx-api.github.io/docs/#/en-us/spot/socket/account.html#Subscription%20order%20update%20data
1036
+ * @see https://bingx-api.github.io/docs/#/en-us/swapV2/socket/account.html#Order%20update%20push
1037
+ * @see https://bingx-api.github.io/docs/#/en-us/cswap/socket/account.html#Order%20update%20push
1038
+ * @param {string} [symbol] unified market symbol of the market the trades are made in
1039
+ * @param {int} [since] the earliest time in ms to watch trades for
1040
+ * @param {int} [limit] the maximum number of trade structures to retrieve
891
1041
  * @param {object} [params] extra parameters specific to the exchange API endpoint
892
1042
  * @returns {object[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=trade-structure}
893
1043
  */
894
1044
  await this.loadMarkets();
895
1045
  await this.authenticate();
896
1046
  let type = undefined;
1047
+ let subType = undefined;
897
1048
  let market = undefined;
898
1049
  if (symbol !== undefined) {
899
1050
  market = this.market(symbol);
900
1051
  symbol = market['symbol'];
901
1052
  }
902
- [type, params] = this.handleMarketTypeAndParams('watchOrders', market, params);
1053
+ [type, params] = this.handleMarketTypeAndParams('watchMyTrades', market, params);
1054
+ [subType, params] = this.handleSubTypeAndParams('watchMyTrades', market, params, 'linear');
903
1055
  const isSpot = (type === 'spot');
904
- const spotSubHash = 'spot:private';
905
- const swapSubHash = 'swap:private';
906
- const subscriptionHash = isSpot ? spotSubHash : swapSubHash;
1056
+ const spotHash = 'spot:private';
1057
+ const swapHash = 'swap:private';
1058
+ const subscriptionHash = isSpot ? spotHash : swapHash;
907
1059
  const spotMessageHash = 'spot:mytrades';
908
1060
  const swapMessageHash = 'swap:mytrades';
909
1061
  let messageHash = isSpot ? spotMessageHash : swapMessageHash;
910
1062
  if (market !== undefined) {
911
1063
  messageHash += ':' + symbol;
912
1064
  }
913
- const url = this.urls['api']['ws'][type] + '?listenKey=' + this.options['listenKey'];
914
- let request = undefined;
915
1065
  const uuid = this.uuid();
916
- if (isSpot) {
1066
+ let baseUrl = undefined;
1067
+ let request = undefined;
1068
+ if (type === 'swap') {
1069
+ if (subType === 'inverse') {
1070
+ throw new errors.NotSupported(this.id + ' watchMyTrades is not supported for inverse swap markets yet');
1071
+ }
1072
+ baseUrl = this.safeString(this.urls['api']['ws'], subType);
1073
+ }
1074
+ else {
1075
+ baseUrl = this.safeString(this.urls['api']['ws'], type);
917
1076
  request = {
918
1077
  'id': uuid,
1078
+ 'reqType': 'sub',
919
1079
  'dataType': 'spot.executionReport',
920
1080
  };
921
1081
  }
1082
+ const url = baseUrl + '?listenKey=' + this.options['listenKey'];
922
1083
  const trades = await this.watch(url, messageHash, request, subscriptionHash);
923
1084
  if (this.newUpdates) {
924
1085
  limit = trades.getLimit(symbol, limit);
@@ -929,16 +1090,19 @@ class bingx extends bingx$1 {
929
1090
  /**
930
1091
  * @method
931
1092
  * @name bingx#watchBalance
1093
+ * @description query for balance and get the amount of funds available for trading or funds locked in orders
932
1094
  * @see https://bingx-api.github.io/docs/#/en-us/spot/socket/account.html#Subscription%20account%20balance%20push
933
1095
  * @see https://bingx-api.github.io/docs/#/en-us/swapV2/socket/account.html#Account%20balance%20and%20position%20update%20push
934
- * @description query for balance and get the amount of funds available for trading or funds locked in orders
1096
+ * @see https://bingx-api.github.io/docs/#/en-us/cswap/socket/account.html#Account%20balance%20and%20position%20update%20push
935
1097
  * @param {object} [params] extra parameters specific to the exchange API endpoint
936
1098
  * @returns {object} a [balance structure]{@link https://docs.ccxt.com/#/?id=balance-structure}
937
1099
  */
938
1100
  await this.loadMarkets();
939
1101
  await this.authenticate();
940
1102
  let type = undefined;
1103
+ let subType = undefined;
941
1104
  [type, params] = this.handleMarketTypeAndParams('watchBalance', undefined, params);
1105
+ [subType, params] = this.handleSubTypeAndParams('watchBalance', undefined, params, 'linear');
942
1106
  const isSpot = (type === 'spot');
943
1107
  const spotSubHash = 'spot:balance';
944
1108
  const swapSubHash = 'swap:private';
@@ -946,17 +1110,25 @@ class bingx extends bingx$1 {
946
1110
  const swapMessageHash = 'swap:balance';
947
1111
  const messageHash = isSpot ? spotMessageHash : swapMessageHash;
948
1112
  const subscriptionHash = isSpot ? spotSubHash : swapSubHash;
949
- const url = this.urls['api']['ws'][type] + '?listenKey=' + this.options['listenKey'];
950
1113
  let request = undefined;
1114
+ let baseUrl = undefined;
951
1115
  const uuid = this.uuid();
952
- if (type === 'spot') {
1116
+ if (type === 'swap') {
1117
+ if (subType === 'inverse') {
1118
+ throw new errors.NotSupported(this.id + ' watchBalance is not supported for inverse swap markets yet');
1119
+ }
1120
+ baseUrl = this.safeString(this.urls['api']['ws'], subType);
1121
+ }
1122
+ else {
1123
+ baseUrl = this.safeString(this.urls['api']['ws'], type);
953
1124
  request = {
954
1125
  'id': uuid,
955
1126
  'dataType': 'ACCOUNT_UPDATE',
956
1127
  };
957
1128
  }
1129
+ const url = baseUrl + '?listenKey=' + this.options['listenKey'];
958
1130
  const client = this.client(url);
959
- this.setBalanceCache(client, type, subscriptionHash, params);
1131
+ this.setBalanceCache(client, type, subType, subscriptionHash, params);
960
1132
  let fetchBalanceSnapshot = undefined;
961
1133
  let awaitBalanceSnapshot = undefined;
962
1134
  [fetchBalanceSnapshot, params] = this.handleOptionAndParams(params, 'watchBalance', 'fetchBalanceSnapshot', true);
@@ -966,7 +1138,7 @@ class bingx extends bingx$1 {
966
1138
  }
967
1139
  return await this.watch(url, messageHash, request, subscriptionHash);
968
1140
  }
969
- setBalanceCache(client, type, subscriptionHash, params) {
1141
+ setBalanceCache(client, type, subType, subscriptionHash, params) {
970
1142
  if (subscriptionHash in client.subscriptions) {
971
1143
  return;
972
1144
  }
@@ -975,15 +1147,15 @@ class bingx extends bingx$1 {
975
1147
  const messageHash = type + ':fetchBalanceSnapshot';
976
1148
  if (!(messageHash in client.futures)) {
977
1149
  client.future(messageHash);
978
- this.spawn(this.loadBalanceSnapshot, client, messageHash, type);
1150
+ this.spawn(this.loadBalanceSnapshot, client, messageHash, type, subType);
979
1151
  }
980
1152
  }
981
1153
  else {
982
1154
  this.balance[type] = {};
983
1155
  }
984
1156
  }
985
- async loadBalanceSnapshot(client, messageHash, type) {
986
- const response = await this.fetchBalance({ 'type': type });
1157
+ async loadBalanceSnapshot(client, messageHash, type, subType) {
1158
+ const response = await this.fetchBalance({ 'type': type, 'subType': subType });
987
1159
  this.balance[type] = this.extend(response, this.safeValue(this.balance, type, {}));
988
1160
  // don't remove the future from the .futures cache
989
1161
  const future = client.futures[messageHash];
@@ -1022,7 +1194,7 @@ class bingx extends bingx$1 {
1022
1194
  await this.userAuthPrivatePutUserDataStream({ 'listenKey': listenKey }); // extend the expiry
1023
1195
  }
1024
1196
  catch (error) {
1025
- const types = ['spot', 'swap'];
1197
+ const types = ['spot', 'linear', 'inverse'];
1026
1198
  for (let i = 0; i < types.length; i++) {
1027
1199
  const type = types[i];
1028
1200
  const url = this.urls['api']['ws'][type] + '?listenKey=' + listenKey;