ccxt 4.5.55 → 4.5.56

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 (177) hide show
  1. package/README.md +209 -5
  2. package/dist/ccxt.browser.min.js +3 -3
  3. package/dist/cjs/ccxt.js +1 -1
  4. package/dist/cjs/src/aftermath.js +10 -5
  5. package/dist/cjs/src/alpaca.js +2 -2
  6. package/dist/cjs/src/apex.js +25 -16
  7. package/dist/cjs/src/arkham.js +7 -4
  8. package/dist/cjs/src/ascendex.js +6 -3
  9. package/dist/cjs/src/base/Exchange.js +3 -3
  10. package/dist/cjs/src/bigone.js +7 -4
  11. package/dist/cjs/src/binance.js +4 -4
  12. package/dist/cjs/src/bingx.js +4 -4
  13. package/dist/cjs/src/bitflyer.js +2 -1
  14. package/dist/cjs/src/bitget.js +14 -3
  15. package/dist/cjs/src/bitmart.js +5 -4
  16. package/dist/cjs/src/bitmex.js +7 -4
  17. package/dist/cjs/src/bitopro.js +1 -1
  18. package/dist/cjs/src/bitrue.js +2 -1
  19. package/dist/cjs/src/bitso.js +6 -3
  20. package/dist/cjs/src/bitstamp.js +5 -3
  21. package/dist/cjs/src/bittrade.js +2 -1
  22. package/dist/cjs/src/blofin.js +2 -1
  23. package/dist/cjs/src/bybit.js +19 -17
  24. package/dist/cjs/src/bybiteu.js +1 -0
  25. package/dist/cjs/src/coinbaseexchange.js +2 -1
  26. package/dist/cjs/src/coinbaseinternational.js +15 -9
  27. package/dist/cjs/src/coinex.js +5 -3
  28. package/dist/cjs/src/coinsph.js +4 -4
  29. package/dist/cjs/src/cryptocom.js +6 -6
  30. package/dist/cjs/src/deepcoin.js +6 -3
  31. package/dist/cjs/src/delta.js +2 -1
  32. package/dist/cjs/src/deribit.js +4 -2
  33. package/dist/cjs/src/derive.js +5 -3
  34. package/dist/cjs/src/digifinex.js +2 -1
  35. package/dist/cjs/src/exmo.js +12 -39
  36. package/dist/cjs/src/foxbit.js +1 -1
  37. package/dist/cjs/src/gemini.js +4 -2
  38. package/dist/cjs/src/grvt.js +13 -7
  39. package/dist/cjs/src/hashkey.js +4 -4
  40. package/dist/cjs/src/hibachi.js +1 -1
  41. package/dist/cjs/src/hitbtc.js +2 -1
  42. package/dist/cjs/src/htx.js +9 -5
  43. package/dist/cjs/src/hyperliquid.js +19 -13
  44. package/dist/cjs/src/indodax.js +2 -1
  45. package/dist/cjs/src/kraken.js +14 -13
  46. package/dist/cjs/src/krakenfutures.js +2 -1
  47. package/dist/cjs/src/lbank.js +8 -4
  48. package/dist/cjs/src/lighter.js +1 -1
  49. package/dist/cjs/src/luno.js +1 -1
  50. package/dist/cjs/src/mercado.js +2 -1
  51. package/dist/cjs/src/mexc.js +24 -14
  52. package/dist/cjs/src/modetrade.js +1 -1
  53. package/dist/cjs/src/okx.js +6 -3
  54. package/dist/cjs/src/oxfun.js +5 -3
  55. package/dist/cjs/src/p2b.js +8 -4
  56. package/dist/cjs/src/paradex.js +3 -2
  57. package/dist/cjs/src/phemex.js +4 -2
  58. package/dist/cjs/src/poloniex.js +2 -1
  59. package/dist/cjs/src/pro/apex.js +10 -1
  60. package/dist/cjs/src/pro/aster.js +10 -9
  61. package/dist/cjs/src/pro/binance.js +3 -3
  62. package/dist/cjs/src/pro/bingx.js +7 -2
  63. package/dist/cjs/src/pro/bitmart.js +10 -0
  64. package/dist/cjs/src/pro/bitmex.js +1 -1
  65. package/dist/cjs/src/pro/grvt.js +8 -0
  66. package/dist/cjs/src/pro/htx.js +4 -4
  67. package/dist/cjs/src/pro/krakenfutures.js +16 -4
  68. package/dist/cjs/src/pro/modetrade.js +3 -3
  69. package/dist/cjs/src/pro/okx.js +4 -4
  70. package/dist/cjs/src/pro/oxfun.js +4 -4
  71. package/dist/cjs/src/pro/woo.js +4 -4
  72. package/dist/cjs/src/pro/woofipro.js +3 -3
  73. package/dist/cjs/src/pro/xt.js +1 -1
  74. package/dist/cjs/src/toobit.js +1 -1
  75. package/dist/cjs/src/woo.js +1 -1
  76. package/dist/cjs/src/woofipro.js +1 -1
  77. package/dist/cjs/src/xt.js +2 -1
  78. package/dist/cjs/src/yobit.js +4 -2
  79. package/dist/cjs/src/zebpay.js +3 -3
  80. package/js/ccxt.d.ts +1 -1
  81. package/js/ccxt.js +1 -1
  82. package/js/src/abstract/mexc.d.ts +1 -0
  83. package/js/src/aftermath.js +10 -5
  84. package/js/src/alpaca.js +2 -2
  85. package/js/src/apex.d.ts +1 -1
  86. package/js/src/apex.js +25 -16
  87. package/js/src/arkham.js +7 -4
  88. package/js/src/ascendex.js +6 -3
  89. package/js/src/base/Exchange.js +3 -3
  90. package/js/src/bigone.js +7 -4
  91. package/js/src/binance.js +4 -4
  92. package/js/src/bingx.js +4 -4
  93. package/js/src/bitflyer.js +2 -1
  94. package/js/src/bitget.js +14 -3
  95. package/js/src/bitmart.js +5 -4
  96. package/js/src/bitmex.js +7 -4
  97. package/js/src/bitopro.js +1 -1
  98. package/js/src/bitrue.js +2 -1
  99. package/js/src/bitso.js +6 -3
  100. package/js/src/bitstamp.js +5 -3
  101. package/js/src/bittrade.js +2 -1
  102. package/js/src/blofin.js +2 -1
  103. package/js/src/bybit.d.ts +1 -1
  104. package/js/src/bybit.js +19 -17
  105. package/js/src/bybiteu.js +1 -0
  106. package/js/src/coinbaseexchange.js +2 -1
  107. package/js/src/coinbaseinternational.d.ts +1 -1
  108. package/js/src/coinbaseinternational.js +15 -9
  109. package/js/src/coinex.d.ts +1 -1
  110. package/js/src/coinex.js +5 -3
  111. package/js/src/coinsph.js +4 -4
  112. package/js/src/cryptocom.js +6 -6
  113. package/js/src/deepcoin.js +6 -3
  114. package/js/src/delta.js +2 -1
  115. package/js/src/deribit.js +4 -2
  116. package/js/src/derive.js +5 -3
  117. package/js/src/digifinex.js +2 -1
  118. package/js/src/exmo.js +12 -39
  119. package/js/src/foxbit.js +1 -1
  120. package/js/src/gemini.js +4 -2
  121. package/js/src/grvt.d.ts +1 -1
  122. package/js/src/grvt.js +13 -7
  123. package/js/src/hashkey.js +4 -4
  124. package/js/src/hibachi.d.ts +1 -1
  125. package/js/src/hibachi.js +1 -1
  126. package/js/src/hitbtc.js +2 -1
  127. package/js/src/htx.js +9 -5
  128. package/js/src/hyperliquid.d.ts +4 -4
  129. package/js/src/hyperliquid.js +19 -13
  130. package/js/src/indodax.js +2 -1
  131. package/js/src/kraken.js +14 -13
  132. package/js/src/krakenfutures.js +2 -1
  133. package/js/src/lbank.js +8 -4
  134. package/js/src/lighter.d.ts +1 -1
  135. package/js/src/lighter.js +1 -1
  136. package/js/src/luno.js +1 -1
  137. package/js/src/mercado.js +2 -1
  138. package/js/src/mexc.d.ts +2 -2
  139. package/js/src/mexc.js +24 -14
  140. package/js/src/modetrade.js +1 -1
  141. package/js/src/okx.js +6 -3
  142. package/js/src/oxfun.js +5 -3
  143. package/js/src/p2b.js +8 -4
  144. package/js/src/paradex.js +3 -2
  145. package/js/src/phemex.js +4 -2
  146. package/js/src/poloniex.js +2 -1
  147. package/js/src/pro/apex.js +10 -1
  148. package/js/src/pro/aster.js +10 -9
  149. package/js/src/pro/binance.d.ts +1 -1
  150. package/js/src/pro/binance.js +3 -3
  151. package/js/src/pro/bingx.js +7 -2
  152. package/js/src/pro/bitmart.js +10 -0
  153. package/js/src/pro/bitmex.js +1 -1
  154. package/js/src/pro/grvt.js +8 -0
  155. package/js/src/pro/htx.d.ts +4 -4
  156. package/js/src/pro/htx.js +4 -4
  157. package/js/src/pro/krakenfutures.d.ts +4 -4
  158. package/js/src/pro/krakenfutures.js +16 -4
  159. package/js/src/pro/modetrade.d.ts +3 -3
  160. package/js/src/pro/modetrade.js +3 -3
  161. package/js/src/pro/okx.d.ts +4 -4
  162. package/js/src/pro/okx.js +4 -4
  163. package/js/src/pro/oxfun.d.ts +4 -4
  164. package/js/src/pro/oxfun.js +4 -4
  165. package/js/src/pro/woo.d.ts +4 -4
  166. package/js/src/pro/woo.js +4 -4
  167. package/js/src/pro/woofipro.d.ts +3 -3
  168. package/js/src/pro/woofipro.js +3 -3
  169. package/js/src/pro/xt.js +1 -1
  170. package/js/src/toobit.d.ts +1 -1
  171. package/js/src/toobit.js +1 -1
  172. package/js/src/woo.js +1 -1
  173. package/js/src/woofipro.js +1 -1
  174. package/js/src/xt.js +2 -1
  175. package/js/src/yobit.js +4 -2
  176. package/js/src/zebpay.js +3 -3
  177. package/package.json +21 -7
