ccxt 4.2.38 → 4.2.40

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 (127) hide show
  1. package/README.md +3 -3
  2. package/dist/ccxt.browser.js +1340 -407
  3. package/dist/ccxt.browser.min.js +3 -3
  4. package/dist/cjs/ccxt.js +1 -1
  5. package/dist/cjs/src/ascendex.js +28 -24
  6. package/dist/cjs/src/base/Exchange.js +28 -16
  7. package/dist/cjs/src/binance.js +528 -181
  8. package/dist/cjs/src/bingx.js +250 -23
  9. package/dist/cjs/src/bitget.js +14 -3
  10. package/dist/cjs/src/bitso.js +18 -2
  11. package/dist/cjs/src/bitstamp.js +24 -2
  12. package/dist/cjs/src/bl3p.js +6 -0
  13. package/dist/cjs/src/blockchaincom.js +21 -0
  14. package/dist/cjs/src/btcalpha.js +9 -0
  15. package/dist/cjs/src/btcbox.js +9 -0
  16. package/dist/cjs/src/btcmarkets.js +19 -0
  17. package/dist/cjs/src/bybit.js +3 -1
  18. package/dist/cjs/src/coinbase.js +21 -8
  19. package/dist/cjs/src/coinbasepro.js +1 -0
  20. package/dist/cjs/src/coinlist.js +9 -7
  21. package/dist/cjs/src/coinmetro.js +2 -1
  22. package/dist/cjs/src/krakenfutures.js +133 -16
  23. package/dist/cjs/src/luno.js +1 -1
  24. package/dist/cjs/src/mexc.js +43 -43
  25. package/dist/cjs/src/okx.js +11 -17
  26. package/dist/cjs/src/phemex.js +1 -0
  27. package/dist/cjs/src/poloniexfutures.js +11 -5
  28. package/dist/cjs/src/pro/bitmart.js +141 -48
  29. package/dist/cjs/src/pro/bybit.js +5 -5
  30. package/dist/cjs/src/pro/mexc.js +1 -1
  31. package/dist/cjs/src/wavesexchange.js +1 -1
  32. package/dist/cjs/src/woo.js +1 -1
  33. package/js/ccxt.d.ts +1 -1
  34. package/js/ccxt.js +1 -1
  35. package/js/src/abstract/bingx.d.ts +4 -0
  36. package/js/src/abstract/coinbase.d.ts +1 -0
  37. package/js/src/abstract/coinbasepro.d.ts +1 -0
  38. package/js/src/abstract/okx.d.ts +1 -0
  39. package/js/src/ascendex.d.ts +2 -2
  40. package/js/src/ascendex.js +28 -24
  41. package/js/src/base/Exchange.d.ts +12 -8
  42. package/js/src/base/Exchange.js +28 -16
  43. package/js/src/base/types.d.ts +2 -0
  44. package/js/src/bigone.d.ts +2 -2
  45. package/js/src/binance.d.ts +9 -9
  46. package/js/src/binance.js +528 -181
  47. package/js/src/bingx.d.ts +6 -5
  48. package/js/src/bingx.js +250 -23
  49. package/js/src/bitfinex.d.ts +3 -3
  50. package/js/src/bitfinex2.d.ts +2 -2
  51. package/js/src/bitget.d.ts +5 -5
  52. package/js/src/bitget.js +14 -3
  53. package/js/src/bitmart.d.ts +2 -2
  54. package/js/src/bitmex.d.ts +2 -2
  55. package/js/src/bitrue.d.ts +2 -2
  56. package/js/src/bitso.d.ts +1 -1
  57. package/js/src/bitso.js +18 -2
  58. package/js/src/bitstamp.d.ts +1 -1
  59. package/js/src/bitstamp.js +24 -2
  60. package/js/src/bitvavo.d.ts +1 -1
  61. package/js/src/bl3p.js +6 -0
  62. package/js/src/blockchaincom.js +21 -0
  63. package/js/src/blofin.d.ts +2 -2
  64. package/js/src/btcalpha.js +9 -0
  65. package/js/src/btcbox.js +9 -0
  66. package/js/src/btcmarkets.js +19 -0
  67. package/js/src/bybit.d.ts +7 -7
  68. package/js/src/bybit.js +3 -1
  69. package/js/src/cex.d.ts +1 -1
  70. package/js/src/coinbase.d.ts +2 -2
  71. package/js/src/coinbase.js +21 -8
  72. package/js/src/coinbasepro.js +1 -0
  73. package/js/src/coinex.d.ts +4 -4
  74. package/js/src/coinlist.d.ts +2 -2
  75. package/js/src/coinlist.js +9 -7
  76. package/js/src/coinmetro.js +2 -1
  77. package/js/src/coinone.d.ts +1 -1
  78. package/js/src/delta.d.ts +2 -2
  79. package/js/src/deribit.d.ts +3 -3
  80. package/js/src/digifinex.d.ts +3 -3
  81. package/js/src/exmo.d.ts +2 -2
  82. package/js/src/gate.d.ts +6 -6
  83. package/js/src/hitbtc.d.ts +2 -2
  84. package/js/src/hollaex.d.ts +1 -1
  85. package/js/src/htx.d.ts +3 -3
  86. package/js/src/huobijp.d.ts +1 -1
  87. package/js/src/kraken.d.ts +2 -2
  88. package/js/src/krakenfutures.d.ts +4 -2
  89. package/js/src/krakenfutures.js +133 -16
  90. package/js/src/kucoin.d.ts +5 -5
  91. package/js/src/kucoinfutures.d.ts +2 -2
  92. package/js/src/latoken.d.ts +1 -1
  93. package/js/src/lbank.d.ts +2 -2
  94. package/js/src/luno.d.ts +1 -1
  95. package/js/src/luno.js +1 -1
  96. package/js/src/mexc.d.ts +4 -4
  97. package/js/src/mexc.js +43 -43
  98. package/js/src/ndax.d.ts +1 -1
  99. package/js/src/novadax.d.ts +1 -1
  100. package/js/src/okcoin.d.ts +2 -2
  101. package/js/src/okx.d.ts +7 -7
  102. package/js/src/okx.js +11 -17
  103. package/js/src/paymium.d.ts +2 -2
  104. package/js/src/phemex.d.ts +4 -4
  105. package/js/src/phemex.js +1 -0
  106. package/js/src/poloniex.d.ts +2 -2
  107. package/js/src/poloniexfutures.d.ts +2 -2
  108. package/js/src/poloniexfutures.js +11 -5
  109. package/js/src/pro/bitmart.d.ts +4 -0
  110. package/js/src/pro/bitmart.js +141 -48
  111. package/js/src/pro/bitvavo.d.ts +1 -1
  112. package/js/src/pro/bybit.d.ts +1 -1
  113. package/js/src/pro/bybit.js +5 -5
  114. package/js/src/pro/cex.d.ts +2 -2
  115. package/js/src/pro/coinbase.d.ts +2 -2
  116. package/js/src/pro/coinex.d.ts +1 -1
  117. package/js/src/pro/lbank.d.ts +1 -1
  118. package/js/src/pro/mexc.js +1 -1
  119. package/js/src/probit.d.ts +1 -1
  120. package/js/src/timex.d.ts +1 -1
  121. package/js/src/upbit.d.ts +1 -1
  122. package/js/src/wavesexchange.js +1 -1
  123. package/js/src/whitebit.d.ts +2 -2
  124. package/js/src/woo.d.ts +3 -3
  125. package/js/src/woo.js +1 -1
  126. package/js/src/zonda.d.ts +3 -3
  127. package/package.json +2 -2
