ccxt 4.5.5 → 4.5.6

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 (90) hide show
  1. package/README.md +4 -4
  2. package/dist/ccxt.browser.min.js +15 -15
  3. package/dist/cjs/ccxt.js +6 -6
  4. package/dist/cjs/src/abstract/toobit.js +11 -0
  5. package/dist/cjs/src/abstract/tradeogre.js +1 -1
  6. package/dist/cjs/src/backpack.js +1 -1
  7. package/dist/cjs/src/base/Exchange.js +129 -2
  8. package/dist/cjs/src/bigone.js +4 -4
  9. package/dist/cjs/src/binance.js +79 -20
  10. package/dist/cjs/src/bingx.js +5 -2
  11. package/dist/cjs/src/bitget.js +16 -9
  12. package/dist/cjs/src/bybit.js +186 -127
  13. package/dist/cjs/src/coinsph.js +4 -1
  14. package/dist/cjs/src/cryptocom.js +6 -3
  15. package/dist/cjs/src/gate.js +1 -1
  16. package/dist/cjs/src/gemini.js +2 -2
  17. package/dist/cjs/src/hyperliquid.js +3 -0
  18. package/dist/cjs/src/kraken.js +6 -2
  19. package/dist/cjs/src/kucoin.js +1 -2
  20. package/dist/cjs/src/luno.js +4 -1
  21. package/dist/cjs/src/mexc.js +4 -1
  22. package/dist/cjs/src/okcoin.js +4 -1
  23. package/dist/cjs/src/okx.js +34 -3
  24. package/dist/cjs/src/phemex.js +1 -1
  25. package/dist/cjs/src/pro/apex.js +1 -0
  26. package/dist/cjs/src/pro/backpack.js +1 -1
  27. package/dist/cjs/src/pro/binance.js +150 -19
  28. package/dist/cjs/src/pro/bitget.js +332 -76
  29. package/dist/cjs/src/pro/cex.js +1 -0
  30. package/dist/cjs/src/pro/independentreserve.js +1 -0
  31. package/dist/cjs/src/pro/mexc.js +23 -23
  32. package/dist/cjs/src/pro/okx.js +46 -10
  33. package/dist/cjs/src/pro/toobit.js +1163 -0
  34. package/dist/cjs/src/pro/tradeogre.js +1 -1
  35. package/dist/cjs/src/toobit.js +2999 -0
  36. package/dist/cjs/src/tradeogre.js +1 -1
  37. package/js/ccxt.d.ts +8 -8
  38. package/js/ccxt.js +6 -6
  39. package/js/src/abstract/myokx.d.ts +1 -0
  40. package/js/src/abstract/okx.d.ts +1 -0
  41. package/js/src/abstract/okxus.d.ts +1 -0
  42. package/js/src/abstract/toobit.d.ts +66 -0
  43. package/js/src/backpack.js +1 -1
  44. package/js/src/base/Exchange.d.ts +9 -0
  45. package/js/src/base/Exchange.js +129 -2
  46. package/js/src/bigone.js +4 -4
  47. package/js/src/binance.d.ts +9 -0
  48. package/js/src/binance.js +79 -20
  49. package/js/src/bingx.js +5 -2
  50. package/js/src/bitget.js +16 -9
  51. package/js/src/bybit.d.ts +8 -0
  52. package/js/src/bybit.js +186 -127
  53. package/js/src/coinsph.js +4 -1
  54. package/js/src/cryptocom.js +6 -3
  55. package/js/src/gate.js +1 -1
  56. package/js/src/gemini.js +2 -2
  57. package/js/src/hyperliquid.js +3 -0
  58. package/js/src/kraken.d.ts +1 -1
  59. package/js/src/kraken.js +6 -2
  60. package/js/src/kucoin.js +1 -2
  61. package/js/src/luno.js +4 -1
  62. package/js/src/mexc.js +4 -1
  63. package/js/src/okcoin.js +4 -1
  64. package/js/src/okx.js +34 -3
  65. package/js/src/phemex.js +1 -1
  66. package/js/src/pro/apex.js +1 -0
  67. package/js/src/pro/backpack.d.ts +1 -1
  68. package/js/src/pro/backpack.js +1 -1
  69. package/js/src/pro/binance.d.ts +24 -0
  70. package/js/src/pro/binance.js +150 -19
  71. package/js/src/pro/bitget.d.ts +6 -0
  72. package/js/src/pro/bitget.js +332 -76
  73. package/js/src/pro/cex.js +1 -0
  74. package/js/src/pro/independentreserve.js +1 -0
  75. package/js/src/pro/mexc.js +23 -23
  76. package/js/src/pro/okx.d.ts +7 -1
  77. package/js/src/pro/okx.js +46 -10
  78. package/js/src/pro/toobit.d.ts +174 -0
  79. package/js/src/pro/toobit.js +1162 -0
  80. package/js/src/toobit.d.ts +456 -0
  81. package/js/src/toobit.js +2992 -0
  82. package/package.json +1 -1
  83. package/dist/373.ccxt.browser.js +0 -7630
  84. package/dist/373.ccxt.browser.min.js +0 -1
  85. package/js/src/abstract/tradeogre.d.ts +0 -21
  86. package/js/src/pro/tradeogre.d.ts +0 -49
  87. package/js/src/pro/tradeogre.js +0 -278
  88. package/js/src/tradeogre.d.ts +0 -149
  89. package/js/src/tradeogre.js +0 -872
  90. /package/js/src/abstract/{tradeogre.js → toobit.js} +0 -0
