ccxt 4.5.46 → 4.5.47

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 (63) hide show
  1. package/README.md +5 -6
  2. package/dist/ccxt.browser.min.js +3 -3
  3. package/dist/cjs/ccxt.js +1 -6
  4. package/dist/cjs/src/aftermath.js +1 -1
  5. package/dist/cjs/src/backpack.js +1 -1
  6. package/dist/cjs/src/base/Exchange.js +24 -0
  7. package/dist/cjs/src/binance.js +12 -15
  8. package/dist/cjs/src/bitfinex.js +6 -11
  9. package/dist/cjs/src/bitget.js +6 -3
  10. package/dist/cjs/src/bitmex.js +46 -0
  11. package/dist/cjs/src/bitstamp.js +14 -1
  12. package/dist/cjs/src/bittrade.js +1 -1
  13. package/dist/cjs/src/blofin.js +137 -29
  14. package/dist/cjs/src/hollaex.js +1 -1
  15. package/dist/cjs/src/kraken.js +39 -31
  16. package/dist/cjs/src/kucoin.js +2158 -461
  17. package/dist/cjs/src/lighter.js +2 -2
  18. package/dist/cjs/src/okx.js +0 -1
  19. package/dist/cjs/src/pro/bittrade.js +4 -0
  20. package/dist/cjs/src/pro/grvt.js +1 -1
  21. package/dist/cjs/src/pro/lighter.js +1 -1
  22. package/dist/cjs/src/whitebit.js +21 -2
  23. package/js/ccxt.d.ts +2 -8
  24. package/js/ccxt.js +2 -6
  25. package/js/src/abstract/blofin.d.ts +28 -12
  26. package/js/src/abstract/kraken.d.ts +36 -30
  27. package/js/src/abstract/kucoin.d.ts +1 -0
  28. package/js/src/abstract/kucoinfutures.d.ts +1 -0
  29. package/js/src/aftermath.js +1 -1
  30. package/js/src/backpack.js +1 -1
  31. package/js/src/base/Exchange.d.ts +1 -0
  32. package/js/src/base/Exchange.js +24 -0
  33. package/js/src/binance.js +12 -15
  34. package/js/src/bitfinex.js +6 -11
  35. package/js/src/bitget.d.ts +1 -1
  36. package/js/src/bitget.js +6 -3
  37. package/js/src/bitmex.d.ts +12 -0
  38. package/js/src/bitmex.js +46 -0
  39. package/js/src/bitstamp.js +14 -1
  40. package/js/src/bittrade.js +1 -1
  41. package/js/src/blofin.d.ts +2 -0
  42. package/js/src/blofin.js +137 -29
  43. package/js/src/hollaex.js +1 -1
  44. package/js/src/kraken.js +39 -31
  45. package/js/src/kucoin.d.ts +249 -8
  46. package/js/src/kucoin.js +2158 -461
  47. package/js/src/lighter.js +2 -2
  48. package/js/src/okx.js +0 -1
  49. package/js/src/pro/bittrade.js +4 -0
  50. package/js/src/pro/grvt.js +1 -1
  51. package/js/src/pro/lighter.js +1 -1
  52. package/js/src/whitebit.d.ts +1 -1
  53. package/js/src/whitebit.js +21 -2
  54. package/package.json +1 -1
  55. package/dist/cjs/src/abstract/coincatch.js +0 -11
  56. package/dist/cjs/src/coincatch.js +0 -5495
  57. package/dist/cjs/src/pro/coincatch.js +0 -1563
  58. package/js/src/abstract/coincatch.d.ts +0 -97
  59. package/js/src/abstract/coincatch.js +0 -5
  60. package/js/src/coincatch.d.ts +0 -788
  61. package/js/src/coincatch.js +0 -5488
  62. package/js/src/pro/coincatch.d.ts +0 -207
  63. package/js/src/pro/coincatch.js +0 -1556
