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
package/dist/cjs/ccxt.js CHANGED
@@ -108,7 +108,7 @@ var poloniex = require('./src/poloniex.js');
108
108
  var probit = require('./src/probit.js');
109
109
  var timex = require('./src/timex.js');
110
110
  var tokocrypto = require('./src/tokocrypto.js');
111
- var tradeogre = require('./src/tradeogre.js');
111
+ var toobit = require('./src/toobit.js');
112
112
  var upbit = require('./src/upbit.js');
113
113
  var wavesexchange = require('./src/wavesexchange.js');
114
114
  var whitebit = require('./src/whitebit.js');
@@ -185,7 +185,7 @@ var paradex$1 = require('./src/pro/paradex.js');
185
185
  var phemex$1 = require('./src/pro/phemex.js');
186
186
  var poloniex$1 = require('./src/pro/poloniex.js');
187
187
  var probit$1 = require('./src/pro/probit.js');
188
- var tradeogre$1 = require('./src/pro/tradeogre.js');
188
+ var toobit$1 = require('./src/pro/toobit.js');
189
189
  var upbit$1 = require('./src/pro/upbit.js');
190
190
  var whitebit$1 = require('./src/pro/whitebit.js');
191
191
  var woo$1 = require('./src/pro/woo.js');
@@ -194,7 +194,7 @@ var xt$1 = require('./src/pro/xt.js');
194
194
 
195
195
  //-----------------------------------------------------------------------------
196
196
  // this is updated by vss.js when building
197
- const version = '4.5.5';
197
+ const version = '4.5.6';
198
198
  Exchange["default"].ccxtVersion = version;