@@ -508,7 +508,7 @@ export default class bitget extends bitgetRest {
508
508
  args['topic'] = 'kline';
509
509
  args['symbol'] = market['id'];
510
510
  args['interval'] = interval;
511
- params['uta'] = true;
511
+ params = this.extend(params, { 'uta': true });
512
512
  messageHash = 'kline:' + symbol;
513
513
  }
514
514
  else {
@@ -557,7 +557,7 @@ export default class bitget extends bitgetRest {
557
557
  args['topic'] = channel;
558
558
  args['symbol'] = market['id'];
559
559
  args['interval'] = interval;
560
- params['uta'] = true;
560
+ params = this.extend(params, { 'uta': true });
561
561
  params['interval'] = interval;
562
562
  messageHash = channel + symbol;
563
563
  }
@@ -755,7 +755,7 @@ export default class bitget extends bitgetRest {
755
755
  args['topic'] = channel;
756
756
  args['symbol'] = market['id'];
757
757
  args['interval'] = this.safeString(params, 'interval', '1m');
758
- params['uta'] = true;
758
+ params = this.extend(params, { 'uta': true });
759
759
  params = this.omit(params, 'interval');
760
760
  }
761
761
  else {
@@ -1004,7 +1004,7 @@ export default class bitget extends bitgetRest {
1004
1004
  messageHashes.push('trade:' + symbol);
1005
1005
  }
1006
1006
  if (uta) {
1007
- params['uta'] = true;
1007
+ params = this.extend(params, { 'uta': true });
1008
1008
  }
1009
1009
  const trades = await this.watchPublicMultiple(messageHashes, topics, params);
1010
1010
  if (this.newUpdates) {
@@ -1238,11 +1238,13 @@ export default class bitget extends bitgetRest {
1238
1238
  * @name bitget#watchPositions
1239
1239
  * @description watch all open positions
1240
1240
  * @see https://www.bitget.com/api-doc/contract/websocket/private/Positions-Channel
1241
+ * @see https://www.bitget.com/api-doc/uta/websocket/private/Positions-Channel
1241
1242
  * @param {string[]|undefined} symbols list of unified market symbols
1242
1243
  * @param {int} [since] the earliest time in ms to fetch positions for
1243
1244
  * @param {int} [limit] the maximum number of positions to retrieve
1244
1245
  * @param {object} params extra parameters specific to the exchange API endpoint
1245
1246
  * @param {string} [params.instType] one of 'USDT-FUTURES', 'USDC-FUTURES', 'COIN-FUTURES', 'SUSDT-FUTURES', 'SUSDC-FUTURES' or 'SCOIN-FUTURES', default is 'USDT-FUTURES'
1247
+ * @param {boolean} [params.uta] set to true for the unified trading account (uta), defaults to false
1246
1248
  * @returns {object[]} a list of [position structure]{@link https://docs.ccxt.com/en/latest/manual.html#position-structure}
1247
1249
  */
1248
1250
  async watchPositions(symbols = undefined, since = undefined, limit = undefined, params = {}) {
@@ -1251,17 +1253,29 @@ export default class bitget extends bitgetRest {
1251
1253
  let messageHash = '';
1252
1254
  const subscriptionHash = 'positions';
1253
1255
  let instType = 'USDT-FUTURES';
1256
+ let uta = undefined;
1257
+ [uta, params] = this.handleOptionAndParams(params, 'watchPositions', 'uta', false);
1254
1258
  symbols = this.marketSymbols(symbols);
1255
1259
  if (!this.isEmpty(symbols)) {
1256
1260
  market = this.getMarketFromSymbols(symbols);
1257
- [instType, params] = this.getInstType(market, false, params);
1261
+ [instType, params] = this.getInstType(market, uta, params);
1262
+ }
1263
+ if (uta) {
1264
+ instType = 'UTA';
1258
1265
  }
1259
1266
  messageHash = instType + ':positions' + messageHash;
1260
1267
  const args = {
1261
1268
  'instType': instType,
1262
- 'channel': 'positions',
1263
- 'instId': 'default',
1264
1269
  };
1270
+ const topicOrChannel = uta ? 'topic' : 'channel';
1271
+ const channel = uta ? 'position' : 'positions';
1272
+ args[topicOrChannel] = channel;
1273
+ if (!uta) {
1274
+ args['instId'] = 'default';
1275
+ }
1276
+ else {
1277
+ params = this.extend(params, { 'uta': true });
1278
+ }
1265
1279
  const newPositions = await this.watchPrivate(messageHash, subscriptionHash, args, params);
1266
1280
  if (this.newUpdates) {
1267
1281
  return newPositions;
@@ -1306,7 +1320,46 @@ export default class bitget extends bitgetRest {
1306
1320
  // "ts": 1701913043767
1307
1321
  // }
1308
1322
  //
1309
- const arg = this.safeValue(message, 'arg', {});
1323
+ // uta
1324
+ //
1325
+ // {
1326
+ // "data": [
1327
+ // {
1328
+ // "symbol": "BTCUSDT",
1329
+ // "leverage": "20",
1330
+ // "openFeeTotal": "",
1331
+ // "mmr": "",
1332
+ // "breakEvenPrice": "",
1333
+ // "available": "0",
1334
+ // "liqPrice": "",
1335
+ // "marginMode": "crossed",
1336
+ // "unrealisedPnl": "0",
1337
+ // "markPrice": "94987.1",
1338
+ // "createdTime": "1736378720620",
1339
+ // "avgPrice": "0",
1340
+ // "totalFundingFee": "0",
1341
+ // "updatedTime": "1736378720620",
1342
+ // "marginCoin": "USDT",
1343
+ // "frozen": "0",
1344
+ // "profitRate": "",
1345
+ // "closeFeeTotal": "",
1346
+ // "marginSize": "0",
1347
+ // "curRealisedPnl": "0",
1348
+ // "size": "0",
1349
+ // "positionStatus": "ended",
1350
+ // "posSide": "long",
1351
+ // "holdMode": "hedge_mode"
1352
+ // }
1353
+ // ],
1354
+ // "arg": {
1355
+ // "instType": "UTA",
1356
+ // "topic": "position"
1357
+ // },
1358
+ // "action": "snapshot",
1359
+ // "ts": 1730711666652
1360
+ // }
1361
+ //
1362
+ const arg = this.safeDict(message, 'arg', {});
1310
1363
  const instType = this.safeString(arg, 'instType', '');
1311
1364
  if (this.positions === undefined) {
1312
1365
  this.positions = {};
@@ -1316,11 +1369,11 @@ export default class bitget extends bitgetRest {
1316
1369
  this.positions[instType] = new ArrayCacheBySymbolBySide();
1317
1370
  }
1318
1371
  const cache = this.positions[instType];
1319
- const rawPositions = this.safeValue(message, 'data', []);
1372
+ const rawPositions = this.safeList(message, 'data', []);
1320
1373
  const newPositions = [];
1321
1374
  for (let i = 0; i < rawPositions.length; i++) {
1322
1375
  const rawPosition = rawPositions[i];
1323
- const marketId = this.safeString(rawPosition, 'instId');
1376
+ const marketId = this.safeString2(rawPosition, 'instId', 'symbol');
1324
1377
  const market = this.safeMarket(marketId, undefined, undefined, 'contract');
1325
1378
  const position = this.parseWsPosition(rawPosition, market);
1326
1379
  newPositions.push(position);
@@ -1365,16 +1418,45 @@ export default class bitget extends bitgetRest {
1365
1418
  // "autoMargin": "off"
1366
1419
  // }
1367
1420
  //
1368
- const marketId = this.safeString(position, 'instId');
1421
+ // uta
1422
+ //
1423
+ // {
1424
+ // "symbol": "BTCUSDT",
1425
+ // "leverage": "20",
1426
+ // "openFeeTotal": "",
1427
+ // "mmr": "",
1428
+ // "breakEvenPrice": "",
1429
+ // "available": "0",
1430
+ // "liqPrice": "",
1431
+ // "marginMode": "crossed",
1432
+ // "unrealisedPnl": "0",
1433
+ // "markPrice": "94987.1",
1434
+ // "createdTime": "1736378720620",
1435
+ // "avgPrice": "0",
1436
+ // "totalFundingFee": "0",
1437
+ // "updatedTime": "1736378720620",
1438
+ // "marginCoin": "USDT",
1439
+ // "frozen": "0",
1440
+ // "profitRate": "",
1441
+ // "closeFeeTotal": "",
1442
+ // "marginSize": "0",
1443
+ // "curRealisedPnl": "0",
1444
+ // "size": "0",
1445
+ // "positionStatus": "ended",
1446
+ // "posSide": "long",
1447
+ // "holdMode": "hedge_mode"
1448
+ // }
1449
+ //
1450
+ const marketId = this.safeString2(position, 'instId', 'symbol');
1369
1451
  const marginModeId = this.safeString(position, 'marginMode');
1370
1452
  const marginMode = this.getSupportedMapping(marginModeId, {
1371
1453
  'crossed': 'cross',
1372
1454
  'isolated': 'isolated',
1373
1455
  });
1374
- const hedgedId = this.safeString(position, 'posMode');
1456
+ const hedgedId = this.safeString2(position, 'posMode', 'holdMode');
1375
1457
  const hedged = (hedgedId === 'hedge_mode') ? true : false;
1376
- const timestamp = this.safeInteger2(position, 'uTime', 'cTime');
1377
- const percentageDecimal = this.safeString(position, 'unrealizedPLR');
1458
+ const timestamp = this.safeIntegerN(position, ['updatedTime', 'uTime', 'cTime', 'createdTime']);
1459
+ const percentageDecimal = this.safeString2(position, 'unrealizedPLR', 'profitRate');
1378
1460
  const percentage = Precise.stringMul(percentageDecimal, '100');
1379
1461
  let contractSize = undefined;
1380
1462
  if (market !== undefined) {
@@ -1386,21 +1468,21 @@ export default class bitget extends bitgetRest {
1386
1468
  'symbol': this.safeSymbol(marketId, market, undefined, 'contract'),
1387
1469
  'notional': undefined,
1388
1470
  'marginMode': marginMode,
1389
- 'liquidationPrice': this.safeNumber(position, 'liquidationPrice'),
1390
- 'entryPrice': this.safeNumber(position, 'openPriceAvg'),
1391
- 'unrealizedPnl': this.safeNumber(position, 'unrealizedPL'),
1471
+ 'liquidationPrice': this.safeNumber2(position, 'liquidationPrice', 'liqPrice'),
1472
+ 'entryPrice': this.safeNumber2(position, 'openPriceAvg', 'avgPrice'),
1473
+ 'unrealizedPnl': this.safeNumber2(position, 'unrealizedPL', 'unrealisedPnl'),
1392
1474
  'percentage': this.parseNumber(percentage),
1393
- 'contracts': this.safeNumber(position, 'total'),
1475
+ 'contracts': this.safeNumber2(position, 'total', 'size'),
1394
1476
  'contractSize': contractSize,
1395
- 'markPrice': undefined,
1396
- 'side': this.safeString(position, 'holdSide'),
1477
+ 'markPrice': this.safeNumber(position, 'markPrice'),
1478
+ 'side': this.safeString2(position, 'holdSide', 'posSide'),
1397
1479
  'hedged': hedged,
1398
1480
  'timestamp': timestamp,
1399
1481
  'datetime': this.iso8601(timestamp),
1400
1482
  'maintenanceMargin': undefined,
1401
- 'maintenanceMarginPercentage': this.safeNumber(position, 'keepMarginRate'),
1402
- 'collateral': undefined,
1403
- 'initialMargin': undefined,
1483
+ 'maintenanceMarginPercentage': this.safeNumber2(position, 'keepMarginRate', 'mmr'),
1484
+ 'collateral': this.safeNumber(position, 'available'),
1485
+ 'initialMargin': this.safeNumber(position, 'marginSize'),
1404
1486
  'initialMarginPercentage': undefined,
1405
1487
  'leverage': this.safeNumber(position, 'leverage'),
1406
1488
  'marginRatio': this.safeNumber(position, 'marginRate'),
@@ -1415,6 +1497,7 @@ export default class bitget extends bitgetRest {
1415
1497
  * @see https://www.bitget.com/api-doc/contract/websocket/private/Plan-Order-Channel
1416
1498
  * @see https://www.bitget.com/api-doc/margin/cross/websocket/private/Cross-Orders
1417
1499
  * @see https://www.bitget.com/api-doc/margin/isolated/websocket/private/Isolate-Orders
1500
+ * @see https://www.bitget.com/api-doc/uta/websocket/private/Order-Channel
1418
1501
  * @param {string} symbol unified market symbol of the market orders were made in
1419
1502
  * @param {int} [since] the earliest time in ms to fetch orders for
1420
1503
  * @param {int} [limit] the maximum number of order structures to retrieve
@@ -1423,6 +1506,7 @@ export default class bitget extends bitgetRest {
1423
1506
  * @param {string} [params.marginMode] 'isolated' or 'cross' for watching spot margin orders]
1424
1507
  * @param {string} [params.type] 'spot', 'swap'
1425
1508
  * @param {string} [params.subType] 'linear', 'inverse'
1509
+ * @param {boolean} [params.uta] set to true for the unified trading account (uta), defaults to false
1426
1510
  * @returns {object[]} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
1427
1511
  */
1428
1512
  async watchOrders(symbol = undefined, since = undefined, limit = undefined, params = {}) {
@@ -1439,6 +1523,8 @@ export default class bitget extends bitgetRest {
1439
1523
  marketId = market['id'];
1440
1524
  messageHash = messageHash + ':' + symbol;
1441
1525
  }
1526
+ let uta = undefined;
1527
+ [uta, params] = this.handleOptionAndParams(params, 'watchOrders', 'uta', false);
1442
1528
  const productType = this.safeString(params, 'productType');
1443
1529
  let type = undefined;
1444
1530
  [type, params] = this.handleMarketTypeAndParams('watchOrders', market, params);
@@ -1464,7 +1550,7 @@ export default class bitget extends bitgetRest {
1464
1550
  instType = 'SPOT';
1465
1551
  }
1466
1552
  else {
1467
- [instType, params] = this.getInstType(market, false, params);
1553
+ [instType, params] = this.getInstType(market, uta, params);
1468
1554
  }
1469
1555
  if (type === 'spot' && (symbol !== undefined)) {
1470
1556
  subscriptionHash = subscriptionHash + ':' + symbol;
@@ -1486,12 +1572,22 @@ export default class bitget extends bitgetRest {
1486
1572
  channel = 'orders-crossed';
1487
1573
  }
1488
1574
  }
1575
+ if (uta) {
1576
+ instType = 'UTA';
1577
+ channel = 'order';
1578
+ }
1489
1579
  subscriptionHash = subscriptionHash + ':' + instType;
1490
1580
  const args = {
1491
1581
  'instType': instType,
1492
- 'channel': channel,
1493
- 'instId': instId,
1494
1582
  };
1583
+ const topicOrChannel = uta ? 'topic' : 'channel';
1584
+ args[topicOrChannel] = channel;
1585
+ if (!uta) {
1586
+ args['instId'] = instId;
1587
+ }
1588
+ else {
1589
+ params = this.extend(params, { 'uta': true });
1590
+ }
1495
1591
  const orders = await this.watchPrivate(messageHash, subscriptionHash, args, params);
1496
1592
  if (this.newUpdates) {
1497
1593
  limit = orders.getLimit(symbol, limit);
@@ -1533,24 +1629,73 @@ export default class bitget extends bitgetRest {
1533
1629
  // "ts": 1701923982497
1534
1630
  // }
1535
1631
  //
1632
+ // uta
1633
+ //
1634
+ // {
1635
+ // "action": "snapshot",
1636
+ // "arg": {
1637
+ // "instType": "UTA",
1638
+ // "topic": "order"
1639
+ // },
1640
+ // "data": [
1641
+ // {
1642
+ // "category": "usdt-futures",
1643
+ // "symbol": "BTCUSDT",
1644
+ // "orderId": "xxx",
1645
+ // "clientOid": "xxx",
1646
+ // "price": "",
1647
+ // "qty": "0.001",
1648
+ // "amount": "1000",
1649
+ // "holdMode": "hedge_mode",
1650
+ // "holdSide": "long",
1651
+ // "tradeSide": "open",
1652
+ // "orderType": "market",
1653
+ // "timeInForce": "gtc",
1654
+ // "side": "buy",
1655
+ // "marginMode": "crossed",
1656
+ // "marginCoin": "USDT",
1657
+ // "reduceOnly": "no",
1658
+ // "cumExecQty": "0.001",
1659
+ // "cumExecValue": "83.1315",
1660
+ // "avgPrice": "83131.5",
1661
+ // "totalProfit": "0",
1662
+ // "orderStatus": "filled",
1663
+ // "cancelReason": "",
1664
+ // "leverage": "20",
1665
+ // "feeDetail": [
1666
+ // {
1667
+ // "feeCoin": "USDT",
1668
+ // "fee": "0.0332526"
1669
+ // }
1670
+ // ],
1671
+ // "createdTime": "1742367838101",
1672
+ // "updatedTime": "1742367838115",
1673
+ // "stpMode": "none"
1674
+ // }
1675
+ // ],
1676
+ // "ts": 1742367838124
1677
+ // }
1678
+ //
1536
1679
  const arg = this.safeDict(message, 'arg', {});
1537
- const channel = this.safeString(arg, 'channel');
1538
- const instType = this.safeString(arg, 'instType');
1680
+ const channel = this.safeString2(arg, 'channel', 'topic');
1681
+ const instType = this.safeStringLower(arg, 'instType');
1539
1682
  const argInstId = this.safeString(arg, 'instId');
1540
1683
  let marketType = undefined;
1541
- if (instType === 'SPOT') {
1684
+ if (instType === 'spot') {
1542
1685
  marketType = 'spot';
1543
1686
  }
1544
- else if (instType === 'MARGIN') {
1687
+ else if (instType === 'margin') {
1545
1688
  marketType = 'spot';
1546
1689
  }
1547
1690
  else {
1548
1691
  marketType = 'contract';
1549
1692
  }
1550
- const isLinearSwap = (instType === 'USDT-FUTURES');
1551
- const isInverseSwap = (instType === 'COIN-FUTURES');
1552
- const isUSDCFutures = (instType === 'USDC-FUTURES');
1553
- const data = this.safeValue(message, 'data', []);
1693
+ const data = this.safeList(message, 'data', []);
1694
+ const first = this.safeDict(data, 0, {});
1695
+ const category = this.safeStringLower(first, 'category', instType);
1696
+ const isLinearSwap = (category === 'usdt-futures');
1697
+ const isInverseSwap = (category === 'coin-futures');
1698
+ const isUSDCFutures = (category === 'usdc-futures');
1554
1699
  if (this.orders === undefined) {
1555
1700
  const limit = this.safeInteger(this.options, 'ordersLimit', 1000);
1556
1701
  this.orders = new ArrayCacheBySymbolById(limit);
@@ -1562,7 +1707,7 @@ export default class bitget extends bitgetRest {
1562
1707
  const marketSymbols = {};
1563
1708
  for (let i = 0; i < data.length; i++) {
1564
1709
  const order = data[i];
1565
- const marketId = this.safeString(order, 'instId', argInstId);
1710
+ const marketId = this.safeString2(order, 'instId', 'symbol', argInstId);
1566
1711
  const market = this.safeMarket(marketId, undefined, undefined, marketType);
1567
1712
  const parsed = this.parseWsOrder(order, market);
1568
1713
  stored.append(parsed);
@@ -1710,13 +1855,57 @@ export default class bitget extends bitgetRest {
1710
1855
  // orderId: "1183419084588060673",
1711
1856
  // }
1712
1857
  //
1713
- const isSpot = !('posMode' in order);
1714
- const isMargin = ('loanType' in order);
1715
- const marketId = this.safeString(order, 'instId');
1858
+ // uta
1859
+ //
1860
+ // {
1861
+ // "category": "usdt-futures",
1862
+ // "symbol": "BTCUSDT",
1863
+ // "orderId": "xxx",
1864
+ // "clientOid": "xxx",
1865
+ // "price": "",
1866
+ // "qty": "0.001",
1867
+ // "amount": "1000",
1868
+ // "holdMode": "hedge_mode",
1869
+ // "holdSide": "long",
1870
+ // "tradeSide": "open",
1871
+ // "orderType": "market",
1872
+ // "timeInForce": "gtc",
1873
+ // "side": "buy",
1874
+ // "marginMode": "crossed",
1875
+ // "marginCoin": "USDT",
1876
+ // "reduceOnly": "no",
1877
+ // "cumExecQty": "0.001",
1878
+ // "cumExecValue": "83.1315",
1879
+ // "avgPrice": "83131.5",
1880
+ // "totalProfit": "0",
1881
+ // "orderStatus": "filled",
1882
+ // "cancelReason": "",
1883
+ // "leverage": "20",
1884
+ // "feeDetail": [
1885
+ // {
1886
+ // "feeCoin": "USDT",
1887
+ // "fee": "0.0332526"
1888
+ // }
1889
+ // ],
1890
+ // "createdTime": "1742367838101",
1891
+ // "updatedTime": "1742367838115",
1892
+ // "stpMode": "none"
1893
+ // }
1894
+ //
1895
+ let isSpot = !('posMode' in order);
1896
+ let isMargin = ('loanType' in order);
1897
+ const category = this.safeStringLower(order, 'category');
1898
+ if (category === 'spot') {
1899
+ isSpot = true;
1900
+ }
1901
+ if (category === 'margin') {
1902
+ isMargin = true;
1903
+ }
1904
+ const marketId = this.safeString2(order, 'instId', 'symbol');
1716
1905
  market = this.safeMarket(marketId, market);
1717
- const timestamp = this.safeInteger(order, 'cTime');
1906
+ const timestamp = this.safeInteger2(order, 'cTime', 'createdTime');
1718
1907
  const symbol = market['symbol'];
1719
- const rawStatus = this.safeString(order, 'status');
1908
+ const rawStatus = this.safeString2(order, 'status', 'orderStatus');
1720
1909
  const orderFee = this.safeValue(order, 'feeDetail', []);
1721
1910
  const fee = this.safeValue(orderFee, 0);
1722
1911
  const feeAmount = this.safeString(fee, 'fee');
@@ -1738,23 +1927,23 @@ export default class bitget extends bitgetRest {
1738
1927
  // for spot trigger order, limit price is this
1739
1928
  price = this.safeNumber(order, 'executePrice');
1740
1929
  }
1741
- const avgPrice = this.omitZero(this.safeString2(order, 'priceAvg', 'fillPrice'));
1930
+ const avgPrice = this.omitZero(this.safeStringLowerN(order, ['priceAvg', 'fillPrice', 'avgPrice']));
1742
1931
  const side = this.safeString(order, 'side');
1743
1932
  const type = this.safeString(order, 'orderType');
1744
- const accBaseVolume = this.omitZero(this.safeString(order, 'accBaseVolume'));
1745
- const newSizeValue = this.omitZero(this.safeString(order, 'newSize'));
1933
+ const accBaseVolume = this.omitZero(this.safeString2(order, 'accBaseVolume', 'cumExecQty'));
1934
+ const newSizeValue = this.omitZero(this.safeString2(order, 'newSize', 'cumExecValue'));
1746
1935
  const isMarketOrder = (type === 'market');
1747
1936
  const isBuy = (side === 'buy');
1748
1937
  let totalAmount = undefined;
1749
1938
  let filledAmount = undefined;
1750
1939
  let cost = undefined;
1751
1940
  let remaining = undefined;
1752
- let totalFilled = this.safeString(order, 'accBaseVolume');
1941
+ let totalFilled = this.safeString2(order, 'accBaseVolume', 'cumExecQty');
1753
1942
  if (isSpot) {
1754
1943
  if (isMargin) {
1755
- totalAmount = this.safeString(order, 'baseSize');
1756
- totalFilled = this.safeString(order, 'baseVolume');
1757
- cost = this.safeString(order, 'fillTotalAmount');
1944
+ totalAmount = this.safeString2(order, 'baseSize', 'qty');
1945
+ totalFilled = this.safeString2(order, 'baseVolume', 'cumExecQty');
1946
+ cost = this.safeString2(order, 'fillTotalAmount', 'cumExecValue');
1758
1947
  }
1759
1948
  else {
1760
1949
  const partialFillAmount = this.safeString(order, 'baseVolume');
@@ -1775,16 +1964,16 @@ export default class bitget extends bitgetRest {
1775
1964
  }
1776
1965
  }
1777
1966
  else {
1778
- totalAmount = this.safeString(order, 'newSize');
1967
+ totalAmount = this.safeString2(order, 'newSize', 'qty');
1779
1968
  // we don't have cost for limit order
1780
1969
  }
1781
1970
  }
1782
1971
  }
1783
1972
  else {
1784
1973
  // baseVolume should not be used for "amount" for contracts !
1785
- filledAmount = this.safeString(order, 'baseVolume');
1786
- totalAmount = this.safeString(order, 'size');
1787
- cost = this.safeString(order, 'fillNotionalUsd');
1974
+ filledAmount = this.safeString2(order, 'baseVolume', 'cumExecQty');
1975
+ totalAmount = this.safeString2(order, 'size', 'qty');
1976
+ cost = this.safeString2(order, 'fillNotionalUsd', 'cumExecValue');
1788
1977
  }
1789
1978
  remaining = Precise.stringSub(totalAmount, totalFilled);
1790
1979
  return this.safeOrder({
@@ -1794,9 +1983,9 @@ export default class bitget extends bitgetRest {
1794
1983
  'clientOrderId': this.safeString(order, 'clientOid'),
1795
1984
  'timestamp': timestamp,
1796
1985
  'datetime': this.iso8601(timestamp),
1797
- 'lastTradeTimestamp': this.safeInteger(order, 'uTime'),
1986
+ 'lastTradeTimestamp': this.safeInteger2(order, 'uTime', 'updatedTime'),
1798
1987
  'type': type,
1799
- 'timeInForce': this.safeStringUpper(order, 'force'),
1988
+ 'timeInForce': this.safeStringUpper2(order, 'force', 'timeInForce'),
1800
1989
  'postOnly': undefined,
1801
1990
  'side': side,
1802
1991
  'price': price,
@@ -1867,7 +2056,7 @@ export default class bitget extends bitgetRest {
1867
2056
  args['instId'] = 'default';
1868
2057
  }
1869
2058
  else {
1870
- params['uta'] = true;
2059
+ params = this.extend(params, { 'uta': true });
1871
2060
  }
1872
2061
  const trades = await this.watchPrivate(messageHash, subscriptionHash, args, params);
1873
2062
  if (this.newUpdates) {
@@ -2011,13 +2200,17 @@ export default class bitget extends bitgetRest {
2011
2200
  * @see https://www.bitget.com/api-doc/contract/websocket/private/Account-Channel
2012
2201
  * @see https://www.bitget.com/api-doc/margin/cross/websocket/private/Margin-Cross-Account-Assets
2013
2202
  * @see https://www.bitget.com/api-doc/margin/isolated/websocket/private/Margin-isolated-account-assets
2203
+ * @see https://www.bitget.com/api-doc/uta/websocket/private/Account-Channel
2014
2204
  * @param {object} [params] extra parameters specific to the exchange API endpoint
2015
2205
  * @param {str} [params.type] spot or contract if not provided this.options['defaultType'] is used
2016
2206
  * @param {string} [params.instType] one of 'SPOT', 'MARGIN', 'USDT-FUTURES', 'USDC-FUTURES', 'COIN-FUTURES', 'SUSDT-FUTURES', 'SUSDC-FUTURES' or 'SCOIN-FUTURES'
2017
2207
  * @param {string} [params.marginMode] 'isolated' or 'cross' for watching spot margin balances
2208
+ * @param {boolean} [params.uta] set to true for the unified trading account (uta), defaults to false
2018
2209
  * @returns {object} a [balance structure]{@link https://docs.ccxt.com/#/?id=balance-structure}
2019
2210
  */
2020
2211
  async watchBalance(params = {}) {
2212
+ let uta = undefined;
2213
+ [uta, params] = this.handleOptionAndParams(params, 'watchBalance', 'uta', false);
2021
2214
  let type = undefined;
2022
2215
  [type, params] = this.handleMarketTypeAndParams('watchBalance', undefined, params);
2023
2216
  let marginMode = undefined;
@@ -2029,22 +2222,33 @@ export default class bitget extends bitgetRest {
2029
2222
  }
2030
2223
  else if (marginMode !== undefined) {
2031
2224
  instType = 'MARGIN';
2032
- if (marginMode === 'isolated') {
2033
- channel = 'account-isolated';
2034
- }
2035
- else {
2036
- channel = 'account-crossed';
2225
+ if (!uta) {
2226
+ if (marginMode === 'isolated') {
2227
+ channel = 'account-isolated';
2228
+ }
2229
+ else {
2230
+ channel = 'account-crossed';
2231
+ }
2037
2232
  }
2038
2233
  }
2039
- else {
2234
+ else if (!uta) {
2040
2235
  instType = 'SPOT';
2041
2236
  }
2042
2237
  [instType, params] = this.handleOptionAndParams(params, 'watchBalance', 'instType', instType);
2238
+ if (uta) {
2239
+ instType = 'UTA';
2240
+ }
2043
2241
  const args = {
2044
2242
  'instType': instType,
2045
- 'channel': channel,
2046
- 'coin': 'default',
2047
2243
  };
2244
+ const topicOrChannel = uta ? 'topic' : 'channel';
2245
+ args[topicOrChannel] = channel;
2246
+ if (!uta) {
2247
+ args['coin'] = 'default';
2248
+ }
2249
+ else {
2250
+ params = this.extend(params, { 'uta': true });
2251
+ }
2048
2252
  const messageHash = 'balance:' + instType.toLowerCase();
2049
2253
  return await this.watchPrivate(messageHash, messageHash, args, params);
2050
2254
  }
@@ -2107,26 +2311,76 @@ export default class bitget extends bitgetRest {
2107
2311
  // "ts": 1701933110544
2108
2312
  // }
2109
2313
  //
2314
+ // uta
2315
+ //
2316
+ // {
2317
+ // "data": [{
2318
+ // "unrealisedPnL": "-10116.55",
2319
+ // "totalEquity": "4976919.05",
2320
+ // "positionMgnRatio": "0",
2321
+ // "mmr": "408.08",
2322
+ // "effEquity": "4847952.35",
2323
+ // "imr": "17795.97",
2324
+ // "mgnRatio": "0",
2325
+ // "coin": [{
2326
+ // "debts": "0",
2327
+ // "balance": "0.9992",
2328
+ // "available": "0.9992",
2329
+ // "borrow": "0",
2330
+ // "locked": "0",
2331
+ // "equity": "0.9992",
2332
+ // "coin": "ETH",
2333
+ // "usdValue": "2488.667472"
2334
+ // }]
2335
+ // }],
2336
+ // "arg": {
2337
+ // "instType": "UTA",
2338
+ // "topic": "account"
2339
+ // },
2340
+ // "action": "snapshot",
2341
+ // "ts": 1740546523244
2342
+ // }
2343
+ //
2344
+ const arg = this.safeDict(message, 'arg', {});
2345
+ const instType = this.safeStringLower(arg, 'instType');
2110
2346
  const data = this.safeValue(message, 'data', []);
2111
2347
  for (let i = 0; i < data.length; i++) {
2112
2348
  const rawBalance = data[i];
2113
- const currencyId = this.safeString2(rawBalance, 'coin', 'marginCoin');
2114
- const code = this.safeCurrencyCode(currencyId);
2115
- const account = (code in this.balance) ? this.balance[code] : this.account();
2116
- const borrow = this.safeString(rawBalance, 'borrow');
2117
- if (borrow !== undefined) {
2118
- const interest = this.safeString(rawBalance, 'interest');
2119
- account['debt'] = Precise.stringAdd(borrow, interest);
2349
+ if (instType === 'uta') {
2350
+ const coins = this.safeList(rawBalance, 'coin', []);
2351
+ for (let j = 0; j < coins.length; j++) {
2352
+ const entry = coins[j];
2353
+ const currencyId = this.safeString(entry, 'coin');
2354
+ const code = this.safeCurrencyCode(currencyId);
2355
+ const account = (code in this.balance) ? this.balance[code] : this.account();
2356
+ const borrow = this.safeString(entry, 'borrow');
2357
+ const debts = this.safeString(entry, 'debts');
2358
+ if ((borrow !== undefined) || (debts !== undefined)) {
2359
+ account['debt'] = Precise.stringAdd(borrow, debts);
2360
+ }
2361
+ account['free'] = this.safeString(entry, 'available');
2362
+ account['used'] = this.safeString(entry, 'locked');
2363
+ account['total'] = this.safeString(entry, 'balance');
2364
+ this.balance[code] = account;
2365
+ }
2366
+ }
2367
+ else {
2368
+ const currencyId = this.safeString2(rawBalance, 'coin', 'marginCoin');
2369
+ const code = this.safeCurrencyCode(currencyId);
2370
+ const account = (code in this.balance) ? this.balance[code] : this.account();
2371
+ const borrow = this.safeString(rawBalance, 'borrow');
2372
+ if (borrow !== undefined) {
2373
+ const interest = this.safeString(rawBalance, 'interest');
2374
+ account['debt'] = Precise.stringAdd(borrow, interest);
2375
+ }
2376
+ const freeQuery = ('maxTransferOut' in rawBalance) ? 'maxTransferOut' : 'available';
2377
+ account['free'] = this.safeString(rawBalance, freeQuery);
2378
+ account['total'] = this.safeString(rawBalance, 'equity');
2379
+ account['used'] = this.safeString(rawBalance, 'frozen');
2380
+ this.balance[code] = account;
2120
2381
  }
2121
- const freeQuery = ('maxTransferOut' in rawBalance) ? 'maxTransferOut' : 'available';
2122
- account['free'] = this.safeString(rawBalance, freeQuery);
2123
- account['total'] = this.safeString(rawBalance, 'equity');
2124
- account['used'] = this.safeString(rawBalance, 'frozen');
2125
- this.balance[code] = account;
2126
2382
  }
2127
2383
  this.balance = this.safeBalance(this.balance);
2128
- const arg = this.safeValue(message, 'arg');
2129
- const instType = this.safeStringLower(arg, 'instType');
2130
2384
  const messageHash = 'balance:' + instType;
2131
2385
  client.resolve(this.balance, messageHash);
2132
2386
  }
@@ -2426,12 +2680,14 @@ export default class bitget extends bitgetRest {
2426
2680
  'trade': this.handleTrades,
2427
2681
  'publicTrade': this.handleTrades,
2428
2682
  'fill': this.handleMyTrades,
2683
+ 'order': this.handleOrder,
2429
2684
  'orders': this.handleOrder,
2430
2685
  'ordersAlgo': this.handleOrder,
2431
2686
  'orders-algo': this.handleOrder,
2432
2687
  'orders-crossed': this.handleOrder,
2433
2688
  'orders-isolated': this.handleOrder,
2434
2689
  'account': this.handleBalance,
2690
+ 'position': this.handlePositions,
2435
2691
  'positions': this.handlePositions,
2436
2692
  'account-isolated': this.handleBalance,
2437
2693
  'account-crossed': this.handleBalance,