ccxt 4.5.39 → 4.5.41

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 (138) hide show
  1. package/README.md +6 -5
  2. package/dist/ccxt.browser.min.js +18 -18
  3. package/dist/cjs/ccxt.js +6 -1
  4. package/dist/cjs/src/abstract/lighter.js +11 -0
  5. package/dist/cjs/src/ascendex.js +73 -1
  6. package/dist/cjs/src/base/Exchange.js +211 -22
  7. package/dist/cjs/src/base/functions/generic.js +1 -0
  8. package/dist/cjs/src/base/functions/io.js +160 -0
  9. package/dist/cjs/src/base/functions.js +6 -0
  10. package/dist/cjs/src/base/ws/Client.js +1 -0
  11. package/dist/cjs/src/base/ws/WsClient.js +1 -0
  12. package/dist/cjs/src/binance.js +143 -0
  13. package/dist/cjs/src/bingx.js +150 -123
  14. package/dist/cjs/src/bitmart.js +20 -6
  15. package/dist/cjs/src/bitmex.js +436 -0
  16. package/dist/cjs/src/blofin.js +86 -1
  17. package/dist/cjs/src/bybit.js +135 -0
  18. package/dist/cjs/src/coinspot.js +7 -2
  19. package/dist/cjs/src/delta.js +367 -0
  20. package/dist/cjs/src/gate.js +11 -4
  21. package/dist/cjs/src/gemini.js +76 -1
  22. package/dist/cjs/src/htx.js +266 -3
  23. package/dist/cjs/src/hyperliquid.js +20 -7
  24. package/dist/cjs/src/independentreserve.js +7 -7
  25. package/dist/cjs/src/kraken.js +1 -1
  26. package/dist/cjs/src/krakenfutures.js +96 -5
  27. package/dist/cjs/src/kucoin.js +3 -3
  28. package/dist/cjs/src/kucoinfutures.js +121 -0
  29. package/dist/cjs/src/lighter.js +2931 -0
  30. package/dist/cjs/src/mexc.js +9 -2
  31. package/dist/cjs/src/phemex.js +359 -0
  32. package/dist/cjs/src/poloniex.js +5 -0
  33. package/dist/cjs/src/pro/binance.js +2 -2
  34. package/dist/cjs/src/pro/bingx.js +248 -35
  35. package/dist/cjs/src/pro/bitget.js +49 -90
  36. package/dist/cjs/src/pro/bitmart.js +68 -0
  37. package/dist/cjs/src/pro/blofin.js +52 -1
  38. package/dist/cjs/src/pro/coinbaseinternational.js +5 -2
  39. package/dist/cjs/src/pro/defx.js +1 -1
  40. package/dist/cjs/src/pro/kucoinfutures.js +1 -1
  41. package/dist/cjs/src/pro/lighter.js +787 -0
  42. package/dist/cjs/src/pro/mexc.js +73 -1
  43. package/dist/cjs/src/pro/okx.js +7 -4
  44. package/dist/cjs/src/pro/paradex.js +138 -1
  45. package/dist/cjs/src/pro/woo.js +43 -0
  46. package/dist/cjs/src/static_dependencies/ethers/abi-coder.js +1 -0
  47. package/dist/cjs/src/static_dependencies/ethers/address/address.js +1 -0
  48. package/dist/cjs/src/static_dependencies/ethers/coders/abstract-coder.js +1 -0
  49. package/dist/cjs/src/static_dependencies/ethers/coders/address.js +1 -0
  50. package/dist/cjs/src/static_dependencies/ethers/coders/array.js +1 -0
  51. package/dist/cjs/src/static_dependencies/ethers/coders/bytes.js +1 -0
  52. package/dist/cjs/src/static_dependencies/ethers/coders/fixed-bytes.js +1 -0
  53. package/dist/cjs/src/static_dependencies/ethers/coders/number.js +1 -0
  54. package/dist/cjs/src/static_dependencies/ethers/fragments.js +1 -0
  55. package/dist/cjs/src/static_dependencies/ethers/index.js +1 -0
  56. package/dist/cjs/src/static_dependencies/ethers/interface.js +1 -0
  57. package/dist/cjs/src/static_dependencies/ethers/typed.js +1 -0
  58. package/dist/cjs/src/static_dependencies/ethers/utils/index.js +1 -0
  59. package/dist/cjs/src/whitebit.js +118 -16
  60. package/dist/cjs/src/woo.js +103 -3
  61. package/js/ccxt.d.ts +9 -3
  62. package/js/ccxt.js +6 -2
  63. package/js/src/abstract/gemini.d.ts +27 -0
  64. package/js/src/abstract/lighter.d.ts +53 -0
  65. package/js/src/abstract/lighter.js +5 -0
  66. package/js/src/ascendex.d.ts +12 -1
  67. package/js/src/ascendex.js +73 -1
  68. package/js/src/base/Exchange.d.ts +29 -14
  69. package/js/src/base/Exchange.js +216 -23
  70. package/js/src/base/functions/generic.js +1 -0
  71. package/js/src/base/functions/io.d.ts +32 -0
  72. package/js/src/base/functions/io.js +131 -0
  73. package/js/src/base/functions.d.ts +1 -0
  74. package/js/src/base/functions.js +1 -0
  75. package/js/src/base/types.d.ts +9 -0
  76. package/js/src/binance.d.ts +27 -1
  77. package/js/src/binance.js +143 -0
  78. package/js/src/bingx.d.ts +113 -108
  79. package/js/src/bingx.js +150 -123
  80. package/js/src/bitmart.js +20 -6
  81. package/js/src/bitmex.d.ts +50 -1
  82. package/js/src/bitmex.js +436 -0
  83. package/js/src/blofin.d.ts +12 -1
  84. package/js/src/blofin.js +86 -1
  85. package/js/src/bybit.d.ts +12 -1
  86. package/js/src/bybit.js +135 -0
  87. package/js/src/coinspot.js +7 -2
  88. package/js/src/delta.d.ts +12 -1
  89. package/js/src/delta.js +367 -0
  90. package/js/src/gate.d.ts +1 -0
  91. package/js/src/gate.js +11 -4
  92. package/js/src/gemini.d.ts +11 -0
  93. package/js/src/gemini.js +76 -1
  94. package/js/src/htx.d.ts +15 -1
  95. package/js/src/htx.js +266 -3
  96. package/js/src/hyperliquid.js +20 -7
  97. package/js/src/independentreserve.js +7 -7
  98. package/js/src/kraken.js +1 -1
  99. package/js/src/krakenfutures.d.ts +1 -1
  100. package/js/src/krakenfutures.js +96 -5
  101. package/js/src/kucoin.d.ts +3 -3
  102. package/js/src/kucoin.js +3 -3
  103. package/js/src/kucoinfutures.d.ts +12 -1
  104. package/js/src/kucoinfutures.js +121 -0
  105. package/js/src/lighter.d.ts +424 -0
  106. package/js/src/lighter.js +2924 -0
  107. package/js/src/mexc.js +9 -2
  108. package/js/src/phemex.d.ts +16 -1
  109. package/js/src/phemex.js +359 -0
  110. package/js/src/poloniex.js +5 -0
  111. package/js/src/pro/binance.js +2 -2
  112. package/js/src/pro/bingx.d.ts +50 -34
  113. package/js/src/pro/bingx.js +249 -36
  114. package/js/src/pro/bitget.d.ts +6 -6
  115. package/js/src/pro/bitget.js +49 -90
  116. package/js/src/pro/bitmart.d.ts +22 -1
  117. package/js/src/pro/bitmart.js +69 -1
  118. package/js/src/pro/blofin.d.ts +12 -1
  119. package/js/src/pro/blofin.js +52 -1
  120. package/js/src/pro/coinbaseinternational.d.ts +2 -2
  121. package/js/src/pro/coinbaseinternational.js +6 -3
  122. package/js/src/pro/defx.js +1 -1
  123. package/js/src/pro/kucoinfutures.js +1 -1
  124. package/js/src/pro/lighter.d.ts +161 -0
  125. package/js/src/pro/lighter.js +780 -0
  126. package/js/src/pro/mexc.d.ts +22 -1
  127. package/js/src/pro/mexc.js +73 -1
  128. package/js/src/pro/okx.d.ts +4 -4
  129. package/js/src/pro/okx.js +7 -4
  130. package/js/src/pro/paradex.d.ts +23 -1
  131. package/js/src/pro/paradex.js +138 -1
  132. package/js/src/pro/woo.d.ts +12 -1
  133. package/js/src/pro/woo.js +43 -0
  134. package/js/src/whitebit.d.ts +2 -1
  135. package/js/src/whitebit.js +118 -16
  136. package/js/src/woo.d.ts +12 -1
  137. package/js/src/woo.js +103 -3
  138. package/package.json +1 -1
