ccxt 4.1.14 → 4.1.17

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 (97) hide show
  1. package/README.md +3 -3
  2. package/dist/ccxt.browser.js +381 -169
  3. package/dist/ccxt.browser.min.js +9 -9
  4. package/dist/cjs/ccxt.js +1 -1
  5. package/dist/cjs/src/ascendex.js +1 -1
  6. package/dist/cjs/src/base/Exchange.js +3 -0
  7. package/dist/cjs/src/bingx.js +9 -4
  8. package/dist/cjs/src/bitget.js +274 -132
  9. package/dist/cjs/src/bitmex.js +6 -3
  10. package/dist/cjs/src/bittrex.js +1 -0
  11. package/dist/cjs/src/btcalpha.js +2 -1
  12. package/dist/cjs/src/btcturk.js +3 -0
  13. package/dist/cjs/src/bybit.js +9 -2
  14. package/dist/cjs/src/coinone.js +13 -4
  15. package/dist/cjs/src/digifinex.js +9 -8
  16. package/dist/cjs/src/gate.js +2 -2
  17. package/dist/cjs/src/huobi.js +8 -0
  18. package/dist/cjs/src/kraken.js +2 -1
  19. package/dist/cjs/src/kucoin.js +1 -0
  20. package/dist/cjs/src/kucoinfutures.js +1 -0
  21. package/dist/cjs/src/kuna.js +1 -0
  22. package/dist/cjs/src/lbank.js +1 -0
  23. package/dist/cjs/src/lbank2.js +2 -0
  24. package/dist/cjs/src/luno.js +1 -0
  25. package/dist/cjs/src/lykke.js +2 -1
  26. package/dist/cjs/src/mercado.js +1 -0
  27. package/dist/cjs/src/mexc.js +4 -1
  28. package/dist/cjs/src/ndax.js +1 -0
  29. package/dist/cjs/src/novadax.js +1 -0
  30. package/dist/cjs/src/oceanex.js +1 -0
  31. package/dist/cjs/src/okx.js +3 -3
  32. package/dist/cjs/src/phemex.js +2 -0
  33. package/dist/cjs/src/pro/hollaex.js +1 -1
  34. package/dist/cjs/src/pro/mexc.js +1 -1
  35. package/dist/cjs/src/probit.js +1 -0
  36. package/dist/cjs/src/tidex.js +1 -0
  37. package/dist/cjs/src/timex.js +1 -0
  38. package/dist/cjs/src/tokocrypto.js +1 -0
  39. package/dist/cjs/src/upbit.js +1 -0
  40. package/dist/cjs/src/wavesexchange.js +1 -0
  41. package/dist/cjs/src/wazirx.js +2 -1
  42. package/dist/cjs/src/whitebit.js +2 -1
  43. package/dist/cjs/src/woo.js +1 -1
  44. package/dist/cjs/src/yobit.js +1 -0
  45. package/dist/cjs/src/zaif.js +1 -0
  46. package/dist/cjs/src/zonda.js +1 -0
  47. package/js/ccxt.d.ts +1 -1
  48. package/js/ccxt.js +1 -1
  49. package/js/src/abstract/btcturk.d.ts +3 -0
  50. package/js/src/ascendex.js +1 -1
  51. package/js/src/base/Exchange.d.ts +1 -0
  52. package/js/src/base/Exchange.js +3 -0
  53. package/js/src/bingx.js +9 -4
  54. package/js/src/bitget.js +274 -132
  55. package/js/src/bitmex.js +6 -3
  56. package/js/src/bittrex.js +1 -0
  57. package/js/src/btcalpha.js +2 -1
  58. package/js/src/btcturk.js +3 -0
  59. package/js/src/bybit.js +9 -2
  60. package/js/src/coinone.js +13 -4
  61. package/js/src/digifinex.d.ts +3 -28
  62. package/js/src/digifinex.js +9 -8
  63. package/js/src/gate.js +2 -2
  64. package/js/src/huobi.js +8 -0
  65. package/js/src/kraken.js +2 -1
  66. package/js/src/kucoin.js +1 -0
  67. package/js/src/kucoinfutures.js +1 -0
  68. package/js/src/kuna.js +1 -0
  69. package/js/src/lbank.js +1 -0
  70. package/js/src/lbank2.js +2 -0
  71. package/js/src/luno.js +1 -0
  72. package/js/src/lykke.js +2 -1
  73. package/js/src/mercado.js +1 -0
  74. package/js/src/mexc.js +4 -1
  75. package/js/src/ndax.js +1 -0
  76. package/js/src/novadax.js +1 -0
  77. package/js/src/oceanex.js +1 -0
  78. package/js/src/okx.js +3 -3
  79. package/js/src/phemex.d.ts +2 -0
  80. package/js/src/phemex.js +2 -0
  81. package/js/src/pro/hollaex.js +1 -1
  82. package/js/src/pro/mexc.js +1 -1
  83. package/js/src/probit.js +1 -0
  84. package/js/src/tidex.js +1 -0
  85. package/js/src/timex.d.ts +1 -0
  86. package/js/src/timex.js +1 -0
  87. package/js/src/tokocrypto.js +1 -0
  88. package/js/src/upbit.js +1 -0
  89. package/js/src/wavesexchange.js +1 -0
  90. package/js/src/wazirx.js +2 -1
  91. package/js/src/whitebit.js +2 -1
  92. package/js/src/woo.js +1 -1
  93. package/js/src/yobit.js +1 -0
  94. package/js/src/zaif.js +1 -0
  95. package/js/src/zonda.js +1 -0
  96. package/package.json +1 -1
  97. package/skip-tests.json +108 -5