package/js/src/mexc.js CHANGED
@@ -317,6 +317,7 @@ export default class mexc extends Exchange {
317
317
  'position/funding_records': 2,
318
318
  'position/position_mode': 2,
319
319
  'order/list/open_orders/{symbol}': 2,
320
+ 'order/list/open_orders': 2,
320
321
  'order/list/history_orders': 2,
321
322
  'order/list/order_deals/v3': 2,
322
323
  'order/external/{symbol}/{external_oid}': 2,
@@ -2591,8 +2592,10 @@ export default class mexc extends Exchange {
2591
2592
  // Trigger
2592
2593
  // {"success":true,"code":0,"data":259208506303929856}
2593
2594
  //
2594
- const data = this.safeString(response, 'data');
2595
- return this.safeOrder({ 'id': data }, market);
2595
+ // {"success":true,"code":0,"data":{"orderId":"814218083416790528","ts":1779795118533}}
2596
+ //
2597
+ const data = this.safeDict(response, 'data');
2598
+ return this.safeOrder({ 'id': this.safeString(data, 'orderId'), 'timestamp': this.safeInteger(data, 'ts') }, market);
2596
2599
  }
2597
2600
  /**
2598
2601
  * @method
@@ -3125,8 +3128,12 @@ export default class mexc extends Exchange {
3125
3128
  return this.parseOrders(response, market, since, limit);
3126
3129
  }
3127
3130
  else {
3128
- // TO_DO: another possible way is through: open_orders/{symbol}, but as they have same ratelimits, and less granularity, i think historical orders are more convenient, as it supports more params (however, theoretically, open-orders endpoint might be sligthly fast)
3129
- return await this.fetchOrdersByState(2, symbol, since, limit, params);
3131
+ if (limit === undefined) {
3132
+ request['page_size'] = 100; // max
3133
+ }
3134
+ const swapResponse = await this.contractPrivateGetOrderListOpenOrders(this.extend(request, params));
3135
+ const data = this.safeList(swapResponse, 'data', []);
3136
+ return this.parseOrders(data, market, since, limit, params);
3130
3137
  }
3131
3138
  }
3132
3139
  /**
@@ -3916,7 +3923,7 @@ export default class mexc extends Exchange {
3916
3923
  for (let i = 0; i < wallet.length; i++) {
3917
3924
  const entry = wallet[i];
3918
3925
  const marketId = this.safeString(entry, 'symbol');
3919
- const symbol = this.safeSymbol(marketId, undefined);
3926
+ const symbol = this.safeSymbol(marketId);
3920
3927
  const base = this.safeValue(entry, 'baseAsset', {});
3921
3928
  const quote = this.safeValue(entry, 'quoteAsset', {});
3922
3929
  const baseCode = this.safeCurrencyCode(this.safeString(base, 'asset'));
@@ -4726,14 +4733,17 @@ export default class mexc extends Exchange {
4726
4733
  }
4727
4734
  while (Precise.stringLt(floor, maxVol)) {
4728
4735
  const cap = Precise.stringAdd(floor, riskIncrVol);
4736
+ const minNotional = this.parseNumber(floor);
4737
+ const mainMarginRate = this.parseNumber(maintenanceMarginRate);
4738
+ const maxLev = this.parseNumber(Precise.stringDiv('1', initialMarginRate));
4729
4739
  tiers.push({
4730
4740
  'tier': this.parseNumber(Precise.stringDiv(cap, riskIncrVol)),
4731
4741
  'symbol': this.safeSymbol(marketId, market, undefined, 'contract'),
4732
4742
  'currency': this.safeCurrencyCode(quoteId),
4733
- 'minNotional': this.parseNumber(floor),
4743
+ 'minNotional': minNotional,
4734
4744
  'maxNotional': this.parseNumber(cap),
4735
- 'maintenanceMarginRate': this.parseNumber(maintenanceMarginRate),
4736
- 'maxLeverage': this.parseNumber(Precise.stringDiv('1', initialMarginRate)),
4745
+ 'maintenanceMarginRate': mainMarginRate,
4746
+ 'maxLeverage': maxLev,
4737
4747
  'info': info,
4738
4748
  });
4739
4749
  initialMarginRate = Precise.stringAdd(initialMarginRate, riskIncrImr);
@@ -5359,8 +5369,8 @@ export default class mexc extends Exchange {
5359
5369
  * @description fetch a history of internal transfers made on an account
5360
5370
  * @see https://mexcdevelop.github.io/apidocs/spot_v2_en/#get-internal-assets-transfer-records
5361
5371
  * @see https://mexcdevelop.github.io/apidocs/contract_v1_en/#get-the-user-39-s-asset-transfer-records
5362
- * @see https://www.mexc.com/api-docs/spot-v3/wallet-endpoints#query-user-universal-transfer-history * @param {string} code unified currency code of the currency transferred
5363
- * @param code
5372
+ * @see https://www.mexc.com/api-docs/spot-v3/wallet-endpoints#query-user-universal-transfer-history
5373
+ * @param {string} [code] unified currency code of the currency transferred
5364
5374
  * @param {int} [since] the earliest time in ms to fetch transfers for
5365
5375
  * @param {int} [limit] the maximum number of transfers structures to retrieve
5366
5376
  * @param {object} [params] extra parameters specific to the exchange API endpoint
@@ -6098,8 +6108,8 @@ export default class mexc extends Exchange {
6098
6108
  if (market['spot']) {
6099
6109
  throw new BadSymbol(this.id + ' setMarginMode() supports contract markets only');
6100
6110
  }
6101
- marginMode = marginMode.toLowerCase();
6102
- if (marginMode !== 'isolated' && marginMode !== 'cross') {
6111
+ const marginModeLower = marginMode.toLowerCase();
6112
+ if (marginModeLower !== 'isolated' && marginModeLower !== 'cross') {
6103
6113
  throw new BadRequest(this.id + ' setMarginMode() marginMode argument should be isolated or cross');
6104
6114
  }
6105
6115
  const leverage = this.safeInteger(params, 'leverage');
@@ -6109,7 +6119,7 @@ export default class mexc extends Exchange {
6109
6119
  const direction = this.safeStringLower2(params, 'direction', 'positionId');
6110
6120
  const request = {
6111
6121
  'leverage': leverage,
6112
- 'openType': (marginMode === 'isolated') ? 1 : 2,
6122
+ 'openType': (marginModeLower === 'isolated') ? 1 : 2,
6113
6123
  };
6114
6124
  if (symbol !== undefined) {
6115
6125
  request['symbol'] = market['id'];
@@ -6225,7 +6235,7 @@ export default class mexc extends Exchange {
6225
6235
  if (success === true) {
6226
6236
  return undefined;
6227
6237
  }
6228
- const responseCode = this.safeString(response, 'code', undefined);
6238
+ const responseCode = this.safeString(response, 'code');
6229
6239
  if ((responseCode !== undefined) && (responseCode !== '200') && (responseCode !== '0')) {
6230
6240
  const feedback = this.id + ' ' + body;
6231
6241
  this.throwBroadlyMatchedException(this.exceptions['broad'], body, feedback);
@@ -1400,7 +1400,7 @@ export default class modetrade extends Exchange {
1400
1400
  'fok': 'FOK',
1401
1401
  'post_only': 'PO',
1402
1402
  };
1403
- return this.safeString(timeInForces, timeInForce, undefined);
1403
+ return this.safeString(timeInForces, timeInForce);
1404
1404
  }
1405
1405
  parseOrderStatus(status) {
1406
1406
  if (status !== undefined) {
package/js/src/okx.js CHANGED
@@ -1818,6 +1818,9 @@ export default class okx extends Exchange {
1818
1818
  let maxLeverage = this.safeString(market, 'lever', '1');
1819
1819
  maxLeverage = Precise.stringMax(maxLeverage, '1');
1820
1820
  const maxSpotCost = this.safeNumber(market, 'maxMktSz');
1821
+ const leverageAboveOne = Precise.stringGt(maxLeverage, '1');
1822
+ const quoteEqualSettle = (quoteId === settleId);
1823
+ const baseEqualSettle = (baseId === settleId);
1821
1824
  const status = this.safeString(market, 'state');
1822
1825
  const instIdCode = this.safeInteger(market, 'instIdCode');
1823
1826
  return this.extend(fees, {
@@ -1832,14 +1835,14 @@ export default class okx extends Exchange {
1832
1835
  'settleId': settleId,
1833
1836
  'type': type,
1834
1837
  'spot': spot,
1835
- 'margin': spot && (Precise.stringGt(maxLeverage, '1')),
1838
+ 'margin': spot && leverageAboveOne,
1836
1839
  'swap': swap,
1837
1840
  'future': future,
1838
1841
  'option': option,
1839
1842
  'active': status === 'live',
1840
1843
  'contract': contract,
1841
- 'linear': contract ? (quoteId === settleId) : undefined,
1842
- 'inverse': contract ? (baseId === settleId) : undefined,
1844
+ 'linear': contract ? quoteEqualSettle : undefined,
1845
+ 'inverse': contract ? baseEqualSettle : undefined,
1843
1846
  'contractSize': contract ? this.safeNumber(market, 'ctVal') : undefined,
1844
1847
  'expiry': expiry,
1845
1848
  'expiryDatetime': this.iso8601(expiry),
package/js/src/oxfun.js CHANGED
@@ -2261,9 +2261,11 @@ export default class oxfun extends Exchange {
2261
2261
  */
2262
2262
  async createOrder(symbol, type, side, amount, price = undefined, params = {}) {
2263
2263
  await this.loadMarkets();
2264
+ const responseType = this.safeString(params, 'responseType', 'FULL');
2265
+ const timestamp = this.safeInteger(params, 'timestamp', this.milliseconds());
2264
2266
  const request = {
2265
- 'responseType': this.safeString(params, 'responseType', 'FULL'),
2266
- 'timestamp': this.safeInteger(params, 'timestamp', this.milliseconds()),
2267
+ 'responseType': responseType,
2268
+ 'timestamp': timestamp,
2267
2269
  };
2268
2270
  params = this.omit(params, ['responseType', 'timestamp']);
2269
2271
  const recvWindow = this.safeInteger(params, 'recvWindow');
@@ -2913,7 +2915,7 @@ export default class oxfun extends Exchange {
2913
2915
  return undefined;
2914
2916
  }
2915
2917
  if (code !== 200) {
2916
- const responseCode = this.safeString(response, 'code', undefined);
2918
+ const responseCode = this.safeString(response, 'code');
2917
2919
  const feedback = this.id + ' ' + body;
2918
2920
  this.throwBroadlyMatchedException(this.exceptions['broad'], body, feedback);
2919
2921
  this.throwExactlyMatchedException(this.exceptions['exact'], responseCode, feedback);
package/js/src/p2b.js CHANGED
@@ -1108,10 +1108,12 @@ export default class p2b extends Exchange {
1108
1108
  throw new BadRequest(this.id + ' fetchMyTrades () the time between since and params["until"] cannot be greater than 24 hours');
1109
1109
  }
1110
1110
  const market = this.market(symbol);
1111
+ const sinceSec = this.parseToInt(since / 1000);
1112
+ const untilSec = this.parseToInt(until / 1000);
1111
1113
  const request = {
1112
1114
  'market': market['id'],
1113
- 'startTime': this.parseToInt(since / 1000),
1114
- 'endTime': this.parseToInt(until / 1000),
1115
+ 'startTime': sinceSec,
1116
+ 'endTime': untilSec,
1115
1117
  };
1116
1118
  if (limit !== undefined) {
1117
1119
  request['limit'] = limit;
@@ -1184,9 +1186,11 @@ export default class p2b extends Exchange {
1184
1186
  if ((until - since) > 86400000) {
1185
1187
  throw new BadRequest(this.id + ' fetchClosedOrders () the time between since and params["until"] cannot be greater than 24 hours');
1186
1188
  }
1189
+ const sinceSec = this.parseToInt(since / 1000);
1190
+ const untilSec = this.parseToInt(until / 1000);
1187
1191
  const request = {
1188
- 'startTime': this.parseToInt(since / 1000),
1189
- 'endTime': this.parseToInt(until / 1000),
1192
+ 'startTime': sinceSec,
1193
+ 'endTime': untilSec,
1190
1194
  };
1191
1195
  if (market !== undefined) {
1192
1196
  request['market'] = market['id'];
package/js/src/paradex.js CHANGED
@@ -622,6 +622,7 @@ export default class paradex extends Exchange {
622
622
  else {
623
623
  expiry = undefined;
624
624
  }
625
+ const expireDatetime = (expiry === 0) ? undefined : this.iso8601(expiry);
625
626
  return this.safeMarketStructure({
626
627
  'id': marketId,
627
628
  'symbol': symbol,
@@ -645,7 +646,7 @@ export default class paradex extends Exchange {
645
646
  'maker': makerFee,
646
647
  'contractSize': this.parseNumber('1'),
647
648
  'expiry': expiry,
648
- 'expiryDatetime': (expiry === 0) ? undefined : this.iso8601(expiry),
649
+ 'expiryDatetime': expireDatetime,
649
650
  'strike': this.parseNumber(strikePrice),
650
651
  'optionType': this.safeStringLower(market, 'option_type'),
651
652
  'precision': {
@@ -1491,7 +1492,7 @@ export default class paradex extends Exchange {
1491
1492
  'GTC': 'GTC',
1492
1493
  'POST_ONLY': 'PO',
1493
1494
  };
1494
- return this.safeString(timeInForces, timeInForce, undefined);
1495
+ return this.safeString(timeInForces, timeInForce);
1495
1496
  }
1496
1497
  parseOrderStatus(status) {
1497
1498
  if (status !== undefined) {
package/js/src/phemex.js CHANGED
@@ -726,6 +726,7 @@ export default class phemex extends Exchange {
726
726
  // "1.0"
727
727
  contractSize = this.parseNumber(contractSizeString);
728
728
  }
729
+ const isLinear = !inverse;
729
730
  return this.safeMarketStructure({
730
731
  'id': id,
731
732
  'symbol': base + '/' + quote + ':' + settle,
@@ -743,7 +744,7 @@ export default class phemex extends Exchange {
743
744
  'option': false,
744
745
  'active': status === 'Listed',
745
746
  'contract': true,
746
- 'linear': !inverse,
747
+ 'linear': isLinear,
747
748
  'inverse': inverse,
748
749
  'taker': this.parseNumber(this.fromEn(takerFeeRateEr, ratioScale)),
749
750
  'maker': this.parseNumber(this.fromEn(makerFeeRateEr, ratioScale)),
@@ -4662,11 +4663,12 @@ export default class phemex extends Exchange {
4662
4663
  for (let i = 0; i < riskLimits.length; i++) {
4663
4664
  const tier = riskLimits[i];
4664
4665
  const maxNotional = this.safeInteger(tier, 'limit');
4666
+ const minNotionalResponse = minNotional; // java req
4665
4667
  tiers.push({
4666
4668
  'tier': this.sum(i, 1),
4667
4669
  'symbol': this.safeSymbol(marketId, market),
4668
4670
  'currency': market['settle'],
4669
- 'minNotional': minNotional,
4671
+ 'minNotional': minNotionalResponse,
4670
4672
  'maxNotional': maxNotional,
4671
4673
  'maintenanceMarginRate': this.safeString(tier, 'maintenanceMargin'),
4672
4674
  'maxLeverage': undefined,
@@ -917,6 +917,7 @@ export default class poloniex extends Exchange {
917
917
  if (alias !== undefined) {
918
918
  type = 'future';
919
919
  }
920
+ const marketType = (type === 'future') ? 'future' : 'swap';
920
921
  return {
921
922
  'id': id,
922
923
  'symbol': symbol,
@@ -926,7 +927,7 @@ export default class poloniex extends Exchange {
926
927
  'baseId': baseId,
927
928
  'quoteId': quoteId,
928
929
  'settleId': settleId,
929
- 'type': (type === 'future') ? 'future' : 'swap',
930
+ 'type': marketType,
930
931
  'spot': false,
931
932
  'margin': false,
932
933
  'swap': type === 'swap',
@@ -762,7 +762,7 @@ export default class apex extends apexRest {
762
762
  async loadPositionsSnapshot(client, messageHash) {
763
763
  // as only one ws channel gives positions for all types, for snapshot must load all positions
764
764
  const fetchFunctions = [
765
- this.fetchPositions(undefined),
765
+ this.fetchPositions(),
766
766
  ];
767
767
  const promises = await Promise.all(fetchFunctions);
768
768
  this.positions = new ArrayCacheBySymbolBySide();
@@ -932,6 +932,15 @@ export default class apex extends apexRest {
932
932
  const ret_msg = this.safeString(message, 'ret_msg');
933
933
  const request = this.safeValue(message, 'request', {});
934
934
  const op = this.safeString(request, 'op');
935
+ // Benign re-subscribe notice (same shape as bitmart 90008 /
936
+ // krakenfutures "Already subscribed"): the original subscription
937
+ // is still active and delivering data on this socket. Without
938
+ // this short-circuit the catch-clause's `client.reject(error,
939
+ // messageHash)` rejects every in-flight future on the connection
940
+ // because apex doesn't echo a `reqId` on these warnings.
941
+ if (ret_msg !== undefined && ret_msg.indexOf('already subscribed') >= 0) {
942
+ return false;
943
+ }
935
944
  if (op === 'auth') {
936
945
  throw new AuthenticationError('Authentication failed: ' + ret_msg);
937
946
  }
@@ -372,13 +372,11 @@ export default class aster extends asterRest {
372
372
  }
373
373
  parseWsTicker(message, marketType) {
374
374
  const event = this.safeString(message, 'e');
375
- const part = event.split('@');
376
- const channel = this.safeString(part, 1);
377
375
  const marketId = this.safeString(message, 's');
378
376
  const timestamp = this.safeInteger(message, 'E');
379
377
  const market = this.safeMarket(marketId, undefined, undefined, marketType);
380
378
  const last = this.safeString(message, 'c');
381
- if (channel === 'markPriceUpdate') {
379
+ if (event === 'markPriceUpdate') {
382
380
  return this.safeTicker({
383
381
  'symbol': market['symbol'],
384
382
  'timestamp': timestamp,
@@ -1198,7 +1196,12 @@ export default class aster extends asterRest {
1198
1196
  return;
1199
1197
  }
1200
1198
  try {
1201
- await this.sapiPrivatePutV3ListenKey(); // extend the expiry
1199
+ if (type === 'spot') {
1200
+ await this.sapiPrivatePutV3ListenKey(); // extend the expiry
1201
+ }
1202
+ else {
1203
+ await this.fapiPrivatePutV3ListenKey(); // extend the expiry
1204
+ }
1202
1205
  }
1203
1206
  catch (error) {
1204
1207
  const url = this.urls['api']['ws']['private'][type] + '/' + listenKey;
@@ -1875,13 +1878,11 @@ export default class aster extends asterRest {
1875
1878
  const messageInner = this.safeDict(message, 'data', message); // can be either wrapped in 'data' or full object itself
1876
1879
  const event = this.safeString(messageInner, 'e');
1877
1880
  const methods = {
1878
- 'ticker': this.handleTicker,
1881
+ '24hrTicker': this.handleTicker,
1879
1882
  'aggTrade': this.handleTrade,
1880
- 'depth5': this.handleOrderBook,
1881
- 'depth10': this.handleOrderBook,
1882
- 'depth20': this.handleOrderBook,
1883
+ 'depthUpdate': this.handleOrderBook,
1883
1884
  'kline': this.handleOHLCV,
1884
- 'markPrice': this.handleTicker,
1885
+ 'markPriceUpdate': this.handleTicker,
1885
1886
  'bookTicker': this.handleBidAsk,
1886
1887
  'outboundAccountPosition': this.handleBalance,
1887
1888
  'ACCOUNT_UPDATE': this.handleBalanceAndPosition,
@@ -597,7 +597,7 @@ export default class binance extends binanceRest {
597
597
  /**
598
598
  * @name binance#ensureUserDataStreamWsSubscribeSignature
599
599
  * @description watches best bid & ask for symbols
600
- * @param marketType {string} only support on 'spot'
600
+ * @param {string} [marketType] only supports 'spot'
601
601
  * @see {@link https://developers.binance.com/docs/binance-spot-api-docs/websocket-api/user-data-stream-requests#subscribe-to-user-data-stream-through-signature-subscription-user_data Binance User Data Stream Documentation}
602
602
  * @returns Promise<number> The subscription ID for the user data stream
603
603
  */
@@ -1499,7 +1499,7 @@ export default class binance extends binanceRest {
1499
1499
  }
1500
1500
  const isSpot = (type === 'spot');
1501
1501
  let timezone = undefined;
1502
- [timezone, params] = this.handleParamString(params, 'timezone', undefined);
1502
+ [timezone, params] = this.handleParamString(params, 'timezone');
1503
1503
  const isUtc8 = (timezone !== undefined) && ((timezone === '+08:00') || Precise.stringEq(timezone, '8'));
1504
1504
  const rawHashes = [];
1505
1505
  const messageHashes = [];
@@ -1564,7 +1564,7 @@ export default class binance extends binanceRest {
1564
1564
  }
1565
1565
  const isSpot = (type === 'spot');
1566
1566
  let timezone = undefined;
1567
- [timezone, params] = this.handleParamString(params, 'timezone', undefined);
1567
+ [timezone, params] = this.handleParamString(params, 'timezone');
1568
1568
  const isUtc8 = (timezone !== undefined) && ((timezone === '+08:00') || Precise.stringEq(timezone, '8'));
1569
1569
  const rawHashes = [];
1570
1570
  const subMessageHashes = [];
@@ -2402,7 +2402,7 @@ export default class binance extends binanceRest {
2402
2402
  /**
2403
2403
  * @name binance#ensureUserDataStreamWsSubscribeSignature
2404
2404
  * @description watches best bid & ask for symbols
2405
- * @param marketType {string} only support on 'spot'
2405
+ * @param {string} [marketType] only supports 'spot'
2406
2406
  * @see {@link https://developers.binance.com/docs/binance-spot-api-docs/websocket-api/user-data-stream-requests#subscribe-to-user-data-stream-through-signature-subscription-user_data Binance User Data Stream Documentation}
2407
2407
  * @returns Promise<number> The subscription ID for the user data stream
2408
2408
  */
@@ -691,7 +691,9 @@ export default class bingx extends bingxRest {
691
691
  // const limit = [ 5, 10, 20, 50, 100 ]
692
692
  const subscriptionHash = dataType;
693
693
  const subscription = client.subscriptions[subscriptionHash];
694
- const limit = this.safeInteger(subscription, 'limit');
694
+ // see handleOHLCV — subscription.limit may be missing for non-orderbook callers;
695
+ // default to a reasonable depth instead of throwing NPE in the Java port.
696
+ const limit = this.safeInteger(subscription, 'limit', 100);
695
697
  this.orderbooks[symbol] = this.orderBook({}, limit);
696
698
  }
697
699
  orderbook = this.orderbooks[symbol];
@@ -837,7 +839,10 @@ export default class bingx extends bingxRest {
837
839
  if (this.safeValue(this.ohlcvs[symbol], rawTimeframe) === undefined) {
838
840
  const subscriptionHash = dataType;
839
841
  const subscription = client.subscriptions[subscriptionHash];
840
- const limit = this.safeInteger(subscription, 'limit');
842
+ // subscription.limit is only set when watchOHLCV registers the subscription;
843
+ // when handleMessage routes a non-OHLCV-originated subscription here (or the
844
+ // subscription dict was reset on reconnect), fall back to the OHLCVLimit option.
845
+ const limit = this.safeInteger(subscription, 'limit', this.safeInteger(this.options, 'OHLCVLimit', 1000));
841
846
  this.ohlcvs[symbol][unifiedTimeframe] = new ArrayCacheByTimestamp(limit);
842
847
  }
843
848
  const stored = this.ohlcvs[symbol][unifiedTimeframe];
@@ -1869,6 +1869,16 @@ export default class bitmart extends bitmartRest {
1869
1869
  //
1870
1870
  const errorCode = this.safeString(message, 'errorCode');
1871
1871
  const error = this.safeString(message, 'error');
1872
+ // Duplicate-subscription notice errorCode 90008: bitmart's WS rejects
1873
+ // a re-subscribe attempt on a topic that's already active on this
1874
+ // connection, but the original subscription keeps delivering data —
1875
+ // so treat it as benign. Without this short-circuit, the generic
1876
+ // client.reject below kills every unrelated in-flight future —
1877
+ // e.g. a watchOHLCV waiting on its kline subscription gets rejected
1878
+ // by an orderbook 90008 raised on the same socket.
1879
+ if (errorCode === '90008') {
1880
+ return false;
1881
+ }
1872
1882
  try {
1873
1883
  if (errorCode !== undefined || error !== undefined) {
1874
1884
  const feedback = this.id + ' ' + this.json(message);
@@ -1592,7 +1592,7 @@ export default class bitmex extends bitmexRest {
1592
1592
  if (!(marketId in numUpdatesByMarketId)) {
1593
1593
  numUpdatesByMarketId[marketId] = 0;
1594
1594
  }
1595
- numUpdatesByMarketId[marketId] = this.sum(numUpdatesByMarketId, 1);
1595
+ numUpdatesByMarketId[marketId] = this.sum(numUpdatesByMarketId[marketId], 1);
1596
1596
  const market = this.safeMarket(marketId);
1597
1597
  const symbol = market['symbol'];
1598
1598
  const orderbook = this.orderbooks[symbol];
@@ -573,6 +573,14 @@ export default class grvt extends grvtRest {
573
573
  orderbook['timestamp'] = timestamp;
574
574
  orderbook['datetime'] = this.iso8601(timestamp);
575
575
  }
576
+ // grvt defaults to the delta channel (v1.book.d); if the very first
577
+ // message is a delta, the freshly-created orderbook has symbol=null
578
+ // because no snapshot has reset it yet. Set it unconditionally — we
579
+ // know the symbol from the selector regardless of channel. Java's
580
+ // typed WsOrderBook surfaces this as `"symbol":null` in the output;
581
+ // Python/JS dict-backed orderbooks happen to mask it but the
582
+ // unconditional assignment is correct for every language.
583
+ orderbook['symbol'] = symbol;
576
584
  orderbook['nonce'] = sequenceNumber;
577
585
  const messageHash = 'orderbook::' + symbol;
578
586
  this.orderbooks[symbol] = orderbook;
@@ -153,10 +153,10 @@ export default class htx extends htxRest {
153
153
  * @see https://www.huobi.com/en-in/opend/newApiPages/?id=28c34a7d-77ae-11ed-9966-0242ac110003
154
154
  * @see https://www.huobi.com/en-in/opend/newApiPages/?id=5d5156b5-77b6-11ed-9966-0242ac110003
155
155
  * @description watch all open positions. Note: huobi has one channel for each marginMode and type
156
- * @param {string[]|undefined} symbols list of unified market symbols
157
- * @param since
158
- * @param limit
159
- * @param {object} params extra parameters specific to the exchange API endpoint
156
+ * @param {string[]} [symbols] list of unified market symbols
157
+ * @param {int} [since] timestamp in ms of the earliest position to fetch
158
+ * @param {int} [limit] the maximum number of positions to fetch
159
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
160
160
  * @returns {object[]} a list of [position structure]{@link https://docs.ccxt.com/en/latest/manual.html#position-structure}
161
161
  */
162
162
  watchPositions(symbols?: Strings, since?: Int, limit?: Int, params?: {}): Promise<Position[]>;
package/js/src/pro/htx.js CHANGED
@@ -1356,10 +1356,10 @@ export default class htx extends htxRest {
1356
1356
  * @see https://www.huobi.com/en-in/opend/newApiPages/?id=28c34a7d-77ae-11ed-9966-0242ac110003
1357
1357
  * @see https://www.huobi.com/en-in/opend/newApiPages/?id=5d5156b5-77b6-11ed-9966-0242ac110003
1358
1358
  * @description watch all open positions. Note: huobi has one channel for each marginMode and type
1359
- * @param {string[]|undefined} symbols list of unified market symbols
1360
- * @param since
1361
- * @param limit
1362
- * @param {object} params extra parameters specific to the exchange API endpoint
1359
+ * @param {string[]} [symbols] list of unified market symbols
1360
+ * @param {int} [since] timestamp in ms of the earliest position to fetch
1361
+ * @param {int} [limit] the maximum number of positions to fetch
1362
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
1363
1363
  * @returns {object[]} a list of [position structure]{@link https://docs.ccxt.com/en/latest/manual.html#position-structure}
1364
1364
  */
1365
1365
  async watchPositions(symbols = undefined, since = undefined, limit = undefined, params = {}) {
@@ -112,10 +112,10 @@ export default class krakenfutures extends krakenfuturesRest {
112
112
  * @name krakenfutures#watchPositions
113
113
  * @see https://docs.futures.kraken.com/#websocket-api-private-feeds-open-positions
114
114
  * @description watch all open positions
115
- * @param {string[]|undefined} symbols list of unified market symbols
116
- * @param since
117
- * @param limit
118
- * @param {object} params extra parameters specific to the exchange API endpoint
115
+ * @param {string[]} [symbols] list of unified market symbols
116
+ * @param {int} [since] timestamp in ms of the earliest position to fetch
117
+ * @param {int} [limit] the maximum number of positions to fetch
118
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
119
119
  * @returns {object[]} a list of [position structure]{@link https://docs.ccxt.com/en/latest/manual.html#position-structure}
120
120
  */
121
121
  watchPositions(symbols?: Strings, since?: Int, limit?: Int, params?: {}): Promise<Position[]>;
@@ -261,10 +261,10 @@ export default class krakenfutures extends krakenfuturesRest {
261
261
  * @name krakenfutures#watchPositions
262
262
  * @see https://docs.futures.kraken.com/#websocket-api-private-feeds-open-positions
263
263
  * @description watch all open positions
264
- * @param {string[]|undefined} symbols list of unified market symbols
265
- * @param since
266
- * @param limit
267
- * @param {object} params extra parameters specific to the exchange API endpoint
264
+ * @param {string[]} [symbols] list of unified market symbols
265
+ * @param {int} [since] timestamp in ms of the earliest position to fetch
266
+ * @param {int} [limit] the maximum number of positions to fetch
267
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
268
268
  * @returns {object[]} a list of [position structure]{@link https://docs.ccxt.com/en/latest/manual.html#position-structure}
269
269
  */
270
270
  async watchPositions(symbols = undefined, since = undefined, limit = undefined, params = {}) {
@@ -1537,8 +1537,20 @@ export default class krakenfutures extends krakenfuturesRest {
1537
1537
  // event: 'alert',
1538
1538
  // message: 'Failed to subscribe to authenticated feed'
1539
1539
  // }
1540
+ // {
1541
+ // event: 'alert',
1542
+ // message: 'Already subscribed to feed, re-requesting'
1543
+ // }
1540
1544
  //
1541
1545
  const errMsg = this.safeString(message, 'message');
1546
+ // Benign "already subscribed" notice: the original subscription is still
1547
+ // active and delivering data on this socket. The generic client.reject
1548
+ // below rejects every pending future on the connection, so a stray
1549
+ // re-subscribe warning would kill unrelated in-flight watch* calls —
1550
+ // mirrors the bitmart 90008 fix.
1551
+ if (errMsg !== undefined && errMsg.indexOf('Already subscribed') >= 0) {
1552
+ return false;
1553
+ }
1542
1554
  try {
1543
1555
  throw new ExchangeError(this.id + ' ' + errMsg);
1544
1556
  }
@@ -122,9 +122,9 @@ export default class modetrade extends modetradeRest {
122
122
  * @see https://orderly.network/docs/build-on-evm/evm-api/websocket-api/private/position-push
123
123
  * @description watch all open positions
124
124
  * @param {string[]} [symbols] list of unified market symbols
125
- * @param since timestamp in ms of the earliest position to fetch
126
- * @param limit the maximum number of positions to fetch
127
- * @param {object} params extra parameters specific to the exchange API endpoint
125
+ * @param {int} [since] timestamp in ms of the earliest position to fetch
126
+ * @param {int} [limit] the maximum number of positions to fetch
127
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
128
128
  * @returns {object[]} a list of [position structure]{@link https://docs.ccxt.com/en/latest/manual.html#position-structure}
129
129
  */
130
130
  watchPositions(symbols?: Strings, since?: Int, limit?: Int, params?: {}): Promise<Position[]>;
@@ -956,9 +956,9 @@ export default class modetrade extends modetradeRest {
956
956
  * @see https://orderly.network/docs/build-on-evm/evm-api/websocket-api/private/position-push
957
957
  * @description watch all open positions
958
958
  * @param {string[]} [symbols] list of unified market symbols
959
- * @param since timestamp in ms of the earliest position to fetch
960
- * @param limit the maximum number of positions to fetch
961
- * @param {object} params extra parameters specific to the exchange API endpoint
959
+ * @param {int} [since] timestamp in ms of the earliest position to fetch
960
+ * @param {int} [limit] the maximum number of positions to fetch
961
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
962
962
  * @returns {object[]} a list of [position structure]{@link https://docs.ccxt.com/en/latest/manual.html#position-structure}
963
963
  */
964
964
  async watchPositions(symbols = undefined, since = undefined, limit = undefined, params = {}) {
@@ -309,10 +309,10 @@ export default class okx extends okxRest {
309
309
  * @name okx#watchPositions
310
310
  * @see https://www.okx.com/docs-v5/en/#trading-account-websocket-positions-channel
311
311
  * @description watch all open positions
312
- * @param {string[]|undefined} symbols list of unified market symbols
313
- * @param since
314
- * @param limit
315
- * @param {object} params extra parameters specific to the exchange API endpoint
312
+ * @param {string[]} [symbols] list of unified market symbols
313
+ * @param {int} [since] timestamp in ms of the earliest position to fetch
314
+ * @param {int} [limit] the maximum number of positions to fetch
315
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
316
316
  * @returns {object[]} a list of [position structure]{@link https://docs.ccxt.com/en/latest/manual.html#position-structure}
317
317
  */
318
318
  watchPositions(symbols?: Strings, since?: Int, limit?: Int, params?: {}): Promise<Position[]>;
package/js/src/pro/okx.js CHANGED
@@ -1699,10 +1699,10 @@ export default class okx extends okxRest {
1699
1699
  * @name okx#watchPositions
1700
1700
  * @see https://www.okx.com/docs-v5/en/#trading-account-websocket-positions-channel
1701
1701
  * @description watch all open positions
1702
- * @param {string[]|undefined} symbols list of unified market symbols
1703
- * @param since
1704
- * @param limit
1705
- * @param {object} params extra parameters specific to the exchange API endpoint
1702
+ * @param {string[]} [symbols] list of unified market symbols
1703
+ * @param {int} [since] timestamp in ms of the earliest position to fetch
1704
+ * @param {int} [limit] the maximum number of positions to fetch
1705
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
1706
1706
  * @returns {object[]} a list of [position structure]{@link https://docs.ccxt.com/en/latest/manual.html#position-structure}
1707
1707
  */
1708
1708
  async watchPositions(symbols = undefined, since = undefined, limit = undefined, params = {}) {
@@ -138,10 +138,10 @@ export default class oxfun extends oxfunRest {
138
138
  * @name oxfun#watchPositions
139
139
  * @see https://docs.ox.fun/?json#position-channel
140
140
  * @description watch all open positions
141
- * @param {string[]|undefined} symbols list of unified market symbols
142
- * @param since
143
- * @param limit
144
- * @param {object} params extra parameters specific to the exchange API endpoint
141
+ * @param {string[]} [symbols] list of unified market symbols
142
+ * @param {int} [since] timestamp in ms of the earliest position to fetch
143
+ * @param {int} [limit] the maximum number of positions to fetch
144
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
145
145
  * @param {int|string} [params.tag] If given it will be echoed in the reply and the max size of tag is 32
146
146
  * @returns {object[]} a list of [position structure]{@link https://docs.ccxt.com/en/latest/manual.html#position-structure}
147
147
  */