ccxt 4.2.13 → 4.2.15

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 (53) hide show
  1. package/README.md +3 -3
  2. package/dist/ccxt.browser.js +781 -133
  3. package/dist/ccxt.browser.min.js +7 -7
  4. package/dist/cjs/ccxt.js +1 -1
  5. package/dist/cjs/js/ccxt.js +1 -1
  6. package/dist/cjs/js/src/base/Exchange.js +148 -1
  7. package/dist/cjs/js/src/bigone.js +36 -32
  8. package/dist/cjs/js/src/binance.js +108 -0
  9. package/dist/cjs/js/src/binanceus.js +8 -0
  10. package/dist/cjs/js/src/bingx.js +5 -0
  11. package/dist/cjs/js/src/bitget.js +4 -0
  12. package/dist/cjs/js/src/bybit.js +4 -0
  13. package/dist/cjs/js/src/coinex.js +3 -0
  14. package/dist/cjs/js/src/delta.js +7 -1
  15. package/dist/cjs/js/src/gate.js +5 -0
  16. package/dist/cjs/js/src/htx.js +126 -1
  17. package/dist/cjs/js/src/kraken.js +43 -9
  18. package/dist/cjs/js/src/kucoin.js +5 -0
  19. package/dist/cjs/js/src/kucoinfutures.js +131 -77
  20. package/dist/cjs/js/src/okx.js +9 -8
  21. package/dist/cjs/js/src/pro/htx.js +6 -1
  22. package/dist/cjs/js/src/pro/woo.js +126 -0
  23. package/dist/cjs/js/src/woo.js +6 -2
  24. package/js/ccxt.d.ts +1 -1
  25. package/js/ccxt.js +1 -1
  26. package/js/src/abstract/bigone.d.ts +1 -0
  27. package/js/src/abstract/kucoin.d.ts +4 -0
  28. package/js/src/abstract/kucoinfutures.d.ts +4 -0
  29. package/js/src/base/Exchange.d.ts +8 -0
  30. package/js/src/base/Exchange.js +148 -1
  31. package/js/src/bigone.js +36 -32
  32. package/js/src/binance.d.ts +9 -0
  33. package/js/src/binance.js +108 -0
  34. package/js/src/binanceus.js +8 -0
  35. package/js/src/bingx.js +5 -0
  36. package/js/src/bitget.js +4 -0
  37. package/js/src/bybit.js +4 -0
  38. package/js/src/coinex.js +3 -0
  39. package/js/src/delta.js +7 -1
  40. package/js/src/gate.js +5 -0
  41. package/js/src/htx.d.ts +9 -0
  42. package/js/src/htx.js +126 -1
  43. package/js/src/kraken.d.ts +1 -0
  44. package/js/src/kraken.js +43 -9
  45. package/js/src/kucoin.js +5 -0
  46. package/js/src/kucoinfutures.d.ts +4 -2
  47. package/js/src/kucoinfutures.js +131 -77
  48. package/js/src/okx.js +9 -8
  49. package/js/src/pro/htx.js +6 -1
  50. package/js/src/pro/woo.d.ts +5 -1
  51. package/js/src/pro/woo.js +127 -1
  52. package/js/src/woo.js +6 -2
  53. package/package.json +1 -1