@@ -1,5 +1,5 @@
1
1
  import mexcRest from '../mexc.js';
2
- import type { Int, OHLCV, Str, OrderBook, Order, Trade, Ticker, Balances, Tickers, Strings } from '../base/types.js';
2
+ import type { Int, OHLCV, Str, OrderBook, Order, Trade, Ticker, Balances, Tickers, Strings, FundingRate } from '../base/types.js';
3
3
  import Client from '../base/ws/Client.js';
4
4
  export default class mexc extends mexcRest {
5
5
  describe(): any;
@@ -139,6 +139,27 @@ export default class mexc extends mexcRest {
139
139
  */
140
140
  watchBalance(params?: {}): Promise<Balances>;
141
141
  handleBalance(client: Client, message: any): void;
142
+ /**
143
+ * @method
144
+ * @name mexc#watchFundingRate
145
+ * @description watch the current funding rate
146
+ * @see https://www.mexc.com/api-docs/futures/websocket-api#funding-rate
147
+ * @param {string} symbol unified market symbol
148
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
149
+ * @returns {object} a [funding rate structure]{@link https://docs.ccxt.com/?id=funding-rate-structure}
150
+ */
151
+ watchFundingRate(symbol: string, params?: {}): Promise<FundingRate>;
152
+ /**
153
+ * @method
154
+ * @name mexc#unWatchFundingRate
155
+ * @description unWatches the current funding rate for a symbol
156
+ * @see https://www.mexc.com/api-docs/futures/websocket-api#funding-rate
157
+ * @param {string} symbol unified symbol of the market
158
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
159
+ * @returns {object} a [funding rate structure]{@link https://docs.ccxt.com/?id=funding-rate-structure}
160
+ */
161
+ unWatchFundingRate(symbol: string, params?: {}): Promise<any>;
162
+ handleFundingRate(client: Client, message: any): void;
142
163
  /**
143
164
  * @method
144
165
  * @name mexc#unWatchTicker
@@ -19,6 +19,8 @@ export default class mexc extends mexcRest {
19
19
  'fetchOrderWs': false,
20
20
  'fetchTradesWs': false,
21
21
  'watchBalance': true,
22
+ 'watchFundingRate': true,
23
+ 'watchFundingRates': false,
22
24
  'watchMyTrades': true,
23
25
  'watchOHLCV': true,
24
26
  'watchOrderBook': true,
@@ -1538,7 +1540,7 @@ export default class mexc extends mexcRest {
1538
1540
  // "frozenBalance": 0,
1539
1541
  // "positionMargin": 1.36945756
1540
1542
  // },
1541
- // "ts": 1680059188190
1543
+ // "ts": 1680059188191
1542
1544
  // }
1543
1545
  //
1544
1546
  const channel = this.safeString(message, 'channel');
@@ -1562,6 +1564,69 @@ export default class mexc extends mexcRest {
1562
1564
  this.balance[type] = this.safeBalance(this.balance[type]);
1563
1565
  client.resolve(this.balance[type], messageHash);
1564
1566
  }
1567
+ /**
1568
+ * @method
1569
+ * @name mexc#watchFundingRate
1570
+ * @description watch the current funding rate
1571
+ * @see https://www.mexc.com/api-docs/futures/websocket-api#funding-rate
1572
+ * @param {string} symbol unified market symbol
1573
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
1574
+ * @returns {object} a [funding rate structure]{@link https://docs.ccxt.com/?id=funding-rate-structure}
1575
+ */
1576
+ async watchFundingRate(symbol, params = {}) {
1577
+ await this.loadMarkets();
1578
+ const market = this.market(symbol);
1579
+ const messageHash = 'fundingRate:' + market['symbol'];
1580
+ const channel = 'sub.funding.rate';
1581
+ const requestParams = {
1582
+ 'symbol': market['id'],
1583
+ };
1584
+ return await this.watchSwapPublic(channel, messageHash, requestParams, params);
1585
+ }
1586
+ /**
1587
+ * @method
1588
+ * @name mexc#unWatchFundingRate
1589
+ * @description unWatches the current funding rate for a symbol
1590
+ * @see https://www.mexc.com/api-docs/futures/websocket-api#funding-rate
1591
+ * @param {string} symbol unified symbol of the market
1592
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
1593
+ * @returns {object} a [funding rate structure]{@link https://docs.ccxt.com/?id=funding-rate-structure}
1594
+ */
1595
+ async unWatchFundingRate(symbol, params = {}) {
1596
+ await this.loadMarkets();
1597
+ const market = this.market(symbol);
1598
+ const messageHash = 'unsubscribe:fundingRate:' + market['symbol'];
1599
+ let url = undefined;
1600
+ const channel = 'unsub.funding.rate';
1601
+ const requestParams = {
1602
+ 'symbol': market['id'],
1603
+ };
1604
+ url = this.urls['api']['ws']['swap'];
1605
+ this.watchSwapPublic(channel, messageHash, requestParams, params);
1606
+ const client = this.client(url);
1607
+ this.handleUnsubscriptions(client, [messageHash]);
1608
+ return undefined;
1609
+ }
1610
+ handleFundingRate(client, message) {
1611
+ //
1612
+ // {
1613
+ // "symbol": "BTC_USDT",
1614
+ // "data": {
1615
+ // "symbol": "BTC_USDT",
1616
+ // "rate": -0.000021,
1617
+ // "nextSettleTime": 1771084800000
1618
+ // },
1619
+ // "channel": "push.funding.rate",
1620
+ // "ts": 1771069020506
1621
+ // }
1622
+ //
1623
+ const data = this.safeDict(message, 'data', {});
1624
+ const fundingRate = this.parseFundingRate(data);
1625
+ const symbol = fundingRate['symbol'];
1626
+ this.fundingRates[symbol] = fundingRate;
1627
+ const messageHash = 'fundingRate:' + symbol;
1628
+ client.resolve(fundingRate, messageHash);
1629
+ }
1565
1630
  /**
1566
1631
  * @method
1567
1632
  * @name mexc#unWatchTicker
@@ -1846,6 +1911,12 @@ export default class mexc extends mexcRest {
1846
1911
  delete this.trades[symbol];
1847
1912
  }
1848
1913
  }
1914
+ else if (messageHash.indexOf('fundingRate') >= 0) {
1915
+ const symbol = messageHash.replace('unsubscribe:fundingRate:', '');
1916
+ if (symbol in this.fundingRates) {
1917
+ delete this.fundingRates[symbol];
1918
+ }
1919
+ }
1849
1920
  }
1850
1921
  }
1851
1922
  async authenticate(subscriptionHash, params = {}) {
@@ -2005,6 +2076,7 @@ export default class mexc extends mexcRest {
2005
2076
  'private.deals.v3.api': this.handleMyTrade,
2006
2077
  'push.personal.order.deal': this.handleMyTrade,
2007
2078
  'pong': this.handlePong,
2079
+ 'push.funding.rate': this.handleFundingRate,
2008
2080
  };
2009
2081
  if (channel in methods) {
2010
2082
  const method = methods[channel];
@@ -65,14 +65,14 @@ export default class okx extends okxRest {
65
65
  watchFundingRate(symbol: string, params?: {}): Promise<FundingRate>;
66
66
  /**
67
67
  * @method
68
- * @name coinbaseinternational#watchFundingRates
68
+ * @name okx#watchFundingRates
69
69
  * @description watch the funding rate for multiple markets
70
70
  * @see https://www.okx.com/docs-v5/en/#public-data-websocket-funding-rate-channel
71
- * @param {string[]} symbols list of unified market symbols
71
+ * @param {string[]} symbols a list of unified market symbols
72
72
  * @param {object} [params] extra parameters specific to the exchange API endpoint
73
- * @returns {object} a dictionary of [funding rates structures]{@link https://docs.ccxt.com/?id=funding-rates-structure}, indexe by market symbols
73
+ * @returns {object} a dictionary of [funding rates structures]{@link https://docs.ccxt.com/?id=funding-rate-structure}, indexed by market symbols
74
74
  */
75
- watchFundingRates(symbols: string[], params?: {}): Promise<FundingRates>;
75
+ watchFundingRates(symbols?: Strings, params?: {}): Promise<FundingRates>;
76
76
  handleFundingRate(client: Client, message: any): void;
77
77
  /**
78
78
  * @method
package/js/src/pro/okx.js CHANGED
@@ -344,14 +344,17 @@ export default class okx extends okxRest {
344
344
  }
345
345
  /**
346
346
  * @method
347
- * @name coinbaseinternational#watchFundingRates
347
+ * @name okx#watchFundingRates
348
348
  * @description watch the funding rate for multiple markets
349
349
  * @see https://www.okx.com/docs-v5/en/#public-data-websocket-funding-rate-channel
350
- * @param {string[]} symbols list of unified market symbols
350
+ * @param {string[]} symbols a list of unified market symbols
351
351
  * @param {object} [params] extra parameters specific to the exchange API endpoint
352
- * @returns {object} a dictionary of [funding rates structures]{@link https://docs.ccxt.com/?id=funding-rates-structure}, indexe by market symbols
352
+ * @returns {object} a dictionary of [funding rates structures]{@link https://docs.ccxt.com/?id=funding-rate-structure}, indexed by market symbols
353
353
  */
354
- async watchFundingRates(symbols, params = {}) {
354
+ async watchFundingRates(symbols = undefined, params = {}) {
355
+ if (symbols === undefined) {
356
+ throw new ArgumentsRequired(this.id + ' watchFundingRates() requires an array of symbols');
357
+ }
355
358
  await this.loadMarkets();
356
359
  symbols = this.marketSymbols(symbols);
357
360
  const channel = 'funding-rate';
@@ -1,5 +1,5 @@
1
1
  import paradexRest from '../paradex.js';
2
- import type { Int, Str, Trade, Order, OrderBook, Ticker, Strings, Tickers, Bool } from '../base/types.js';
2
+ import type { Int, Str, Trade, Order, OrderBook, Ticker, Strings, Tickers, Bool, Market, FundingRate, FundingRates } from '../base/types.js';
3
3
  import Client from '../base/ws/Client.js';
4
4
  export default class paradex extends paradexRest {
5
5
  describe(): any;
@@ -65,6 +65,28 @@ export default class paradex extends paradexRest {
65
65
  watchOrders(symbol?: Str, since?: Int, limit?: Int, params?: {}): Promise<Order[]>;
66
66
  handleOrder(client: Client, message: any): void;
67
67
  handleTicker(client: Client, message: any): any;
68
+ /**
69
+ * @method
70
+ * @name paradex#watchFundingRate
71
+ * @description watch the current funding rate for a symbol
72
+ * @see https://docs.paradex.trade/ws/web-socket-channels/funding-data-market-symbol/funding-data-market-symbol
73
+ * @param {string} symbol unified market symbol
74
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
75
+ * @returns {object} a [funding rate structure]{@link https://docs.ccxt.com/?id=funding-rate-structure}
76
+ */
77
+ watchFundingRate(symbol: string, params?: {}): Promise<FundingRate>;
78
+ /**
79
+ * @method
80
+ * @name paradex#watchFundingRates
81
+ * @description watch the funding rate for multiple markets
82
+ * @see https://docs.paradex.trade/ws/web-socket-channels/markets-summary/markets-summary
83
+ * @param {string[]} [symbols] a list of unified market symbols
84
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
85
+ * @returns {object} a [funding rate structure]{@link https://docs.ccxt.com/?id=funding-rate-structure}
86
+ */
87
+ watchFundingRates(symbols?: Strings, params?: {}): Promise<FundingRates>;
88
+ handleFundingRate(client: Client, message: any): void;
89
+ parseFundingRateWs(contract: any, market?: Market): FundingRate;
68
90
  handleErrorMessage(client: Client, message: any): Bool;
69
91
  handleMessage(client: Client, message: any): void;
70
92
  }
@@ -7,6 +7,8 @@ export default class paradex extends paradexRest {
7
7
  return this.deepExtend(super.describe(), {
8
8
  'has': {
9
9
  'ws': true,
10
+ 'watchFundingRate': true,
11
+ 'watchFundingRates': true,
10
12
  'watchTicker': true,
11
13
  'watchTickers': true,
12
14
  'watchOrderBook': true,
@@ -226,7 +228,7 @@ export default class paradex extends paradexRest {
226
228
  }
227
229
  const orderbook = this.orderbooks[symbol];
228
230
  const snapshot = this.parseOrderBook(orderbookData, symbol, timestamp, 'bids', 'asks');
229
- snapshot['nonce'] = this.safeNumber(data, 'seq_no');
231
+ snapshot['nonce'] = this.safeInteger(data, 'seq_no');
230
232
  orderbook.reset(snapshot);
231
233
  const messageHash = this.safeString(params, 'channel');
232
234
  client.resolve(orderbook, messageHash);
@@ -415,6 +417,140 @@ export default class paradex extends paradexRest {
415
417
  client.resolve(ticker, messageHash);
416
418
  return message;
417
419
  }
420
+ /**
421
+ * @method
422
+ * @name paradex#watchFundingRate
423
+ * @description watch the current funding rate for a symbol
424
+ * @see https://docs.paradex.trade/ws/web-socket-channels/funding-data-market-symbol/funding-data-market-symbol
425
+ * @param {string} symbol unified market symbol
426
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
427
+ * @returns {object} a [funding rate structure]{@link https://docs.ccxt.com/?id=funding-rate-structure}
428
+ */
429
+ async watchFundingRate(symbol, params = {}) {
430
+ await this.loadMarkets();
431
+ symbol = this.symbol(symbol);
432
+ const channel = 'funding_data';
433
+ const url = this.urls['api']['ws'];
434
+ const request = {
435
+ 'jsonrpc': '2.0',
436
+ 'method': 'subscribe',
437
+ 'params': {
438
+ 'channel': channel,
439
+ },
440
+ };
441
+ const messageHash = channel + '.' + symbol;
442
+ return await this.watch(url, messageHash, this.deepExtend(request, params), messageHash);
443
+ }
444
+ /**
445
+ * @method
446
+ * @name paradex#watchFundingRates
447
+ * @description watch the funding rate for multiple markets
448
+ * @see https://docs.paradex.trade/ws/web-socket-channels/markets-summary/markets-summary
449
+ * @param {string[]} [symbols] a list of unified market symbols
450
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
451
+ * @returns {object} a [funding rate structure]{@link https://docs.ccxt.com/?id=funding-rate-structure}
452
+ */
453
+ async watchFundingRates(symbols = undefined, params = {}) {
454
+ await this.loadMarkets();
455
+ symbols = this.marketSymbols(symbols);
456
+ const channel = 'funding_data';
457
+ const url = this.urls['api']['ws'];
458
+ const request = {
459
+ 'jsonrpc': '2.0',
460
+ 'method': 'subscribe',
461
+ 'params': {
462
+ 'channel': channel,
463
+ },
464
+ };
465
+ const messageHashes = [];
466
+ if (symbols !== undefined) {
467
+ const symbolsLength = symbols.length;
468
+ if (symbolsLength > 0) {
469
+ for (let i = 0; i < symbols.length; i++) {
470
+ const messageHash = channel + '.' + symbols[i];
471
+ messageHashes.push(messageHash);
472
+ }
473
+ }
474
+ else {
475
+ messageHashes.push(channel); // if an empty array is passed, subscribe to all funding rates
476
+ }
477
+ }
478
+ else {
479
+ messageHashes.push(channel);
480
+ }
481
+ const newFundingRates = await this.watchMultiple(url, messageHashes, this.deepExtend(request, params), messageHashes);
482
+ if (this.newUpdates) {
483
+ const result = {};
484
+ result[newFundingRates['symbol']] = newFundingRates;
485
+ return result;
486
+ }
487
+ return this.filterByArray(this.fundingRates, 'symbol', symbols);
488
+ }
489
+ handleFundingRate(client, message) {
490
+ //
491
+ // {
492
+ // "jsonrpc": "2.0",
493
+ // "method": "subscription",
494
+ // "params": {
495
+ // "channel": "funding_data",
496
+ // "data": {
497
+ // "market": "TRUMP-USD-PERP",
498
+ // "funding_index": "-0.551694014226244835",
499
+ // "funding_premium": "-0.000509914923994872836",
500
+ // "funding_rate": "-0.00014969570582",
501
+ // "funding_rate_8h": "-0.00014969",
502
+ // "funding_period_hours": 8,
503
+ // "created_at": 1771506636154
504
+ // }
505
+ // }
506
+ // }
507
+ //
508
+ const params = this.safeDict(message, 'params', {});
509
+ const data = this.safeDict(params, 'data', {});
510
+ const fundingRate = this.parseFundingRateWs(data);
511
+ const symbol = fundingRate['symbol'];
512
+ this.fundingRates[symbol] = fundingRate;
513
+ const channel = this.safeString(params, 'channel');
514
+ const messageHash = channel + '.' + symbol;
515
+ client.resolve(fundingRate, messageHash);
516
+ }
517
+ parseFundingRateWs(contract, market = undefined) {
518
+ //
519
+ // {
520
+ // "market": "TRUMP-USD-PERP",
521
+ // "funding_index": "-0.551694014226244835",
522
+ // "funding_premium": "-0.000509914923994872836",
523
+ // "funding_rate": "-0.00014969570582",
524
+ // "funding_rate_8h": "-0.00014969",
525
+ // "funding_period_hours": 8,
526
+ // "created_at": 1771506636154
527
+ // }
528
+ //
529
+ const marketId = this.safeString(contract, 'market');
530
+ const symbol = this.safeSymbol(marketId, market);
531
+ const timestamp = this.safeInteger(contract, 'created_at');
532
+ const fundingPeriod = this.safeString(contract, 'funding_period_hours');
533
+ return {
534
+ 'info': contract,
535
+ 'symbol': symbol,
536
+ 'markPrice': undefined,
537
+ 'indexPrice': undefined,
538
+ 'interestRate': this.parseNumber('0'),
539
+ 'estimatedSettlePrice': undefined,
540
+ 'timestamp': timestamp,
541
+ 'datetime': this.iso8601(timestamp),
542
+ 'fundingRate': this.safeNumber(contract, 'funding_rate'),
543
+ 'fundingTimestamp': undefined,
544
+ 'fundingDatetime': undefined,
545
+ 'nextFundingRate': undefined,
546
+ 'nextFundingTimestamp': undefined,
547
+ 'nextFundingDatetime': undefined,
548
+ 'previousFundingRate': undefined,
549
+ 'previousFundingTimestamp': undefined,
550
+ 'previousFundingDatetime': undefined,
551
+ 'interval': fundingPeriod + 'h',
552
+ };
553
+ }
418
554
  handleErrorMessage(client, message) {
419
555
  //
420
556
  // {
@@ -494,6 +630,7 @@ export default class paradex extends paradexRest {
494
630
  'order_book': this.handleOrderBook,
495
631
  'markets_summary': this.handleTicker,
496
632
  'orders': this.handleOrder,
633
+ 'funding_data': this.handleFundingRate,
497
634
  };
498
635
  const method = this.safeValue(methods, name);
499
636
  if (method !== undefined) {
@@ -1,5 +1,5 @@
1
1
  import wooRest from '../woo.js';
2
- import type { Int, Str, Strings, OrderBook, Order, Trade, Ticker, Tickers, OHLCV, Balances, Position, Bool } from '../base/types.js';
2
+ import type { Int, Str, Strings, OrderBook, Order, Trade, Ticker, Tickers, OHLCV, Balances, Position, Bool, FundingRate } from '../base/types.js';
3
3
  import Client from '../base/ws/Client.js';
4
4
  export default class woo extends wooRest {
5
5
  describe(): any;
@@ -210,6 +210,17 @@ export default class woo extends wooRest {
210
210
  */
211
211
  watchBalance(params?: {}): Promise<Balances>;
212
212
  handleBalance(client: any, message: any): void;
213
+ /**
214
+ * @method
215
+ * @name woo#watchFundingRate
216
+ * @description watch the current funding rate
217
+ * @see https://docs.woox.io/#estfundingrate
218
+ * @param {string} symbol unified market symbol
219
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
220
+ * @returns {object} a [funding rate structure]{@link https://docs.ccxt.com/?id=funding-rate-structure}
221
+ */
222
+ watchFundingRate(symbol: string, params?: {}): Promise<FundingRate>;
223
+ handleFundingRate(client: Client, message: any): void;
213
224
  handleErrorMessage(client: Client, message: any): Bool;
214
225
  handleUnSubscription(client: Client, message: any): void;
215
226
  handleMessage(client: Client, message: any): void;
package/js/src/pro/woo.js CHANGED
@@ -11,6 +11,8 @@ export default class woo extends wooRest {
11
11
  'has': {
12
12
  'ws': true,
13
13
  'watchBalance': true,
14
+ 'watchFundingRate': true,
15
+ 'watchFundingRates': false,
14
16
  'watchMyTrades': true,
15
17
  'watchOHLCV': true,
16
18
  'watchOrderBook': true,
@@ -1385,6 +1387,46 @@ export default class woo extends wooRest {
1385
1387
  this.balance = this.safeBalance(this.balance);
1386
1388
  client.resolve(this.balance, 'balance');
1387
1389
  }
1390
+ /**
1391
+ * @method
1392
+ * @name woo#watchFundingRate
1393
+ * @description watch the current funding rate
1394
+ * @see https://docs.woox.io/#estfundingrate
1395
+ * @param {string} symbol unified market symbol
1396
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
1397
+ * @returns {object} a [funding rate structure]{@link https://docs.ccxt.com/?id=funding-rate-structure}
1398
+ */
1399
+ async watchFundingRate(symbol, params = {}) {
1400
+ await this.loadMarkets();
1401
+ const market = this.market(symbol);
1402
+ symbol = market['symbol'];
1403
+ const topic = market['id'] + '@estfundingrate';
1404
+ const request = {
1405
+ 'event': 'subscribe',
1406
+ 'topic': topic,
1407
+ };
1408
+ const message = this.extend(request, params);
1409
+ return await this.watchPublic(topic, message);
1410
+ }
1411
+ handleFundingRate(client, message) {
1412
+ //
1413
+ // {
1414
+ // "topic": "PERP_BTC_USDT@estfundingrate",
1415
+ // "ts": 1771484159016,
1416
+ // "data": {
1417
+ // "symbol": "PERP_BTC_USDT",
1418
+ // "fundingRate": 0.0001,
1419
+ // "fundingTs": 1771488000000
1420
+ // }
1421
+ // }
1422
+ //
1423
+ const data = this.safeDict(message, 'data', {});
1424
+ const fundingRate = this.parseFundingRate(data);
1425
+ const symbol = fundingRate['symbol'];
1426
+ this.fundingRates[symbol] = fundingRate;
1427
+ const messageHash = this.safeString(message, 'topic');
1428
+ client.resolve(fundingRate, messageHash);
1429
+ }
1388
1430
  handleErrorMessage(client, message) {
1389
1431
  //
1390
1432
  // {"id":"1","event":"subscribe","success":false,"ts":1710780997216,"errorMsg":"Auth is needed."}
@@ -1461,6 +1503,7 @@ export default class woo extends wooRest {
1461
1503
  'balance': this.handleBalance,
1462
1504
  'position': this.handlePositions,
1463
1505
  'bbos': this.handleBidAsk,
1506
+ 'estfundingrate': this.handleFundingRate,
1464
1507
  };
1465
1508
  const event = this.safeString(message, 'event');
1466
1509
  let method = this.safeValue(methods, event);
@@ -113,7 +113,8 @@ export default class whitebit extends Exchange {
113
113
  * @see https://docs.whitebit.com/public/http-v4/#market-activity
114
114
  * @param {string[]} [symbols] unified symbols of the markets to fetch the ticker for, all market tickers are returned if not assigned
115
115
  * @param {object} [params] extra parameters specific to the exchange API endpoint
116
- * @param {string} [params.method] either v2PublicGetTicker or v4PublicGetTicker default is v4PublicGetTicker
116
+ * @param {string} [params.type] 'spot' or 'swap' - default is 'spot'. If type is 'swap', it will call v4PublicGetFutures
117
+ * @param {string} [params.method] either v2PublicGetTicker or v4PublicGetTicker or v4PublicGetFutures - default is v4PublicGetTicker for spot and mixed markets, and v4PublicGetFutures for swap
117
118
  * @returns {object} a dictionary of [ticker structures]{@link https://docs.ccxt.com/?id=ticker-structure}
118
119
  */
119
120
  fetchTickers(symbols?: Strings, params?: {}): Promise<Tickers>;
@@ -1307,7 +1307,40 @@ export default class whitebit extends Exchange {
1307
1307
  // tradesEnabled: true
1308
1308
  // }
1309
1309
  //
1310
- const marketId = this.safeString(ticker, 'tradingPairs');
1310
+ // v4PublicGetFutures
1311
+ // {
1312
+ // "ticker_id": "0G_PERP",
1313
+ // "stock_currency": "0G",
1314
+ // "money_currency": "USDT",
1315
+ // "last_price": "0.6065",
1316
+ // "stock_volume": "2563218",
1317
+ // "money_volume": "1587952.6137",
1318
+ // "bid": "0.6065",
1319
+ // "ask": "0.6077",
1320
+ // "high": "0.6472",
1321
+ // "low": "0.6045",
1322
+ // "product_type": "Perpetual",
1323
+ // "open_interest": "3721488",
1324
+ // "index_price": "0.61",
1325
+ // "index_name": "0G future contract",
1326
+ // "index_currency": "0G",
1327
+ // "funding_rate": "-0.00000778",
1328
+ // "next_funding_rate_timestamp": "1772467200000",
1329
+ // "brackets": {
1330
+ // "1": 0,
1331
+ // "10": 0,
1332
+ // "100": 0,
1333
+ // "2": 0,
1334
+ // "20": 4000,
1335
+ // "3": 0,
1336
+ // "5": 0,
1337
+ // "50": 800
1338
+ // },
1339
+ // "max_leverage": 50,
1340
+ // "funding_interval_minutes": 240
1341
+ // }
1342
+ //
1343
+ const marketId = this.safeString2(ticker, 'tradingPairs', 'ticker_id');
1311
1344
  market = this.safeMarket(marketId, market);
1312
1345
  // last price is provided as "last" or "last_price"
1313
1346
  const last = this.safeStringN(ticker, ['last', 'last_price', 'lastPrice']);
@@ -1331,8 +1364,9 @@ export default class whitebit extends Exchange {
1331
1364
  'change': undefined,
1332
1365
  'percentage': this.safeString(ticker, 'change'),
1333
1366
  'average': undefined,
1334
- 'baseVolume': this.safeStringN(ticker, ['base_volume', 'volume', 'baseVolume24h']),
1335
- 'quoteVolume': this.safeStringN(ticker, ['quote_volume', 'deal', 'quoteVolume24h']),
1367
+ 'baseVolume': this.safeStringN(ticker, ['base_volume', 'volume', 'baseVolume24h', 'stock_volume']),
1368
+ 'quoteVolume': this.safeStringN(ticker, ['quote_volume', 'deal', 'quoteVolume24h', 'money_volume']),
1369
+ 'indexPrice': this.safeString(ticker, 'index_price'),
1336
1370
  'info': ticker,
1337
1371
  }, market);
1338
1372
  }
@@ -1418,32 +1452,100 @@ export default class whitebit extends Exchange {
1418
1452
  * @see https://docs.whitebit.com/public/http-v4/#market-activity
1419
1453
  * @param {string[]} [symbols] unified symbols of the markets to fetch the ticker for, all market tickers are returned if not assigned
1420
1454
  * @param {object} [params] extra parameters specific to the exchange API endpoint
1421
- * @param {string} [params.method] either v2PublicGetTicker or v4PublicGetTicker default is v4PublicGetTicker
1455
+ * @param {string} [params.type] 'spot' or 'swap' - default is 'spot'. If type is 'swap', it will call v4PublicGetFutures
1456
+ * @param {string} [params.method] either v2PublicGetTicker or v4PublicGetTicker or v4PublicGetFutures - default is v4PublicGetTicker for spot and mixed markets, and v4PublicGetFutures for swap
1422
1457
  * @returns {object} a dictionary of [ticker structures]{@link https://docs.ccxt.com/?id=ticker-structure}
1423
1458
  */
1424
1459
  async fetchTickers(symbols = undefined, params = {}) {
1425
1460
  await this.loadMarkets();
1426
1461
  symbols = this.marketSymbols(symbols);
1427
- let method = 'v4PublicGetTicker';
1462
+ let onlyContractSymbols = true;
1463
+ if (symbols !== undefined) {
1464
+ for (let i = 0; i < symbols.length; i++) {
1465
+ const symbol = symbols[i];
1466
+ const market = this.market(symbol);
1467
+ if (!(market['contract'])) {
1468
+ onlyContractSymbols = false;
1469
+ break;
1470
+ }
1471
+ }
1472
+ }
1473
+ else {
1474
+ onlyContractSymbols = false;
1475
+ }
1476
+ let marketType = undefined;
1477
+ [marketType, params] = this.handleMarketTypeAndParams('fetchTickers', undefined, params);
1478
+ let method = undefined;
1428
1479
  [method, params] = this.handleOptionAndParams(params, 'fetchTickers', 'method', method);
1480
+ if (method === undefined) {
1481
+ // if the user did not specify a method, choose it based on market type and symbols
1482
+ if (onlyContractSymbols || (marketType === 'swap')) {
1483
+ method = 'v4PublicGetFutures';
1484
+ }
1485
+ else {
1486
+ method = 'v4PublicGetTicker';
1487
+ }
1488
+ }
1429
1489
  let response = undefined;
1430
1490
  if (method === 'v4PublicGetTicker') {
1491
+ //
1492
+ // "BCH_RUB": {
1493
+ // "base_id":1831,
1494
+ // "quote_id":0,
1495
+ // "last_price":"32830.21",
1496
+ // "quote_volume":"1494659.8024096",
1497
+ // "base_volume":"46.1083",
1498
+ // "isFrozen":false,
1499
+ // "change":"2.12"
1500
+ // },
1501
+ //
1431
1502
  response = await this.v4PublicGetTicker(params);
1432
1503
  }
1504
+ else if (method === 'v4PublicGetFutures') {
1505
+ //
1506
+ // {
1507
+ // "success": true,
1508
+ // "message": null,
1509
+ // "result": [
1510
+ // {
1511
+ // "ticker_id": "0G_PERP",
1512
+ // "stock_currency": "0G",
1513
+ // "money_currency": "USDT",
1514
+ // "last_price": "0.6065",
1515
+ // "stock_volume": "2563218",
1516
+ // "money_volume": "1587952.6137",
1517
+ // "bid": "0.6065",
1518
+ // "ask": "0.6077",
1519
+ // "high": "0.6472",
1520
+ // "low": "0.6045",
1521
+ // "product_type": "Perpetual",
1522
+ // "open_interest": "3721488",
1523
+ // "index_price": "0.61",
1524
+ // "index_name": "0G future contract",
1525
+ // "index_currency": "0G",
1526
+ // "funding_rate": "-0.00000778",
1527
+ // "next_funding_rate_timestamp": "1772467200000",
1528
+ // "brackets": {
1529
+ // "1": 0,
1530
+ // "10": 0,
1531
+ // "100": 0,
1532
+ // "2": 0,
1533
+ // "20": 4000,
1534
+ // "3": 0,
1535
+ // "5": 0,
1536
+ // "50": 800
1537
+ // },
1538
+ // "max_leverage": 50,
1539
+ // "funding_interval_minutes": 240
1540
+ // }
1541
+ // ]
1542
+ // }
1543
+ //
1544
+ response = await this.v4PublicGetFutures(params);
1545
+ }
1433
1546
  else {
1434
1547
  response = await this.v2PublicGetTicker(params);
1435
1548
  }
1436
- //
1437
- // "BCH_RUB": {
1438
- // "base_id":1831,
1439
- // "quote_id":0,
1440
- // "last_price":"32830.21",
1441
- // "quote_volume":"1494659.8024096",
1442
- // "base_volume":"46.1083",
1443
- // "isFrozen":false,
1444
- // "change":"2.12"
1445
- // },
1446
- //
1447
1549
  const resultList = this.safeList(response, 'result');
1448
1550
  if (resultList !== undefined) {
1449
1551
  return this.parseTickers(resultList, symbols);