ccxt 4.5.45 → 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 (91) 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 +27 -0
  7. package/dist/cjs/src/binance.js +23 -17
  8. package/dist/cjs/src/bitfinex.js +6 -11
  9. package/dist/cjs/src/bitget.js +9 -4
  10. package/dist/cjs/src/bitmart.js +144 -21
  11. package/dist/cjs/src/bitmex.js +46 -0
  12. package/dist/cjs/src/bitstamp.js +14 -1
  13. package/dist/cjs/src/bittrade.js +1 -1
  14. package/dist/cjs/src/blofin.js +137 -29
  15. package/dist/cjs/src/bybit.js +58 -56
  16. package/dist/cjs/src/bydfi.js +102 -100
  17. package/dist/cjs/src/gate.js +37 -2
  18. package/dist/cjs/src/hollaex.js +1 -1
  19. package/dist/cjs/src/kraken.js +39 -29
  20. package/dist/cjs/src/kucoin.js +2161 -462
  21. package/dist/cjs/src/lighter.js +2 -2
  22. package/dist/cjs/src/okx.js +75 -58
  23. package/dist/cjs/src/paradex.js +2 -6
  24. package/dist/cjs/src/pro/bittrade.js +4 -0
  25. package/dist/cjs/src/pro/bydfi.js +19 -19
  26. package/dist/cjs/src/pro/gate.js +79 -54
  27. package/dist/cjs/src/pro/grvt.js +6 -4
  28. package/dist/cjs/src/pro/htx.js +4 -4
  29. package/dist/cjs/src/pro/lighter.js +1 -1
  30. package/dist/cjs/src/pro/okx.js +1 -1
  31. package/dist/cjs/src/whitebit.js +21 -2
  32. package/index.d.cts +2 -0
  33. package/js/ccxt.d.ts +2 -8
  34. package/js/ccxt.js +2 -6
  35. package/js/src/abstract/bitmart.d.ts +7 -0
  36. package/js/src/abstract/blofin.d.ts +28 -12
  37. package/js/src/abstract/bydfi.d.ts +29 -29
  38. package/js/src/abstract/kraken.d.ts +36 -29
  39. package/js/src/abstract/kucoin.d.ts +2 -0
  40. package/js/src/abstract/kucoinfutures.d.ts +2 -0
  41. package/js/src/aftermath.js +1 -1
  42. package/js/src/backpack.js +1 -1
  43. package/js/src/base/Exchange.d.ts +2 -0
  44. package/js/src/base/Exchange.js +27 -0
  45. package/js/src/binance.js +23 -17
  46. package/js/src/bitfinex.js +6 -11
  47. package/js/src/bitget.d.ts +1 -1
  48. package/js/src/bitget.js +9 -4
  49. package/js/src/bitmart.d.ts +18 -4
  50. package/js/src/bitmart.js +144 -21
  51. package/js/src/bitmex.d.ts +12 -0
  52. package/js/src/bitmex.js +46 -0
  53. package/js/src/bitstamp.js +14 -1
  54. package/js/src/bittrade.js +1 -1
  55. package/js/src/blofin.d.ts +2 -0
  56. package/js/src/blofin.js +137 -29
  57. package/js/src/bybit.d.ts +1 -0
  58. package/js/src/bybit.js +58 -56
  59. package/js/src/bydfi.d.ts +31 -31
  60. package/js/src/bydfi.js +102 -100
  61. package/js/src/gate.js +37 -2
  62. package/js/src/hollaex.js +1 -1
  63. package/js/src/kraken.js +39 -29
  64. package/js/src/kucoin.d.ts +249 -8
  65. package/js/src/kucoin.js +2161 -462
  66. package/js/src/lighter.js +2 -2
  67. package/js/src/okx.d.ts +1 -0
  68. package/js/src/okx.js +75 -58
  69. package/js/src/paradex.d.ts +0 -1
  70. package/js/src/paradex.js +2 -6
  71. package/js/src/pro/bittrade.js +4 -0
  72. package/js/src/pro/bydfi.d.ts +18 -18
  73. package/js/src/pro/bydfi.js +19 -19
  74. package/js/src/pro/gate.d.ts +2 -2
  75. package/js/src/pro/gate.js +79 -54
  76. package/js/src/pro/grvt.js +6 -4
  77. package/js/src/pro/htx.js +4 -4
  78. package/js/src/pro/lighter.js +1 -1
  79. package/js/src/pro/okx.js +1 -1
  80. package/js/src/whitebit.d.ts +1 -1
  81. package/js/src/whitebit.js +21 -2
  82. package/package.json +2 -2
  83. package/dist/cjs/src/abstract/coincatch.js +0 -11
  84. package/dist/cjs/src/coincatch.js +0 -5495
  85. package/dist/cjs/src/pro/coincatch.js +0 -1563
  86. package/js/src/abstract/coincatch.d.ts +0 -97
  87. package/js/src/abstract/coincatch.js +0 -5
  88. package/js/src/coincatch.d.ts +0 -788
  89. package/js/src/coincatch.js +0 -5488
  90. package/js/src/pro/coincatch.d.ts +0 -207
  91. 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,