@@ -47,10 +47,13 @@ class kucoin extends kucoin$1["default"] {
47
47
  'createMarketSellOrderWithCost': true,
48
48
  'createOrder': true,
49
49
  'createOrders': true,
50
+ 'createOrderWithTakeProfitAndStopLoss': true,
50
51
  'createPostOnlyOrder': true,
51
52
  'createStopLimitOrder': true,
53
+ 'createStopLossOrder': true,
52
54
  'createStopMarketOrder': true,
53
55
  'createStopOrder': true,
56
+ 'createTakeProfitOrder': true,
54
57
  'createTriggerOrder': true,
55
58
  'editOrder': true,
56
59
  'fetchAccounts': true,
@@ -89,8 +92,9 @@ class kucoin extends kucoin$1["default"] {
89
92
  'fetchMarkPrices': true,
90
93
  'fetchMyTrades': true,
91
94
  'fetchOHLCV': true,
92
- 'fetchOpenInterest': false,
93
- 'fetchOpenInterestHistory': false,
95
+ 'fetchOpenInterest': true,
96
+ 'fetchOpenInterestHistory': true,
97
+ 'fetchOpenInterests': true,
94
98
  'fetchOpenOrders': true,
95
99
  'fetchOrder': true,
96
100
  'fetchOrderBook': true,
@@ -99,7 +103,7 @@ class kucoin extends kucoin$1["default"] {
99
103
  'fetchOrderTrades': true,
100
104
  'fetchPosition': true,
101
105
  'fetchPositionADLRank': true,
102
- 'fetchPositionHistory': false,
106
+ 'fetchPositionHistory': true,
103
107
  'fetchPositionMode': true,
104
108
  'fetchPositions': true,
105
109
  'fetchPositionsADLRank': true,
@@ -567,6 +571,7 @@ class kucoin extends kucoin$1["default"] {
567
571
  '{accountMode}/order/execution': 8,
568
572
  '{accountMode}/position/open-list': 6,
569
573
  '{accountMode}/position/history': 4,
574
+ 'position/history': 4,
570
575
  '{accountMode}/position/tiers': 40,
571
576
  'sub-account/balance': 10,
572
577
  'user/fee-rate': 6,
@@ -631,6 +636,7 @@ class kucoin extends kucoin$1["default"] {
631
636
  '503': errors.ExchangeNotAvailable,
632
637
  '101030': errors.PermissionDenied,
633
638
  '103000': errors.InvalidOrder,
639
+ '112010': errors.PermissionDenied,
634
640
  '130101': errors.BadRequest,
635
641
  '130102': errors.ExchangeError,
636
642
  '130103': errors.OrderNotFound,
@@ -880,15 +886,14 @@ class kucoin extends kucoin$1["default"] {
880
886
  },
881
887
  'options': {
882
888
  'hf': undefined,
889
+ 'uta': undefined,
883
890
  'version': 'v1',
884
891
  'symbolSeparator': '-',
885
892
  'fetchMyTradesMethod': 'private_get_fills',
886
893
  'timeDifference': 0,
887
894
  'adjustForTimeDifference': false,
888
895
  'fetchCurrencies': {
889
- 'webApiEnable': true,
890
- 'webApiRetries': 1,
891
- 'webApiMuteFailure': true,
896
+ 'brokenCurrencies': ['00', 'OPEN_ERROR', 'HUF', 'BDT'], // skip buggy entries: https://t.me/KuCoin_API/217798
892
897
  },
893
898
  'fetchMarkets': {
894
899
  'types': ['spot', 'swap', 'future', 'contract'],
@@ -903,6 +908,13 @@ class kucoin extends kucoin$1["default"] {
903
908
  'fetchBalance': {
904
909
  'code': 'USDT', // for contract endpoint
905
910
  },
911
+ 'timeInForce': {
912
+ 'IOC': 'IOC',
913
+ 'FOK': 'FOK',
914
+ 'PO': 'PO',
915
+ 'GTD': 'GTT',
916
+ 'RPI': 'RPI',
917
+ },
906
918
  'timeframes': {
907
919
  'swap': {
908
920
  '1m': 1,
@@ -1066,12 +1078,32 @@ class kucoin extends kucoin$1["default"] {
1066
1078
  'mining': 'pool',
1067
1079
  'hf': 'trade_hf',
1068
1080
  'contract': 'contract',
1081
+ 'uta': 'unified',
1082
+ 'unified': 'unified',
1083
+ },
1084
+ 'utaAccountsByType': {
1085
+ 'trade': 'SPOT',
1086
+ 'spot': 'SPOT',
1087
+ 'margin': 'CROSS',
1088
+ 'cross': 'CROSS',
1089
+ 'isolated': 'ISOLATED',
1090
+ 'main': 'FUNDING',
1091
+ 'funding': 'FUNDING',
1092
+ 'future': 'FUTURES',
1093
+ 'swap': 'FUTURES',
1094
+ 'contract': 'FUTURES',
1095
+ 'uta': 'unified',
1096
+ 'unified': 'unified',
1069
1097
  },
1070
1098
  'networks': {
1099
+ 'BTC': 'btc',
1071
1100
  'BRC20': 'btc',
1072
1101
  'BTCNATIVESEGWIT': 'bech32',
1102
+ 'ETH': 'eth',
1073
1103
  'ERC20': 'eth',
1104
+ 'TRX': 'trx',
1074
1105
  'TRC20': 'trx',
1106
+ 'HECO': 'heco',
1075
1107
  'HRC20': 'heco',
1076
1108
  'MATIC': 'matic',
1077
1109
  'KCC': 'kcc',
@@ -1086,6 +1118,7 @@ class kucoin extends kucoin$1["default"] {
1086
1118
  'TLOS': 'tlos',
1087
1119
  'CFX': 'cfx',
1088
1120
  'ACA': 'aca',
1121
+ 'OP': 'optimism',
1089
1122
  'OPTIMISM': 'optimism',
1090
1123
  'ONT': 'ont',
1091
1124
  'GLMR': 'glmr',
@@ -1276,6 +1309,14 @@ class kucoin extends kucoin$1["default"] {
1276
1309
  // 'KLEVER': 'klv',
1277
1310
  // undetermined: xns(insolar), rhoc, luk (luniverse), kts (klimatas), bchn (bitcoin cash node), god (shallow entry), lit (litmus),
1278
1311
  },
1312
+ 'networksById': {
1313
+ 'btc': 'BTC',
1314
+ 'trx': 'TRC20',
1315
+ 'eth': 'ERC20',
1316
+ 'heco': 'HRC20',
1317
+ 'optimism': 'OP',
1318
+ 'op': 'OP',
1319
+ },
1279
1320
  'marginModes': {
1280
1321
  'cross': 'MARGIN_TRADE',
1281
1322
  'isolated': 'MARGIN_ISOLATED_TRADE',
@@ -1359,7 +1400,11 @@ class kucoin extends kucoin$1["default"] {
1359
1400
  'stopLossPrice': true,
1360
1401
  'takeProfitPrice': true,
1361
1402
  'attachedStopLossTakeProfit': {
1362
- 'triggerPriceType': undefined,
1403
+ 'triggerPriceType': {
1404
+ 'last': true,
1405
+ 'mark': true,
1406
+ 'index': true,
1407
+ },
1363
1408
  'price': true,
1364
1409
  },
1365
1410
  'timeInForce': {
@@ -1485,8 +1530,8 @@ class kucoin extends kucoin$1["default"] {
1485
1530
  * @returns {object} a [status structure]{@link https://docs.ccxt.com/?id=exchange-status-structure}
1486
1531
  */
1487
1532
  async fetchStatus(params = {}) {
1488
- let uta = undefined;
1489
- [uta, params] = this.handleOptionAndParams(params, 'fetchStatus', 'uta', false);
1533
+ let uta = false;
1534
+ [uta, params] = this.handleOptionAndParams(params, 'fetchStatus', 'uta', uta);
1490
1535
  let type = undefined;
1491
1536
  [type, params] = this.handleMarketTypeAndParams('fetchStatus', undefined, params);
1492
1537
  let response = undefined;
@@ -1557,8 +1602,8 @@ class kucoin extends kucoin$1["default"] {
1557
1602
  async fetchMarkets(params = {}) {
1558
1603
  let fetchTickersFees = undefined;
1559
1604
  [fetchTickersFees, params] = this.handleOptionAndParams(params, 'fetchMarkets', 'fetchTickersFees', true);
1560
- let uta = undefined;
1561
- [uta, params] = this.handleOptionAndParams(params, 'fetchMarkets', 'uta', false);
1605
+ let uta = false;
1606
+ [uta, params] = this.handleOptionAndParams(params, 'fetchMarkets', 'uta', uta);
1562
1607
  if (uta) {
1563
1608
  return await this.fetchUTAMarkets(params);
1564
1609
  }
@@ -2094,7 +2139,7 @@ class kucoin extends kucoin$1["default"] {
2094
2139
  'strike': undefined,
2095
2140
  'optionType': undefined,
2096
2141
  'precision': {
2097
- 'amount': this.safeNumber(market, 'lotSize'),
2142
+ 'amount': this.safeNumber2(market, 'lotSize', 'baseOrderStep'),
2098
2143
  'price': this.safeNumber(market, 'tickSize'),
2099
2144
  },
2100
2145
  'limits': {
@@ -2166,9 +2211,13 @@ class kucoin extends kucoin$1["default"] {
2166
2211
  */
2167
2212
  async fetchCurrencies(params = {}) {
2168
2213
  let uta = false;
2214
+ if (this.checkRequiredCredentials(false)) {
2215
+ uta = await this.isUTAEnabled();
2216
+ }
2169
2217
  [uta, params] = this.handleOptionAndParams(params, 'fetchCurrencies', 'uta', uta);
2170
2218
  let response = undefined;
2171
2219
  if (uta) {
2220
+ response = await this.utaGetAssetCurrencies(params);
2172
2221
  //
2173
2222
  // {
2174
2223
  // "code": "200000",
@@ -2203,7 +2252,6 @@ class kucoin extends kucoin$1["default"] {
2203
2252
  // ]
2204
2253
  // }
2205
2254
  //
2206
- response = await this.utaGetAssetCurrencies(params);
2207
2255
  }
2208
2256
  else {
2209
2257
  //
@@ -2246,64 +2294,61 @@ class kucoin extends kucoin$1["default"] {
2246
2294
  response = await this.publicGetCurrencies(params);
2247
2295
  }
2248
2296
  const currenciesData = this.safeList(response, 'data', []);
2249
- const brokenCurrencies = this.safeList(this.options, 'brokenCurrencies', ['00', 'OPEN_ERROR', 'HUF', 'BDT']);
2250
- const result = {};
2251
- for (let i = 0; i < currenciesData.length; i++) {
2252
- const entry = currenciesData[i];
2253
- const id = this.safeString(entry, 'currency');
2254
- if (this.inArray(id, brokenCurrencies)) {
2255
- continue; // skip buggy entries: https://t.me/KuCoin_API/217798
2256
- }
2257
- const code = this.safeCurrencyCode(id);
2258
- const networks = {};
2259
- const chains = this.safeList2(entry, 'chains', 'items', []);
2260
- const chainsLength = chains.length;
2261
- for (let j = 0; j < chainsLength; j++) {
2262
- const chain = chains[j];
2263
- const chainId = this.safeString(chain, 'chainId');
2264
- const networkCode = this.networkIdToCode(chainId, code);
2265
- networks[networkCode] = {
2266
- 'info': chain,
2267
- 'id': chainId,
2268
- 'name': this.safeString(chain, 'chainName'),
2269
- 'code': networkCode,
2270
- 'active': undefined,
2271
- 'fee': this.safeNumber2(chain, 'withdrawalMinFee', 'minWithdrawFee'),
2272
- 'deposit': this.safeBool(chain, 'isDepositEnabled'),
2273
- 'withdraw': this.safeBool(chain, 'isWithdrawEnabled'),
2274
- 'precision': this.parseNumber(this.parsePrecision(this.safeString(chain, 'withdrawPrecision'))),
2275
- 'limits': {
2276
- 'withdraw': {
2277
- 'min': this.safeNumber2(chain, 'withdrawalMinSize', 'minWithdrawSize'),
2278
- 'max': this.safeNumber2(chain, 'maxWithdraw', 'maxWithdrawSize'),
2279
- },
2280
- 'deposit': {
2281
- 'min': this.safeNumber2(chain, 'depositMinSize', 'minDepositSize'),
2282
- 'max': this.safeNumber2(chain, 'maxDeposit', 'maxDepositSize'),
2283
- },
2284
- },
2285
- };
2286
- }
2287
- // kucoin has determined 'fiat' currencies with below logic
2288
- const rawPrecision = this.safeString(entry, 'precision');
2289
- const precision = this.parseNumber(this.parsePrecision(rawPrecision));
2290
- const isFiat = chainsLength === 0;
2291
- result[code] = this.safeCurrencyStructure({
2292
- 'id': id,
2293
- 'name': this.safeString(entry, 'fullName'),
2294
- 'code': code,
2295
- 'type': isFiat ? 'fiat' : 'crypto',
2296
- 'precision': precision,
2297
- 'info': entry,
2298
- 'networks': networks,
2299
- 'deposit': undefined,
2300
- 'withdraw': undefined,
2297
+ const brokenCurrencies = this.handleOption('fetchCurrencies', 'brokenCurrencies', []);
2298
+ const filteredCurrencies = this.filterOutByArray(currenciesData, 'currency', brokenCurrencies); // remove broken entries
2299
+ return this.parseCurrencies(filteredCurrencies);
2300
+ }
2301
+ parseCurrency(currency) {
2302
+ const entry = currency;
2303
+ const id = this.safeString(entry, 'currency');
2304
+ const code = this.safeCurrencyCode(id);
2305
+ const networks = {};
2306
+ const chains = this.safeList2(entry, 'chains', 'items', []);
2307
+ const chainsLength = chains.length;
2308
+ for (let j = 0; j < chainsLength; j++) {
2309
+ const chain = chains[j];
2310
+ const chainId = this.safeString(chain, 'chainId');
2311
+ const networkCode = this.networkIdToCode(chainId, code);
2312
+ networks[networkCode] = {
2313
+ 'info': chain,
2314
+ 'id': chainId,
2315
+ 'name': this.safeString(chain, 'chainName'),
2316
+ 'code': networkCode,
2301
2317
  'active': undefined,
2302
- 'fee': undefined,
2303
- 'limits': undefined,
2304
- });
2318
+ 'fee': this.safeNumber2(chain, 'withdrawalMinFee', 'minWithdrawFee'),
2319
+ 'deposit': this.safeBool(chain, 'isDepositEnabled'),
2320
+ 'withdraw': this.safeBool(chain, 'isWithdrawEnabled'),
2321
+ 'precision': this.parseNumber(this.parsePrecision(this.safeString(chain, 'withdrawPrecision'))),
2322
+ 'limits': {
2323
+ 'withdraw': {
2324
+ 'min': this.safeNumber2(chain, 'withdrawalMinSize', 'minWithdrawSize'),
2325
+ 'max': this.safeNumber2(chain, 'maxWithdraw', 'maxWithdrawSize'),
2326
+ },
2327
+ 'deposit': {
2328
+ 'min': this.safeNumber2(chain, 'depositMinSize', 'minDepositSize'),
2329
+ 'max': this.safeNumber2(chain, 'maxDeposit', 'maxDepositSize'),
2330
+ },
2331
+ },
2332
+ };
2305
2333
  }
2306
- return result;
2334
+ // kucoin has determined 'fiat' currencies with below logic
2335
+ const rawPrecision = this.safeString(entry, 'precision');
2336
+ const precision = this.parseNumber(this.parsePrecision(rawPrecision));
2337
+ const isFiat = chainsLength === 0;
2338
+ return this.safeCurrencyStructure({
2339
+ 'id': id,
2340
+ 'name': this.safeString(entry, 'fullName'),
2341
+ 'code': code,
2342
+ 'type': isFiat ? 'fiat' : 'crypto',
2343
+ 'precision': precision,
2344
+ 'info': entry,
2345
+ 'networks': networks,
2346
+ 'deposit': undefined,
2347
+ 'withdraw': undefined,
2348
+ 'active': undefined,
2349
+ 'fee': undefined,
2350
+ 'limits': undefined,
2351
+ });
2307
2352
  }
2308
2353
  /**
2309
2354
  * @method
@@ -2311,41 +2356,68 @@ class kucoin extends kucoin$1["default"] {
2311
2356
  * @description fetch all the accounts associated with a profile
2312
2357
  * @see https://www.kucoin.com/docs-new/rest/account-info/account-funding/get-account-list-spot
2313
2358
  * @param {object} [params] extra parameters specific to the exchange API endpoint
2359
+ * @param {boolean} [params.uta] set to true for the unified trading account (uta), defaults to false
2314
2360
  * @returns {object} a dictionary of [account structures]{@link https://docs.ccxt.com/?id=account-structure} indexed by the account type
2315
2361
  */
2316
2362
  async fetchAccounts(params = {}) {
2317
- const response = await this.privateGetAccounts(params);
2318
- //
2319
- // {
2320
- // "code": "200000",
2321
- // "data": [
2322
- // {
2323
- // "balance": "0.00009788",
2324
- // "available": "0.00009788",
2325
- // "holds": "0",
2326
- // "currency": "BTC",
2327
- // "id": "5c6a4fd399a1d81c4f9cc4d0",
2328
- // "type": "trade"
2329
- // },
2330
- // {
2331
- // "balance": "0.00000001",
2332
- // "available": "0.00000001",
2333
- // "holds": "0",
2334
- // "currency": "ETH",
2335
- // "id": "5c6a49ec99a1d819392e8e9f",
2336
- // "type": "trade"
2337
- // }
2338
- // ]
2339
- // }
2340
- //
2341
- const data = this.safeList(response, 'data', []);
2363
+ let uta = await this.isUTAEnabled();
2364
+ [uta, params] = this.handleOptionAndParams(params, 'fetchAccounts', 'uta', uta);
2365
+ let response = undefined;
2366
+ let data = [];
2367
+ if (uta) {
2368
+ response = await this.utaPrivateGetAccountModeAccountOverview(this.extend(params, { 'accountMode': 'unified' }));
2369
+ //
2370
+ // {
2371
+ // "code": "200000",
2372
+ // "data": {
2373
+ // "accountType": "UNIFIED",
2374
+ // "riskRatio": "0.0000000000",
2375
+ // "equity": "30.0000000000",
2376
+ // "liability": "0.0000000000",
2377
+ // "availableMargin": "30.0000000000",
2378
+ // "adjustedEquity": "30.0000000000",
2379
+ // "im": "0.0000000000",
2380
+ // "mm": "0.0000000000"
2381
+ // }
2382
+ // }
2383
+ //
2384
+ const dataDict = this.safeDict(response, 'data', {});
2385
+ data = [dataDict];
2386
+ }
2387
+ else {
2388
+ //
2389
+ // {
2390
+ // "code": "200000",
2391
+ // "data": [
2392
+ // {
2393
+ // "balance": "0.00009788",
2394
+ // "available": "0.00009788",
2395
+ // "holds": "0",
2396
+ // "currency": "BTC",
2397
+ // "id": "5c6a4fd399a1d81c4f9cc4d0",
2398
+ // "type": "trade"
2399
+ // },
2400
+ // {
2401
+ // "balance": "0.00000001",
2402
+ // "available": "0.00000001",
2403
+ // "holds": "0",
2404
+ // "currency": "ETH",
2405
+ // "id": "5c6a49ec99a1d819392e8e9f",
2406
+ // "type": "trade"
2407
+ // }
2408
+ // ]
2409
+ // }
2410
+ //
2411
+ response = await this.privateGetAccounts(params);
2412
+ data = this.safeList(response, 'data', []);
2413
+ }
2342
2414
  const result = [];
2343
2415
  for (let i = 0; i < data.length; i++) {
2344
2416
  const account = data[i];
2345
2417
  const accountId = this.safeString(account, 'id');
2346
2418
  const currencyId = this.safeString(account, 'currency');
2347
2419
  const code = this.safeCurrencyCode(currencyId);
2348
- const type = this.safeString(account, 'type'); // main or trade
2420
+ const type = this.safeStringLower2(account, 'type', 'accountType'); // main or trade or unified
2349
2421
  result.push({
2350
2422
  'id': accountId,
2351
2423
  'type': type,
@@ -2374,7 +2446,7 @@ class kucoin extends kucoin$1["default"] {
2374
2446
  let networkCode = undefined;
2375
2447
  [networkCode, params] = this.handleNetworkCodeAndParams(params);
2376
2448
  if (networkCode !== undefined) {
2377
- request['chain'] = this.networkCodeToId(networkCode).toLowerCase();
2449
+ request['chain'] = this.networkCodeToId(networkCode, currency['code']).toLowerCase();
2378
2450
  }
2379
2451
  const response = await this.privateGetWithdrawalsQuotas(this.extend(request, params));
2380
2452
  const data = this.safeDict(response, 'data', {});
@@ -2405,7 +2477,7 @@ class kucoin extends kucoin$1["default"] {
2405
2477
  let networkCode = undefined;
2406
2478
  [networkCode, params] = this.handleNetworkCodeAndParams(params);
2407
2479
  if (networkCode !== undefined) {
2408
- request['chain'] = this.networkCodeToId(networkCode).toLowerCase();
2480
+ request['chain'] = this.networkCodeToId(networkCode, currency['code']).toLowerCase();
2409
2481
  }
2410
2482
  const response = await this.privateGetWithdrawalsQuotas(this.extend(request, params));
2411
2483
  //
@@ -2462,7 +2534,8 @@ class kucoin extends kucoin$1["default"] {
2462
2534
  const chains = this.safeList(fee, 'chains', []);
2463
2535
  for (let i = 0; i < chains.length; i++) {
2464
2536
  const chain = chains[i];
2465
- const networkCodeNew = this.networkIdToCode(this.safeString(chain, 'chainId'), this.safeString(currency, 'code'));
2537
+ const chainId = this.safeString(chain, 'chainId');
2538
+ const networkCodeNew = this.networkIdToCode(chainId, this.safeString(currency, 'code'));
2466
2539
  resultNew['networks'][networkCodeNew] = {
2467
2540
  'withdraw': {
2468
2541
  'fee': this.safeNumber2(chain, 'withdrawalMinFee', 'withdrawMinFee'),
@@ -2490,7 +2563,9 @@ class kucoin extends kucoin$1["default"] {
2490
2563
  'networks': {},
2491
2564
  };
2492
2565
  const networkId = this.safeString(fee, 'chain');
2493
- const networkCode = this.networkIdToCode(networkId, this.safeString(currency, 'code'));
2566
+ const currencyId = this.safeString(fee, 'currency');
2567
+ currency = this.safeCurrency(currencyId, currency);
2568
+ const networkCode = this.networkIdToCode(networkId, currency['code']);
2494
2569
  result['networks'][networkCode] = {
2495
2570
  'withdraw': minWithdrawFee,
2496
2571
  'deposit': {
@@ -2775,8 +2850,8 @@ class kucoin extends kucoin$1["default"] {
2775
2850
  await this.loadMarkets();
2776
2851
  const request = {};
2777
2852
  symbols = this.marketSymbols(symbols, undefined, true, true);
2778
- let uta = undefined;
2779
- [uta, params] = this.handleOptionAndParams(params, 'fetchTickers', 'uta', false);
2853
+ let uta = false;
2854
+ [uta, params] = this.handleOptionAndParams(params, 'fetchTickers', 'uta', uta);
2780
2855
  const tradeType = this.safeString(params, 'tradeType');
2781
2856
  let firstMarket = undefined;
2782
2857
  if (symbols !== undefined) {
@@ -2976,8 +3051,8 @@ class kucoin extends kucoin$1["default"] {
2976
3051
  const request = {
2977
3052
  'symbol': market['id'],
2978
3053
  };
2979
- let uta = undefined;
2980
- [uta, params] = this.handleOptionAndParams(params, 'fetchTicker', 'uta', false);
3054
+ let uta = false;
3055
+ [uta, params] = this.handleOptionAndParams(params, 'fetchTicker', 'uta', uta);
2981
3056
  let response = undefined;
2982
3057
  let result = undefined;
2983
3058
  let type = undefined;
@@ -3150,8 +3225,8 @@ class kucoin extends kucoin$1["default"] {
3150
3225
  async fetchOHLCV(symbol, timeframe = '1m', since = undefined, limit = undefined, params = {}) {
3151
3226
  await this.loadMarkets();
3152
3227
  const market = this.market(symbol);
3153
- let uta = undefined;
3154
- [uta, params] = this.handleOptionAndParams(params, 'fetchOHLCV', 'uta', false);
3228
+ let uta = false;
3229
+ [uta, params] = this.handleOptionAndParams(params, 'fetchOHLCV', 'uta', uta);
3155
3230
  if (uta) {
3156
3231
  return await this.fetchUTAOHLCV(symbol, timeframe, since, limit, params);
3157
3232
  }
@@ -3372,7 +3447,7 @@ class kucoin extends kucoin$1["default"] {
3372
3447
  let networkCode = undefined;
3373
3448
  [networkCode, params] = this.handleNetworkCodeAndParams(params);
3374
3449
  if (networkCode !== undefined) {
3375
- request['chain'] = this.networkCodeToId(networkCode); // docs mention "chain-name", but seems "chain-id" is used, like in "fetchDepositAddress"
3450
+ request['chain'] = this.networkCodeToId(networkCode, currency['code']); // docs mention "chain-name", but seems "chain-id" is used, like in "fetchDepositAddress"
3376
3451
  }
3377
3452
  const response = await this.privatePostDepositAddressCreate(this.extend(request, params));
3378
3453
  // {"code":"260000","msg":"Deposit address already exists."}
@@ -3398,10 +3473,12 @@ class kucoin extends kucoin$1["default"] {
3398
3473
  * @name kucoin#fetchDepositAddress
3399
3474
  * @description fetch the deposit address for a currency associated with this account
3400
3475
  * @see https://www.kucoin.com/docs-new/rest/account-info/deposit/get-deposit-address-v3/en
3476
+ * @see https://www.kucoin.com/docs-new/rest/ua/get-deposit-address
3401
3477
  * @param {string} code unified currency code
3402
3478
  * @param {object} [params] extra parameters specific to the exchange API endpoint
3403
3479
  * @param {string} [params.network] the blockchain network name
3404
- * @param {string} [params.accountType] 'main' or 'contract' (default is 'main')
3480
+ * @param {string} [params.accountType] 'main', 'contract' or 'uta' (default is 'main')
3481
+ * @param {boolean} [params.uta] set to true for the unified trading account (uta) endpoint, defaults to false
3405
3482
  * @returns {object} an [address structure]{@link https://docs.ccxt.com/?id=address-structure}
3406
3483
  */
3407
3484
  async fetchDepositAddress(code, params = {}) {
@@ -3410,9 +3487,14 @@ class kucoin extends kucoin$1["default"] {
3410
3487
  [accountType, params] = this.handleOptionAndParams(params, 'fetchDepositAddress', 'accountType', accountType);
3411
3488
  const accountsByType = this.safeDict(this.options, 'accountsByType', {});
3412
3489
  accountType = this.safeString(accountsByType, accountType, accountType);
3490
+ let uta = await this.isUTAEnabled();
3491
+ [uta, params] = this.handleOptionAndParams(params, 'fetchDepositAddress', 'uta', uta);
3413
3492
  if (accountType === 'contract') {
3414
3493
  return await this.fetchContractDepositAddress(code, params);
3415
3494
  }
3495
+ else if (uta || (accountType === 'uta') || (accountType === 'unified')) {
3496
+ return await super.fetchDepositAddress(code, this.extend(params, { 'uta': true }));
3497
+ }
3416
3498
  const currency = this.currency(code);
3417
3499
  const request = {
3418
3500
  'currency': currency['id'],
@@ -3423,7 +3505,7 @@ class kucoin extends kucoin$1["default"] {
3423
3505
  let networkCode = undefined;
3424
3506
  [networkCode, params] = this.handleNetworkCodeAndParams(params);
3425
3507
  if (networkCode !== undefined) {
3426
- request['chain'] = this.networkCodeToId(networkCode).toLowerCase();
3508
+ request['chain'] = this.networkCodeToId(networkCode, currency['code']).toLowerCase();
3427
3509
  }
3428
3510
  const version = this.options['versions']['private']['GET']['deposit-addresses'];
3429
3511
  this.options['versions']['private']['GET']['deposit-addresses'] = 'v1';
@@ -3491,10 +3573,11 @@ class kucoin extends kucoin$1["default"] {
3491
3573
  this.checkAddress(address);
3492
3574
  }
3493
3575
  }
3576
+ const chainId = this.safeString(depositAddress, 'chainId');
3494
3577
  return {
3495
3578
  'info': depositAddress,
3496
3579
  'currency': code,
3497
- 'network': this.networkIdToCode(this.safeString(depositAddress, 'chainId')),
3580
+ 'network': this.networkIdToCode(chainId, code),
3498
3581
  'address': address,
3499
3582
  'tag': this.safeString(depositAddress, 'memo'),
3500
3583
  };
@@ -3503,9 +3586,11 @@ class kucoin extends kucoin$1["default"] {
3503
3586
  * @method
3504
3587
  * @name kucoin#fetchDepositAddressesByNetwork
3505
3588
  * @see https://www.kucoin.com/docs-new/rest/account-info/deposit/get-deposit-address-v3/en
3589
+ * @see https://www.kucoin.com/docs-new/rest/ua/get-deposit-address
3506
3590
  * @description fetch the deposit address for a currency associated with this account
3507
3591
  * @param {string} code unified currency code
3508
3592
  * @param {object} [params] extra parameters specific to the exchange API endpoint
3593
+ * @param {boolean} [params.uta] set to true for the unified trading account (uta) endpoint, defaults to false
3509
3594
  * @returns {object} an array of [address structures]{@link https://docs.ccxt.com/?id=address-structure}
3510
3595
  */
3511
3596
  async fetchDepositAddressesByNetwork(code, params = {}) {
@@ -3514,25 +3599,56 @@ class kucoin extends kucoin$1["default"] {
3514
3599
  const request = {
3515
3600
  'currency': currency['id'],
3516
3601
  };
3517
- const version = this.options['versions']['private']['GET']['deposit-addresses'];
3518
- this.options['versions']['private']['GET']['deposit-addresses'] = 'v2';
3519
- const response = await this.privateGetDepositAddresses(this.extend(request, params));
3520
- //
3521
- // {
3522
- // "code": "200000",
3523
- // "data": [
3524
- // {
3525
- // "address": "fr1qvus7d4d5fgxj5e7zvqe6yhxd7txm95h2and69r",
3526
- // "memo": "",
3527
- // "chain": "BTC-Segwit",
3528
- // "contractAddress": ""
3529
- // },
3530
- // {"address":"37icNMEWbiF8ZkwUMxmfzMxi2A1MQ44bMn","memo":"","chain":"BTC","contractAddress":""},
3531
- // {"address":"Deposit temporarily blocked","memo":"","chain":"TRC20","contractAddress":""}
3532
- // ]
3533
- // }
3534
- //
3535
- this.options['versions']['private']['GET']['deposit-addresses'] = version;
3602
+ let uta = await this.isUTAEnabled();
3603
+ [uta, params] = this.handleOptionAndParams(params, 'fetchDepositAddressesByNetwork', 'uta', uta);
3604
+ let response = undefined;
3605
+ if (uta) {
3606
+ let networkCode = undefined;
3607
+ [networkCode, params] = this.handleNetworkCodeAndParams(params);
3608
+ if (networkCode !== undefined) {
3609
+ request['chain'] = this.networkCodeToId(networkCode).toLowerCase();
3610
+ }
3611
+ //
3612
+ // {
3613
+ // "code": "200000",
3614
+ // "data": [
3615
+ // {
3616
+ // "address": "0xf30a9b6968183668dbce515bd6449438ab3252b3",
3617
+ // "memo": "",
3618
+ // "remark": "",
3619
+ // "chainId": "eth",
3620
+ // "to": "FUNDING",
3621
+ // "expirationDate": 0,
3622
+ // "currency": "USDT",
3623
+ // "contractAddress": "0xdac17f958d2ee523a2206206994597c13d831ec7",
3624
+ // "chainName": "ERC20"
3625
+ // }
3626
+ // ]
3627
+ // }
3628
+ //
3629
+ response = await this.utaPrivateGetAssetDepositAddress(this.extend(request, params));
3630
+ }
3631
+ else {
3632
+ const version = this.options['versions']['private']['GET']['deposit-addresses'];
3633
+ this.options['versions']['private']['GET']['deposit-addresses'] = 'v2';
3634
+ response = await this.privateGetDepositAddresses(this.extend(request, params));
3635
+ //
3636
+ // {
3637
+ // "code": "200000",
3638
+ // "data": [
3639
+ // {
3640
+ // "address": "fr1qvus7d4d5fgxj5e7zvqe6yhxd7txm95h2and69r",
3641
+ // "memo": "",
3642
+ // "chain": "BTC-Segwit",
3643
+ // "contractAddress": ""
3644
+ // },
3645
+ // {"address":"37icNMEWbiF8ZkwUMxmfzMxi2A1MQ44bMn","memo":"","chain":"BTC","contractAddress":""},
3646
+ // {"address":"Deposit temporarily blocked","memo":"","chain":"TRC20","contractAddress":""}
3647
+ // ]
3648
+ // }
3649
+ //
3650
+ this.options['versions']['private']['GET']['deposit-addresses'] = version;
3651
+ }
3536
3652
  const chains = this.safeList(response, 'data', []);
3537
3653
  const parsed = this.parseDepositAddresses(chains, [currency['code']], false, {
3538
3654
  'currency': currency['code'],
@@ -3559,8 +3675,8 @@ class kucoin extends kucoin$1["default"] {
3559
3675
  const level = this.safeInteger(params, 'level', 2);
3560
3676
  const request = { 'symbol': market['id'] };
3561
3677
  const isAuthenticated = this.checkRequiredCredentials(false);
3562
- let uta = undefined;
3563
- [uta, params] = this.handleOptionAndParams(params, 'fetchOrderBook', 'uta', false);
3678
+ let uta = false;
3679
+ [uta, params] = this.handleOptionAndParams(params, 'fetchOrderBook', 'uta', uta);
3564
3680
  let response = undefined;
3565
3681
  let type = undefined;
3566
3682
  [type, params] = this.handleMarketTypeAndParams('fetchOrderBook', market, params);
@@ -3714,19 +3830,26 @@ class kucoin extends kucoin$1["default"] {
3714
3830
  * @see https://www.kucoin.com/docs-new/rest/futures-trading/orders/add-order
3715
3831
  * @see https://www.kucoin.com/docs-new/rest/futures-trading/orders/add-order-test
3716
3832
  * @see https://www.kucoin.com/docs-new/rest/futures-trading/orders/add-take-profit-and-stop-loss-order
3833
+ * @see https://www.kucoin.com/docs-new/rest/ua/place-order
3717
3834
  * @param {string} symbol Unified CCXT market symbol
3718
3835
  * @param {string} type 'limit' or 'market'
3719
3836
  * @param {string} side 'buy' or 'sell'
3720
3837
  * @param {float} amount the amount of currency to trade
3721
3838
  * @param {float} [price] the price at which the order is to be fulfilled, in units of the quote currency, ignored in market orders
3722
3839
  * @param {object} [params] extra parameters specific to the exchange API endpoint
3723
- * Check createSpotOrder() and createContractOrder() for more details on the extra parameters that can be used in params
3840
+ * @param {boolean} [params.uta] set to true for the unified trading account (uta) endpoint, defaults to false
3841
+ * Check createSpotOrder(), createContractOrder() and createUtaOrder () for more details on the extra parameters that can be used in params
3724
3842
  * @returns {object} an [order structure]{@link https://docs.ccxt.com/?id=order-structure}
3725
3843
  */
3726
3844
  async createOrder(symbol, type, side, amount, price = undefined, params = {}) {
3727
3845
  await this.loadMarkets();
3728
3846
  const market = this.market(symbol);
3729
- if (market['spot']) {
3847
+ let uta = await this.isUTAEnabled();
3848
+ [uta, params] = this.handleOptionAndParams(params, 'createOrder', 'uta', uta);
3849
+ if (uta) {
3850
+ return await this.createUtaOrder(symbol, type, side, amount, price, params);
3851
+ }
3852
+ else if (market['spot']) {
3730
3853
  return await this.createSpotOrder(symbol, type, side, amount, price, params);
3731
3854
  }
3732
3855
  else if (market['contract']) {
@@ -3756,7 +3879,7 @@ class kucoin extends kucoin$1["default"] {
3756
3879
  * @param {float} [params.triggerPrice] The price at which a trigger order is triggered at
3757
3880
  * @param {string} [params.marginMode] 'cross', // cross (cross mode) and isolated (isolated mode), set to cross by default, the isolated mode will be released soon, stay tuned
3758
3881
  * @param {string} [params.timeInForce] GTC, GTT, IOC, or FOK, default is GTC, limit orders only
3759
- * @param {string} [params.postOnly] Post only flag, invalid when timeInForce is IOC or FOK
3882
+ * @param {bool} [params.postOnly] Post only flag, invalid when timeInForce is IOC or FOK
3760
3883
  *
3761
3884
  * EXCHANGE SPECIFIC PARAMETERS
3762
3885
  * @param {string} [params.clientOid] client order id, defaults to uuid if not passed
@@ -3949,7 +4072,7 @@ class kucoin extends kucoin$1["default"] {
3949
4072
  * @param {float} [params.takeProfitPrice] price to trigger take-profit orders
3950
4073
  * @param {bool} [params.reduceOnly] A mark to reduce the position size only. Set to false by default. Need to set the position size when reduceOnly is true.
3951
4074
  * @param {string} [params.timeInForce] GTC, GTT, IOC, or FOK, default is GTC, limit orders only
3952
- * @param {string} [params.postOnly] Post only flag, invalid when timeInForce is IOC or FOK
4075
+ * @param {bool} [params.postOnly] Post only flag, invalid when timeInForce is IOC or FOK
3953
4076
  * @param {float} [params.cost] the cost of the order in units of USDT
3954
4077
  * @param {string} [params.marginMode] 'cross' or 'isolated', default is 'isolated'
3955
4078
  * @param {bool} [params.hedged] *swap and future only* true for hedged mode, false for one way mode, default is false
@@ -4119,6 +4242,223 @@ class kucoin extends kucoin$1["default"] {
4119
4242
  params = this.omit(params, ['timeInForce', 'stopPrice', 'triggerPrice', 'stopLossPrice', 'takeProfitPrice', 'reduceOnly', 'hedged']); // Time in force only valid for limit orders, exchange error when gtc for market orders
4120
4243
  return this.extend(request, params);
4121
4244
  }
4245
+ /**
4246
+ * @method
4247
+ * @name kucoin#createUtaOrder
4248
+ * @description helper method for creating uta orders
4249
+ * @see https://www.kucoin.com/docs-new/rest/ua/place-order
4250
+ * @param {string} symbol Unified CCXT market symbol
4251
+ * @param {string} type 'limit' or 'market'
4252
+ * @param {string} side 'buy' or 'sell'
4253
+ * @param {float} amount the amount of currency to trade
4254
+ * @param {float} [price] the price at which the order is to be fulfilled, in units of the quote currency, ignored in market orders
4255
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
4256
+ * @param {string} [params.clientOrderId] client order id, defaults to uuid if not passed
4257
+ * @param {float} [params.cost] the cost of the order in units of quote currency
4258
+ * @param {string} [params.timeInForce] GTC, GTD, IOC, FOK or PO
4259
+ * @param {bool} [params.postOnly] Post only flag, invalid when timeInForce is IOC or FOK (default is false)
4260
+ * @param {bool} [params.reduceOnly] *contract markets only* A mark to reduce the position size only. Set to false by default
4261
+ * @param {float} [params.triggerPrice] The price a trigger order is triggered at
4262
+ * @param {string} [params.triggerDirection] 'ascending' or 'descending', the direction the triggerPrice is triggered from, requires triggerPrice
4263
+ * @param {string} [params.triggerPriceType] *contract markets only* "last", "mark", "index" - defaults to "mark"
4264
+ * @param {float} [params.stopLossPrice] price to trigger stop-loss orders
4265
+ * @param {float} [params.takeProfitPrice] price to trigger take-profit orders
4266
+ * @param {string} [params.marginMode] 'cross' or 'isolated', (default is 'cross' for margin orders, default is 'isolated' for contract orders)
4267
+ *
4268
+ * Exchange-specific parameters -------------------------------------------------
4269
+ * @param {string} [params.accountMode] 'unified' or 'classic', default is 'unified'
4270
+ * @param {string} [params.stp] '', // self trade prevention, CN, CO, CB or DC
4271
+ * @param {int} [params.cancelAfter] - Cancel After N Seconds (Calculated from the time of entering the matching engine), only effective when timeInForce is GTD
4272
+ * @param {string} [params.sizeUnit] *contracts only* 'BASECCY' (amount of base currency) or 'UNIT' (number of contracts), default is 'UNIT'
4273
+ *
4274
+ * Classic account parameters
4275
+ * @param {bool} [params.autoBorrow] *classic margin orders only*
4276
+ * @param {bool} [params.autoRepay] *classic margin orders only*
4277
+ * @param {string} [params.hedged] *classic contract orders only* true for hedged mode, false for one way mode, default is false
4278
+ * @param {int} [params.leverage] *classic contract orders with isolated marginMode only* Leverage size of the order
4279
+ * @returns {object} an [order structure]{@link https://docs.ccxt.com/?id=order-structure}
4280
+ */
4281
+ async createUtaOrder(symbol, type, side, amount, price = undefined, params = {}) {
4282
+ await this.loadMarkets();
4283
+ const request = this.createUtaOrderRequest(symbol, type, side, amount, price, params);
4284
+ const response = await this.utaPrivatePostAccountModeOrderPlace(request);
4285
+ //
4286
+ // {
4287
+ // "code": "200000",
4288
+ // "data": {
4289
+ // "orderId": "426319129738321920",
4290
+ // "tradeType": "SPOT",
4291
+ // "ts": 1774455603216000000,
4292
+ // "clientOid": "b896c118-a674-4863-baf4-a9ea3cd696c5"
4293
+ // }
4294
+ // }
4295
+ //
4296
+ const data = this.safeDict(response, 'data', {});
4297
+ return this.parseOrder(data);
4298
+ }
4299
+ createUtaOrderRequest(symbol, type, side, amount, price = undefined, params = {}) {
4300
+ const market = this.market(symbol);
4301
+ const isSpot = market['spot'];
4302
+ const isContract = market['contract'];
4303
+ let accountMode = 'unified';
4304
+ [accountMode, params] = this.handleOptionAndParams(params, 'createOrder', 'accountMode', accountMode);
4305
+ const isUnified = (accountMode === 'unified');
4306
+ let marginMode = undefined;
4307
+ [marginMode, params] = this.handleMarginModeAndParams('createOrder', params);
4308
+ const marginModeDefined = (marginMode !== undefined);
4309
+ const isSpotMargin = (isSpot && marginModeDefined);
4310
+ if (isSpotMargin && isUnified) {
4311
+ throw new errors.NotSupported(this.id + ' createOrder() does not support spot margin orders with unified accountMode');
4312
+ }
4313
+ const tradeType = this.handleTradeType(isContract, marginMode, params);
4314
+ const clientOrderId = this.safeString2(params, 'clientOid', 'clientOrderId', this.uuid());
4315
+ params = this.omit(params, ['clientOid', 'clientOrderId']);
4316
+ const request = {
4317
+ 'accountMode': accountMode,
4318
+ 'tradeType': tradeType,
4319
+ 'clientOid': clientOrderId,
4320
+ 'symbol': market['id'],
4321
+ // 'triggerDirection'- 'UP' or 'DOWN (required for trigger orders, supported for classic-FUTURES and unified-SPOT and unified-FUTURES)
4322
+ // 'triggerPriceType' - 'TP', 'IP', 'MP' (required for trigger orders, supported for classic-FUTURES and unified-SPOT and unified-FUTURES)
4323
+ // 'triggerPrice' (required for trigger orders)
4324
+ 'side': side.toUpperCase(),
4325
+ 'orderType': type.toUpperCase(),
4326
+ // 'size'
4327
+ // 'sizeUnit' - 'BASECCY', 'QUOTECCY' (for market SPOT) or 'UNIT' (for unified-FUTURES)
4328
+ // 'price'
4329
+ // 'timeInForce' - 'GTC', 'IOC', 'FOK', 'GTT' or 'RPI' (GTT is not supported for FUTURES)
4330
+ // 'postOnly'
4331
+ // 'reduceOnly' (only for FUTURES)
4332
+ // 'stp' - 'CN', 'CO', 'CB' or 'DC' (DC is not supported for FUTURES)
4333
+ // 'cancelAfter' - time in seconds (only valid when timeInForce is GTT, not supported for FUTURES)
4334
+ // 'tags'
4335
+ // 'autoBorrow' (only for classic-CROSS and classic-ISOLATED)
4336
+ // 'autoRepay' (only for classic-CROSS and classic-ISOLATED)
4337
+ // 'positionSide' - 'BOTH', 'LONG' or 'SHORT' (only for classic-FUTURES)
4338
+ // 'marginMode' - 'ISOLATED' or 'CROSS' (only for classic-FUTURES, default is 'ISOLATED')
4339
+ // 'leverage' (only for classic-FUTURES-ISOLATED, required)
4340
+ // 'tpTriggerPriceType' - 'TP', 'IP', 'MP' (only for unified-FUTURES and classic-FUTURES)
4341
+ // 'tpTriggerPrice' (only for unified-FUTURES and classic-FUTURES)
4342
+ // 'slTriggerPriceType' - 'TP', 'IP', 'MP' (only for unified-FUTURES and classic-FUTURES)
4343
+ // 'slTriggerPrice' (only for unified-FUTURES and classic-FUTURES)
4344
+ };
4345
+ if (tradeType !== undefined) {
4346
+ request['tradeType'] = tradeType;
4347
+ }
4348
+ request['clientOid'] = clientOrderId;
4349
+ const isMarketOrder = (type === 'market');
4350
+ const cost = this.safeString(params, 'cost');
4351
+ if (cost !== undefined) {
4352
+ params = this.omit(params, 'cost');
4353
+ if (isSpot && isMarketOrder) {
4354
+ request['sizeUnit'] = 'QUOTECCY';
4355
+ request['size'] = this.marketOrderAmountToPrecision(symbol, cost);
4356
+ }
4357
+ else {
4358
+ throw new errors.NotSupported(this.id + ' createOrder() with cost is supported for spot market orders only');
4359
+ }
4360
+ }
4361
+ else {
4362
+ let sizeUnit = 'BASECCY';
4363
+ if (isContract) {
4364
+ [sizeUnit, params] = this.handleOptionAndParams(params, 'createOrder', 'sizeUnit', 'UNIT');
4365
+ }
4366
+ request['sizeUnit'] = sizeUnit;
4367
+ request['size'] = this.amountToPrecision(symbol, amount);
4368
+ }
4369
+ if (!isMarketOrder) {
4370
+ request['price'] = this.priceToPrecision(symbol, price);
4371
+ }
4372
+ let postOnly = undefined;
4373
+ [postOnly, params] = this.handlePostOnly(isMarketOrder, false, params);
4374
+ const timeInForce = this.handleTimeInForce(params);
4375
+ if ((timeInForce !== undefined)) {
4376
+ params = this.omit(params, 'timeInForce');
4377
+ request['timeInForce'] = timeInForce;
4378
+ }
4379
+ if (postOnly) {
4380
+ request['postOnly'] = true;
4381
+ }
4382
+ if (isContract) {
4383
+ if (!isUnified) {
4384
+ if (marginModeDefined) {
4385
+ request['marginMode'] = marginMode.toUpperCase();
4386
+ if (marginMode === 'isolated') {
4387
+ const leverage = this.safeInteger(params, 'leverage');
4388
+ if (leverage === undefined) {
4389
+ request['leverage'] = 1;
4390
+ }
4391
+ }
4392
+ }
4393
+ const reduceOnly = this.safeBool(params, 'reduceOnly', false);
4394
+ let hedged = false;
4395
+ [hedged, params] = this.handleParamBool(params, 'hedged', hedged);
4396
+ if (hedged) {
4397
+ let positionSide = (side === 'buy') ? 'LONG' : 'SHORT';
4398
+ if (reduceOnly) {
4399
+ positionSide = (positionSide === 'LONG') ? 'SHORT' : 'LONG';
4400
+ }
4401
+ request['positionSide'] = positionSide;
4402
+ }
4403
+ }
4404
+ }
4405
+ // handling with coinditional orders
4406
+ const [triggerPrice, stopLossPrice, takeProfitPrice] = this.handleTriggerPrices(params);
4407
+ const stopLoss = this.safeDict(params, 'stopLoss');
4408
+ const takeProfit = this.safeDict(params, 'takeProfit');
4409
+ const hasStopLoss = stopLoss !== undefined;
4410
+ const hasTakeProfit = takeProfit !== undefined;
4411
+ const triggerPriceTypes = {
4412
+ 'mark': 'MP',
4413
+ 'last': 'TP',
4414
+ 'index': 'IP',
4415
+ };
4416
+ if (triggerPrice) {
4417
+ const triggerDirection = this.safeString(params, 'triggerDirection');
4418
+ if (triggerDirection === undefined) {
4419
+ throw new errors.ArgumentsRequired(this.id + ' createOrder() requires a triggerDirection parameter for trigger orders. Provide params.tringgerDirection or use params.stopLossPrice or params.takeProfitPrice instead of params.triggerPrice');
4420
+ }
4421
+ request['triggerDirection'] = (triggerDirection === 'ascending') ? 'UP' : 'DOWN';
4422
+ request['triggerPrice'] = this.priceToPrecision(symbol, triggerPrice);
4423
+ }
4424
+ else if (hasStopLoss || hasTakeProfit) {
4425
+ if (!isContract) {
4426
+ throw new errors.NotSupported(this.id + ' createOrder() stopLoss and takeProfit parameters are only supported for contract orders');
4427
+ }
4428
+ if (hasStopLoss) {
4429
+ const slTriggerPrice = this.safeString2(stopLoss, 'triggerPrice', 'stopPrice');
4430
+ const slTriggerPriceType = this.safeString(stopLoss, 'triggerPriceType', 'mark');
4431
+ request['slTriggerPrice'] = this.priceToPrecision(symbol, slTriggerPrice);
4432
+ request['slTriggerPriceType'] = this.safeString(triggerPriceTypes, slTriggerPriceType, slTriggerPriceType);
4433
+ }
4434
+ if (hasTakeProfit) {
4435
+ const tpTriggerPrice = this.safeString2(takeProfit, 'triggerPrice', 'takeProfitPrice');
4436
+ const tpTriggerPriceType = this.safeString(takeProfit, 'triggerPriceType', 'mark');
4437
+ request['tpTriggerPrice'] = this.priceToPrecision(symbol, tpTriggerPrice);
4438
+ request['tpTriggerPriceType'] = this.safeString(triggerPriceTypes, tpTriggerPriceType, tpTriggerPriceType);
4439
+ }
4440
+ }
4441
+ else if (stopLossPrice || takeProfitPrice) {
4442
+ if (stopLossPrice) {
4443
+ request['triggerDirection'] = (side === 'buy') ? 'UP' : 'DOWN';
4444
+ request['triggerPrice'] = this.priceToPrecision(symbol, stopLossPrice);
4445
+ if (isContract) {
4446
+ const stopLossPriceType = this.safeString2(params, 'stopLossPriceType', 'triggerPriceType', 'mark');
4447
+ request['triggerPriceType'] = this.safeString(triggerPriceTypes, stopLossPriceType, stopLossPriceType);
4448
+ }
4449
+ }
4450
+ else {
4451
+ request['triggerDirection'] = (side === 'buy') ? 'DOWN' : 'UP';
4452
+ request['triggerPrice'] = this.priceToPrecision(symbol, takeProfitPrice);
4453
+ if (isContract) {
4454
+ const takeProfitPriceType = this.safeString2(params, 'takeProfitPriceType', 'triggerPriceType', 'mark');
4455
+ request['triggerPriceType'] = this.safeString(triggerPriceTypes, takeProfitPriceType, takeProfitPriceType);
4456
+ }
4457
+ }
4458
+ }
4459
+ params = this.omit(params, ['triggerPrice', 'stopLossPrice', 'takeProfitPrice', 'stopPriceType', 'stopLossPriceType', 'takeProfitPriceType', 'triggerPriceType', 'triggerDirection', 'stopLoss', 'takeProfit', 'hedged']);
4460
+ return this.extend(request, params);
4461
+ }
4122
4462
  /**
4123
4463
  * @method
4124
4464
  * @name kucoin#createMarketOrderWithCost
@@ -4410,16 +4750,23 @@ class kucoin extends kucoin$1["default"] {
4410
4750
  * @see https://www.kucoin.com/docs-new/rest/margin-trading/orders/cancel-stop-order-by-clientoid
4411
4751
  * @see https://www.kucoin.com/docs-new/rest/futures-trading/orders/cancel-order-by-orderld
4412
4752
  * @see https://www.kucoin.com/docs-new/rest/futures-trading/orders/cancel-order-by-clientoid
4753
+ * @see https://www.kucoin.com/docs-new/rest/ua/cancel-order
4413
4754
  * @param {string} id order id
4414
4755
  * @param {string} symbol unified symbol of the market the order was made in
4415
4756
  * @param {object} [params] extra parameters specific to the exchange API endpoint
4416
4757
  * @param {string} [params.type] 'spot' or 'swap', used if symbol is not provided (default is 'spot')
4417
4758
  * @param {string} [params.marginMode] *spot only* 'cross' or 'isolated'
4759
+ * @param {boolean} [params.uta] true for cancelling order with unified account endpoint (default is false)
4418
4760
  * Check cancelSpotOrder() and cancelContractOrder() for more details on the extra parameters that can be used in params
4419
4761
  * @returns Response from the exchange
4420
4762
  */
4421
4763
  async cancelOrder(id, symbol = undefined, params = {}) {
4422
4764
  await this.loadMarkets();
4765
+ let uta = await this.isUTAEnabled();
4766
+ [uta, params] = this.handleOptionAndParams(params, 'cancelOrder', 'uta', uta);
4767
+ if (uta) {
4768
+ return await this.cancelUtaOrder(id, symbol, params);
4769
+ }
4423
4770
  let marketType = undefined;
4424
4771
  let market = undefined;
4425
4772
  if (symbol !== undefined) {
@@ -4636,6 +4983,61 @@ class kucoin extends kucoin$1["default"] {
4636
4983
  //
4637
4984
  return this.safeOrder({ 'info': response });
4638
4985
  }
4986
+ /**
4987
+ * @method
4988
+ * @name kucoin#cancelUtaOrder
4989
+ * @description helper method for cancelling uta orders
4990
+ * @see https://www.kucoin.com/docs-new/rest/ua/cancel-order
4991
+ * @param {string} id order id
4992
+ * @param {string} symbol unified symbol of the market the order was made in
4993
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
4994
+ * @param {string} [params.accountMode] 'unified' or 'classic' (default is 'unified')
4995
+ * @param {string} [params.clientOrderId] client order id, required if id is not provided
4996
+ * @param {string} [params.marginMode] 'cross' or 'isolated', required if fetching a margin order
4997
+ * @returns Response from the exchange
4998
+ */
4999
+ async cancelUtaOrder(id, symbol = undefined, params = {}) {
5000
+ if (symbol === undefined) {
5001
+ throw new errors.ArgumentsRequired(this.id + ' cancelOrder() requires a symbol argument for uta endpoint');
5002
+ }
5003
+ await this.loadMarkets();
5004
+ const request = {};
5005
+ const clientOrderId = this.safeString2(params, 'clientOid', 'clientOrderId');
5006
+ if (clientOrderId !== undefined) {
5007
+ request['clientOid'] = clientOrderId;
5008
+ params = this.omit(params, ['clientOid', 'clientOrderId']);
5009
+ }
5010
+ else {
5011
+ if (id === undefined) {
5012
+ throw new errors.ArgumentsRequired(this.id + ' fetchOrder() requires an id argument or clientOrderId parameter');
5013
+ }
5014
+ request['orderId'] = id;
5015
+ }
5016
+ await this.loadMarkets();
5017
+ const market = this.market(symbol);
5018
+ request['symbol'] = market['id'];
5019
+ let accountMode = 'unified';
5020
+ [accountMode, params] = this.handleOptionAndParams(params, 'fetchOrder', 'accountMode', accountMode);
5021
+ request['accountMode'] = accountMode;
5022
+ let marginMode = undefined;
5023
+ [marginMode, params] = this.handleMarginModeAndParams('fetchOrder', params);
5024
+ const tradeType = this.handleTradeType(market['contract'], marginMode, params);
5025
+ request['tradeType'] = tradeType;
5026
+ const response = await this.utaPrivatePostAccountModeOrderCancel(this.extend(request, params));
5027
+ //
5028
+ // {
5029
+ // "code": "200000",
5030
+ // "data": {
5031
+ // "orderId": "426319129738321920",
5032
+ // "tradeType": "SPOT",
5033
+ // "ts": 1774457628105000000,
5034
+ // "clientOid": "b896c118-a674-4863-baf4-a9ea3cd696c5"
5035
+ // }
5036
+ // }
5037
+ //
5038
+ const data = this.safeDict(response, 'data', {});
5039
+ return this.parseOrder(data, market);
5040
+ }
4639
5041
  /**
4640
5042
  * @method
4641
5043
  * @name kucoin#cancelAllOrders
@@ -4647,14 +5049,22 @@ class kucoin extends kucoin$1["default"] {
4647
5049
  * @see https://www.kucoin.com/docs-new/rest/margin-trading/orders/batch-cancel-stop-orders
4648
5050
  * @see https://www.kucoin.com/docs-new/rest/futures-trading/orders/cancel-all-orders
4649
5051
  * @see https://www.kucoin.com/docs-new/rest/futures-trading/orders/cancel-all-stop-orders
5052
+ * @see https://www.kucoin.com/docs-new/rest/ua/batch-cancel-order-by-symbol
4650
5053
  * @param {string} symbol unified market symbol, only orders in the market of this symbol are cancelled when symbol is not undefined
4651
5054
  * @param {object} [params] extra parameters specific to the exchange API endpoint
4652
5055
  * @param {string} [params.type] 'spot' or 'swap', used if symbol is not provided (default is 'spot')
4653
5056
  * @param {string} [params.marginMode] *spot only* 'cross' or 'isolated'
5057
+ * @param {boolean} [params.uta] true for cancelling orders with unified account endpoint (default is false)
5058
+ * Check cancelAllSpotOrders(), cancelAllContractOrders() and cancelAllUtaOrders() for more details on the extra parameters that can be used in params
4654
5059
  * @returns Response from the exchange
4655
5060
  */
4656
5061
  async cancelAllOrders(symbol = undefined, params = {}) {
4657
5062
  await this.loadMarkets();
5063
+ let uta = await this.isUTAEnabled();
5064
+ [uta, params] = this.handleOptionAndParams(params, 'cancelAllOrders', 'uta', uta);
5065
+ if (uta) {
5066
+ return await this.cancelAllUtaOrders(symbol, params);
5067
+ }
4658
5068
  let marketType = undefined;
4659
5069
  let market = undefined;
4660
5070
  if (symbol !== undefined) {
@@ -4772,26 +5182,78 @@ class kucoin extends kucoin$1["default"] {
4772
5182
  }
4773
5183
  /**
4774
5184
  * @method
4775
- * @name kucoin#fetchOrdersByStatus
4776
- * @description fetches a list of orders placed on the exchange
4777
- * @see https://www.kucoin.com/docs-new/rest/spot-trading/orders/get-open-orders
4778
- * @see https://www.kucoin.com/docs-new/rest/spot-trading/orders/get-closed-orders
4779
- * @see https://www.kucoin.com/docs-new/rest/spot-trading/orders/get-stop-orders-list
4780
- * @see https://www.kucoin.com/docs-new/rest/margin-trading/orders/get-open-orders
4781
- * @see https://www.kucoin.com/docs-new/rest/margin-trading/orders/get-closed-orders
4782
- * @see https://www.kucoin.com/docs-new/rest/margin-trading/orders/get-stop-order-list
4783
- * @see https://www.kucoin.com/docs-new/rest/futures-trading/orders/get-order-list
4784
- * @see https://www.kucoin.com/docs-new/rest/futures-trading/orders/get-stop-order-list
4785
- * @param {string} status 'active' or 'closed', only 'active' is valid for stop orders
4786
- * @param {string} symbol unified symbol for the market to retrieve orders from
4787
- * @param {int} [since] timestamp in ms of the earliest order to retrieve
4788
- * @param {int} [limit] The maximum number of orders to retrieve
5185
+ * @name kucoin#cancelAllUtaOrders
5186
+ * @description helper method for cancelling all uta orders
5187
+ * @see https://www.kucoin.com/docs-new/rest/ua/batch-cancel-order-by-symbol
5188
+ * @param {string} symbol unified market symbol, only orders in the market of this symbol are cancelled when symbol is not undefined
5189
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
5190
+ * @param {bool} [params.trigger] true if cancelling all stop orders
5191
+ * @param {string} [params.marginMode] 'CROSS' or 'ISOLATED'
5192
+ * @returns Response from the exchange
5193
+ */
5194
+ async cancelAllUtaOrders(symbol = undefined, params = {}) {
5195
+ if (symbol === undefined) {
5196
+ throw new errors.ArgumentsRequired(this.id + ' cancelAllOrders() requires a symbol argument for uta endpoint');
5197
+ }
5198
+ await this.loadMarkets();
5199
+ const market = this.market(symbol);
5200
+ const isContract = market['contract'];
5201
+ const tradeType = isContract ? 'FUTURES' : 'SPOT';
5202
+ let trigger = false;
5203
+ [trigger, params] = this.handleParamBool(params, 'trigger', trigger);
5204
+ const orderFilter = trigger ? 'ADVANCED' : 'NORMAL';
5205
+ const request = {
5206
+ 'accountMode': 'unified',
5207
+ 'symbol': market['id'],
5208
+ 'tradeType': tradeType,
5209
+ 'orderFilter': orderFilter,
5210
+ };
5211
+ const response = await this.utaPrivatePostAccountModeOrderCancelAll(this.extend(request, params));
5212
+ //
5213
+ // {
5214
+ // "code": "200000",
5215
+ // "data": {
5216
+ // "tradeType": "SPOT",
5217
+ // "ts": 1774458644140000000,
5218
+ // "items": [
5219
+ // {
5220
+ // "orderId": "426328635071352832"
5221
+ // }
5222
+ // ]
5223
+ // }
5224
+ // }
5225
+ //
5226
+ const data = this.safeDict(response, 'data', {});
5227
+ const orders = this.safeList(data, 'items', []);
5228
+ return this.parseOrders(orders, market, undefined, undefined, { 'status': 'canceled' });
5229
+ }
5230
+ /**
5231
+ * @method
5232
+ * @name kucoin#fetchOrdersByStatus
5233
+ * @description fetches a list of orders placed on the exchange
5234
+ * @see https://www.kucoin.com/docs-new/rest/spot-trading/orders/get-open-orders
5235
+ * @see https://www.kucoin.com/docs-new/rest/spot-trading/orders/get-closed-orders
5236
+ * @see https://www.kucoin.com/docs-new/rest/spot-trading/orders/get-stop-orders-list
5237
+ * @see https://www.kucoin.com/docs-new/rest/margin-trading/orders/get-open-orders
5238
+ * @see https://www.kucoin.com/docs-new/rest/margin-trading/orders/get-closed-orders
5239
+ * @see https://www.kucoin.com/docs-new/rest/margin-trading/orders/get-stop-order-list
5240
+ * @see https://www.kucoin.com/docs-new/rest/futures-trading/orders/get-order-list
5241
+ * @see https://www.kucoin.com/docs-new/rest/futures-trading/orders/get-stop-order-list
5242
+ * @see https://www.kucoin.com/docs-new/rest/ua/get-open-order-list
5243
+ * @see https://www.kucoin.com/docs-new/rest/ua/get-order-history
5244
+ * @param {string} status 'active' or 'closed', only 'active' is valid for stop orders
5245
+ * @param {string} symbol unified symbol for the market to retrieve orders from
5246
+ * @param {int} [since] timestamp in ms of the earliest order to retrieve
5247
+ * @param {int} [limit] The maximum number of orders to retrieve
4789
5248
  * @param {object} [params] exchange specific parameters
4790
- * Check fetchSpotOrdersByStatus() and fetchContractOrdersByStatus() for more details on the extra parameters that can be used in params
5249
+ * @param {boolean} [params.uta] true for fetch orders with uta endpoint (default is false)
5250
+ * Check fetchSpotOrdersByStatus(), fetchContractOrdersByStatus() and fetchUtaOrdersByStatus() for more details on the extra parameters that can be used in params
4791
5251
  * @returns An [array of order structures]{@link https://docs.ccxt.com/?id=order-structure}
4792
5252
  */
4793
5253
  async fetchOrdersByStatus(status, symbol = undefined, since = undefined, limit = undefined, params = {}) {
4794
5254
  await this.loadMarkets();
5255
+ let uta = await this.isUTAEnabled();
5256
+ [uta, params] = this.handleOptionAndParams(params, 'fetchOrdersByStatus', 'uta', uta);
4795
5257
  let marketType = undefined;
4796
5258
  if (symbol === undefined) {
4797
5259
  const type = this.safeString(params, 'type'); // exchange has specific param for order type
@@ -4801,14 +5263,26 @@ class kucoin extends kucoin$1["default"] {
4801
5263
  params = this.omit(params, 'type');
4802
5264
  }
4803
5265
  else {
4804
- [marketType, params] = this.handleMarketTypeAndParams('fetchOrdersByStatus', undefined, {});
5266
+ const methodOptions = this.safeDict(this.options, 'fetchOrdersByStatus', {});
5267
+ const methodDefaultType = this.safeString2(methodOptions, 'defaultType', 'type');
5268
+ if (methodDefaultType === undefined) {
5269
+ marketType = this.safeString2(this.options, 'defaultType', 'type', 'spot');
5270
+ }
5271
+ else {
5272
+ marketType = methodDefaultType;
5273
+ }
4805
5274
  }
4806
5275
  }
4807
5276
  else {
4808
5277
  const market = this.market(symbol);
4809
5278
  marketType = market['type'];
4810
5279
  }
4811
- if ((marketType === 'spot') || (marketType === 'margin')) {
5280
+ if (uta) {
5281
+ params = this.omit(params, 'uta');
5282
+ params = this.extend(params, { 'marketType': marketType });
5283
+ return await this.fetchUtaOrdersByStatus(status, symbol, since, limit, params);
5284
+ }
5285
+ else if ((marketType === 'spot') || (marketType === 'margin')) {
4812
5286
  return await this.fetchSpotOrdersByStatus(status, symbol, since, limit, params);
4813
5287
  }
4814
5288
  else {
@@ -5073,6 +5547,128 @@ class kucoin extends kucoin$1["default"] {
5073
5547
  const orders = this.safeList(responseData, 'items', []);
5074
5548
  return this.parseOrders(orders, market, since, limit);
5075
5549
  }
5550
+ /**
5551
+ * @method
5552
+ * @name kucoin#fetchUtaOrdersByStatus
5553
+ * @description helper method for fetching orders by status with uta endpoint
5554
+ * @see https://www.kucoin.com/docs-new/rest/ua/get-open-order-list
5555
+ * @see https://www.kucoin.com/docs-new/rest/ua/get-order-history
5556
+ * @param {string} status 'active' or 'closed', only 'active' is valid for stop orders
5557
+ * @param {string} symbol unified symbol for the market to retrieve orders from
5558
+ * @param {int} [since] timestamp in ms of the earliest order to retrieve
5559
+ * @param {int} [limit] The maximum number of orders to retrieve
5560
+ * @param {object} [params] exchange specific parameters
5561
+ * @param {int} [params.until] End time in ms
5562
+ * @param {string} [params.side] *closed orders only* 'BUY' or 'SELL'
5563
+ * @param {string} [params.accountMode] 'unified' or 'classic' (default is unified)
5564
+ * @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)
5565
+ * @returns An [array of order structures]{@link https://docs.ccxt.com/?id=order-structure}
5566
+ */
5567
+ async fetchUtaOrdersByStatus(status, symbol = undefined, since = undefined, limit = undefined, params = {}) {
5568
+ await this.loadMarkets();
5569
+ let paginate = false;
5570
+ const maxLimit = 200;
5571
+ [paginate, params] = this.handleOptionAndParams(params, 'fetchOrdersByStatus', 'paginate');
5572
+ if (paginate) {
5573
+ return await this.fetchPaginatedCallDynamic('fetchOrdersByStatus', symbol, since, limit, params, maxLimit);
5574
+ }
5575
+ let accountMode = 'unified';
5576
+ [accountMode, params] = this.handleOptionAndParams(params, 'fetchUtaOrdersByStatus', 'accountMode', accountMode);
5577
+ let request = {
5578
+ 'accountMode': accountMode,
5579
+ };
5580
+ let marketType = undefined;
5581
+ let market = undefined;
5582
+ if (symbol !== undefined) {
5583
+ market = this.market(symbol);
5584
+ marketType = market['type'];
5585
+ request['symbol'] = market['id'];
5586
+ }
5587
+ else {
5588
+ marketType = this.safeString(params, 'marketType');
5589
+ }
5590
+ params = this.omit(params, 'marketType');
5591
+ const isContract = (marketType !== 'spot') && (marketType !== 'margin');
5592
+ if (!isContract && (symbol === undefined)) {
5593
+ throw new errors.ArgumentsRequired(this.id + ' fetchOrdersByStatus() requires a symbol argument for spot and margin markets when using uta endpoint');
5594
+ }
5595
+ let marginMode = undefined;
5596
+ [marginMode, params] = this.handleMarginModeAndParams('fetchOrdersByStatus', params);
5597
+ const tradeType = this.handleTradeType(isContract, marginMode, params);
5598
+ params['tradeType'] = tradeType;
5599
+ if (since !== undefined) {
5600
+ request['startAt'] = since;
5601
+ }
5602
+ [request, params] = this.handleUntilOption('endAt', request, params);
5603
+ if (limit !== undefined) {
5604
+ request['pageSize'] = limit;
5605
+ }
5606
+ let lowercaseStatus = status.toLowerCase();
5607
+ if (lowercaseStatus === 'open') {
5608
+ lowercaseStatus = 'active';
5609
+ }
5610
+ else if (lowercaseStatus === 'closed') {
5611
+ lowercaseStatus = 'done';
5612
+ }
5613
+ let response = undefined;
5614
+ if (lowercaseStatus === 'active') {
5615
+ //
5616
+ // {
5617
+ // "code": "200000",
5618
+ // "data": {
5619
+ // "pageNumber": 1,
5620
+ // "pageSize": 50,
5621
+ // "totalNum": 1,
5622
+ // "totalPage": 1,
5623
+ // "items": [
5624
+ // {
5625
+ // "orderId": "426328635071352832",
5626
+ // "symbol": "ETH-USDT",
5627
+ // "orderType": "LIMIT",
5628
+ // "side": "BUY",
5629
+ // "size": "0.001",
5630
+ // "price": "1000",
5631
+ // "timeInForce": "GTC",
5632
+ // "tags": "partner:ccxt",
5633
+ // "orderTime": 1774457869404794617,
5634
+ // "stp": "",
5635
+ // "cancelAfter": null,
5636
+ // "postOnly": false,
5637
+ // "reduceOnly": false,
5638
+ // "triggerDirection": "",
5639
+ // "triggerPrice": "",
5640
+ // "triggerPriceType": "",
5641
+ // "tpTriggerPrice": "",
5642
+ // "tpTriggerPriceType": "",
5643
+ // "slTriggerPrice": "",
5644
+ // "slTriggerPriceType": "",
5645
+ // "filledSize": "0",
5646
+ // "avgPrice": "0",
5647
+ // "fee": "0",
5648
+ // "feeCurrency": "USDT",
5649
+ // "tax": "0",
5650
+ // "updatedTime": 1774457869469028819,
5651
+ // "triggerOrderId": "",
5652
+ // "cancelReason": "",
5653
+ // "cancelSize": "0",
5654
+ // "clientOid": "708987d5-c346-487a-a70c-ea267377b0ca",
5655
+ // "sizeUnit": "BASECCY",
5656
+ // "status": 2
5657
+ // }
5658
+ // ],
5659
+ // "tradeType": "SPOT"
5660
+ // }
5661
+ // }
5662
+ //
5663
+ response = await this.utaPrivateGetAccountModeOrderOpenList(this.extend(request, params));
5664
+ }
5665
+ else {
5666
+ response = await this.utaPrivateGetAccountModeOrderHistory(this.extend(request, params));
5667
+ }
5668
+ const data = this.safeDict(response, 'data', {});
5669
+ const orders = this.safeList(data, 'items', []);
5670
+ return this.parseOrders(orders, market, since, limit);
5671
+ }
5076
5672
  /**
5077
5673
  * @method
5078
5674
  * @name kucoin#fetchClosedOrders
@@ -5083,6 +5679,7 @@ class kucoin extends kucoin$1["default"] {
5083
5679
  * @see https://www.kucoin.com/docs-new/rest/futures-trading/orders/get-stop-order-list
5084
5680
  * @see https://www.kucoin.com/docs-new/rest/margin-trading/orders/get-open-orders
5085
5681
  * @see https://www.kucoin.com/docs-new/rest/margin-trading/orders/get-closed-orders
5682
+ * @see https://www.kucoin.com/docs-new/rest/ua/get-order-history
5086
5683
  * @param {string} symbol unified market symbol of the market orders were made in
5087
5684
  * @param {int} [since] the earliest time in ms to fetch orders for
5088
5685
  * @param {int} [limit] the maximum number of order structures to retrieve
@@ -5116,6 +5713,7 @@ class kucoin extends kucoin$1["default"] {
5116
5713
  * @see https://www.kucoin.com/docs-new/rest/margin-trading/orders/get-open-orders
5117
5714
  * @see https://www.kucoin.com/docs-new/rest/margin-trading/orders/get-closed-orders
5118
5715
  * @see https://www.kucoin.com/docs-new/rest/margin-trading/orders/get-stop-order-list
5716
+ * @see https://www.kucoin.com/docs-new/rest/ua/get-open-order-list
5119
5717
  * @param {string} symbol unified market symbol
5120
5718
  * @param {int} [since] the earliest time in ms to fetch open orders for
5121
5719
  * @param {int} [limit] the maximum number of open orders structures to retrieve
@@ -5154,15 +5752,23 @@ class kucoin extends kucoin$1["default"] {
5154
5752
  * @see https://www.kucoin.com/docs-new/rest/margin-trading/orders/get-stop-order-by-clientoid
5155
5753
  * @see https://www.kucoin.com/docs-new/rest/futures-trading/orders/get-order-by-orderld
5156
5754
  * @see https://www.kucoin.com/docs-new/rest/futures-trading/get-stop-order-by-clientoid
5755
+ * @see https://www.kucoin.com/docs-new/rest/ua/get-order-details
5157
5756
  * @param {string} id order id
5158
5757
  * @param {string} symbol unified symbol of the market the order was made in
5159
5758
  * @param {object} [params] extra parameters specific to the exchange API endpoint
5160
5759
  * @param {string} [params.type] 'spot' or 'swap', used if symbol is not provided (default is 'spot')
5161
- * Check fetchSpotOrder() and fetchContractOrder() for more details on the extra parameters that can be used in params
5760
+ * @param {bool} [params.uta] true if fetching an order with uta endpoint (default is false)
5761
+ * Check fetchSpotOrder(), fetchContractOrder() and fetchUtaOrder() for more details on the extra parameters that can be used in params
5162
5762
  * @returns {object} An [order structure]{@link https://docs.ccxt.com/?id=order-structure}
5163
5763
  */
5164
5764
  async fetchOrder(id, symbol = undefined, params = {}) {
5165
5765
  await this.loadMarkets();
5766
+ let uta = await this.isUTAEnabled();
5767
+ [uta, params] = this.handleOptionAndParams(params, 'fetchOrder', 'uta', uta);
5768
+ if (uta) {
5769
+ params = this.omit(params, 'uta');
5770
+ return await this.fetchUtaOrder(id, symbol, params);
5771
+ }
5166
5772
  let marketType = undefined;
5167
5773
  if (symbol === undefined) {
5168
5774
  [marketType, params] = this.handleMarketTypeAndParams('fetchOrder', undefined, params);
@@ -5353,7 +5959,115 @@ class kucoin extends kucoin$1["default"] {
5353
5959
  const responseData = this.safeDict(response, 'data');
5354
5960
  return this.parseOrder(responseData, market);
5355
5961
  }
5962
+ /**
5963
+ * @method
5964
+ * @name kucoin#fetchUtaOrder
5965
+ * @description fetch uta order
5966
+ * @see https://www.kucoin.com/docs-new/rest/ua/get-order-details
5967
+ * @param {string} id order id
5968
+ * @param {string} symbol unified symbol of the market the order was made in
5969
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
5970
+ * @param {string} [params.accountMode] 'unified' or 'classic' (default is 'unified')
5971
+ * @param {string} [params.clientOrderId] client order id, required if id is not provided
5972
+ * @param {string} [params.marginMode] 'cross' or 'isolated', required if fetching a margin order
5973
+ * @returns {object} An [order structure]{@link https://docs.ccxt.com/?id=order-structure}
5974
+ */
5975
+ async fetchUtaOrder(id, symbol = undefined, params = {}) {
5976
+ if (symbol === undefined) {
5977
+ throw new errors.ArgumentsRequired(this.id + ' fetchOrder() requires a symbol argument for uta orders');
5978
+ }
5979
+ const request = {};
5980
+ const clientOrderId = this.safeString2(params, 'clientOid', 'clientOrderId');
5981
+ if (clientOrderId !== undefined) {
5982
+ request['clientOid'] = clientOrderId;
5983
+ params = this.omit(params, ['clientOid', 'clientOrderId']);
5984
+ }
5985
+ else {
5986
+ if (id === undefined) {
5987
+ throw new errors.ArgumentsRequired(this.id + ' fetchOrder() requires an id argument or clientOrderId parameter');
5988
+ }
5989
+ request['orderId'] = id;
5990
+ }
5991
+ await this.loadMarkets();
5992
+ const market = this.market(symbol);
5993
+ request['symbol'] = market['id'];
5994
+ let accountMode = 'unified';
5995
+ [accountMode, params] = this.handleOptionAndParams(params, 'fetchOrder', 'accountMode', accountMode);
5996
+ request['accountMode'] = accountMode;
5997
+ let marginMode = undefined;
5998
+ [marginMode, params] = this.handleMarginModeAndParams('fetchOrder', params);
5999
+ const tradeType = this.handleTradeType(market['contract'], marginMode, params);
6000
+ request['tradeType'] = tradeType;
6001
+ const response = await this.utaPrivateGetAccountModeOrderDetail(this.extend(request, params));
6002
+ //
6003
+ // {
6004
+ // "code": "200000",
6005
+ // "data": {
6006
+ // "orderId": "426319129738321920",
6007
+ // "symbol": "ETH-USDT",
6008
+ // "orderType": "LIMIT",
6009
+ // "side": "BUY",
6010
+ // "size": "0.001",
6011
+ // "price": "1000",
6012
+ // "timeInForce": "GTC",
6013
+ // "tags": "partner:ccxt",
6014
+ // "orderTime": 1774455603156417582,
6015
+ // "stp": "",
6016
+ // "cancelAfter": null,
6017
+ // "postOnly": false,
6018
+ // "reduceOnly": false,
6019
+ // "triggerDirection": "",
6020
+ // "triggerPrice": "",
6021
+ // "triggerPriceType": "",
6022
+ // "tpTriggerPrice": "",
6023
+ // "tpTriggerPriceType": "",
6024
+ // "slTriggerPrice": "",
6025
+ // "slTriggerPriceType": "",
6026
+ // "filledSize": "0",
6027
+ // "avgPrice": "0",
6028
+ // "fee": "0",
6029
+ // "feeCurrency": "USDT",
6030
+ // "tax": "0",
6031
+ // "updatedTime": 1774455603371523690,
6032
+ // "triggerOrderId": "",
6033
+ // "cancelReason": "",
6034
+ // "cancelSize": "0",
6035
+ // "clientOid": "b896c118-a674-4863-baf4-a9ea3cd696c5",
6036
+ // "sizeUnit": "BASECCY",
6037
+ // "tradeType": "SPOT",
6038
+ // "tradeId": "",
6039
+ // "status": 2
6040
+ // }
6041
+ // }
6042
+ //
6043
+ const data = this.safeDict(response, 'data', {});
6044
+ return this.parseOrder(data, market);
6045
+ }
6046
+ handleTradeType(isContractMarket = false, marginMode = undefined, params = {}) {
6047
+ let tradeType = this.safeString(params, 'tradeType');
6048
+ if (tradeType === undefined) {
6049
+ if (isContractMarket) {
6050
+ tradeType = 'FUTURES';
6051
+ }
6052
+ else if (marginMode !== undefined) {
6053
+ tradeType = marginMode.toUpperCase();
6054
+ }
6055
+ else {
6056
+ tradeType = 'SPOT';
6057
+ }
6058
+ }
6059
+ return tradeType;
6060
+ }
5356
6061
  parseOrder(order, market = undefined) {
6062
+ const tradeType = this.safeString(order, 'tradeType');
6063
+ const utaTradeTypes = ['SPOT', 'CROSS', 'ISOLATED', 'FUTURES']; // tradeType specific for uta endpoint
6064
+ let isUtaOrder = this.inArray(tradeType, utaTradeTypes);
6065
+ if ('sizeUnit' in order) { // property specific for uta endpoint
6066
+ isUtaOrder = true;
6067
+ }
6068
+ if (isUtaOrder) {
6069
+ return this.parseUtaOrder(order, market);
6070
+ }
5357
6071
  const marketId = this.safeString(order, 'symbol');
5358
6072
  market = this.safeMarket(marketId, market);
5359
6073
  if ((market !== undefined) && (market['contract'])) {
@@ -5678,6 +6392,128 @@ class kucoin extends kucoin$1["default"] {
5678
6392
  'trades': undefined,
5679
6393
  }, market);
5680
6394
  }
6395
+ parseUtaOrder(order, market = undefined) {
6396
+ //
6397
+ // createOrder
6398
+ // {
6399
+ // "orderId": "426319129738321920",
6400
+ // "tradeType": "SPOT",
6401
+ // "ts": 1774455603216000000,
6402
+ // "clientOid": "b896c118-a674-4863-baf4-a9ea3cd696c5"
6403
+ // }
6404
+ //
6405
+ // fetchOrder
6406
+ // {
6407
+ // "orderId": "426319129738321920",
6408
+ // "symbol": "ETH-USDT",
6409
+ // "orderType": "LIMIT",
6410
+ // "side": "BUY",
6411
+ // "size": "0.001",
6412
+ // "price": "1000",
6413
+ // "timeInForce": "GTC",
6414
+ // "tags": "partner:ccxt",
6415
+ // "orderTime": 1774455603156417582,
6416
+ // "stp": "",
6417
+ // "cancelAfter": null,
6418
+ // "postOnly": false,
6419
+ // "reduceOnly": false,
6420
+ // "triggerDirection": "",
6421
+ // "triggerPrice": "",
6422
+ // "triggerPriceType": "",
6423
+ // "tpTriggerPrice": "",
6424
+ // "tpTriggerPriceType": "",
6425
+ // "slTriggerPrice": "",
6426
+ // "slTriggerPriceType": "",
6427
+ // "filledSize": "0",
6428
+ // "avgPrice": "0",
6429
+ // "fee": "0",
6430
+ // "feeCurrency": "USDT",
6431
+ // "tax": "0",
6432
+ // "updatedTime": 1774455603371523690,
6433
+ // "triggerOrderId": "",
6434
+ // "cancelReason": "",
6435
+ // "cancelSize": "0",
6436
+ // "clientOid": "b896c118-a674-4863-baf4-a9ea3cd696c5",
6437
+ // "sizeUnit": "BASECCY",
6438
+ // "tradeType": "SPOT",
6439
+ // "tradeId": "",
6440
+ // "status": 2
6441
+ // }
6442
+ //
6443
+ const marketId = this.safeString(order, 'symbol');
6444
+ market = this.safeMarket(marketId, market);
6445
+ const symbol = market['symbol'];
6446
+ const timestamp = this.safeIntegerProduct2(order, 'orderTime', 'ts', 0.000001);
6447
+ const lastUpdateTimestamp = this.safeIntegerProduct(order, 'updatedTime', 0.000001);
6448
+ const rawTimeInForce = this.safeString(order, 'timeInForce');
6449
+ let amount = undefined;
6450
+ let cost = undefined;
6451
+ const sizeUnit = this.safeString(order, 'sizeUnit');
6452
+ const size = this.safeString(order, 'size');
6453
+ const rawStatus = this.safeString(order, 'status');
6454
+ const average = this.safeString(order, 'avgPrice');
6455
+ let filled = this.safeString(order, 'filledSize'); // might be in base or quote, need to check sizeUnit
6456
+ if ((sizeUnit === 'BASECCY') || (sizeUnit === 'UNIT')) {
6457
+ amount = size;
6458
+ }
6459
+ else {
6460
+ cost = filled;
6461
+ filled = Precise["default"].stringDiv(filled, average);
6462
+ filled = this.amountToPrecision(symbol, filled);
6463
+ }
6464
+ const fee = {
6465
+ 'currency': this.safeCurrencyCode(this.safeString(order, 'feeCurrency')),
6466
+ 'cost': this.safeString(order, 'fee'),
6467
+ };
6468
+ return this.safeOrder({
6469
+ 'id': this.safeString(order, 'orderId'),
6470
+ 'clientOrderId': this.safeString(order, 'clientOid'),
6471
+ 'symbol': symbol,
6472
+ 'type': this.safeStringLower(order, 'orderType'),
6473
+ 'timeInForce': this.parseOrderTimeInForce(rawTimeInForce),
6474
+ 'postOnly': this.safeBool(order, 'postOnly'),
6475
+ 'reduceOnly': this.safeBool(order, 'reduceOnly'),
6476
+ 'side': this.safeStringLower(order, 'side'),
6477
+ 'amount': amount,
6478
+ 'price': this.safeString(order, 'price'),
6479
+ 'triggerPrice': this.safeString2(order, 'stopPrice', 'triggerPrice'),
6480
+ 'cost': cost,
6481
+ 'filled': filled,
6482
+ 'remaining': undefined,
6483
+ 'timestamp': timestamp,
6484
+ 'datetime': this.iso8601(timestamp),
6485
+ 'fee': fee,
6486
+ 'status': this.parseOrderStatus(rawStatus),
6487
+ 'lastTradeTimestamp': undefined,
6488
+ 'lastUpdateTimestamp': lastUpdateTimestamp,
6489
+ 'average': average,
6490
+ 'trades': undefined,
6491
+ 'stopLossPrice': this.safeString(order, 'slTriggerPrice'),
6492
+ 'takeProfitPrice': this.safeString(order, 'tpTriggerPrice'),
6493
+ 'info': order,
6494
+ }, market);
6495
+ }
6496
+ parseOrderTimeInForce(timeInForce) {
6497
+ const timeInForces = {
6498
+ 'GTC': 'GTC',
6499
+ 'IOC': 'IOC',
6500
+ 'FOK': 'FOK',
6501
+ 'GTT': 'GTD',
6502
+ };
6503
+ return this.safeString(timeInForces, timeInForce, timeInForce);
6504
+ }
6505
+ parseOrderStatus(status) {
6506
+ const statuses = {
6507
+ '0': 'open',
6508
+ '1': 'open',
6509
+ '2': 'open',
6510
+ '3': 'closed',
6511
+ '4': 'open',
6512
+ '5': 'canceled',
6513
+ '6': 'closed', // partial canceled
6514
+ };
6515
+ return this.safeString(statuses, status, status);
6516
+ }
5681
6517
  /**
5682
6518
  * @method
5683
6519
  * @name kucoin#fetchOrderTrades
@@ -5685,12 +6521,14 @@ class kucoin extends kucoin$1["default"] {
5685
6521
  * @see https://docs.kucoin.com/#list-fills
5686
6522
  * @see https://www.kucoin.com/docs-new/rest/futures-trading/orders/get-trade-history
5687
6523
  * @see https://www.kucoin.com/docs-new/rest/margin-trading/orders/get-trade-history
6524
+ * @see https://www.kucoin.com/docs-new/rest/ua/get-trade-history
5688
6525
  * @param {string} id order id
5689
6526
  * @param {string} symbol unified market symbol
5690
6527
  * @param {int} [since] the earliest time in ms to fetch trades for
5691
6528
  * @param {int} [limit] the maximum number of trades to retrieve
5692
6529
  * @param {object} [params] extra parameters specific to the exchange API endpoint
5693
6530
  * @param {string} [params.type] 'spot' or 'swap', used if symbol is not provided (default is 'spot')
6531
+ * @param {boolean} [params.uta] set to true if fetching trades from uta endpoint, default is false.
5694
6532
  * @returns {object[]} a list of [trade structures]{@link https://docs.ccxt.com/?id=trade-structure}
5695
6533
  */
5696
6534
  async fetchOrderTrades(id, symbol = undefined, since = undefined, limit = undefined, params = {}) {
@@ -5704,6 +6542,7 @@ class kucoin extends kucoin$1["default"] {
5704
6542
  * @name kucoin#fetchMyTrades
5705
6543
  * @see https://www.kucoin.com/docs-new/rest/spot-trading/orders/get-trade-history
5706
6544
  * @see https://www.kucoin.com/docs-new/rest/margin-trading/orders/get-trade-history
6545
+ * @see https://www.kucoin.com/docs-new/rest/ua/get-trade-history
5707
6546
  * @description fetch all trades made by the user
5708
6547
  * @param {string} symbol unified market symbol
5709
6548
  * @param {int} [since] the earliest time in ms to fetch trades for
@@ -5722,6 +6561,12 @@ class kucoin extends kucoin$1["default"] {
5722
6561
  market = this.market(symbol);
5723
6562
  }
5724
6563
  [marketType, params] = this.handleMarketTypeAndParams('fetchMyTrades', market, params);
6564
+ let uta = await this.isUTAEnabled();
6565
+ [uta, params] = this.handleOptionAndParams(params, 'fetchMyTrades', 'uta', uta);
6566
+ if (uta) {
6567
+ params = this.extend(params, { 'marketType': marketType });
6568
+ return await this.fetchMyUtaTrades(symbol, since, limit, params);
6569
+ }
5725
6570
  if ((marketType === 'spot') || (marketType === 'margin')) {
5726
6571
  return await this.fetchMySpotTrades(symbol, since, limit, params);
5727
6572
  }
@@ -5938,57 +6783,144 @@ class kucoin extends kucoin$1["default"] {
5938
6783
  }
5939
6784
  /**
5940
6785
  * @method
5941
- * @name kucoin#fetchTrades
5942
- * @description get the list of most recent trades for a particular symbol
5943
- * @see https://www.kucoin.com/docs-new/rest/spot-trading/market-data/get-trade-history
5944
- * @see https://www.kucoin.com/docs-new/rest/ua/get-trades
5945
- * @see https://www.kucoin.com/docs-new/rest/futures-trading/market-data/get-trade-history
5946
- * @param {string} symbol unified symbol of the market to fetch trades for
5947
- * @param {int} [since] timestamp in ms of the earliest trade to fetch
5948
- * @param {int} [limit] the maximum amount of trades to fetch
6786
+ * @name kucoin#fetchMyUtaTrades
6787
+ * @see https://www.kucoin.com/docs-new/rest/ua/get-trade-history
6788
+ * @description fetch all trades made by the user
6789
+ * @param {string} symbol unified market symbol
6790
+ * @param {int} [since] the earliest time in ms to fetch trades for
6791
+ * @param {int} [limit] the maximum number of trades structures to retrieve (default is 50, max is 200)
5949
6792
  * @param {object} [params] extra parameters specific to the exchange API endpoint
5950
- * @param {boolean} [params.uta] set to true for the unified trading account (uta), defaults to false
5951
- * @returns {Trade[]} a list of [trade structures]{@link https://docs.ccxt.com/?id=public-trades}
6793
+ * @param {int} [params.until] the latest time in ms to fetch entries for
6794
+ * @param {string} [params.accountMode] 'unified' or 'classic', defaults to 'unified'
6795
+ * @param {string} [params.marginMode] 'cross' or 'isolated', only for margin trades
6796
+ * @param {string} [params.side] 'BUY' or 'SELL' (both if not provided)
6797
+ * @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)
6798
+ * @returns {Trade[]} a list of [trade structures]{@link https://docs.ccxt.com/?id=trade-structure}
5952
6799
  */
5953
- async fetchTrades(symbol, since = undefined, limit = undefined, params = {}) {
6800
+ async fetchMyUtaTrades(symbol = undefined, since = undefined, limit = undefined, params = {}) {
5954
6801
  await this.loadMarkets();
5955
- const market = this.market(symbol);
5956
- const request = {
5957
- 'symbol': market['id'],
5958
- };
5959
- // pagination is not supported on the exchange side anymore
5960
- // if (since !== undefined) {
5961
- // request['startAt'] = Math.floor (since / 1000);
5962
- // }
5963
- // if (limit !== undefined) {
5964
- // request['pageSize'] = limit;
5965
- // }
5966
- let uta = undefined;
5967
- [uta, params] = this.handleOptionAndParams(params, 'fetchTrades', 'uta', false);
5968
- let response = undefined;
5969
- let trades = undefined;
5970
- let type = undefined;
5971
- [type, params] = this.handleMarketTypeAndParams('fetchTrades', market, params);
5972
- if (uta) {
5973
- if ((type === 'spot') || (type === 'margin')) {
5974
- request['tradeType'] = 'SPOT';
5975
- }
5976
- else {
5977
- request['tradeType'] = 'FUTURES';
5978
- }
5979
- response = await this.utaGetMarketTrade(this.extend(request, params));
5980
- //
5981
- // {
5982
- // "code": "200000",
5983
- // "data": {
5984
- // "tradeType": "SPOT",
5985
- // "list": [
5986
- // {
5987
- // "sequence": "18746044393340932",
5988
- // "tradeId": "18746044393340932",
5989
- // "price": "104355.6",
5990
- // "size": "0.00011886",
5991
- // "side": "sell",
6802
+ let paginate = false;
6803
+ [paginate, params] = this.handleOptionAndParams(params, 'fetchMyTrades', 'paginate');
6804
+ if (paginate) {
6805
+ return await this.fetchPaginatedCallDynamic('fetchMyTrades', symbol, since, limit, params);
6806
+ }
6807
+ const marketType = this.safeString(params, 'marketType');
6808
+ if (marketType !== undefined) {
6809
+ params = this.omit(params, 'marketType');
6810
+ }
6811
+ let request = {};
6812
+ let isContract = false;
6813
+ let market = undefined;
6814
+ if (symbol !== undefined) {
6815
+ market = this.market(symbol);
6816
+ request['symbol'] = market['id'];
6817
+ isContract = market['contract'];
6818
+ }
6819
+ else if ((marketType === 'spot') || (marketType === 'margin')) {
6820
+ throw new errors.ArgumentsRequired(this.id + ' fetchMyTrades() requires a symbol parameter for uta spot or margin trades');
6821
+ }
6822
+ else {
6823
+ isContract = true;
6824
+ }
6825
+ let marginMode = undefined;
6826
+ [marginMode, params] = this.handleMarginModeAndParams('fetchMyTrades', params);
6827
+ const tradeType = this.handleTradeType(isContract, marginMode, params);
6828
+ request['tradeType'] = tradeType;
6829
+ let accountMode = 'unified';
6830
+ [accountMode, params] = this.handleOptionAndParams(params, 'fetchMyTrades', 'accountMode', accountMode);
6831
+ request['accountMode'] = accountMode;
6832
+ if (since !== undefined) {
6833
+ request['startAt'] = since;
6834
+ }
6835
+ if (limit !== undefined) {
6836
+ request['pageSize'] = limit;
6837
+ }
6838
+ [request, params] = this.handleUntilOption('endAt', request, params);
6839
+ const response = await this.utaPrivateGetAccountModeOrderExecution(this.extend(request, params));
6840
+ //
6841
+ // {
6842
+ // "code": "200000",
6843
+ // "data": {
6844
+ // "tradeType": "FUTURES",
6845
+ // "lastId": 30000000000531982,
6846
+ // "items": [
6847
+ // {
6848
+ // "orderId": "426373228194254848",
6849
+ // "symbol": "DOGEUSDTM",
6850
+ // "orderType": "MARKET",
6851
+ // "side": "BUY",
6852
+ // "tradeId": "1711108516570",
6853
+ // "size": "1",
6854
+ // "price": "0.09641",
6855
+ // "value": "9.641",
6856
+ // "executionTime": 1774468501294000000,
6857
+ // "fee": "0.0057846",
6858
+ // "feeCurrency": "USDT",
6859
+ // "tax": "",
6860
+ // "liquidityRole": "TAKER",
6861
+ // "fillType": "NORMAL"
6862
+ // }
6863
+ // ]
6864
+ // }
6865
+ // }
6866
+ //
6867
+ const data = this.safeDict(response, 'data', {});
6868
+ const trades = this.safeList(data, 'items', []);
6869
+ return this.parseTrades(trades, market, since, limit);
6870
+ }
6871
+ /**
6872
+ * @method
6873
+ * @name kucoin#fetchTrades
6874
+ * @description get the list of most recent trades for a particular symbol
6875
+ * @see https://www.kucoin.com/docs-new/rest/spot-trading/market-data/get-trade-history
6876
+ * @see https://www.kucoin.com/docs-new/rest/ua/get-trades
6877
+ * @see https://www.kucoin.com/docs-new/rest/futures-trading/market-data/get-trade-history
6878
+ * @param {string} symbol unified symbol of the market to fetch trades for
6879
+ * @param {int} [since] timestamp in ms of the earliest trade to fetch
6880
+ * @param {int} [limit] the maximum amount of trades to fetch
6881
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
6882
+ * @param {boolean} [params.uta] set to true for the unified trading account (uta), defaults to false
6883
+ * @returns {Trade[]} a list of [trade structures]{@link https://docs.ccxt.com/?id=public-trades}
6884
+ */
6885
+ async fetchTrades(symbol, since = undefined, limit = undefined, params = {}) {
6886
+ await this.loadMarkets();
6887
+ const market = this.market(symbol);
6888
+ const request = {
6889
+ 'symbol': market['id'],
6890
+ };
6891
+ // pagination is not supported on the exchange side anymore
6892
+ // if (since !== undefined) {
6893
+ // request['startAt'] = Math.floor (since / 1000);
6894
+ // }
6895
+ // if (limit !== undefined) {
6896
+ // request['pageSize'] = limit;
6897
+ // }
6898
+ let uta = false;
6899
+ [uta, params] = this.handleOptionAndParams(params, 'fetchTrades', 'uta', uta);
6900
+ let response = undefined;
6901
+ let trades = undefined;
6902
+ let type = undefined;
6903
+ [type, params] = this.handleMarketTypeAndParams('fetchTrades', market, params);
6904
+ if (uta) {
6905
+ if ((type === 'spot') || (type === 'margin')) {
6906
+ request['tradeType'] = 'SPOT';
6907
+ }
6908
+ else {
6909
+ request['tradeType'] = 'FUTURES';
6910
+ }
6911
+ response = await this.utaGetMarketTrade(this.extend(request, params));
6912
+ //
6913
+ // {
6914
+ // "code": "200000",
6915
+ // "data": {
6916
+ // "tradeType": "SPOT",
6917
+ // "list": [
6918
+ // {
6919
+ // "sequence": "18746044393340932",
6920
+ // "tradeId": "18746044393340932",
6921
+ // "price": "104355.6",
6922
+ // "size": "0.00011886",
6923
+ // "side": "sell",
5992
6924
  // "ts": 1762242540829000000
5993
6925
  // },
5994
6926
  // ]
@@ -6040,6 +6972,9 @@ class kucoin extends kucoin$1["default"] {
6040
6972
  return this.parseTrades(trades, market, since, limit);
6041
6973
  }
6042
6974
  parseTrade(trade, market = undefined) {
6975
+ if ('liquidityRole' in trade) { // property specific to myTrades from uta endpoint
6976
+ return this.parseMyUtaTrade(trade, market);
6977
+ }
6043
6978
  const marketId = this.safeString(trade, 'symbol');
6044
6979
  market = this.safeMarket(marketId, market);
6045
6980
  if ((market === undefined) || (market['spot'])) {
@@ -6326,23 +7261,97 @@ class kucoin extends kucoin$1["default"] {
6326
7261
  'fee': fee,
6327
7262
  }, market);
6328
7263
  }
7264
+ parseMyUtaTrade(trade, market = undefined) {
7265
+ //
7266
+ // {
7267
+ // "orderId": "426373228194254848",
7268
+ // "symbol": "DOGEUSDTM",
7269
+ // "orderType": "MARKET",
7270
+ // "side": "BUY",
7271
+ // "tradeId": "1711108516570",
7272
+ // "size": "1",
7273
+ // "price": "0.09641",
7274
+ // "value": "9.641",
7275
+ // "executionTime": 1774468501294000000,
7276
+ // "fee": "0.0057846",
7277
+ // "feeCurrency": "USDT",
7278
+ // "tax": "",
7279
+ // "liquidityRole": "TAKER",
7280
+ // "fillType": "NORMAL"
7281
+ // }
7282
+ //
7283
+ const marketId = this.safeString(trade, 'symbol');
7284
+ market = this.safeMarket(marketId, market);
7285
+ const timestamp = this.safeIntegerProduct(trade, 'executionTime', 0.000001);
7286
+ const fee = {
7287
+ 'cost': this.safeString(trade, 'fee'),
7288
+ 'currency': this.safeCurrencyCode(this.safeString(trade, 'feeCurrency')),
7289
+ };
7290
+ return this.safeTrade({
7291
+ 'info': trade,
7292
+ 'id': this.safeString(trade, 'tradeId'),
7293
+ 'order': this.safeString(trade, 'orderId'),
7294
+ 'timestamp': timestamp,
7295
+ 'datetime': this.iso8601(timestamp),
7296
+ 'symbol': market['symbol'],
7297
+ 'type': this.safeStringLower(trade, 'orderType'),
7298
+ 'takerOrMaker': this.safeStringLower(trade, 'liquidityRole'),
7299
+ 'side': this.safeStringLower(trade, 'side'),
7300
+ 'price': this.safeString(trade, 'price'),
7301
+ 'amount': this.safeString(trade, 'size'),
7302
+ 'cost': this.safeString(trade, 'value'),
7303
+ 'fee': fee,
7304
+ }, market);
7305
+ }
6329
7306
  /**
6330
7307
  * @method
6331
7308
  * @name kucoin#fetchTradingFee
6332
7309
  * @description fetch the trading fees for a market
6333
7310
  * @see https://www.kucoin.com/docs-new/rest/account-info/trade-fee/get-actual-fee-spot-margin
6334
7311
  * @see https://www.kucoin.com/docs-new/rest/account-info/trade-fee/get-actual-fee-futures
7312
+ * @see https://www.kucoin.com/docs-new/rest/ua/get-actual-fee
6335
7313
  * @param {string} symbol unified market symbol
6336
7314
  * @param {object} [params] extra parameters specific to the exchange API endpoint
7315
+ * @param {boolean} [params.uta] set to true for the unified trading account (uta) endpoint, defaults to false
6337
7316
  * @returns {object} a [fee structure]{@link https://docs.ccxt.com/?id=fee-structure}
6338
7317
  */
6339
7318
  async fetchTradingFee(symbol, params = {}) {
6340
7319
  await this.loadMarkets();
6341
7320
  const market = this.market(symbol);
7321
+ let uta = await this.isUTAEnabled();
7322
+ [uta, params] = this.handleOptionAndParams(params, 'fetchTradingFee', 'uta', uta);
6342
7323
  const request = {};
6343
7324
  let response = undefined;
6344
7325
  let entry = undefined;
6345
- if (market['spot']) {
7326
+ if (uta) {
7327
+ if (market['spot']) {
7328
+ request['tradeType'] = 'SPOT';
7329
+ }
7330
+ else {
7331
+ request['tradeType'] = 'FUTURES';
7332
+ }
7333
+ request['symbol'] = market['id'];
7334
+ response = await this.utaPrivateGetUserFeeRate(this.extend(request, params));
7335
+ //
7336
+ // {
7337
+ // "code": "200000",
7338
+ // "data": {
7339
+ // "tradeType": "SPOT",
7340
+ // "list": [
7341
+ // {
7342
+ // "symbol": "ETH-USDT",
7343
+ // "takerFeeRate": "0.001",
7344
+ // "makerFeeRate": "0.001"
7345
+ // }
7346
+ // ]
7347
+ // }
7348
+ // }
7349
+ //
7350
+ const data = this.safeDict(response, 'data', {});
7351
+ const dataList = this.safeList(data, 'list', []);
7352
+ entry = this.safeDict(dataList, 0);
7353
+ }
7354
+ else if (market['spot']) {
6346
7355
  request['symbols'] = market['id'];
6347
7356
  response = await this.privateGetTradeFees(this.extend(request, params));
6348
7357
  //
@@ -6418,7 +7427,7 @@ class kucoin extends kucoin$1["default"] {
6418
7427
  let networkCode = undefined;
6419
7428
  [networkCode, params] = this.handleNetworkCodeAndParams(params);
6420
7429
  if (networkCode !== undefined) {
6421
- request['chain'] = this.networkCodeToId(networkCode).toLowerCase();
7430
+ request['chain'] = this.networkCodeToId(networkCode, currency['code']).toLowerCase();
6422
7431
  }
6423
7432
  request['amount'] = parseFloat(this.currencyToPrecision(code, amount, networkCode));
6424
7433
  let includeFee = undefined;
@@ -6539,12 +7548,13 @@ class kucoin extends kucoin$1["default"] {
6539
7548
  }
6540
7549
  const internal = this.safeBool(transaction, 'isInner');
6541
7550
  const tag = this.safeString(transaction, 'memo');
7551
+ const chainId = this.safeString(transaction, 'chain');
6542
7552
  return {
6543
7553
  'info': transaction,
6544
7554
  'id': this.safeString2(transaction, 'id', 'withdrawalId'),
6545
7555
  'timestamp': timestamp,
6546
7556
  'datetime': this.iso8601(timestamp),
6547
- 'network': this.networkIdToCode(this.safeString(transaction, 'chain')),
7557
+ 'network': this.networkIdToCode(chainId, code),
6548
7558
  'address': address,
6549
7559
  'addressTo': address,
6550
7560
  'addressFrom': undefined,
@@ -6736,10 +7746,11 @@ class kucoin extends kucoin$1["default"] {
6736
7746
  if (accountType === 'contract') {
6737
7747
  return await this.fetchContractWithdrawals(code, since, limit, params);
6738
7748
  }
7749
+ const maxLimit = 500;
6739
7750
  let paginate = false;
6740
7751
  [paginate, params] = this.handleOptionAndParams(params, 'fetchWithdrawals', 'paginate');
6741
7752
  if (paginate) {
6742
- return await this.fetchPaginatedCallDynamic('fetchWithdrawals', code, since, limit, params, 500);
7753
+ return await this.fetchPaginatedCallDynamic('fetchWithdrawals', code, since, limit, params, maxLimit);
6743
7754
  }
6744
7755
  let request = {};
6745
7756
  let currency = undefined;
@@ -6879,14 +7890,24 @@ class kucoin extends kucoin$1["default"] {
6879
7890
  * @see https://www.kucoin.com/docs-new/rest/account-info/account-funding/get-account-cross-margin
6880
7891
  * @see https://www.kucoin.com/docs-new/rest/account-info/account-funding/get-account-isolated-margin
6881
7892
  * @see https://www.kucoin.com/docs-new/rest/account-info/account-funding/get-account-futures
7893
+ * @see https://www.kucoin.com/docs-new/rest/ua/get-account-currency-assets-uta
7894
+ * @see https://www.kucoin.com/docs-new/rest/ua/get-account-currency-assets-classic
6882
7895
  * @param {object} [params] extra parameters specific to the exchange API endpoint
6883
7896
  * @param {object} [params.marginMode] 'cross' or 'isolated', margin type for fetching margin balance
6884
7897
  * @param {object} [params.type] extra parameters specific to the exchange API endpoint
6885
7898
  * @param {object} [params.hf] *default if false* if true, the result includes the balance of the high frequency account
7899
+ * @param {boolean} [params.uta] set to true for the unified trading account (uta) endpoint, defaults to false
6886
7900
  * @returns {object} a [balance structure]{@link https://docs.ccxt.com/?id=balance-structure}
6887
7901
  */
6888
7902
  async fetchBalance(params = {}) {
6889
7903
  await this.loadMarkets();
7904
+ let uta = await this.isUTAEnabled();
7905
+ [uta, params] = this.handleOptionAndParams(params, 'fetchBalance', 'uta', uta);
7906
+ if (uta) {
7907
+ return await this.fetchUtaBalance(params);
7908
+ }
7909
+ let response = undefined;
7910
+ const request = {};
6890
7911
  const code = this.safeString(params, 'code');
6891
7912
  let currency = undefined;
6892
7913
  if (code !== undefined) {
@@ -6905,26 +7926,25 @@ class kucoin extends kucoin$1["default"] {
6905
7926
  if (hf && (type !== 'main')) {
6906
7927
  type = 'trade_hf';
6907
7928
  }
6908
- const [marginMode, query] = this.handleMarginModeAndParams('fetchBalance', params);
6909
- let response = undefined;
6910
- const request = {};
7929
+ let marginMode = undefined;
7930
+ [marginMode, params] = this.handleMarginModeAndParams('fetchBalance', params);
6911
7931
  const isolated = (marginMode === 'isolated') || (type === 'isolated');
6912
7932
  const cross = (marginMode === 'cross') || (type === 'margin');
6913
7933
  if (isolated) {
6914
7934
  if (currency !== undefined) {
6915
7935
  request['balanceCurrency'] = currency['id'];
6916
7936
  }
6917
- response = await this.privateGetIsolatedAccounts(this.extend(request, query));
7937
+ response = await this.privateGetIsolatedAccounts(this.extend(request, params));
6918
7938
  }
6919
7939
  else if (cross) {
6920
- response = await this.privateGetMarginAccount(this.extend(request, query));
7940
+ response = await this.privateGetMarginAccount(this.extend(request, params));
6921
7941
  }
6922
7942
  else {
6923
7943
  if (currency !== undefined) {
6924
7944
  request['currency'] = currency['id'];
6925
7945
  }
6926
7946
  request['type'] = type;
6927
- response = await this.privateGetAccounts(this.extend(request, query));
7947
+ response = await this.privateGetAccounts(this.extend(request, params));
6928
7948
  }
6929
7949
  //
6930
7950
  // Spot
@@ -7108,11 +8128,260 @@ class kucoin extends kucoin$1["default"] {
7108
8128
  result[currencyCode] = account;
7109
8129
  return this.safeBalance(result);
7110
8130
  }
8131
+ /**
8132
+ * @method
8133
+ * @name kucoin#fetchUtaBalance
8134
+ * @description helper method for fetching balance with unified trading account (uta) endpoint
8135
+ * @see https://www.kucoin.com/docs-new/rest/ua/get-account-currency-assets-uta
8136
+ * @see https://www.kucoin.com/docs-new/rest/ua/get-account-currency-assets-classic
8137
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
8138
+ * @param {string} [params.type] 'spot', 'unified', 'funding', 'cross', 'isolated' or 'swap' (default is 'spot')
8139
+ * @param {string} [params.marginMode] 'cross' or 'isolated', margin type for fetching margin balance, only applicable if type is margin (default is cross)
8140
+ * @returns {object} a [balance structure]{@link https://docs.ccxt.com/?id=balance-structure}
8141
+ */
8142
+ async fetchUtaBalance(params = {}) {
8143
+ await this.loadMarkets();
8144
+ let requestedType = undefined;
8145
+ [requestedType, params] = this.handleMarketTypeAndParams('fetchUtaBalance', undefined, params);
8146
+ if (requestedType === 'margin') {
8147
+ // assume cross margin if margin is specified but marginMode is not specified
8148
+ let marginMode = 'cross';
8149
+ [marginMode, params] = this.handleMarginModeAndParams('fetchUtaBalance', params, marginMode);
8150
+ requestedType = marginMode;
8151
+ }
8152
+ const utaAccountsByType = this.safeDict(this.options, 'utaAccountsByType', {});
8153
+ let type = undefined;
8154
+ type = this.safeString(utaAccountsByType, requestedType, type);
8155
+ const isIsolated = (type === 'ISOLATED');
8156
+ const request = {};
8157
+ let response = undefined;
8158
+ if (type === 'unified') {
8159
+ request['accountMode'] = type;
8160
+ // uta
8161
+ // {
8162
+ // "code": "200000",
8163
+ // "data": {
8164
+ // "accountType": "UNIFIED",
8165
+ // "ts": 1764731696945,
8166
+ // "accounts": [
8167
+ // {
8168
+ // "currencies": [
8169
+ // {
8170
+ // "currency": "USDT",
8171
+ // "equity": "97.9936711985",
8172
+ // "hold": "0.0000000000",
8173
+ // "balance": "97.9936711985",
8174
+ // "available": "97.9936711985",
8175
+ // "liability": "0.0000000000"
8176
+ // },
8177
+ // {
8178
+ // "currency": "BTC",
8179
+ // "equity": "0.0000216000",
8180
+ // "hold": "0.0000000000",
8181
+ // "balance": "0.0000216000",
8182
+ // "available": "0.0000216000",
8183
+ // "liability": "0.0000000000"
8184
+ // }
8185
+ // ]
8186
+ // }
8187
+ // ]
8188
+ // }
8189
+ // }
8190
+ //
8191
+ response = await this.utaPrivateGetAccountModeAccountBalance(this.extend(request, params));
8192
+ }
8193
+ else {
8194
+ request['accountType'] = type;
8195
+ //
8196
+ // isolated
8197
+ // {
8198
+ // "code": "200000",
8199
+ // "data": {
8200
+ // "accountType": "ISOLATED",
8201
+ // "ts": 1774244660519,
8202
+ // "accounts": [
8203
+ // {
8204
+ // "accountSubtype": "LTC-USDT",
8205
+ // "riskRatio": "0",
8206
+ // "currencies": [
8207
+ // {
8208
+ // "currency": "LTC",
8209
+ // "hold": "0",
8210
+ // "available": "0",
8211
+ // "liability": "0",
8212
+ // "balance": "0",
8213
+ // "equity": "0"},{
8214
+ // "currency": "USDT",
8215
+ // "hold": "0",
8216
+ // "available": "6",
8217
+ // "liability": "0",
8218
+ // "balance": "6",
8219
+ // "equity": "6"
8220
+ // }
8221
+ // ]
8222
+ // }
8223
+ // ]
8224
+ // }
8225
+ // }
8226
+ //
8227
+ response = await this.utaPrivateGetAccountBalance(this.extend(request, params));
8228
+ }
8229
+ const data = this.safeDict(response, 'data', {});
8230
+ const timestamp = this.safeInteger(data, 'ts');
8231
+ const result = {
8232
+ 'info': response,
8233
+ 'timestamp': timestamp,
8234
+ 'datetime': this.iso8601(timestamp),
8235
+ };
8236
+ const accounts = this.safeList(data, 'accounts', []);
8237
+ if (isIsolated) {
8238
+ for (let i = 0; i < accounts.length; i++) {
8239
+ const entry = accounts[i];
8240
+ const marketId = this.safeString(entry, 'accountSubtype');
8241
+ const symbol = this.safeSymbol(marketId, undefined, '-');
8242
+ const subResult = {};
8243
+ const currencies = this.safeList(entry, 'currencies', []);
8244
+ for (let j = 0; j < currencies.length; j++) {
8245
+ const currencyEntry = this.safeDict(currencies, j, {});
8246
+ const currencyId = this.safeString(currencyEntry, 'currency');
8247
+ const currencyCode = this.safeCurrencyCode(currencyId);
8248
+ subResult[currencyCode] = this.parseBalanceHelper(currencyEntry);
8249
+ }
8250
+ result[symbol] = this.safeBalance(subResult);
8251
+ }
8252
+ }
8253
+ else {
8254
+ const firstAccount = this.safeDict(accounts, 0, {});
8255
+ const currencies = this.safeList(firstAccount, 'currencies', []);
8256
+ for (let i = 0; i < currencies.length; i++) {
8257
+ const currencyEntry = this.safeDict(currencies, i, {});
8258
+ const currencyId = this.safeString(currencyEntry, 'currency');
8259
+ const currencyCode = this.safeCurrencyCode(currencyId);
8260
+ result[currencyCode] = this.parseBalanceHelper(currencyEntry);
8261
+ }
8262
+ }
8263
+ let returnType = result;
8264
+ if (!isIsolated) {
8265
+ returnType = this.safeBalance(result);
8266
+ }
8267
+ return returnType;
8268
+ }
7111
8269
  /**
7112
8270
  * @method
7113
8271
  * @name kucoin#transfer
7114
8272
  * @description transfer currency internally between wallets on the same account
7115
8273
  * @see https://www.kucoin.com/docs-new/rest/account-info/transfer/flex-transfer?lang=en_US&
8274
+ * @see https://www.kucoin.com/docs-new/rest/ua/flex-transfer
8275
+ * @param {string} code unified currency code
8276
+ * @param {float} amount amount to transfer
8277
+ * @param {string} fromAccount account to transfer from
8278
+ * @param {string} toAccount account to transfer to
8279
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
8280
+ * @param {boolean} [params.uta] set to true for the unified trading account (uta) endpoint, defaults to false
8281
+ * Check transferClassic() and transferUta() for more details on params
8282
+ * @returns {object} a [transfer structure]{@link https://docs.ccxt.com/?id=transfer-structure}
8283
+ */
8284
+ async transfer(code, amount, fromAccount, toAccount, params = {}) {
8285
+ await this.loadMarkets();
8286
+ let uta = await this.isUTAEnabled();
8287
+ [uta, params] = this.handleOptionAndParams(params, 'transfer', 'uta', uta);
8288
+ if (uta) {
8289
+ return await this.transferUta(code, amount, fromAccount, toAccount, params);
8290
+ }
8291
+ return await this.transferClassic(code, amount, fromAccount, toAccount, params);
8292
+ }
8293
+ /**
8294
+ * @method
8295
+ * @name kucoin#transferUta
8296
+ * @description transfer currency internally between wallets on the same account with uta endpoint
8297
+ * @see https://www.kucoin.com/docs-new/rest/ua/flex-transfer
8298
+ * @param {string} code unified currency code
8299
+ * @param {float} amount amount to transfer
8300
+ * @param {string} fromAccount account to transfer from
8301
+ * @param {string} toAccount account to transfer to
8302
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
8303
+ * @param {string} [params.transferType] INTERNAL, PARENT_TO_SUB, SUB_TO_PARENT, SUB_TO_SUB (default is INTERNAL)
8304
+ * @param {string} [params.fromUserId] required if transferType is SUB_TO_PARENT or SUB_TO_SUB
8305
+ * @param {string} [params.toUserId] required if transferType is PARENT_TO_SUB or SUB_TO_SUB
8306
+ * @returns {object} a [transfer structure]{@link https://docs.ccxt.com/?id=transfer-structure}
8307
+ */
8308
+ async transferUta(code, amount, fromAccount, toAccount, params = {}) {
8309
+ await this.loadMarkets();
8310
+ const currency = this.currency(code);
8311
+ const requestedAmount = this.currencyToPrecision(code, amount);
8312
+ const request = {
8313
+ 'currency': currency['id'],
8314
+ 'amount': requestedAmount,
8315
+ };
8316
+ let transferType = 'INTERNAL';
8317
+ [transferType, params] = this.handleParamString2(params, 'transferType', 'type', transferType);
8318
+ let fromUserId = undefined;
8319
+ [fromUserId, params] = this.handleParamString2(params, 'fromUserId', 'fromUid', fromUserId);
8320
+ let toUserId = undefined;
8321
+ [toUserId, params] = this.handleParamString2(params, 'toUserId', 'toUid', toUserId);
8322
+ if (transferType === 'PARENT_TO_SUB' || transferType === 'SUB_TO_SUB') {
8323
+ if (toUserId === undefined) {
8324
+ throw new errors.ExchangeError(this.id + ' transfer() requires a toUserId param for PARENT_TO_SUB or SUB_TO_SUB transfers');
8325
+ }
8326
+ else {
8327
+ request['toUid'] = toUserId;
8328
+ }
8329
+ }
8330
+ else if (transferType === 'SUB_TO_PARENT' || transferType === 'SUB_TO_SUB') {
8331
+ if (fromUserId === undefined) {
8332
+ throw new errors.ExchangeError(this.id + ' transfer() requires a fromUserId param for SUB_TO_PARENT or SUB_TO_SUB transfers');
8333
+ }
8334
+ else {
8335
+ request['fromUid'] = fromUserId;
8336
+ }
8337
+ }
8338
+ let clientOid = this.uuid();
8339
+ [clientOid, params] = this.handleParamString2(params, 'clientOid', 'clientOrderId', clientOid);
8340
+ request['clientOid'] = clientOid;
8341
+ let fromId = this.convertTypeToAccount(fromAccount);
8342
+ let toId = this.convertTypeToAccount(toAccount);
8343
+ const fromIsolated = this.inArray(fromId, this.ids);
8344
+ const toIsolated = this.inArray(toId, this.ids);
8345
+ if (fromIsolated) {
8346
+ request['fromAccountSymbol'] = fromId;
8347
+ fromId = 'ISOLATED';
8348
+ }
8349
+ if (toIsolated) {
8350
+ request['toAccountSymbol'] = toId;
8351
+ toId = 'ISOLATED';
8352
+ }
8353
+ const utaAccountsByType = this.safeDict(this.options, 'utaAccountsByType', {});
8354
+ fromId = this.safeString(utaAccountsByType, fromId, fromId);
8355
+ toId = this.safeString(utaAccountsByType, toId, toId);
8356
+ request['fromAccountType'] = fromId.toUpperCase();
8357
+ request['toAccountType'] = toId.toUpperCase();
8358
+ const types = {
8359
+ 'INTERNAL': '0',
8360
+ 'PARENT_TO_SUB': '1',
8361
+ 'SUB_TO_PARENT': '2',
8362
+ 'SUB_TO_SUB': '3',
8363
+ };
8364
+ request['type'] = this.safeString(types, transferType, transferType);
8365
+ const response = await this.utaPrivatePostAccountTransfer(this.extend(request, params));
8366
+ //
8367
+ //
8368
+ const data = this.safeDict(response, 'data');
8369
+ const transfer = this.parseTransfer(data, currency);
8370
+ const transferOptions = this.safeDict(this.options, 'transfer', {});
8371
+ const fillResponseFromRequest = this.safeBool(transferOptions, 'fillResponseFromRequest', true);
8372
+ if (fillResponseFromRequest) {
8373
+ transfer['amount'] = amount;
8374
+ transfer['fromAccount'] = fromAccount;
8375
+ transfer['toAccount'] = toAccount;
8376
+ transfer['status'] = 'ok';
8377
+ }
8378
+ return transfer;
8379
+ }
8380
+ /**
8381
+ * @method
8382
+ * @name kucoin#transferClassic
8383
+ * @description transfer currency internally between wallets on the same account with classic endpoints
8384
+ * @see https://www.kucoin.com/docs-new/rest/account-info/transfer/flex-transfer?lang=en_US&
7116
8385
  * @param {string} code unified currency code
7117
8386
  * @param {float} amount amount to transfer
7118
8387
  * @param {string} fromAccount account to transfer from
@@ -7123,7 +8392,7 @@ class kucoin extends kucoin$1["default"] {
7123
8392
  * @param {string} [params.toUserId] required if transferType is PARENT_TO_SUB
7124
8393
  * @returns {object} a [transfer structure]{@link https://docs.ccxt.com/?id=transfer-structure}
7125
8394
  */
7126
- async transfer(code, amount, fromAccount, toAccount, params = {}) {
8395
+ async transferClassic(code, amount, fromAccount, toAccount, params = {}) {
7127
8396
  await this.loadMarkets();
7128
8397
  const currency = this.currency(code);
7129
8398
  const requestedAmount = this.currencyToPrecision(code, amount);
@@ -7337,12 +8606,32 @@ class kucoin extends kucoin$1["default"] {
7337
8606
  // 'Pool transactions': 'Pool transactions', // Pool-X transactions
7338
8607
  'Instant Exchange': 'trade',
7339
8608
  'Sub-account transfer': 'transfer',
7340
- 'Liquidation Fees': 'fee', // Liquidation Fees
8609
+ 'Liquidation Fees': 'fee',
7341
8610
  // 'Soft Staking Profits': 'Soft Staking Profits', // Soft Staking Profits
7342
8611
  // 'Voting Earnings': 'Voting Earnings', // Voting Earnings on Pool-X
7343
8612
  // 'Redemption of Voting': 'Redemption of Voting', // Redemption of Voting on Pool-X
7344
8613
  // 'Voting': 'Voting', // Voting on Pool-X
7345
8614
  // 'Convert to KCS': 'Convert to KCS', // Convert to KCS
8615
+ 'RealisedPNL': 'trade',
8616
+ 'TransferIn': 'transfer',
8617
+ 'TransferOut': 'transfer',
8618
+ 'TRADE_EXCHANGE': 'trade',
8619
+ 'TRANSFER': 'transfer',
8620
+ 'SUB_TRANSFER': 'transfer',
8621
+ 'RETURNED_FEES': 'fee',
8622
+ 'DEDUCTION_FEES': 'fee',
8623
+ 'OTHER': 'other',
8624
+ 'SUB_TO_SUB_TRANSFER': 'transfer',
8625
+ 'SPOT_EXCHANGE': 'trade',
8626
+ 'SPOT_EXCHANGE_REBATE': 'rebate',
8627
+ 'FUTURES_EXCHANGE_OPEN': 'trade',
8628
+ 'FUTURES_EXCHANGE_CLOSE': 'trade',
8629
+ 'FUTURES_EXCHANGE_REBATE': 'rebate',
8630
+ 'FUNDING_FEE': 'fee',
8631
+ 'LIABILITY_INTEREST': 'fee',
8632
+ 'KCS_DEDUCTION_FEES': 'fee',
8633
+ 'KCS_RETURNED_FEES': 'fee',
8634
+ 'AUTO_EXCHANGE_USER': 'trade',
7346
8635
  };
7347
8636
  return this.safeString(types, type, type);
7348
8637
  }
@@ -7352,6 +8641,8 @@ class kucoin extends kucoin$1["default"] {
7352
8641
  'out': 'out',
7353
8642
  'TransferIn': 'in',
7354
8643
  'TransferOut': 'out',
8644
+ 'IN': 'in',
8645
+ 'OUT': 'out',
7355
8646
  };
7356
8647
  return this.safeString(directions, direction, direction);
7357
8648
  }
@@ -7390,14 +8681,28 @@ class kucoin extends kucoin$1["default"] {
7390
8681
  // "currency": "USDT"
7391
8682
  // }
7392
8683
  //
8684
+ // ledger entry from UTA API
8685
+ // {
8686
+ // "accountType": "UNIFIED",
8687
+ // "id": "30000000001200350",
8688
+ // "currency": "USDT",
8689
+ // "direction": "IN",
8690
+ // "businessType": "TRANSFER",
8691
+ // "amount": "30",
8692
+ // "balance": "30",
8693
+ // "fee": "0",
8694
+ // "tax": "0",
8695
+ // "remark": "Funding Account",
8696
+ // "ts": 1774241648267000000
8697
+ // }
8698
+ //
7393
8699
  const id = this.safeString(item, 'id');
7394
8700
  const currencyId = this.safeString(item, 'currency');
7395
8701
  const code = this.safeCurrencyCode(currencyId, currency);
7396
8702
  currency = this.safeCurrency(currencyId, currency);
7397
8703
  const amount = this.safeString(item, 'amount');
7398
- const balanceAfter = undefined;
7399
- // const balanceAfter = this.safeNumber (item, 'balance'); only returns zero string
7400
- const bizType = this.safeString(item, 'bizType');
8704
+ const balanceAfter = this.safeNumberOmitZero(item, 'balance');
8705
+ const bizType = this.safeStringN(item, ['bizType', 'businessType', 'type']);
7401
8706
  const type = this.parseLedgerEntryType(bizType);
7402
8707
  const direction = this.safeString2(item, 'direction', 'type');
7403
8708
  let account = this.safeString(item, 'accountType'); // MAIN, TRADE, MARGIN, or CONTRACT
@@ -7407,6 +8712,9 @@ class kucoin extends kucoin$1["default"] {
7407
8712
  if (timestamp !== undefined) {
7408
8713
  account = 'CONTRACT'; // contract ledger entries do not have an accountType field, so we set it to CONTRACT if the time field is present
7409
8714
  }
8715
+ else {
8716
+ timestamp = this.safeIntegerProduct(item, 'ts', 0.000001); // for UTA API
8717
+ }
7410
8718
  }
7411
8719
  const datetime = this.iso8601(timestamp);
7412
8720
  const context = this.safeString(item, 'context'); // contains other information about the ledger entry
@@ -7475,6 +8783,7 @@ class kucoin extends kucoin$1["default"] {
7475
8783
  * @see https://www.kucoin.com/docs-new/rest/account-info/account-funding/get-account-ledgers-tradehf
7476
8784
  * @see https://www.kucoin.com/docs-new/rest/account-info/account-funding/get-account-ledgers-marginhf
7477
8785
  * @see https://www.kucoin.com/docs-new/rest/account-info/account-funding/get-account-ledgers-futures
8786
+ * @see https://www.kucoin.com/docs-new/rest/ua/get-account-ledger
7478
8787
  * @param {string} [code] unified currency code, default is undefined
7479
8788
  * @param {int} [since] timestamp in ms of the earliest ledger entry, default is undefined
7480
8789
  * @param {int} [limit] max number of ledger entries to return, default is undefined
@@ -7482,18 +8791,50 @@ class kucoin extends kucoin$1["default"] {
7482
8791
  * @param {object} [params.type] extra parameters specific to the exchange API endpoint
7483
8792
  * @param {boolean} [params.hf] default false, when true will fetch ledger entries for the high frequency trading account
7484
8793
  * @param {int} [params.until] the latest time in ms to fetch entries for
8794
+ * @param {boolean} [params.uta] default false, when true will fetch ledger entries for the unified trading account (UTA) instead of the regular accounts endpoint
7485
8795
  * @param {boolean} [params.paginate] default false, when true will automatically paginate by calling this endpoint multiple times. See in the docs all the [available parameters](https://github.com/ccxt/ccxt/wiki/Manual#pagination-params)
7486
8796
  * @returns {object} a [ledger structure]{@link https://docs.ccxt.com/?id=ledger-entry-structure}
7487
8797
  */
7488
8798
  async fetchLedger(code = undefined, since = undefined, limit = undefined, params = {}) {
7489
8799
  await this.loadMarkets();
7490
8800
  await this.loadAccounts();
7491
- let paginate = false;
7492
- [paginate, params] = this.handleOptionAndParams(params, 'fetchLedger', 'paginate');
8801
+ let uta = await this.isUTAEnabled();
8802
+ [uta, params] = this.handleOptionAndParams(params, 'fetchLedger', 'uta', uta);
7493
8803
  let hf = undefined;
7494
8804
  [hf, params] = this.handleHfAndParams(params);
8805
+ let requestedType = undefined;
8806
+ [requestedType, params] = this.handleMarketTypeAndParams('fetchLedger', undefined, params);
8807
+ let marginMode = undefined;
8808
+ [marginMode, params] = this.handleMarginModeAndParams('fetchLedger', params);
8809
+ if (uta && (requestedType === 'margin')) {
8810
+ marginMode = (marginMode === undefined) ? 'cross' : marginMode; // default to cross margin for UTA if margin is requested but marginMode is not specified
8811
+ requestedType = marginMode;
8812
+ }
8813
+ let accountsByType = this.safeDict(this.options, 'accountsByType');
8814
+ if (uta) {
8815
+ accountsByType = this.safeDict(this.options, 'utaAccountsByType');
8816
+ }
8817
+ let type = undefined;
8818
+ type = this.safeString(accountsByType, requestedType, requestedType);
8819
+ let maxLimit = 500; // for spot non-uta and margin
8820
+ if (hf) {
8821
+ maxLimit = 200;
8822
+ }
8823
+ else if (type === 'contract') {
8824
+ maxLimit = 50;
8825
+ }
8826
+ else if (uta) {
8827
+ if ((type === 'UNIFIED') || (type === 'SPOT')) {
8828
+ maxLimit = 200;
8829
+ }
8830
+ else if (type === 'FUTURES') {
8831
+ maxLimit = 100;
8832
+ }
8833
+ }
8834
+ let paginate = false;
8835
+ [paginate, params] = this.handleOptionAndParams(params, 'fetchLedger', 'paginate');
7495
8836
  if (paginate) {
7496
- return await this.fetchPaginatedCallDynamic('fetchLedger', code, since, limit, params);
8837
+ return await this.fetchPaginatedCallDynamic('fetchLedger', code, since, limit, params, maxLimit);
7497
8838
  }
7498
8839
  let request = {
7499
8840
  // 'currency': currency['id'], // can choose up to 10, if not provided returns for all currencies by default
@@ -7512,14 +8853,23 @@ class kucoin extends kucoin$1["default"] {
7512
8853
  request['currency'] = currency['id'];
7513
8854
  }
7514
8855
  [request, params] = this.handleUntilOption('endAt', request, params);
7515
- let marginMode = undefined;
7516
- [marginMode, params] = this.handleMarginModeAndParams('fetchLedger', params);
7517
- let type = undefined;
7518
- [type, params] = this.handleMarketTypeAndParams('fetchLedger', undefined, params);
7519
- const accountsByType = this.safeDict(this.options, 'accountsByType');
7520
- type = this.safeString(accountsByType, type, type);
8856
+ if (limit !== undefined) {
8857
+ if (type === 'contract') {
8858
+ request['maxCount'] = limit;
8859
+ }
8860
+ else if (hf) {
8861
+ request['limit'] = limit;
8862
+ }
8863
+ else {
8864
+ request['pageSize'] = limit;
8865
+ }
8866
+ }
7521
8867
  let response = undefined;
7522
- if (hf) {
8868
+ if (uta) {
8869
+ request['accountType'] = type;
8870
+ response = await this.utaPrivateGetAccountLedger(this.extend(request, params));
8871
+ }
8872
+ else if (hf) {
7523
8873
  if (marginMode !== undefined) {
7524
8874
  response = await this.privateGetHfMarginAccountLedgers(this.extend(request, params));
7525
8875
  }
@@ -7761,12 +9111,14 @@ class kucoin extends kucoin$1["default"] {
7761
9111
  // Cross
7762
9112
  //
7763
9113
  // {
7764
- // "currency": "1INCH",
7765
- // "total": "0",
7766
- // "available": "0",
9114
+ // "currency": "DOGE",
9115
+ // "total": "119.99995308",
9116
+ // "available": "119.99995308",
7767
9117
  // "hold": "0",
7768
- // "liability": "0",
7769
- // "maxBorrowSize": "0",
9118
+ // "liability": "10.00004692",
9119
+ // "liabilityPrincipal": "10",
9120
+ // "liabilityInterest": "0.00004692",
9121
+ // "maxBorrowSize": "1140",
7770
9122
  // "borrowEnabled": true,
7771
9123
  // "transferInEnabled": true
7772
9124
  // }
@@ -7774,30 +9126,32 @@ class kucoin extends kucoin$1["default"] {
7774
9126
  // Isolated
7775
9127
  //
7776
9128
  // {
7777
- // "symbol": "MANA-USDT",
7778
- // "debtRatio": "0",
7779
- // "status": "BORROW",
9129
+ // "symbol": "DOGE-USDT",
9130
+ // "status": "EFFECTIVE",
9131
+ // "debtRatio": "0.0822",
7780
9132
  // "baseAsset": {
7781
- // "currency": "MANA",
9133
+ // "currency": "DOGE",
7782
9134
  // "borrowEnabled": true,
7783
- // "repayEnabled": true,
7784
- // "transferEnabled": true,
7785
- // "borrowed": "0",
7786
- // "totalAsset": "0",
7787
- // "available": "0",
9135
+ // "transferInEnabled": true,
9136
+ // "liability": "10.00009385",
9137
+ // "liabilityPrincipal": "10.00004692",
9138
+ // "liabilityInterest": "0.00004693",
9139
+ // "total": "10",
9140
+ // "available": "10",
7788
9141
  // "hold": "0",
7789
- // "maxBorrowSize": "1000"
9142
+ // "maxBorrowSize": "990"
7790
9143
  // },
7791
9144
  // "quoteAsset": {
7792
9145
  // "currency": "USDT",
7793
9146
  // "borrowEnabled": true,
7794
- // "repayEnabled": true,
7795
- // "transferEnabled": true,
7796
- // "borrowed": "0",
7797
- // "totalAsset": "0",
7798
- // "available": "0",
9147
+ // "transferInEnabled": true,
9148
+ // "liability": "0",
9149
+ // "liabilityPrincipal": "0",
9150
+ // "liabilityInterest": "0",
9151
+ // "total": "10",
9152
+ // "available": "10",
7799
9153
  // "hold": "0",
7800
- // "maxBorrowSize": "50000"
9154
+ // "maxBorrowSize": "89"
7801
9155
  // }
7802
9156
  // }
7803
9157
  //
@@ -7805,19 +9159,18 @@ class kucoin extends kucoin$1["default"] {
7805
9159
  const marginMode = (marketId === undefined) ? 'cross' : 'isolated';
7806
9160
  market = this.safeMarket(marketId, market);
7807
9161
  const symbol = this.safeString(market, 'symbol');
7808
- const timestamp = this.safeInteger(info, 'createdAt');
7809
9162
  const isolatedBase = this.safeDict(info, 'baseAsset', {});
7810
9163
  let amountBorrowed = undefined;
7811
9164
  let interest = undefined;
7812
9165
  let currencyId = undefined;
7813
9166
  if (marginMode === 'isolated') {
7814
- amountBorrowed = this.safeNumber(isolatedBase, 'liability');
7815
- interest = this.safeNumber(isolatedBase, 'interest');
9167
+ amountBorrowed = this.safeNumber(isolatedBase, 'liabilityPrincipal');
9168
+ interest = this.safeNumber(isolatedBase, 'liabilityInterest');
7816
9169
  currencyId = this.safeString(isolatedBase, 'currency');
7817
9170
  }
7818
9171
  else {
7819
- amountBorrowed = this.safeNumber(info, 'liability');
7820
- interest = this.safeNumber(info, 'accruedInterest');
9172
+ amountBorrowed = this.safeNumber(info, 'liabilityPrincipal');
9173
+ interest = this.safeNumber(info, 'liabilityInterest');
7821
9174
  currencyId = this.safeString(info, 'currency');
7822
9175
  }
7823
9176
  return {
@@ -7828,8 +9181,8 @@ class kucoin extends kucoin$1["default"] {
7828
9181
  'interestRate': this.safeNumber(info, 'dailyIntRate'),
7829
9182
  'amountBorrowed': amountBorrowed,
7830
9183
  'marginMode': marginMode,
7831
- 'timestamp': timestamp,
7832
- 'datetime': this.iso8601(timestamp),
9184
+ 'timestamp': undefined,
9185
+ 'datetime': undefined,
7833
9186
  };
7834
9187
  }
7835
9188
  /**
@@ -8212,9 +9565,11 @@ class kucoin extends kucoin$1["default"] {
8212
9565
  * @description set the level of leverage for a market
8213
9566
  * @see https://www.kucoin.com/docs-new/rest/margin-trading/debit/modify-leverage
8214
9567
  * @see https://www.kucoin.com/docs-new/rest/futures-trading/positions/modify-cross-margin-leverage
9568
+ * @see https://www.kucoin.com/docs-new/rest/ua/modify-leverage-uta
8215
9569
  * @param {int } [leverage] New leverage multiplier. Must be greater than 1 and up to two decimal places, and cannot be less than the user's current debt leverage or greater than the system's maximum leverage
8216
9570
  * @param {string} [symbol] unified market symbol
8217
9571
  * @param {object} [params] extra parameters specific to the exchange API endpoint
9572
+ * @param {boolean} [params.uta] *contract markets only* set to true for the unified trading account (uta)
8218
9573
  * @returns {object} response from the exchange
8219
9574
  */
8220
9575
  async setLeverage(leverage, symbol = undefined, params = {}) {
@@ -8223,11 +9578,19 @@ class kucoin extends kucoin$1["default"] {
8223
9578
  let marketType = undefined;
8224
9579
  [marketType, params] = this.handleMarketTypeAndParams('setLeverage', undefined, params);
8225
9580
  if ((symbol !== undefined) || ((marketType !== 'spot') && (marketType !== 'margin'))) {
9581
+ if (symbol === undefined) {
9582
+ throw new errors.ArgumentsRequired(this.id + ' setLeverage requires a symbol argument for contract markets');
9583
+ }
8226
9584
  market = this.market(symbol);
8227
9585
  if (market['contract']) {
8228
9586
  return await this.setContractLeverage(leverage, symbol, params);
8229
9587
  }
8230
9588
  }
9589
+ let uta = await this.isUTAEnabled();
9590
+ [uta, params] = this.handleOptionAndParams(params, 'setLeverage', 'uta', uta);
9591
+ if (uta) {
9592
+ throw new errors.NotSupported(this.id + ' setLeverage with params["uta"] is supported for contract markets only');
9593
+ }
8231
9594
  let marginMode = undefined;
8232
9595
  [marginMode, params] = this.handleMarginModeAndParams('setLeverage', params);
8233
9596
  if (marginMode === undefined) {
@@ -8249,15 +9612,17 @@ class kucoin extends kucoin$1["default"] {
8249
9612
  * @name kucoin#setContractLeverage
8250
9613
  * @description set the level of leverage for a market
8251
9614
  * @see https://www.kucoin.com/docs-new/rest/futures-trading/positions/modify-cross-margin-leverage
9615
+ * @see https://www.kucoin.com/docs-new/rest/ua/modify-leverage-uta
8252
9616
  * @param {float} leverage the rate of leverage
8253
9617
  * @param {string} symbol unified market symbol
8254
9618
  * @param {object} [params] extra parameters specific to the exchange API endpoint
9619
+ * @param {boolean} [params.uta] set to true for the unified trading account (uta)
8255
9620
  * @returns {object} response from the exchange
8256
9621
  */
8257
9622
  async setContractLeverage(leverage, symbol = undefined, params = {}) {
8258
9623
  let marginMode = undefined;
8259
9624
  [marginMode, params] = this.handleMarginModeAndParams(symbol, params);
8260
- if (marginMode !== 'cross') {
9625
+ if ((marginMode !== undefined) && (marginMode !== 'cross')) {
8261
9626
  throw new errors.NotSupported(this.id + ' setLeverage() currently supports only params["marginMode"] = "cross" for contracts');
8262
9627
  }
8263
9628
  await this.loadMarkets();
@@ -8266,14 +9631,24 @@ class kucoin extends kucoin$1["default"] {
8266
9631
  'symbol': market['id'],
8267
9632
  'leverage': leverage.toString(),
8268
9633
  };
8269
- const response = await this.futuresPrivatePostChangeCrossUserLeverage(this.extend(request, params));
8270
- //
8271
- // {
8272
- // "code": "200000",
8273
- // "data": true
8274
- // }
8275
- //
8276
- const leverageNum = this.safeInteger(response, 'leverage');
9634
+ let uta = await this.isUTAEnabled();
9635
+ [uta, params] = this.handleOptionAndParams(params, 'setLeverage', 'uta', uta);
9636
+ let response = undefined;
9637
+ if (uta) {
9638
+ request['accountMode'] = 'unified';
9639
+ response = await this.utaPrivatePostAccountModeAccountModifyLeverage(this.extend(request, params));
9640
+ }
9641
+ else {
9642
+ //
9643
+ // {
9644
+ // "code": "200000",
9645
+ // "data": true
9646
+ // }
9647
+ //
9648
+ response = await this.futuresPrivatePostChangeCrossUserLeverage(this.extend(request, params));
9649
+ }
9650
+ const data = this.safeDict(response, 'data', {});
9651
+ const leverageNum = this.safeNumber(data, 'leverage');
8277
9652
  return {
8278
9653
  'info': response,
8279
9654
  'symbol': market['symbol'],
@@ -8432,7 +9807,7 @@ class kucoin extends kucoin$1["default"] {
8432
9807
  'symbol': market['id'],
8433
9808
  };
8434
9809
  const until = this.safeInteger(params, 'until');
8435
- let uta = true; // for backward compatibility, dafult endpoint is uta
9810
+ let uta = false;
8436
9811
  [uta, params] = this.handleOptionAndParams(params, 'fetchFundingRateHistory', 'uta', uta);
8437
9812
  params = this.omit(params, 'until');
8438
9813
  let start = since;
@@ -8587,9 +9962,11 @@ class kucoin extends kucoin$1["default"] {
8587
9962
  * @method
8588
9963
  * @name kucoin#fetchPosition
8589
9964
  * @see https://www.kucoin.com/docs-new/rest/futures-trading/positions/get-position-details
9965
+ * @see https://www.kucoin.com/docs-new/rest/ua/get-position-list-uta
8590
9966
  * @description fetch data on an open position
8591
9967
  * @param {string} symbol unified market symbol of the market the position is held in
8592
9968
  * @param {object} [params] extra parameters specific to the exchange API endpoint
9969
+ * @param {boolean} [params.uta] set to true for the unified trading account (uta), defaults to false
8593
9970
  * @returns {object} a [position structure]{@link https://docs.ccxt.com/?id=position-structure}
8594
9971
  */
8595
9972
  async fetchPosition(symbol, params = {}) {
@@ -8598,112 +9975,157 @@ class kucoin extends kucoin$1["default"] {
8598
9975
  const request = {
8599
9976
  'symbol': market['id'],
8600
9977
  };
8601
- const response = await this.futuresPrivateGetPosition(this.extend(request, params));
8602
- //
8603
- // {
8604
- // "code": "200000",
8605
- // "data": {
8606
- // "id": "6505ee6eaff4070001f651c4",
8607
- // "symbol": "XBTUSDTM",
8608
- // "autoDeposit": false,
8609
- // "maintMarginReq": 0,
8610
- // "riskLimit": 200,
8611
- // "realLeverage": 0.0,
8612
- // "crossMode": false,
8613
- // "delevPercentage": 0.0,
8614
- // "currentTimestamp": 1694887534594,
8615
- // "currentQty": 0,
8616
- // "currentCost": 0.0,
8617
- // "currentComm": 0.0,
8618
- // "unrealisedCost": 0.0,
8619
- // "realisedGrossCost": 0.0,
8620
- // "realisedCost": 0.0,
8621
- // "isOpen": false,
8622
- // "markPrice": 26611.71,
8623
- // "markValue": 0.0,
8624
- // "posCost": 0.0,
8625
- // "posCross": 0,
8626
- // "posInit": 0.0,
8627
- // "posComm": 0.0,
8628
- // "posLoss": 0.0,
8629
- // "posMargin": 0.0,
8630
- // "posMaint": 0.0,
8631
- // "maintMargin": 0.0,
8632
- // "realisedGrossPnl": 0.0,
8633
- // "realisedPnl": 0.0,
8634
- // "unrealisedPnl": 0.0,
8635
- // "unrealisedPnlPcnt": 0,
8636
- // "unrealisedRoePcnt": 0,
8637
- // "avgEntryPrice": 0.0,
8638
- // "liquidationPrice": 0.0,
8639
- // "bankruptPrice": 0.0,
8640
- // "settleCurrency": "USDT",
8641
- // "maintainMargin": 0,
8642
- // "riskLimitLevel": 1
8643
- // }
8644
- // }
8645
- //
8646
- const data = this.safeDict(response, 'data', {});
8647
- return this.parsePosition(data, market);
9978
+ let uta = await this.isUTAEnabled();
9979
+ [uta, params] = this.handleOptionAndParams(params, 'fetchPosition', 'uta', uta);
9980
+ let response = undefined;
9981
+ let position = undefined;
9982
+ if (uta) {
9983
+ request['accountMode'] = 'unified';
9984
+ response = await this.utaPrivateGetAccountModePositionOpenList(this.extend(request, params));
9985
+ //
9986
+ // {
9987
+ // "code": "200000",
9988
+ // "data": [
9989
+ // {
9990
+ // "symbol": "DOGEUSDTM",
9991
+ // "id": "30000000000084351",
9992
+ // "marginMode": "CROSS",
9993
+ // "size": "2",
9994
+ // "entryPrice": "0.093795",
9995
+ // "positionValue": "18.298",
9996
+ // "markPrice": "0.09149",
9997
+ // "leverage": "3",
9998
+ // "unrealizedPnL": "-0.461",
9999
+ // "realizedPnL": "-0.01122489",
10000
+ // "initialMargin": "6.0993333327234",
10001
+ // "mmr": "0.007",
10002
+ // "maintenanceMargin": "0.128086",
10003
+ // "creationTime": 1774469753178000000
10004
+ // }
10005
+ // ]
10006
+ // }
10007
+ //
10008
+ const data = this.safeList(response, 'data', []);
10009
+ position = this.safeDict(data, 0, {});
10010
+ }
10011
+ else {
10012
+ response = await this.futuresPrivateGetPosition(this.extend(request, params));
10013
+ //
10014
+ // {
10015
+ // "code": "200000",
10016
+ // "data": {
10017
+ // "id": "6505ee6eaff4070001f651c4",
10018
+ // "symbol": "XBTUSDTM",
10019
+ // "autoDeposit": false,
10020
+ // "maintMarginReq": 0,
10021
+ // "riskLimit": 200,
10022
+ // "realLeverage": 0.0,
10023
+ // "crossMode": false,
10024
+ // "delevPercentage": 0.0,
10025
+ // "currentTimestamp": 1694887534594,
10026
+ // "currentQty": 0,
10027
+ // "currentCost": 0.0,
10028
+ // "currentComm": 0.0,
10029
+ // "unrealisedCost": 0.0,
10030
+ // "realisedGrossCost": 0.0,
10031
+ // "realisedCost": 0.0,
10032
+ // "isOpen": false,
10033
+ // "markPrice": 26611.71,
10034
+ // "markValue": 0.0,
10035
+ // "posCost": 0.0,
10036
+ // "posCross": 0,
10037
+ // "posInit": 0.0,
10038
+ // "posComm": 0.0,
10039
+ // "posLoss": 0.0,
10040
+ // "posMargin": 0.0,
10041
+ // "posMaint": 0.0,
10042
+ // "maintMargin": 0.0,
10043
+ // "realisedGrossPnl": 0.0,
10044
+ // "realisedPnl": 0.0,
10045
+ // "unrealisedPnl": 0.0,
10046
+ // "unrealisedPnlPcnt": 0,
10047
+ // "unrealisedRoePcnt": 0,
10048
+ // "avgEntryPrice": 0.0,
10049
+ // "liquidationPrice": 0.0,
10050
+ // "bankruptPrice": 0.0,
10051
+ // "settleCurrency": "USDT",
10052
+ // "maintainMargin": 0,
10053
+ // "riskLimitLevel": 1
10054
+ // }
10055
+ // }
10056
+ //
10057
+ position = this.safeDict(response, 'data', {});
10058
+ }
10059
+ return this.parsePosition(position, market);
8648
10060
  }
8649
10061
  /**
8650
10062
  * @method
8651
10063
  * @name kucoin#fetchPositions
8652
10064
  * @description fetch all open positions
8653
10065
  * @see https://www.kucoin.com/docs-new/rest/futures-trading/positions/get-position-list
10066
+ * @see https://www.kucoin.com/docs-new/rest/ua/get-position-list-uta
8654
10067
  * @param {string[]|undefined} symbols list of unified market symbols
8655
10068
  * @param {object} [params] extra parameters specific to the exchange API endpoint
10069
+ * @param {boolean} [params.uta] set to true for the unified trading account (uta), defaults to false
8656
10070
  * @returns {object[]} a list of [position structure]{@link https://docs.ccxt.com/?id=position-structure}
8657
10071
  */
8658
10072
  async fetchPositions(symbols = undefined, params = {}) {
8659
10073
  await this.loadMarkets();
8660
- const response = await this.futuresPrivateGetPositions(params);
8661
- //
8662
- // {
8663
- // "code": "200000",
8664
- // "data": [
8665
- // {
8666
- // "id": "615ba79f83a3410001cde321",
8667
- // "symbol": "ETHUSDTM",
8668
- // "autoDeposit": false,
8669
- // "maintMarginReq": 0.005,
8670
- // "riskLimit": 1000000,
8671
- // "realLeverage": 18.61,
8672
- // "crossMode": false,
8673
- // "delevPercentage": 0.86,
8674
- // "openingTimestamp": 1638563515618,
8675
- // "currentTimestamp": 1638576872774,
8676
- // "currentQty": 2,
8677
- // "currentCost": 83.64200000,
8678
- // "currentComm": 0.05018520,
8679
- // "unrealisedCost": 83.64200000,
8680
- // "realisedGrossCost": 0.00000000,
8681
- // "realisedCost": 0.05018520,
8682
- // "isOpen": true,
8683
- // "markPrice": 4225.01,
8684
- // "markValue": 84.50020000,
8685
- // "posCost": 83.64200000,
8686
- // "posCross": 0.0000000000,
8687
- // "posInit": 3.63660870,
8688
- // "posComm": 0.05236717,
8689
- // "posLoss": 0.00000000,
8690
- // "posMargin": 3.68897586,
8691
- // "posMaint": 0.50637594,
8692
- // "maintMargin": 4.54717586,
8693
- // "realisedGrossPnl": 0.00000000,
8694
- // "realisedPnl": -0.05018520,
8695
- // "unrealisedPnl": 0.85820000,
8696
- // "unrealisedPnlPcnt": 0.0103,
8697
- // "unrealisedRoePcnt": 0.2360,
8698
- // "avgEntryPrice": 4182.10,
8699
- // "liquidationPrice": 4023.00,
8700
- // "bankruptPrice": 4000.25,
8701
- // "settleCurrency": "USDT",
8702
- // "isInverse": false
8703
- // }
8704
- // ]
8705
- // }
8706
- //
10074
+ let uta = await this.isUTAEnabled();
10075
+ [uta, params] = this.handleOptionAndParams(params, 'fetchPositions', 'uta', uta);
10076
+ let response = undefined;
10077
+ if (uta) {
10078
+ response = await this.utaPrivateGetAccountModePositionOpenList(this.extend(params, { 'accountMode': 'unified' }));
10079
+ }
10080
+ else {
10081
+ response = await this.futuresPrivateGetPositions(params);
10082
+ //
10083
+ // {
10084
+ // "code": "200000",
10085
+ // "data": [
10086
+ // {
10087
+ // "id": "615ba79f83a3410001cde321",
10088
+ // "symbol": "ETHUSDTM",
10089
+ // "autoDeposit": false,
10090
+ // "maintMarginReq": 0.005,
10091
+ // "riskLimit": 1000000,
10092
+ // "realLeverage": 18.61,
10093
+ // "crossMode": false,
10094
+ // "delevPercentage": 0.86,
10095
+ // "openingTimestamp": 1638563515618,
10096
+ // "currentTimestamp": 1638576872774,
10097
+ // "currentQty": 2,
10098
+ // "currentCost": 83.64200000,
10099
+ // "currentComm": 0.05018520,
10100
+ // "unrealisedCost": 83.64200000,
10101
+ // "realisedGrossCost": 0.00000000,
10102
+ // "realisedCost": 0.05018520,
10103
+ // "isOpen": true,
10104
+ // "markPrice": 4225.01,
10105
+ // "markValue": 84.50020000,
10106
+ // "posCost": 83.64200000,
10107
+ // "posCross": 0.0000000000,
10108
+ // "posInit": 3.63660870,
10109
+ // "posComm": 0.05236717,
10110
+ // "posLoss": 0.00000000,
10111
+ // "posMargin": 3.68897586,
10112
+ // "posMaint": 0.50637594,
10113
+ // "maintMargin": 4.54717586,
10114
+ // "realisedGrossPnl": 0.00000000,
10115
+ // "realisedPnl": -0.05018520,
10116
+ // "unrealisedPnl": 0.85820000,
10117
+ // "unrealisedPnlPcnt": 0.0103,
10118
+ // "unrealisedRoePcnt": 0.2360,
10119
+ // "avgEntryPrice": 4182.10,
10120
+ // "liquidationPrice": 4023.00,
10121
+ // "bankruptPrice": 4000.25,
10122
+ // "settleCurrency": "USDT",
10123
+ // "isInverse": false
10124
+ // }
10125
+ // ]
10126
+ // }
10127
+ //
10128
+ }
8707
10129
  const data = this.safeList(response, 'data');
8708
10130
  return this.parsePositions(data, symbols);
8709
10131
  }
@@ -8712,69 +10134,120 @@ class kucoin extends kucoin$1["default"] {
8712
10134
  * @name kucoin#fetchPositionsHistory
8713
10135
  * @description fetches historical positions
8714
10136
  * @see https://www.kucoin.com/docs-new/rest/futures-trading/positions/get-positions-history
10137
+ * @see https://www.kucoin.com/docs-new/rest/ua/get-position-history-uta
8715
10138
  * @param {string[]} [symbols] list of unified market symbols
8716
10139
  * @param {int} [since] the earliest time in ms to fetch position history for
8717
10140
  * @param {int} [limit] the maximum number of entries to retrieve
8718
10141
  * @param {object} [params] extra parameters specific to the exchange API endpoint
8719
10142
  * @param {int} [params.until] closing end time
8720
10143
  * @param {int} [params.pageId] page id
10144
+ * @param {boolean} [params.uta] set to true for the unified trading account (uta), defaults to false
8721
10145
  * @returns {object[]} a list of [position structure]{@link https://docs.ccxt.com/?id=position-structure}
8722
10146
  */
8723
10147
  async fetchPositionsHistory(symbols = undefined, since = undefined, limit = undefined, params = {}) {
8724
10148
  await this.loadMarkets();
8725
- if (limit === undefined) {
8726
- limit = 200;
10149
+ let uta = await this.isUTAEnabled();
10150
+ [uta, params] = this.handleOptionAndParams(params, 'fetchPositionsHistory', 'uta', uta);
10151
+ let response = undefined;
10152
+ let request = {};
10153
+ symbols = this.marketSymbols(symbols);
10154
+ if (symbols !== undefined) {
10155
+ const length = symbols.length;
10156
+ if (length === 1) {
10157
+ const market = this.market(symbols[0]);
10158
+ request['symbol'] = market['id'];
10159
+ }
8727
10160
  }
8728
- const request = {
8729
- 'limit': limit,
8730
- };
8731
- if (since !== undefined) {
8732
- request['from'] = since;
10161
+ if (uta) {
10162
+ if (since !== undefined) {
10163
+ request['startAt'] = since;
10164
+ }
10165
+ if (limit !== undefined) {
10166
+ request['pageSize'] = limit;
10167
+ }
10168
+ [request, params] = this.handleUntilOption('endAt', request, params);
10169
+ //
10170
+ // {
10171
+ // "code": "200000",
10172
+ // "data": {
10173
+ // "items": [
10174
+ // {
10175
+ // "symbol": "DOGEUSDTM",
10176
+ // "closeId": "30000000000162175",
10177
+ // "marginMode": "CROSS",
10178
+ // "side": "LONG",
10179
+ // "entryPrice": "0.09641",
10180
+ // "closePrice": "0.09613",
10181
+ // "maxSize": "1",
10182
+ // "avgClosePrice": "0.09613",
10183
+ // "leverage": "3",
10184
+ // "realizedPnL": "-0.0395524",
10185
+ // "fee": "0.0115524",
10186
+ // "tax": "0",
10187
+ // "fundingFee": "0",
10188
+ // "closingTime": 1774469647311000000,
10189
+ // "creationTime": 1774468501294000000
10190
+ // }
10191
+ // ],
10192
+ // "lastId": 30000000000162175
10193
+ // }
10194
+ // }
10195
+ //
10196
+ response = await this.utaPrivateGetPositionHistory(this.extend(request, params));
8733
10197
  }
8734
- const until = this.safeInteger(params, 'until');
8735
- if (until !== undefined) {
8736
- params = this.omit(params, 'until');
8737
- request['to'] = until;
10198
+ else {
10199
+ if (limit === undefined) {
10200
+ limit = 200;
10201
+ }
10202
+ request['limit'] = limit;
10203
+ if (since !== undefined) {
10204
+ request['from'] = since;
10205
+ }
10206
+ const until = this.safeInteger(params, 'until');
10207
+ if (until !== undefined) {
10208
+ params = this.omit(params, 'until');
10209
+ request['to'] = until;
10210
+ }
10211
+ //
10212
+ // {
10213
+ // "success": true,
10214
+ // "code": "200",
10215
+ // "msg": "success",
10216
+ // "retry": false,
10217
+ // "data": {
10218
+ // "currentPage": 1,
10219
+ // "pageSize": 10,
10220
+ // "totalNum": 25,
10221
+ // "totalPage": 3,
10222
+ // "items": [
10223
+ // {
10224
+ // "closeId": "300000000000000030",
10225
+ // "positionId": "300000000000000009",
10226
+ // "uid": 99996908309485,
10227
+ // "userId": "6527d4fc8c7f3d0001f40f5f",
10228
+ // "symbol": "XBTUSDM",
10229
+ // "settleCurrency": "XBT",
10230
+ // "leverage": "0.0",
10231
+ // "type": "LIQUID_LONG",
10232
+ // "side": null,
10233
+ // "closeSize": null,
10234
+ // "pnl": "-1.0000003793999999",
10235
+ // "realisedGrossCost": "0.9993849748999999",
10236
+ // "withdrawPnl": "0.0",
10237
+ // "roe": null,
10238
+ // "tradeFee": "0.0006154045",
10239
+ // "fundingFee": "0.0",
10240
+ // "openTime": 1713785751181,
10241
+ // "closeTime": 1713785752784,
10242
+ // "openPrice": null,
10243
+ // "closePrice": null
10244
+ // }
10245
+ // ]
10246
+ // }
10247
+ // }
10248
+ //
10249
+ response = await this.futuresPrivateGetHistoryPositions(this.extend(request, params));
8738
10250
  }
8739
- const response = await this.futuresPrivateGetHistoryPositions(this.extend(request, params));
8740
- //
8741
- // {
8742
- // "success": true,
8743
- // "code": "200",
8744
- // "msg": "success",
8745
- // "retry": false,
8746
- // "data": {
8747
- // "currentPage": 1,
8748
- // "pageSize": 10,
8749
- // "totalNum": 25,
8750
- // "totalPage": 3,
8751
- // "items": [
8752
- // {
8753
- // "closeId": "300000000000000030",
8754
- // "positionId": "300000000000000009",
8755
- // "uid": 99996908309485,
8756
- // "userId": "6527d4fc8c7f3d0001f40f5f",
8757
- // "symbol": "XBTUSDM",
8758
- // "settleCurrency": "XBT",
8759
- // "leverage": "0.0",
8760
- // "type": "LIQUID_LONG",
8761
- // "side": null,
8762
- // "closeSize": null,
8763
- // "pnl": "-1.0000003793999999",
8764
- // "realisedGrossCost": "0.9993849748999999",
8765
- // "withdrawPnl": "0.0",
8766
- // "roe": null,
8767
- // "tradeFee": "0.0006154045",
8768
- // "fundingFee": "0.0",
8769
- // "openTime": 1713785751181,
8770
- // "closeTime": 1713785752784,
8771
- // "openPrice": null,
8772
- // "closePrice": null
8773
- // }
8774
- // ]
8775
- // }
8776
- // }
8777
- //
8778
10251
  const data = this.safeDict(response, 'data');
8779
10252
  const items = this.safeList(data, 'items', []);
8780
10253
  return this.parsePositions(items, symbols);
@@ -8849,61 +10322,107 @@ class kucoin extends kucoin$1["default"] {
8849
10322
  // "closePrice": null
8850
10323
  // }
8851
10324
  //
10325
+ // uta fetchPositions
10326
+ // {
10327
+ // "symbol": "DOGEUSDTM",
10328
+ // "id": "30000000000084351",
10329
+ // "marginMode": "CROSS",
10330
+ // "size": "2",
10331
+ // "entryPrice": "0.093795",
10332
+ // "positionValue": "18.298",
10333
+ // "markPrice": "0.09149",
10334
+ // "leverage": "3",
10335
+ // "unrealizedPnL": "-0.461",
10336
+ // "realizedPnL": "-0.01122489",
10337
+ // "initialMargin": "6.0993333327234",
10338
+ // "mmr": "0.007",
10339
+ // "maintenanceMargin": "0.128086",
10340
+ // "creationTime": 1774469753178000000
10341
+ // }
10342
+ //
10343
+ // uta fetchPositionsHistory
10344
+ // {
10345
+ // "symbol": "DOGEUSDTM",
10346
+ // "closeId": "30000000000162175",
10347
+ // "marginMode": "CROSS",
10348
+ // "side": "LONG",
10349
+ // "entryPrice": "0.09641",
10350
+ // "closePrice": "0.09613",
10351
+ // "maxSize": "1",
10352
+ // "avgClosePrice": "0.09613",
10353
+ // "leverage": "3",
10354
+ // "realizedPnL": "-0.0395524",
10355
+ // "fee": "0.0115524",
10356
+ // "tax": "0",
10357
+ // "fundingFee": "0",
10358
+ // "closingTime": 1774469647311000000,
10359
+ // "creationTime": 1774468501294000000
10360
+ // }
10361
+ //
8852
10362
  const symbol = this.safeString(position, 'symbol');
8853
10363
  market = this.safeMarket(symbol, market);
8854
- const timestamp = this.safeInteger(position, 'currentTimestamp');
8855
- const size = this.safeString(position, 'currentQty');
8856
- let side = undefined;
8857
- const type = this.safeStringLower(position, 'type');
8858
- if (size !== undefined) {
8859
- if (Precise["default"].stringGt(size, '0')) {
8860
- side = 'long';
8861
- }
8862
- else if (Precise["default"].stringLt(size, '0')) {
8863
- side = 'short';
8864
- }
10364
+ let timestamp = this.safeInteger(position, 'currentTimestamp');
10365
+ if (timestamp === undefined) {
10366
+ timestamp = this.safeIntegerProduct(position, 'creationTime', 0.000001);
8865
10367
  }
8866
- else if (type !== undefined) {
8867
- if (type.indexOf('long') > -1) {
8868
- side = 'long';
10368
+ const size = this.safeStringN(position, ['currentQty', 'size', 'maxSize', 'closeSize']);
10369
+ let side = this.safeStringLower(position, 'side');
10370
+ const type = this.safeStringLower(position, 'type');
10371
+ if (side === undefined) {
10372
+ if (size !== undefined) {
10373
+ if (Precise["default"].stringGt(size, '0')) {
10374
+ side = 'long';
10375
+ }
10376
+ else if (Precise["default"].stringLt(size, '0')) {
10377
+ side = 'short';
10378
+ }
8869
10379
  }
8870
- else {
8871
- side = 'short';
10380
+ else if (type !== undefined) {
10381
+ if (type.indexOf('long') > -1) {
10382
+ side = 'long';
10383
+ }
10384
+ else {
10385
+ side = 'short';
10386
+ }
8872
10387
  }
8873
10388
  }
8874
- const notional = Precise["default"].stringAbs(this.safeString(position, 'posCost'));
8875
- const initialMargin = this.safeString(position, 'posInit');
10389
+ const notional = Precise["default"].stringAbs(this.safeString2(position, 'posCost', 'positionValue'));
10390
+ const initialMargin = this.safeString2(position, 'posInit', 'initialMargin');
8876
10391
  const initialMarginPercentage = Precise["default"].stringDiv(initialMargin, notional);
8877
10392
  // const marginRatio = Precise.stringDiv (maintenanceRate, collateral);
8878
- const unrealisedPnl = this.safeString(position, 'unrealisedPnl');
10393
+ const unrealisedPnl = this.safeString2(position, 'unrealisedPnl', 'unrealizedPnL');
8879
10394
  const crossMode = this.safeValue(position, 'crossMode');
8880
10395
  // currently crossMode is always set to false and only isolated positions are supported
8881
- let marginMode = undefined;
10396
+ let marginMode = this.safeStringLower(position, 'marginMode');
8882
10397
  if (crossMode !== undefined) {
8883
10398
  marginMode = crossMode ? 'cross' : 'isolated';
8884
10399
  }
10400
+ let lastUpdateTimestamp = this.safeInteger(position, 'closeTime');
10401
+ if (lastUpdateTimestamp === undefined) {
10402
+ lastUpdateTimestamp = this.safeIntegerProduct(position, 'closingTime', 0.000001);
10403
+ }
8885
10404
  return this.safePosition({
8886
10405
  'info': position,
8887
- 'id': this.safeString2(position, 'id', 'positionId'),
10406
+ 'id': this.safeStringN(position, ['id', 'positionId', 'closeId']),
8888
10407
  'symbol': this.safeString(market, 'symbol'),
8889
10408
  'timestamp': timestamp,
8890
10409
  'datetime': this.iso8601(timestamp),
8891
- 'lastUpdateTimestamp': this.safeInteger(position, 'closeTime'),
10410
+ 'lastUpdateTimestamp': lastUpdateTimestamp,
8892
10411
  'initialMargin': this.parseNumber(initialMargin),
8893
10412
  'initialMarginPercentage': this.parseNumber(initialMarginPercentage),
8894
- 'maintenanceMargin': this.safeNumber(position, 'posMaint'),
8895
- 'maintenanceMarginPercentage': this.safeNumber(position, 'maintMarginReq'),
8896
- 'entryPrice': this.safeNumber2(position, 'avgEntryPrice', 'openPrice'),
10413
+ 'maintenanceMargin': this.safeNumber2(position, 'posMaint', 'maintenanceMargin'),
10414
+ 'maintenanceMarginPercentage': this.safeNumber2(position, 'maintMarginReq', 'mmr'),
10415
+ 'entryPrice': this.safeNumberN(position, ['avgEntryPrice', 'openPrice', 'entryPrice']),
8897
10416
  'notional': this.parseNumber(notional),
8898
10417
  'leverage': this.safeNumber2(position, 'realLeverage', 'leverage'),
8899
10418
  'unrealizedPnl': this.parseNumber(unrealisedPnl),
8900
10419
  'contracts': this.parseNumber(Precise["default"].stringAbs(size)),
8901
10420
  'contractSize': this.safeValue(market, 'contractSize'),
8902
- 'realizedPnl': this.safeNumber2(position, 'realisedPnl', 'pnl'),
10421
+ 'realizedPnl': this.safeNumberN(position, ['realisedPnl', 'pnl', 'realizedPnL']),
8903
10422
  'marginRatio': undefined,
8904
10423
  'liquidationPrice': this.safeNumber(position, 'liquidationPrice'),
8905
10424
  'markPrice': this.safeNumber(position, 'markPrice'),
8906
- 'lastPrice': undefined,
10425
+ 'lastPrice': this.safeNumber(position, 'closePrice'),
8907
10426
  'collateral': this.safeNumber(position, 'maintMargin'),
8908
10427
  'marginMode': marginMode,
8909
10428
  'side': side,
@@ -8917,18 +10436,31 @@ class kucoin extends kucoin$1["default"] {
8917
10436
  * @name kucoin#cancelOrders
8918
10437
  * @description cancel multiple orders for contract markets
8919
10438
  * @see https://www.kucoin.com/docs-new/3470241e0
10439
+ * @see https://www.kucoin.com/docs-new/rest/ua/batch-cancel-order-by-id
8920
10440
  * @param {string[]} ids order ids
8921
10441
  * @param {string} symbol unified symbol of the market the order was made in
8922
10442
  * @param {object} [params] extra parameters specific to the exchange API endpoint
8923
10443
  * @param {string[]} [params.clientOrderIds] client order ids
10444
+ * @param {boolean} [params.uta] set to true to use the unified trading account (uta) endpoint, defaults to false for the contract orders
10445
+ * @param {string} [params.accountMode] *for uta endpoint only* 'unified' or 'classic' (default is 'unified')
10446
+ * @param {string} [params.marginMode] *for margin orders only* 'cross' or 'isolated'
8924
10447
  * @returns {object} an list of [order structures]{@link https://docs.ccxt.com/?id=order-structure}
8925
10448
  */
8926
10449
  async cancelOrders(ids, symbol = undefined, params = {}) {
8927
- // contract markets only
8928
10450
  await this.loadMarkets();
10451
+ let uta = await this.isUTAEnabled();
10452
+ [uta, params] = this.handleOptionAndParams(params, 'cancelOrders', 'uta', uta);
8929
10453
  let market = undefined;
10454
+ let isContractMarket = true; // default to contract market orders if symbol is not provided, uta endpoint requires a symbol to be provided
8930
10455
  if (symbol !== undefined) {
8931
10456
  market = this.market(symbol);
10457
+ isContractMarket = market['contract'];
10458
+ if (!isContractMarket) {
10459
+ uta = true; // spot market orders can only be cancelled via the uta endpoint
10460
+ }
10461
+ }
10462
+ else if (uta) {
10463
+ throw new errors.ArgumentsRequired(this.id + ' cancelOrders() requires a symbol argument for uta endpoint');
8932
10464
  }
8933
10465
  const ordersRequests = [];
8934
10466
  const clientOrderIds = this.safeList2(params, 'clientOrderIds', 'clientOids', []);
@@ -8945,33 +10477,59 @@ class kucoin extends kucoin$1["default"] {
8945
10477
  });
8946
10478
  }
8947
10479
  for (let i = 0; i < ids.length; i++) {
8948
- ordersRequests.push(ids[i]);
10480
+ const orderId = ids[i];
10481
+ if (uta) {
10482
+ ordersRequests.push({
10483
+ 'orderId': orderId,
10484
+ 'symbol': market['id'],
10485
+ });
10486
+ }
10487
+ else {
10488
+ ordersRequests.push(ids[i]);
10489
+ }
8949
10490
  }
8950
- const requestKey = useClientorderId ? 'clientOidsList' : 'orderIdsList';
8951
10491
  const request = {};
8952
- request[requestKey] = ordersRequests;
8953
- const response = await this.futuresPrivateDeleteOrdersMultiCancel(this.extend(request, params));
8954
- //
8955
- // {
8956
- // "code": "200000",
8957
- // "data":
8958
- // [
8959
- // {
8960
- // "orderId": "80465574458560512",
8961
- // "clientOid": null,
8962
- // "code": "200",
8963
- // "msg": "success"
8964
- // },
8965
- // {
8966
- // "orderId": "80465575289094144",
8967
- // "clientOid": null,
8968
- // "code": "200",
8969
- // "msg": "success"
8970
- // }
8971
- // ]
8972
- // }
8973
- //
8974
- const orders = this.safeList(response, 'data', []);
10492
+ let response = undefined;
10493
+ let orders = [];
10494
+ if (uta) {
10495
+ let accountMode = 'unified';
10496
+ [accountMode, params] = this.handleOptionAndParams(params, 'cancelOrders', 'accountMode', accountMode);
10497
+ request['accountMode'] = accountMode;
10498
+ let marginMode = undefined;
10499
+ [marginMode, params] = this.handleMarginModeAndParams('fetchOrder', params);
10500
+ const tradeType = this.handleTradeType(isContractMarket, marginMode, params);
10501
+ request['tradeType'] = tradeType;
10502
+ request['cancelOrderList'] = ordersRequests;
10503
+ response = await this.utaPrivatePostAccountModeOrderCancelBatch(this.extend(request, params));
10504
+ const data = this.safeDict(response, 'data', {});
10505
+ orders = this.safeList(data, 'items', []);
10506
+ }
10507
+ else {
10508
+ const requestKey = useClientorderId ? 'clientOidsList' : 'orderIdsList';
10509
+ request[requestKey] = ordersRequests;
10510
+ response = await this.futuresPrivateDeleteOrdersMultiCancel(this.extend(request, params));
10511
+ //
10512
+ // {
10513
+ // "code": "200000",
10514
+ // "data":
10515
+ // [
10516
+ // {
10517
+ // "orderId": "80465574458560512",
10518
+ // "clientOid": null,
10519
+ // "code": "200",
10520
+ // "msg": "success"
10521
+ // },
10522
+ // {
10523
+ // "orderId": "80465575289094144",
10524
+ // "clientOid": null,
10525
+ // "code": "200",
10526
+ // "msg": "success"
10527
+ // }
10528
+ // ]
10529
+ // }
10530
+ //
10531
+ orders = this.safeList(response, 'data', []);
10532
+ }
8975
10533
  return this.parseOrders(orders, market);
8976
10534
  }
8977
10535
  /**
@@ -9436,6 +10994,139 @@ class kucoin extends kucoin$1["default"] {
9436
10994
  }
9437
10995
  return result;
9438
10996
  }
10997
+ /**
10998
+ * @method
10999
+ * @name kucoin#fetchOpenInterests
11000
+ * @description Retrieves the open interest for a list of symbols
11001
+ * @see https://www.kucoin.com/docs-new/rest/ua/get-futures-open-interset
11002
+ * @param {string[]} [symbols] Unified CCXT market symbol
11003
+ * @param {object} [params] exchange specific parameters
11004
+ * @returns {object} an open interest structure{@link https://docs.ccxt.com/?id=open-interest-structure}
11005
+ */
11006
+ async fetchOpenInterests(symbols = undefined, params = {}) {
11007
+ await this.loadMarkets();
11008
+ symbols = this.marketSymbols(symbols);
11009
+ const request = {};
11010
+ if (symbols !== undefined) {
11011
+ const length = symbols.length;
11012
+ if (length < 11) {
11013
+ // the endpoint does not accept more than 10 symbols at a time
11014
+ // if user provided more than 10 symbols, we will fetch all symbols
11015
+ const marketIds = this.marketIds(symbols);
11016
+ request['symbol'] = marketIds.join(',');
11017
+ }
11018
+ }
11019
+ const response = await this.utaGetMarketOpenInterest(this.extend(request, params));
11020
+ //
11021
+ // {
11022
+ // "code": "200000",
11023
+ // "data": [
11024
+ // {
11025
+ // "symbol": "ETHUSDTM",
11026
+ // "openInterest": "8053960",
11027
+ // "ts": 1774007467050
11028
+ // }
11029
+ // ]
11030
+ // }
11031
+ //
11032
+ const data = this.safeList(response, 'data', []);
11033
+ return this.parseOpenInterests(data, symbols);
11034
+ }
11035
+ parseOpenInterest(interest, market = undefined) {
11036
+ //
11037
+ // {
11038
+ // "symbol": "ETHUSDTM",
11039
+ // "openInterest": "8053960",
11040
+ // "ts": 1774007467050
11041
+ // }
11042
+ //
11043
+ const marketId = this.safeString(interest, 'symbol');
11044
+ market = this.safeMarket(marketId, market);
11045
+ const timestamp = this.safeInteger(interest, 'ts');
11046
+ return this.safeOpenInterest({
11047
+ 'symbol': this.safeSymbol(marketId),
11048
+ 'openInterestAmount': this.safeNumber(interest, 'openInterest'),
11049
+ 'openInterestValue': undefined,
11050
+ 'timestamp': timestamp,
11051
+ 'datetime': this.iso8601(timestamp),
11052
+ 'info': interest,
11053
+ }, market);
11054
+ }
11055
+ /**
11056
+ * @method
11057
+ * @name kucoin#fetchOpenInterestHistory
11058
+ * @description Retrieves the open interest history of a currency
11059
+ * @see https://www.kucoin.com/docs-new/rest/ua/get-futures-open-interset
11060
+ * @param {string} symbol Unified CCXT market symbol
11061
+ * @param {string} timeframe '5m', '15m', '30m', '1h', '4h' or '1d'
11062
+ * @param {int} [since] the time(ms) of the earliest record to retrieve as a unix timestamp
11063
+ * @param {int} [limit] default 30,max 200
11064
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
11065
+ * @param {int} [params.until] the latest time in ms to fetch entries for
11066
+ * @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)
11067
+ * @returns {object} an array of [open interest structures]{@link https://docs.ccxt.com/?id=open-interest-structure}
11068
+ */
11069
+ async fetchOpenInterestHistory(symbol, timeframe = '5m', since = undefined, limit = undefined, params = {}) {
11070
+ const timeframes = {
11071
+ '5m': '5min',
11072
+ '15m': '15min',
11073
+ '30m': '30min',
11074
+ '1h': '1hour',
11075
+ '4h': '4hour',
11076
+ '1d': '1day',
11077
+ '5min': '5min',
11078
+ '15min': '15min',
11079
+ '30min': '30min',
11080
+ '1hour': '1hour',
11081
+ '4hour': '4hour',
11082
+ '1day': '1day',
11083
+ };
11084
+ const interval = this.safeString(timeframes, timeframe);
11085
+ if (interval === undefined) {
11086
+ throw new errors.BadRequest(this.id + ' fetchOpenInterestHistory() invalid timeframe, supported are 5m, 15m, 30m, 1h, 4h, 1d');
11087
+ }
11088
+ await this.loadMarkets();
11089
+ const market = this.market(symbol);
11090
+ const maxLimit = 200;
11091
+ let paginate = false;
11092
+ [paginate, params] = this.handleOptionAndParams(params, 'fetchOpenInterestHistory', 'paginate', paginate);
11093
+ if (paginate) {
11094
+ return await this.fetchPaginatedCallDeterministic('fetchOpenInterestHistory', symbol, since, limit, timeframe, params, maxLimit);
11095
+ }
11096
+ let request = {
11097
+ 'symbol': market['id'],
11098
+ 'interval': interval,
11099
+ };
11100
+ if (since !== undefined) {
11101
+ request['startAt'] = since;
11102
+ }
11103
+ if (limit !== undefined) {
11104
+ request['pageSize'] = limit;
11105
+ }
11106
+ [request, params] = this.handleUntilOption('endAt', request, params);
11107
+ const response = await this.utaGetMarketOpenInterest(this.extend(request, params));
11108
+ const data = this.safeList(response, 'data');
11109
+ return this.parseOpenInterestsHistory(data, market, since, limit);
11110
+ }
11111
+ /**
11112
+ * @method
11113
+ * @name kucoin#isUTAEnabled
11114
+ * @see https://www.kucoin.com/docs-new/rest/ua/get-account-mode
11115
+ * @description returns true or false so the user can check if unified account is enabled
11116
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
11117
+ * @returns {boolean} true if unified account is enabled, false otherwise
11118
+ */
11119
+ async isUTAEnabled(params = {}) {
11120
+ let uta = this.safeBool(this.options, 'uta');
11121
+ if (uta === undefined) {
11122
+ const response = await this.utaPrivateGetAccountMode(params);
11123
+ const data = this.safeDict(response, 'data', {});
11124
+ const accountMode = this.safeString(data, 'selfAccountMode');
11125
+ uta = (accountMode === 'UNIFIED');
11126
+ this.options['uta'] = uta;
11127
+ }
11128
+ return this.safeBool(this.options, 'uta', false);
11129
+ }
9439
11130
  sign(path, api = 'public', method = 'GET', params = {}, headers = undefined, body = undefined) {
9440
11131
  //
9441
11132
  // the v2 URL is https://openapi-v2.kucoin.com/api/v1/endpoint
@@ -9466,11 +11157,15 @@ class kucoin extends kucoin$1["default"] {
9466
11157
  let endpart = '';
9467
11158
  headers = (headers !== undefined) ? headers : {};
9468
11159
  let url = this.urls['api'][api];
11160
+ const tradeType = this.safeString(query, 'tradeType');
9469
11161
  if (!this.isEmpty(query)) {
9470
11162
  if (((method === 'GET') || (method === 'DELETE')) && (path !== 'orders/multi-cancel')) {
9471
11163
  endpoint += '?' + this.rawencode(query);
9472
11164
  }
9473
11165
  else {
11166
+ if (endpoint === '/api/ua/v1/classic/order/place') {
11167
+ endpoint += '?tradeType=' + tradeType;
11168
+ }
9474
11169
  body = this.json(query);
9475
11170
  endpart = body;
9476
11171
  headers['Content-Type'] = 'application/json';
@@ -9501,7 +11196,9 @@ class kucoin extends kucoin$1["default"] {
9501
11196
  const signature = this.hmac(this.encode(payload), this.encode(this.secret), sha256.sha256, 'base64');
9502
11197
  headers['KC-API-SIGN'] = signature;
9503
11198
  let partner = this.safeDict(this.options, 'partner', {});
9504
- partner = isFuturePrivate ? this.safeValue(partner, 'future', partner) : this.safeValue(partner, 'spot', partner);
11199
+ const isUtaFuturePrivate = isUtaPrivate && (tradeType === 'FUTURES');
11200
+ const isFuturePartner = isFuturePrivate || isUtaFuturePrivate;
11201
+ partner = isFuturePartner ? this.safeValue(partner, 'future', partner) : this.safeValue(partner, 'spot', partner);
9505
11202
  const partnerId = this.safeString(partner, 'id');
9506
11203
  const partnerSecret = this.safeString2(partner, 'secret', 'key');
9507
11204
  if ((partnerId !== undefined) && (partnerSecret !== undefined)) {