package/dist/cjs/ccxt.js CHANGED
@@ -180,7 +180,7 @@ var woo$1 = require('./src/pro/woo.js');
180
180
 
181
181
  //-----------------------------------------------------------------------------
182
182
  // this is updated by vss.js when building
183
- const version = '4.1.14';
183
+ const version = '4.1.17';
184
184
  Exchange["default"].ccxtVersion = version;
185
185
  const exchanges = {
186
186
  'ace': ace,
@@ -2743,7 +2743,7 @@ class ascendex extends ascendex$1 {
2743
2743
  * @param {object} [params] extra parameters specific to the ascendex api endpoint
2744
2744
  * @returns {object} a [margin structure]{@link https://github.com/ccxt/ccxt/wiki/Manual#reduce-margin-structure}
2745
2745
  */
2746
- return await this.modifyMarginHelper(symbol, amount, 'reduce', params);
2746
+ return await this.modifyMarginHelper(symbol, -amount, 'reduce', params);
2747
2747
  }
2748
2748
  async addMargin(symbol, amount, params = {}) {
2749
2749
  /**
@@ -1056,6 +1056,9 @@ class Exchange {
1056
1056
  convertToBigInt(value) {
1057
1057
  return BigInt(value); // used on XT
1058
1058
  }
1059
+ stringToCharsArray(value) {
1060
+ return value.split('');
1061
+ }
1059
1062
  valueIsDefined(value) {
1060
1063
  return value !== undefined && value !== null;
1061
1064
  }
@@ -880,14 +880,19 @@ class bingx extends bingx$1 {
880
880
  if (time === 0) {
881
881
  time = undefined;
882
882
  }
883
- const isBuyerMaker = this.safeValue2(trade, 'buyerMaker', 'isBuyerMaker');
884
- const side = this.safeStringLower2(trade, 'side', 'S');
885
883
  const cost = this.safeString(trade, 'quoteQty');
886
884
  const type = (cost === undefined) ? 'spot' : 'swap';
887
885
  const currencyId = this.safeString2(trade, 'currency', 'N');
888
886
  const currencyCode = this.safeCurrencyCode(currencyId);
889
887
  const m = this.safeValue(trade, 'm', false);
890
888
  const marketId = this.safeString(trade, 's');
889
+ const isBuyerMaker = this.safeValue2(trade, 'buyerMaker', 'isBuyerMaker');
890
+ let takeOrMaker = (isBuyerMaker || m) ? 'maker' : 'taker';
891
+ let side = this.safeStringLower2(trade, 'side', 'S');
892
+ if (side === undefined) {
893
+ side = (isBuyerMaker || m) ? 'sell' : 'buy';
894
+ takeOrMaker = 'taker';
895
+ }
891
896
  return this.safeTrade({
892
897
  'id': this.safeStringN(trade, ['id', 't']),
893
898
  'info': trade,
@@ -897,7 +902,7 @@ class bingx extends bingx$1 {
897
902
  'order': this.safeString2(trade, 'orderId', 'i'),
898
903
  'type': this.safeStringLower(trade, 'o'),
899
904
  'side': this.parseOrderSide(side),
900
- 'takerOrMaker': (isBuyerMaker || m) ? 'maker' : 'taker',
905
+ 'takerOrMaker': takeOrMaker,
901
906
  'price': this.safeString2(trade, 'price', 'p'),
902
907
  'amount': this.safeStringN(trade, ['qty', 'amount', 'q']),
903
908
  'cost': cost,
@@ -1553,7 +1558,7 @@ class bingx extends bingx$1 {
1553
1558
  'info': position,
1554
1559
  'id': this.safeString(position, 'positionId'),
1555
1560
  'symbol': this.safeSymbol(marketId, market, '-', 'swap'),
1556
- 'notional': this.safeString(position, 'positionAmt'),
1561
+ 'notional': this.safeNumber(position, 'positionAmt'),
1557
1562
  'marginMode': marginMode,
1558
1563
  'liquidationPrice': undefined,
1559
1564
  'entryPrice': this.safeNumber2(position, 'avgPrice', 'entryPrice'),
@@ -1740,7 +1740,7 @@ class bitget extends bitget$1 {
1740
1740
  'startTime': since,
1741
1741
  'endTime': this.milliseconds(),
1742
1742
  };
1743
- [request, params] = this.handleUntilOption('endTime', params, request);
1743
+ [request, params] = this.handleUntilOption('endTime', request, params);
1744
1744
  if (limit !== undefined) {
1745
1745
  request['pageSize'] = limit;
1746
1746
  }
@@ -2641,18 +2641,20 @@ class bitget extends bitget$1 {
2641
2641
  * @description query for balance and get the amount of funds available for trading or funds locked in orders
2642
2642
  * @see https://bitgetlimited.github.io/apidoc/en/spot/#get-account-assets
2643
2643
  * @see https://bitgetlimited.github.io/apidoc/en/mix/#get-account-list
2644
+ * @see https://bitgetlimited.github.io/apidoc/en/margin/#get-cross-assets
2645
+ * @see https://bitgetlimited.github.io/apidoc/en/margin/#get-isolated-assets
2644
2646
  * @param {object} [params] extra parameters specific to the bitget api endpoint
2645
2647
  * @returns {object} a [balance structure]{@link https://github.com/ccxt/ccxt/wiki/Manual#balance-structure}
2646
2648
  */
2647
2649
  const sandboxMode = this.safeValue(this.options, 'sandboxMode', false);
2648
2650
  await this.loadMarkets();
2649
- const [marketType, query] = this.handleMarketTypeAndParams('fetchBalance', undefined, params);
2650
- const method = this.getSupportedMapping(marketType, {
2651
- 'spot': 'privateSpotGetAccountAssets',
2652
- 'swap': 'privateMixGetAccountAccounts',
2653
- });
2654
2651
  const request = {};
2655
- if (marketType === 'swap') {
2652
+ let marketType = undefined;
2653
+ let marginMode = undefined;
2654
+ let response = undefined;
2655
+ [marketType, params] = this.handleMarketTypeAndParams('fetchBalance', undefined, params);
2656
+ [marginMode, params] = this.handleMarginModeAndParams('fetchBalance', params);
2657
+ if ((marketType === 'swap') || (marketType === 'future')) {
2656
2658
  let subType = undefined;
2657
2659
  [subType, params] = this.handleSubTypeAndParams('fetchBalance', undefined, params);
2658
2660
  let productType = (subType === 'linear') ? 'UMCBL' : 'DMCBL';
@@ -2660,45 +2662,106 @@ class bitget extends bitget$1 {
2660
2662
  productType = 'S' + productType;
2661
2663
  }
2662
2664
  request['productType'] = productType;
2665
+ response = await this.privateMixGetAccountAccounts(this.extend(request, params));
2666
+ }
2667
+ else if (marginMode === 'isolated') {
2668
+ response = await this.privateMarginGetIsolatedAccountAssets(this.extend(request, params));
2669
+ }
2670
+ else if (marginMode === 'cross') {
2671
+ response = await this.privateMarginGetCrossAccountAssets(this.extend(request, params));
2672
+ }
2673
+ else if (marketType === 'spot') {
2674
+ response = await this.privateSpotGetAccountAssets(this.extend(request, params));
2675
+ }
2676
+ else {
2677
+ throw new errors.NotSupported(this.id + ' fetchBalance() does not support ' + marketType + ' accounts');
2663
2678
  }
2664
- const response = await this[method](this.extend(request, query));
2665
2679
  // spot
2680
+ //
2666
2681
  // {
2667
- // code: '00000',
2668
- // msg: 'success',
2669
- // requestTime: 1645928868827,
2670
- // data: [
2671
- // {
2672
- // coinId: 1,
2673
- // coinName: 'BTC',
2674
- // available: '0.00070000',
2675
- // frozen: '0.00000000',
2676
- // lock: '0.00000000',
2677
- // uTime: '1645921706000'
2678
- // }
2679
- // ]
2682
+ // "code": "00000",
2683
+ // "msg": "success",
2684
+ // "requestTime": 1697507299139,
2685
+ // "data": [
2686
+ // {
2687
+ // "coinId": 1,
2688
+ // "coinName": "BTC",
2689
+ // "available": "0.00000000",
2690
+ // "frozen": "0.00000000",
2691
+ // "lock": "0.00000000",
2692
+ // "uTime": "1697248128000"
2693
+ // },
2694
+ // ]
2680
2695
  // }
2681
2696
  //
2682
2697
  // swap
2698
+ //
2683
2699
  // {
2684
- // code: '00000',
2685
- // msg: 'success',
2686
- // requestTime: 1645928929251,
2687
- // data: [
2688
- // {
2689
- // marginCoin: 'USDT',
2690
- // locked: '0',
2691
- // available: '8.078525',
2692
- // crossMaxAvailable: '8.078525',
2693
- // fixedMaxAvailable: '8.078525',
2694
- // maxTransferOut: '8.078525',
2695
- // equity: '10.02508',
2696
- // usdtEquity: '10.02508',
2697
- // btcEquity: '0.00026057027'
2698
- // }
2699
- // ]
2700
+ // "code": "00000",
2701
+ // "msg": "success",
2702
+ // "requestTime": 1697507505367,
2703
+ // "data": [
2704
+ // {
2705
+ // "marginCoin": "STETH",
2706
+ // "locked": "0",
2707
+ // "available": "0",
2708
+ // "crossMaxAvailable": "0",
2709
+ // "fixedMaxAvailable": "0",
2710
+ // "maxTransferOut": "0",
2711
+ // "equity": "0",
2712
+ // "usdtEquity": "0",
2713
+ // "btcEquity": "0",
2714
+ // "crossRiskRate": "0",
2715
+ // "unrealizedPL": "0",
2716
+ // "bonus": "0"
2717
+ // },
2718
+ // ]
2700
2719
  // }
2701
- const data = this.safeValue(response, 'data');
2720
+ //
2721
+ // isolated margin
2722
+ //
2723
+ // {
2724
+ // "code": "00000",
2725
+ // "msg": "success",
2726
+ // "requestTime": 1697501436571,
2727
+ // "data": [
2728
+ // {
2729
+ // "symbol": "BTCUSDT",
2730
+ // "coin": "BTC",
2731
+ // "totalAmount": "0.00021654",
2732
+ // "available": "0.00021654",
2733
+ // "transferable": "0.00021654",
2734
+ // "frozen": "0",
2735
+ // "borrow": "0",
2736
+ // "interest": "0",
2737
+ // "net": "0.00021654",
2738
+ // "ctime": "1697248128071"
2739
+ // },
2740
+ // ]
2741
+ // }
2742
+ //
2743
+ // cross margin
2744
+ //
2745
+ // {
2746
+ // "code": "00000",
2747
+ // "msg": "success",
2748
+ // "requestTime": 1697515463804,
2749
+ // "data": [
2750
+ // {
2751
+ // "coin": "BTC",
2752
+ // "totalAmount": "0.00024996",
2753
+ // "available": "0.00024996",
2754
+ // "transferable": "0.00004994",
2755
+ // "frozen": "0",
2756
+ // "borrow": "0.0001",
2757
+ // "interest": "0.00000001",
2758
+ // "net": "0.00014995",
2759
+ // "ctime": "1697251265504"
2760
+ // },
2761
+ // ]
2762
+ // }
2763
+ //
2764
+ const data = this.safeValue(response, 'data', []);
2702
2765
  return this.parseBalance(data);
2703
2766
  }
2704
2767
  parseBalance(balance) {
@@ -2707,42 +2770,81 @@ class bitget extends bitget$1 {
2707
2770
  // spot
2708
2771
  //
2709
2772
  // {
2710
- // coinId: '1',
2711
- // coinName: 'BTC',
2712
- // available: '0.00099900',
2713
- // frozen: '0.00000000',
2714
- // lock: '0.00000000',
2715
- // uTime: '1661595535000'
2773
+ // "coinId": 1,
2774
+ // "coinName": "BTC",
2775
+ // "available": "0.00000000",
2776
+ // "frozen": "0.00000000",
2777
+ // "lock": "0.00000000",
2778
+ // "uTime": "1697248128000"
2716
2779
  // }
2717
2780
  //
2718
2781
  // swap
2719
2782
  //
2720
2783
  // {
2721
- // marginCoin: 'BTC',
2722
- // locked: '0.00001948',
2723
- // available: '0.00006622',
2724
- // crossMaxAvailable: '0.00004674',
2725
- // fixedMaxAvailable: '0.00004674',
2726
- // maxTransferOut: '0.00004674',
2727
- // equity: '0.00006622',
2728
- // usdtEquity: '1.734307497491',
2729
- // btcEquity: '0.000066229058',
2730
- // crossRiskRate: '0.066308887072',
2731
- // unrealizedPL: '0',
2732
- // bonus: '0'
2784
+ // "marginCoin": "STETH",
2785
+ // "locked": "0",
2786
+ // "available": "0",
2787
+ // "crossMaxAvailable": "0",
2788
+ // "fixedMaxAvailable": "0",
2789
+ // "maxTransferOut": "0",
2790
+ // "equity": "0",
2791
+ // "usdtEquity": "0",
2792
+ // "btcEquity": "0",
2793
+ // "crossRiskRate": "0",
2794
+ // "unrealizedPL": "0",
2795
+ // "bonus": "0"
2796
+ // }
2797
+ //
2798
+ // isolated margin
2799
+ //
2800
+ // {
2801
+ // "symbol": "BTCUSDT",
2802
+ // "coin": "BTC",
2803
+ // "totalAmount": "0.00021654",
2804
+ // "available": "0.00021654",
2805
+ // "transferable": "0.00021654",
2806
+ // "frozen": "0",
2807
+ // "borrow": "0",
2808
+ // "interest": "0",
2809
+ // "net": "0.00021654",
2810
+ // "ctime": "1697248128071"
2811
+ // }
2812
+ //
2813
+ // cross margin
2814
+ //
2815
+ // {
2816
+ // "coin": "BTC",
2817
+ // "totalAmount": "0.00024995",
2818
+ // "available": "0.00024995",
2819
+ // "transferable": "0.00004993",
2820
+ // "frozen": "0",
2821
+ // "borrow": "0.0001",
2822
+ // "interest": "0.00000001",
2823
+ // "net": "0.00014994",
2824
+ // "ctime": "1697251265504"
2733
2825
  // }
2734
2826
  //
2735
2827
  for (let i = 0; i < balance.length; i++) {
2736
2828
  const entry = balance[i];
2737
- const currencyId = this.safeString2(entry, 'coinName', 'marginCoin');
2738
- const code = this.safeCurrencyCode(currencyId);
2739
2829
  const account = this.account();
2740
- const spotAccountFree = this.safeString(entry, 'available');
2741
- const contractAccountFree = this.safeString(entry, 'maxTransferOut');
2742
- account['free'] = (contractAccountFree !== undefined) ? contractAccountFree : spotAccountFree;
2743
- const frozen = this.safeString(entry, 'frozen');
2744
- const locked = this.safeString2(entry, 'lock', 'locked');
2745
- account['used'] = Precise["default"].stringAdd(frozen, locked);
2830
+ const currencyId = this.safeStringN(entry, ['coinName', 'marginCoin', 'coin']);
2831
+ const code = this.safeCurrencyCode(currencyId);
2832
+ const borrow = this.safeString(entry, 'borrow');
2833
+ if (borrow !== undefined) {
2834
+ const interest = this.safeString(entry, 'interest');
2835
+ account['free'] = this.safeString(entry, 'transferable');
2836
+ account['total'] = this.safeString(entry, 'totalAmount');
2837
+ account['debt'] = Precise["default"].stringAdd(borrow, interest);
2838
+ }
2839
+ else {
2840
+ // Use transferable instead of available for swap and margin https://github.com/ccxt/ccxt/pull/19127
2841
+ const spotAccountFree = this.safeString(entry, 'available');
2842
+ const contractAccountFree = this.safeString(entry, 'maxTransferOut');
2843
+ account['free'] = (contractAccountFree !== undefined) ? contractAccountFree : spotAccountFree;
2844
+ const frozen = this.safeString(entry, 'frozen');
2845
+ const locked = this.safeString2(entry, 'lock', 'locked');
2846
+ account['used'] = Precise["default"].stringAdd(frozen, locked);
2847
+ }
2746
2848
  result[code] = account;
2747
2849
  }
2748
2850
  return this.safeBalance(result);
@@ -2905,6 +3007,8 @@ class bitget extends bitget$1 {
2905
3007
  * @see https://bitgetlimited.github.io/apidoc/en/mix/#place-stop-order
2906
3008
  * @see https://bitgetlimited.github.io/apidoc/en/mix/#place-position-tpsl
2907
3009
  * @see https://bitgetlimited.github.io/apidoc/en/mix/#place-plan-order
3010
+ * @see https://bitgetlimited.github.io/apidoc/en/margin/#isolated-place-order
3011
+ * @see https://bitgetlimited.github.io/apidoc/en/margin/#cross-place-order
2908
3012
  * @param {string} symbol unified symbol of the market to create an order in
2909
3013
  * @param {string} type 'market' or 'limit'
2910
3014
  * @param {string} side 'buy' or 'sell' or 'open_long' or 'open_short' or 'close_long' or 'close_short'
@@ -2919,13 +3023,23 @@ class bitget extends bitget$1 {
2919
3023
  * @param {object} [params.stopLoss] *stopLoss object in params* containing the triggerPrice at which the attached stop loss order will be triggered (perpetual swap markets only)
2920
3024
  * @param {float} [params.stopLoss.triggerPrice] *swap only* stop loss trigger price
2921
3025
  * @param {string} [params.timeInForce] "GTC", "IOC", "FOK", or "PO"
3026
+ * @param {string} [params.marginMode] 'isolated' or 'cross' for spot margin trading
3027
+ * @param {string} [params.loanType] *spot margin only* 'normal', 'autoLoan', 'autoRepay', or 'autoLoanAndRepay' default is 'normal'
2922
3028
  * @returns {object} an [order structure]{@link https://github.com/ccxt/ccxt/wiki/Manual#order-structure}
2923
3029
  */
2924
3030
  await this.loadMarkets();
2925
3031
  const market = this.market(symbol);
2926
- const [marketType, query] = this.handleMarketTypeAndParams('createOrder', market, params);
3032
+ let marketType = undefined;
3033
+ let marginMode = undefined;
3034
+ let response = undefined;
3035
+ [marketType, params] = this.handleMarketTypeAndParams('createOrder', market, params);
3036
+ [marginMode, params] = this.handleMarginModeAndParams('createOrder', params);
3037
+ const marketId = market['id'];
3038
+ const parts = marketId.split('_');
3039
+ const marginMarketId = this.safeStringUpper(parts, 0);
3040
+ const symbolRequest = (marginMode !== undefined) ? marginMarketId : marketId;
2927
3041
  const request = {
2928
- 'symbol': market['id'],
3042
+ 'symbol': symbolRequest,
2929
3043
  'orderType': type,
2930
3044
  };
2931
3045
  const isMarketOrder = type === 'market';
@@ -2947,12 +3061,10 @@ class bitget extends bitget$1 {
2947
3061
  if ((type === 'limit') && (triggerPrice === undefined)) {
2948
3062
  request['price'] = this.priceToPrecision(symbol, price);
2949
3063
  }
3064
+ // default triggerType to market price for unification
3065
+ const triggerType = this.safeString(params, 'triggerType', 'market_price');
3066
+ const reduceOnly = this.safeValue(params, 'reduceOnly', false);
2950
3067
  const clientOrderId = this.safeString2(params, 'clientOid', 'clientOrderId');
2951
- let method = this.getSupportedMapping(marketType, {
2952
- 'spot': 'privateSpotPostTradeOrders',
2953
- 'swap': 'privateMixPostOrderPlaceOrder',
2954
- 'future': 'privateMixPostOrderPlaceOrder',
2955
- });
2956
3068
  const exchangeSpecificTifParam = this.safeStringN(params, ['force', 'timeInForceValue', 'timeInForce']);
2957
3069
  let postOnly = undefined;
2958
3070
  [postOnly, params] = this.handlePostOnly(isMarketOrder, exchangeSpecificTifParam === 'post_only', params);
@@ -2960,55 +3072,33 @@ class bitget extends bitget$1 {
2960
3072
  const timeInForce = this.safeStringLower(params, 'timeInForce', defaultTimeInForce);
2961
3073
  let timeInForceKey = 'timeInForceValue';
2962
3074
  if (marketType === 'spot') {
2963
- if (isStopLossOrTakeProfitTrigger || isStopLossOrTakeProfit) {
2964
- throw new errors.InvalidOrder(this.id + ' createOrder() does not support stop loss/take profit orders on spot markets, only swap markets');
2965
- }
2966
- timeInForceKey = 'force';
2967
- let quantityKey = 'quantity';
2968
- let quantity = undefined;
2969
- const createMarketBuyOrderRequiresPrice = this.safeValue(this.options, 'createMarketBuyOrderRequiresPrice', true);
2970
- if (createMarketBuyOrderRequiresPrice && isMarketOrder && (side === 'buy')) {
2971
- if (price === undefined) {
2972
- throw new errors.InvalidOrder(this.id + ' createOrder() requires price argument for market buy orders on spot markets to calculate the total amount to spend (amount * price), alternatively set the createMarketBuyOrderRequiresPrice option to false and pass in the cost to spend into the amount parameter');
2973
- }
2974
- else {
2975
- const amountString = this.numberToString(amount);
2976
- const priceString = this.numberToString(price);
2977
- const cost = this.parseNumber(Precise["default"].stringMul(amountString, priceString));
2978
- quantity = this.priceToPrecision(symbol, cost);
2979
- }
2980
- }
2981
- else {
2982
- quantity = this.amountToPrecision(symbol, amount);
2983
- }
2984
- if (clientOrderId !== undefined) {
2985
- request['clientOrderId'] = clientOrderId;
2986
- }
2987
- request['side'] = side;
2988
- if (triggerPrice !== undefined) {
2989
- quantityKey = 'size';
2990
- timeInForceKey = 'timeInForceValue';
2991
- // default triggerType to market price for unification
2992
- const triggerType = this.safeString(params, 'triggerType', 'market_price');
2993
- request['triggerType'] = triggerType;
2994
- request['triggerPrice'] = this.priceToPrecision(symbol, triggerPrice);
2995
- if (price !== undefined) {
2996
- request['executePrice'] = this.priceToPrecision(symbol, price);
2997
- }
2998
- method = 'privateSpotPostPlanPlacePlan';
3075
+ if (marginMode !== undefined) {
3076
+ timeInForceKey = 'timeInForce';
2999
3077
  }
3000
- if (quantity !== undefined) {
3001
- request[quantityKey] = quantity;
3078
+ else if (triggerPrice === undefined) {
3079
+ timeInForceKey = 'force';
3002
3080
  }
3003
3081
  }
3004
- else {
3082
+ if (postOnly) {
3083
+ request[timeInForceKey] = 'post_only';
3084
+ }
3085
+ else if (timeInForce === 'gtc') {
3086
+ const gtcRequest = (marginMode !== undefined) ? 'gtc' : 'normal';
3087
+ request[timeInForceKey] = gtcRequest;
3088
+ }
3089
+ else if (timeInForce === 'fok') {
3090
+ request[timeInForceKey] = 'fok';
3091
+ }
3092
+ else if (timeInForce === 'ioc') {
3093
+ request[timeInForceKey] = 'ioc';
3094
+ }
3095
+ params = this.omit(params, ['stopPrice', 'triggerType', 'stopLossPrice', 'takeProfitPrice', 'stopLoss', 'takeProfit', 'postOnly', 'reduceOnly']);
3096
+ if ((marketType === 'swap') || (marketType === 'future')) {
3005
3097
  request['marginCoin'] = market['settleId'];
3006
3098
  if (clientOrderId !== undefined) {
3007
3099
  request['clientOid'] = clientOrderId;
3008
3100
  }
3009
3101
  if (isTriggerOrder || isStopLossOrTakeProfitTrigger) {
3010
- // default triggerType to market price for unification
3011
- const triggerType = this.safeString(params, 'triggerType', 'market_price');
3012
3102
  request['triggerType'] = triggerType;
3013
3103
  }
3014
3104
  if (isStopLossOrTakeProfitTrigger) {
@@ -3018,7 +3108,6 @@ class bitget extends bitget$1 {
3018
3108
  request['holdSide'] = (side === 'buy') ? 'long' : 'short';
3019
3109
  }
3020
3110
  else {
3021
- const reduceOnly = this.safeValue(params, 'reduceOnly', false);
3022
3111
  request['size'] = this.amountToPrecision(symbol, amount);
3023
3112
  if (reduceOnly) {
3024
3113
  request['side'] = (side === 'buy') ? 'close_short' : 'close_long';
@@ -3040,7 +3129,7 @@ class bitget extends bitget$1 {
3040
3129
  if (price !== undefined) {
3041
3130
  request['executePrice'] = this.priceToPrecision(symbol, price);
3042
3131
  }
3043
- method = 'privateMixPostPlanPlacePlan';
3132
+ response = await this.privateMixPostPlanPlacePlan(this.extend(request, params));
3044
3133
  }
3045
3134
  else if (isStopLossOrTakeProfitTrigger) {
3046
3135
  if (isStopLossTriggerOrder) {
@@ -3051,9 +3140,9 @@ class bitget extends bitget$1 {
3051
3140
  request['triggerPrice'] = this.priceToPrecision(symbol, takeProfitTriggerPrice);
3052
3141
  request['planType'] = 'pos_profit';
3053
3142
  }
3054
- method = 'privateMixPostPlanPlacePositionsTPSL';
3143
+ response = await this.privateMixPostPlanPlacePositionsTPSL(this.extend(request, params));
3055
3144
  }
3056
- else if (isStopLossOrTakeProfit) {
3145
+ else {
3057
3146
  if (isStopLoss) {
3058
3147
  const slTriggerPrice = this.safeValue2(stopLoss, 'triggerPrice', 'stopPrice');
3059
3148
  request['presetStopLossPrice'] = this.priceToPrecision(symbol, slTriggerPrice);
@@ -3062,22 +3151,75 @@ class bitget extends bitget$1 {
3062
3151
  const tpTriggerPrice = this.safeValue2(takeProfit, 'triggerPrice', 'stopPrice');
3063
3152
  request['presetTakeProfitPrice'] = this.priceToPrecision(symbol, tpTriggerPrice);
3064
3153
  }
3154
+ response = await this.privateMixPostOrderPlaceOrder(this.extend(request, params));
3065
3155
  }
3066
3156
  }
3067
- if (postOnly) {
3068
- request[timeInForceKey] = 'post_only';
3069
- }
3070
- else if (timeInForce === 'gtc') {
3071
- request[timeInForceKey] = 'normal';
3072
- }
3073
- else if (timeInForce === 'fok') {
3074
- request[timeInForceKey] = 'fok';
3157
+ else if (marketType === 'spot') {
3158
+ if (isStopLossOrTakeProfitTrigger || isStopLossOrTakeProfit) {
3159
+ throw new errors.InvalidOrder(this.id + ' createOrder() does not support stop loss/take profit orders on spot markets, only swap markets');
3160
+ }
3161
+ let quantity = undefined;
3162
+ const createMarketBuyOrderRequiresPrice = this.safeValue(this.options, 'createMarketBuyOrderRequiresPrice', true);
3163
+ if (createMarketBuyOrderRequiresPrice && isMarketOrder && (side === 'buy')) {
3164
+ if (price === undefined) {
3165
+ throw new errors.InvalidOrder(this.id + ' createOrder() requires price argument for market buy orders on spot markets to calculate the total amount to spend (amount * price), alternatively set the createMarketBuyOrderRequiresPrice option to false and pass in the cost to spend into the amount parameter');
3166
+ }
3167
+ else {
3168
+ const amountString = this.numberToString(amount);
3169
+ const priceString = this.numberToString(price);
3170
+ const cost = this.parseNumber(Precise["default"].stringMul(amountString, priceString));
3171
+ quantity = this.priceToPrecision(symbol, cost);
3172
+ }
3173
+ }
3174
+ else {
3175
+ quantity = this.amountToPrecision(symbol, amount);
3176
+ }
3177
+ request['side'] = side;
3178
+ if (triggerPrice !== undefined) {
3179
+ if (quantity !== undefined) {
3180
+ request['size'] = quantity;
3181
+ }
3182
+ request['triggerType'] = triggerType;
3183
+ request['triggerPrice'] = this.priceToPrecision(symbol, triggerPrice);
3184
+ if (price !== undefined) {
3185
+ request['executePrice'] = this.priceToPrecision(symbol, price);
3186
+ }
3187
+ if (clientOrderId !== undefined) {
3188
+ request['clientOrderId'] = clientOrderId;
3189
+ }
3190
+ response = await this.privateSpotPostPlanPlacePlan(this.extend(request, params));
3191
+ }
3192
+ else if (marginMode !== undefined) {
3193
+ request['loanType'] = 'normal';
3194
+ if (clientOrderId !== undefined) {
3195
+ request['clientOid'] = clientOrderId;
3196
+ }
3197
+ if (createMarketBuyOrderRequiresPrice && isMarketOrder && (side === 'buy')) {
3198
+ request['quoteAmount'] = quantity;
3199
+ }
3200
+ else {
3201
+ request['baseQuantity'] = quantity;
3202
+ }
3203
+ if (marginMode === 'isolated') {
3204
+ response = await this.privateMarginPostIsolatedOrderPlaceOrder(this.extend(request, params));
3205
+ }
3206
+ else if (marginMode === 'cross') {
3207
+ response = await this.privateMarginPostCrossOrderPlaceOrder(this.extend(request, params));
3208
+ }
3209
+ }
3210
+ else {
3211
+ if (clientOrderId !== undefined) {
3212
+ request['clientOrderId'] = clientOrderId;
3213
+ }
3214
+ if (quantity !== undefined) {
3215
+ request['quantity'] = quantity;
3216
+ }
3217
+ response = await this.privateSpotPostTradeOrders(this.extend(request, params));
3218
+ }
3075
3219
  }
3076
- else if (timeInForce === 'ioc') {
3077
- request[timeInForceKey] = 'ioc';
3220
+ else {
3221
+ throw new errors.NotSupported(this.id + ' createOrder() does not support ' + marketType + ' orders');
3078
3222
  }
3079
- const omitted = this.omit(query, ['stopPrice', 'triggerType', 'stopLossPrice', 'takeProfitPrice', 'stopLoss', 'takeProfit', 'postOnly', 'reduceOnly']);
3080
- const response = await this[method](this.extend(request, omitted));
3081
3223
  //
3082
3224
  // {
3083
3225
  // "code": "00000",
@@ -3089,7 +3231,7 @@ class bitget extends bitget$1 {
3089
3231
  // }
3090
3232
  // }
3091
3233
  //
3092
- const data = this.safeValue(response, 'data');
3234
+ const data = this.safeValue(response, 'data', {});
3093
3235
  return this.parseOrder(data, market);
3094
3236
  }
3095
3237
  async editOrder(id, symbol, type, side, amount = undefined, price = undefined, params = {}) {
@@ -3944,7 +4086,7 @@ class bitget extends bitget$1 {
3944
4086
  if (since !== undefined) {
3945
4087
  request['before'] = since;
3946
4088
  }
3947
- [request, params] = this.handleUntilOption('after', params, request);
4089
+ [request, params] = this.handleUntilOption('after', request, params);
3948
4090
  const response = await this.privateSpotPostAccountBills(this.extend(request, params));
3949
4091
  //
3950
4092
  // {
@@ -4061,7 +4203,7 @@ class bitget extends bitget$1 {
4061
4203
  else if (orderId === undefined) {
4062
4204
  request['startTime'] = 0;
4063
4205
  }
4064
- [request, params] = this.handleUntilOption('endTime', params, request);
4206
+ [request, params] = this.handleUntilOption('endTime', request, params);
4065
4207
  if (!('endTime' in request) && (orderId === undefined)) {
4066
4208
  request['endTime'] = this.milliseconds();
4067
4209
  }
@@ -4975,7 +5117,7 @@ class bitget extends bitget$1 {
4975
5117
  if (limit !== undefined) {
4976
5118
  request['limit'] = limit;
4977
5119
  }
4978
- [request, params] = this.handleUntilOption('after', params, request);
5120
+ [request, params] = this.handleUntilOption('after', request, params);
4979
5121
  const response = await this.privateSpotGetAccountTransferRecords(this.extend(request, params));
4980
5122
  //
4981
5123
  // {