package/js/src/binance.js CHANGED
@@ -2652,7 +2652,7 @@ export default class binance extends Exchange {
2652
2652
  let minPrecision = undefined;
2653
2653
  let isWithdrawEnabled = true;
2654
2654
  let isDepositEnabled = true;
2655
- const networkList = this.safeValue(entry, 'networkList', []);
2655
+ const networkList = this.safeList(entry, 'networkList', []);
2656
2656
  const fees = {};
2657
2657
  let fee = undefined;
2658
2658
  for (let j = 0; j < networkList.length; j++) {
@@ -2660,12 +2660,12 @@ export default class binance extends Exchange {
2660
2660
  const network = this.safeString(networkItem, 'network');
2661
2661
  // const name = this.safeString (networkItem, 'name');
2662
2662
  const withdrawFee = this.safeNumber(networkItem, 'withdrawFee');
2663
- const depositEnable = this.safeValue(networkItem, 'depositEnable');
2664
- const withdrawEnable = this.safeValue(networkItem, 'withdrawEnable');
2663
+ const depositEnable = this.safeBool(networkItem, 'depositEnable');
2664
+ const withdrawEnable = this.safeBool(networkItem, 'withdrawEnable');
2665
2665
  isDepositEnabled = isDepositEnabled || depositEnable;
2666
2666
  isWithdrawEnabled = isWithdrawEnabled || withdrawEnable;
2667
2667
  fees[network] = withdrawFee;
2668
- const isDefault = this.safeValue(networkItem, 'isDefault');
2668
+ const isDefault = this.safeBool(networkItem, 'isDefault');
2669
2669
  if (isDefault || (fee === undefined)) {
2670
2670
  fee = withdrawFee;
2671
2671
  }
@@ -2676,7 +2676,7 @@ export default class binance extends Exchange {
2676
2676
  minPrecision = (minPrecision === undefined) ? precisionTick : Precise.stringMin(minPrecision, precisionTick);
2677
2677
  }
2678
2678
  }
2679
- const trading = this.safeValue(entry, 'trading');
2679
+ const trading = this.safeBool(entry, 'trading');
2680
2680
  const active = (isWithdrawEnabled && isDepositEnabled && trading);
2681
2681
  let maxDecimalPlaces = undefined;
2682
2682
  if (minPrecision !== undefined) {
@@ -2712,8 +2712,8 @@ export default class binance extends Exchange {
2712
2712
  * @returns {object[]} an array of objects representing market data
2713
2713
  */
2714
2714
  const promisesRaw = [];
2715
- const rawFetchMarkets = this.safeValue(this.options, 'fetchMarkets', ['spot', 'linear', 'inverse']);
2716
- const sandboxMode = this.safeValue(this.options, 'sandboxMode', false);
2715
+ const rawFetchMarkets = this.safeList(this.options, 'fetchMarkets', ['spot', 'linear', 'inverse']);
2716
+ const sandboxMode = this.safeBool(this.options, 'sandboxMode', false);
2717
2717
  const fetchMarkets = [];
2718
2718
  for (let i = 0; i < rawFetchMarkets.length; i++) {
2719
2719
  const type = rawFetchMarkets[i];
@@ -2991,7 +2991,7 @@ export default class binance extends Exchange {
2991
2991
  }
2992
2992
  const settle = this.safeCurrencyCode(settleId);
2993
2993
  const spot = !contract;
2994
- const filters = this.safeValue(market, 'filters', []);
2994
+ const filters = this.safeList(market, 'filters', []);
2995
2995
  const filtersByType = this.indexBy(filters, 'filterType');
2996
2996
  const status = this.safeString2(market, 'status', 'contractStatus');
2997
2997
  let contractSize = undefined;
@@ -3014,11 +3014,11 @@ export default class binance extends Exchange {
3014
3014
  linear = settle === quote;
3015
3015
  inverse = settle === base;
3016
3016
  const feesType = linear ? 'linear' : 'inverse';
3017
- fees = this.safeValue(this.fees, feesType, {});
3017
+ fees = this.safeDict(this.fees, feesType, {});
3018
3018
  }
3019
3019
  let active = (status === 'TRADING');
3020
3020
  if (spot) {
3021
- const permissions = this.safeValue(market, 'permissions', []);
3021
+ const permissions = this.safeList(market, 'permissions', []);
3022
3022
  for (let j = 0; j < permissions.length; j++) {
3023
3023
  if (permissions[j] === 'TRD_GRP_003') {
3024
3024
  active = false;
@@ -3096,7 +3096,7 @@ export default class binance extends Exchange {
3096
3096
  'created': this.safeInteger(market, 'onboardDate'), // present in inverse & linear apis
3097
3097
  };
3098
3098
  if ('PRICE_FILTER' in filtersByType) {
3099
- const filter = this.safeValue(filtersByType, 'PRICE_FILTER', {});
3099
+ const filter = this.safeDict(filtersByType, 'PRICE_FILTER', {});
3100
3100
  // PRICE_FILTER reports zero values for maxPrice
3101
3101
  // since they updated filter types in November 2018
3102
3102
  // https://github.com/ccxt/ccxt/issues/4286
@@ -3108,7 +3108,7 @@ export default class binance extends Exchange {
3108
3108
  entry['precision']['price'] = this.precisionFromString(filter['tickSize']);
3109
3109
  }
3110
3110
  if ('LOT_SIZE' in filtersByType) {
3111
- const filter = this.safeValue(filtersByType, 'LOT_SIZE', {});
3111
+ const filter = this.safeDict(filtersByType, 'LOT_SIZE', {});
3112
3112
  const stepSize = this.safeString(filter, 'stepSize');
3113
3113
  entry['precision']['amount'] = this.precisionFromString(stepSize);
3114
3114
  entry['limits']['amount'] = {
@@ -3117,14 +3117,14 @@ export default class binance extends Exchange {
3117
3117
  };
3118
3118
  }
3119
3119
  if ('MARKET_LOT_SIZE' in filtersByType) {
3120
- const filter = this.safeValue(filtersByType, 'MARKET_LOT_SIZE', {});
3120
+ const filter = this.safeDict(filtersByType, 'MARKET_LOT_SIZE', {});
3121
3121
  entry['limits']['market'] = {
3122
3122
  'min': this.safeNumber(filter, 'minQty'),
3123
3123
  'max': this.safeNumber(filter, 'maxQty'),
3124
3124
  };
3125
3125
  }
3126
3126
  if (('MIN_NOTIONAL' in filtersByType) || ('NOTIONAL' in filtersByType)) { // notional added in 12/04/23 to spot testnet
3127
- const filter = this.safeValue2(filtersByType, 'MIN_NOTIONAL', 'NOTIONAL', {});
3127
+ const filter = this.safeDict2(filtersByType, 'MIN_NOTIONAL', 'NOTIONAL', {});
3128
3128
  entry['limits']['cost']['min'] = this.safeNumber2(filter, 'minNotional', 'notional');
3129
3129
  entry['limits']['cost']['max'] = this.safeNumber(filter, 'maxNotional');
3130
3130
  }
@@ -3818,7 +3818,7 @@ export default class binance extends Exchange {
3818
3818
  }
3819
3819
  }
3820
3820
  if (Array.isArray(response)) {
3821
- const firstTicker = this.safeValue(response, 0, {});
3821
+ const firstTicker = this.safeDict(response, 0, {});
3822
3822
  return this.parseTicker(firstTicker, market);
3823
3823
  }
3824
3824
  return this.parseTicker(response, market);
@@ -5051,7 +5051,7 @@ export default class binance extends Exchange {
5051
5051
  // "msg": "Quantity greater than max quantity."
5052
5052
  // }
5053
5053
  //
5054
- // createOrder, fetchOpenOrders: portfolio margin linear swap and future
5054
+ // createOrder, fetchOpenOrders, fetchOrder, cancelOrder: portfolio margin linear swap and future
5055
5055
  //
5056
5056
  // {
5057
5057
  // "symbol": "BTCUSDT",
@@ -5074,7 +5074,7 @@ export default class binance extends Exchange {
5074
5074
  // "status": "NEW"
5075
5075
  // }
5076
5076
  //
5077
- // createOrder, fetchOpenOrders: portfolio margin inverse swap and future
5077
+ // createOrder, fetchOpenOrders, fetchOrder, cancelOrder: portfolio margin inverse swap and future
5078
5078
  //
5079
5079
  // {
5080
5080
  // "symbol": "ETHUSD_PERP",
@@ -5140,7 +5140,7 @@ export default class binance extends Exchange {
5140
5140
  // "priceProtect": false
5141
5141
  // }
5142
5142
  //
5143
- // createOrder, cancelAllOrders: portfolio margin spot margin
5143
+ // createOrder, cancelAllOrders, cancelOrder: portfolio margin spot margin
5144
5144
  //
5145
5145
  // {
5146
5146
  // "clientOrderId": "x-R4BD3S82e9ef29d8346440f0b28b86",
@@ -5159,7 +5159,7 @@ export default class binance extends Exchange {
5159
5159
  // "type": "LIMIT"
5160
5160
  // }
5161
5161
  //
5162
- // fetchOpenOrders: portfolio margin spot margin
5162
+ // fetchOpenOrders, fetchOrder: portfolio margin spot margin
5163
5163
  //
5164
5164
  // {
5165
5165
  // "symbol": "BTCUSDT",
@@ -5184,6 +5184,31 @@ export default class binance extends Exchange {
5184
5184
  // "preventedQuantity": null
5185
5185
  // }
5186
5186
  //
5187
+ // cancelOrder: portfolio margin linear and inverse swap conditional
5188
+ //
5189
+ // {
5190
+ // "strategyId": 3733211,
5191
+ // "newClientStrategyId": "x-xcKtGhcuaf166172ed504cd1bc0396",
5192
+ // "strategyType": "STOP",
5193
+ // "strategyStatus": "CANCELED",
5194
+ // "origQty": "0.010",
5195
+ // "price": "35000.00",
5196
+ // "reduceOnly": false,
5197
+ // "side": "BUY",
5198
+ // "positionSide": "BOTH",
5199
+ // "stopPrice": "50000.00", // ignored with trailing orders
5200
+ // "symbol": "BTCUSDT",
5201
+ // "timeInForce": "GTC",
5202
+ // "activatePrice": null, // only return with trailing orders
5203
+ // "priceRate": null, // only return with trailing orders
5204
+ // "bookTime": 1707270098774,
5205
+ // "updateTime": 1707270119261,
5206
+ // "workingType": "CONTRACT_PRICE",
5207
+ // "priceProtect": false,
5208
+ // "goodTillDate": 0,
5209
+ // "selfTradePreventionMode": "NONE"
5210
+ // }
5211
+ //
5187
5212
  const code = this.safeString(order, 'code');
5188
5213
  if (code !== undefined) {
5189
5214
  // cancelOrders/createOrders might have a partial success
@@ -5219,7 +5244,7 @@ export default class binance extends Exchange {
5219
5244
  cost = this.safeString(order, 'cumBase', cost);
5220
5245
  let type = this.safeStringLower(order, 'type');
5221
5246
  const side = this.safeStringLower(order, 'side');
5222
- const fills = this.safeValue(order, 'fills', []);
5247
+ const fills = this.safeList(order, 'fills', []);
5223
5248
  let timeInForce = this.safeString(order, 'timeInForce');
5224
5249
  if (timeInForce === 'GTX') {
5225
5250
  // GTX means "Good Till Crossing" and is an equivalent way of saying Post Only
@@ -5252,7 +5277,7 @@ export default class binance extends Exchange {
5252
5277
  'type': type,
5253
5278
  'timeInForce': timeInForce,
5254
5279
  'postOnly': postOnly,
5255
- 'reduceOnly': this.safeValue(order, 'reduceOnly'),
5280
+ 'reduceOnly': this.safeBool(order, 'reduceOnly'),
5256
5281
  'side': side,
5257
5282
  'price': price,
5258
5283
  'triggerPrice': stopPrice,
@@ -5286,7 +5311,7 @@ export default class binance extends Exchange {
5286
5311
  const side = this.safeString(rawOrder, 'side');
5287
5312
  const amount = this.safeValue(rawOrder, 'amount');
5288
5313
  const price = this.safeValue(rawOrder, 'price');
5289
- const orderParams = this.safeValue(rawOrder, 'params', {});
5314
+ const orderParams = this.safeDict(rawOrder, 'params', {});
5290
5315
  const orderRequest = this.createOrderRequest(marketId, type, side, amount, price, orderParams);
5291
5316
  ordersRequests.push(orderRequest);
5292
5317
  }
@@ -5794,9 +5819,14 @@ export default class binance extends Exchange {
5794
5819
  * @see https://binance-docs.github.io/apidocs/delivery/en/#query-order-user_data
5795
5820
  * @see https://binance-docs.github.io/apidocs/voptions/en/#query-single-order-trade
5796
5821
  * @see https://binance-docs.github.io/apidocs/spot/en/#query-margin-account-39-s-order-user_data
5822
+ * @see https://binance-docs.github.io/apidocs/pm/en/#query-um-order-user_data
5823
+ * @see https://binance-docs.github.io/apidocs/pm/en/#query-cm-order-user_data
5824
+ * @see https://binance-docs.github.io/apidocs/pm/en/#query-margin-account-order-user_data
5825
+ * @param {string} id the order id
5797
5826
  * @param {string} symbol unified symbol of the market the order was made in
5798
5827
  * @param {object} [params] extra parameters specific to the exchange API endpoint
5799
5828
  * @param {string} [params.marginMode] 'cross' or 'isolated', for spot margin trading
5829
+ * @param {boolean} [params.portfolioMargin] set to true if you would like to fetch an order in a portfolio margin account
5800
5830
  * @returns {object} An [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
5801
5831
  */
5802
5832
  if (symbol === undefined) {
@@ -5806,11 +5836,14 @@ export default class binance extends Exchange {
5806
5836
  const market = this.market(symbol);
5807
5837
  const defaultType = this.safeString2(this.options, 'fetchOrder', 'defaultType', 'spot');
5808
5838
  const type = this.safeString(params, 'type', defaultType);
5809
- const [marginMode, query] = this.handleMarginModeAndParams('fetchOrder', params);
5839
+ let marginMode = undefined;
5840
+ [marginMode, params] = this.handleMarginModeAndParams('fetchOrder', params);
5841
+ let isPortfolioMargin = undefined;
5842
+ [isPortfolioMargin, params] = this.handleOptionAndParams2(params, 'fetchOrder', 'papi', 'portfolioMargin', false);
5810
5843
  const request = {
5811
5844
  'symbol': market['id'],
5812
5845
  };
5813
- const clientOrderId = this.safeValue2(params, 'origClientOrderId', 'clientOrderId');
5846
+ const clientOrderId = this.safeString2(params, 'origClientOrderId', 'clientOrderId');
5814
5847
  if (clientOrderId !== undefined) {
5815
5848
  if (market['option']) {
5816
5849
  request['clientOrderId'] = clientOrderId;
@@ -5822,25 +5855,40 @@ export default class binance extends Exchange {
5822
5855
  else {
5823
5856
  request['orderId'] = id;
5824
5857
  }
5825
- const requestParams = this.omit(query, ['type', 'clientOrderId', 'origClientOrderId']);
5858
+ params = this.omit(params, ['type', 'clientOrderId', 'origClientOrderId']);
5826
5859
  let response = undefined;
5827
5860
  if (market['option']) {
5828
- response = await this.eapiPrivateGetOrder(this.extend(request, requestParams));
5861
+ response = await this.eapiPrivateGetOrder(this.extend(request, params));
5829
5862
  }
5830
5863
  else if (market['linear']) {
5831
- response = await this.fapiPrivateGetOrder(this.extend(request, requestParams));
5864
+ if (isPortfolioMargin) {
5865
+ response = await this.papiGetUmOrder(this.extend(request, params));
5866
+ }
5867
+ else {
5868
+ response = await this.fapiPrivateGetOrder(this.extend(request, params));
5869
+ }
5832
5870
  }
5833
5871
  else if (market['inverse']) {
5834
- response = await this.dapiPrivateGetOrder(this.extend(request, requestParams));
5872
+ if (isPortfolioMargin) {
5873
+ response = await this.papiGetCmOrder(this.extend(request, params));
5874
+ }
5875
+ else {
5876
+ response = await this.dapiPrivateGetOrder(this.extend(request, params));
5877
+ }
5835
5878
  }
5836
- else if (type === 'margin' || marginMode !== undefined) {
5837
- if (marginMode === 'isolated') {
5838
- request['isIsolated'] = true;
5879
+ else if ((type === 'margin') || (marginMode !== undefined) || isPortfolioMargin) {
5880
+ if (isPortfolioMargin) {
5881
+ response = await this.papiGetMarginOrder(this.extend(request, params));
5882
+ }
5883
+ else {
5884
+ if (marginMode === 'isolated') {
5885
+ request['isIsolated'] = true;
5886
+ }
5887
+ response = await this.sapiGetMarginOrder(this.extend(request, params));
5839
5888
  }
5840
- response = await this.sapiGetMarginOrder(this.extend(request, requestParams));
5841
5889
  }
5842
5890
  else {
5843
- response = await this.privateGetOrder(this.extend(request, requestParams));
5891
+ response = await this.privateGetOrder(this.extend(request, params));
5844
5892
  }
5845
5893
  return this.parseOrder(response, market);
5846
5894
  }
@@ -6155,9 +6203,16 @@ export default class binance extends Exchange {
6155
6203
  * @see https://binance-docs.github.io/apidocs/delivery/en/#cancel-order-trade
6156
6204
  * @see https://binance-docs.github.io/apidocs/voptions/en/#cancel-option-order-trade
6157
6205
  * @see https://binance-docs.github.io/apidocs/spot/en/#margin-account-cancel-order-trade
6206
+ * @see https://binance-docs.github.io/apidocs/pm/en/#cancel-um-order-trade
6207
+ * @see https://binance-docs.github.io/apidocs/pm/en/#cancel-cm-order-trade
6208
+ * @see https://binance-docs.github.io/apidocs/pm/en/#cancel-um-conditional-order-trade
6209
+ * @see https://binance-docs.github.io/apidocs/pm/en/#cancel-cm-conditional-order-trade
6210
+ * @see https://binance-docs.github.io/apidocs/pm/en/#cancel-margin-account-order-trade
6158
6211
  * @param {string} id order id
6159
6212
  * @param {string} symbol unified symbol of the market the order was made in
6160
6213
  * @param {object} [params] extra parameters specific to the exchange API endpoint
6214
+ * @param {boolean} [params.portfolioMargin] set to true if you would like to cancel an order in a portfolio margin account
6215
+ * @param {boolean} [params.stop] set to true if you would like to cancel a portfolio margin account conditional order
6161
6216
  * @returns {object} An [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
6162
6217
  */
6163
6218
  if (symbol === undefined) {
@@ -6167,43 +6222,80 @@ export default class binance extends Exchange {
6167
6222
  const market = this.market(symbol);
6168
6223
  const defaultType = this.safeString2(this.options, 'cancelOrder', 'defaultType', 'spot');
6169
6224
  const type = this.safeString(params, 'type', defaultType);
6170
- const [marginMode, query] = this.handleMarginModeAndParams('cancelOrder', params);
6225
+ let marginMode = undefined;
6226
+ [marginMode, params] = this.handleMarginModeAndParams('cancelOrder', params);
6227
+ let isPortfolioMargin = undefined;
6228
+ [isPortfolioMargin, params] = this.handleOptionAndParams2(params, 'cancelOrder', 'papi', 'portfolioMargin', false);
6229
+ const isConditional = this.safeBool2(params, 'stop', 'conditional');
6171
6230
  const request = {
6172
6231
  'symbol': market['id'],
6173
- // 'orderId': id,
6174
- // 'origClientOrderId': id,
6175
6232
  };
6176
- const clientOrderId = this.safeValue2(params, 'origClientOrderId', 'clientOrderId');
6233
+ const clientOrderId = this.safeStringN(params, ['origClientOrderId', 'clientOrderId', 'newClientStrategyId']);
6177
6234
  if (clientOrderId !== undefined) {
6178
6235
  if (market['option']) {
6179
6236
  request['clientOrderId'] = clientOrderId;
6180
6237
  }
6181
6238
  else {
6182
- request['origClientOrderId'] = clientOrderId;
6239
+ if (isPortfolioMargin && isConditional) {
6240
+ request['newClientStrategyId'] = clientOrderId;
6241
+ }
6242
+ else {
6243
+ request['origClientOrderId'] = clientOrderId;
6244
+ }
6183
6245
  }
6184
6246
  }
6185
6247
  else {
6186
- request['orderId'] = id;
6248
+ if (isPortfolioMargin && isConditional) {
6249
+ request['strategyId'] = id;
6250
+ }
6251
+ else {
6252
+ request['orderId'] = id;
6253
+ }
6187
6254
  }
6188
- const requestParams = this.omit(query, ['type', 'origClientOrderId', 'clientOrderId']);
6255
+ params = this.omit(params, ['type', 'origClientOrderId', 'clientOrderId', 'newClientStrategyId', 'stop', 'conditional']);
6189
6256
  let response = undefined;
6190
6257
  if (market['option']) {
6191
- response = await this.eapiPrivateDeleteOrder(this.extend(request, requestParams));
6258
+ response = await this.eapiPrivateDeleteOrder(this.extend(request, params));
6192
6259
  }
6193
6260
  else if (market['linear']) {
6194
- response = await this.fapiPrivateDeleteOrder(this.extend(request, requestParams));
6261
+ if (isPortfolioMargin) {
6262
+ if (isConditional) {
6263
+ response = await this.papiDeleteUmConditionalOrder(this.extend(request, params));
6264
+ }
6265
+ else {
6266
+ response = await this.papiDeleteUmOrder(this.extend(request, params));
6267
+ }
6268
+ }
6269
+ else {
6270
+ response = await this.fapiPrivateDeleteOrder(this.extend(request, params));
6271
+ }
6195
6272
  }
6196
6273
  else if (market['inverse']) {
6197
- response = await this.dapiPrivateDeleteOrder(this.extend(request, requestParams));
6274
+ if (isPortfolioMargin) {
6275
+ if (isConditional) {
6276
+ response = await this.papiDeleteCmConditionalOrder(this.extend(request, params));
6277
+ }
6278
+ else {
6279
+ response = await this.papiDeleteCmOrder(this.extend(request, params));
6280
+ }
6281
+ }
6282
+ else {
6283
+ response = await this.dapiPrivateDeleteOrder(this.extend(request, params));
6284
+ }
6198
6285
  }
6199
- else if (type === 'margin' || marginMode !== undefined) {
6200
- if (marginMode === 'isolated') {
6201
- request['isIsolated'] = true;
6286
+ else if ((type === 'margin') || (marginMode !== undefined) || isPortfolioMargin) {
6287
+ if (isPortfolioMargin) {
6288
+ response = await this.papiDeleteMarginOrder(this.extend(request, params));
6289
+ }
6290
+ else {
6291
+ if (marginMode === 'isolated') {
6292
+ request['isIsolated'] = true;
6293
+ }
6294
+ response = await this.sapiDeleteMarginOrder(this.extend(request, params));
6202
6295
  }
6203
- response = await this.sapiDeleteMarginOrder(this.extend(request, requestParams));
6204
6296
  }
6205
6297
  else {
6206
- response = await this.privateDeleteOrder(this.extend(request, requestParams));
6298
+ response = await this.privateDeleteOrder(this.extend(request, params));
6207
6299
  }
6208
6300
  return this.parseOrder(response, market);
6209
6301
  }
@@ -6611,11 +6703,11 @@ export default class binance extends Exchange {
6611
6703
  // },
6612
6704
  // ]
6613
6705
  // }
6614
- const results = this.safeValue(response, 'userAssetDribblets', []);
6706
+ const results = this.safeList(response, 'userAssetDribblets', []);
6615
6707
  const rows = this.safeInteger(response, 'total', 0);
6616
6708
  const data = [];
6617
6709
  for (let i = 0; i < rows; i++) {
6618
- const logs = this.safeValue(results[i], 'userAssetDribbletDetails', []);
6710
+ const logs = this.safeList(results[i], 'userAssetDribbletDetails', []);
6619
6711
  for (let j = 0; j < logs.length; j++) {
6620
6712
  logs[j]['isDustTrade'] = true;
6621
6713
  data.push(logs[j]);
@@ -6722,7 +6814,7 @@ export default class binance extends Exchange {
6722
6814
  let currency = undefined;
6723
6815
  let response = undefined;
6724
6816
  const request = {};
6725
- const legalMoney = this.safeValue(this.options, 'legalMoney', {});
6817
+ const legalMoney = this.safeDict(this.options, 'legalMoney', {});
6726
6818
  const fiatOnly = this.safeBool(params, 'fiat', false);
6727
6819
  params = this.omit(params, 'fiatOnly');
6728
6820
  const until = this.safeInteger(params, 'until');
@@ -6834,7 +6926,7 @@ export default class binance extends Exchange {
6834
6926
  if (paginate) {
6835
6927
  return await this.fetchPaginatedCallDynamic('fetchWithdrawals', code, since, limit, params);
6836
6928
  }
6837
- const legalMoney = this.safeValue(this.options, 'legalMoney', {});
6929
+ const legalMoney = this.safeDict(this.options, 'legalMoney', {});
6838
6930
  const fiatOnly = this.safeBool(params, 'fiat', false);
6839
6931
  params = this.omit(params, 'fiatOnly');
6840
6932
  const request = {};
@@ -6978,7 +7070,7 @@ export default class binance extends Exchange {
6978
7070
  'Refund Failed': 'failed',
6979
7071
  },
6980
7072
  };
6981
- const statuses = this.safeValue(statusesByType, type, {});
7073
+ const statuses = this.safeDict(statusesByType, type, {});
6982
7074
  return this.safeString(statuses, status, status);
6983
7075
  }
6984
7076
  parseTransaction(transaction, currency = undefined) {
@@ -7143,7 +7235,7 @@ export default class binance extends Exchange {
7143
7235
  const type = this.safeString(transfer, 'type');
7144
7236
  let fromAccount = undefined;
7145
7237
  let toAccount = undefined;
7146
- const accountsById = this.safeValue(this.options, 'accountsById', {});
7238
+ const accountsById = this.safeDict(this.options, 'accountsById', {});
7147
7239
  if (type !== undefined) {
7148
7240
  const parts = type.split('_');
7149
7241
  fromAccount = this.safeValue(parts, 0);
@@ -7179,20 +7271,16 @@ export default class binance extends Exchange {
7179
7271
  // }
7180
7272
  //
7181
7273
  const marketId = this.safeString(income, 'symbol');
7182
- const symbol = this.safeSymbol(marketId, market, undefined, 'swap');
7183
- const amount = this.safeNumber(income, 'income');
7184
7274
  const currencyId = this.safeString(income, 'asset');
7185
- const code = this.safeCurrencyCode(currencyId);
7186
- const id = this.safeString(income, 'tranId');
7187
7275
  const timestamp = this.safeInteger(income, 'time');
7188
7276
  return {
7189
7277
  'info': income,
7190
- 'symbol': symbol,
7191
- 'code': code,
7278
+ 'symbol': this.safeSymbol(marketId, market, undefined, 'swap'),
7279
+ 'code': this.safeCurrencyCode(currencyId),
7192
7280
  'timestamp': timestamp,
7193
7281
  'datetime': this.iso8601(timestamp),
7194
- 'id': id,
7195
- 'amount': amount,
7282
+ 'id': this.safeString(income, 'tranId'),
7283
+ 'amount': this.safeNumber(income, 'income'),
7196
7284
  };
7197
7285
  }
7198
7286
  async transfer(code, amount, fromAccount, toAccount, params = {}) {
@@ -7241,7 +7329,7 @@ export default class binance extends Exchange {
7241
7329
  throw new ArgumentsRequired(this.id + ' transfer () requires params["symbol"] when toAccount is ' + toAccount);
7242
7330
  }
7243
7331
  }
7244
- const accountsById = this.safeValue(this.options, 'accountsById', {});
7332
+ const accountsById = this.safeDict(this.options, 'accountsById', {});
7245
7333
  const fromIsolated = !(fromId in accountsById);
7246
7334
  const toIsolated = !(toId in accountsById);
7247
7335
  if (fromIsolated && (market === undefined)) {
@@ -7331,7 +7419,7 @@ export default class binance extends Exchange {
7331
7419
  const defaultTo = (fromAccount === 'future') ? 'spot' : 'future';
7332
7420
  const toAccount = this.safeString(params, 'toAccount', defaultTo);
7333
7421
  let type = this.safeString(params, 'type');
7334
- const accountsByType = this.safeValue(this.options, 'accountsByType', {});
7422
+ const accountsByType = this.safeDict(this.options, 'accountsByType', {});
7335
7423
  const fromId = this.safeString(accountsByType, fromAccount);
7336
7424
  const toId = this.safeString(accountsByType, toAccount);
7337
7425
  if (type === undefined) {
@@ -7375,7 +7463,7 @@ export default class binance extends Exchange {
7375
7463
  // ]
7376
7464
  // }
7377
7465
  //
7378
- const rows = this.safeValue(response, 'rows', []);
7466
+ const rows = this.safeList(response, 'rows', []);
7379
7467
  return this.parseTransfers(rows, currency, since, limit);
7380
7468
  }
7381
7469
  async fetchDepositAddress(code, params = {}) {
@@ -7394,7 +7482,7 @@ export default class binance extends Exchange {
7394
7482
  'coin': currency['id'],
7395
7483
  // 'network': 'ETH', // 'BSC', 'XMR', you can get network and isDefault in networkList in the response of sapiGetCapitalConfigDetail
7396
7484
  };
7397
- const networks = this.safeValue(this.options, 'networks', {});
7485
+ const networks = this.safeDict(this.options, 'networks', {});
7398
7486
  let network = this.safeStringUpper(params, 'network'); // this line allows the user to specify either ERC20 or ETH
7399
7487
  network = this.safeString(networks, network, network); // handle ERC20>ETH alias
7400
7488
  if (network !== undefined) {
@@ -7421,7 +7509,7 @@ export default class binance extends Exchange {
7421
7509
  const url = this.safeString(response, 'url');
7422
7510
  let impliedNetwork = undefined;
7423
7511
  if (url !== undefined) {
7424
- const reverseNetworks = this.safeValue(this.options, 'reverseNetworks', {});
7512
+ const reverseNetworks = this.safeDict(this.options, 'reverseNetworks', {});
7425
7513
  const parts = url.split('/');
7426
7514
  let topLevel = this.safeString(parts, 2);
7427
7515
  if ((topLevel === 'blockchair.com') || (topLevel === 'viewblock.io')) {
@@ -7436,7 +7524,7 @@ export default class binance extends Exchange {
7436
7524
  'TRX': { 'TRC20': 'TRX' },
7437
7525
  });
7438
7526
  if (code in impliedNetworks) {
7439
- const conversion = this.safeValue(impliedNetworks, code, {});
7527
+ const conversion = this.safeDict(impliedNetworks, code, {});
7440
7528
  impliedNetwork = this.safeString(conversion, impliedNetwork, impliedNetwork);
7441
7529
  }
7442
7530
  }
@@ -7552,7 +7640,7 @@ export default class binance extends Exchange {
7552
7640
  const entry = response[i];
7553
7641
  const currencyId = this.safeString(entry, 'coin');
7554
7642
  const code = this.safeCurrencyCode(currencyId);
7555
- const networkList = this.safeValue(entry, 'networkList', []);
7643
+ const networkList = this.safeList(entry, 'networkList', []);
7556
7644
  withdrawFees[code] = {};
7557
7645
  for (let j = 0; j < networkList.length; j++) {
7558
7646
  const networkEntry = networkList[j];
@@ -7665,14 +7753,14 @@ export default class binance extends Exchange {
7665
7753
  // ]
7666
7754
  // }
7667
7755
  //
7668
- const networkList = this.safeValue(fee, 'networkList', []);
7756
+ const networkList = this.safeList(fee, 'networkList', []);
7669
7757
  const result = this.depositWithdrawFee(fee);
7670
7758
  for (let j = 0; j < networkList.length; j++) {
7671
7759
  const networkEntry = networkList[j];
7672
7760
  const networkId = this.safeString(networkEntry, 'network');
7673
7761
  const networkCode = this.networkIdToCode(networkId);
7674
7762
  const withdrawFee = this.safeNumber(networkEntry, 'withdrawFee');
7675
- const isDefault = this.safeValue(networkEntry, 'isDefault');
7763
+ const isDefault = this.safeBool(networkEntry, 'isDefault');
7676
7764
  if (isDefault === true) {
7677
7765
  result['withdraw'] = {
7678
7766
  'fee': withdrawFee,
@@ -7720,7 +7808,7 @@ export default class binance extends Exchange {
7720
7808
  if (tag !== undefined) {
7721
7809
  request['addressTag'] = tag;
7722
7810
  }
7723
- const networks = this.safeValue(this.options, 'networks', {});
7811
+ const networks = this.safeDict(this.options, 'networks', {});
7724
7812
  let network = this.safeStringUpper(params, 'network'); // this line allows the user to specify either ERC20 or ETH
7725
7813
  network = this.safeString(networks, network, network); // handle ERC20>ETH alias
7726
7814
  if (network !== undefined) {
@@ -7812,7 +7900,7 @@ export default class binance extends Exchange {
7812
7900
  //
7813
7901
  let data = response;
7814
7902
  if (Array.isArray(data)) {
7815
- data = this.safeValue(data, 0, {});
7903
+ data = this.safeDict(data, 0, {});
7816
7904
  }
7817
7905
  return this.parseTradingFee(data);
7818
7906
  }
@@ -8226,8 +8314,8 @@ export default class binance extends Exchange {
8226
8314
  };
8227
8315
  }
8228
8316
  parseAccountPositions(account) {
8229
- const positions = this.safeValue(account, 'positions');
8230
- const assets = this.safeValue(account, 'assets', []);
8317
+ const positions = this.safeList(account, 'positions');
8318
+ const assets = this.safeList(account, 'assets', []);
8231
8319
  const balances = {};
8232
8320
  for (let i = 0; i < assets.length; i++) {
8233
8321
  const entry = assets[i];
@@ -8246,13 +8334,17 @@ export default class binance extends Exchange {
8246
8334
  const marketId = this.safeString(position, 'symbol');
8247
8335
  const market = this.safeMarket(marketId, undefined, undefined, 'contract');
8248
8336
  const code = market['linear'] ? market['quote'] : market['base'];
8249
- // sometimes not all the codes are correctly returned...
8250
- if (code in balances) {
8251
- const parsed = this.parseAccountPosition(this.extend(position, {
8252
- 'crossMargin': balances[code]['crossMargin'],
8253
- 'crossWalletBalance': balances[code]['crossWalletBalance'],
8254
- }), market);
8255
- result.push(parsed);
8337
+ const maintenanceMargin = this.safeString(position, 'maintMargin');
8338
+ // check for maintenance margin so empty positions are not returned
8339
+ if ((maintenanceMargin !== '0') && (maintenanceMargin !== '0.00000000')) {
8340
+ // sometimes not all the codes are correctly returned...
8341
+ if (code in balances) {
8342
+ const parsed = this.parseAccountPosition(this.extend(position, {
8343
+ 'crossMargin': balances[code]['crossMargin'],
8344
+ 'crossWalletBalance': balances[code]['crossWalletBalance'],
8345
+ }), market);
8346
+ result.push(parsed);
8347
+ }
8256
8348
  }
8257
8349
  }
8258
8350
  return result;
@@ -8260,6 +8352,7 @@ export default class binance extends Exchange {
8260
8352
  parseAccountPosition(position, market = undefined) {
8261
8353
  //
8262
8354
  // usdm
8355
+ //
8263
8356
  // {
8264
8357
  // "symbol": "BTCBUSD",
8265
8358
  // "initialMargin": "0",
@@ -8280,6 +8373,7 @@ export default class binance extends Exchange {
8280
8373
  // }
8281
8374
  //
8282
8375
  // coinm
8376
+ //
8283
8377
  // {
8284
8378
  // "symbol": "BTCUSD_210625",
8285
8379
  // "initialMargin": "0.00024393",
@@ -8298,6 +8392,46 @@ export default class binance extends Exchange {
8298
8392
  // "crossWalletBalance": "34",
8299
8393
  // }
8300
8394
  //
8395
+ // linear portfolio margin
8396
+ //
8397
+ // {
8398
+ // "symbol": "CTSIUSDT",
8399
+ // "initialMargin": "0",
8400
+ // "maintMargin": "0",
8401
+ // "unrealizedProfit": "0.00000000",
8402
+ // "positionInitialMargin": "0",
8403
+ // "openOrderInitialMargin": "0",
8404
+ // "leverage": "20",
8405
+ // "entryPrice": "0.0",
8406
+ // "maxNotional": "25000",
8407
+ // "bidNotional": "0",
8408
+ // "askNotional": "0",
8409
+ // "positionSide": "SHORT",
8410
+ // "positionAmt": "0",
8411
+ // "updateTime": 0,
8412
+ // "notional": "0",
8413
+ // "breakEvenPrice": "0.0"
8414
+ // }
8415
+ //
8416
+ // inverse portoflio margin
8417
+ //
8418
+ // {
8419
+ // "symbol": "TRXUSD_PERP",
8420
+ // "initialMargin": "0",
8421
+ // "maintMargin": "0",
8422
+ // "unrealizedProfit": "0.00000000",
8423
+ // "positionInitialMargin": "0",
8424
+ // "openOrderInitialMargin": "0",
8425
+ // "leverage": "20",
8426
+ // "entryPrice": "0.00000000",
8427
+ // "positionSide": "SHORT",
8428
+ // "positionAmt": "0",
8429
+ // "maxQty": "5000000",
8430
+ // "updateTime": 0,
8431
+ // "notionalValue": "0",
8432
+ // "breakEvenPrice": "0.00000000"
8433
+ // }
8434
+ //
8301
8435
  const marketId = this.safeString(position, 'symbol');
8302
8436
  market = this.safeMarket(marketId, market, undefined, 'contract');
8303
8437
  const symbol = this.safeString(market, 'symbol');
@@ -8328,8 +8462,8 @@ export default class binance extends Exchange {
8328
8462
  contractsStringAbs = Precise.stringDiv(Precise.stringAdd(contractsString, '0.5'), '1', 0);
8329
8463
  }
8330
8464
  const contracts = this.parseNumber(contractsStringAbs);
8331
- const leverageBrackets = this.safeValue(this.options, 'leverageBrackets', {});
8332
- const leverageBracket = this.safeValue(leverageBrackets, symbol, []);
8465
+ const leverageBrackets = this.safeDict(this.options, 'leverageBrackets', {});
8466
+ const leverageBracket = this.safeList(leverageBrackets, symbol, []);
8333
8467
  let maintenanceMarginPercentageString = undefined;
8334
8468
  for (let i = 0; i < leverageBracket.length; i++) {
8335
8469
  const bracket = leverageBracket[i];
@@ -8345,7 +8479,7 @@ export default class binance extends Exchange {
8345
8479
  if (timestamp === 0) {
8346
8480
  timestamp = undefined;
8347
8481
  }
8348
- const isolated = this.safeValue(position, 'isolated');
8482
+ const isolated = this.safeBool(position, 'isolated');
8349
8483
  let marginMode = undefined;
8350
8484
  let collateralString = undefined;
8351
8485
  let walletBalance = undefined;
@@ -8498,11 +8632,45 @@ export default class binance extends Exchange {
8498
8632
  // "isolatedWallet": "0.00268058"
8499
8633
  // }
8500
8634
  //
8635
+ // inverse portfolio margin
8636
+ //
8637
+ // {
8638
+ // "symbol": "ETHUSD_PERP",
8639
+ // "positionAmt": "1",
8640
+ // "entryPrice": "2422.400000007",
8641
+ // "markPrice": "2424.51267823",
8642
+ // "unRealizedProfit": "0.0000036",
8643
+ // "liquidationPrice": "293.57678898",
8644
+ // "leverage": "100",
8645
+ // "positionSide": "LONG",
8646
+ // "updateTime": 1707371941861,
8647
+ // "maxQty": "15",
8648
+ // "notionalValue": "0.00412454",
8649
+ // "breakEvenPrice": "2423.368960034"
8650
+ // }
8651
+ //
8652
+ // linear portfolio margin
8653
+ //
8654
+ // {
8655
+ // "symbol": "BTCUSDT",
8656
+ // "positionAmt": "0.01",
8657
+ // "entryPrice": "44525.0",
8658
+ // "markPrice": "45464.1735922",
8659
+ // "unRealizedProfit": "9.39173592",
8660
+ // "liquidationPrice": "38007.16308568",
8661
+ // "leverage": "100",
8662
+ // "positionSide": "LONG",
8663
+ // "updateTime": 1707371879042,
8664
+ // "maxNotionalValue": "500000.0",
8665
+ // "notional": "454.64173592",
8666
+ // "breakEvenPrice": "44542.81"
8667
+ // }
8668
+ //
8501
8669
  const marketId = this.safeString(position, 'symbol');
8502
8670
  market = this.safeMarket(marketId, market, undefined, 'contract');
8503
8671
  const symbol = this.safeString(market, 'symbol');
8504
- const leverageBrackets = this.safeValue(this.options, 'leverageBrackets', {});
8505
- const leverageBracket = this.safeValue(leverageBrackets, symbol, []);
8672
+ const leverageBrackets = this.safeDict(this.options, 'leverageBrackets', {});
8673
+ const leverageBracket = this.safeList(leverageBrackets, symbol, []);
8506
8674
  const notionalString = this.safeString2(position, 'notional', 'notionalValue');
8507
8675
  const notionalStringAbs = Precise.stringAbs(notionalString);
8508
8676
  let maintenanceMarginPercentageString = undefined;
@@ -8539,7 +8707,7 @@ export default class binance extends Exchange {
8539
8707
  const linear = ('notional' in position);
8540
8708
  if (marginMode === 'cross') {
8541
8709
  // calculate collateral
8542
- const precision = this.safeValue(market, 'precision', {});
8710
+ const precision = this.safeDict(market, 'precision', {});
8543
8711
  if (linear) {
8544
8712
  // walletBalance = (liquidationPrice * (±1 + mmp) ± entryPrice) * contracts
8545
8713
  let onePlusMaintenanceMarginPercentageString = undefined;
@@ -8646,12 +8814,24 @@ export default class binance extends Exchange {
8646
8814
  const query = this.omit(params, 'type');
8647
8815
  let subType = undefined;
8648
8816
  [subType, params] = this.handleSubTypeAndParams('loadLeverageBrackets', undefined, params, 'linear');
8817
+ let isPortfolioMargin = undefined;
8818
+ [isPortfolioMargin, params] = this.handleOptionAndParams2(params, 'loadLeverageBrackets', 'papi', 'portfolioMargin', false);
8649
8819
  let response = undefined;
8650
8820
  if (this.isLinear(type, subType)) {
8651
- response = await this.fapiPrivateGetLeverageBracket(query);
8821
+ if (isPortfolioMargin) {
8822
+ response = await this.papiGetUmLeverageBracket(query);
8823
+ }
8824
+ else {
8825
+ response = await this.fapiPrivateGetLeverageBracket(query);
8826
+ }
8652
8827
  }
8653
8828
  else if (this.isInverse(type, subType)) {
8654
- response = await this.dapiPrivateV2GetLeverageBracket(query);
8829
+ if (isPortfolioMargin) {
8830
+ response = await this.papiGetCmLeverageBracket(query);
8831
+ }
8832
+ else {
8833
+ response = await this.dapiPrivateV2GetLeverageBracket(query);
8834
+ }
8655
8835
  }
8656
8836
  else {
8657
8837
  throw new NotSupported(this.id + ' loadLeverageBrackets() supports linear and inverse contracts only');
@@ -8661,7 +8841,7 @@ export default class binance extends Exchange {
8661
8841
  const entry = response[i];
8662
8842
  const marketId = this.safeString(entry, 'symbol');
8663
8843
  const symbol = this.safeSymbol(marketId, undefined, undefined, 'contract');
8664
- const brackets = this.safeValue(entry, 'brackets', []);
8844
+ const brackets = this.safeList(entry, 'brackets', []);
8665
8845
  const result = [];
8666
8846
  for (let j = 0; j < brackets.length; j++) {
8667
8847
  const bracket = brackets[j];
@@ -8681,8 +8861,11 @@ export default class binance extends Exchange {
8681
8861
  * @description retrieve information on the maximum leverage, and maintenance margin for trades of varying trade sizes
8682
8862
  * @see https://binance-docs.github.io/apidocs/futures/en/#notional-and-leverage-brackets-user_data
8683
8863
  * @see https://binance-docs.github.io/apidocs/delivery/en/#notional-bracket-for-symbol-user_data
8864
+ * @see https://binance-docs.github.io/apidocs/pm/en/#um-notional-and-leverage-brackets-user_data
8865
+ * @see https://binance-docs.github.io/apidocs/pm/en/#cm-notional-and-leverage-brackets-user_data
8684
8866
  * @param {string[]|undefined} symbols list of unified market symbols
8685
8867
  * @param {object} [params] extra parameters specific to the exchange API endpoint
8868
+ * @param {boolean} [params.portfolioMargin] set to true if you would like to fetch the leverage tiers for a portfolio margin account
8686
8869
  * @returns {object} a dictionary of [leverage tiers structures]{@link https://docs.ccxt.com/#/?id=leverage-tiers-structure}, indexed by market symbols
8687
8870
  */
8688
8871
  await this.loadMarkets();
@@ -8690,12 +8873,24 @@ export default class binance extends Exchange {
8690
8873
  [type, params] = this.handleMarketTypeAndParams('fetchLeverageTiers', undefined, params);
8691
8874
  let subType = undefined;
8692
8875
  [subType, params] = this.handleSubTypeAndParams('fetchLeverageTiers', undefined, params, 'linear');
8876
+ let isPortfolioMargin = undefined;
8877
+ [isPortfolioMargin, params] = this.handleOptionAndParams2(params, 'fetchLeverageTiers', 'papi', 'portfolioMargin', false);
8693
8878
  let response = undefined;
8694
8879
  if (this.isLinear(type, subType)) {
8695
- response = await this.fapiPrivateGetLeverageBracket(params);
8880
+ if (isPortfolioMargin) {
8881
+ response = await this.papiGetUmLeverageBracket(params);
8882
+ }
8883
+ else {
8884
+ response = await this.fapiPrivateGetLeverageBracket(params);
8885
+ }
8696
8886
  }
8697
8887
  else if (this.isInverse(type, subType)) {
8698
- response = await this.dapiPrivateV2GetLeverageBracket(params);
8888
+ if (isPortfolioMargin) {
8889
+ response = await this.papiGetCmLeverageBracket(params);
8890
+ }
8891
+ else {
8892
+ response = await this.dapiPrivateV2GetLeverageBracket(params);
8893
+ }
8699
8894
  }
8700
8895
  else {
8701
8896
  throw new NotSupported(this.id + ' fetchLeverageTiers() supports linear and inverse contracts only');
@@ -8765,7 +8960,7 @@ export default class binance extends Exchange {
8765
8960
  //
8766
8961
  const marketId = this.safeString(info, 'symbol');
8767
8962
  market = this.safeMarket(marketId, market, undefined, 'contract');
8768
- const brackets = this.safeValue(info, 'brackets', []);
8963
+ const brackets = this.safeList(info, 'brackets', []);
8769
8964
  const tiers = [];
8770
8965
  for (let j = 0; j < brackets.length; j++) {
8771
8966
  const bracket = brackets[j];
@@ -8980,8 +9175,11 @@ export default class binance extends Exchange {
8980
9175
  * @description fetch account positions
8981
9176
  * @see https://binance-docs.github.io/apidocs/futures/en/#account-information-v2-user_data
8982
9177
  * @see https://binance-docs.github.io/apidocs/delivery/en/#account-information-user_data
9178
+ * @see https://binance-docs.github.io/apidocs/pm/en/#get-um-account-detail-user_data
9179
+ * @see https://binance-docs.github.io/apidocs/pm/en/#get-cm-account-detail-user_data
8983
9180
  * @param {string[]|undefined} symbols list of unified market symbols
8984
9181
  * @param {object} [params] extra parameters specific to the exchange API endpoint
9182
+ * @param {boolean} [params.portfolioMargin] set to true if you would like to fetch positions in a portfolio margin account
8985
9183
  * @returns {object} data on account positions
8986
9184
  */
8987
9185
  if (symbols !== undefined) {
@@ -8993,15 +9191,27 @@ export default class binance extends Exchange {
8993
9191
  await this.loadLeverageBrackets(false, params);
8994
9192
  const defaultType = this.safeString(this.options, 'defaultType', 'future');
8995
9193
  const type = this.safeString(params, 'type', defaultType);
8996
- let query = this.omit(params, 'type');
9194
+ params = this.omit(params, 'type');
8997
9195
  let subType = undefined;
8998
- [subType, query] = this.handleSubTypeAndParams('fetchAccountPositions', undefined, params, 'linear');
9196
+ [subType, params] = this.handleSubTypeAndParams('fetchAccountPositions', undefined, params, 'linear');
9197
+ let isPortfolioMargin = undefined;
9198
+ [isPortfolioMargin, params] = this.handleOptionAndParams2(params, 'fetchAccountPositions', 'papi', 'portfolioMargin', false);
8999
9199
  let response = undefined;
9000
9200
  if (this.isLinear(type, subType)) {
9001
- response = await this.fapiPrivateV2GetAccount(query);
9201
+ if (isPortfolioMargin) {
9202
+ response = await this.papiGetUmAccount(params);
9203
+ }
9204
+ else {
9205
+ response = await this.fapiPrivateV2GetAccount(params);
9206
+ }
9002
9207
  }
9003
9208
  else if (this.isInverse(type, subType)) {
9004
- response = await this.dapiPrivateGetAccount(query);
9209
+ if (isPortfolioMargin) {
9210
+ response = await this.papiGetCmAccount(params);
9211
+ }
9212
+ else {
9213
+ response = await this.dapiPrivateGetAccount(params);
9214
+ }
9005
9215
  }
9006
9216
  else {
9007
9217
  throw new NotSupported(this.id + ' fetchPositions() supports linear and inverse contracts only');
@@ -9018,8 +9228,11 @@ export default class binance extends Exchange {
9018
9228
  * @description fetch positions risk
9019
9229
  * @see https://binance-docs.github.io/apidocs/futures/en/#position-information-v2-user_data
9020
9230
  * @see https://binance-docs.github.io/apidocs/delivery/en/#position-information-user_data
9231
+ * @see https://binance-docs.github.io/apidocs/pm/en/#query-um-position-information-user_data
9232
+ * @see https://binance-docs.github.io/apidocs/pm/en/#query-cm-position-information-user_data
9021
9233
  * @param {string[]|undefined} symbols list of unified market symbols
9022
9234
  * @param {object} [params] extra parameters specific to the exchange API endpoint
9235
+ * @param {boolean} [params.portfolioMargin] set to true if you would like to fetch positions for a portfolio margin account
9023
9236
  * @returns {object} data on the positions risk
9024
9237
  */
9025
9238
  if (symbols !== undefined) {
@@ -9035,71 +9248,124 @@ export default class binance extends Exchange {
9035
9248
  const type = this.safeString(params, 'type', defaultType);
9036
9249
  let subType = undefined;
9037
9250
  [subType, params] = this.handleSubTypeAndParams('fetchPositionsRisk', undefined, params, 'linear');
9251
+ let isPortfolioMargin = undefined;
9252
+ [isPortfolioMargin, params] = this.handleOptionAndParams2(params, 'fetchPositionsRisk', 'papi', 'portfolioMargin', false);
9038
9253
  params = this.omit(params, 'type');
9039
9254
  let response = undefined;
9040
9255
  if (this.isLinear(type, subType)) {
9041
- response = await this.fapiPrivateV2GetPositionRisk(this.extend(request, params));
9042
- // ### Response examples ###
9043
- //
9044
- // For One-way position mode:
9045
- // [
9046
- // {
9047
- // "entryPrice": "0.00000",
9048
- // "marginType": "isolated",
9049
- // "isAutoAddMargin": "false",
9050
- // "isolatedMargin": "0.00000000",
9051
- // "leverage": "10",
9052
- // "liquidationPrice": "0",
9053
- // "markPrice": "6679.50671178",
9054
- // "maxNotionalValue": "20000000",
9055
- // "positionAmt": "0.000",
9056
- // "symbol": "BTCUSDT",
9057
- // "unRealizedProfit": "0.00000000",
9058
- // "positionSide": "BOTH",
9059
- // "updateTime": 0
9060
- // }
9061
- // ]
9062
- //
9063
- // For Hedge position mode:
9064
- // [
9065
- // {
9066
- // "entryPrice": "6563.66500",
9067
- // "marginType": "isolated",
9068
- // "isAutoAddMargin": "false",
9069
- // "isolatedMargin": "15517.54150468",
9070
- // "leverage": "10",
9071
- // "liquidationPrice": "5930.78",
9072
- // "markPrice": "6679.50671178",
9073
- // "maxNotionalValue": "20000000",
9074
- // "positionAmt": "20.000",
9075
- // "symbol": "BTCUSDT",
9076
- // "unRealizedProfit": "2316.83423560"
9077
- // "positionSide": "LONG",
9078
- // "updateTime": 1625474304765
9079
- // },
9080
- // {
9081
- // "entryPrice": "0.00000",
9082
- // "marginType": "isolated",
9083
- // "isAutoAddMargin": "false",
9084
- // "isolatedMargin": "5413.95799991",
9085
- // "leverage": "10",
9086
- // "liquidationPrice": "7189.95",
9087
- // "markPrice": "6679.50671178",
9088
- // "maxNotionalValue": "20000000",
9089
- // "positionAmt": "-10.000",
9090
- // "symbol": "BTCUSDT",
9091
- // "unRealizedProfit": "-1156.46711780",
9092
- // "positionSide": "SHORT",
9093
- // "updateTime": 0
9094
- // }
9095
- // ]
9256
+ if (isPortfolioMargin) {
9257
+ response = await this.papiGetUmPositionRisk(this.extend(request, params));
9258
+ }
9259
+ else {
9260
+ response = await this.fapiPrivateV2GetPositionRisk(this.extend(request, params));
9261
+ }
9096
9262
  }
9097
9263
  else if (this.isInverse(type, subType)) {
9098
- response = await this.dapiPrivateGetPositionRisk(this.extend(request, params));
9264
+ if (isPortfolioMargin) {
9265
+ response = await this.papiGetCmPositionRisk(this.extend(request, params));
9266
+ }
9267
+ else {
9268
+ response = await this.dapiPrivateGetPositionRisk(this.extend(request, params));
9269
+ }
9099
9270
  }
9100
9271
  else {
9101
9272
  throw new NotSupported(this.id + ' fetchPositionsRisk() supports linear and inverse contracts only');
9102
9273
  }
9274
+ // ### Response examples ###
9275
+ //
9276
+ // For One-way position mode:
9277
+ //
9278
+ // [
9279
+ // {
9280
+ // "entryPrice": "0.00000",
9281
+ // "marginType": "isolated",
9282
+ // "isAutoAddMargin": "false",
9283
+ // "isolatedMargin": "0.00000000",
9284
+ // "leverage": "10",
9285
+ // "liquidationPrice": "0",
9286
+ // "markPrice": "6679.50671178",
9287
+ // "maxNotionalValue": "20000000",
9288
+ // "positionAmt": "0.000",
9289
+ // "symbol": "BTCUSDT",
9290
+ // "unRealizedProfit": "0.00000000",
9291
+ // "positionSide": "BOTH",
9292
+ // "updateTime": 0
9293
+ // }
9294
+ // ]
9295
+ //
9296
+ // For Hedge position mode:
9297
+ //
9298
+ // [
9299
+ // {
9300
+ // "entryPrice": "6563.66500",
9301
+ // "marginType": "isolated",
9302
+ // "isAutoAddMargin": "false",
9303
+ // "isolatedMargin": "15517.54150468",
9304
+ // "leverage": "10",
9305
+ // "liquidationPrice": "5930.78",
9306
+ // "markPrice": "6679.50671178",
9307
+ // "maxNotionalValue": "20000000",
9308
+ // "positionAmt": "20.000",
9309
+ // "symbol": "BTCUSDT",
9310
+ // "unRealizedProfit": "2316.83423560"
9311
+ // "positionSide": "LONG",
9312
+ // "updateTime": 1625474304765
9313
+ // },
9314
+ // {
9315
+ // "entryPrice": "0.00000",
9316
+ // "marginType": "isolated",
9317
+ // "isAutoAddMargin": "false",
9318
+ // "isolatedMargin": "5413.95799991",
9319
+ // "leverage": "10",
9320
+ // "liquidationPrice": "7189.95",
9321
+ // "markPrice": "6679.50671178",
9322
+ // "maxNotionalValue": "20000000",
9323
+ // "positionAmt": "-10.000",
9324
+ // "symbol": "BTCUSDT",
9325
+ // "unRealizedProfit": "-1156.46711780",
9326
+ // "positionSide": "SHORT",
9327
+ // "updateTime": 0
9328
+ // }
9329
+ // ]
9330
+ //
9331
+ // inverse portfolio margin:
9332
+ //
9333
+ // [
9334
+ // {
9335
+ // "symbol": "ETHUSD_PERP",
9336
+ // "positionAmt": "1",
9337
+ // "entryPrice": "2422.400000007",
9338
+ // "markPrice": "2424.51267823",
9339
+ // "unRealizedProfit": "0.0000036",
9340
+ // "liquidationPrice": "293.57678898",
9341
+ // "leverage": "100",
9342
+ // "positionSide": "LONG",
9343
+ // "updateTime": 1707371941861,
9344
+ // "maxQty": "15",
9345
+ // "notionalValue": "0.00412454",
9346
+ // "breakEvenPrice": "2423.368960034"
9347
+ // }
9348
+ // ]
9349
+ //
9350
+ // linear portfolio margin:
9351
+ //
9352
+ // [
9353
+ // {
9354
+ // "symbol": "BTCUSDT",
9355
+ // "positionAmt": "0.01",
9356
+ // "entryPrice": "44525.0",
9357
+ // "markPrice": "45464.1735922",
9358
+ // "unRealizedProfit": "9.39173592",
9359
+ // "liquidationPrice": "38007.16308568",
9360
+ // "leverage": "100",
9361
+ // "positionSide": "LONG",
9362
+ // "updateTime": 1707371879042,
9363
+ // "maxNotionalValue": "500000.0",
9364
+ // "notional": "454.64173592",
9365
+ // "breakEvenPrice": "44542.81"
9366
+ // }
9367
+ // ]
9368
+ //
9103
9369
  const result = [];
9104
9370
  for (let i = 0; i < response.length; i++) {
9105
9371
  const parsed = this.parsePositionRisk(response[i]);
@@ -9115,15 +9381,19 @@ export default class binance extends Exchange {
9115
9381
  * @description fetch the history of funding payments paid and received on this account
9116
9382
  * @see https://binance-docs.github.io/apidocs/futures/en/#get-income-history-user_data
9117
9383
  * @see https://binance-docs.github.io/apidocs/delivery/en/#get-income-history-user_data
9384
+ * @see https://binance-docs.github.io/apidocs/pm/en/#get-um-income-history-user_data
9385
+ * @see https://binance-docs.github.io/apidocs/pm/en/#get-cm-income-history-user_data
9118
9386
  * @param {string} symbol unified market symbol
9119
9387
  * @param {int} [since] the earliest time in ms to fetch funding history for
9120
9388
  * @param {int} [limit] the maximum number of funding history structures to retrieve
9121
9389
  * @param {object} [params] extra parameters specific to the exchange API endpoint
9390
+ * @param {int} [params.until] timestamp in ms of the latest funding history entry
9391
+ * @param {boolean} [params.portfolioMargin] set to true if you would like to fetch the funding history for a portfolio margin account
9122
9392
  * @returns {object} a [funding history structure]{@link https://docs.ccxt.com/#/?id=funding-history-structure}
9123
9393
  */
9124
9394
  await this.loadMarkets();
9125
9395
  let market = undefined;
9126
- const request = {
9396
+ let request = {
9127
9397
  'incomeType': 'FUNDING_FEE', // "TRANSFER","WELCOME_BONUS", "REALIZED_PNL","FUNDING_FEE", "COMMISSION" and "INSURANCE_CLEAR"
9128
9398
  };
9129
9399
  if (symbol !== undefined) {
@@ -9135,6 +9405,9 @@ export default class binance extends Exchange {
9135
9405
  }
9136
9406
  let subType = undefined;
9137
9407
  [subType, params] = this.handleSubTypeAndParams('fetchFundingHistory', market, params, 'linear');
9408
+ let isPortfolioMargin = undefined;
9409
+ [isPortfolioMargin, params] = this.handleOptionAndParams2(params, 'fetchFundingHistory', 'papi', 'portfolioMargin', false);
9410
+ [request, params] = this.handleUntilOption('endTime', request, params);
9138
9411
  if (since !== undefined) {
9139
9412
  request['startTime'] = since;
9140
9413
  }
@@ -9146,10 +9419,20 @@ export default class binance extends Exchange {
9146
9419
  params = this.omit(params, 'type');
9147
9420
  let response = undefined;
9148
9421
  if (this.isLinear(type, subType)) {
9149
- response = await this.fapiPrivateGetIncome(this.extend(request, params));
9422
+ if (isPortfolioMargin) {
9423
+ response = await this.papiGetUmIncome(this.extend(request, params));
9424
+ }
9425
+ else {
9426
+ response = await this.fapiPrivateGetIncome(this.extend(request, params));
9427
+ }
9150
9428
  }
9151
9429
  else if (this.isInverse(type, subType)) {
9152
- response = await this.dapiPrivateGetIncome(this.extend(request, params));
9430
+ if (isPortfolioMargin) {
9431
+ response = await this.papiGetCmIncome(this.extend(request, params));
9432
+ }
9433
+ else {
9434
+ response = await this.dapiPrivateGetIncome(this.extend(request, params));
9435
+ }
9153
9436
  }
9154
9437
  else {
9155
9438
  throw new NotSupported(this.id + ' fetchFundingHistory() supports linear and inverse contracts only');
@@ -9163,9 +9446,12 @@ export default class binance extends Exchange {
9163
9446
  * @description set the level of leverage for a market
9164
9447
  * @see https://binance-docs.github.io/apidocs/futures/en/#change-initial-leverage-trade
9165
9448
  * @see https://binance-docs.github.io/apidocs/delivery/en/#change-initial-leverage-trade
9449
+ * @see https://binance-docs.github.io/apidocs/pm/en/#change-um-initial-leverage-trade
9450
+ * @see https://binance-docs.github.io/apidocs/pm/en/#change-cm-initial-leverage-trade
9166
9451
  * @param {float} leverage the rate of leverage
9167
9452
  * @param {string} symbol unified market symbol
9168
9453
  * @param {object} [params] extra parameters specific to the exchange API endpoint
9454
+ * @param {boolean} [params.portfolioMargin] set to true if you would like to set the leverage for a trading pair in a portfolio margin account
9169
9455
  * @returns {object} response from the exchange
9170
9456
  */
9171
9457
  if (symbol === undefined) {
@@ -9182,12 +9468,24 @@ export default class binance extends Exchange {
9182
9468
  'symbol': market['id'],
9183
9469
  'leverage': leverage,
9184
9470
  };
9471
+ let isPortfolioMargin = undefined;
9472
+ [isPortfolioMargin, params] = this.handleOptionAndParams2(params, 'setLeverage', 'papi', 'portfolioMargin', false);
9185
9473
  let response = undefined;
9186
9474
  if (market['linear']) {
9187
- response = await this.fapiPrivatePostLeverage(this.extend(request, params));
9475
+ if (isPortfolioMargin) {
9476
+ response = await this.papiPostUmLeverage(this.extend(request, params));
9477
+ }
9478
+ else {
9479
+ response = await this.fapiPrivatePostLeverage(this.extend(request, params));
9480
+ }
9188
9481
  }
9189
9482
  else if (market['inverse']) {
9190
- response = await this.dapiPrivatePostLeverage(this.extend(request, params));
9483
+ if (isPortfolioMargin) {
9484
+ response = await this.papiPostCmLeverage(this.extend(request, params));
9485
+ }
9486
+ else {
9487
+ response = await this.dapiPrivatePostLeverage(this.extend(request, params));
9488
+ }
9191
9489
  }
9192
9490
  else {
9193
9491
  throw new NotSupported(this.id + ' setLeverage() supports linear and inverse contracts only');
@@ -9269,9 +9567,12 @@ export default class binance extends Exchange {
9269
9567
  * @description set hedged to true or false for a market
9270
9568
  * @see https://binance-docs.github.io/apidocs/futures/en/#change-position-mode-trade
9271
9569
  * @see https://binance-docs.github.io/apidocs/delivery/en/#change-position-mode-trade
9570
+ * @see https://binance-docs.github.io/apidocs/pm/en/#change-um-position-mode-trade
9571
+ * @see https://binance-docs.github.io/apidocs/pm/en/#change-cm-position-mode-trade
9272
9572
  * @param {bool} hedged set to true to use dualSidePosition
9273
9573
  * @param {string} symbol not used by binance setPositionMode ()
9274
9574
  * @param {object} [params] extra parameters specific to the exchange API endpoint
9575
+ * @param {boolean} [params.portfolioMargin] set to true if you would like to set the position mode for a portfolio margin account
9275
9576
  * @returns {object} response from the exchange
9276
9577
  */
9277
9578
  const defaultType = this.safeString(this.options, 'defaultType', 'future');
@@ -9279,6 +9580,8 @@ export default class binance extends Exchange {
9279
9580
  params = this.omit(params, ['type']);
9280
9581
  let subType = undefined;
9281
9582
  [subType, params] = this.handleSubTypeAndParams('setPositionMode', undefined, params);
9583
+ let isPortfolioMargin = undefined;
9584
+ [isPortfolioMargin, params] = this.handleOptionAndParams2(params, 'setPositionMode', 'papi', 'portfolioMargin', false);
9282
9585
  let dualSidePosition = undefined;
9283
9586
  if (hedged) {
9284
9587
  dualSidePosition = 'true';
@@ -9291,11 +9594,20 @@ export default class binance extends Exchange {
9291
9594
  };
9292
9595
  let response = undefined;
9293
9596
  if (this.isInverse(type, subType)) {
9294
- response = await this.dapiPrivatePostPositionSideDual(this.extend(request, params));
9597
+ if (isPortfolioMargin) {
9598
+ response = await this.papiPostCmPositionSideDual(this.extend(request, params));
9599
+ }
9600
+ else {
9601
+ response = await this.dapiPrivatePostPositionSideDual(this.extend(request, params));
9602
+ }
9295
9603
  }
9296
9604
  else {
9297
- // default to future
9298
- response = await this.fapiPrivatePostPositionSideDual(this.extend(request, params));
9605
+ if (isPortfolioMargin) {
9606
+ response = await this.papiPostUmPositionSideDual(this.extend(request, params));
9607
+ }
9608
+ else {
9609
+ response = await this.fapiPrivatePostPositionSideDual(this.extend(request, params));
9610
+ }
9299
9611
  }
9300
9612
  //
9301
9613
  // {
@@ -9495,12 +9807,15 @@ export default class binance extends Exchange {
9495
9807
  * @see https://binance-docs.github.io/apidocs/voptions/en/#account-funding-flow-user_data
9496
9808
  * @see https://binance-docs.github.io/apidocs/futures/en/#get-income-history-user_data
9497
9809
  * @see https://binance-docs.github.io/apidocs/delivery/en/#get-income-history-user_data
9810
+ * @see https://binance-docs.github.io/apidocs/pm/en/#get-um-income-history-user_data
9811
+ * @see https://binance-docs.github.io/apidocs/pm/en/#get-cm-income-history-user_data
9498
9812
  * @param {string} code unified currency code
9499
9813
  * @param {int} [since] timestamp in ms of the earliest ledger entry
9500
9814
  * @param {int} [limit] max number of ledger entrys to return
9501
9815
  * @param {object} [params] extra parameters specific to the exchange API endpoint
9502
9816
  * @param {int} [params.until] timestamp in ms of the latest ledger entry
9503
- * @param {boolean} [params.paginate] default false, when true will automatically paginate by calling this endpoint multiple times. See in the docs all the [availble parameters](https://github.com/ccxt/ccxt/wiki/Manual#pagination-params)
9817
+ * @param {boolean} [params.paginate] default false, when true will automatically paginate by calling this endpoint multiple times. See in the docs all the [available parameters](https://github.com/ccxt/ccxt/wiki/Manual#pagination-params)
9818
+ * @param {boolean} [params.portfolioMargin] set to true if you would like to fetch the ledger for a portfolio margin account
9504
9819
  * @returns {object} a [ledger structure]{@link https://docs.ccxt.com/#/?id=ledger-structure}
9505
9820
  */
9506
9821
  await this.loadMarkets();
@@ -9529,6 +9844,8 @@ export default class binance extends Exchange {
9529
9844
  params = this.omit(params, 'until');
9530
9845
  request['endTime'] = until;
9531
9846
  }
9847
+ let isPortfolioMargin = undefined;
9848
+ [isPortfolioMargin, params] = this.handleOptionAndParams2(params, 'fetchLedger', 'papi', 'portfolioMargin', false);
9532
9849
  let response = undefined;
9533
9850
  if (type === 'option') {
9534
9851
  this.checkRequiredArgument('fetchLedger', code, 'code');
@@ -9536,10 +9853,20 @@ export default class binance extends Exchange {
9536
9853
  response = await this.eapiPrivateGetBill(this.extend(request, params));
9537
9854
  }
9538
9855
  else if (this.isLinear(type, subType)) {
9539
- response = await this.fapiPrivateGetIncome(this.extend(request, params));
9856
+ if (isPortfolioMargin) {
9857
+ response = await this.papiGetUmIncome(this.extend(request, params));
9858
+ }
9859
+ else {
9860
+ response = await this.fapiPrivateGetIncome(this.extend(request, params));
9861
+ }
9540
9862
  }
9541
9863
  else if (this.isInverse(type, subType)) {
9542
- response = await this.dapiPrivateGetIncome(this.extend(request, params));
9864
+ if (isPortfolioMargin) {
9865
+ response = await this.papiGetCmIncome(this.extend(request, params));
9866
+ }
9867
+ else {
9868
+ response = await this.dapiPrivateGetIncome(this.extend(request, params));
9869
+ }
9543
9870
  }
9544
9871
  else {
9545
9872
  throw new NotSupported(this.id + ' fetchLedger() supports contract wallets only');
@@ -9557,7 +9884,7 @@ export default class binance extends Exchange {
9557
9884
  // }
9558
9885
  // ]
9559
9886
  //
9560
- // futures (fapi, dapi)
9887
+ // futures (fapi, dapi, papi)
9561
9888
  //
9562
9889
  // [
9563
9890
  // {
@@ -9586,7 +9913,7 @@ export default class binance extends Exchange {
9586
9913
  // "createDate": 1676621042489
9587
9914
  // }
9588
9915
  //
9589
- // futures (fapi, dapi)
9916
+ // futures (fapi, dapi, papi)
9590
9917
  //
9591
9918
  // {
9592
9919
  // "symbol": "",
@@ -9695,7 +10022,7 @@ export default class binance extends Exchange {
9695
10022
  const isSpotOrMargin = (api.indexOf('sapi') > -1 || api === 'private');
9696
10023
  const marketType = isSpotOrMargin ? 'spot' : 'future';
9697
10024
  const defaultId = (!isSpotOrMargin) ? 'x-xcKtGhcu' : 'x-R4BD3S82';
9698
- const broker = this.safeValue(this.options, 'broker', {});
10025
+ const broker = this.safeDict(this.options, 'broker', {});
9699
10026
  const brokerId = this.safeString(broker, marketType, defaultId);
9700
10027
  params['newClientOrderId'] = brokerId + this.uuid22();
9701
10028
  }
@@ -9723,8 +10050,8 @@ export default class binance extends Exchange {
9723
10050
  }
9724
10051
  else if ((path === 'batchOrders') || (path.indexOf('sub-account') >= 0) || (path === 'capital/withdraw/apply') || (path.indexOf('staking') >= 0)) {
9725
10052
  if ((method === 'DELETE') && (path === 'batchOrders')) {
9726
- const orderidlist = this.safeValue(extendedParams, 'orderidlist', []);
9727
- const origclientorderidlist = this.safeValue(extendedParams, 'origclientorderidlist', []);
10053
+ const orderidlist = this.safeList(extendedParams, 'orderidlist', []);
10054
+ const origclientorderidlist = this.safeList(extendedParams, 'origclientorderidlist', []);
9728
10055
  extendedParams = this.omit(extendedParams, ['orderidlist', 'origclientorderidlist']);
9729
10056
  query = this.rawencode(extendedParams);
9730
10057
  const orderidlistLength = orderidlist.length;
@@ -9793,8 +10120,8 @@ export default class binance extends Exchange {
9793
10120
  marketType = 'portfoliomargin';
9794
10121
  }
9795
10122
  if (marketType !== undefined) {
9796
- const exceptionsForMarketType = this.safeValue(this.exceptions, marketType, {});
9797
- return this.safeValue(exceptionsForMarketType, exactOrBroad, {});
10123
+ const exceptionsForMarketType = this.safeDict(this.exceptions, marketType, {});
10124
+ return this.safeDict(exceptionsForMarketType, exactOrBroad, {});
9798
10125
  }
9799
10126
  return {};
9800
10127
  }
@@ -10028,7 +10355,7 @@ export default class binance extends Exchange {
10028
10355
  // },
10029
10356
  // ]
10030
10357
  //
10031
- const rate = this.safeValue(response, 0);
10358
+ const rate = this.safeDict(response, 0);
10032
10359
  return this.parseBorrowRate(rate);
10033
10360
  }
10034
10361
  async fetchBorrowRateHistory(code, since = undefined, limit = undefined, params = {}) {
@@ -10132,7 +10459,7 @@ export default class binance extends Exchange {
10132
10459
  // "success": true
10133
10460
  // }
10134
10461
  //
10135
- const data = this.safeValue(response, 'data');
10462
+ const data = this.safeDict(response, 'data');
10136
10463
  const giftcardCode = this.safeString(data, 'code');
10137
10464
  const id = this.safeString(data, 'referenceNo');
10138
10465
  return {
@@ -10241,7 +10568,7 @@ export default class binance extends Exchange {
10241
10568
  // "total": 1
10242
10569
  // }
10243
10570
  //
10244
- const rows = this.safeValue(response, 'rows');
10571
+ const rows = this.safeList(response, 'rows');
10245
10572
  const interest = this.parseBorrowInterests(rows, market);
10246
10573
  return this.filterByCurrencySinceLimit(interest, code, since, limit);
10247
10574
  }
@@ -10268,9 +10595,11 @@ export default class binance extends Exchange {
10268
10595
  * @name binance#repayCrossMargin
10269
10596
  * @description repay borrowed margin and interest
10270
10597
  * @see https://binance-docs.github.io/apidocs/spot/en/#margin-account-borrow-repay-margin
10598
+ * @see https://binance-docs.github.io/apidocs/pm/en/#margin-account-repay-margin
10271
10599
  * @param {string} code unified currency code of the currency to repay
10272
10600
  * @param {float} amount the amount to repay
10273
10601
  * @param {object} [params] extra parameters specific to the exchange API endpoint
10602
+ * @param {boolean} [params.portfolioMargin] set to true if you would like to repay margin in a portfolio margin account
10274
10603
  * @returns {object} a [margin loan structure]{@link https://docs.ccxt.com/#/?id=margin-loan-structure}
10275
10604
  */
10276
10605
  await this.loadMarkets();
@@ -10278,10 +10607,18 @@ export default class binance extends Exchange {
10278
10607
  const request = {
10279
10608
  'asset': currency['id'],
10280
10609
  'amount': this.currencyToPrecision(code, amount),
10281
- 'isIsolated': 'FALSE',
10282
- 'type': 'REPAY',
10283
10610
  };
10284
- const response = await this.sapiPostMarginBorrowRepay(this.extend(request, params));
10611
+ let response = undefined;
10612
+ let isPortfolioMargin = undefined;
10613
+ [isPortfolioMargin, params] = this.handleOptionAndParams2(params, 'repayCrossMargin', 'papi', 'portfolioMargin', false);
10614
+ if (isPortfolioMargin) {
10615
+ response = await this.papiPostRepayLoan(this.extend(request, params));
10616
+ }
10617
+ else {
10618
+ request['isIsolated'] = 'FALSE';
10619
+ request['type'] = 'REPAY';
10620
+ response = await this.sapiPostMarginBorrowRepay(this.extend(request, params));
10621
+ }
10285
10622
  //
10286
10623
  // {
10287
10624
  // "tranId": 108988250265,
@@ -10327,9 +10664,11 @@ export default class binance extends Exchange {
10327
10664
  * @name binance#borrowCrossMargin
10328
10665
  * @description create a loan to borrow margin
10329
10666
  * @see https://binance-docs.github.io/apidocs/spot/en/#margin-account-borrow-repay-margin
10667
+ * @see https://binance-docs.github.io/apidocs/pm/en/#margin-account-borrow-margin
10330
10668
  * @param {string} code unified currency code of the currency to borrow
10331
10669
  * @param {float} amount the amount to borrow
10332
10670
  * @param {object} [params] extra parameters specific to the exchange API endpoint
10671
+ * @param {boolean} [params.portfolioMargin] set to true if you would like to borrow margin in a portfolio margin account
10333
10672
  * @returns {object} a [margin loan structure]{@link https://docs.ccxt.com/#/?id=margin-loan-structure}
10334
10673
  */
10335
10674
  await this.loadMarkets();
@@ -10337,10 +10676,18 @@ export default class binance extends Exchange {
10337
10676
  const request = {
10338
10677
  'asset': currency['id'],
10339
10678
  'amount': this.currencyToPrecision(code, amount),
10340
- 'isIsolated': 'FALSE',
10341
- 'type': 'BORROW',
10342
10679
  };
10343
- const response = await this.sapiPostMarginBorrowRepay(this.extend(request, params));
10680
+ let response = undefined;
10681
+ let isPortfolioMargin = undefined;
10682
+ [isPortfolioMargin, params] = this.handleOptionAndParams2(params, 'borrowCrossMargin', 'papi', 'portfolioMargin', false);
10683
+ if (isPortfolioMargin) {
10684
+ response = await this.papiPostMarginLoan(this.extend(request, params));
10685
+ }
10686
+ else {
10687
+ request['isIsolated'] = 'FALSE';
10688
+ request['type'] = 'BORROW';
10689
+ response = await this.sapiPostMarginBorrowRepay(this.extend(request, params));
10690
+ }
10344
10691
  //
10345
10692
  // {
10346
10693
  // "tranId": 108988250265,