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
@@ -1050,6 +1050,9 @@ export default class Exchange {
1050
1050
  convertToBigInt(value) {
1051
1051
  return BigInt(value); // used on XT
1052
1052
  }
1053
+ stringToCharsArray(value) {
1054
+ return value.split('');
1055
+ }
1053
1056
  valueIsDefined(value) {
1054
1057
  return value !== undefined && value !== null;
1055
1058
  }
package/js/src/bingx.js CHANGED
@@ -883,14 +883,19 @@ export default class bingx extends Exchange {
883
883
  if (time === 0) {
884
884
  time = undefined;
885
885
  }
886
- const isBuyerMaker = this.safeValue2(trade, 'buyerMaker', 'isBuyerMaker');
887
- const side = this.safeStringLower2(trade, 'side', 'S');
888
886
  const cost = this.safeString(trade, 'quoteQty');
889
887
  const type = (cost === undefined) ? 'spot' : 'swap';
890
888
  const currencyId = this.safeString2(trade, 'currency', 'N');
891
889
  const currencyCode = this.safeCurrencyCode(currencyId);
892
890
  const m = this.safeValue(trade, 'm', false);
893
891
  const marketId = this.safeString(trade, 's');
892
+ const isBuyerMaker = this.safeValue2(trade, 'buyerMaker', 'isBuyerMaker');
893
+ let takeOrMaker = (isBuyerMaker || m) ? 'maker' : 'taker';
894
+ let side = this.safeStringLower2(trade, 'side', 'S');
895
+ if (side === undefined) {
896
+ side = (isBuyerMaker || m) ? 'sell' : 'buy';
897
+ takeOrMaker = 'taker';
898
+ }
894
899
  return this.safeTrade({
895
900
  'id': this.safeStringN(trade, ['id', 't']),
896
901
  'info': trade,
@@ -900,7 +905,7 @@ export default class bingx extends Exchange {
900
905
  'order': this.safeString2(trade, 'orderId', 'i'),
901
906
  'type': this.safeStringLower(trade, 'o'),
902
907
  'side': this.parseOrderSide(side),
903
- 'takerOrMaker': (isBuyerMaker || m) ? 'maker' : 'taker',
908
+ 'takerOrMaker': takeOrMaker,
904
909
  'price': this.safeString2(trade, 'price', 'p'),
905
910
  'amount': this.safeStringN(trade, ['qty', 'amount', 'q']),
906
911
  'cost': cost,
@@ -1556,7 +1561,7 @@ export default class bingx extends Exchange {
1556
1561
  'info': position,
1557
1562
  'id': this.safeString(position, 'positionId'),
1558
1563
  'symbol': this.safeSymbol(marketId, market, '-', 'swap'),
1559
- 'notional': this.safeString(position, 'positionAmt'),
1564
+ 'notional': this.safeNumber(position, 'positionAmt'),
1560
1565
  'marginMode': marginMode,
1561
1566
  'liquidationPrice': undefined,
1562
1567
  'entryPrice': this.safeNumber2(position, 'avgPrice', 'entryPrice'),
package/js/src/bitget.js CHANGED
@@ -1743,7 +1743,7 @@ export default class bitget extends Exchange {
1743
1743
  'startTime': since,
1744
1744
  'endTime': this.milliseconds(),
1745
1745
  };
1746
- [request, params] = this.handleUntilOption('endTime', params, request);
1746
+ [request, params] = this.handleUntilOption('endTime', request, params);
1747
1747
  if (limit !== undefined) {
1748
1748
  request['pageSize'] = limit;
1749
1749
  }
@@ -2644,18 +2644,20 @@ export default class bitget extends Exchange {
2644
2644
  * @description query for balance and get the amount of funds available for trading or funds locked in orders
2645
2645
  * @see https://bitgetlimited.github.io/apidoc/en/spot/#get-account-assets
2646
2646
  * @see https://bitgetlimited.github.io/apidoc/en/mix/#get-account-list
2647
+ * @see https://bitgetlimited.github.io/apidoc/en/margin/#get-cross-assets
2648
+ * @see https://bitgetlimited.github.io/apidoc/en/margin/#get-isolated-assets
2647
2649
  * @param {object} [params] extra parameters specific to the bitget api endpoint
2648
2650
  * @returns {object} a [balance structure]{@link https://github.com/ccxt/ccxt/wiki/Manual#balance-structure}
2649
2651
  */
2650
2652
  const sandboxMode = this.safeValue(this.options, 'sandboxMode', false);
2651
2653
  await this.loadMarkets();
2652
- const [marketType, query] = this.handleMarketTypeAndParams('fetchBalance', undefined, params);
2653
- const method = this.getSupportedMapping(marketType, {
2654
- 'spot': 'privateSpotGetAccountAssets',
2655
- 'swap': 'privateMixGetAccountAccounts',
2656
- });
2657
2654
  const request = {};
2658
- if (marketType === 'swap') {
2655
+ let marketType = undefined;
2656
+ let marginMode = undefined;
2657
+ let response = undefined;
2658
+ [marketType, params] = this.handleMarketTypeAndParams('fetchBalance', undefined, params);
2659
+ [marginMode, params] = this.handleMarginModeAndParams('fetchBalance', params);
2660
+ if ((marketType === 'swap') || (marketType === 'future')) {
2659
2661
  let subType = undefined;
2660
2662
  [subType, params] = this.handleSubTypeAndParams('fetchBalance', undefined, params);
2661
2663
  let productType = (subType === 'linear') ? 'UMCBL' : 'DMCBL';
@@ -2663,45 +2665,106 @@ export default class bitget extends Exchange {
2663
2665
  productType = 'S' + productType;
2664
2666
  }
2665
2667
  request['productType'] = productType;
2668
+ response = await this.privateMixGetAccountAccounts(this.extend(request, params));
2669
+ }
2670
+ else if (marginMode === 'isolated') {
2671
+ response = await this.privateMarginGetIsolatedAccountAssets(this.extend(request, params));
2672
+ }
2673
+ else if (marginMode === 'cross') {
2674
+ response = await this.privateMarginGetCrossAccountAssets(this.extend(request, params));
2675
+ }
2676
+ else if (marketType === 'spot') {
2677
+ response = await this.privateSpotGetAccountAssets(this.extend(request, params));
2678
+ }
2679
+ else {
2680
+ throw new NotSupported(this.id + ' fetchBalance() does not support ' + marketType + ' accounts');
2666
2681
  }
2667
- const response = await this[method](this.extend(request, query));
2668
2682
  // spot
2683
+ //
2669
2684
  // {
2670
- // code: '00000',
2671
- // msg: 'success',
2672
- // requestTime: 1645928868827,
2673
- // data: [
2674
- // {
2675
- // coinId: 1,
2676
- // coinName: 'BTC',
2677
- // available: '0.00070000',
2678
- // frozen: '0.00000000',
2679
- // lock: '0.00000000',
2680
- // uTime: '1645921706000'
2681
- // }
2682
- // ]
2685
+ // "code": "00000",
2686
+ // "msg": "success",
2687
+ // "requestTime": 1697507299139,
2688
+ // "data": [
2689
+ // {
2690
+ // "coinId": 1,
2691
+ // "coinName": "BTC",
2692
+ // "available": "0.00000000",
2693
+ // "frozen": "0.00000000",
2694
+ // "lock": "0.00000000",
2695
+ // "uTime": "1697248128000"
2696
+ // },
2697
+ // ]
2683
2698
  // }
2684
2699
  //
2685
2700
  // swap
2701
+ //
2686
2702
  // {
2687
- // code: '00000',
2688
- // msg: 'success',
2689
- // requestTime: 1645928929251,
2690
- // data: [
2691
- // {
2692
- // marginCoin: 'USDT',
2693
- // locked: '0',
2694
- // available: '8.078525',
2695
- // crossMaxAvailable: '8.078525',
2696
- // fixedMaxAvailable: '8.078525',
2697
- // maxTransferOut: '8.078525',
2698
- // equity: '10.02508',
2699
- // usdtEquity: '10.02508',
2700
- // btcEquity: '0.00026057027'
2701
- // }
2702
- // ]
2703
+ // "code": "00000",
2704
+ // "msg": "success",
2705
+ // "requestTime": 1697507505367,
2706
+ // "data": [
2707
+ // {
2708
+ // "marginCoin": "STETH",
2709
+ // "locked": "0",
2710
+ // "available": "0",
2711
+ // "crossMaxAvailable": "0",
2712
+ // "fixedMaxAvailable": "0",
2713
+ // "maxTransferOut": "0",
2714
+ // "equity": "0",
2715
+ // "usdtEquity": "0",
2716
+ // "btcEquity": "0",
2717
+ // "crossRiskRate": "0",
2718
+ // "unrealizedPL": "0",
2719
+ // "bonus": "0"
2720
+ // },
2721
+ // ]
2703
2722
  // }
2704
- const data = this.safeValue(response, 'data');
2723
+ //
2724
+ // isolated margin
2725
+ //
2726
+ // {
2727
+ // "code": "00000",
2728
+ // "msg": "success",
2729
+ // "requestTime": 1697501436571,
2730
+ // "data": [
2731
+ // {
2732
+ // "symbol": "BTCUSDT",
2733
+ // "coin": "BTC",
2734
+ // "totalAmount": "0.00021654",
2735
+ // "available": "0.00021654",
2736
+ // "transferable": "0.00021654",
2737
+ // "frozen": "0",
2738
+ // "borrow": "0",
2739
+ // "interest": "0",
2740
+ // "net": "0.00021654",
2741
+ // "ctime": "1697248128071"
2742
+ // },
2743
+ // ]
2744
+ // }
2745
+ //
2746
+ // cross margin
2747
+ //
2748
+ // {
2749
+ // "code": "00000",
2750
+ // "msg": "success",
2751
+ // "requestTime": 1697515463804,
2752
+ // "data": [
2753
+ // {
2754
+ // "coin": "BTC",
2755
+ // "totalAmount": "0.00024996",
2756
+ // "available": "0.00024996",
2757
+ // "transferable": "0.00004994",
2758
+ // "frozen": "0",
2759
+ // "borrow": "0.0001",
2760
+ // "interest": "0.00000001",
2761
+ // "net": "0.00014995",
2762
+ // "ctime": "1697251265504"
2763
+ // },
2764
+ // ]
2765
+ // }
2766
+ //
2767
+ const data = this.safeValue(response, 'data', []);
2705
2768
  return this.parseBalance(data);
2706
2769
  }
2707
2770
  parseBalance(balance) {
@@ -2710,42 +2773,81 @@ export default class bitget extends Exchange {
2710
2773
  // spot
2711
2774
  //
2712
2775
  // {
2713
- // coinId: '1',
2714
- // coinName: 'BTC',
2715
- // available: '0.00099900',
2716
- // frozen: '0.00000000',
2717
- // lock: '0.00000000',
2718
- // uTime: '1661595535000'
2776
+ // "coinId": 1,
2777
+ // "coinName": "BTC",
2778
+ // "available": "0.00000000",
2779
+ // "frozen": "0.00000000",
2780
+ // "lock": "0.00000000",
2781
+ // "uTime": "1697248128000"
2719
2782
  // }
2720
2783
  //
2721
2784
  // swap
2722
2785
  //
2723
2786
  // {
2724
- // marginCoin: 'BTC',
2725
- // locked: '0.00001948',
2726
- // available: '0.00006622',
2727
- // crossMaxAvailable: '0.00004674',
2728
- // fixedMaxAvailable: '0.00004674',
2729
- // maxTransferOut: '0.00004674',
2730
- // equity: '0.00006622',
2731
- // usdtEquity: '1.734307497491',
2732
- // btcEquity: '0.000066229058',
2733
- // crossRiskRate: '0.066308887072',
2734
- // unrealizedPL: '0',
2735
- // bonus: '0'
2787
+ // "marginCoin": "STETH",
2788
+ // "locked": "0",
2789
+ // "available": "0",
2790
+ // "crossMaxAvailable": "0",
2791
+ // "fixedMaxAvailable": "0",
2792
+ // "maxTransferOut": "0",
2793
+ // "equity": "0",
2794
+ // "usdtEquity": "0",
2795
+ // "btcEquity": "0",
2796
+ // "crossRiskRate": "0",
2797
+ // "unrealizedPL": "0",
2798
+ // "bonus": "0"
2799
+ // }
2800
+ //
2801
+ // isolated margin
2802
+ //
2803
+ // {
2804
+ // "symbol": "BTCUSDT",
2805
+ // "coin": "BTC",
2806
+ // "totalAmount": "0.00021654",
2807
+ // "available": "0.00021654",
2808
+ // "transferable": "0.00021654",
2809
+ // "frozen": "0",
2810
+ // "borrow": "0",
2811
+ // "interest": "0",
2812
+ // "net": "0.00021654",
2813
+ // "ctime": "1697248128071"
2814
+ // }
2815
+ //
2816
+ // cross margin
2817
+ //
2818
+ // {
2819
+ // "coin": "BTC",
2820
+ // "totalAmount": "0.00024995",
2821
+ // "available": "0.00024995",
2822
+ // "transferable": "0.00004993",
2823
+ // "frozen": "0",
2824
+ // "borrow": "0.0001",
2825
+ // "interest": "0.00000001",
2826
+ // "net": "0.00014994",
2827
+ // "ctime": "1697251265504"
2736
2828
  // }
2737
2829
  //
2738
2830
  for (let i = 0; i < balance.length; i++) {
2739
2831
  const entry = balance[i];
2740
- const currencyId = this.safeString2(entry, 'coinName', 'marginCoin');
2741
- const code = this.safeCurrencyCode(currencyId);
2742
2832
  const account = this.account();
2743
- const spotAccountFree = this.safeString(entry, 'available');
2744
- const contractAccountFree = this.safeString(entry, 'maxTransferOut');
2745
- account['free'] = (contractAccountFree !== undefined) ? contractAccountFree : spotAccountFree;
2746
- const frozen = this.safeString(entry, 'frozen');
2747
- const locked = this.safeString2(entry, 'lock', 'locked');
2748
- account['used'] = Precise.stringAdd(frozen, locked);
2833
+ const currencyId = this.safeStringN(entry, ['coinName', 'marginCoin', 'coin']);
2834
+ const code = this.safeCurrencyCode(currencyId);
2835
+ const borrow = this.safeString(entry, 'borrow');
2836
+ if (borrow !== undefined) {
2837
+ const interest = this.safeString(entry, 'interest');
2838
+ account['free'] = this.safeString(entry, 'transferable');
2839
+ account['total'] = this.safeString(entry, 'totalAmount');
2840
+ account['debt'] = Precise.stringAdd(borrow, interest);
2841
+ }
2842
+ else {
2843
+ // Use transferable instead of available for swap and margin https://github.com/ccxt/ccxt/pull/19127
2844
+ const spotAccountFree = this.safeString(entry, 'available');
2845
+ const contractAccountFree = this.safeString(entry, 'maxTransferOut');
2846
+ account['free'] = (contractAccountFree !== undefined) ? contractAccountFree : spotAccountFree;
2847
+ const frozen = this.safeString(entry, 'frozen');
2848
+ const locked = this.safeString2(entry, 'lock', 'locked');
2849
+ account['used'] = Precise.stringAdd(frozen, locked);
2850
+ }
2749
2851
  result[code] = account;
2750
2852
  }
2751
2853
  return this.safeBalance(result);
@@ -2908,6 +3010,8 @@ export default class bitget extends Exchange {
2908
3010
  * @see https://bitgetlimited.github.io/apidoc/en/mix/#place-stop-order
2909
3011
  * @see https://bitgetlimited.github.io/apidoc/en/mix/#place-position-tpsl
2910
3012
  * @see https://bitgetlimited.github.io/apidoc/en/mix/#place-plan-order
3013
+ * @see https://bitgetlimited.github.io/apidoc/en/margin/#isolated-place-order
3014
+ * @see https://bitgetlimited.github.io/apidoc/en/margin/#cross-place-order
2911
3015
  * @param {string} symbol unified symbol of the market to create an order in
2912
3016
  * @param {string} type 'market' or 'limit'
2913
3017
  * @param {string} side 'buy' or 'sell' or 'open_long' or 'open_short' or 'close_long' or 'close_short'
@@ -2922,13 +3026,23 @@ export default class bitget extends Exchange {
2922
3026
  * @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)
2923
3027
  * @param {float} [params.stopLoss.triggerPrice] *swap only* stop loss trigger price
2924
3028
  * @param {string} [params.timeInForce] "GTC", "IOC", "FOK", or "PO"
3029
+ * @param {string} [params.marginMode] 'isolated' or 'cross' for spot margin trading
3030
+ * @param {string} [params.loanType] *spot margin only* 'normal', 'autoLoan', 'autoRepay', or 'autoLoanAndRepay' default is 'normal'
2925
3031
  * @returns {object} an [order structure]{@link https://github.com/ccxt/ccxt/wiki/Manual#order-structure}
2926
3032
  */
2927
3033
  await this.loadMarkets();
2928
3034
  const market = this.market(symbol);
2929
- const [marketType, query] = this.handleMarketTypeAndParams('createOrder', market, params);
3035
+ let marketType = undefined;
3036
+ let marginMode = undefined;
3037
+ let response = undefined;
3038
+ [marketType, params] = this.handleMarketTypeAndParams('createOrder', market, params);
3039
+ [marginMode, params] = this.handleMarginModeAndParams('createOrder', params);
3040
+ const marketId = market['id'];
3041
+ const parts = marketId.split('_');
3042
+ const marginMarketId = this.safeStringUpper(parts, 0);
3043
+ const symbolRequest = (marginMode !== undefined) ? marginMarketId : marketId;
2930
3044
  const request = {
2931
- 'symbol': market['id'],
3045
+ 'symbol': symbolRequest,
2932
3046
  'orderType': type,
2933
3047
  };
2934
3048
  const isMarketOrder = type === 'market';
@@ -2950,12 +3064,10 @@ export default class bitget extends Exchange {
2950
3064
  if ((type === 'limit') && (triggerPrice === undefined)) {
2951
3065
  request['price'] = this.priceToPrecision(symbol, price);
2952
3066
  }
3067
+ // default triggerType to market price for unification
3068
+ const triggerType = this.safeString(params, 'triggerType', 'market_price');
3069
+ const reduceOnly = this.safeValue(params, 'reduceOnly', false);
2953
3070
  const clientOrderId = this.safeString2(params, 'clientOid', 'clientOrderId');
2954
- let method = this.getSupportedMapping(marketType, {
2955
- 'spot': 'privateSpotPostTradeOrders',
2956
- 'swap': 'privateMixPostOrderPlaceOrder',
2957
- 'future': 'privateMixPostOrderPlaceOrder',
2958
- });
2959
3071
  const exchangeSpecificTifParam = this.safeStringN(params, ['force', 'timeInForceValue', 'timeInForce']);
2960
3072
  let postOnly = undefined;
2961
3073
  [postOnly, params] = this.handlePostOnly(isMarketOrder, exchangeSpecificTifParam === 'post_only', params);
@@ -2963,55 +3075,33 @@ export default class bitget extends Exchange {
2963
3075
  const timeInForce = this.safeStringLower(params, 'timeInForce', defaultTimeInForce);
2964
3076
  let timeInForceKey = 'timeInForceValue';
2965
3077
  if (marketType === 'spot') {
2966
- if (isStopLossOrTakeProfitTrigger || isStopLossOrTakeProfit) {
2967
- throw new InvalidOrder(this.id + ' createOrder() does not support stop loss/take profit orders on spot markets, only swap markets');
2968
- }
2969
- timeInForceKey = 'force';
2970
- let quantityKey = 'quantity';
2971
- let quantity = undefined;
2972
- const createMarketBuyOrderRequiresPrice = this.safeValue(this.options, 'createMarketBuyOrderRequiresPrice', true);
2973
- if (createMarketBuyOrderRequiresPrice && isMarketOrder && (side === 'buy')) {
2974
- if (price === undefined) {
2975
- throw new 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');
2976
- }
2977
- else {
2978
- const amountString = this.numberToString(amount);
2979
- const priceString = this.numberToString(price);
2980
- const cost = this.parseNumber(Precise.stringMul(amountString, priceString));
2981
- quantity = this.priceToPrecision(symbol, cost);
2982
- }
2983
- }
2984
- else {
2985
- quantity = this.amountToPrecision(symbol, amount);
2986
- }
2987
- if (clientOrderId !== undefined) {
2988
- request['clientOrderId'] = clientOrderId;
2989
- }
2990
- request['side'] = side;
2991
- if (triggerPrice !== undefined) {
2992
- quantityKey = 'size';
2993
- timeInForceKey = 'timeInForceValue';
2994
- // default triggerType to market price for unification
2995
- const triggerType = this.safeString(params, 'triggerType', 'market_price');
2996
- request['triggerType'] = triggerType;
2997
- request['triggerPrice'] = this.priceToPrecision(symbol, triggerPrice);
2998
- if (price !== undefined) {
2999
- request['executePrice'] = this.priceToPrecision(symbol, price);
3000
- }
3001
- method = 'privateSpotPostPlanPlacePlan';
3078
+ if (marginMode !== undefined) {
3079
+ timeInForceKey = 'timeInForce';
3002
3080
  }
3003
- if (quantity !== undefined) {
3004
- request[quantityKey] = quantity;
3081
+ else if (triggerPrice === undefined) {
3082
+ timeInForceKey = 'force';
3005
3083
  }
3006
3084
  }
3007
- else {
3085
+ if (postOnly) {
3086
+ request[timeInForceKey] = 'post_only';
3087
+ }
3088
+ else if (timeInForce === 'gtc') {
3089
+ const gtcRequest = (marginMode !== undefined) ? 'gtc' : 'normal';
3090
+ request[timeInForceKey] = gtcRequest;
3091
+ }
3092
+ else if (timeInForce === 'fok') {
3093
+ request[timeInForceKey] = 'fok';
3094
+ }
3095
+ else if (timeInForce === 'ioc') {
3096
+ request[timeInForceKey] = 'ioc';
3097
+ }
3098
+ params = this.omit(params, ['stopPrice', 'triggerType', 'stopLossPrice', 'takeProfitPrice', 'stopLoss', 'takeProfit', 'postOnly', 'reduceOnly']);
3099
+ if ((marketType === 'swap') || (marketType === 'future')) {
3008
3100
  request['marginCoin'] = market['settleId'];
3009
3101
  if (clientOrderId !== undefined) {
3010
3102
  request['clientOid'] = clientOrderId;
3011
3103
  }
3012
3104
  if (isTriggerOrder || isStopLossOrTakeProfitTrigger) {
3013
- // default triggerType to market price for unification
3014
- const triggerType = this.safeString(params, 'triggerType', 'market_price');
3015
3105
  request['triggerType'] = triggerType;
3016
3106
  }
3017
3107
  if (isStopLossOrTakeProfitTrigger) {
@@ -3021,7 +3111,6 @@ export default class bitget extends Exchange {
3021
3111
  request['holdSide'] = (side === 'buy') ? 'long' : 'short';
3022
3112
  }
3023
3113
  else {
3024
- const reduceOnly = this.safeValue(params, 'reduceOnly', false);
3025
3114
  request['size'] = this.amountToPrecision(symbol, amount);
3026
3115
  if (reduceOnly) {
3027
3116
  request['side'] = (side === 'buy') ? 'close_short' : 'close_long';
@@ -3043,7 +3132,7 @@ export default class bitget extends Exchange {
3043
3132
  if (price !== undefined) {
3044
3133
  request['executePrice'] = this.priceToPrecision(symbol, price);
3045
3134
  }
3046
- method = 'privateMixPostPlanPlacePlan';
3135
+ response = await this.privateMixPostPlanPlacePlan(this.extend(request, params));
3047
3136
  }
3048
3137
  else if (isStopLossOrTakeProfitTrigger) {
3049
3138
  if (isStopLossTriggerOrder) {
@@ -3054,9 +3143,9 @@ export default class bitget extends Exchange {
3054
3143
  request['triggerPrice'] = this.priceToPrecision(symbol, takeProfitTriggerPrice);
3055
3144
  request['planType'] = 'pos_profit';
3056
3145
  }
3057
- method = 'privateMixPostPlanPlacePositionsTPSL';
3146
+ response = await this.privateMixPostPlanPlacePositionsTPSL(this.extend(request, params));
3058
3147
  }
3059
- else if (isStopLossOrTakeProfit) {
3148
+ else {
3060
3149
  if (isStopLoss) {
3061
3150
  const slTriggerPrice = this.safeValue2(stopLoss, 'triggerPrice', 'stopPrice');
3062
3151
  request['presetStopLossPrice'] = this.priceToPrecision(symbol, slTriggerPrice);
@@ -3065,22 +3154,75 @@ export default class bitget extends Exchange {
3065
3154
  const tpTriggerPrice = this.safeValue2(takeProfit, 'triggerPrice', 'stopPrice');
3066
3155
  request['presetTakeProfitPrice'] = this.priceToPrecision(symbol, tpTriggerPrice);
3067
3156
  }
3157
+ response = await this.privateMixPostOrderPlaceOrder(this.extend(request, params));
3068
3158
  }
3069
3159
  }
3070
- if (postOnly) {
3071
- request[timeInForceKey] = 'post_only';
3072
- }
3073
- else if (timeInForce === 'gtc') {
3074
- request[timeInForceKey] = 'normal';
3075
- }
3076
- else if (timeInForce === 'fok') {
3077
- request[timeInForceKey] = 'fok';
3160
+ else if (marketType === 'spot') {
3161
+ if (isStopLossOrTakeProfitTrigger || isStopLossOrTakeProfit) {
3162
+ throw new InvalidOrder(this.id + ' createOrder() does not support stop loss/take profit orders on spot markets, only swap markets');
3163
+ }
3164
+ let quantity = undefined;
3165
+ const createMarketBuyOrderRequiresPrice = this.safeValue(this.options, 'createMarketBuyOrderRequiresPrice', true);
3166
+ if (createMarketBuyOrderRequiresPrice && isMarketOrder && (side === 'buy')) {
3167
+ if (price === undefined) {
3168
+ throw new 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');
3169
+ }
3170
+ else {
3171
+ const amountString = this.numberToString(amount);
3172
+ const priceString = this.numberToString(price);
3173
+ const cost = this.parseNumber(Precise.stringMul(amountString, priceString));
3174
+ quantity = this.priceToPrecision(symbol, cost);
3175
+ }
3176
+ }
3177
+ else {
3178
+ quantity = this.amountToPrecision(symbol, amount);
3179
+ }
3180
+ request['side'] = side;
3181
+ if (triggerPrice !== undefined) {
3182
+ if (quantity !== undefined) {
3183
+ request['size'] = quantity;
3184
+ }
3185
+ request['triggerType'] = triggerType;
3186
+ request['triggerPrice'] = this.priceToPrecision(symbol, triggerPrice);
3187
+ if (price !== undefined) {
3188
+ request['executePrice'] = this.priceToPrecision(symbol, price);
3189
+ }
3190
+ if (clientOrderId !== undefined) {
3191
+ request['clientOrderId'] = clientOrderId;
3192
+ }
3193
+ response = await this.privateSpotPostPlanPlacePlan(this.extend(request, params));
3194
+ }
3195
+ else if (marginMode !== undefined) {
3196
+ request['loanType'] = 'normal';
3197
+ if (clientOrderId !== undefined) {
3198
+ request['clientOid'] = clientOrderId;
3199
+ }
3200
+ if (createMarketBuyOrderRequiresPrice && isMarketOrder && (side === 'buy')) {
3201
+ request['quoteAmount'] = quantity;
3202
+ }
3203
+ else {
3204
+ request['baseQuantity'] = quantity;
3205
+ }
3206
+ if (marginMode === 'isolated') {
3207
+ response = await this.privateMarginPostIsolatedOrderPlaceOrder(this.extend(request, params));
3208
+ }
3209
+ else if (marginMode === 'cross') {
3210
+ response = await this.privateMarginPostCrossOrderPlaceOrder(this.extend(request, params));
3211
+ }
3212
+ }
3213
+ else {
3214
+ if (clientOrderId !== undefined) {
3215
+ request['clientOrderId'] = clientOrderId;
3216
+ }
3217
+ if (quantity !== undefined) {
3218
+ request['quantity'] = quantity;
3219
+ }
3220
+ response = await this.privateSpotPostTradeOrders(this.extend(request, params));
3221
+ }
3078
3222
  }
3079
- else if (timeInForce === 'ioc') {
3080
- request[timeInForceKey] = 'ioc';
3223
+ else {
3224
+ throw new NotSupported(this.id + ' createOrder() does not support ' + marketType + ' orders');
3081
3225
  }
3082
- const omitted = this.omit(query, ['stopPrice', 'triggerType', 'stopLossPrice', 'takeProfitPrice', 'stopLoss', 'takeProfit', 'postOnly', 'reduceOnly']);
3083
- const response = await this[method](this.extend(request, omitted));
3084
3226
  //
3085
3227
  // {
3086
3228
  // "code": "00000",
@@ -3092,7 +3234,7 @@ export default class bitget extends Exchange {
3092
3234
  // }
3093
3235
  // }
3094
3236
  //
3095
- const data = this.safeValue(response, 'data');
3237
+ const data = this.safeValue(response, 'data', {});
3096
3238
  return this.parseOrder(data, market);
3097
3239
  }
3098
3240
  async editOrder(id, symbol, type, side, amount = undefined, price = undefined, params = {}) {
@@ -3947,7 +4089,7 @@ export default class bitget extends Exchange {
3947
4089
  if (since !== undefined) {
3948
4090
  request['before'] = since;
3949
4091
  }
3950
- [request, params] = this.handleUntilOption('after', params, request);
4092
+ [request, params] = this.handleUntilOption('after', request, params);
3951
4093
  const response = await this.privateSpotPostAccountBills(this.extend(request, params));
3952
4094
  //
3953
4095
  // {
@@ -4064,7 +4206,7 @@ export default class bitget extends Exchange {
4064
4206
  else if (orderId === undefined) {
4065
4207
  request['startTime'] = 0;
4066
4208
  }
4067
- [request, params] = this.handleUntilOption('endTime', params, request);
4209
+ [request, params] = this.handleUntilOption('endTime', request, params);
4068
4210
  if (!('endTime' in request) && (orderId === undefined)) {
4069
4211
  request['endTime'] = this.milliseconds();
4070
4212
  }
@@ -4978,7 +5120,7 @@ export default class bitget extends Exchange {
4978
5120
  if (limit !== undefined) {
4979
5121
  request['limit'] = limit;
4980
5122
  }
4981
- [request, params] = this.handleUntilOption('after', params, request);
5123
+ [request, params] = this.handleUntilOption('after', request, params);
4982
5124
  const response = await this.privateSpotGetAccountTransferRecords(this.extend(request, params));
4983
5125
  //
4984
5126
  // {
package/js/src/bitmex.js CHANGED
@@ -663,6 +663,7 @@ export default class bitmex extends Exchange {
663
663
  'max': positionIsQuote ? maxOrderQty : undefined,
664
664
  },
665
665
  },
666
+ 'created': this.parse8601(this.safeString(market, 'listing')),
666
667
  'info': market,
667
668
  });
668
669
  }
@@ -1043,6 +1044,7 @@ export default class bitmex extends Exchange {
1043
1044
  'Deposit': 'transaction',
1044
1045
  'Transfer': 'transfer',
1045
1046
  'AffiliatePayout': 'referral',
1047
+ 'SpotTrade': 'trade',
1046
1048
  };
1047
1049
  return this.safeString(types, type, type);
1048
1050
  }
@@ -1580,9 +1582,9 @@ export default class bitmex extends Exchange {
1580
1582
  const feeCurrencyCode = this.safeCurrencyCode(currencyId);
1581
1583
  const feeRateString = this.safeString(trade, 'commission');
1582
1584
  fee = {
1583
- 'cost': feeCostString,
1585
+ 'cost': Precise.stringAbs(feeCostString),
1584
1586
  'currency': feeCurrencyCode,
1585
- 'rate': feeRateString,
1587
+ 'rate': Precise.stringAbs(feeRateString),
1586
1588
  };
1587
1589
  }
1588
1590
  // Trade or Funding
@@ -2110,7 +2112,8 @@ export default class bitmex extends Exchange {
2110
2112
  // }
2111
2113
  // ]
2112
2114
  //
2113
- return this.parsePositions(response, symbols);
2115
+ const results = this.parsePositions(response, symbols);
2116
+ return this.filterByArrayPositions(results, 'symbol', symbols, false);
2114
2117
  }
2115
2118
  parsePosition(position, market = undefined) {
2116
2119
  //