@@ -45,9 +45,12 @@ class htx extends htx$1 {
45
45
  'createOrders': true,
46
46
  'createReduceOnlyOrder': false,
47
47
  'createStopLimitOrder': true,
48
+ 'createStopLossOrder': true,
48
49
  'createStopMarketOrder': true,
49
50
  'createStopOrder': true,
51
+ 'createTakeProfitOrder': true,
50
52
  'createTrailingPercentOrder': true,
53
+ 'createTriggerOrder': true,
51
54
  'fetchAccounts': true,
52
55
  'fetchBalance': true,
53
56
  'fetchBidsAsks': undefined,
@@ -75,6 +78,7 @@ class htx extends htx$1 {
75
78
  'fetchIsolatedBorrowRate': false,
76
79
  'fetchIsolatedBorrowRates': true,
77
80
  'fetchL3OrderBook': undefined,
81
+ 'fetchLastPrices': true,
78
82
  'fetchLedger': true,
79
83
  'fetchLedgerEntry': undefined,
80
84
  'fetchLeverage': false,
@@ -2267,6 +2271,127 @@ class htx extends htx$1 {
2267
2271
  }
2268
2272
  return this.filterByArrayTickers(result, 'symbol', symbols);
2269
2273
  }
2274
+ async fetchLastPrices(symbols = undefined, params = {}) {
2275
+ /**
2276
+ * @method
2277
+ * @name binance#fetchLastPrices
2278
+ * @description fetches the last price for multiple markets
2279
+ * @see https://www.htx.com/en-us/opend/newApiPages/?id=8cb81024-77b5-11ed-9966-0242ac110003 linear swap & linear future
2280
+ * @see https://www.htx.com/en-us/opend/newApiPages/?id=28c2e8fc-77ae-11ed-9966-0242ac110003 inverse future
2281
+ * @see https://www.htx.com/en-us/opend/newApiPages/?id=5d517ef5-77b6-11ed-9966-0242ac110003 inverse swap
2282
+ * @param {string[]|undefined} symbols unified symbols of the markets to fetch the last prices
2283
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
2284
+ * @returns {object} a dictionary of lastprices structures
2285
+ */
2286
+ await this.loadMarkets();
2287
+ symbols = this.marketSymbols(symbols);
2288
+ const market = this.getMarketFromSymbols(symbols);
2289
+ let type = undefined;
2290
+ let subType = undefined;
2291
+ [subType, params] = this.handleSubTypeAndParams('fetchLastPrices', market, params);
2292
+ [type, params] = this.handleMarketTypeAndParams('fetchLastPrices', market, params);
2293
+ let response = undefined;
2294
+ if (((type === 'swap') || (type === 'future')) && (subType === 'linear')) {
2295
+ response = await this.contractPublicGetLinearSwapExMarketTrade(params);
2296
+ //
2297
+ // {
2298
+ // "ch": "market.*.trade.detail",
2299
+ // "status": "ok",
2300
+ // "tick": {
2301
+ // "data": [
2302
+ // {
2303
+ // "amount": "4",
2304
+ // "quantity": "40",
2305
+ // "trade_turnover": "22.176",
2306
+ // "ts": 1703697705028,
2307
+ // "id": 1000003558478170000,
2308
+ // "price": "0.5544",
2309
+ // "direction": "buy",
2310
+ // "contract_code": "MANA-USDT",
2311
+ // "business_type": "swap",
2312
+ // "trade_partition": "USDT"
2313
+ // },
2314
+ // ],
2315
+ // "id": 1703697740147,
2316
+ // "ts": 1703697740147
2317
+ // },
2318
+ // "ts": 1703697740147
2319
+ // }
2320
+ //
2321
+ }
2322
+ else if ((type === 'swap') && (subType === 'inverse')) {
2323
+ response = await this.contractPublicGetSwapExMarketTrade(params);
2324
+ //
2325
+ // {
2326
+ // "ch": "market.*.trade.detail",
2327
+ // "status": "ok",
2328
+ // "tick": {
2329
+ // "data": [
2330
+ // {
2331
+ // "amount": "6",
2332
+ // "quantity": "94.5000945000945000945000945000945000945",
2333
+ // "ts": 1703698704594,
2334
+ // "id": 1000001187811060000,
2335
+ // "price": "0.63492",
2336
+ // "direction": "buy",
2337
+ // "contract_code": "XRP-USD"
2338
+ // },
2339
+ // ],
2340
+ // "id": 1703698706589,
2341
+ // "ts": 1703698706589
2342
+ // },
2343
+ // "ts": 1703698706589
2344
+ // }
2345
+ //
2346
+ }
2347
+ else if ((type === 'future') && (subType === 'inverse')) {
2348
+ response = await this.contractPublicGetMarketTrade(params);
2349
+ //
2350
+ // {
2351
+ // "ch": "market.*.trade.detail",
2352
+ // "status": "ok",
2353
+ // "tick": {
2354
+ // "data": [
2355
+ // {
2356
+ // "amount": "20",
2357
+ // "quantity": "44.4444444444444444444444444444444444444",
2358
+ // "ts": 1686134498885,
2359
+ // "id": 2323000000174820000,
2360
+ // "price": "4.5",
2361
+ // "direction": "sell",
2362
+ // "symbol": "DORA_CW"
2363
+ // },
2364
+ // ],
2365
+ // "id": 1703698855142,
2366
+ // "ts": 1703698855142
2367
+ // },
2368
+ // "ts": 1703698855142
2369
+ // }
2370
+ //
2371
+ }
2372
+ else {
2373
+ throw new errors.NotSupported(this.id + ' fetchLastPrices() does not support ' + type + ' markets yet');
2374
+ }
2375
+ const tick = this.safeValue(response, 'tick', {});
2376
+ const data = this.safeValue(tick, 'data', []);
2377
+ return this.parseLastPrices(data, symbols);
2378
+ }
2379
+ parseLastPrice(entry, market = undefined) {
2380
+ // example responses are documented in fetchLastPrices
2381
+ const marketId = this.safeString2(entry, 'symbol', 'contract_code');
2382
+ market = this.safeMarket(marketId, market);
2383
+ const price = this.safeNumber(entry, 'price');
2384
+ const direction = this.safeString(entry, 'direction'); // "buy" or "sell"
2385
+ // group timestamp should not be assigned to the individual trades' times
2386
+ return {
2387
+ 'symbol': market['symbol'],
2388
+ 'timestamp': undefined,
2389
+ 'datetime': undefined,
2390
+ 'price': price,
2391
+ 'side': direction,
2392
+ 'info': entry,
2393
+ };
2394
+ }
2270
2395
  async fetchOrderBook(symbol, limit = undefined, params = {}) {
2271
2396
  /**
2272
2397
  * @method
@@ -4972,7 +5097,7 @@ class htx extends htx$1 {
4972
5097
  async createTrailingPercentOrder(symbol, type, side, amount, price = undefined, trailingPercent = undefined, trailingTriggerPrice = undefined, params = {}) {
4973
5098
  /**
4974
5099
  * @method
4975
- * @name createTrailingPercentOrder
5100
+ * @name htx#createTrailingPercentOrder
4976
5101
  * @description create a trailing order by providing the symbol, type, side, amount, price and trailingPercent
4977
5102
  * @param {string} symbol unified symbol of the market to create an order in
4978
5103
  * @param {string} type 'market' or 'limit'
@@ -1438,6 +1438,16 @@ class kraken extends kraken$1 {
1438
1438
  };
1439
1439
  return this.safeString(statuses, status, status);
1440
1440
  }
1441
+ parseOrderType(status) {
1442
+ const statuses = {
1443
+ 'take-profit': 'market',
1444
+ 'stop-loss-limit': 'limit',
1445
+ 'stop-loss': 'market',
1446
+ 'take-profit-limit': 'limit',
1447
+ 'trailing-stop-limit': 'limit',
1448
+ };
1449
+ return this.safeString(statuses, status, status);
1450
+ }
1441
1451
  parseOrder(order, market = undefined) {
1442
1452
  //
1443
1453
  // createOrder for regular orders
@@ -1580,7 +1590,17 @@ class kraken extends kraken$1 {
1580
1590
  trades.push(rawTrade);
1581
1591
  }
1582
1592
  }
1583
- stopPrice = this.safeNumber(order, 'stopprice', stopPrice);
1593
+ stopPrice = this.omitZero(this.safeString(order, 'stopprice', stopPrice));
1594
+ let stopLossPrice = undefined;
1595
+ let takeProfitPrice = undefined;
1596
+ if (type.startsWith('take-profit')) {
1597
+ takeProfitPrice = this.safeString(description, 'price');
1598
+ price = this.omitZero(this.safeString(description, 'price2'));
1599
+ }
1600
+ else if (type.startsWith('stop-loss')) {
1601
+ stopLossPrice = this.safeString(description, 'price');
1602
+ price = this.omitZero(this.safeString(description, 'price2'));
1603
+ }
1584
1604
  return this.safeOrder({
1585
1605
  'id': id,
1586
1606
  'clientOrderId': clientOrderId,
@@ -1590,13 +1610,15 @@ class kraken extends kraken$1 {
1590
1610
  'lastTradeTimestamp': undefined,
1591
1611
  'status': status,
1592
1612
  'symbol': symbol,
1593
- 'type': type,
1613
+ 'type': this.parseOrderType(type),
1594
1614
  'timeInForce': undefined,
1595
1615
  'postOnly': isPostOnly,
1596
1616
  'side': side,
1597
1617
  'price': price,
1598
1618
  'stopPrice': stopPrice,
1599
1619
  'triggerPrice': stopPrice,
1620
+ 'takeProfitPrice': takeProfitPrice,
1621
+ 'stopLossPrice': stopLossPrice,
1600
1622
  'cost': undefined,
1601
1623
  'amount': amount,
1602
1624
  'filled': filled,
@@ -1620,27 +1642,39 @@ class kraken extends kraken$1 {
1620
1642
  const trailingAmount = this.safeString(params, 'trailingAmount');
1621
1643
  const trailingLimitAmount = this.safeString(params, 'trailingLimitAmount');
1622
1644
  const isTrailingAmountOrder = trailingAmount !== undefined;
1623
- if ((type === 'limit') && !isTrailingAmountOrder) {
1645
+ const isLimitOrder = type.endsWith('limit'); // supporting limit, stop-loss-limit, take-profit-limit, etc
1646
+ if (isLimitOrder && !isTrailingAmountOrder) {
1624
1647
  request['price'] = this.priceToPrecision(symbol, price);
1625
1648
  }
1626
- let reduceOnly = this.safeValue2(params, 'reduceOnly', 'reduce_only');
1649
+ const reduceOnly = this.safeValue2(params, 'reduceOnly', 'reduce_only');
1627
1650
  if (isStopLossOrTakeProfitTrigger) {
1628
1651
  if (isStopLossTriggerOrder) {
1629
1652
  request['price'] = this.priceToPrecision(symbol, stopLossTriggerPrice);
1630
- request['ordertype'] = 'stop-loss-limit';
1653
+ if (isLimitOrder) {
1654
+ request['ordertype'] = 'stop-loss-limit';
1655
+ }
1656
+ else {
1657
+ request['ordertype'] = 'stop-loss';
1658
+ }
1631
1659
  }
1632
1660
  else if (isTakeProfitTriggerOrder) {
1633
1661
  request['price'] = this.priceToPrecision(symbol, takeProfitTriggerPrice);
1634
- request['ordertype'] = 'take-profit-limit';
1662
+ if (isLimitOrder) {
1663
+ request['ordertype'] = 'take-profit-limit';
1664
+ }
1665
+ else {
1666
+ request['ordertype'] = 'take-profit';
1667
+ }
1668
+ }
1669
+ if (isLimitOrder) {
1670
+ request['price2'] = this.priceToPrecision(symbol, price);
1635
1671
  }
1636
- request['price2'] = this.priceToPrecision(symbol, price);
1637
- reduceOnly = true;
1638
1672
  }
1639
1673
  else if (isTrailingAmountOrder) {
1640
1674
  const trailingActivationPriceType = this.safeString(params, 'trigger', 'last');
1641
1675
  const trailingAmountString = '+' + trailingAmount;
1642
1676
  request['trigger'] = trailingActivationPriceType;
1643
- if ((type === 'limit') || (trailingLimitAmount !== undefined)) {
1677
+ if (isLimitOrder || (trailingLimitAmount !== undefined)) {
1644
1678
  const offset = this.safeString(params, 'offset', '-');
1645
1679
  const trailingLimitAmountString = offset + this.numberToString(trailingLimitAmount);
1646
1680
  request['price'] = trailingAmountString;
@@ -47,6 +47,7 @@ class kucoin extends kucoin$1 {
47
47
  'createStopLimitOrder': true,
48
48
  'createStopMarketOrder': true,
49
49
  'createStopOrder': true,
50
+ 'createTriggerOrder': true,
50
51
  'editOrder': true,
51
52
  'fetchAccounts': true,
52
53
  'fetchBalance': true,
@@ -313,6 +314,7 @@ class kucoin extends kucoin$1 {
313
314
  'premium/query': 4.5,
314
315
  'trade-statistics': 4.5,
315
316
  'funding-rate/{symbol}/current': 3,
317
+ 'contract/funding-rates': 7.5,
316
318
  'timestamp': 3,
317
319
  'status': 6,
318
320
  // ?
@@ -342,6 +344,7 @@ class kucoin extends kucoin$1 {
342
344
  'openOrderStatistics': 15,
343
345
  'position': 3,
344
346
  'positions': 3,
347
+ 'margin/maxWithdrawMargin': 15,
345
348
  'contracts/risk-limit/{symbol}': 7.5,
346
349
  'funding-history': 7.5, // 5FW
347
350
  },
@@ -352,7 +355,9 @@ class kucoin extends kucoin$1 {
352
355
  // futures
353
356
  'orders': 3,
354
357
  'orders/test': 3,
358
+ 'orders/multi': 4.5,
355
359
  'position/margin/auto-deposit-status': 6,
360
+ 'margin/withdrawMargin': 15,
356
361
  'position/margin/deposit-margin': 6,
357
362
  'position/risk-limit-level/change': 6,
358
363
  // ws
@@ -33,10 +33,14 @@ class kucoinfutures extends kucoinfutures$1 {
33
33
  'closePositions': false,
34
34
  'createDepositAddress': true,
35
35
  'createOrder': true,
36
+ 'createOrders': true,
36
37
  'createReduceOnlyOrder': true,
37
38
  'createStopLimitOrder': true,
39
+ 'createStopLossOrder': true,
38
40
  'createStopMarketOrder': true,
39
41
  'createStopOrder': true,
42
+ 'createTakeProfitOrder': true,
43
+ 'createTriggerOrder': true,
40
44
  'fetchAccounts': true,
41
45
  'fetchBalance': true,
42
46
  'fetchBorrowRateHistories': false,
@@ -51,7 +55,7 @@ class kucoinfutures extends kucoinfutures$1 {
51
55
  'fetchDepositWithdrawFees': false,
52
56
  'fetchFundingHistory': true,
53
57
  'fetchFundingRate': true,
54
- 'fetchFundingRateHistory': false,
58
+ 'fetchFundingRateHistory': true,
55
59
  'fetchIndexOHLCV': false,
56
60
  'fetchIsolatedBorrowRate': false,
57
61
  'fetchIsolatedBorrowRates': false,
@@ -1112,6 +1116,78 @@ class kucoinfutures extends kucoinfutures$1 {
1112
1116
  * @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
1113
1117
  */
1114
1118
  await this.loadMarkets();
1119
+ const market = this.market(symbol);
1120
+ const testOrder = this.safeValue(params, 'test', false);
1121
+ params = this.omit(params, 'test');
1122
+ const orderRequest = this.createContractOrderRequest(symbol, type, side, amount, price, params);
1123
+ let response = undefined;
1124
+ if (testOrder) {
1125
+ response = await this.futuresPrivatePostOrdersTest(orderRequest);
1126
+ }
1127
+ else {
1128
+ response = await this.futuresPrivatePostOrders(orderRequest);
1129
+ }
1130
+ //
1131
+ // {
1132
+ // "code": "200000",
1133
+ // "data": {
1134
+ // "orderId": "619717484f1d010001510cde",
1135
+ // },
1136
+ // }
1137
+ //
1138
+ const data = this.safeValue(response, 'data', {});
1139
+ return this.parseOrder(data, market);
1140
+ }
1141
+ async createOrders(orders, params = {}) {
1142
+ /**
1143
+ * @method
1144
+ * @name kucoinfutures#createOrders
1145
+ * @description create a list of trade orders
1146
+ * @see https://www.kucoin.com/docs/rest/futures-trading/orders/place-multiple-orders
1147
+ * @param {Array} orders list of orders to create, each object should contain the parameters required by createOrder, namely symbol, type, side, amount, price and params
1148
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
1149
+ * @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
1150
+ */
1151
+ await this.loadMarkets();
1152
+ const ordersRequests = [];
1153
+ for (let i = 0; i < orders.length; i++) {
1154
+ const rawOrder = orders[i];
1155
+ const symbol = this.safeString(rawOrder, 'symbol');
1156
+ const market = this.market(symbol);
1157
+ const type = this.safeString(rawOrder, 'type');
1158
+ const side = this.safeString(rawOrder, 'side');
1159
+ const amount = this.safeValue(rawOrder, 'amount');
1160
+ const price = this.safeValue(rawOrder, 'price');
1161
+ const orderParams = this.safeValue(rawOrder, 'params', {});
1162
+ const orderRequest = this.createContractOrderRequest(market['id'], type, side, amount, price, orderParams);
1163
+ ordersRequests.push(orderRequest);
1164
+ }
1165
+ const response = await this.futuresPrivatePostOrdersMulti(ordersRequests);
1166
+ //
1167
+ // {
1168
+ // "code": "200000",
1169
+ // "data": [
1170
+ // {
1171
+ // "orderId": "135241412609331200",
1172
+ // "clientOid": "3d8fcc13-0b13-447f-ad30-4b3441e05213",
1173
+ // "symbol": "LTCUSDTM",
1174
+ // "code": "200000",
1175
+ // "msg": "success"
1176
+ // },
1177
+ // {
1178
+ // "orderId": "135241412747743234",
1179
+ // "clientOid": "b878c7ee-ae3e-4d63-a20b-038acbb7306f",
1180
+ // "symbol": "LTCUSDTM",
1181
+ // "code": "200000",
1182
+ // "msg": "success"
1183
+ // }
1184
+ // ]
1185
+ // }
1186
+ //
1187
+ const data = this.safeValue(response, 'data', []);
1188
+ return this.parseOrders(data);
1189
+ }
1190
+ createContractOrderRequest(symbol, type, side, amount, price = undefined, params = {}) {
1115
1191
  const market = this.market(symbol);
1116
1192
  // required param, cannot be used twice
1117
1193
  const clientOrderId = this.safeString2(params, 'clientOid', 'clientOrderId', this.uuid());
@@ -1184,48 +1260,7 @@ class kucoinfutures extends kucoinfutures$1 {
1184
1260
  }
1185
1261
  }
1186
1262
  params = this.omit(params, ['timeInForce', 'stopPrice', 'triggerPrice', 'stopLossPrice', 'takeProfitPrice']); // Time in force only valid for limit orders, exchange error when gtc for market orders
1187
- let response = undefined;
1188
- const testOrder = this.safeValue(params, 'test', false);
1189
- params = this.omit(params, 'test');
1190
- if (testOrder) {
1191
- response = await this.futuresPrivatePostOrdersTest(this.extend(request, params));
1192
- }
1193
- else {
1194
- response = await this.futuresPrivatePostOrders(this.extend(request, params));
1195
- }
1196
- //
1197
- // {
1198
- // "code": "200000",
1199
- // "data": {
1200
- // "orderId": "619717484f1d010001510cde",
1201
- // },
1202
- // }
1203
- //
1204
- const data = this.safeValue(response, 'data', {});
1205
- return this.safeOrder({
1206
- 'id': this.safeString(data, 'orderId'),
1207
- 'clientOrderId': undefined,
1208
- 'timestamp': undefined,
1209
- 'datetime': undefined,
1210
- 'lastTradeTimestamp': undefined,
1211
- 'symbol': undefined,
1212
- 'type': undefined,
1213
- 'side': undefined,
1214
- 'price': undefined,
1215
- 'amount': undefined,
1216
- 'cost': undefined,
1217
- 'average': undefined,
1218
- 'filled': undefined,
1219
- 'remaining': undefined,
1220
- 'status': undefined,
1221
- 'fee': undefined,
1222
- 'trades': undefined,
1223
- 'timeInForce': undefined,
1224
- 'postOnly': undefined,
1225
- 'stopPrice': undefined,
1226
- 'triggerPrice': undefined,
1227
- 'info': response,
1228
- }, market);
1263
+ return this.extend(request, params);
1229
1264
  }