199
199
  const exchanges = {
200
200
  'alpaca': alpaca["default"],
@@ -293,7 +293,7 @@ const exchanges = {
293
293
  'probit': probit["default"],
294
294
  'timex': timex["default"],
295
295
  'tokocrypto': tokocrypto["default"],
296
- 'tradeogre': tradeogre["default"],
296
+ 'toobit': toobit["default"],
297
297
  'upbit': upbit["default"],
298
298
  'wavesexchange': wavesexchange["default"],
299
299
  'whitebit': whitebit["default"],
@@ -372,7 +372,7 @@ const pro = {
372
372
  'phemex': phemex$1["default"],
373
373
  'poloniex': poloniex$1["default"],
374
374
  'probit': probit$1["default"],
375
- 'tradeogre': tradeogre$1["default"],
375
+ 'toobit': toobit$1["default"],
376
376
  'upbit': upbit$1["default"],
377
377
  'whitebit': whitebit$1["default"],
378
378
  'woo': woo$1["default"],
@@ -526,7 +526,7 @@ exports.poloniex = poloniex["default"];
526
526
  exports.probit = probit["default"];
527
527
  exports.timex = timex["default"];
528
528
  exports.tokocrypto = tokocrypto["default"];
529
- exports.tradeogre = tradeogre["default"];
529
+ exports.toobit = toobit["default"];
530
530
  exports.upbit = upbit["default"];
531
531
  exports.wavesexchange = wavesexchange["default"];
532
532
  exports.whitebit = whitebit["default"];
@@ -0,0 +1,11 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, '__esModule', { value: true });
4
+
5
+ var Exchange$1 = require('../base/Exchange.js');
6
+
7
+ // -------------------------------------------------------------------------------
8
+ class Exchange extends Exchange$1["default"] {
9
+ }
10
+
11
+ exports["default"] = Exchange;
@@ -4,7 +4,7 @@ Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
5
  var Exchange$1 = require('../base/Exchange.js');
6
6
 
7
- // -------------------------------------------------------------------------------
7
+ // ----------------------------------------------------------------------------
8
8
  class Exchange extends Exchange$1["default"] {
9
9
  }
10
10
 
@@ -1913,7 +1913,7 @@ class backpack extends backpack$1["default"] {
1913
1913
  // "createdAt": 1753626206762,
1914
1914
  // "executedQuantity": "0",
1915
1915
  // "executedQuoteQuantity": "0",
1916
- // "id": "4228978330",
1916
+ // "id": "4228978331",
1917
1917
  // "orderType": "Limit",
1918
1918
  // "postOnly": true,
1919
1919
  // "price": "3000",
@@ -1424,7 +1424,7 @@ class Exchange {
1424
1424
  // ########################################################################
1425
1425
  // ########################################################################
1426
1426
  // ------------------------------------------------------------------------
1427
- // METHODS BELOW THIS LINE ARE TRANSPILED FROM JAVASCRIPT TO PYTHON AND PHP
1427
+ // METHODS BELOW THIS LINE ARE TRANSPILED FROM TYPESCRIPT
1428
1428
  describe() {
1429
1429
  return {
1430
1430
  'id': undefined,
@@ -2172,6 +2172,27 @@ class Exchange {
2172
2172
  this.isSandboxModeEnabled = false;
2173
2173
  }
2174
2174
  }
2175
+ /**
2176
+ * @method
2177
+ * @name Exchange#enableDemoTrading
2178
+ * @description enables or disables demo trading mode
2179
+ * @param {boolean} [enable] true if demo trading should be enabled, false otherwise
2180
+ */
2181
+ enableDemoTrading(enable) {
2182
+ if (this.isSandboxModeEnabled) {
2183
+ throw new errors.NotSupported(this.id + ' demo trading does not support in sandbox environment. Please check https://www.binance.com/en/support/faq/detail/9be58f73e5e14338809e3b705b9687dd to see the differences');
2184
+ }
2185
+ if (enable) {
2186
+ this.urls['apiBackupDemoTrading'] = this.urls['api'];
2187
+ this.urls['api'] = this.urls['demo'];
2188
+ }
2189
+ else if ('apiBackupDemoTrading' in this.urls) {
2190
+ this.urls['api'] = this.urls['apiBackupDemoTrading'];
2191
+ const newUrls = this.omit(this.urls, 'apiBackupDemoTrading');
2192
+ this.urls = newUrls;
2193
+ }
2194
+ this.options['enableDemoTrading'] = enable;
2195
+ }
2175
2196
  sign(path, api = 'public', method = 'GET', params = {}, headers = undefined, body = undefined) {
2176
2197
  return {};
2177
2198
  }
@@ -2626,6 +2647,97 @@ class Exchange {
2626
2647
  }
2627
2648
  return featuresObj;
2628
2649
  }
2650
+ featureValue(symbol, methodName = undefined, paramName = undefined, subParamName = undefined, defaultValue = undefined) {
2651
+ /**
2652
+ * @method
2653
+ * @name exchange#featureValue
2654
+ * @description this method is a very deterministic to help users to know what feature is supported by the exchange
2655
+ * @param {string} [symbol] unified symbol
2656
+ * @param {string} [methodName] view currently supported methods: https://docs.ccxt.com/#/README?id=features
2657
+ * @param {string} [paramName] unified param value (check docs for supported param names)
2658
+ * @param {string} [subParamName] unified sub-param value (eg. stopLoss->triggerPriceType)
2659
+ * @param {object} [defaultValue] return default value if no result found
2660
+ * @returns {object} returns feature value
2661
+ */
2662
+ const market = this.market(symbol);
2663
+ return this.featureValueByType(market['type'], market['subType'], methodName, paramName, subParamName, defaultValue);
2664
+ }
2665
+ featureValueByType(marketType, subType, methodName = undefined, paramName = undefined, subParamName = undefined, defaultValue = undefined) {
2666
+ /**
2667
+ * @method
2668
+ * @name exchange#featureValueByType
2669
+ * @description this method is a very deterministic to help users to know what feature is supported by the exchange
2670
+ * @param {string} [marketType] supported only: "spot", "swap", "future"
2671
+ * @param {string} [subType] supported only: "linear", "inverse"
2672
+ * @param {string} [methodName] view currently supported methods: https://docs.ccxt.com/#/README?id=features
2673
+ * @param {string} [paramName] unified param value (check docs for supported param names)
2674
+ * @param {string} [subParamName] unified sub-param value (eg. stopLoss->triggerPriceType)
2675
+ * @param {object} [defaultValue] return default value if no result found
2676
+ * @returns {object} returns feature value
2677
+ */
2678
+ // if exchange does not yet have features manually implemented
2679
+ if (this.features === undefined) {
2680
+ return defaultValue;
2681
+ }
2682
+ // if marketType (e.g. 'option') does not exist in features
2683
+ if (!(marketType in this.features)) {
2684
+ return defaultValue; // unsupported marketType, check "exchange.features" for details
2685
+ }
2686
+ // if marketType dict undefined
2687
+ if (this.features[marketType] === undefined) {
2688
+ return defaultValue;
2689
+ }
2690
+ let methodsContainer = this.features[marketType];
2691
+ if (subType === undefined) {
2692
+ if (marketType !== 'spot') {
2693
+ return defaultValue; // subType is required for non-spot markets
2694
+ }
2695
+ }
2696
+ else {
2697
+ if (!(subType in this.features[marketType])) {
2698
+ return defaultValue; // unsupported subType, check "exchange.features" for details
2699
+ }
2700
+ // if subType dict undefined
2701
+ if (this.features[marketType][subType] === undefined) {
2702
+ return defaultValue;
2703
+ }
2704
+ methodsContainer = this.features[marketType][subType];
2705
+ }
2706
+ // if user wanted only marketType and didn't provide methodName, eg: featureIsSupported('spot')
2707
+ if (methodName === undefined) {
2708
+ return methodsContainer;
2709
+ }
2710
+ if (!(methodName in methodsContainer)) {
2711
+ return defaultValue; // unsupported method, check "exchange.features" for details');
2712
+ }
2713
+ const methodDict = methodsContainer[methodName];
2714
+ if (methodDict === undefined) {
2715
+ return defaultValue;
2716
+ }
2717
+ // if user wanted only method and didn't provide `paramName`, eg: featureIsSupported('swap', 'linear', 'createOrder')
2718
+ if (paramName === undefined) {
2719
+ return methodDict;
2720
+ }
2721
+ if (!(paramName in methodDict)) {
2722
+ return defaultValue; // unsupported paramName, check "exchange.features" for details');
2723
+ }
2724
+ const dictionary = this.safeDict(methodDict, paramName);
2725
+ if (dictionary === undefined) {
2726
+ // if the value is not dictionary but a scalar value (or undefined), return as is
2727
+ return methodDict[paramName];
2728
+ }
2729
+ else {
2730
+ // return as is, when calling without `subParamName` eg: featureValueByType('spot', undefined, 'createOrder', 'stopLoss')
2731
+ if (subParamName === undefined) {
2732
+ return methodDict[paramName];
2733
+ }
2734
+ // throw an exception for unsupported subParamName
2735
+ if (!(subParamName in methodDict[paramName])) {
2736
+ return defaultValue; // unsupported subParamName, check "exchange.features" for details
2737
+ }
2738
+ return methodDict[paramName][subParamName];
2739
+ }
2740
+ }
2629
2741
  orderbookChecksumMessage(symbol) {
2630
2742
  return symbol + ' : ' + 'orderbook data checksum validation failed. You can reconnect by calling watchOrderBook again or you can mute the error by setting exchange.options["watchOrderBook"]["checksum"] = false';
2631
2743
  }
@@ -2930,7 +3042,12 @@ class Exchange {
2930
3042
  const marketsSortedById = this.keysort(this.markets_by_id);
2931
3043
  this.symbols = Object.keys(marketsSortedBySymbol);
2932
3044
  this.ids = Object.keys(marketsSortedById);
3045
+ let numCurrencies = 0;
2933
3046
  if (currencies !== undefined) {
3047
+ const keys = Object.keys(currencies);
3048
+ numCurrencies = keys.length;
3049
+ }
3050
+ if (numCurrencies > 0) {
2934
3051
  // currencies is always undefined when called in constructor but not when called from loadMarkets
2935
3052
  this.currencies = this.mapToSafeMap(this.deepExtend(this.currencies, currencies));
2936
3053
  }
@@ -3009,6 +3126,14 @@ class Exchange {
3009
3126
  this.baseCurrencies = sourceExchange.baseCurrencies;
3010
3127
  this.quoteCurrencies = sourceExchange.quoteCurrencies;
3011
3128
  this.codes = sourceExchange.codes;
3129
+ // check marketHelperProps
3130
+ const sourceExchangeHelpers = this.safeList(sourceExchange.options, 'marketHelperProps', []);
3131
+ for (let i = 0; i < sourceExchangeHelpers.length; i++) {
3132
+ const helper = sourceExchangeHelpers[i];
3133
+ if (sourceExchange.options[helper] !== undefined) {
3134
+ this.options[helper] = sourceExchange.options[helper];
3135
+ }
3136
+ }
3012
3137
  return this;
3013
3138
  }
3014
3139
  getDescribeForExtendedWsExchange(currentRestInstance, parentRestInstance, wsBaseDescribe) {
@@ -5750,7 +5875,9 @@ class Exchange {
5750
5875
  return this.safeString(this.commonCurrencies, code, code);
5751
5876
  }
5752
5877
  currency(code) {
5753
- if (this.currencies === undefined) {
5878
+ const keys = Object.keys(this.currencies);
5879
+ const numCurrencies = keys.length;
5880
+ if (numCurrencies === 0) {
5754
5881
  throw new errors.ExchangeError(this.id + ' currencies not loaded');
5755
5882
  }
5756
5883
  if (typeof code === 'string') {
@@ -27,7 +27,7 @@ class bigone extends bigone$1["default"] {
27
27
  'CORS': undefined,
28
28
  'spot': true,
29
29
  'margin': false,
30
- 'swap': undefined,
30
+ 'swap': true,
31
31
  'future': undefined,
32
32
  'option': false,
33
33
  'cancelAllOrders': true,
@@ -451,7 +451,7 @@ class bigone extends bigone$1["default"] {
451
451
  // we use undocumented link (possible, less informative alternative is : https://big.one/api/uc/v3/assets/accounts)
452
452
  const data = await this.fetchWebEndpoint('fetchCurrencies', 'webExchangeGetV3Assets', true);
453
453
  if (data === undefined) {
454
- return undefined;
454
+ return {};
455
455
  }
456
456
  //
457
457
  // {
@@ -1256,7 +1256,7 @@ class bigone extends bigone$1["default"] {
1256
1256
  await this.loadMarkets();
1257
1257
  const market = this.market(symbol);
1258
1258
  if (market['contract']) {
1259
- throw new errors.BadRequest(this.id + ' fetchTrades () can only fetch trades for spot markets');
1259
+ throw new errors.NotSupported(this.id + ' fetchTrades () can only fetch trades for spot markets');
1260
1260
  }
1261
1261
  const request = {
1262
1262
  'asset_pair_name': market['id'],
@@ -1323,7 +1323,7 @@ class bigone extends bigone$1["default"] {
1323
1323
  await this.loadMarkets();
1324
1324
  const market = this.market(symbol);
1325
1325
  if (market['contract']) {
1326
- throw new errors.BadRequest(this.id + ' fetchOHLCV () can only fetch ohlcvs for spot markets');
1326
+ throw new errors.NotSupported(this.id + ' fetchOHLCV () can only fetch ohlcvs for spot markets');
1327
1327
  }
1328
1328
  const until = this.safeInteger(params, 'until');
1329
1329
  const untilIsDefined = (until !== undefined);
@@ -207,6 +207,20 @@ class binance extends binance$1["default"] {
207
207
  'private': 'https://testnet.binance.vision/api/v3',
208
208
  'v1': 'https://testnet.binance.vision/api/v1',
209
209
  },
210
+ 'demo': {
211
+ 'dapiPublic': 'https://demo-dapi.binance.com/dapi/v1',
212
+ 'dapiPrivate': 'https://demo-dapi.binance.com/dapi/v1',
213
+ 'dapiPrivateV2': 'https://demo-dapi.binance.com/dapi/v2',
214
+ 'fapiPublic': 'https://demo-fapi.binance.com/fapi/v1',
215
+ 'fapiPublicV2': 'https://demo-fapi.binance.com/fapi/v2',
216
+ 'fapiPublicV3': 'https://demo-fapi.binance.com/fapi/v3',
217
+ 'fapiPrivate': 'https://demo-fapi.binance.com/fapi/v1',
218
+ 'fapiPrivateV2': 'https://demo-fapi.binance.com/fapi/v2',
219
+ 'fapiPrivateV3': 'https://demo-fapi.binance.com/fapi/v3',
220
+ 'public': 'https://demo-api.binance.com/api/v3',
221
+ 'private': 'https://demo-api.binance.com/api/v3',
222
+ 'v1': 'https://demo-api.binance.com/api/v1',
223
+ },
210
224
  'api': {
211
225
  'sapi': 'https://api.binance.com/sapi/v1',
212
226
  'sapiV2': 'https://api.binance.com/sapi/v2',
@@ -1392,6 +1406,9 @@ class binance extends binance$1["default"] {
1392
1406
  'features': {
1393
1407
  'spot': {
1394
1408
  'sandbox': true,
1409
+ 'fetchCurrencies': {
1410
+ 'private': true,
1411
+ },
1395
1412
  'createOrder': {
1396
1413
  'marginMode': true,
1397
1414
  'triggerPrice': true,
@@ -2758,6 +2775,29 @@ class binance extends binance$1["default"] {
2758
2775
  nonce() {
2759
2776
  return this.milliseconds() - this.options['timeDifference'];
2760
2777
  }
2778
+ /**
2779
+ * @method
2780
+ * @name binance#enableDemoTrading
2781
+ * @description enables or disables demo trading mode
2782
+ * @see https://www.binance.com/en/support/faq/detail/9be58f73e5e14338809e3b705b9687dd
2783
+ * @see https://demo.binance.com/en/my/settings/api-management
2784
+ * @param {boolean} [enable] true if demo trading should be enabled, false otherwise
2785
+ */
2786
+ enableDemoTrading(enable) {
2787
+ if (this.isSandboxModeEnabled) {
2788
+ throw new errors.NotSupported(this.id + ' demo trading is not supported in the sandbox environment. Please check https://www.binance.com/en/support/faq/detail/9be58f73e5e14338809e3b705b9687dd to see the differences');
2789
+ }
2790
+ if (enable) {
2791
+ this.urls['apiBackupDemoTrading'] = this.urls['api'];
2792
+ this.urls['api'] = this.urls['demo'];
2793
+ }
2794
+ else if ('apiBackupDemoTrading' in this.urls) {
2795
+ this.urls['api'] = this.urls['apiBackupDemoTrading'];
2796
+ const newUrls = this.omit(this.urls, 'apiBackupDemoTrading');
2797
+ this.urls = newUrls;
2798
+ }
2799
+ this.options['enableDemoTrading'] = enable;
2800
+ }
2761
2801
  /**
2762
2802
  * @method
2763
2803
  * @name binance#fetchTime
@@ -2799,19 +2839,23 @@ class binance extends binance$1["default"] {
2799
2839
  async fetchCurrencies(params = {}) {
2800
2840
  const fetchCurrenciesEnabled = this.safeBool(this.options, 'fetchCurrencies');
2801
2841
  if (!fetchCurrenciesEnabled) {
2802
- return undefined;
2842
+ return {};
2803
2843
  }
2804
2844
  // this endpoint requires authentication
2805
2845
  // while fetchCurrencies is a public API method by design
2806
2846
  // therefore we check the keys here
2807
2847
  // and fallback to generating the currencies from the markets
2808
2848
  if (!this.checkRequiredCredentials(false)) {
2809
- return undefined;
2849
+ return {};
2810
2850
  }
2811
2851
  // sandbox/testnet does not support sapi endpoints
2812
2852
  const apiBackup = this.safeValue(this.urls, 'apiBackup');
2813
2853
  if (apiBackup !== undefined) {
2814
- return undefined;
2854
+ return {};
2855
+ }
2856
+ // demotrading does not support sapi endpoints
2857
+ if (this.safeBool(this.options, 'enableDemoTrading', false)) {
2858
+ return {};
2815
2859
  }
2816
2860
  const promises = [this.sapiGetCapitalConfigGetall(params)];
2817
2861
  const fetchMargins = this.safeBool(this.options, 'fetchMargins', false);
@@ -2885,7 +2929,7 @@ class binance extends binance$1["default"] {
2885
2929
  // "addressRegex": "^(bnb1)[0-9a-z]{38}$",
2886
2930
  // "addressRule": "",
2887
2931
  // "memoRegex": "^[0-9A-Za-z\\-_]{1,120}$",
2888
- // "withdrawFee": "0.002",
2932
+ // "withdrawFee": "0.003",
2889
2933
  // "withdrawMin": "0.01",
2890
2934
  // "withdrawMax": "10000000000",
2891
2935
  // "minConfirm": "1",
@@ -3056,10 +3100,12 @@ class binance extends binance$1["default"] {
3056
3100
  }
3057
3101
  }
3058
3102
  const sandboxMode = this.safeBool(this.options, 'sandboxMode', false);
3103
+ const demoMode = this.safeBool(this.options, 'enableDemoTrading', false);
3104
+ const isDemoEnv = demoMode || sandboxMode;
3059
3105
  const fetchMarkets = [];
3060
3106
  for (let i = 0; i < rawFetchMarkets.length; i++) {
3061
3107
  const type = rawFetchMarkets[i];
3062
- if (type === 'option' && sandboxMode) {
3108
+ if (type === 'option' && isDemoEnv) {
3063
3109
  continue;
3064
3110
  }
3065
3111
  fetchMarkets.push(type);
@@ -3069,7 +3115,7 @@ class binance extends binance$1["default"] {
3069
3115
  const marketType = fetchMarkets[i];
3070
3116
  if (marketType === 'spot') {
3071
3117
  promisesRaw.push(this.publicGetExchangeInfo(params));
3072
- if (fetchMargins && this.checkRequiredCredentials(false) && !sandboxMode) {
3118
+ if (fetchMargins && this.checkRequiredCredentials(false) && !isDemoEnv) {
3073
3119
  promisesRaw.push(this.sapiGetMarginAllPairs(params));
3074
3120
  promisesRaw.push(this.sapiGetMarginIsolatedAllPairs(params));
3075
3121
  }
@@ -6400,6 +6446,7 @@ class binance extends binance$1["default"] {
6400
6446
  const isConditional = isTriggerOrder || isTrailingPercentOrder || isStopLoss || isTakeProfit;
6401
6447
  const isPortfolioMarginConditional = (isPortfolioMargin && isConditional);
6402
6448
  const isPriceMatch = priceMatch !== undefined;
6449
+ let priceRequiredForTrailing = true;
6403
6450
  let uppercaseType = type.toUpperCase();
6404
6451
  let stopPrice = undefined;
6405
6452
  if (isTrailingPercentOrder) {
@@ -6411,19 +6458,31 @@ class binance extends binance$1["default"] {
6411
6458
  }
6412
6459
  }
6413
6460
  else {
6414
- if (isMarketOrder) {
6415
- throw new errors.InvalidOrder(this.id + ' trailingPercent orders are not supported for ' + symbol + ' ' + type + ' orders');
6416
- }
6417
- const stopLossOrTakeProfit = this.safeString(params, 'stopLossOrTakeProfit');
6418
- params = this.omit(params, 'stopLossOrTakeProfit');
6419
- if (stopLossOrTakeProfit !== 'stopLoss' && stopLossOrTakeProfit !== 'takeProfit') {
6420
- throw new errors.InvalidOrder(this.id + symbol + ' trailingPercent orders require a stopLossOrTakeProfit parameter of either stopLoss or takeProfit');
6421
- }
6422
- if (stopLossOrTakeProfit === 'stopLoss') {
6423
- uppercaseType = 'STOP_LOSS_LIMIT';
6461
+ if ((uppercaseType !== 'STOP_LOSS') && (uppercaseType !== 'TAKE_PROFIT') && (uppercaseType !== 'STOP_LOSS_LIMIT') && (uppercaseType !== 'TAKE_PROFIT_LIMIT')) {
6462
+ const stopLossOrTakeProfit = this.safeString(params, 'stopLossOrTakeProfit');
6463
+ params = this.omit(params, 'stopLossOrTakeProfit');
6464
+ if ((stopLossOrTakeProfit !== 'stopLoss') && (stopLossOrTakeProfit !== 'takeProfit')) {
6465
+ throw new errors.InvalidOrder(this.id + symbol + ' trailingPercent orders require a stopLossOrTakeProfit parameter of either stopLoss or takeProfit');
6466
+ }
6467
+ if (isMarketOrder) {
6468
+ if (stopLossOrTakeProfit === 'stopLoss') {
6469
+ uppercaseType = 'STOP_LOSS';
6470
+ }
6471
+ else if (stopLossOrTakeProfit === 'takeProfit') {
6472
+ uppercaseType = 'TAKE_PROFIT';
6473
+ }
6474
+ }
6475
+ else {
6476
+ if (stopLossOrTakeProfit === 'stopLoss') {
6477
+ uppercaseType = 'STOP_LOSS_LIMIT';
6478
+ }
6479
+ else if (stopLossOrTakeProfit === 'takeProfit') {
6480
+ uppercaseType = 'TAKE_PROFIT_LIMIT';
6481
+ }
6482
+ }
6424
6483
  }
6425
- else if (stopLossOrTakeProfit === 'takeProfit') {
6426
- uppercaseType = 'TAKE_PROFIT_LIMIT';
6484
+ if ((uppercaseType === 'STOP_LOSS') || (uppercaseType === 'TAKE_PROFIT')) {
6485
+ priceRequiredForTrailing = false;
6427
6486
  }
6428
6487
  if (trailingTriggerPrice !== undefined) {
6429
6488
  stopPrice = this.priceToPrecision(symbol, trailingTriggerPrice);
@@ -6577,7 +6636,7 @@ class binance extends binance$1["default"] {
6577
6636
  else if ((uppercaseType === 'STOP_LOSS') || (uppercaseType === 'TAKE_PROFIT')) {
6578
6637
  triggerPriceIsRequired = true;
6579
6638
  quantityIsRequired = true;
6580
- if (market['linear'] || market['inverse']) {
6639
+ if ((market['linear'] || market['inverse']) && priceRequiredForTrailing) {
6581
6640
  priceIsRequired = true;
6582
6641
  }
6583
6642
  }
@@ -11866,7 +11925,7 @@ class binance extends binance$1["default"] {
11866
11925
  // "asset": "USDT",
11867
11926
  // "amount": "-0.16518203",
11868
11927
  // "type": "FEE",
11869
- // "createDate": 1676621042489
11928
+ // "createDate": 167662104241
11870
11929
  // }
11871
11930
  //
11872
11931
  // futures (fapi, dapi, papi)
@@ -666,6 +666,9 @@ class bingx extends bingx$1["default"] {
666
666
  //
667
667
  'spot': {
668
668
  'extends': 'defaultForLinear',
669
+ 'fetchCurrencies': {
670
+ 'private': true,
671
+ },
669
672
  'createOrder': {
670
673
  'triggerPriceType': undefined,
671
674
  'attachedStopLossTakeProfit': undefined,
@@ -737,11 +740,11 @@ class bingx extends bingx$1["default"] {
737
740
  */
738
741
  async fetchCurrencies(params = {}) {
739
742
  if (!this.checkRequiredCredentials(false)) {
740
- return undefined;
743
+ return {};
741
744
  }
742
745
  const isSandbox = this.safeBool(this.options, 'sandboxMode', false);
743
746
  if (isSandbox) {
744
- return undefined;
747
+ return {};
745
748
  }
746
749
  const response = await this.walletsV1PrivateGetCapitalConfigGetall(params);
747
750
  //
@@ -1326,6 +1326,8 @@ class bitget extends bitget$1["default"] {
1326
1326
  '43025': errors.InvalidOrder,
1327
1327
  '43115': errors.OnMaintenance,
1328
1328
  '45110': errors.InvalidOrder,
1329
+ '40774': errors.InvalidOrder,
1330
+ '45122': errors.InvalidOrder,
1329
1331
  // spot
1330
1332
  'invalid sign': errors.AuthenticationError,
1331
1333
  'invalid currency': errors.BadSymbol,
@@ -5247,6 +5249,14 @@ class bitget extends bitget$1["default"] {
5247
5249
  'symbol': market['id'],
5248
5250
  'orderType': type,
5249
5251
  };
5252
+ let hedged = undefined;
5253
+ [hedged, params] = this.handleParamBool(params, 'hedged', false);
5254
+ // backward compatibility for `oneWayMode`
5255
+ let oneWayMode = undefined;
5256
+ [oneWayMode, params] = this.handleParamBool(params, 'oneWayMode');
5257
+ if (oneWayMode !== undefined) {
5258
+ hedged = !oneWayMode;
5259
+ }
5250
5260
  const isMarketOrder = type === 'market';
5251
5261
  const triggerPrice = this.safeValue2(params, 'stopPrice', 'triggerPrice');
5252
5262
  const stopLossTriggerPrice = this.safeValue(params, 'stopLossPrice');
@@ -5340,7 +5350,12 @@ class bitget extends bitget$1["default"] {
5340
5350
  if (!isMarketOrder) {
5341
5351
  throw new errors.ExchangeError(this.id + ' createOrder() bitget stopLoss or takeProfit orders must be market orders');
5342
5352
  }
5343
- request['holdSide'] = (side === 'buy') ? 'long' : 'short';
5353
+ if (hedged) {
5354
+ request['holdSide'] = (side === 'sell') ? 'long' : 'short';
5355
+ }
5356
+ else {
5357
+ request['holdSide'] = (side === 'sell') ? 'buy' : 'sell';
5358
+ }
5344
5359
  if (isStopLossTriggerOrder) {
5345
5360
  request['triggerPrice'] = this.priceToPrecision(symbol, stopLossTriggerPrice);
5346
5361
  request['planType'] = 'pos_loss';
@@ -5366,14 +5381,6 @@ class bitget extends bitget$1["default"] {
5366
5381
  }
5367
5382
  const marginModeRequest = (marginMode === 'cross') ? 'crossed' : 'isolated';
5368
5383
  request['marginMode'] = marginModeRequest;
5369
- let hedged = undefined;
5370
- [hedged, params] = this.handleParamBool(params, 'hedged', false);
5371
- // backward compatibility for `oneWayMode`
5372
- let oneWayMode = undefined;
5373
- [oneWayMode, params] = this.handleParamBool(params, 'oneWayMode');
5374
- if (oneWayMode !== undefined) {
5375
- hedged = !oneWayMode;
5376
- }
5377
5384
  let requestSide = side;
5378
5385
  if (reduceOnly) {
5379
5386
  if (!hedged) {