@@ -191,6 +195,7 @@ class kucoin extends kucoin$1["default"] {
191
195
  'get': {
192
196
  // account
193
197
  'user-info': 20,
198
+ 'user/api-key': 20,
194
199
  'accounts': 5,
195
200
  'accounts/{accountId}': 5,
196
201
  'accounts/ledgers': 2,
@@ -566,6 +571,7 @@ class kucoin extends kucoin$1["default"] {
566
571
  '{accountMode}/order/execution': 8,
567
572
  '{accountMode}/position/open-list': 6,
568
573
  '{accountMode}/position/history': 4,
574
+ 'position/history': 4,
569
575
  '{accountMode}/position/tiers': 40,
570
576
  'sub-account/balance': 10,
571
577
  'user/fee-rate': 6,
@@ -630,6 +636,7 @@ class kucoin extends kucoin$1["default"] {
630
636
  '503': errors.ExchangeNotAvailable,
631
637
  '101030': errors.PermissionDenied,
632
638
  '103000': errors.InvalidOrder,
639
+ '112010': errors.PermissionDenied,
633
640
  '130101': errors.BadRequest,
634
641
  '130102': errors.ExchangeError,
635
642
  '130103': errors.OrderNotFound,
@@ -708,7 +715,7 @@ class kucoin extends kucoin$1["default"] {
708
715
  '400006': errors.AuthenticationError,
709
716
  '400007': errors.AuthenticationError,
710
717
  '400008': errors.NotSupported,
711
- '400100': errors.InsufficientFunds,
718
+ '400100': errors.BadRequest,
712
719
  '400200': errors.InvalidOrder,
713
720
  '400330': errors.InvalidOrder,
714
721
  '400350': errors.InvalidOrder,
@@ -740,6 +747,7 @@ class kucoin extends kucoin$1["default"] {
740
747
  '330008': errors.InsufficientFunds, // {"msg":"Your current margin and leverage have reached the maximum open limit. Please increase your margin or raise your leverage to open larger positions.","code":"330008"}
741
748
  },
742
749
  'broad': {
750
+ 'pageSize should not greater than 500': errors.BadRequest,
743
751
  'Exceeded the access frequency': errors.RateLimitExceeded,
744
752
  'require more permission': errors.PermissionDenied,
745
753
  // futures errors
@@ -878,15 +886,14 @@ class kucoin extends kucoin$1["default"] {
878
886
  },
879
887
  'options': {
880
888
  'hf': undefined,
889
+ 'uta': undefined,
881
890
  'version': 'v1',
882
891
  'symbolSeparator': '-',
883
892
  'fetchMyTradesMethod': 'private_get_fills',
884
893
  'timeDifference': 0,
885
894
  'adjustForTimeDifference': false,
886
895
  'fetchCurrencies': {
887
- 'webApiEnable': true,
888
- 'webApiRetries': 1,
889
- 'webApiMuteFailure': true,
896
+ 'brokenCurrencies': ['00', 'OPEN_ERROR', 'HUF', 'BDT'], // skip buggy entries: https://t.me/KuCoin_API/217798
890
897
  },
891
898
  'fetchMarkets': {
892
899
  'types': ['spot', 'swap', 'future', 'contract'],
@@ -901,6 +908,13 @@ class kucoin extends kucoin$1["default"] {
901
908
  'fetchBalance': {
902
909
  'code': 'USDT', // for contract endpoint
903
910
  },
911
+ 'timeInForce': {
912
+ 'IOC': 'IOC',
913
+ 'FOK': 'FOK',
914
+ 'PO': 'PO',
915
+ 'GTD': 'GTT',
916
+ 'RPI': 'RPI',
917
+ },
904
918
  'timeframes': {
905
919
  'swap': {
906
920
  '1m': 1,
@@ -1064,12 +1078,32 @@ class kucoin extends kucoin$1["default"] {
1064
1078
  'mining': 'pool',
1065
1079
  'hf': 'trade_hf',
1066
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',
1067
1097
  },
1068
1098
  'networks': {
1099
+ 'BTC': 'btc',
1069
1100
  'BRC20': 'btc',
1070
1101
  'BTCNATIVESEGWIT': 'bech32',
1102
+ 'ETH': 'eth',
1071
1103
  'ERC20': 'eth',
1104
+ 'TRX': 'trx',
1072
1105
  'TRC20': 'trx',
1106
+ 'HECO': 'heco',
1073
1107
  'HRC20': 'heco',
1074
1108
  'MATIC': 'matic',
1075
1109
  'KCC': 'kcc',
@@ -1084,6 +1118,7 @@ class kucoin extends kucoin$1["default"] {
1084
1118
  'TLOS': 'tlos',
1085
1119
  'CFX': 'cfx',
1086
1120
  'ACA': 'aca',
1121
+ 'OP': 'optimism',
1087
1122
  'OPTIMISM': 'optimism',
1088
1123
  'ONT': 'ont',
1089
1124
  'GLMR': 'glmr',
@@ -1274,6 +1309,14 @@ class kucoin extends kucoin$1["default"] {
1274
1309
  // 'KLEVER': 'klv',
1275
1310
  // undetermined: xns(insolar), rhoc, luk (luniverse), kts (klimatas), bchn (bitcoin cash node), god (shallow entry), lit (litmus),
1276
1311
  },
1312
+ 'networksById': {
1313
+ 'btc': 'BTC',
1314
+ 'trx': 'TRC20',
1315
+ 'eth': 'ERC20',
1316
+ 'heco': 'HRC20',
1317
+ 'optimism': 'OP',
1318
+ 'op': 'OP',
1319
+ },
1277
1320
  'marginModes': {
1278
1321
  'cross': 'MARGIN_TRADE',
1279
1322
  'isolated': 'MARGIN_ISOLATED_TRADE',
@@ -1357,7 +1400,11 @@ class kucoin extends kucoin$1["default"] {
1357
1400
  'stopLossPrice': true,
1358
1401
  'takeProfitPrice': true,
1359
1402
  'attachedStopLossTakeProfit': {
1360
- 'triggerPriceType': undefined,
1403
+ 'triggerPriceType': {
1404
+ 'last': true,
1405
+ 'mark': true,
1406
+ 'index': true,
1407
+ },
1361
1408
  'price': true,
1362
1409
  },
1363
1410
  'timeInForce': {
@@ -1483,8 +1530,8 @@ class kucoin extends kucoin$1["default"] {
1483
1530
  * @returns {object} a [status structure]{@link https://docs.ccxt.com/?id=exchange-status-structure}
1484
1531
  */
1485
1532
  async fetchStatus(params = {}) {
1486
- let uta = undefined;
1487
- [uta, params] = this.handleOptionAndParams(params, 'fetchStatus', 'uta', false);
1533
+ let uta = false;
1534
+ [uta, params] = this.handleOptionAndParams(params, 'fetchStatus', 'uta', uta);
1488
1535
  let type = undefined;
1489
1536
  [type, params] = this.handleMarketTypeAndParams('fetchStatus', undefined, params);
1490
1537
  let response = undefined;
@@ -1555,8 +1602,8 @@ class kucoin extends kucoin$1["default"] {
1555
1602
  async fetchMarkets(params = {}) {
1556
1603
  let fetchTickersFees = undefined;
1557
1604
  [fetchTickersFees, params] = this.handleOptionAndParams(params, 'fetchMarkets', 'fetchTickersFees', true);
1558
- let uta = undefined;
1559
- [uta, params] = this.handleOptionAndParams(params, 'fetchMarkets', 'uta', false);
1605
+ let uta = false;
1606
+ [uta, params] = this.handleOptionAndParams(params, 'fetchMarkets', 'uta', uta);
1560
1607
  if (uta) {
1561
1608
  return await this.fetchUTAMarkets(params);
1562
1609
  }
@@ -2092,7 +2139,7 @@ class kucoin extends kucoin$1["default"] {
2092
2139
  'strike': undefined,
2093
2140
  'optionType': undefined,
2094
2141
  'precision': {
2095
- 'amount': this.safeNumber(market, 'lotSize'),
2142
+ 'amount': this.safeNumber2(market, 'lotSize', 'baseOrderStep'),
2096
2143
  'price': this.safeNumber(market, 'tickSize'),
2097
2144
  },
2098
2145
  'limits': {
@@ -2164,9 +2211,13 @@ class kucoin extends kucoin$1["default"] {
2164
2211
  */
2165
2212
  async fetchCurrencies(params = {}) {
2166
2213
  let uta = false;
2214
+ if (this.checkRequiredCredentials(false)) {
2215
+ uta = await this.isUTAEnabled();
2216
+ }
2167
2217
  [uta, params] = this.handleOptionAndParams(params, 'fetchCurrencies', 'uta', uta);
2168
2218
  let response = undefined;
2169
2219
  if (uta) {
2220
+ response = await this.utaGetAssetCurrencies(params);
2170
2221
  //
2171
2222
  // {
2172
2223
  // "code": "200000",
@@ -2201,7 +2252,6 @@ class kucoin extends kucoin$1["default"] {
2201
2252
  // ]
2202
2253
  // }
2203
2254
  //
2204
- response = await this.utaGetAssetCurrencies(params);
2205
2255
  }
2206
2256
  else {
2207
2257
  //
@@ -2244,64 +2294,61 @@ class kucoin extends kucoin$1["default"] {
2244
2294
  response = await this.publicGetCurrencies(params);
2245
2295
  }
2246
2296
  const currenciesData = this.safeList(response, 'data', []);
2247
- const brokenCurrencies = this.safeList(this.options, 'brokenCurrencies', ['00', 'OPEN_ERROR', 'HUF', 'BDT']);
2248
- const result = {};
2249
- for (let i = 0; i < currenciesData.length; i++) {
2250
- const entry = currenciesData[i];
2251
- const id = this.safeString(entry, 'currency');
2252
- if (this.inArray(id, brokenCurrencies)) {
2253
- continue; // skip buggy entries: https://t.me/KuCoin_API/217798
2254
- }
2255
- const code = this.safeCurrencyCode(id);
2256
- const networks = {};
2257
- const chains = this.safeList2(entry, 'chains', 'items', []);
2258
- const chainsLength = chains.length;
2259
- for (let j = 0; j < chainsLength; j++) {
2260
- const chain = chains[j];
2261
- const chainId = this.safeString(chain, 'chainId');
2262
- const networkCode = this.networkIdToCode(chainId, code);
2263
- networks[networkCode] = {
2264
- 'info': chain,
2265
- 'id': chainId,
2266
- 'name': this.safeString(chain, 'chainName'),
2267
- 'code': networkCode,
2268
- 'active': undefined,
2269
- 'fee': this.safeNumber2(chain, 'withdrawalMinFee', 'minWithdrawFee'),
2270
- 'deposit': this.safeBool(chain, 'isDepositEnabled'),
2271
- 'withdraw': this.safeBool(chain, 'isWithdrawEnabled'),
2272
- 'precision': this.parseNumber(this.parsePrecision(this.safeString(chain, 'withdrawPrecision'))),
2273
- 'limits': {
2274
- 'withdraw': {
2275
- 'min': this.safeNumber2(chain, 'withdrawalMinSize', 'minWithdrawSize'),
2276
- 'max': this.safeNumber2(chain, 'maxWithdraw', 'maxWithdrawSize'),
2277
- },
2278
- 'deposit': {
2279
- 'min': this.safeNumber2(chain, 'depositMinSize', 'minDepositSize'),
2280
- 'max': this.safeNumber2(chain, 'maxDeposit', 'maxDepositSize'),
2281
- },
2282
- },
2283
- };
2284
- }
2285
- // kucoin has determined 'fiat' currencies with below logic
2286
- const rawPrecision = this.safeString(entry, 'precision');
2287
- const precision = this.parseNumber(this.parsePrecision(rawPrecision));
2288
- const isFiat = chainsLength === 0;
2289
- result[code] = this.safeCurrencyStructure({
2290
- 'id': id,
2291
- 'name': this.safeString(entry, 'fullName'),
2292
- 'code': code,
2293
- 'type': isFiat ? 'fiat' : 'crypto',
2294
- 'precision': precision,
2295
- 'info': entry,
2296
- 'networks': networks,
2297
- 'deposit': undefined,
2298
- '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,
2299
2317
  'active': undefined,
2300
- 'fee': undefined,
2301
- 'limits': undefined,
2302
- });
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
+ };
2303
2333
  }
2304
- 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
+ });
2305
2352
  }
2306
2353
  /**
2307
2354
  * @method
@@ -2309,41 +2356,68 @@ class kucoin extends kucoin$1["default"] {
2309
2356
  * @description fetch all the accounts associated with a profile
2310
2357
  * @see https://www.kucoin.com/docs-new/rest/account-info/account-funding/get-account-list-spot
2311
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
2312
2360
  * @returns {object} a dictionary of [account structures]{@link https://docs.ccxt.com/?id=account-structure} indexed by the account type
2313
2361
  */
2314
2362
  async fetchAccounts(params = {}) {
2315
- const response = await this.privateGetAccounts(params);
2316
- //
2317
- // {
2318
- // "code": "200000",
2319
- // "data": [
2320
- // {
2321
- // "balance": "0.00009788",
2322
- // "available": "0.00009788",
2323
- // "holds": "0",
2324
- // "currency": "BTC",
2325
- // "id": "5c6a4fd399a1d81c4f9cc4d0",
2326
- // "type": "trade"
2327
- // },
2328
- // {
2329
- // "balance": "0.00000001",
2330
- // "available": "0.00000001",
2331
- // "holds": "0",
2332
- // "currency": "ETH",
2333
- // "id": "5c6a49ec99a1d819392e8e9f",
2334
- // "type": "trade"
2335
- // }
2336
- // ]
2337
- // }
2338
- //
2339
- 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
+ }
2340
2414
  const result = [];
2341
2415
  for (let i = 0; i < data.length; i++) {
2342
2416
  const account = data[i];
2343
2417
  const accountId = this.safeString(account, 'id');
2344
2418
  const currencyId = this.safeString(account, 'currency');
2345
2419
  const code = this.safeCurrencyCode(currencyId);
2346
- const type = this.safeString(account, 'type'); // main or trade
2420
+ const type = this.safeStringLower2(account, 'type', 'accountType'); // main or trade or unified
2347
2421
  result.push({
2348
2422
  'id': accountId,
2349
2423
  'type': type,
@@ -2372,7 +2446,7 @@ class kucoin extends kucoin$1["default"] {
2372
2446
  let networkCode = undefined;
2373
2447
  [networkCode, params] = this.handleNetworkCodeAndParams(params);
2374
2448
  if (networkCode !== undefined) {
2375
- request['chain'] = this.networkCodeToId(networkCode).toLowerCase();
2449
+ request['chain'] = this.networkCodeToId(networkCode, currency['code']).toLowerCase();
2376
2450
  }
2377
2451
  const response = await this.privateGetWithdrawalsQuotas(this.extend(request, params));
2378
2452
  const data = this.safeDict(response, 'data', {});
@@ -2403,7 +2477,7 @@ class kucoin extends kucoin$1["default"] {
2403
2477
  let networkCode = undefined;
2404
2478
  [networkCode, params] = this.handleNetworkCodeAndParams(params);
2405
2479
  if (networkCode !== undefined) {
2406
- request['chain'] = this.networkCodeToId(networkCode).toLowerCase();
2480
+ request['chain'] = this.networkCodeToId(networkCode, currency['code']).toLowerCase();
2407
2481
  }
2408
2482
  const response = await this.privateGetWithdrawalsQuotas(this.extend(request, params));
2409
2483
  //
@@ -2460,7 +2534,8 @@ class kucoin extends kucoin$1["default"] {
2460
2534
  const chains = this.safeList(fee, 'chains', []);
2461
2535
  for (let i = 0; i < chains.length; i++) {
2462
2536
  const chain = chains[i];
2463
- 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'));
2464
2539
  resultNew['networks'][networkCodeNew] = {
2465
2540
  'withdraw': {
2466
2541
  'fee': this.safeNumber2(chain, 'withdrawalMinFee', 'withdrawMinFee'),
@@ -2488,7 +2563,9 @@ class kucoin extends kucoin$1["default"] {
2488
2563
  'networks': {},
2489
2564
  };
2490
2565
  const networkId = this.safeString(fee, 'chain');
2491
- 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']);
2492
2569
  result['networks'][networkCode] = {
2493
2570
  'withdraw': minWithdrawFee,
2494
2571
  'deposit': {
@@ -2773,8 +2850,8 @@ class kucoin extends kucoin$1["default"] {
2773
2850
  await this.loadMarkets();
2774
2851
  const request = {};
2775
2852
  symbols = this.marketSymbols(symbols, undefined, true, true);
2776
- let uta = undefined;
2777
- [uta, params] = this.handleOptionAndParams(params, 'fetchTickers', 'uta', false);
2853
+ let uta = false;
2854
+ [uta, params] = this.handleOptionAndParams(params, 'fetchTickers', 'uta', uta);
2778
2855
  const tradeType = this.safeString(params, 'tradeType');
2779
2856
  let firstMarket = undefined;
2780
2857
  if (symbols !== undefined) {
@@ -2974,8 +3051,8 @@ class kucoin extends kucoin$1["default"] {
2974
3051
  const request = {
2975
3052
  'symbol': market['id'],
2976
3053
  };
2977
- let uta = undefined;
2978
- [uta, params] = this.handleOptionAndParams(params, 'fetchTicker', 'uta', false);
3054
+ let uta = false;
3055
+ [uta, params] = this.handleOptionAndParams(params, 'fetchTicker', 'uta', uta);
2979
3056
  let response = undefined;
2980
3057
  let result = undefined;
2981
3058
  let type = undefined;
@@ -3148,8 +3225,8 @@ class kucoin extends kucoin$1["default"] {
3148
3225
  async fetchOHLCV(symbol, timeframe = '1m', since = undefined, limit = undefined, params = {}) {
3149
3226
  await this.loadMarkets();
3150
3227
  const market = this.market(symbol);
3151
- let uta = undefined;
3152
- [uta, params] = this.handleOptionAndParams(params, 'fetchOHLCV', 'uta', false);
3228
+ let uta = false;
3229
+ [uta, params] = this.handleOptionAndParams(params, 'fetchOHLCV', 'uta', uta);
3153
3230
  if (uta) {
3154
3231
  return await this.fetchUTAOHLCV(symbol, timeframe, since, limit, params);
3155
3232
  }
@@ -3370,7 +3447,7 @@ class kucoin extends kucoin$1["default"] {
3370
3447
  let networkCode = undefined;
3371
3448
  [networkCode, params] = this.handleNetworkCodeAndParams(params);
3372
3449
  if (networkCode !== undefined) {
3373
- 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"
3374
3451
  }
3375
3452
  const response = await this.privatePostDepositAddressCreate(this.extend(request, params));
3376
3453
  // {"code":"260000","msg":"Deposit address already exists."}
@@ -3396,10 +3473,12 @@ class kucoin extends kucoin$1["default"] {
3396
3473
  * @name kucoin#fetchDepositAddress
3397
3474
  * @description fetch the deposit address for a currency associated with this account
3398
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
3399
3477
  * @param {string} code unified currency code
3400
3478
  * @param {object} [params] extra parameters specific to the exchange API endpoint
3401
3479
  * @param {string} [params.network] the blockchain network name
3402
- * @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
3403
3482
  * @returns {object} an [address structure]{@link https://docs.ccxt.com/?id=address-structure}
3404
3483
  */
3405
3484
  async fetchDepositAddress(code, params = {}) {
@@ -3408,9 +3487,14 @@ class kucoin extends kucoin$1["default"] {
3408
3487
  [accountType, params] = this.handleOptionAndParams(params, 'fetchDepositAddress', 'accountType', accountType);
3409
3488
  const accountsByType = this.safeDict(this.options, 'accountsByType', {});
3410
3489
  accountType = this.safeString(accountsByType, accountType, accountType);
3490
+ let uta = await this.isUTAEnabled();
3491
+ [uta, params] = this.handleOptionAndParams(params, 'fetchDepositAddress', 'uta', uta);
3411
3492
  if (accountType === 'contract') {
3412
3493
  return await this.fetchContractDepositAddress(code, params);
3413
3494
  }
3495
+ else if (uta || (accountType === 'uta') || (accountType === 'unified')) {
3496
+ return await super.fetchDepositAddress(code, this.extend(params, { 'uta': true }));
3497
+ }
3414
3498
  const currency = this.currency(code);
3415
3499
  const request = {
3416
3500
  'currency': currency['id'],
@@ -3421,7 +3505,7 @@ class kucoin extends kucoin$1["default"] {
3421
3505
  let networkCode = undefined;
3422
3506
  [networkCode, params] = this.handleNetworkCodeAndParams(params);
3423
3507
  if (networkCode !== undefined) {
3424
- request['chain'] = this.networkCodeToId(networkCode).toLowerCase();
3508
+ request['chain'] = this.networkCodeToId(networkCode, currency['code']).toLowerCase();
3425
3509
  }
3426
3510
  const version = this.options['versions']['private']['GET']['deposit-addresses'];
3427
3511
  this.options['versions']['private']['GET']['deposit-addresses'] = 'v1';
@@ -3489,10 +3573,11 @@ class kucoin extends kucoin$1["default"] {
3489
3573
  this.checkAddress(address);
3490
3574
  }
3491
3575
  }
3576
+ const chainId = this.safeString(depositAddress, 'chainId');
3492
3577
  return {
3493
3578
  'info': depositAddress,
3494
3579
  'currency': code,
3495
- 'network': this.networkIdToCode(this.safeString(depositAddress, 'chainId')),
3580
+ 'network': this.networkIdToCode(chainId, code),
3496
3581
  'address': address,
3497
3582
  'tag': this.safeString(depositAddress, 'memo'),
3498
3583
  };
@@ -3501,9 +3586,11 @@ class kucoin extends kucoin$1["default"] {
3501
3586
  * @method
3502
3587
  * @name kucoin#fetchDepositAddressesByNetwork
3503
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
3504
3590
  * @description fetch the deposit address for a currency associated with this account
3505
3591
  * @param {string} code unified currency code
3506
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
3507
3594
  * @returns {object} an array of [address structures]{@link https://docs.ccxt.com/?id=address-structure}
3508
3595
  */
3509
3596
  async fetchDepositAddressesByNetwork(code, params = {}) {
@@ -3512,25 +3599,56 @@ class kucoin extends kucoin$1["default"] {
3512
3599
  const request = {
3513
3600
  'currency': currency['id'],
3514
3601
  };
3515
- const version = this.options['versions']['private']['GET']['deposit-addresses'];
3516
- this.options['versions']['private']['GET']['deposit-addresses'] = 'v2';
3517
- const response = await this.privateGetDepositAddresses(this.extend(request, params));
3518
- //
3519
- // {
3520
- // "code": "200000",
3521
- // "data": [
3522
- // {
3523
- // "address": "fr1qvus7d4d5fgxj5e7zvqe6yhxd7txm95h2and69r",
3524
- // "memo": "",
3525
- // "chain": "BTC-Segwit",
3526
- // "contractAddress": ""
3527
- // },
3528
- // {"address":"37icNMEWbiF8ZkwUMxmfzMxi2A1MQ44bMn","memo":"","chain":"BTC","contractAddress":""},
3529
- // {"address":"Deposit temporarily blocked","memo":"","chain":"TRC20","contractAddress":""}
3530
- // ]
3531
- // }
3532
- //
3533
- 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
+ }
3534
3652
  const chains = this.safeList(response, 'data', []);
3535
3653
  const parsed = this.parseDepositAddresses(chains, [currency['code']], false, {
3536
3654
  'currency': currency['code'],
@@ -3557,8 +3675,8 @@ class kucoin extends kucoin$1["default"] {
3557
3675
  const level = this.safeInteger(params, 'level', 2);
3558
3676
  const request = { 'symbol': market['id'] };
3559
3677
  const isAuthenticated = this.checkRequiredCredentials(false);
3560
- let uta = undefined;
3561
- [uta, params] = this.handleOptionAndParams(params, 'fetchOrderBook', 'uta', false);
3678
+ let uta = false;
3679
+ [uta, params] = this.handleOptionAndParams(params, 'fetchOrderBook', 'uta', uta);
3562
3680
  let response = undefined;
3563
3681
  let type = undefined;
3564
3682
  [type, params] = this.handleMarketTypeAndParams('fetchOrderBook', market, params);
@@ -3712,19 +3830,26 @@ class kucoin extends kucoin$1["default"] {
3712
3830
  * @see https://www.kucoin.com/docs-new/rest/futures-trading/orders/add-order
3713
3831
  * @see https://www.kucoin.com/docs-new/rest/futures-trading/orders/add-order-test
3714
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
3715
3834
  * @param {string} symbol Unified CCXT market symbol
3716
3835
  * @param {string} type 'limit' or 'market'
3717
3836
  * @param {string} side 'buy' or 'sell'
3718
3837
  * @param {float} amount the amount of currency to trade
3719
3838
  * @param {float} [price] the price at which the order is to be fulfilled, in units of the quote currency, ignored in market orders
3720
3839
  * @param {object} [params] extra parameters specific to the exchange API endpoint
3721
- * 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
3722
3842
  * @returns {object} an [order structure]{@link https://docs.ccxt.com/?id=order-structure}
3723
3843
  */
3724
3844
  async createOrder(symbol, type, side, amount, price = undefined, params = {}) {
3725
3845
  await this.loadMarkets();
3726
3846
  const market = this.market(symbol);
3727
- 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']) {
3728
3853
  return await this.createSpotOrder(symbol, type, side, amount, price, params);
3729
3854
  }
3730
3855
  else if (market['contract']) {
@@ -3754,7 +3879,7 @@ class kucoin extends kucoin$1["default"] {
3754
3879
  * @param {float} [params.triggerPrice] The price at which a trigger order is triggered at
3755
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
3756
3881
  * @param {string} [params.timeInForce] GTC, GTT, IOC, or FOK, default is GTC, limit orders only
3757
- * @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
3758
3883
  *
3759
3884
  * EXCHANGE SPECIFIC PARAMETERS
3760
3885
  * @param {string} [params.clientOid] client order id, defaults to uuid if not passed
@@ -3947,7 +4072,7 @@ class kucoin extends kucoin$1["default"] {
3947
4072
  * @param {float} [params.takeProfitPrice] price to trigger take-profit orders
3948
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.
3949
4074
  * @param {string} [params.timeInForce] GTC, GTT, IOC, or FOK, default is GTC, limit orders only
3950
- * @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
3951
4076
  * @param {float} [params.cost] the cost of the order in units of USDT
3952
4077
  * @param {string} [params.marginMode] 'cross' or 'isolated', default is 'isolated'
3953
4078
  * @param {bool} [params.hedged] *swap and future only* true for hedged mode, false for one way mode, default is false
@@ -4117,6 +4242,223 @@ class kucoin extends kucoin$1["default"] {
4117
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
4118
4243
  return this.extend(request, params);
4119
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
+ }
4120
4462
  /**
4121
4463
  * @method
4122
4464
  * @name kucoin#createMarketOrderWithCost
@@ -4408,16 +4750,23 @@ class kucoin extends kucoin$1["default"] {
4408
4750
  * @see https://www.kucoin.com/docs-new/rest/margin-trading/orders/cancel-stop-order-by-clientoid
4409
4751
  * @see https://www.kucoin.com/docs-new/rest/futures-trading/orders/cancel-order-by-orderld
4410
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
4411
4754
  * @param {string} id order id
4412
4755
  * @param {string} symbol unified symbol of the market the order was made in
4413
4756
  * @param {object} [params] extra parameters specific to the exchange API endpoint
4414
4757
  * @param {string} [params.type] 'spot' or 'swap', used if symbol is not provided (default is 'spot')
4415
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)
4416
4760
  * Check cancelSpotOrder() and cancelContractOrder() for more details on the extra parameters that can be used in params
4417
4761
  * @returns Response from the exchange
4418
4762
  */
4419
4763
  async cancelOrder(id, symbol = undefined, params = {}) {
4420
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
+ }
4421
4770
  let marketType = undefined;
4422
4771
  let market = undefined;
4423
4772
  if (symbol !== undefined) {
@@ -4634,6 +4983,61 @@ class kucoin extends kucoin$1["default"] {
4634
4983
  //
4635
4984
  return this.safeOrder({ 'info': response });
4636
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
+ }
4637
5041
  /**
4638
5042
  * @method
4639
5043
  * @name kucoin#cancelAllOrders
@@ -4645,14 +5049,22 @@ class kucoin extends kucoin$1["default"] {
4645
5049
  * @see https://www.kucoin.com/docs-new/rest/margin-trading/orders/batch-cancel-stop-orders
4646
5050
  * @see https://www.kucoin.com/docs-new/rest/futures-trading/orders/cancel-all-orders
4647
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
4648
5053
  * @param {string} symbol unified market symbol, only orders in the market of this symbol are cancelled when symbol is not undefined
4649
5054
  * @param {object} [params] extra parameters specific to the exchange API endpoint
4650
5055
  * @param {string} [params.type] 'spot' or 'swap', used if symbol is not provided (default is 'spot')
4651
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
4652
5059
  * @returns Response from the exchange
4653
5060
  */
4654
5061
  async cancelAllOrders(symbol = undefined, params = {}) {
4655
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
+ }
4656
5068
  let marketType = undefined;
4657
5069
  let market = undefined;
4658
5070
  if (symbol !== undefined) {
@@ -4770,26 +5182,78 @@ class kucoin extends kucoin$1["default"] {
4770
5182
  }
4771
5183
  /**
4772
5184
  * @method
4773
- * @name kucoin#fetchOrdersByStatus
4774
- * @description fetches a list of orders placed on the exchange
4775
- * @see https://www.kucoin.com/docs-new/rest/spot-trading/orders/get-open-orders
4776
- * @see https://www.kucoin.com/docs-new/rest/spot-trading/orders/get-closed-orders
4777
- * @see https://www.kucoin.com/docs-new/rest/spot-trading/orders/get-stop-orders-list
4778
- * @see https://www.kucoin.com/docs-new/rest/margin-trading/orders/get-open-orders
4779
- * @see https://www.kucoin.com/docs-new/rest/margin-trading/orders/get-closed-orders
4780
- * @see https://www.kucoin.com/docs-new/rest/margin-trading/orders/get-stop-order-list
4781
- * @see https://www.kucoin.com/docs-new/rest/futures-trading/orders/get-order-list
4782
- * @see https://www.kucoin.com/docs-new/rest/futures-trading/orders/get-stop-order-list
4783
- * @param {string} status 'active' or 'closed', only 'active' is valid for stop orders
4784
- * @param {string} symbol unified symbol for the market to retrieve orders from
4785
- * @param {int} [since] timestamp in ms of the earliest order to retrieve
4786
- * @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
4787
5248
  * @param {object} [params] exchange specific parameters
4788
- * 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
4789
5251
  * @returns An [array of order structures]{@link https://docs.ccxt.com/?id=order-structure}
4790
5252
  */
4791
5253
  async fetchOrdersByStatus(status, symbol = undefined, since = undefined, limit = undefined, params = {}) {
4792
5254
  await this.loadMarkets();
5255
+ let uta = await this.isUTAEnabled();
5256
+ [uta, params] = this.handleOptionAndParams(params, 'fetchOrdersByStatus', 'uta', uta);
4793
5257
  let marketType = undefined;
4794
5258
  if (symbol === undefined) {
4795
5259
  const type = this.safeString(params, 'type'); // exchange has specific param for order type
@@ -4799,14 +5263,26 @@ class kucoin extends kucoin$1["default"] {
4799
5263
  params = this.omit(params, 'type');
4800
5264
  }
4801
5265
  else {
4802
- [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
+ }
4803
5274
  }
4804
5275
  }
4805
5276
  else {
4806
5277
  const market = this.market(symbol);
4807
5278
  marketType = market['type'];
4808
5279
  }
4809
- 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')) {
4810
5286
  return await this.fetchSpotOrdersByStatus(status, symbol, since, limit, params);
4811
5287
  }
4812
5288
  else {
@@ -5071,6 +5547,128 @@ class kucoin extends kucoin$1["default"] {
5071
5547
  const orders = this.safeList(responseData, 'items', []);
5072
5548
  return this.parseOrders(orders, market, since, limit);
5073
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
+ }
5074
5672
  /**
5075
5673
  * @method
5076
5674
  * @name kucoin#fetchClosedOrders
@@ -5081,6 +5679,7 @@ class kucoin extends kucoin$1["default"] {
5081
5679
  * @see https://www.kucoin.com/docs-new/rest/futures-trading/orders/get-stop-order-list
5082
5680
  * @see https://www.kucoin.com/docs-new/rest/margin-trading/orders/get-open-orders
5083
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
5084
5683
  * @param {string} symbol unified market symbol of the market orders were made in
5085
5684
  * @param {int} [since] the earliest time in ms to fetch orders for
5086
5685
  * @param {int} [limit] the maximum number of order structures to retrieve
@@ -5114,6 +5713,7 @@ class kucoin extends kucoin$1["default"] {
5114
5713
  * @see https://www.kucoin.com/docs-new/rest/margin-trading/orders/get-open-orders
5115
5714
  * @see https://www.kucoin.com/docs-new/rest/margin-trading/orders/get-closed-orders
5116
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
5117
5717
  * @param {string} symbol unified market symbol
5118
5718
  * @param {int} [since] the earliest time in ms to fetch open orders for
5119
5719
  * @param {int} [limit] the maximum number of open orders structures to retrieve
@@ -5152,15 +5752,23 @@ class kucoin extends kucoin$1["default"] {
5152
5752
  * @see https://www.kucoin.com/docs-new/rest/margin-trading/orders/get-stop-order-by-clientoid
5153
5753
  * @see https://www.kucoin.com/docs-new/rest/futures-trading/orders/get-order-by-orderld
5154
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
5155
5756
  * @param {string} id order id
5156
5757
  * @param {string} symbol unified symbol of the market the order was made in
5157
5758
  * @param {object} [params] extra parameters specific to the exchange API endpoint
5158
5759
  * @param {string} [params.type] 'spot' or 'swap', used if symbol is not provided (default is 'spot')
5159
- * 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
5160
5762
  * @returns {object} An [order structure]{@link https://docs.ccxt.com/?id=order-structure}
5161
5763
  */
5162
5764
  async fetchOrder(id, symbol = undefined, params = {}) {
5163
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
+ }
5164
5772
  let marketType = undefined;
5165
5773
  if (symbol === undefined) {
5166
5774
  [marketType, params] = this.handleMarketTypeAndParams('fetchOrder', undefined, params);
@@ -5351,7 +5959,115 @@ class kucoin extends kucoin$1["default"] {
5351
5959
  const responseData = this.safeDict(response, 'data');
5352
5960
  return this.parseOrder(responseData, market);
5353
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
+ }
5354
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
+ }
5355
6071
  const marketId = this.safeString(order, 'symbol');
5356
6072
  market = this.safeMarket(marketId, market);
5357
6073
  if ((market !== undefined) && (market['contract'])) {
@@ -5676,6 +6392,128 @@ class kucoin extends kucoin$1["default"] {
5676
6392
  'trades': undefined,
5677
6393
  }, market);
5678
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
+ }
5679
6517
  /**
5680
6518
  * @method
5681
6519
  * @name kucoin#fetchOrderTrades
@@ -5683,12 +6521,14 @@ class kucoin extends kucoin$1["default"] {
5683
6521
  * @see https://docs.kucoin.com/#list-fills
5684
6522
  * @see https://www.kucoin.com/docs-new/rest/futures-trading/orders/get-trade-history
5685
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
5686
6525
  * @param {string} id order id
5687
6526
  * @param {string} symbol unified market symbol
5688
6527
  * @param {int} [since] the earliest time in ms to fetch trades for
5689
6528
  * @param {int} [limit] the maximum number of trades to retrieve
5690
6529
  * @param {object} [params] extra parameters specific to the exchange API endpoint
5691
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.
5692
6532
  * @returns {object[]} a list of [trade structures]{@link https://docs.ccxt.com/?id=trade-structure}
5693
6533
  */
5694
6534
  async fetchOrderTrades(id, symbol = undefined, since = undefined, limit = undefined, params = {}) {
@@ -5702,6 +6542,7 @@ class kucoin extends kucoin$1["default"] {
5702
6542
  * @name kucoin#fetchMyTrades
5703
6543
  * @see https://www.kucoin.com/docs-new/rest/spot-trading/orders/get-trade-history
5704
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
5705
6546
  * @description fetch all trades made by the user
5706
6547
  * @param {string} symbol unified market symbol
5707
6548
  * @param {int} [since] the earliest time in ms to fetch trades for
@@ -5720,6 +6561,12 @@ class kucoin extends kucoin$1["default"] {
5720
6561
  market = this.market(symbol);
5721
6562
  }
5722
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
+ }
5723
6570
  if ((marketType === 'spot') || (marketType === 'margin')) {
5724
6571
  return await this.fetchMySpotTrades(symbol, since, limit, params);
5725
6572
  }
@@ -5936,57 +6783,144 @@ class kucoin extends kucoin$1["default"] {
5936
6783
  }
5937
6784
  /**
5938
6785
  * @method
5939
- * @name kucoin#fetchTrades
5940
- * @description get the list of most recent trades for a particular symbol
5941
- * @see https://www.kucoin.com/docs-new/rest/spot-trading/market-data/get-trade-history
5942
- * @see https://www.kucoin.com/docs-new/rest/ua/get-trades
5943
- * @see https://www.kucoin.com/docs-new/rest/futures-trading/market-data/get-trade-history
5944
- * @param {string} symbol unified symbol of the market to fetch trades for
5945
- * @param {int} [since] timestamp in ms of the earliest trade to fetch
5946
- * @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)
5947
6792
  * @param {object} [params] extra parameters specific to the exchange API endpoint
5948
- * @param {boolean} [params.uta] set to true for the unified trading account (uta), defaults to false
5949
- * @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}
5950
6799
  */
5951
- async fetchTrades(symbol, since = undefined, limit = undefined, params = {}) {
6800
+ async fetchMyUtaTrades(symbol = undefined, since = undefined, limit = undefined, params = {}) {
5952
6801
  await this.loadMarkets();
5953
- const market = this.market(symbol);
5954
- const request = {
5955
- 'symbol': market['id'],
5956
- };
5957
- // pagination is not supported on the exchange side anymore
5958
- // if (since !== undefined) {
5959
- // request['startAt'] = Math.floor (since / 1000);
5960
- // }
5961
- // if (limit !== undefined) {
5962
- // request['pageSize'] = limit;
5963
- // }
5964
- let uta = undefined;
5965
- [uta, params] = this.handleOptionAndParams(params, 'fetchTrades', 'uta', false);
5966
- let response = undefined;
5967
- let trades = undefined;
5968
- let type = undefined;
5969
- [type, params] = this.handleMarketTypeAndParams('fetchTrades', market, params);
5970
- if (uta) {
5971
- if ((type === 'spot') || (type === 'margin')) {
5972
- request['tradeType'] = 'SPOT';
5973
- }
5974
- else {
5975
- request['tradeType'] = 'FUTURES';
5976
- }
5977
- response = await this.utaGetMarketTrade(this.extend(request, params));
5978
- //
5979
- // {
5980
- // "code": "200000",
5981
- // "data": {
5982
- // "tradeType": "SPOT",
5983
- // "list": [
5984
- // {
5985
- // "sequence": "18746044393340932",
5986
- // "tradeId": "18746044393340932",
5987
- // "price": "104355.6",
5988
- // "size": "0.00011886",
5989
- // "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",
5990
6924
  // "ts": 1762242540829000000
5991
6925
  // },
5992
6926
  // ]
@@ -6038,6 +6972,9 @@ class kucoin extends kucoin$1["default"] {
6038
6972
  return this.parseTrades(trades, market, since, limit);
6039
6973
  }
6040
6974
  parseTrade(trade, market = undefined) {
6975
+ if ('liquidityRole' in trade) { // property specific to myTrades from uta endpoint
6976
+ return this.parseMyUtaTrade(trade, market);
6977
+ }
6041
6978
  const marketId = this.safeString(trade, 'symbol');
6042
6979
  market = this.safeMarket(marketId, market);
6043
6980
  if ((market === undefined) || (market['spot'])) {
@@ -6324,23 +7261,97 @@ class kucoin extends kucoin$1["default"] {
6324
7261
  'fee': fee,
6325
7262
  }, market);
6326
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
+ }
6327
7306
  /**
6328
7307
  * @method
6329
7308
  * @name kucoin#fetchTradingFee
6330
7309
  * @description fetch the trading fees for a market
6331
7310
  * @see https://www.kucoin.com/docs-new/rest/account-info/trade-fee/get-actual-fee-spot-margin
6332
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
6333
7313
  * @param {string} symbol unified market symbol
6334
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
6335
7316
  * @returns {object} a [fee structure]{@link https://docs.ccxt.com/?id=fee-structure}
6336
7317
  */
6337
7318
  async fetchTradingFee(symbol, params = {}) {
6338
7319
  await this.loadMarkets();
6339
7320
  const market = this.market(symbol);
7321
+ let uta = await this.isUTAEnabled();
7322
+ [uta, params] = this.handleOptionAndParams(params, 'fetchTradingFee', 'uta', uta);
6340
7323
  const request = {};
6341
7324
  let response = undefined;
6342
7325
  let entry = undefined;
6343
- 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']) {
6344
7355
  request['symbols'] = market['id'];
6345
7356
  response = await this.privateGetTradeFees(this.extend(request, params));
6346
7357
  //
@@ -6416,7 +7427,7 @@ class kucoin extends kucoin$1["default"] {
6416
7427
  let networkCode = undefined;
6417
7428
  [networkCode, params] = this.handleNetworkCodeAndParams(params);
6418
7429
  if (networkCode !== undefined) {
6419
- request['chain'] = this.networkCodeToId(networkCode).toLowerCase();
7430
+ request['chain'] = this.networkCodeToId(networkCode, currency['code']).toLowerCase();
6420
7431
  }
6421
7432
  request['amount'] = parseFloat(this.currencyToPrecision(code, amount, networkCode));
6422
7433
  let includeFee = undefined;
@@ -6537,12 +7548,13 @@ class kucoin extends kucoin$1["default"] {
6537
7548
  }
6538
7549
  const internal = this.safeBool(transaction, 'isInner');
6539
7550
  const tag = this.safeString(transaction, 'memo');
7551
+ const chainId = this.safeString(transaction, 'chain');
6540
7552
  return {
6541
7553
  'info': transaction,
6542
7554
  'id': this.safeString2(transaction, 'id', 'withdrawalId'),
6543
7555
  'timestamp': timestamp,
6544
7556
  'datetime': this.iso8601(timestamp),
6545
- 'network': this.networkIdToCode(this.safeString(transaction, 'chain')),
7557
+ 'network': this.networkIdToCode(chainId, code),
6546
7558
  'address': address,
6547
7559
  'addressTo': address,
6548
7560
  'addressFrom': undefined,
@@ -6734,10 +7746,11 @@ class kucoin extends kucoin$1["default"] {
6734
7746
  if (accountType === 'contract') {
6735
7747
  return await this.fetchContractWithdrawals(code, since, limit, params);
6736
7748
  }
7749
+ const maxLimit = 500;
6737
7750
  let paginate = false;
6738
7751
  [paginate, params] = this.handleOptionAndParams(params, 'fetchWithdrawals', 'paginate');
6739
7752
  if (paginate) {
6740
- return await this.fetchPaginatedCallDynamic('fetchWithdrawals', code, since, limit, params);
7753
+ return await this.fetchPaginatedCallDynamic('fetchWithdrawals', code, since, limit, params, maxLimit);
6741
7754
  }
6742
7755
  let request = {};
6743
7756
  let currency = undefined;
@@ -6877,14 +7890,24 @@ class kucoin extends kucoin$1["default"] {
6877
7890
  * @see https://www.kucoin.com/docs-new/rest/account-info/account-funding/get-account-cross-margin
6878
7891
  * @see https://www.kucoin.com/docs-new/rest/account-info/account-funding/get-account-isolated-margin
6879
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
6880
7895
  * @param {object} [params] extra parameters specific to the exchange API endpoint
6881
7896
  * @param {object} [params.marginMode] 'cross' or 'isolated', margin type for fetching margin balance
6882
7897
  * @param {object} [params.type] extra parameters specific to the exchange API endpoint
6883
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
6884
7900
  * @returns {object} a [balance structure]{@link https://docs.ccxt.com/?id=balance-structure}
6885
7901
  */
6886
7902
  async fetchBalance(params = {}) {
6887
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 = {};
6888
7911
  const code = this.safeString(params, 'code');
6889
7912
  let currency = undefined;
6890
7913
  if (code !== undefined) {
@@ -6903,26 +7926,25 @@ class kucoin extends kucoin$1["default"] {
6903
7926
  if (hf && (type !== 'main')) {
6904
7927
  type = 'trade_hf';
6905
7928
  }
6906
- const [marginMode, query] = this.handleMarginModeAndParams('fetchBalance', params);
6907
- let response = undefined;
6908
- const request = {};
7929
+ let marginMode = undefined;
7930
+ [marginMode, params] = this.handleMarginModeAndParams('fetchBalance', params);
6909
7931
  const isolated = (marginMode === 'isolated') || (type === 'isolated');
6910
7932
  const cross = (marginMode === 'cross') || (type === 'margin');
6911
7933
  if (isolated) {
6912
7934
  if (currency !== undefined) {
6913
7935
  request['balanceCurrency'] = currency['id'];
6914
7936
  }
6915
- response = await this.privateGetIsolatedAccounts(this.extend(request, query));
7937
+ response = await this.privateGetIsolatedAccounts(this.extend(request, params));
6916
7938
  }
6917
7939
  else if (cross) {
6918
- response = await this.privateGetMarginAccount(this.extend(request, query));
7940
+ response = await this.privateGetMarginAccount(this.extend(request, params));
6919
7941
  }
6920
7942
  else {
6921
7943
  if (currency !== undefined) {
6922
7944
  request['currency'] = currency['id'];
6923
7945
  }
6924
7946
  request['type'] = type;
6925
- response = await this.privateGetAccounts(this.extend(request, query));
7947
+ response = await this.privateGetAccounts(this.extend(request, params));
6926
7948
  }
6927
7949
  //
6928
7950
  // Spot
@@ -7106,11 +8128,260 @@ class kucoin extends kucoin$1["default"] {
7106
8128
  result[currencyCode] = account;
7107
8129
  return this.safeBalance(result);
7108
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
+ }
7109
8269
  /**
7110
8270
  * @method
7111
8271
  * @name kucoin#transfer
7112
8272
  * @description transfer currency internally between wallets on the same account
7113
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&
7114
8385
  * @param {string} code unified currency code
7115
8386
  * @param {float} amount amount to transfer
7116
8387
  * @param {string} fromAccount account to transfer from
@@ -7121,7 +8392,7 @@ class kucoin extends kucoin$1["default"] {
7121
8392
  * @param {string} [params.toUserId] required if transferType is PARENT_TO_SUB
7122
8393
  * @returns {object} a [transfer structure]{@link https://docs.ccxt.com/?id=transfer-structure}
7123
8394
  */
7124
- async transfer(code, amount, fromAccount, toAccount, params = {}) {
8395
+ async transferClassic(code, amount, fromAccount, toAccount, params = {}) {
7125
8396
  await this.loadMarkets();
7126
8397
  const currency = this.currency(code);
7127
8398
  const requestedAmount = this.currencyToPrecision(code, amount);
@@ -7335,12 +8606,32 @@ class kucoin extends kucoin$1["default"] {
7335
8606
  // 'Pool transactions': 'Pool transactions', // Pool-X transactions
7336
8607
  'Instant Exchange': 'trade',
7337
8608
  'Sub-account transfer': 'transfer',
7338
- 'Liquidation Fees': 'fee', // Liquidation Fees
8609
+ 'Liquidation Fees': 'fee',
7339
8610
  // 'Soft Staking Profits': 'Soft Staking Profits', // Soft Staking Profits
7340
8611
  // 'Voting Earnings': 'Voting Earnings', // Voting Earnings on Pool-X
7341
8612
  // 'Redemption of Voting': 'Redemption of Voting', // Redemption of Voting on Pool-X
7342
8613
  // 'Voting': 'Voting', // Voting on Pool-X
7343
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',
7344
8635
  };
7345
8636
  return this.safeString(types, type, type);
7346
8637
  }
@@ -7350,6 +8641,8 @@ class kucoin extends kucoin$1["default"] {
7350
8641
  'out': 'out',
7351
8642
  'TransferIn': 'in',
7352
8643
  'TransferOut': 'out',
8644
+ 'IN': 'in',
8645
+ 'OUT': 'out',
7353
8646
  };
7354
8647
  return this.safeString(directions, direction, direction);
7355
8648
  }
@@ -7388,14 +8681,28 @@ class kucoin extends kucoin$1["default"] {
7388
8681
  // "currency": "USDT"
7389
8682
  // }
7390
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
+ //
7391
8699
  const id = this.safeString(item, 'id');
7392
8700
  const currencyId = this.safeString(item, 'currency');
7393
8701
  const code = this.safeCurrencyCode(currencyId, currency);
7394
8702
  currency = this.safeCurrency(currencyId, currency);
7395
8703
  const amount = this.safeString(item, 'amount');
7396
- const balanceAfter = undefined;
7397
- // const balanceAfter = this.safeNumber (item, 'balance'); only returns zero string
7398
- const bizType = this.safeString(item, 'bizType');
8704
+ const balanceAfter = this.safeNumberOmitZero(item, 'balance');
8705
+ const bizType = this.safeStringN(item, ['bizType', 'businessType', 'type']);
7399
8706
  const type = this.parseLedgerEntryType(bizType);
7400
8707
  const direction = this.safeString2(item, 'direction', 'type');
7401
8708
  let account = this.safeString(item, 'accountType'); // MAIN, TRADE, MARGIN, or CONTRACT
@@ -7405,6 +8712,9 @@ class kucoin extends kucoin$1["default"] {
7405
8712
  if (timestamp !== undefined) {
7406
8713
  account = 'CONTRACT'; // contract ledger entries do not have an accountType field, so we set it to CONTRACT if the time field is present
7407
8714
  }
8715
+ else {
8716
+ timestamp = this.safeIntegerProduct(item, 'ts', 0.000001); // for UTA API
8717
+ }
7408
8718
  }
7409
8719
  const datetime = this.iso8601(timestamp);
7410
8720
  const context = this.safeString(item, 'context'); // contains other information about the ledger entry
@@ -7473,6 +8783,7 @@ class kucoin extends kucoin$1["default"] {
7473
8783
  * @see https://www.kucoin.com/docs-new/rest/account-info/account-funding/get-account-ledgers-tradehf
7474
8784
  * @see https://www.kucoin.com/docs-new/rest/account-info/account-funding/get-account-ledgers-marginhf
7475
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
7476
8787
  * @param {string} [code] unified currency code, default is undefined
7477
8788
  * @param {int} [since] timestamp in ms of the earliest ledger entry, default is undefined
7478
8789
  * @param {int} [limit] max number of ledger entries to return, default is undefined
@@ -7480,18 +8791,50 @@ class kucoin extends kucoin$1["default"] {
7480
8791
  * @param {object} [params.type] extra parameters specific to the exchange API endpoint
7481
8792
  * @param {boolean} [params.hf] default false, when true will fetch ledger entries for the high frequency trading account
7482
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
7483
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)
7484
8796
  * @returns {object} a [ledger structure]{@link https://docs.ccxt.com/?id=ledger-entry-structure}
7485
8797
  */
7486
8798
  async fetchLedger(code = undefined, since = undefined, limit = undefined, params = {}) {
7487
8799
  await this.loadMarkets();
7488
8800
  await this.loadAccounts();
7489
- let paginate = false;
7490
- [paginate, params] = this.handleOptionAndParams(params, 'fetchLedger', 'paginate');
8801
+ let uta = await this.isUTAEnabled();
8802
+ [uta, params] = this.handleOptionAndParams(params, 'fetchLedger', 'uta', uta);
7491
8803
  let hf = undefined;
7492
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');
7493
8836
  if (paginate) {
7494
- return await this.fetchPaginatedCallDynamic('fetchLedger', code, since, limit, params);
8837
+ return await this.fetchPaginatedCallDynamic('fetchLedger', code, since, limit, params, maxLimit);
7495
8838
  }
7496
8839
  let request = {
7497
8840
  // 'currency': currency['id'], // can choose up to 10, if not provided returns for all currencies by default
@@ -7510,14 +8853,23 @@ class kucoin extends kucoin$1["default"] {
7510
8853
  request['currency'] = currency['id'];
7511
8854
  }
7512
8855
  [request, params] = this.handleUntilOption('endAt', request, params);
7513
- let marginMode = undefined;
7514
- [marginMode, params] = this.handleMarginModeAndParams('fetchLedger', params);
7515
- let type = undefined;
7516
- [type, params] = this.handleMarketTypeAndParams('fetchLedger', undefined, params);
7517
- const accountsByType = this.safeDict(this.options, 'accountsByType');
7518
- 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
+ }
7519
8867
  let response = undefined;
7520
- if (hf) {
8868
+ if (uta) {
8869
+ request['accountType'] = type;
8870
+ response = await this.utaPrivateGetAccountLedger(this.extend(request, params));
8871
+ }
8872
+ else if (hf) {
7521
8873
  if (marginMode !== undefined) {
7522
8874
  response = await this.privateGetHfMarginAccountLedgers(this.extend(request, params));
7523
8875
  }
@@ -7759,12 +9111,14 @@ class kucoin extends kucoin$1["default"] {
7759
9111
  // Cross
7760
9112
  //
7761
9113
  // {
7762
- // "currency": "1INCH",
7763
- // "total": "0",
7764
- // "available": "0",
9114
+ // "currency": "DOGE",
9115
+ // "total": "119.99995308",
9116
+ // "available": "119.99995308",
7765
9117
  // "hold": "0",
7766
- // "liability": "0",
7767
- // "maxBorrowSize": "0",
9118
+ // "liability": "10.00004692",
9119
+ // "liabilityPrincipal": "10",
9120
+ // "liabilityInterest": "0.00004692",
9121
+ // "maxBorrowSize": "1140",
7768
9122
  // "borrowEnabled": true,
7769
9123
  // "transferInEnabled": true
7770
9124
  // }
@@ -7772,30 +9126,32 @@ class kucoin extends kucoin$1["default"] {
7772
9126
  // Isolated
7773
9127
  //
7774
9128
  // {
7775
- // "symbol": "MANA-USDT",
7776
- // "debtRatio": "0",
7777
- // "status": "BORROW",
9129
+ // "symbol": "DOGE-USDT",
9130
+ // "status": "EFFECTIVE",
9131
+ // "debtRatio": "0.0822",
7778
9132
  // "baseAsset": {
7779
- // "currency": "MANA",
9133
+ // "currency": "DOGE",
7780
9134
  // "borrowEnabled": true,
7781
- // "repayEnabled": true,
7782
- // "transferEnabled": true,
7783
- // "borrowed": "0",
7784
- // "totalAsset": "0",
7785
- // "available": "0",
9135
+ // "transferInEnabled": true,
9136
+ // "liability": "10.00009385",
9137
+ // "liabilityPrincipal": "10.00004692",
9138
+ // "liabilityInterest": "0.00004693",
9139
+ // "total": "10",
9140
+ // "available": "10",
7786
9141
  // "hold": "0",
7787
- // "maxBorrowSize": "1000"
9142
+ // "maxBorrowSize": "990"
7788
9143
  // },
7789
9144
  // "quoteAsset": {
7790
9145
  // "currency": "USDT",
7791
9146
  // "borrowEnabled": true,
7792
- // "repayEnabled": true,
7793
- // "transferEnabled": true,
7794
- // "borrowed": "0",
7795
- // "totalAsset": "0",
7796
- // "available": "0",
9147
+ // "transferInEnabled": true,
9148
+ // "liability": "0",
9149
+ // "liabilityPrincipal": "0",
9150
+ // "liabilityInterest": "0",
9151
+ // "total": "10",
9152
+ // "available": "10",
7797
9153
  // "hold": "0",
7798
- // "maxBorrowSize": "50000"
9154
+ // "maxBorrowSize": "89"
7799
9155
  // }
7800
9156
  // }
7801
9157
  //
@@ -7803,19 +9159,18 @@ class kucoin extends kucoin$1["default"] {
7803
9159
  const marginMode = (marketId === undefined) ? 'cross' : 'isolated';
7804
9160
  market = this.safeMarket(marketId, market);
7805
9161
  const symbol = this.safeString(market, 'symbol');
7806
- const timestamp = this.safeInteger(info, 'createdAt');
7807
9162
  const isolatedBase = this.safeDict(info, 'baseAsset', {});
7808
9163
  let amountBorrowed = undefined;
7809
9164
  let interest = undefined;
7810
9165
  let currencyId = undefined;
7811
9166
  if (marginMode === 'isolated') {
7812
- amountBorrowed = this.safeNumber(isolatedBase, 'liability');
7813
- interest = this.safeNumber(isolatedBase, 'interest');
9167
+ amountBorrowed = this.safeNumber(isolatedBase, 'liabilityPrincipal');
9168
+ interest = this.safeNumber(isolatedBase, 'liabilityInterest');
7814
9169
  currencyId = this.safeString(isolatedBase, 'currency');
7815
9170
  }
7816
9171
  else {
7817
- amountBorrowed = this.safeNumber(info, 'liability');
7818
- interest = this.safeNumber(info, 'accruedInterest');
9172
+ amountBorrowed = this.safeNumber(info, 'liabilityPrincipal');
9173
+ interest = this.safeNumber(info, 'liabilityInterest');
7819
9174
  currencyId = this.safeString(info, 'currency');
7820
9175
  }
7821
9176
  return {
@@ -7826,8 +9181,8 @@ class kucoin extends kucoin$1["default"] {
7826
9181
  'interestRate': this.safeNumber(info, 'dailyIntRate'),
7827
9182
  'amountBorrowed': amountBorrowed,
7828
9183
  'marginMode': marginMode,
7829
- 'timestamp': timestamp,
7830
- 'datetime': this.iso8601(timestamp),
9184
+ 'timestamp': undefined,
9185
+ 'datetime': undefined,
7831
9186
  };
7832
9187
  }
7833
9188
  /**
@@ -8210,9 +9565,11 @@ class kucoin extends kucoin$1["default"] {
8210
9565
  * @description set the level of leverage for a market
8211
9566
  * @see https://www.kucoin.com/docs-new/rest/margin-trading/debit/modify-leverage
8212
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
8213
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
8214
9570
  * @param {string} [symbol] unified market symbol
8215
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)
8216
9573
  * @returns {object} response from the exchange
8217
9574
  */
8218
9575
  async setLeverage(leverage, symbol = undefined, params = {}) {
@@ -8221,11 +9578,19 @@ class kucoin extends kucoin$1["default"] {
8221
9578
  let marketType = undefined;
8222
9579
  [marketType, params] = this.handleMarketTypeAndParams('setLeverage', undefined, params);
8223
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
+ }
8224
9584
  market = this.market(symbol);
8225
9585
  if (market['contract']) {
8226
9586
  return await this.setContractLeverage(leverage, symbol, params);
8227
9587
  }
8228
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
+ }
8229
9594
  let marginMode = undefined;
8230
9595
  [marginMode, params] = this.handleMarginModeAndParams('setLeverage', params);
8231
9596
  if (marginMode === undefined) {
@@ -8247,15 +9612,17 @@ class kucoin extends kucoin$1["default"] {
8247
9612
  * @name kucoin#setContractLeverage
8248
9613
  * @description set the level of leverage for a market
8249
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
8250
9616
  * @param {float} leverage the rate of leverage
8251
9617
  * @param {string} symbol unified market symbol
8252
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)
8253
9620
  * @returns {object} response from the exchange
8254
9621
  */
8255
9622
  async setContractLeverage(leverage, symbol = undefined, params = {}) {
8256
9623
  let marginMode = undefined;
8257
9624
  [marginMode, params] = this.handleMarginModeAndParams(symbol, params);
8258
- if (marginMode !== 'cross') {
9625
+ if ((marginMode !== undefined) && (marginMode !== 'cross')) {
8259
9626
  throw new errors.NotSupported(this.id + ' setLeverage() currently supports only params["marginMode"] = "cross" for contracts');
8260
9627
  }
8261
9628
  await this.loadMarkets();
@@ -8264,14 +9631,24 @@ class kucoin extends kucoin$1["default"] {
8264
9631
  'symbol': market['id'],
8265
9632
  'leverage': leverage.toString(),
8266
9633
  };
8267
- const response = await this.futuresPrivatePostChangeCrossUserLeverage(this.extend(request, params));
8268
- //
8269
- // {
8270
- // "code": "200000",
8271
- // "data": true
8272
- // }
8273
- //
8274
- 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');
8275
9652
  return {
8276
9653
  'info': response,
8277
9654
  'symbol': market['symbol'],
@@ -8430,7 +9807,7 @@ class kucoin extends kucoin$1["default"] {
8430
9807
  'symbol': market['id'],
8431
9808
  };
8432
9809
  const until = this.safeInteger(params, 'until');
8433
- let uta = true; // for backward compatibility, dafult endpoint is uta
9810
+ let uta = false;
8434
9811
  [uta, params] = this.handleOptionAndParams(params, 'fetchFundingRateHistory', 'uta', uta);
8435
9812
  params = this.omit(params, 'until');
8436
9813
  let start = since;
@@ -8585,9 +9962,11 @@ class kucoin extends kucoin$1["default"] {
8585
9962
  * @method
8586
9963
  * @name kucoin#fetchPosition
8587
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
8588
9966
  * @description fetch data on an open position
8589
9967
  * @param {string} symbol unified market symbol of the market the position is held in
8590
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
8591
9970
  * @returns {object} a [position structure]{@link https://docs.ccxt.com/?id=position-structure}
8592
9971
  */
8593
9972
  async fetchPosition(symbol, params = {}) {
@@ -8596,112 +9975,157 @@ class kucoin extends kucoin$1["default"] {
8596
9975
  const request = {
8597
9976
  'symbol': market['id'],
8598
9977
  };
8599
- const response = await this.futuresPrivateGetPosition(this.extend(request, params));
8600
- //
8601
- // {
8602
- // "code": "200000",
8603
- // "data": {
8604
- // "id": "6505ee6eaff4070001f651c4",
8605
- // "symbol": "XBTUSDTM",
8606
- // "autoDeposit": false,
8607
- // "maintMarginReq": 0,
8608
- // "riskLimit": 200,
8609
- // "realLeverage": 0.0,
8610
- // "crossMode": false,
8611
- // "delevPercentage": 0.0,
8612
- // "currentTimestamp": 1694887534594,
8613
- // "currentQty": 0,
8614
- // "currentCost": 0.0,
8615
- // "currentComm": 0.0,
8616
- // "unrealisedCost": 0.0,
8617
- // "realisedGrossCost": 0.0,
8618
- // "realisedCost": 0.0,
8619
- // "isOpen": false,
8620
- // "markPrice": 26611.71,
8621
- // "markValue": 0.0,
8622
- // "posCost": 0.0,
8623
- // "posCross": 0,
8624
- // "posInit": 0.0,
8625
- // "posComm": 0.0,
8626
- // "posLoss": 0.0,
8627
- // "posMargin": 0.0,
8628
- // "posMaint": 0.0,
8629
- // "maintMargin": 0.0,
8630
- // "realisedGrossPnl": 0.0,
8631
- // "realisedPnl": 0.0,
8632
- // "unrealisedPnl": 0.0,
8633
- // "unrealisedPnlPcnt": 0,
8634
- // "unrealisedRoePcnt": 0,
8635
- // "avgEntryPrice": 0.0,
8636
- // "liquidationPrice": 0.0,
8637
- // "bankruptPrice": 0.0,
8638
- // "settleCurrency": "USDT",
8639
- // "maintainMargin": 0,
8640
- // "riskLimitLevel": 1
8641
- // }
8642
- // }
8643
- //
8644
- const data = this.safeDict(response, 'data', {});
8645
- 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);
8646
10060
  }
8647
10061
  /**
8648
10062
  * @method
8649
10063
  * @name kucoin#fetchPositions
8650
10064
  * @description fetch all open positions
8651
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
8652
10067
  * @param {string[]|undefined} symbols list of unified market symbols
8653
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
8654
10070
  * @returns {object[]} a list of [position structure]{@link https://docs.ccxt.com/?id=position-structure}
8655
10071
  */
8656
10072
  async fetchPositions(symbols = undefined, params = {}) {
8657
10073
  await this.loadMarkets();
8658
- const response = await this.futuresPrivateGetPositions(params);
8659
- //
8660
- // {
8661
- // "code": "200000",
8662
- // "data": [
8663
- // {
8664
- // "id": "615ba79f83a3410001cde321",
8665
- // "symbol": "ETHUSDTM",
8666
- // "autoDeposit": false,
8667
- // "maintMarginReq": 0.005,
8668
- // "riskLimit": 1000000,
8669
- // "realLeverage": 18.61,
8670
- // "crossMode": false,
8671
- // "delevPercentage": 0.86,
8672
- // "openingTimestamp": 1638563515618,
8673
- // "currentTimestamp": 1638576872774,
8674
- // "currentQty": 2,
8675
- // "currentCost": 83.64200000,
8676
- // "currentComm": 0.05018520,
8677
- // "unrealisedCost": 83.64200000,
8678
- // "realisedGrossCost": 0.00000000,
8679
- // "realisedCost": 0.05018520,
8680
- // "isOpen": true,
8681
- // "markPrice": 4225.01,
8682
- // "markValue": 84.50020000,
8683
- // "posCost": 83.64200000,
8684
- // "posCross": 0.0000000000,
8685
- // "posInit": 3.63660870,
8686
- // "posComm": 0.05236717,
8687
- // "posLoss": 0.00000000,
8688
- // "posMargin": 3.68897586,
8689
- // "posMaint": 0.50637594,
8690
- // "maintMargin": 4.54717586,
8691
- // "realisedGrossPnl": 0.00000000,
8692
- // "realisedPnl": -0.05018520,
8693
- // "unrealisedPnl": 0.85820000,
8694
- // "unrealisedPnlPcnt": 0.0103,
8695
- // "unrealisedRoePcnt": 0.2360,
8696
- // "avgEntryPrice": 4182.10,
8697
- // "liquidationPrice": 4023.00,
8698
- // "bankruptPrice": 4000.25,
8699
- // "settleCurrency": "USDT",
8700
- // "isInverse": false
8701
- // }
8702
- // ]
8703
- // }
8704
- //
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
+ }
8705
10129
  const data = this.safeList(response, 'data');
8706
10130
  return this.parsePositions(data, symbols);
8707
10131
  }
@@ -8710,69 +10134,120 @@ class kucoin extends kucoin$1["default"] {
8710
10134
  * @name kucoin#fetchPositionsHistory
8711
10135
  * @description fetches historical positions
8712
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
8713
10138
  * @param {string[]} [symbols] list of unified market symbols
8714
10139
  * @param {int} [since] the earliest time in ms to fetch position history for
8715
10140
  * @param {int} [limit] the maximum number of entries to retrieve
8716
10141
  * @param {object} [params] extra parameters specific to the exchange API endpoint
8717
10142
  * @param {int} [params.until] closing end time
8718
10143
  * @param {int} [params.pageId] page id
10144
+ * @param {boolean} [params.uta] set to true for the unified trading account (uta), defaults to false
8719
10145
  * @returns {object[]} a list of [position structure]{@link https://docs.ccxt.com/?id=position-structure}
8720
10146
  */
8721
10147
  async fetchPositionsHistory(symbols = undefined, since = undefined, limit = undefined, params = {}) {
8722
10148
  await this.loadMarkets();
8723
- if (limit === undefined) {
8724
- 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
+ }
8725
10160
  }
8726
- const request = {
8727
- 'limit': limit,
8728
- };
8729
- if (since !== undefined) {
8730
- 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));
8731
10197
  }
8732
- const until = this.safeInteger(params, 'until');
8733
- if (until !== undefined) {
8734
- params = this.omit(params, 'until');
8735
- 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));
8736
10250
  }
8737
- const response = await this.futuresPrivateGetHistoryPositions(this.extend(request, params));
8738
- //
8739
- // {
8740
- // "success": true,
8741
- // "code": "200",
8742
- // "msg": "success",
8743
- // "retry": false,
8744
- // "data": {
8745
- // "currentPage": 1,
8746
- // "pageSize": 10,
8747
- // "totalNum": 25,
8748
- // "totalPage": 3,
8749
- // "items": [
8750
- // {
8751
- // "closeId": "300000000000000030",
8752
- // "positionId": "300000000000000009",
8753
- // "uid": 99996908309485,
8754
- // "userId": "6527d4fc8c7f3d0001f40f5f",
8755
- // "symbol": "XBTUSDM",
8756
- // "settleCurrency": "XBT",
8757
- // "leverage": "0.0",
8758
- // "type": "LIQUID_LONG",
8759
- // "side": null,
8760
- // "closeSize": null,
8761
- // "pnl": "-1.0000003793999999",
8762
- // "realisedGrossCost": "0.9993849748999999",
8763
- // "withdrawPnl": "0.0",
8764
- // "roe": null,
8765
- // "tradeFee": "0.0006154045",
8766
- // "fundingFee": "0.0",
8767
- // "openTime": 1713785751181,
8768
- // "closeTime": 1713785752784,
8769
- // "openPrice": null,
8770
- // "closePrice": null
8771
- // }
8772
- // ]
8773
- // }
8774
- // }
8775
- //
8776
10251
  const data = this.safeDict(response, 'data');
8777
10252
  const items = this.safeList(data, 'items', []);
8778
10253
  return this.parsePositions(items, symbols);
@@ -8847,61 +10322,107 @@ class kucoin extends kucoin$1["default"] {
8847
10322
  // "closePrice": null
8848
10323
  // }
8849
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
+ //
8850
10362
  const symbol = this.safeString(position, 'symbol');
8851
10363
  market = this.safeMarket(symbol, market);
8852
- const timestamp = this.safeInteger(position, 'currentTimestamp');
8853
- const size = this.safeString(position, 'currentQty');
8854
- let side = undefined;
8855
- const type = this.safeStringLower(position, 'type');
8856
- if (size !== undefined) {
8857
- if (Precise["default"].stringGt(size, '0')) {
8858
- side = 'long';
8859
- }
8860
- else if (Precise["default"].stringLt(size, '0')) {
8861
- side = 'short';
8862
- }
10364
+ let timestamp = this.safeInteger(position, 'currentTimestamp');
10365
+ if (timestamp === undefined) {
10366
+ timestamp = this.safeIntegerProduct(position, 'creationTime', 0.000001);
8863
10367
  }
8864
- else if (type !== undefined) {
8865
- if (type.indexOf('long') > -1) {
8866
- 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
+ }
8867
10379
  }
8868
- else {
8869
- side = 'short';
10380
+ else if (type !== undefined) {
10381
+ if (type.indexOf('long') > -1) {
10382
+ side = 'long';
10383
+ }
10384
+ else {
10385
+ side = 'short';
10386
+ }
8870
10387
  }
8871
10388
  }
8872
- const notional = Precise["default"].stringAbs(this.safeString(position, 'posCost'));
8873
- 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');
8874
10391
  const initialMarginPercentage = Precise["default"].stringDiv(initialMargin, notional);
8875
10392
  // const marginRatio = Precise.stringDiv (maintenanceRate, collateral);
8876
- const unrealisedPnl = this.safeString(position, 'unrealisedPnl');
10393
+ const unrealisedPnl = this.safeString2(position, 'unrealisedPnl', 'unrealizedPnL');
8877
10394
  const crossMode = this.safeValue(position, 'crossMode');
8878
10395
  // currently crossMode is always set to false and only isolated positions are supported
8879
- let marginMode = undefined;
10396
+ let marginMode = this.safeStringLower(position, 'marginMode');
8880
10397
  if (crossMode !== undefined) {
8881
10398
  marginMode = crossMode ? 'cross' : 'isolated';
8882
10399
  }
10400
+ let lastUpdateTimestamp = this.safeInteger(position, 'closeTime');
10401
+ if (lastUpdateTimestamp === undefined) {
10402
+ lastUpdateTimestamp = this.safeIntegerProduct(position, 'closingTime', 0.000001);
10403
+ }
8883
10404
  return this.safePosition({
8884
10405
  'info': position,
8885
- 'id': this.safeString2(position, 'id', 'positionId'),
10406
+ 'id': this.safeStringN(position, ['id', 'positionId', 'closeId']),
8886
10407
  'symbol': this.safeString(market, 'symbol'),
8887
10408
  'timestamp': timestamp,
8888
10409
  'datetime': this.iso8601(timestamp),
8889
- 'lastUpdateTimestamp': this.safeInteger(position, 'closeTime'),
10410
+ 'lastUpdateTimestamp': lastUpdateTimestamp,
8890
10411
  'initialMargin': this.parseNumber(initialMargin),
8891
10412
  'initialMarginPercentage': this.parseNumber(initialMarginPercentage),
8892
- 'maintenanceMargin': this.safeNumber(position, 'posMaint'),
8893
- 'maintenanceMarginPercentage': this.safeNumber(position, 'maintMarginReq'),
8894
- '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']),
8895
10416
  'notional': this.parseNumber(notional),
8896
10417
  'leverage': this.safeNumber2(position, 'realLeverage', 'leverage'),
8897
10418
  'unrealizedPnl': this.parseNumber(unrealisedPnl),
8898
10419
  'contracts': this.parseNumber(Precise["default"].stringAbs(size)),
8899
10420
  'contractSize': this.safeValue(market, 'contractSize'),
8900
- 'realizedPnl': this.safeNumber2(position, 'realisedPnl', 'pnl'),
10421
+ 'realizedPnl': this.safeNumberN(position, ['realisedPnl', 'pnl', 'realizedPnL']),
8901
10422
  'marginRatio': undefined,
8902
10423
  'liquidationPrice': this.safeNumber(position, 'liquidationPrice'),
8903
10424
  'markPrice': this.safeNumber(position, 'markPrice'),
8904
- 'lastPrice': undefined,
10425
+ 'lastPrice': this.safeNumber(position, 'closePrice'),
8905
10426
  'collateral': this.safeNumber(position, 'maintMargin'),
8906
10427
  'marginMode': marginMode,
8907
10428
  'side': side,
@@ -8915,18 +10436,31 @@ class kucoin extends kucoin$1["default"] {
8915
10436
  * @name kucoin#cancelOrders
8916
10437
  * @description cancel multiple orders for contract markets
8917
10438
  * @see https://www.kucoin.com/docs-new/3470241e0
10439
+ * @see https://www.kucoin.com/docs-new/rest/ua/batch-cancel-order-by-id
8918
10440
  * @param {string[]} ids order ids
8919
10441
  * @param {string} symbol unified symbol of the market the order was made in
8920
10442
  * @param {object} [params] extra parameters specific to the exchange API endpoint
8921
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'
8922
10447
  * @returns {object} an list of [order structures]{@link https://docs.ccxt.com/?id=order-structure}
8923
10448
  */
8924
10449
  async cancelOrders(ids, symbol = undefined, params = {}) {
8925
- // contract markets only
8926
10450
  await this.loadMarkets();
10451
+ let uta = await this.isUTAEnabled();
10452
+ [uta, params] = this.handleOptionAndParams(params, 'cancelOrders', 'uta', uta);
8927
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
8928
10455
  if (symbol !== undefined) {
8929
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');
8930
10464
  }
8931
10465
  const ordersRequests = [];
8932
10466
  const clientOrderIds = this.safeList2(params, 'clientOrderIds', 'clientOids', []);
@@ -8943,33 +10477,59 @@ class kucoin extends kucoin$1["default"] {
8943
10477
  });
8944
10478
  }
8945
10479
  for (let i = 0; i < ids.length; i++) {
8946
- 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
+ }
8947
10490
  }
8948
- const requestKey = useClientorderId ? 'clientOidsList' : 'orderIdsList';
8949
10491
  const request = {};
8950
- request[requestKey] = ordersRequests;
8951
- const response = await this.futuresPrivateDeleteOrdersMultiCancel(this.extend(request, params));
8952
- //
8953
- // {
8954
- // "code": "200000",
8955
- // "data":
8956
- // [
8957
- // {
8958
- // "orderId": "80465574458560512",
8959
- // "clientOid": null,
8960
- // "code": "200",
8961
- // "msg": "success"
8962
- // },
8963
- // {
8964
- // "orderId": "80465575289094144",
8965
- // "clientOid": null,
8966
- // "code": "200",
8967
- // "msg": "success"
8968
- // }
8969
- // ]
8970
- // }
8971
- //
8972
- 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
+ }
8973
10533
  return this.parseOrders(orders, market);
8974
10534
  }
8975
10535
  /**
@@ -9434,6 +10994,139 @@ class kucoin extends kucoin$1["default"] {
9434
10994
  }
9435
10995
  return result;
9436
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
+ }
9437
11130
  sign(path, api = 'public', method = 'GET', params = {}, headers = undefined, body = undefined) {
9438
11131
  //
9439
11132
  // the v2 URL is https://openapi-v2.kucoin.com/api/v1/endpoint
@@ -9464,11 +11157,15 @@ class kucoin extends kucoin$1["default"] {
9464
11157
  let endpart = '';
9465
11158
  headers = (headers !== undefined) ? headers : {};
9466
11159
  let url = this.urls['api'][api];
11160
+ const tradeType = this.safeString(query, 'tradeType');
9467
11161
  if (!this.isEmpty(query)) {
9468
11162
  if (((method === 'GET') || (method === 'DELETE')) && (path !== 'orders/multi-cancel')) {
9469
11163
  endpoint += '?' + this.rawencode(query);
9470
11164
  }
9471
11165
  else {
11166
+ if (endpoint === '/api/ua/v1/classic/order/place') {
11167
+ endpoint += '?tradeType=' + tradeType;
11168
+ }
9472
11169
  body = this.json(query);
9473
11170
  endpart = body;
9474
11171
  headers['Content-Type'] = 'application/json';
@@ -9499,7 +11196,9 @@ class kucoin extends kucoin$1["default"] {
9499
11196
  const signature = this.hmac(this.encode(payload), this.encode(this.secret), sha256.sha256, 'base64');
9500
11197
  headers['KC-API-SIGN'] = signature;
9501
11198
  let partner = this.safeDict(this.options, 'partner', {});
9502
- 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);
9503
11202
  const partnerId = this.safeString(partner, 'id');
9504
11203
  const partnerSecret = this.safeString2(partner, 'secret', 'key');
9505
11204
  if ((partnerId !== undefined) && (partnerSecret !== undefined)) {