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
@@ -2649,7 +2649,7 @@ class binance extends binance$1 {
2649
2649
  let minPrecision = undefined;
2650
2650
  let isWithdrawEnabled = true;
2651
2651
  let isDepositEnabled = true;
2652
- const networkList = this.safeValue(entry, 'networkList', []);
2652
+ const networkList = this.safeList(entry, 'networkList', []);
2653
2653
  const fees = {};
2654
2654
  let fee = undefined;
2655
2655
  for (let j = 0; j < networkList.length; j++) {
@@ -2657,12 +2657,12 @@ class binance extends binance$1 {
2657
2657
  const network = this.safeString(networkItem, 'network');
2658
2658
  // const name = this.safeString (networkItem, 'name');
2659
2659
  const withdrawFee = this.safeNumber(networkItem, 'withdrawFee');
2660
- const depositEnable = this.safeValue(networkItem, 'depositEnable');
2661
- const withdrawEnable = this.safeValue(networkItem, 'withdrawEnable');
2660
+ const depositEnable = this.safeBool(networkItem, 'depositEnable');
2661
+ const withdrawEnable = this.safeBool(networkItem, 'withdrawEnable');
2662
2662
  isDepositEnabled = isDepositEnabled || depositEnable;
2663
2663
  isWithdrawEnabled = isWithdrawEnabled || withdrawEnable;
2664
2664
  fees[network] = withdrawFee;
2665
- const isDefault = this.safeValue(networkItem, 'isDefault');
2665
+ const isDefault = this.safeBool(networkItem, 'isDefault');
2666
2666
  if (isDefault || (fee === undefined)) {
2667
2667
  fee = withdrawFee;
2668
2668
  }
@@ -2673,7 +2673,7 @@ class binance extends binance$1 {
2673
2673
  minPrecision = (minPrecision === undefined) ? precisionTick : Precise["default"].stringMin(minPrecision, precisionTick);
2674
2674
  }
2675
2675
  }
2676
- const trading = this.safeValue(entry, 'trading');
2676
+ const trading = this.safeBool(entry, 'trading');
2677
2677
  const active = (isWithdrawEnabled && isDepositEnabled && trading);
2678
2678
  let maxDecimalPlaces = undefined;
2679
2679
  if (minPrecision !== undefined) {
@@ -2709,8 +2709,8 @@ class binance extends binance$1 {
2709
2709
  * @returns {object[]} an array of objects representing market data
2710
2710
  */
2711
2711
  const promisesRaw = [];
2712
- const rawFetchMarkets = this.safeValue(this.options, 'fetchMarkets', ['spot', 'linear', 'inverse']);
2713
- const sandboxMode = this.safeValue(this.options, 'sandboxMode', false);
2712
+ const rawFetchMarkets = this.safeList(this.options, 'fetchMarkets', ['spot', 'linear', 'inverse']);
2713
+ const sandboxMode = this.safeBool(this.options, 'sandboxMode', false);
2714
2714
  const fetchMarkets = [];
2715
2715
  for (let i = 0; i < rawFetchMarkets.length; i++) {
2716
2716
  const type = rawFetchMarkets[i];
@@ -2988,7 +2988,7 @@ class binance extends binance$1 {
2988
2988
  }
2989
2989
  const settle = this.safeCurrencyCode(settleId);
2990
2990
  const spot = !contract;
2991
- const filters = this.safeValue(market, 'filters', []);
2991
+ const filters = this.safeList(market, 'filters', []);
2992
2992
  const filtersByType = this.indexBy(filters, 'filterType');
2993
2993
  const status = this.safeString2(market, 'status', 'contractStatus');
2994
2994
  let contractSize = undefined;
@@ -3011,11 +3011,11 @@ class binance extends binance$1 {
3011
3011
  linear = settle === quote;
3012
3012
  inverse = settle === base;
3013
3013
  const feesType = linear ? 'linear' : 'inverse';
3014
- fees = this.safeValue(this.fees, feesType, {});
3014
+ fees = this.safeDict(this.fees, feesType, {});
3015
3015
  }
3016
3016
  let active = (status === 'TRADING');
3017
3017
  if (spot) {
3018
- const permissions = this.safeValue(market, 'permissions', []);
3018
+ const permissions = this.safeList(market, 'permissions', []);
3019
3019
  for (let j = 0; j < permissions.length; j++) {
3020
3020
  if (permissions[j] === 'TRD_GRP_003') {
3021
3021
  active = false;
@@ -3093,7 +3093,7 @@ class binance extends binance$1 {
3093
3093
  'created': this.safeInteger(market, 'onboardDate'), // present in inverse & linear apis
3094
3094
  };
3095
3095
  if ('PRICE_FILTER' in filtersByType) {
3096
- const filter = this.safeValue(filtersByType, 'PRICE_FILTER', {});
3096
+ const filter = this.safeDict(filtersByType, 'PRICE_FILTER', {});
3097
3097
  // PRICE_FILTER reports zero values for maxPrice
3098
3098
  // since they updated filter types in November 2018
3099
3099
  // https://github.com/ccxt/ccxt/issues/4286
@@ -3105,7 +3105,7 @@ class binance extends binance$1 {
3105
3105
  entry['precision']['price'] = this.precisionFromString(filter['tickSize']);
3106
3106
  }
3107
3107
  if ('LOT_SIZE' in filtersByType) {
3108
- const filter = this.safeValue(filtersByType, 'LOT_SIZE', {});
3108
+ const filter = this.safeDict(filtersByType, 'LOT_SIZE', {});
3109
3109
  const stepSize = this.safeString(filter, 'stepSize');
3110
3110
  entry['precision']['amount'] = this.precisionFromString(stepSize);
3111
3111
  entry['limits']['amount'] = {
@@ -3114,14 +3114,14 @@ class binance extends binance$1 {
3114
3114
  };
3115
3115
  }
3116
3116
  if ('MARKET_LOT_SIZE' in filtersByType) {
3117
- const filter = this.safeValue(filtersByType, 'MARKET_LOT_SIZE', {});
3117
+ const filter = this.safeDict(filtersByType, 'MARKET_LOT_SIZE', {});
3118
3118
  entry['limits']['market'] = {
3119
3119
  'min': this.safeNumber(filter, 'minQty'),
3120
3120
  'max': this.safeNumber(filter, 'maxQty'),
3121
3121
  };
3122
3122
  }
3123
3123
  if (('MIN_NOTIONAL' in filtersByType) || ('NOTIONAL' in filtersByType)) { // notional added in 12/04/23 to spot testnet
3124
- const filter = this.safeValue2(filtersByType, 'MIN_NOTIONAL', 'NOTIONAL', {});
3124
+ const filter = this.safeDict2(filtersByType, 'MIN_NOTIONAL', 'NOTIONAL', {});
3125
3125
  entry['limits']['cost']['min'] = this.safeNumber2(filter, 'minNotional', 'notional');
3126
3126
  entry['limits']['cost']['max'] = this.safeNumber(filter, 'maxNotional');
3127
3127
  }
@@ -3815,7 +3815,7 @@ class binance extends binance$1 {
3815
3815
  }
3816
3816
  }
3817
3817
  if (Array.isArray(response)) {
3818
- const firstTicker = this.safeValue(response, 0, {});
3818
+ const firstTicker = this.safeDict(response, 0, {});
3819
3819
  return this.parseTicker(firstTicker, market);
3820
3820
  }
3821
3821
  return this.parseTicker(response, market);
@@ -5048,7 +5048,7 @@ class binance extends binance$1 {
5048
5048
  // "msg": "Quantity greater than max quantity."
5049
5049
  // }
5050
5050
  //
5051
- // createOrder, fetchOpenOrders: portfolio margin linear swap and future
5051
+ // createOrder, fetchOpenOrders, fetchOrder, cancelOrder: portfolio margin linear swap and future
5052
5052
  //
5053
5053
  // {
5054
5054
  // "symbol": "BTCUSDT",
@@ -5071,7 +5071,7 @@ class binance extends binance$1 {
5071
5071
  // "status": "NEW"
5072
5072
  // }
5073
5073
  //
5074
- // createOrder, fetchOpenOrders: portfolio margin inverse swap and future
5074
+ // createOrder, fetchOpenOrders, fetchOrder, cancelOrder: portfolio margin inverse swap and future
5075
5075
  //
5076
5076
  // {
5077
5077
  // "symbol": "ETHUSD_PERP",
@@ -5137,7 +5137,7 @@ class binance extends binance$1 {
5137
5137
  // "priceProtect": false
5138
5138
  // }
5139
5139
  //
5140
- // createOrder, cancelAllOrders: portfolio margin spot margin
5140
+ // createOrder, cancelAllOrders, cancelOrder: portfolio margin spot margin
5141
5141
  //
5142
5142
  // {
5143
5143
  // "clientOrderId": "x-R4BD3S82e9ef29d8346440f0b28b86",
@@ -5156,7 +5156,7 @@ class binance extends binance$1 {
5156
5156
  // "type": "LIMIT"
5157
5157
  // }
5158
5158
  //
5159
- // fetchOpenOrders: portfolio margin spot margin
5159
+ // fetchOpenOrders, fetchOrder: portfolio margin spot margin
5160
5160
  //
5161
5161
  // {
5162
5162
  // "symbol": "BTCUSDT",
@@ -5181,6 +5181,31 @@ class binance extends binance$1 {
5181
5181
  // "preventedQuantity": null
5182
5182
  // }
5183
5183
  //
5184
+ // cancelOrder: portfolio margin linear and inverse swap conditional
5185
+ //
5186
+ // {
5187
+ // "strategyId": 3733211,
5188
+ // "newClientStrategyId": "x-xcKtGhcuaf166172ed504cd1bc0396",
5189
+ // "strategyType": "STOP",
5190
+ // "strategyStatus": "CANCELED",
5191
+ // "origQty": "0.010",
5192
+ // "price": "35000.00",
5193
+ // "reduceOnly": false,
5194
+ // "side": "BUY",
5195
+ // "positionSide": "BOTH",
5196
+ // "stopPrice": "50000.00", // ignored with trailing orders
5197
+ // "symbol": "BTCUSDT",
5198
+ // "timeInForce": "GTC",
5199
+ // "activatePrice": null, // only return with trailing orders
5200
+ // "priceRate": null, // only return with trailing orders
5201
+ // "bookTime": 1707270098774,
5202
+ // "updateTime": 1707270119261,
5203
+ // "workingType": "CONTRACT_PRICE",
5204
+ // "priceProtect": false,
5205
+ // "goodTillDate": 0,
5206
+ // "selfTradePreventionMode": "NONE"
5207
+ // }
5208
+ //
5184
5209
  const code = this.safeString(order, 'code');
5185
5210
  if (code !== undefined) {
5186
5211
  // cancelOrders/createOrders might have a partial success
@@ -5216,7 +5241,7 @@ class binance extends binance$1 {
5216
5241
  cost = this.safeString(order, 'cumBase', cost);
5217
5242
  let type = this.safeStringLower(order, 'type');
5218
5243
  const side = this.safeStringLower(order, 'side');
5219
- const fills = this.safeValue(order, 'fills', []);
5244
+ const fills = this.safeList(order, 'fills', []);
5220
5245
  let timeInForce = this.safeString(order, 'timeInForce');
5221
5246
  if (timeInForce === 'GTX') {
5222
5247
  // GTX means "Good Till Crossing" and is an equivalent way of saying Post Only
@@ -5249,7 +5274,7 @@ class binance extends binance$1 {
5249
5274
  'type': type,
5250
5275
  'timeInForce': timeInForce,
5251
5276
  'postOnly': postOnly,
5252
- 'reduceOnly': this.safeValue(order, 'reduceOnly'),
5277
+ 'reduceOnly': this.safeBool(order, 'reduceOnly'),
5253
5278
  'side': side,
5254
5279
  'price': price,
5255
5280
  'triggerPrice': stopPrice,
@@ -5283,7 +5308,7 @@ class binance extends binance$1 {
5283
5308
  const side = this.safeString(rawOrder, 'side');
5284
5309
  const amount = this.safeValue(rawOrder, 'amount');
5285
5310
  const price = this.safeValue(rawOrder, 'price');
5286
- const orderParams = this.safeValue(rawOrder, 'params', {});
5311
+ const orderParams = this.safeDict(rawOrder, 'params', {});
5287
5312
  const orderRequest = this.createOrderRequest(marketId, type, side, amount, price, orderParams);
5288
5313
  ordersRequests.push(orderRequest);
5289
5314
  }
@@ -5791,9 +5816,14 @@ class binance extends binance$1 {
5791
5816
  * @see https://binance-docs.github.io/apidocs/delivery/en/#query-order-user_data
5792
5817
  * @see https://binance-docs.github.io/apidocs/voptions/en/#query-single-order-trade
5793
5818
  * @see https://binance-docs.github.io/apidocs/spot/en/#query-margin-account-39-s-order-user_data
5819
+ * @see https://binance-docs.github.io/apidocs/pm/en/#query-um-order-user_data
5820
+ * @see https://binance-docs.github.io/apidocs/pm/en/#query-cm-order-user_data
5821
+ * @see https://binance-docs.github.io/apidocs/pm/en/#query-margin-account-order-user_data
5822
+ * @param {string} id the order id
5794
5823
  * @param {string} symbol unified symbol of the market the order was made in
5795
5824
  * @param {object} [params] extra parameters specific to the exchange API endpoint
5796
5825
  * @param {string} [params.marginMode] 'cross' or 'isolated', for spot margin trading
5826
+ * @param {boolean} [params.portfolioMargin] set to true if you would like to fetch an order in a portfolio margin account
5797
5827
  * @returns {object} An [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
5798
5828
  */
5799
5829
  if (symbol === undefined) {
@@ -5803,11 +5833,14 @@ class binance extends binance$1 {
5803
5833
  const market = this.market(symbol);
5804
5834
  const defaultType = this.safeString2(this.options, 'fetchOrder', 'defaultType', 'spot');
5805
5835
  const type = this.safeString(params, 'type', defaultType);
5806
- const [marginMode, query] = this.handleMarginModeAndParams('fetchOrder', params);
5836
+ let marginMode = undefined;
5837
+ [marginMode, params] = this.handleMarginModeAndParams('fetchOrder', params);
5838
+ let isPortfolioMargin = undefined;
5839
+ [isPortfolioMargin, params] = this.handleOptionAndParams2(params, 'fetchOrder', 'papi', 'portfolioMargin', false);
5807
5840
  const request = {
5808
5841
  'symbol': market['id'],
5809
5842
  };
5810
- const clientOrderId = this.safeValue2(params, 'origClientOrderId', 'clientOrderId');
5843
+ const clientOrderId = this.safeString2(params, 'origClientOrderId', 'clientOrderId');
5811
5844
  if (clientOrderId !== undefined) {
5812
5845
  if (market['option']) {
5813
5846
  request['clientOrderId'] = clientOrderId;
@@ -5819,25 +5852,40 @@ class binance extends binance$1 {
5819
5852
  else {
5820
5853
  request['orderId'] = id;
5821
5854
  }
5822
- const requestParams = this.omit(query, ['type', 'clientOrderId', 'origClientOrderId']);
5855
+ params = this.omit(params, ['type', 'clientOrderId', 'origClientOrderId']);
5823
5856
  let response = undefined;
5824
5857
  if (market['option']) {
5825
- response = await this.eapiPrivateGetOrder(this.extend(request, requestParams));
5858
+ response = await this.eapiPrivateGetOrder(this.extend(request, params));
5826
5859
  }
5827
5860
  else if (market['linear']) {
5828
- response = await this.fapiPrivateGetOrder(this.extend(request, requestParams));
5861
+ if (isPortfolioMargin) {
5862
+ response = await this.papiGetUmOrder(this.extend(request, params));
5863
+ }
5864
+ else {
5865
+ response = await this.fapiPrivateGetOrder(this.extend(request, params));
5866
+ }
5829
5867
  }
5830
5868
  else if (market['inverse']) {
5831
- response = await this.dapiPrivateGetOrder(this.extend(request, requestParams));
5869
+ if (isPortfolioMargin) {
5870
+ response = await this.papiGetCmOrder(this.extend(request, params));
5871
+ }
5872
+ else {
5873
+ response = await this.dapiPrivateGetOrder(this.extend(request, params));
5874
+ }
5832
5875
  }
5833
- else if (type === 'margin' || marginMode !== undefined) {
5834
- if (marginMode === 'isolated') {
5835
- request['isIsolated'] = true;
5876
+ else if ((type === 'margin') || (marginMode !== undefined) || isPortfolioMargin) {
5877
+ if (isPortfolioMargin) {
5878
+ response = await this.papiGetMarginOrder(this.extend(request, params));
5879
+ }
5880
+ else {
5881
+ if (marginMode === 'isolated') {
5882
+ request['isIsolated'] = true;
5883
+ }
5884
+ response = await this.sapiGetMarginOrder(this.extend(request, params));
5836
5885
  }
5837
- response = await this.sapiGetMarginOrder(this.extend(request, requestParams));
5838
5886
  }
5839
5887
  else {
5840
- response = await this.privateGetOrder(this.extend(request, requestParams));
5888
+ response = await this.privateGetOrder(this.extend(request, params));
5841
5889
  }
5842
5890
  return this.parseOrder(response, market);
5843
5891
  }
@@ -6152,9 +6200,16 @@ class binance extends binance$1 {
6152
6200
  * @see https://binance-docs.github.io/apidocs/delivery/en/#cancel-order-trade
6153
6201
  * @see https://binance-docs.github.io/apidocs/voptions/en/#cancel-option-order-trade
6154
6202
  * @see https://binance-docs.github.io/apidocs/spot/en/#margin-account-cancel-order-trade
6203
+ * @see https://binance-docs.github.io/apidocs/pm/en/#cancel-um-order-trade
6204
+ * @see https://binance-docs.github.io/apidocs/pm/en/#cancel-cm-order-trade
6205
+ * @see https://binance-docs.github.io/apidocs/pm/en/#cancel-um-conditional-order-trade
6206
+ * @see https://binance-docs.github.io/apidocs/pm/en/#cancel-cm-conditional-order-trade
6207
+ * @see https://binance-docs.github.io/apidocs/pm/en/#cancel-margin-account-order-trade
6155
6208
  * @param {string} id order id
6156
6209
  * @param {string} symbol unified symbol of the market the order was made in
6157
6210
  * @param {object} [params] extra parameters specific to the exchange API endpoint
6211
+ * @param {boolean} [params.portfolioMargin] set to true if you would like to cancel an order in a portfolio margin account
6212
+ * @param {boolean} [params.stop] set to true if you would like to cancel a portfolio margin account conditional order
6158
6213
  * @returns {object} An [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
6159
6214
  */
6160
6215
  if (symbol === undefined) {
@@ -6164,43 +6219,80 @@ class binance extends binance$1 {
6164
6219
  const market = this.market(symbol);
6165
6220
  const defaultType = this.safeString2(this.options, 'cancelOrder', 'defaultType', 'spot');
6166
6221
  const type = this.safeString(params, 'type', defaultType);
6167
- const [marginMode, query] = this.handleMarginModeAndParams('cancelOrder', params);
6222
+ let marginMode = undefined;
6223
+ [marginMode, params] = this.handleMarginModeAndParams('cancelOrder', params);
6224
+ let isPortfolioMargin = undefined;
6225
+ [isPortfolioMargin, params] = this.handleOptionAndParams2(params, 'cancelOrder', 'papi', 'portfolioMargin', false);
6226
+ const isConditional = this.safeBool2(params, 'stop', 'conditional');
6168
6227
  const request = {
6169
6228
  'symbol': market['id'],
6170
- // 'orderId': id,
6171
- // 'origClientOrderId': id,
6172
6229
  };
6173
- const clientOrderId = this.safeValue2(params, 'origClientOrderId', 'clientOrderId');
6230
+ const clientOrderId = this.safeStringN(params, ['origClientOrderId', 'clientOrderId', 'newClientStrategyId']);
6174
6231
  if (clientOrderId !== undefined) {
6175
6232
  if (market['option']) {
6176
6233
  request['clientOrderId'] = clientOrderId;
6177
6234
  }
6178
6235
  else {
6179
- request['origClientOrderId'] = clientOrderId;
6236
+ if (isPortfolioMargin && isConditional) {
6237
+ request['newClientStrategyId'] = clientOrderId;
6238
+ }
6239
+ else {
6240
+ request['origClientOrderId'] = clientOrderId;
6241
+ }
6180
6242
  }
6181
6243
  }
6182
6244
  else {
6183
- request['orderId'] = id;
6245
+ if (isPortfolioMargin && isConditional) {
6246
+ request['strategyId'] = id;
6247
+ }
6248
+ else {
6249
+ request['orderId'] = id;
6250
+ }
6184
6251
  }
6185
- const requestParams = this.omit(query, ['type', 'origClientOrderId', 'clientOrderId']);
6252
+ params = this.omit(params, ['type', 'origClientOrderId', 'clientOrderId', 'newClientStrategyId', 'stop', 'conditional']);
6186
6253
  let response = undefined;
6187
6254
  if (market['option']) {
6188
- response = await this.eapiPrivateDeleteOrder(this.extend(request, requestParams));
6255
+ response = await this.eapiPrivateDeleteOrder(this.extend(request, params));
6189
6256
  }
6190
6257
  else if (market['linear']) {
6191
- response = await this.fapiPrivateDeleteOrder(this.extend(request, requestParams));
6258
+ if (isPortfolioMargin) {
6259
+ if (isConditional) {
6260
+ response = await this.papiDeleteUmConditionalOrder(this.extend(request, params));
6261
+ }
6262
+ else {
6263
+ response = await this.papiDeleteUmOrder(this.extend(request, params));
6264
+ }
6265
+ }
6266
+ else {
6267
+ response = await this.fapiPrivateDeleteOrder(this.extend(request, params));
6268
+ }
6192
6269
  }
6193
6270
  else if (market['inverse']) {
6194
- response = await this.dapiPrivateDeleteOrder(this.extend(request, requestParams));
6271
+ if (isPortfolioMargin) {
6272
+ if (isConditional) {
6273
+ response = await this.papiDeleteCmConditionalOrder(this.extend(request, params));
6274
+ }
6275
+ else {
6276
+ response = await this.papiDeleteCmOrder(this.extend(request, params));
6277
+ }
6278
+ }
6279
+ else {
6280
+ response = await this.dapiPrivateDeleteOrder(this.extend(request, params));
6281
+ }
6195
6282
  }
6196
- else if (type === 'margin' || marginMode !== undefined) {
6197
- if (marginMode === 'isolated') {
6198
- request['isIsolated'] = true;
6283
+ else if ((type === 'margin') || (marginMode !== undefined) || isPortfolioMargin) {
6284
+ if (isPortfolioMargin) {
6285
+ response = await this.papiDeleteMarginOrder(this.extend(request, params));
6286
+ }
6287
+ else {
6288
+ if (marginMode === 'isolated') {
6289
+ request['isIsolated'] = true;
6290
+ }
6291
+ response = await this.sapiDeleteMarginOrder(this.extend(request, params));
6199
6292
  }
6200
- response = await this.sapiDeleteMarginOrder(this.extend(request, requestParams));
6201
6293
  }
6202
6294
  else {
6203
- response = await this.privateDeleteOrder(this.extend(request, requestParams));
6295
+ response = await this.privateDeleteOrder(this.extend(request, params));
6204
6296
  }
6205
6297
  return this.parseOrder(response, market);
6206
6298
  }
@@ -6608,11 +6700,11 @@ class binance extends binance$1 {
6608
6700
  // },
6609
6701
  // ]
6610
6702
  // }
6611
- const results = this.safeValue(response, 'userAssetDribblets', []);
6703
+ const results = this.safeList(response, 'userAssetDribblets', []);
6612
6704
  const rows = this.safeInteger(response, 'total', 0);
6613
6705
  const data = [];
6614
6706
  for (let i = 0; i < rows; i++) {
6615
- const logs = this.safeValue(results[i], 'userAssetDribbletDetails', []);
6707
+ const logs = this.safeList(results[i], 'userAssetDribbletDetails', []);
6616
6708
  for (let j = 0; j < logs.length; j++) {
6617
6709
  logs[j]['isDustTrade'] = true;
6618
6710
  data.push(logs[j]);
@@ -6719,7 +6811,7 @@ class binance extends binance$1 {
6719
6811
  let currency = undefined;
6720
6812
  let response = undefined;
6721
6813
  const request = {};
6722
- const legalMoney = this.safeValue(this.options, 'legalMoney', {});
6814
+ const legalMoney = this.safeDict(this.options, 'legalMoney', {});
6723
6815
  const fiatOnly = this.safeBool(params, 'fiat', false);
6724
6816
  params = this.omit(params, 'fiatOnly');
6725
6817
  const until = this.safeInteger(params, 'until');
@@ -6831,7 +6923,7 @@ class binance extends binance$1 {
6831
6923
  if (paginate) {
6832
6924
  return await this.fetchPaginatedCallDynamic('fetchWithdrawals', code, since, limit, params);
6833
6925
  }
6834
- const legalMoney = this.safeValue(this.options, 'legalMoney', {});
6926
+ const legalMoney = this.safeDict(this.options, 'legalMoney', {});
6835
6927
  const fiatOnly = this.safeBool(params, 'fiat', false);
6836
6928
  params = this.omit(params, 'fiatOnly');
6837
6929
  const request = {};
@@ -6975,7 +7067,7 @@ class binance extends binance$1 {
6975
7067
  'Refund Failed': 'failed',
6976
7068
  },
6977
7069
  };
6978
- const statuses = this.safeValue(statusesByType, type, {});
7070
+ const statuses = this.safeDict(statusesByType, type, {});
6979
7071
  return this.safeString(statuses, status, status);
6980
7072
  }
6981
7073
  parseTransaction(transaction, currency = undefined) {
@@ -7140,7 +7232,7 @@ class binance extends binance$1 {
7140
7232
  const type = this.safeString(transfer, 'type');
7141
7233
  let fromAccount = undefined;
7142
7234
  let toAccount = undefined;
7143
- const accountsById = this.safeValue(this.options, 'accountsById', {});
7235
+ const accountsById = this.safeDict(this.options, 'accountsById', {});
7144
7236
  if (type !== undefined) {
7145
7237
  const parts = type.split('_');
7146
7238
  fromAccount = this.safeValue(parts, 0);
@@ -7176,20 +7268,16 @@ class binance extends binance$1 {
7176
7268
  // }
7177
7269
  //
7178
7270
  const marketId = this.safeString(income, 'symbol');
7179
- const symbol = this.safeSymbol(marketId, market, undefined, 'swap');
7180
- const amount = this.safeNumber(income, 'income');
7181
7271
  const currencyId = this.safeString(income, 'asset');
7182
- const code = this.safeCurrencyCode(currencyId);
7183
- const id = this.safeString(income, 'tranId');
7184
7272
  const timestamp = this.safeInteger(income, 'time');
7185
7273
  return {
7186
7274
  'info': income,
7187
- 'symbol': symbol,
7188
- 'code': code,
7275
+ 'symbol': this.safeSymbol(marketId, market, undefined, 'swap'),
7276
+ 'code': this.safeCurrencyCode(currencyId),
7189
7277
  'timestamp': timestamp,
7190
7278
  'datetime': this.iso8601(timestamp),
7191
- 'id': id,
7192
- 'amount': amount,
7279
+ 'id': this.safeString(income, 'tranId'),
7280
+ 'amount': this.safeNumber(income, 'income'),
7193
7281
  };
7194
7282
  }
7195
7283
  async transfer(code, amount, fromAccount, toAccount, params = {}) {
@@ -7238,7 +7326,7 @@ class binance extends binance$1 {
7238
7326
  throw new errors.ArgumentsRequired(this.id + ' transfer () requires params["symbol"] when toAccount is ' + toAccount);
7239
7327
  }
7240
7328
  }
7241
- const accountsById = this.safeValue(this.options, 'accountsById', {});
7329
+ const accountsById = this.safeDict(this.options, 'accountsById', {});
7242
7330
  const fromIsolated = !(fromId in accountsById);
7243
7331
  const toIsolated = !(toId in accountsById);
7244
7332
  if (fromIsolated && (market === undefined)) {
@@ -7328,7 +7416,7 @@ class binance extends binance$1 {
7328
7416
  const defaultTo = (fromAccount === 'future') ? 'spot' : 'future';
7329
7417
  const toAccount = this.safeString(params, 'toAccount', defaultTo);
7330
7418
  let type = this.safeString(params, 'type');
7331
- const accountsByType = this.safeValue(this.options, 'accountsByType', {});
7419
+ const accountsByType = this.safeDict(this.options, 'accountsByType', {});
7332
7420
  const fromId = this.safeString(accountsByType, fromAccount);
7333
7421
  const toId = this.safeString(accountsByType, toAccount);
7334
7422
  if (type === undefined) {
@@ -7372,7 +7460,7 @@ class binance extends binance$1 {
7372
7460
  // ]
7373
7461
  // }
7374
7462
  //
7375
- const rows = this.safeValue(response, 'rows', []);
7463
+ const rows = this.safeList(response, 'rows', []);
7376
7464
  return this.parseTransfers(rows, currency, since, limit);
7377
7465
  }
7378
7466
  async fetchDepositAddress(code, params = {}) {
@@ -7391,7 +7479,7 @@ class binance extends binance$1 {
7391
7479
  'coin': currency['id'],
7392
7480
  // 'network': 'ETH', // 'BSC', 'XMR', you can get network and isDefault in networkList in the response of sapiGetCapitalConfigDetail
7393
7481
  };
7394
- const networks = this.safeValue(this.options, 'networks', {});
7482
+ const networks = this.safeDict(this.options, 'networks', {});
7395
7483
  let network = this.safeStringUpper(params, 'network'); // this line allows the user to specify either ERC20 or ETH
7396
7484
  network = this.safeString(networks, network, network); // handle ERC20>ETH alias
7397
7485
  if (network !== undefined) {
@@ -7418,7 +7506,7 @@ class binance extends binance$1 {
7418
7506
  const url = this.safeString(response, 'url');
7419
7507
  let impliedNetwork = undefined;
7420
7508
  if (url !== undefined) {
7421
- const reverseNetworks = this.safeValue(this.options, 'reverseNetworks', {});
7509
+ const reverseNetworks = this.safeDict(this.options, 'reverseNetworks', {});
7422
7510
  const parts = url.split('/');
7423
7511
  let topLevel = this.safeString(parts, 2);
7424
7512
  if ((topLevel === 'blockchair.com') || (topLevel === 'viewblock.io')) {
@@ -7433,7 +7521,7 @@ class binance extends binance$1 {
7433
7521
  'TRX': { 'TRC20': 'TRX' },
7434
7522
  });
7435
7523
  if (code in impliedNetworks) {
7436
- const conversion = this.safeValue(impliedNetworks, code, {});
7524
+ const conversion = this.safeDict(impliedNetworks, code, {});
7437
7525
  impliedNetwork = this.safeString(conversion, impliedNetwork, impliedNetwork);
7438
7526
  }
7439
7527
  }
@@ -7549,7 +7637,7 @@ class binance extends binance$1 {
7549
7637
  const entry = response[i];
7550
7638
  const currencyId = this.safeString(entry, 'coin');
7551
7639
  const code = this.safeCurrencyCode(currencyId);
7552
- const networkList = this.safeValue(entry, 'networkList', []);
7640
+ const networkList = this.safeList(entry, 'networkList', []);
7553
7641
  withdrawFees[code] = {};
7554
7642
  for (let j = 0; j < networkList.length; j++) {
7555
7643
  const networkEntry = networkList[j];
@@ -7662,14 +7750,14 @@ class binance extends binance$1 {
7662
7750
  // ]
7663
7751
  // }
7664
7752
  //
7665
- const networkList = this.safeValue(fee, 'networkList', []);
7753
+ const networkList = this.safeList(fee, 'networkList', []);
7666
7754
  const result = this.depositWithdrawFee(fee);
7667
7755
  for (let j = 0; j < networkList.length; j++) {
7668
7756
  const networkEntry = networkList[j];
7669
7757
  const networkId = this.safeString(networkEntry, 'network');
7670
7758
  const networkCode = this.networkIdToCode(networkId);
7671
7759
  const withdrawFee = this.safeNumber(networkEntry, 'withdrawFee');
7672
- const isDefault = this.safeValue(networkEntry, 'isDefault');
7760
+ const isDefault = this.safeBool(networkEntry, 'isDefault');
7673
7761
  if (isDefault === true) {
7674
7762
  result['withdraw'] = {
7675
7763
  'fee': withdrawFee,
@@ -7717,7 +7805,7 @@ class binance extends binance$1 {
7717
7805
  if (tag !== undefined) {
7718
7806
  request['addressTag'] = tag;
7719
7807
  }
7720
- const networks = this.safeValue(this.options, 'networks', {});
7808
+ const networks = this.safeDict(this.options, 'networks', {});
7721
7809
  let network = this.safeStringUpper(params, 'network'); // this line allows the user to specify either ERC20 or ETH
7722
7810
  network = this.safeString(networks, network, network); // handle ERC20>ETH alias
7723
7811
  if (network !== undefined) {
@@ -7809,7 +7897,7 @@ class binance extends binance$1 {
7809
7897
  //
7810
7898
  let data = response;
7811
7899
  if (Array.isArray(data)) {
7812
- data = this.safeValue(data, 0, {});
7900
+ data = this.safeDict(data, 0, {});
7813
7901
  }
7814
7902
  return this.parseTradingFee(data);
7815
7903
  }
@@ -8223,8 +8311,8 @@ class binance extends binance$1 {
8223
8311
  };
8224
8312
  }
8225
8313
  parseAccountPositions(account) {
8226
- const positions = this.safeValue(account, 'positions');
8227
- const assets = this.safeValue(account, 'assets', []);
8314
+ const positions = this.safeList(account, 'positions');
8315
+ const assets = this.safeList(account, 'assets', []);
8228
8316
  const balances = {};
8229
8317
  for (let i = 0; i < assets.length; i++) {
8230
8318
  const entry = assets[i];
@@ -8243,13 +8331,17 @@ class binance extends binance$1 {
8243
8331
  const marketId = this.safeString(position, 'symbol');
8244
8332
  const market = this.safeMarket(marketId, undefined, undefined, 'contract');
8245
8333
  const code = market['linear'] ? market['quote'] : market['base'];
8246
- // sometimes not all the codes are correctly returned...
8247
- if (code in balances) {
8248
- const parsed = this.parseAccountPosition(this.extend(position, {
8249
- 'crossMargin': balances[code]['crossMargin'],
8250
- 'crossWalletBalance': balances[code]['crossWalletBalance'],
8251
- }), market);
8252
- result.push(parsed);
8334
+ const maintenanceMargin = this.safeString(position, 'maintMargin');
8335
+ // check for maintenance margin so empty positions are not returned
8336
+ if ((maintenanceMargin !== '0') && (maintenanceMargin !== '0.00000000')) {
8337
+ // sometimes not all the codes are correctly returned...
8338
+ if (code in balances) {
8339
+ const parsed = this.parseAccountPosition(this.extend(position, {
8340
+ 'crossMargin': balances[code]['crossMargin'],
8341
+ 'crossWalletBalance': balances[code]['crossWalletBalance'],
8342
+ }), market);
8343
+ result.push(parsed);
8344
+ }
8253
8345
  }
8254
8346
  }
8255
8347
  return result;
@@ -8257,6 +8349,7 @@ class binance extends binance$1 {
8257
8349
  parseAccountPosition(position, market = undefined) {
8258
8350
  //
8259
8351
  // usdm
8352
+ //
8260
8353
  // {
8261
8354
  // "symbol": "BTCBUSD",
8262
8355
  // "initialMargin": "0",
@@ -8277,6 +8370,7 @@ class binance extends binance$1 {
8277
8370
  // }
8278
8371
  //
8279
8372
  // coinm
8373
+ //
8280
8374
  // {
8281
8375
  // "symbol": "BTCUSD_210625",
8282
8376
  // "initialMargin": "0.00024393",
@@ -8295,6 +8389,46 @@ class binance extends binance$1 {
8295
8389
  // "crossWalletBalance": "34",
8296
8390
  // }
8297
8391
  //
8392
+ // linear portfolio margin
8393
+ //
8394
+ // {
8395
+ // "symbol": "CTSIUSDT",
8396
+ // "initialMargin": "0",
8397
+ // "maintMargin": "0",
8398
+ // "unrealizedProfit": "0.00000000",
8399
+ // "positionInitialMargin": "0",
8400
+ // "openOrderInitialMargin": "0",
8401
+ // "leverage": "20",
8402
+ // "entryPrice": "0.0",
8403
+ // "maxNotional": "25000",
8404
+ // "bidNotional": "0",
8405
+ // "askNotional": "0",
8406
+ // "positionSide": "SHORT",
8407
+ // "positionAmt": "0",
8408
+ // "updateTime": 0,
8409
+ // "notional": "0",
8410
+ // "breakEvenPrice": "0.0"
8411
+ // }
8412
+ //
8413
+ // inverse portoflio margin
8414
+ //
8415
+ // {
8416
+ // "symbol": "TRXUSD_PERP",
8417
+ // "initialMargin": "0",
8418
+ // "maintMargin": "0",
8419
+ // "unrealizedProfit": "0.00000000",
8420
+ // "positionInitialMargin": "0",
8421
+ // "openOrderInitialMargin": "0",
8422
+ // "leverage": "20",
8423
+ // "entryPrice": "0.00000000",
8424
+ // "positionSide": "SHORT",
8425
+ // "positionAmt": "0",
8426
+ // "maxQty": "5000000",
8427
+ // "updateTime": 0,
8428
+ // "notionalValue": "0",
8429
+ // "breakEvenPrice": "0.00000000"
8430
+ // }
8431
+ //
8298
8432
  const marketId = this.safeString(position, 'symbol');
8299
8433
  market = this.safeMarket(marketId, market, undefined, 'contract');
8300
8434
  const symbol = this.safeString(market, 'symbol');
@@ -8325,8 +8459,8 @@ class binance extends binance$1 {
8325
8459
  contractsStringAbs = Precise["default"].stringDiv(Precise["default"].stringAdd(contractsString, '0.5'), '1', 0);
8326
8460
  }
8327
8461
  const contracts = this.parseNumber(contractsStringAbs);
8328
- const leverageBrackets = this.safeValue(this.options, 'leverageBrackets', {});
8329
- const leverageBracket = this.safeValue(leverageBrackets, symbol, []);
8462
+ const leverageBrackets = this.safeDict(this.options, 'leverageBrackets', {});
8463
+ const leverageBracket = this.safeList(leverageBrackets, symbol, []);
8330
8464
  let maintenanceMarginPercentageString = undefined;
8331
8465
  for (let i = 0; i < leverageBracket.length; i++) {
8332
8466
  const bracket = leverageBracket[i];
@@ -8342,7 +8476,7 @@ class binance extends binance$1 {
8342
8476
  if (timestamp === 0) {
8343
8477
  timestamp = undefined;
8344
8478
  }
8345
- const isolated = this.safeValue(position, 'isolated');
8479
+ const isolated = this.safeBool(position, 'isolated');
8346
8480
  let marginMode = undefined;
8347
8481
  let collateralString = undefined;
8348
8482
  let walletBalance = undefined;
@@ -8495,11 +8629,45 @@ class binance extends binance$1 {
8495
8629
  // "isolatedWallet": "0.00268058"
8496
8630
  // }
8497
8631
  //
8632
+ // inverse portfolio margin
8633
+ //
8634
+ // {
8635
+ // "symbol": "ETHUSD_PERP",
8636
+ // "positionAmt": "1",
8637
+ // "entryPrice": "2422.400000007",
8638
+ // "markPrice": "2424.51267823",
8639
+ // "unRealizedProfit": "0.0000036",
8640
+ // "liquidationPrice": "293.57678898",
8641
+ // "leverage": "100",
8642
+ // "positionSide": "LONG",
8643
+ // "updateTime": 1707371941861,
8644
+ // "maxQty": "15",
8645
+ // "notionalValue": "0.00412454",
8646
+ // "breakEvenPrice": "2423.368960034"
8647
+ // }
8648
+ //
8649
+ // linear portfolio margin
8650
+ //
8651
+ // {
8652
+ // "symbol": "BTCUSDT",
8653
+ // "positionAmt": "0.01",
8654
+ // "entryPrice": "44525.0",
8655
+ // "markPrice": "45464.1735922",
8656
+ // "unRealizedProfit": "9.39173592",
8657
+ // "liquidationPrice": "38007.16308568",
8658
+ // "leverage": "100",
8659
+ // "positionSide": "LONG",
8660
+ // "updateTime": 1707371879042,
8661
+ // "maxNotionalValue": "500000.0",
8662
+ // "notional": "454.64173592",
8663
+ // "breakEvenPrice": "44542.81"
8664
+ // }
8665
+ //
8498
8666
  const marketId = this.safeString(position, 'symbol');
8499
8667
  market = this.safeMarket(marketId, market, undefined, 'contract');
8500
8668
  const symbol = this.safeString(market, 'symbol');
8501
- const leverageBrackets = this.safeValue(this.options, 'leverageBrackets', {});
8502
- const leverageBracket = this.safeValue(leverageBrackets, symbol, []);
8669
+ const leverageBrackets = this.safeDict(this.options, 'leverageBrackets', {});
8670
+ const leverageBracket = this.safeList(leverageBrackets, symbol, []);
8503
8671
  const notionalString = this.safeString2(position, 'notional', 'notionalValue');
8504
8672
  const notionalStringAbs = Precise["default"].stringAbs(notionalString);
8505
8673
  let maintenanceMarginPercentageString = undefined;
@@ -8536,7 +8704,7 @@ class binance extends binance$1 {
8536
8704
  const linear = ('notional' in position);
8537
8705
  if (marginMode === 'cross') {
8538
8706
  // calculate collateral
8539
- const precision = this.safeValue(market, 'precision', {});
8707
+ const precision = this.safeDict(market, 'precision', {});
8540
8708
  if (linear) {
8541
8709
  // walletBalance = (liquidationPrice * (±1 + mmp) ± entryPrice) * contracts
8542
8710
  let onePlusMaintenanceMarginPercentageString = undefined;
@@ -8643,12 +8811,24 @@ class binance extends binance$1 {
8643
8811
  const query = this.omit(params, 'type');
8644
8812
  let subType = undefined;
8645
8813
  [subType, params] = this.handleSubTypeAndParams('loadLeverageBrackets', undefined, params, 'linear');
8814
+ let isPortfolioMargin = undefined;
8815
+ [isPortfolioMargin, params] = this.handleOptionAndParams2(params, 'loadLeverageBrackets', 'papi', 'portfolioMargin', false);
8646
8816
  let response = undefined;
8647
8817
  if (this.isLinear(type, subType)) {
8648
- response = await this.fapiPrivateGetLeverageBracket(query);
8818
+ if (isPortfolioMargin) {
8819
+ response = await this.papiGetUmLeverageBracket(query);
8820
+ }
8821
+ else {
8822
+ response = await this.fapiPrivateGetLeverageBracket(query);
8823
+ }
8649
8824
  }
8650
8825
  else if (this.isInverse(type, subType)) {
8651
- response = await this.dapiPrivateV2GetLeverageBracket(query);
8826
+ if (isPortfolioMargin) {
8827
+ response = await this.papiGetCmLeverageBracket(query);
8828
+ }
8829
+ else {
8830
+ response = await this.dapiPrivateV2GetLeverageBracket(query);
8831
+ }
8652
8832
  }
8653
8833
  else {
8654
8834
  throw new errors.NotSupported(this.id + ' loadLeverageBrackets() supports linear and inverse contracts only');
@@ -8658,7 +8838,7 @@ class binance extends binance$1 {
8658
8838
  const entry = response[i];
8659
8839
  const marketId = this.safeString(entry, 'symbol');
8660
8840
  const symbol = this.safeSymbol(marketId, undefined, undefined, 'contract');
8661
- const brackets = this.safeValue(entry, 'brackets', []);
8841
+ const brackets = this.safeList(entry, 'brackets', []);
8662
8842
  const result = [];
8663
8843
  for (let j = 0; j < brackets.length; j++) {
8664
8844
  const bracket = brackets[j];
@@ -8678,8 +8858,11 @@ class binance extends binance$1 {
8678
8858
  * @description retrieve information on the maximum leverage, and maintenance margin for trades of varying trade sizes
8679
8859
  * @see https://binance-docs.github.io/apidocs/futures/en/#notional-and-leverage-brackets-user_data
8680
8860
  * @see https://binance-docs.github.io/apidocs/delivery/en/#notional-bracket-for-symbol-user_data
8861
+ * @see https://binance-docs.github.io/apidocs/pm/en/#um-notional-and-leverage-brackets-user_data
8862
+ * @see https://binance-docs.github.io/apidocs/pm/en/#cm-notional-and-leverage-brackets-user_data
8681
8863
  * @param {string[]|undefined} symbols list of unified market symbols
8682
8864
  * @param {object} [params] extra parameters specific to the exchange API endpoint
8865
+ * @param {boolean} [params.portfolioMargin] set to true if you would like to fetch the leverage tiers for a portfolio margin account
8683
8866
  * @returns {object} a dictionary of [leverage tiers structures]{@link https://docs.ccxt.com/#/?id=leverage-tiers-structure}, indexed by market symbols
8684
8867
  */
8685
8868
  await this.loadMarkets();
@@ -8687,12 +8870,24 @@ class binance extends binance$1 {
8687
8870
  [type, params] = this.handleMarketTypeAndParams('fetchLeverageTiers', undefined, params);
8688
8871
  let subType = undefined;
8689
8872
  [subType, params] = this.handleSubTypeAndParams('fetchLeverageTiers', undefined, params, 'linear');
8873
+ let isPortfolioMargin = undefined;
8874
+ [isPortfolioMargin, params] = this.handleOptionAndParams2(params, 'fetchLeverageTiers', 'papi', 'portfolioMargin', false);
8690
8875
  let response = undefined;
8691
8876
  if (this.isLinear(type, subType)) {
8692
- response = await this.fapiPrivateGetLeverageBracket(params);
8877
+ if (isPortfolioMargin) {
8878
+ response = await this.papiGetUmLeverageBracket(params);
8879
+ }
8880
+ else {
8881
+ response = await this.fapiPrivateGetLeverageBracket(params);
8882
+ }
8693
8883
  }
8694
8884
  else if (this.isInverse(type, subType)) {
8695
- response = await this.dapiPrivateV2GetLeverageBracket(params);
8885
+ if (isPortfolioMargin) {
8886
+ response = await this.papiGetCmLeverageBracket(params);
8887
+ }
8888
+ else {
8889
+ response = await this.dapiPrivateV2GetLeverageBracket(params);
8890
+ }
8696
8891
  }
8697
8892
  else {
8698
8893
  throw new errors.NotSupported(this.id + ' fetchLeverageTiers() supports linear and inverse contracts only');
@@ -8762,7 +8957,7 @@ class binance extends binance$1 {
8762
8957
  //
8763
8958
  const marketId = this.safeString(info, 'symbol');
8764
8959
  market = this.safeMarket(marketId, market, undefined, 'contract');
8765
- const brackets = this.safeValue(info, 'brackets', []);
8960
+ const brackets = this.safeList(info, 'brackets', []);
8766
8961
  const tiers = [];
8767
8962
  for (let j = 0; j < brackets.length; j++) {
8768
8963
  const bracket = brackets[j];
@@ -8977,8 +9172,11 @@ class binance extends binance$1 {
8977
9172
  * @description fetch account positions
8978
9173
  * @see https://binance-docs.github.io/apidocs/futures/en/#account-information-v2-user_data
8979
9174
  * @see https://binance-docs.github.io/apidocs/delivery/en/#account-information-user_data
9175
+ * @see https://binance-docs.github.io/apidocs/pm/en/#get-um-account-detail-user_data
9176
+ * @see https://binance-docs.github.io/apidocs/pm/en/#get-cm-account-detail-user_data
8980
9177
  * @param {string[]|undefined} symbols list of unified market symbols
8981
9178
  * @param {object} [params] extra parameters specific to the exchange API endpoint
9179
+ * @param {boolean} [params.portfolioMargin] set to true if you would like to fetch positions in a portfolio margin account
8982
9180
  * @returns {object} data on account positions
8983
9181
  */
8984
9182
  if (symbols !== undefined) {
@@ -8990,15 +9188,27 @@ class binance extends binance$1 {
8990
9188
  await this.loadLeverageBrackets(false, params);
8991
9189
  const defaultType = this.safeString(this.options, 'defaultType', 'future');
8992
9190
  const type = this.safeString(params, 'type', defaultType);
8993
- let query = this.omit(params, 'type');
9191
+ params = this.omit(params, 'type');
8994
9192
  let subType = undefined;
8995
- [subType, query] = this.handleSubTypeAndParams('fetchAccountPositions', undefined, params, 'linear');
9193
+ [subType, params] = this.handleSubTypeAndParams('fetchAccountPositions', undefined, params, 'linear');
9194
+ let isPortfolioMargin = undefined;
9195
+ [isPortfolioMargin, params] = this.handleOptionAndParams2(params, 'fetchAccountPositions', 'papi', 'portfolioMargin', false);
8996
9196
  let response = undefined;
8997
9197
  if (this.isLinear(type, subType)) {
8998
- response = await this.fapiPrivateV2GetAccount(query);
9198
+ if (isPortfolioMargin) {
9199
+ response = await this.papiGetUmAccount(params);
9200
+ }
9201
+ else {
9202
+ response = await this.fapiPrivateV2GetAccount(params);
9203
+ }
8999
9204
  }
9000
9205
  else if (this.isInverse(type, subType)) {
9001
- response = await this.dapiPrivateGetAccount(query);
9206
+ if (isPortfolioMargin) {
9207
+ response = await this.papiGetCmAccount(params);
9208
+ }
9209
+ else {
9210
+ response = await this.dapiPrivateGetAccount(params);
9211
+ }
9002
9212
  }
9003
9213
  else {
9004
9214
  throw new errors.NotSupported(this.id + ' fetchPositions() supports linear and inverse contracts only');
@@ -9015,8 +9225,11 @@ class binance extends binance$1 {
9015
9225
  * @description fetch positions risk
9016
9226
  * @see https://binance-docs.github.io/apidocs/futures/en/#position-information-v2-user_data
9017
9227
  * @see https://binance-docs.github.io/apidocs/delivery/en/#position-information-user_data
9228
+ * @see https://binance-docs.github.io/apidocs/pm/en/#query-um-position-information-user_data
9229
+ * @see https://binance-docs.github.io/apidocs/pm/en/#query-cm-position-information-user_data
9018
9230
  * @param {string[]|undefined} symbols list of unified market symbols
9019
9231
  * @param {object} [params] extra parameters specific to the exchange API endpoint
9232
+ * @param {boolean} [params.portfolioMargin] set to true if you would like to fetch positions for a portfolio margin account
9020
9233
  * @returns {object} data on the positions risk
9021
9234
  */
9022
9235
  if (symbols !== undefined) {
@@ -9032,71 +9245,124 @@ class binance extends binance$1 {
9032
9245
  const type = this.safeString(params, 'type', defaultType);
9033
9246
  let subType = undefined;
9034
9247
  [subType, params] = this.handleSubTypeAndParams('fetchPositionsRisk', undefined, params, 'linear');
9248
+ let isPortfolioMargin = undefined;
9249
+ [isPortfolioMargin, params] = this.handleOptionAndParams2(params, 'fetchPositionsRisk', 'papi', 'portfolioMargin', false);
9035
9250
  params = this.omit(params, 'type');
9036
9251
  let response = undefined;
9037
9252
  if (this.isLinear(type, subType)) {
9038
- response = await this.fapiPrivateV2GetPositionRisk(this.extend(request, params));
9039
- // ### Response examples ###
9040
- //
9041
- // For One-way position mode:
9042
- // [
9043
- // {
9044
- // "entryPrice": "0.00000",
9045
- // "marginType": "isolated",
9046
- // "isAutoAddMargin": "false",
9047
- // "isolatedMargin": "0.00000000",
9048
- // "leverage": "10",
9049
- // "liquidationPrice": "0",
9050
- // "markPrice": "6679.50671178",
9051
- // "maxNotionalValue": "20000000",
9052
- // "positionAmt": "0.000",
9053
- // "symbol": "BTCUSDT",
9054
- // "unRealizedProfit": "0.00000000",
9055
- // "positionSide": "BOTH",
9056
- // "updateTime": 0
9057
- // }
9058
- // ]
9059
- //
9060
- // For Hedge position mode:
9061
- // [
9062
- // {
9063
- // "entryPrice": "6563.66500",
9064
- // "marginType": "isolated",
9065
- // "isAutoAddMargin": "false",
9066
- // "isolatedMargin": "15517.54150468",
9067
- // "leverage": "10",
9068
- // "liquidationPrice": "5930.78",
9069
- // "markPrice": "6679.50671178",
9070
- // "maxNotionalValue": "20000000",
9071
- // "positionAmt": "20.000",
9072
- // "symbol": "BTCUSDT",
9073
- // "unRealizedProfit": "2316.83423560"
9074
- // "positionSide": "LONG",
9075
- // "updateTime": 1625474304765
9076
- // },
9077
- // {
9078
- // "entryPrice": "0.00000",
9079
- // "marginType": "isolated",
9080
- // "isAutoAddMargin": "false",
9081
- // "isolatedMargin": "5413.95799991",
9082
- // "leverage": "10",
9083
- // "liquidationPrice": "7189.95",
9084
- // "markPrice": "6679.50671178",
9085
- // "maxNotionalValue": "20000000",
9086
- // "positionAmt": "-10.000",
9087
- // "symbol": "BTCUSDT",
9088
- // "unRealizedProfit": "-1156.46711780",
9089
- // "positionSide": "SHORT",
9090
- // "updateTime": 0
9091
- // }
9092
- // ]
9253
+ if (isPortfolioMargin) {
9254
+ response = await this.papiGetUmPositionRisk(this.extend(request, params));
9255
+ }
9256
+ else {
9257
+ response = await this.fapiPrivateV2GetPositionRisk(this.extend(request, params));
9258
+ }
9093
9259
  }
9094
9260
  else if (this.isInverse(type, subType)) {
9095
- response = await this.dapiPrivateGetPositionRisk(this.extend(request, params));
9261
+ if (isPortfolioMargin) {
9262
+ response = await this.papiGetCmPositionRisk(this.extend(request, params));
9263
+ }
9264
+ else {
9265
+ response = await this.dapiPrivateGetPositionRisk(this.extend(request, params));
9266
+ }
9096
9267
  }
9097
9268
  else {
9098
9269
  throw new errors.NotSupported(this.id + ' fetchPositionsRisk() supports linear and inverse contracts only');
9099
9270
  }
9271
+ // ### Response examples ###
9272
+ //
9273
+ // For One-way position mode:
9274
+ //
9275
+ // [
9276
+ // {
9277
+ // "entryPrice": "0.00000",
9278
+ // "marginType": "isolated",
9279
+ // "isAutoAddMargin": "false",
9280
+ // "isolatedMargin": "0.00000000",
9281
+ // "leverage": "10",
9282
+ // "liquidationPrice": "0",
9283
+ // "markPrice": "6679.50671178",
9284
+ // "maxNotionalValue": "20000000",
9285
+ // "positionAmt": "0.000",
9286
+ // "symbol": "BTCUSDT",
9287
+ // "unRealizedProfit": "0.00000000",
9288
+ // "positionSide": "BOTH",
9289
+ // "updateTime": 0
9290
+ // }
9291
+ // ]
9292
+ //
9293
+ // For Hedge position mode:
9294
+ //
9295
+ // [
9296
+ // {
9297
+ // "entryPrice": "6563.66500",
9298
+ // "marginType": "isolated",
9299
+ // "isAutoAddMargin": "false",
9300
+ // "isolatedMargin": "15517.54150468",
9301
+ // "leverage": "10",
9302
+ // "liquidationPrice": "5930.78",
9303
+ // "markPrice": "6679.50671178",
9304
+ // "maxNotionalValue": "20000000",
9305
+ // "positionAmt": "20.000",
9306
+ // "symbol": "BTCUSDT",
9307
+ // "unRealizedProfit": "2316.83423560"
9308
+ // "positionSide": "LONG",
9309
+ // "updateTime": 1625474304765
9310
+ // },
9311
+ // {
9312
+ // "entryPrice": "0.00000",
9313
+ // "marginType": "isolated",
9314
+ // "isAutoAddMargin": "false",
9315
+ // "isolatedMargin": "5413.95799991",
9316
+ // "leverage": "10",
9317
+ // "liquidationPrice": "7189.95",
9318
+ // "markPrice": "6679.50671178",
9319
+ // "maxNotionalValue": "20000000",
9320
+ // "positionAmt": "-10.000",
9321
+ // "symbol": "BTCUSDT",
9322
+ // "unRealizedProfit": "-1156.46711780",
9323
+ // "positionSide": "SHORT",
9324
+ // "updateTime": 0
9325
+ // }
9326
+ // ]
9327
+ //
9328
+ // inverse portfolio margin:
9329
+ //
9330
+ // [
9331
+ // {
9332
+ // "symbol": "ETHUSD_PERP",
9333
+ // "positionAmt": "1",
9334
+ // "entryPrice": "2422.400000007",
9335
+ // "markPrice": "2424.51267823",
9336
+ // "unRealizedProfit": "0.0000036",
9337
+ // "liquidationPrice": "293.57678898",
9338
+ // "leverage": "100",
9339
+ // "positionSide": "LONG",
9340
+ // "updateTime": 1707371941861,
9341
+ // "maxQty": "15",
9342
+ // "notionalValue": "0.00412454",
9343
+ // "breakEvenPrice": "2423.368960034"
9344
+ // }
9345
+ // ]
9346
+ //
9347
+ // linear portfolio margin:
9348
+ //
9349
+ // [
9350
+ // {
9351
+ // "symbol": "BTCUSDT",
9352
+ // "positionAmt": "0.01",
9353
+ // "entryPrice": "44525.0",
9354
+ // "markPrice": "45464.1735922",
9355
+ // "unRealizedProfit": "9.39173592",
9356
+ // "liquidationPrice": "38007.16308568",
9357
+ // "leverage": "100",
9358
+ // "positionSide": "LONG",
9359
+ // "updateTime": 1707371879042,
9360
+ // "maxNotionalValue": "500000.0",
9361
+ // "notional": "454.64173592",
9362
+ // "breakEvenPrice": "44542.81"
9363
+ // }
9364
+ // ]
9365
+ //
9100
9366
  const result = [];
9101
9367
  for (let i = 0; i < response.length; i++) {
9102
9368
  const parsed = this.parsePositionRisk(response[i]);
@@ -9112,15 +9378,19 @@ class binance extends binance$1 {
9112
9378
  * @description fetch the history of funding payments paid and received on this account
9113
9379
  * @see https://binance-docs.github.io/apidocs/futures/en/#get-income-history-user_data
9114
9380
  * @see https://binance-docs.github.io/apidocs/delivery/en/#get-income-history-user_data
9381
+ * @see https://binance-docs.github.io/apidocs/pm/en/#get-um-income-history-user_data
9382
+ * @see https://binance-docs.github.io/apidocs/pm/en/#get-cm-income-history-user_data
9115
9383
  * @param {string} symbol unified market symbol
9116
9384
  * @param {int} [since] the earliest time in ms to fetch funding history for
9117
9385
  * @param {int} [limit] the maximum number of funding history structures to retrieve
9118
9386
  * @param {object} [params] extra parameters specific to the exchange API endpoint
9387
+ * @param {int} [params.until] timestamp in ms of the latest funding history entry
9388
+ * @param {boolean} [params.portfolioMargin] set to true if you would like to fetch the funding history for a portfolio margin account
9119
9389
  * @returns {object} a [funding history structure]{@link https://docs.ccxt.com/#/?id=funding-history-structure}
9120
9390
  */
9121
9391
  await this.loadMarkets();
9122
9392
  let market = undefined;
9123
- const request = {
9393
+ let request = {
9124
9394
  'incomeType': 'FUNDING_FEE', // "TRANSFER","WELCOME_BONUS", "REALIZED_PNL","FUNDING_FEE", "COMMISSION" and "INSURANCE_CLEAR"
9125
9395
  };
9126
9396
  if (symbol !== undefined) {
@@ -9132,6 +9402,9 @@ class binance extends binance$1 {
9132
9402
  }
9133
9403
  let subType = undefined;
9134
9404
  [subType, params] = this.handleSubTypeAndParams('fetchFundingHistory', market, params, 'linear');
9405
+ let isPortfolioMargin = undefined;
9406
+ [isPortfolioMargin, params] = this.handleOptionAndParams2(params, 'fetchFundingHistory', 'papi', 'portfolioMargin', false);
9407
+ [request, params] = this.handleUntilOption('endTime', request, params);
9135
9408
  if (since !== undefined) {
9136
9409
  request['startTime'] = since;
9137
9410
  }
@@ -9143,10 +9416,20 @@ class binance extends binance$1 {
9143
9416
  params = this.omit(params, 'type');
9144
9417
  let response = undefined;
9145
9418
  if (this.isLinear(type, subType)) {
9146
- response = await this.fapiPrivateGetIncome(this.extend(request, params));
9419
+ if (isPortfolioMargin) {
9420
+ response = await this.papiGetUmIncome(this.extend(request, params));
9421
+ }
9422
+ else {
9423
+ response = await this.fapiPrivateGetIncome(this.extend(request, params));
9424
+ }
9147
9425
  }
9148
9426
  else if (this.isInverse(type, subType)) {
9149
- response = await this.dapiPrivateGetIncome(this.extend(request, params));
9427
+ if (isPortfolioMargin) {
9428
+ response = await this.papiGetCmIncome(this.extend(request, params));
9429
+ }
9430
+ else {
9431
+ response = await this.dapiPrivateGetIncome(this.extend(request, params));
9432
+ }
9150
9433
  }
9151
9434
  else {
9152
9435
  throw new errors.NotSupported(this.id + ' fetchFundingHistory() supports linear and inverse contracts only');
@@ -9160,9 +9443,12 @@ class binance extends binance$1 {
9160
9443
  * @description set the level of leverage for a market
9161
9444
  * @see https://binance-docs.github.io/apidocs/futures/en/#change-initial-leverage-trade
9162
9445
  * @see https://binance-docs.github.io/apidocs/delivery/en/#change-initial-leverage-trade
9446
+ * @see https://binance-docs.github.io/apidocs/pm/en/#change-um-initial-leverage-trade
9447
+ * @see https://binance-docs.github.io/apidocs/pm/en/#change-cm-initial-leverage-trade
9163
9448
  * @param {float} leverage the rate of leverage
9164
9449
  * @param {string} symbol unified market symbol
9165
9450
  * @param {object} [params] extra parameters specific to the exchange API endpoint
9451
+ * @param {boolean} [params.portfolioMargin] set to true if you would like to set the leverage for a trading pair in a portfolio margin account
9166
9452
  * @returns {object} response from the exchange
9167
9453
  */
9168
9454
  if (symbol === undefined) {
@@ -9179,12 +9465,24 @@ class binance extends binance$1 {
9179
9465
  'symbol': market['id'],
9180
9466
  'leverage': leverage,
9181
9467
  };
9468
+ let isPortfolioMargin = undefined;
9469
+ [isPortfolioMargin, params] = this.handleOptionAndParams2(params, 'setLeverage', 'papi', 'portfolioMargin', false);
9182
9470
  let response = undefined;
9183
9471
  if (market['linear']) {
9184
- response = await this.fapiPrivatePostLeverage(this.extend(request, params));
9472
+ if (isPortfolioMargin) {
9473
+ response = await this.papiPostUmLeverage(this.extend(request, params));
9474
+ }
9475
+ else {
9476
+ response = await this.fapiPrivatePostLeverage(this.extend(request, params));
9477
+ }
9185
9478
  }
9186
9479
  else if (market['inverse']) {
9187
- response = await this.dapiPrivatePostLeverage(this.extend(request, params));
9480
+ if (isPortfolioMargin) {
9481
+ response = await this.papiPostCmLeverage(this.extend(request, params));
9482
+ }
9483
+ else {
9484
+ response = await this.dapiPrivatePostLeverage(this.extend(request, params));
9485
+ }
9188
9486
  }
9189
9487
  else {
9190
9488
  throw new errors.NotSupported(this.id + ' setLeverage() supports linear and inverse contracts only');
@@ -9266,9 +9564,12 @@ class binance extends binance$1 {
9266
9564
  * @description set hedged to true or false for a market
9267
9565
  * @see https://binance-docs.github.io/apidocs/futures/en/#change-position-mode-trade
9268
9566
  * @see https://binance-docs.github.io/apidocs/delivery/en/#change-position-mode-trade
9567
+ * @see https://binance-docs.github.io/apidocs/pm/en/#change-um-position-mode-trade
9568
+ * @see https://binance-docs.github.io/apidocs/pm/en/#change-cm-position-mode-trade
9269
9569
  * @param {bool} hedged set to true to use dualSidePosition
9270
9570
  * @param {string} symbol not used by binance setPositionMode ()
9271
9571
  * @param {object} [params] extra parameters specific to the exchange API endpoint
9572
+ * @param {boolean} [params.portfolioMargin] set to true if you would like to set the position mode for a portfolio margin account
9272
9573
  * @returns {object} response from the exchange
9273
9574
  */
9274
9575
  const defaultType = this.safeString(this.options, 'defaultType', 'future');
@@ -9276,6 +9577,8 @@ class binance extends binance$1 {
9276
9577
  params = this.omit(params, ['type']);
9277
9578
  let subType = undefined;
9278
9579
  [subType, params] = this.handleSubTypeAndParams('setPositionMode', undefined, params);
9580
+ let isPortfolioMargin = undefined;
9581
+ [isPortfolioMargin, params] = this.handleOptionAndParams2(params, 'setPositionMode', 'papi', 'portfolioMargin', false);
9279
9582
  let dualSidePosition = undefined;
9280
9583
  if (hedged) {
9281
9584
  dualSidePosition = 'true';
@@ -9288,11 +9591,20 @@ class binance extends binance$1 {
9288
9591
  };
9289
9592
  let response = undefined;
9290
9593
  if (this.isInverse(type, subType)) {
9291
- response = await this.dapiPrivatePostPositionSideDual(this.extend(request, params));
9594
+ if (isPortfolioMargin) {
9595
+ response = await this.papiPostCmPositionSideDual(this.extend(request, params));
9596
+ }
9597
+ else {
9598
+ response = await this.dapiPrivatePostPositionSideDual(this.extend(request, params));
9599
+ }
9292
9600
  }
9293
9601
  else {
9294
- // default to future
9295
- response = await this.fapiPrivatePostPositionSideDual(this.extend(request, params));
9602
+ if (isPortfolioMargin) {
9603
+ response = await this.papiPostUmPositionSideDual(this.extend(request, params));
9604
+ }
9605
+ else {
9606
+ response = await this.fapiPrivatePostPositionSideDual(this.extend(request, params));
9607
+ }
9296
9608
  }
9297
9609
  //
9298
9610
  // {
@@ -9492,12 +9804,15 @@ class binance extends binance$1 {
9492
9804
  * @see https://binance-docs.github.io/apidocs/voptions/en/#account-funding-flow-user_data
9493
9805
  * @see https://binance-docs.github.io/apidocs/futures/en/#get-income-history-user_data
9494
9806
  * @see https://binance-docs.github.io/apidocs/delivery/en/#get-income-history-user_data
9807
+ * @see https://binance-docs.github.io/apidocs/pm/en/#get-um-income-history-user_data
9808
+ * @see https://binance-docs.github.io/apidocs/pm/en/#get-cm-income-history-user_data
9495
9809
  * @param {string} code unified currency code
9496
9810
  * @param {int} [since] timestamp in ms of the earliest ledger entry
9497
9811
  * @param {int} [limit] max number of ledger entrys to return
9498
9812
  * @param {object} [params] extra parameters specific to the exchange API endpoint
9499
9813
  * @param {int} [params.until] timestamp in ms of the latest ledger entry
9500
- * @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)
9814
+ * @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)
9815
+ * @param {boolean} [params.portfolioMargin] set to true if you would like to fetch the ledger for a portfolio margin account
9501
9816
  * @returns {object} a [ledger structure]{@link https://docs.ccxt.com/#/?id=ledger-structure}
9502
9817
  */
9503
9818
  await this.loadMarkets();
@@ -9526,6 +9841,8 @@ class binance extends binance$1 {
9526
9841
  params = this.omit(params, 'until');
9527
9842
  request['endTime'] = until;
9528
9843
  }
9844
+ let isPortfolioMargin = undefined;
9845
+ [isPortfolioMargin, params] = this.handleOptionAndParams2(params, 'fetchLedger', 'papi', 'portfolioMargin', false);
9529
9846
  let response = undefined;
9530
9847
  if (type === 'option') {
9531
9848
  this.checkRequiredArgument('fetchLedger', code, 'code');
@@ -9533,10 +9850,20 @@ class binance extends binance$1 {
9533
9850
  response = await this.eapiPrivateGetBill(this.extend(request, params));
9534
9851
  }
9535
9852
  else if (this.isLinear(type, subType)) {
9536
- response = await this.fapiPrivateGetIncome(this.extend(request, params));
9853
+ if (isPortfolioMargin) {
9854
+ response = await this.papiGetUmIncome(this.extend(request, params));
9855
+ }
9856
+ else {
9857
+ response = await this.fapiPrivateGetIncome(this.extend(request, params));
9858
+ }
9537
9859
  }
9538
9860
  else if (this.isInverse(type, subType)) {
9539
- response = await this.dapiPrivateGetIncome(this.extend(request, params));
9861
+ if (isPortfolioMargin) {
9862
+ response = await this.papiGetCmIncome(this.extend(request, params));
9863
+ }
9864
+ else {
9865
+ response = await this.dapiPrivateGetIncome(this.extend(request, params));
9866
+ }
9540
9867
  }
9541
9868
  else {
9542
9869
  throw new errors.NotSupported(this.id + ' fetchLedger() supports contract wallets only');
@@ -9554,7 +9881,7 @@ class binance extends binance$1 {
9554
9881
  // }
9555
9882
  // ]
9556
9883
  //
9557
- // futures (fapi, dapi)
9884
+ // futures (fapi, dapi, papi)
9558
9885
  //
9559
9886
  // [
9560
9887
  // {
@@ -9583,7 +9910,7 @@ class binance extends binance$1 {
9583
9910
  // "createDate": 1676621042489
9584
9911
  // }
9585
9912
  //
9586
- // futures (fapi, dapi)
9913
+ // futures (fapi, dapi, papi)
9587
9914
  //
9588
9915
  // {
9589
9916
  // "symbol": "",
@@ -9692,7 +10019,7 @@ class binance extends binance$1 {
9692
10019
  const isSpotOrMargin = (api.indexOf('sapi') > -1 || api === 'private');
9693
10020
  const marketType = isSpotOrMargin ? 'spot' : 'future';
9694
10021
  const defaultId = (!isSpotOrMargin) ? 'x-xcKtGhcu' : 'x-R4BD3S82';
9695
- const broker = this.safeValue(this.options, 'broker', {});
10022
+ const broker = this.safeDict(this.options, 'broker', {});
9696
10023
  const brokerId = this.safeString(broker, marketType, defaultId);
9697
10024
  params['newClientOrderId'] = brokerId + this.uuid22();
9698
10025
  }
@@ -9720,8 +10047,8 @@ class binance extends binance$1 {
9720
10047
  }
9721
10048
  else if ((path === 'batchOrders') || (path.indexOf('sub-account') >= 0) || (path === 'capital/withdraw/apply') || (path.indexOf('staking') >= 0)) {
9722
10049
  if ((method === 'DELETE') && (path === 'batchOrders')) {
9723
- const orderidlist = this.safeValue(extendedParams, 'orderidlist', []);
9724
- const origclientorderidlist = this.safeValue(extendedParams, 'origclientorderidlist', []);
10050
+ const orderidlist = this.safeList(extendedParams, 'orderidlist', []);
10051
+ const origclientorderidlist = this.safeList(extendedParams, 'origclientorderidlist', []);
9725
10052
  extendedParams = this.omit(extendedParams, ['orderidlist', 'origclientorderidlist']);
9726
10053
  query = this.rawencode(extendedParams);
9727
10054
  const orderidlistLength = orderidlist.length;
@@ -9790,8 +10117,8 @@ class binance extends binance$1 {
9790
10117
  marketType = 'portfoliomargin';
9791
10118
  }
9792
10119
  if (marketType !== undefined) {
9793
- const exceptionsForMarketType = this.safeValue(this.exceptions, marketType, {});
9794
- return this.safeValue(exceptionsForMarketType, exactOrBroad, {});
10120
+ const exceptionsForMarketType = this.safeDict(this.exceptions, marketType, {});
10121
+ return this.safeDict(exceptionsForMarketType, exactOrBroad, {});
9795
10122
  }
9796
10123
  return {};
9797
10124
  }
@@ -10025,7 +10352,7 @@ class binance extends binance$1 {
10025
10352
  // },
10026
10353
  // ]
10027
10354
  //
10028
- const rate = this.safeValue(response, 0);
10355
+ const rate = this.safeDict(response, 0);
10029
10356
  return this.parseBorrowRate(rate);
10030
10357
  }
10031
10358
  async fetchBorrowRateHistory(code, since = undefined, limit = undefined, params = {}) {
@@ -10129,7 +10456,7 @@ class binance extends binance$1 {
10129
10456
  // "success": true
10130
10457
  // }
10131
10458
  //
10132
- const data = this.safeValue(response, 'data');
10459
+ const data = this.safeDict(response, 'data');
10133
10460
  const giftcardCode = this.safeString(data, 'code');
10134
10461
  const id = this.safeString(data, 'referenceNo');
10135
10462
  return {
@@ -10238,7 +10565,7 @@ class binance extends binance$1 {
10238
10565
  // "total": 1
10239
10566
  // }
10240
10567
  //
10241
- const rows = this.safeValue(response, 'rows');
10568
+ const rows = this.safeList(response, 'rows');
10242
10569
  const interest = this.parseBorrowInterests(rows, market);
10243
10570
  return this.filterByCurrencySinceLimit(interest, code, since, limit);
10244
10571
  }
@@ -10265,9 +10592,11 @@ class binance extends binance$1 {
10265
10592
  * @name binance#repayCrossMargin
10266
10593
  * @description repay borrowed margin and interest
10267
10594
  * @see https://binance-docs.github.io/apidocs/spot/en/#margin-account-borrow-repay-margin
10595
+ * @see https://binance-docs.github.io/apidocs/pm/en/#margin-account-repay-margin
10268
10596
  * @param {string} code unified currency code of the currency to repay
10269
10597
  * @param {float} amount the amount to repay
10270
10598
  * @param {object} [params] extra parameters specific to the exchange API endpoint
10599
+ * @param {boolean} [params.portfolioMargin] set to true if you would like to repay margin in a portfolio margin account
10271
10600
  * @returns {object} a [margin loan structure]{@link https://docs.ccxt.com/#/?id=margin-loan-structure}
10272
10601
  */
10273
10602
  await this.loadMarkets();
@@ -10275,10 +10604,18 @@ class binance extends binance$1 {
10275
10604
  const request = {
10276
10605
  'asset': currency['id'],
10277
10606
  'amount': this.currencyToPrecision(code, amount),
10278
- 'isIsolated': 'FALSE',
10279
- 'type': 'REPAY',
10280
10607
  };
10281
- const response = await this.sapiPostMarginBorrowRepay(this.extend(request, params));
10608
+ let response = undefined;
10609
+ let isPortfolioMargin = undefined;
10610
+ [isPortfolioMargin, params] = this.handleOptionAndParams2(params, 'repayCrossMargin', 'papi', 'portfolioMargin', false);
10611
+ if (isPortfolioMargin) {
10612
+ response = await this.papiPostRepayLoan(this.extend(request, params));
10613
+ }
10614
+ else {
10615
+ request['isIsolated'] = 'FALSE';
10616
+ request['type'] = 'REPAY';
10617
+ response = await this.sapiPostMarginBorrowRepay(this.extend(request, params));
10618
+ }
10282
10619
  //
10283
10620
  // {
10284
10621
  // "tranId": 108988250265,
@@ -10324,9 +10661,11 @@ class binance extends binance$1 {
10324
10661
  * @name binance#borrowCrossMargin
10325
10662
  * @description create a loan to borrow margin
10326
10663
  * @see https://binance-docs.github.io/apidocs/spot/en/#margin-account-borrow-repay-margin
10664
+ * @see https://binance-docs.github.io/apidocs/pm/en/#margin-account-borrow-margin
10327
10665
  * @param {string} code unified currency code of the currency to borrow
10328
10666
  * @param {float} amount the amount to borrow
10329
10667
  * @param {object} [params] extra parameters specific to the exchange API endpoint
10668
+ * @param {boolean} [params.portfolioMargin] set to true if you would like to borrow margin in a portfolio margin account
10330
10669
  * @returns {object} a [margin loan structure]{@link https://docs.ccxt.com/#/?id=margin-loan-structure}
10331
10670
  */
10332
10671
  await this.loadMarkets();
@@ -10334,10 +10673,18 @@ class binance extends binance$1 {
10334
10673
  const request = {
10335
10674
  'asset': currency['id'],
10336
10675
  'amount': this.currencyToPrecision(code, amount),
10337
- 'isIsolated': 'FALSE',
10338
- 'type': 'BORROW',
10339
10676
  };
10340
- const response = await this.sapiPostMarginBorrowRepay(this.extend(request, params));
10677
+ let response = undefined;
10678
+ let isPortfolioMargin = undefined;
10679
+ [isPortfolioMargin, params] = this.handleOptionAndParams2(params, 'borrowCrossMargin', 'papi', 'portfolioMargin', false);
10680
+ if (isPortfolioMargin) {
10681
+ response = await this.papiPostMarginLoan(this.extend(request, params));
10682
+ }
10683
+ else {
10684
+ request['isIsolated'] = 'FALSE';
10685
+ request['type'] = 'BORROW';
10686
+ response = await this.sapiPostMarginBorrowRepay(this.extend(request, params));
10687
+ }
10341
10688
  //
10342
10689
  // {
10343
10690
  // "tranId": 108988250265,