1230
1265
  async cancelOrder(id, symbol = undefined, params = {}) {
1231
1266
  /**
@@ -1698,10 +1733,26 @@ class kucoinfutures extends kucoinfutures$1 {
1698
1733
  // "reduceOnly": false
1699
1734
  // }
1700
1735
  //
1736
+ // createOrder
1737
+ //
1738
+ // {
1739
+ // "orderId": "619717484f1d010001510cde"
1740
+ // }
1741
+ //
1742
+ // createOrders
1743
+ //
1744
+ // {
1745
+ // "orderId": "80465574458560512",
1746
+ // "clientOid": "5c52e11203aa677f33e491",
1747
+ // "symbol": "ETHUSDTM",
1748
+ // "code": "200000",
1749
+ // "msg": "success"
1750
+ // }
1751
+ //
1701
1752
  const marketId = this.safeString(order, 'symbol');
1702
1753
  market = this.safeMarket(marketId, market);
1703
1754
  const symbol = market['symbol'];
1704
- const orderId = this.safeString(order, 'id');
1755
+ const orderId = this.safeString2(order, 'id', 'orderId');
1705
1756
  const type = this.safeString(order, 'type');
1706
1757
  const timestamp = this.safeInteger(order, 'createdAt');
1707
1758
  const datetime = this.iso8601(timestamp);
@@ -1728,9 +1779,12 @@ class kucoinfutures extends kucoinfutures$1 {
1728
1779
  // precision reported by their api is 8 d.p.
1729
1780
  // const average = Precise.stringDiv (cost, Precise.stringMul (filled, market['contractSize']));
1730
1781
  // bool
1731
- const isActive = this.safeValue(order, 'isActive', false);
1782
+ const isActive = this.safeValue(order, 'isActive');
1732
1783
  const cancelExist = this.safeValue(order, 'cancelExist', false);
1733
- let status = isActive ? 'open' : 'closed';
1784
+ let status = undefined;
1785
+ if (isActive !== undefined) {
1786
+ status = isActive ? 'open' : 'closed';
1787
+ }
1734
1788
  status = cancelExist ? 'canceled' : status;
1735
1789
  let fee = undefined;
1736
1790
  if (feeCost !== undefined) {
@@ -2375,62 +2429,62 @@ class kucoinfutures extends kucoinfutures$1 {
2375
2429
  /**
2376
2430
  * @method
2377
2431
  * @name kucoinfutures#fetchFundingRateHistory
2432
+ * @see https://www.kucoin.com/docs/rest/futures-trading/funding-fees/get-public-funding-history#request-url
2378
2433
  * @description fetches historical funding rate prices
2379
2434
  * @param {string} symbol unified symbol of the market to fetch the funding rate history for
2380
2435
  * @param {int} [since] not used by kucuoinfutures
2381
2436
  * @param {int} [limit] the maximum amount of [funding rate structures]{@link https://docs.ccxt.com/#/?id=funding-rate-history-structure} to fetch
2382
2437
  * @param {object} [params] extra parameters specific to the exchange API endpoint
2383
- * @param {boolean} [params.paginate] default false, when true will automatically paginate by calling this endpoint multiple times. See in the docs all the [availble parameters](https://github.com/ccxt/ccxt/wiki/Manual#pagination-params)
2438
+ * @param {int} [params.until] end time in ms
2384
2439
  * @returns {object[]} a list of [funding rate structures]{@link https://docs.ccxt.com/#/?id=funding-rate-history-structure}
2385
2440
  */
2386
2441
  if (symbol === undefined) {
2387
2442
  throw new errors.ArgumentsRequired(this.id + ' fetchFundingRateHistory() requires a symbol argument');
2388
2443
  }
2389
2444
  await this.loadMarkets();
2390
- let paginate = false;
2391
- [paginate, params] = this.handleOptionAndParams(params, 'fetchFundingRateHistory', 'paginate');
2392
- if (paginate) {
2393
- return await this.fetchPaginatedCallDeterministic('fetchFundingRateHistory', symbol, since, limit, '8h', params);
2394
- }
2395
2445
  const market = this.market(symbol);
2396
2446
  const request = {
2397
2447
  'symbol': market['id'],
2448
+ 'from': 0,
2449
+ 'to': this.milliseconds(),
2398
2450
  };
2399
- if (limit !== undefined) {
2400
- request['maxCount'] = limit;
2451
+ const until = this.safeInteger2(params, 'until', 'till');
2452
+ params = this.omit(params, ['until', 'till']);
2453
+ if (since !== undefined) {
2454
+ request['from'] = since;
2455
+ if (until === undefined) {
2456
+ request['to'] = since + 1000 * 8 * 60 * 60 * 100;
2457
+ }
2458
+ }
2459
+ if (until !== undefined) {
2460
+ request['to'] = until;
2461
+ if (since === undefined) {
2462
+ request['to'] = until - 1000 * 8 * 60 * 60 * 100;
2463
+ }
2401
2464
  }
2402
- const response = await this.webExchangeGetContractSymbolFundingRates(this.extend(request, params));
2465
+ const response = await this.futuresPublicGetContractFundingRates(this.extend(request, params));
2403
2466
  //
2404
- // {
2405
- // "success": true,
2406
- // "code": "200",
2407
- // "msg": "success",
2408
- // "retry": false,
2409
- // "data": {
2410
- // "dataList": [
2411
- // {
2412
- // "symbol": "XBTUSDTM",
2413
- // "granularity": 28800000,
2414
- // "timePoint": 1675108800000,
2415
- // "value": 0.0001
2416
- // },
2417
- // ...
2418
- // ],
2419
- // "hasMore": true
2420
- // }
2421
- // }
2467
+ // {
2468
+ // "code": "200000",
2469
+ // "data": [
2470
+ // {
2471
+ // "symbol": "IDUSDTM",
2472
+ // "fundingRate": 2.26E-4,
2473
+ // "timepoint": 1702296000000
2474
+ // }
2475
+ // ]
2476
+ // }
2422
2477
  //
2423
2478
  const data = this.safeValue(response, 'data');
2424
- const dataList = this.safeValue(data, 'dataList');
2425
- return this.parseFundingRateHistories(dataList, market, since, limit);
2479
+ return this.parseFundingRateHistories(data, market, since, limit);
2426
2480
  }
2427
2481
  parseFundingRateHistory(info, market = undefined) {
2428
- const timestamp = this.safeInteger(info, 'timePoint');
2482
+ const timestamp = this.safeInteger(info, 'timepoint');
2429
2483
  const marketId = this.safeString(info, 'symbol');
2430
2484
  return {
2431
2485
  'info': info,
2432
2486
  'symbol': this.safeSymbol(marketId, market),
2433
- 'fundingRate': this.safeNumber(info, 'value'),
2487
+ 'fundingRate': this.safeNumber(info, 'fundingRate'),
2434
2488
  'timestamp': timestamp,
2435
2489
  'datetime': this.iso8601(timestamp),
2436
2490
  };
@@ -40,12 +40,16 @@ class okx extends okx$1 {
40
40
  'createMarketSellOrderWithCost': true,
41
41
  'createOrder': true,
42
42
  'createOrders': true,
43
+ 'createOrderWithTakeProfitAndStopLoss': true,
43
44
  'createPostOnlyOrder': true,
44
45
  'createReduceOnlyOrder': true,
45
46
  'createStopLimitOrder': true,
47
+ 'createStopLossOrder': true,
46
48
  'createStopMarketOrder': true,
47
49
  'createStopOrder': true,
50
+ 'createTakeProfitOrder': true,
48
51
  'createTrailingPercentOrder': true,
52
+ 'createTriggerOrder': true,
49
53
  'editOrder': true,
50
54
  'fetchAccounts': true,
51
55
  'fetchBalance': true,
@@ -2133,17 +2137,14 @@ class okx extends okx$1 {
2133
2137
  let defaultType = 'Candles';
2134
2138
  if (since !== undefined) {
2135
2139
  const now = this.milliseconds();
2136
- const difference = now - since;
2137
2140
  const durationInMilliseconds = duration * 1000;
2138
- // if the since timestamp is more than limit candles back in the past
2139
- // additional one bar for max offset to round the current day to UTC
2140
- const calc = (1440 - limit - 1) * durationInMilliseconds;
2141
- if (difference > calc) {
2141
+ // switch to history candles if since is past the cutoff for current candles
2142
+ const historyBorder = now - ((1440 - 1) * durationInMilliseconds);
2143
+ if (since < historyBorder) {
2142
2144
  defaultType = 'HistoryCandles';
2143
2145
  }
2144
- const startTime = Math.max(since - 1, 0);
2145
- request['before'] = startTime;
2146
- request['after'] = this.sum(startTime, durationInMilliseconds * limit);
2146
+ request['before'] = since;
2147
+ request['after'] = this.sum(since, durationInMilliseconds * limit);
2147
2148
  }
2148
2149
  const until = this.safeInteger(params, 'until');
2149
2150
  if (until !== undefined) {
@@ -930,11 +930,16 @@ class htx extends htx$1 {
930
930
  // inject trade in existing order by faking an order object
931
931
  const orderId = this.safeString(parsedTrade, 'order');
932
932
  const trades = [parsedTrade];
933
+ const status = this.parseOrderStatus(this.safeString2(data, 'orderStatus', 'status', 'closed'));
934
+ const filled = this.safeString(data, 'execAmt');
935
+ const remaining = this.safeString(data, 'remainAmt');
933
936
  const order = {
934
937
  'id': orderId,
935
938
  'trades': trades,
936
- 'status': 'closed',
939
+ 'status': status,
937
940
  'symbol': market['symbol'],
941
+ 'filled': this.parseNumber(filled),
942
+ 'remaining': this.parseNumber(remaining),
938
943
  };
939
944
  parsedOrder = order;
940
945
  }