ccxt 4.2.39 → 4.2.41

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 (57) hide show
  1. package/README.md +3 -3
  2. package/dist/ccxt.browser.js +1140 -341
  3. package/dist/ccxt.browser.min.js +2 -2
  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 +14 -14
  7. package/dist/cjs/src/binance.js +561 -168
  8. package/dist/cjs/src/bingx.js +271 -25
  9. package/dist/cjs/src/bitforex.js +2 -2
  10. package/dist/cjs/src/bitget.js +13 -2
  11. package/dist/cjs/src/bybit.js +3 -1
  12. package/dist/cjs/src/coinbase.js +8 -6
  13. package/dist/cjs/src/coinbasepro.js +1 -0
  14. package/dist/cjs/src/coinlist.js +9 -7
  15. package/dist/cjs/src/coinmetro.js +2 -1
  16. package/dist/cjs/src/currencycom.js +1 -1
  17. package/dist/cjs/src/htx.js +1 -1
  18. package/dist/cjs/src/krakenfutures.js +126 -2
  19. package/dist/cjs/src/mexc.js +44 -44
  20. package/dist/cjs/src/okx.js +9 -15
  21. package/dist/cjs/src/phemex.js +1 -0
  22. package/dist/cjs/src/pro/bitmart.js +38 -20
  23. package/dist/cjs/src/pro/bybit.js +5 -5
  24. package/dist/cjs/src/pro/cex.js +1 -1
  25. package/dist/cjs/src/pro/gemini.js +1 -1
  26. package/js/ccxt.d.ts +1 -1
  27. package/js/ccxt.js +1 -1
  28. package/js/src/abstract/bingx.d.ts +4 -0
  29. package/js/src/abstract/coinbasepro.d.ts +1 -0
  30. package/js/src/ascendex.js +28 -24
  31. package/js/src/base/Exchange.d.ts +8 -8
  32. package/js/src/base/Exchange.js +14 -14
  33. package/js/src/binance.d.ts +1 -1
  34. package/js/src/binance.js +561 -168
  35. package/js/src/bingx.d.ts +2 -0
  36. package/js/src/bingx.js +271 -25
  37. package/js/src/bitforex.js +2 -2
  38. package/js/src/bitget.js +13 -2
  39. package/js/src/bybit.js +3 -1
  40. package/js/src/coinbase.js +8 -6
  41. package/js/src/coinbasepro.js +1 -0
  42. package/js/src/coinlist.js +9 -7
  43. package/js/src/coinmetro.js +2 -1
  44. package/js/src/currencycom.js +1 -1
  45. package/js/src/htx.js +1 -1
  46. package/js/src/krakenfutures.d.ts +2 -0
  47. package/js/src/krakenfutures.js +126 -2
  48. package/js/src/mexc.js +44 -44
  49. package/js/src/okx.js +9 -15
  50. package/js/src/phemex.js +1 -0
  51. package/js/src/pro/bitmart.d.ts +2 -0
  52. package/js/src/pro/bitmart.js +38 -20
  53. package/js/src/pro/bybit.d.ts +1 -1
  54. package/js/src/pro/bybit.js +5 -5
  55. package/js/src/pro/cex.js +1 -1
  56. package/js/src/pro/gemini.js +1 -1
  57. package/package.json +1 -1
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);
@@ -4340,20 +4340,73 @@ export default class binance extends Exchange {
4340
4340
  // "time": 1676366446072
4341
4341
  // }
4342
4342
  //
4343
+ // fetchMyTrades: linear portfolio margin
4344
+ //
4345
+ // {
4346
+ // "symbol": "BTCUSDT",
4347
+ // "id": 4575108247,
4348
+ // "orderId": 261942655610,
4349
+ // "side": "SELL",
4350
+ // "price": "47263.40",
4351
+ // "qty": "0.010",
4352
+ // "realizedPnl": "27.38400000",
4353
+ // "marginAsset": "USDT",
4354
+ // "quoteQty": "472.63",
4355
+ // "commission": "0.18905360",
4356
+ // "commissionAsset": "USDT",
4357
+ // "time": 1707530039409,
4358
+ // "buyer": false,
4359
+ // "maker": false,
4360
+ // "positionSide": "LONG"
4361
+ // }
4362
+ //
4363
+ // fetchMyTrades: inverse portfolio margin
4364
+ //
4365
+ // {
4366
+ // "symbol": "ETHUSD_PERP",
4367
+ // "id": 701907838,
4368
+ // "orderId": 71548909034,
4369
+ // "pair": "ETHUSD",
4370
+ // "side": "SELL",
4371
+ // "price": "2498.15",
4372
+ // "qty": "1",
4373
+ // "realizedPnl": "0.00012517",
4374
+ // "marginAsset": "ETH",
4375
+ // "baseQty": "0.00400296",
4376
+ // "commission": "0.00000160",
4377
+ // "commissionAsset": "ETH",
4378
+ // "time": 1707530317519,
4379
+ // "positionSide": "LONG",
4380
+ // "buyer": false,
4381
+ // "maker": false
4382
+ // }
4383
+ //
4384
+ // fetchMyTrades: spot margin portfolio margin
4385
+ //
4386
+ // {
4387
+ // "symbol": "ADAUSDT",
4388
+ // "id": 470227543,
4389
+ // "orderId": 4421170947,
4390
+ // "price": "0.53880000",
4391
+ // "qty": "10.00000000",
4392
+ // "quoteQty": "5.38800000",
4393
+ // "commission": "0.00538800",
4394
+ // "commissionAsset": "USDT",
4395
+ // "time": 1707545780522,
4396
+ // "isBuyer": false,
4397
+ // "isMaker": false,
4398
+ // "isBestMatch": true
4399
+ // }
4400
+ //
4343
4401
  const timestamp = this.safeInteger2(trade, 'T', 'time');
4344
- const price = this.safeString2(trade, 'p', 'price');
4345
4402
  let amount = this.safeString2(trade, 'q', 'qty');
4346
4403
  amount = this.safeString(trade, 'quantity', amount);
4347
- const cost = this.safeString2(trade, 'quoteQty', 'baseQty'); // inverse futures
4348
4404
  const marketId = this.safeString(trade, 'symbol');
4349
- const isSpotTrade = ('isIsolated' in trade) || ('M' in trade) || ('orderListId' in trade);
4405
+ const isSpotTrade = ('isIsolated' in trade) || ('M' in trade) || ('orderListId' in trade) || ('isMaker' in trade);
4350
4406
  const marketType = isSpotTrade ? 'spot' : 'contract';
4351
4407
  market = this.safeMarket(marketId, market, undefined, marketType);
4352
4408
  const symbol = market['symbol'];
4353
- let id = this.safeString2(trade, 't', 'a');
4354
- id = this.safeString2(trade, 'tradeId', 'id', id);
4355
4409
  let side = undefined;
4356
- const orderId = this.safeString(trade, 'orderId');
4357
4410
  const buyerMaker = this.safeValue2(trade, 'm', 'isBuyerMaker');
4358
4411
  let takerOrMaker = undefined;
4359
4412
  if (buyerMaker !== undefined) {
@@ -4403,14 +4456,14 @@ export default class binance extends Exchange {
4403
4456
  'timestamp': timestamp,
4404
4457
  'datetime': this.iso8601(timestamp),
4405
4458
  'symbol': symbol,
4406
- 'id': id,
4407
- 'order': orderId,
4459
+ 'id': this.safeStringN(trade, ['t', 'a', 'tradeId', 'id']),
4460
+ 'order': this.safeString(trade, 'orderId'),
4408
4461
  'type': this.safeStringLower(trade, 'type'),
4409
4462
  'side': side,
4410
4463
  'takerOrMaker': takerOrMaker,
4411
- 'price': price,
4464
+ 'price': this.safeString2(trade, 'p', 'price'),
4412
4465
  'amount': amount,
4413
- 'cost': cost,
4466
+ 'cost': this.safeString2(trade, 'quoteQty', 'baseQty'),
4414
4467
  'fee': fee,
4415
4468
  }, market);
4416
4469
  }
@@ -5244,7 +5297,7 @@ export default class binance extends Exchange {
5244
5297
  cost = this.safeString(order, 'cumBase', cost);
5245
5298
  let type = this.safeStringLower(order, 'type');
5246
5299
  const side = this.safeStringLower(order, 'side');
5247
- const fills = this.safeValue(order, 'fills', []);
5300
+ const fills = this.safeList(order, 'fills', []);
5248
5301
  let timeInForce = this.safeString(order, 'timeInForce');
5249
5302
  if (timeInForce === 'GTX') {
5250
5303
  // GTX means "Good Till Crossing" and is an equivalent way of saying Post Only
@@ -5277,7 +5330,7 @@ export default class binance extends Exchange {
5277
5330
  'type': type,
5278
5331
  'timeInForce': timeInForce,
5279
5332
  'postOnly': postOnly,
5280
- 'reduceOnly': this.safeValue(order, 'reduceOnly'),
5333
+ 'reduceOnly': this.safeBool(order, 'reduceOnly'),
5281
5334
  'side': side,
5282
5335
  'price': price,
5283
5336
  'triggerPrice': stopPrice,
@@ -5311,7 +5364,7 @@ export default class binance extends Exchange {
5311
5364
  const side = this.safeString(rawOrder, 'side');
5312
5365
  const amount = this.safeValue(rawOrder, 'amount');
5313
5366
  const price = this.safeValue(rawOrder, 'price');
5314
- const orderParams = this.safeValue(rawOrder, 'params', {});
5367
+ const orderParams = this.safeDict(rawOrder, 'params', {});
5315
5368
  const orderRequest = this.createOrderRequest(marketId, type, side, amount, price, orderParams);
5316
5369
  ordersRequests.push(orderRequest);
5317
5370
  }
@@ -6499,12 +6552,16 @@ export default class binance extends Exchange {
6499
6552
  * @see https://binance-docs.github.io/apidocs/futures/en/#account-trade-list-user_data
6500
6553
  * @see https://binance-docs.github.io/apidocs/delivery/en/#account-trade-list-user_data
6501
6554
  * @see https://binance-docs.github.io/apidocs/spot/en/#query-margin-account-39-s-trade-list-user_data
6555
+ * @see https://binance-docs.github.io/apidocs/pm/en/#margin-account-trade-list-user_data
6556
+ * @see https://binance-docs.github.io/apidocs/pm/en/#um-account-trade-list-user_data
6557
+ * @see https://binance-docs.github.io/apidocs/pm/en/#cm-account-trade-list-user_data
6502
6558
  * @param {string} symbol unified market symbol
6503
6559
  * @param {int} [since] the earliest time in ms to fetch trades for
6504
6560
  * @param {int} [limit] the maximum number of trades structures to retrieve
6505
6561
  * @param {object} [params] extra parameters specific to the exchange API endpoint
6506
- * @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)
6562
+ * @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)
6507
6563
  * @param {int} [params.until] the latest time in ms to fetch entries for
6564
+ * @param {boolean} [params.portfolioMargin] set to true if you would like to fetch trades for a portfolio margin account
6508
6565
  * @returns {Trade[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=trade-structure}
6509
6566
  */
6510
6567
  await this.loadMarkets();
@@ -6558,8 +6615,13 @@ export default class binance extends Exchange {
6558
6615
  throw new ArgumentsRequired(this.id + ' fetchMyTrades() requires a symbol argument');
6559
6616
  }
6560
6617
  [marginMode, params] = this.handleMarginModeAndParams('fetchMyTrades', params);
6618
+ let isPortfolioMargin = undefined;
6619
+ [isPortfolioMargin, params] = this.handleOptionAndParams2(params, 'fetchMyTrades', 'papi', 'portfolioMargin', false);
6561
6620
  if (type === 'spot' || type === 'margin') {
6562
- if ((type === 'margin') || (marginMode !== undefined)) {
6621
+ if (isPortfolioMargin) {
6622
+ response = await this.papiGetMarginMyTrades(this.extend(request, params));
6623
+ }
6624
+ else if ((type === 'margin') || (marginMode !== undefined)) {
6563
6625
  if (marginMode === 'isolated') {
6564
6626
  request['isIsolated'] = true;
6565
6627
  }
@@ -6570,10 +6632,20 @@ export default class binance extends Exchange {
6570
6632
  }
6571
6633
  }
6572
6634
  else if (market['linear']) {
6573
- response = await this.fapiPrivateGetUserTrades(this.extend(request, params));
6635
+ if (isPortfolioMargin) {
6636
+ response = await this.papiGetUmUserTrades(this.extend(request, params));
6637
+ }
6638
+ else {
6639
+ response = await this.fapiPrivateGetUserTrades(this.extend(request, params));
6640
+ }
6574
6641
  }
6575
6642
  else if (market['inverse']) {
6576
- response = await this.dapiPrivateGetUserTrades(this.extend(request, params));
6643
+ if (isPortfolioMargin) {
6644
+ response = await this.papiGetCmUserTrades(this.extend(request, params));
6645
+ }
6646
+ else {
6647
+ response = await this.dapiPrivateGetUserTrades(this.extend(request, params));
6648
+ }
6577
6649
  }
6578
6650
  }
6579
6651
  //
@@ -6641,6 +6713,70 @@ export default class binance extends Exchange {
6641
6713
  // }
6642
6714
  // ]
6643
6715
  //
6716
+ // linear portfolio margin
6717
+ //
6718
+ // [
6719
+ // {
6720
+ // "symbol": "BTCUSDT",
6721
+ // "id": 4575108247,
6722
+ // "orderId": 261942655610,
6723
+ // "side": "SELL",
6724
+ // "price": "47263.40",
6725
+ // "qty": "0.010",
6726
+ // "realizedPnl": "27.38400000",
6727
+ // "marginAsset": "USDT",
6728
+ // "quoteQty": "472.63",
6729
+ // "commission": "0.18905360",
6730
+ // "commissionAsset": "USDT",
6731
+ // "time": 1707530039409,
6732
+ // "buyer": false,
6733
+ // "maker": false,
6734
+ // "positionSide": "LONG"
6735
+ // }
6736
+ // ]
6737
+ //
6738
+ // inverse portfolio margin
6739
+ //
6740
+ // [
6741
+ // {
6742
+ // "symbol": "ETHUSD_PERP",
6743
+ // "id": 701907838,
6744
+ // "orderId": 71548909034,
6745
+ // "pair": "ETHUSD",
6746
+ // "side": "SELL",
6747
+ // "price": "2498.15",
6748
+ // "qty": "1",
6749
+ // "realizedPnl": "0.00012517",
6750
+ // "marginAsset": "ETH",
6751
+ // "baseQty": "0.00400296",
6752
+ // "commission": "0.00000160",
6753
+ // "commissionAsset": "ETH",
6754
+ // "time": 1707530317519,
6755
+ // "positionSide": "LONG",
6756
+ // "buyer": false,
6757
+ // "maker": false
6758
+ // }
6759
+ // ]
6760
+ //
6761
+ // spot margin portfolio margin
6762
+ //
6763
+ // [
6764
+ // {
6765
+ // "symbol": "ADAUSDT",
6766
+ // "id": 470227543,
6767
+ // "orderId": 4421170947,
6768
+ // "price": "0.53880000",
6769
+ // "qty": "10.00000000",
6770
+ // "quoteQty": "5.38800000",
6771
+ // "commission": "0.00538800",
6772
+ // "commissionAsset": "USDT",
6773
+ // "time": 1707545780522,
6774
+ // "isBuyer": false,
6775
+ // "isMaker": false,
6776
+ // "isBestMatch": true
6777
+ // }
6778
+ // ]
6779
+ //
6644
6780
  return this.parseTrades(response, market, since, limit);
6645
6781
  }
6646
6782
  async fetchMyDustTrades(symbol = undefined, since = undefined, limit = undefined, params = {}) {
@@ -6703,11 +6839,11 @@ export default class binance extends Exchange {
6703
6839
  // },
6704
6840
  // ]
6705
6841
  // }
6706
- const results = this.safeValue(response, 'userAssetDribblets', []);
6842
+ const results = this.safeList(response, 'userAssetDribblets', []);
6707
6843
  const rows = this.safeInteger(response, 'total', 0);
6708
6844
  const data = [];
6709
6845
  for (let i = 0; i < rows; i++) {
6710
- const logs = this.safeValue(results[i], 'userAssetDribbletDetails', []);
6846
+ const logs = this.safeList(results[i], 'userAssetDribbletDetails', []);
6711
6847
  for (let j = 0; j < logs.length; j++) {
6712
6848
  logs[j]['isDustTrade'] = true;
6713
6849
  data.push(logs[j]);
@@ -6814,7 +6950,7 @@ export default class binance extends Exchange {
6814
6950
  let currency = undefined;
6815
6951
  let response = undefined;
6816
6952
  const request = {};
6817
- const legalMoney = this.safeValue(this.options, 'legalMoney', {});
6953
+ const legalMoney = this.safeDict(this.options, 'legalMoney', {});
6818
6954
  const fiatOnly = this.safeBool(params, 'fiat', false);
6819
6955
  params = this.omit(params, 'fiatOnly');
6820
6956
  const until = this.safeInteger(params, 'until');
@@ -6926,7 +7062,7 @@ export default class binance extends Exchange {
6926
7062
  if (paginate) {
6927
7063
  return await this.fetchPaginatedCallDynamic('fetchWithdrawals', code, since, limit, params);
6928
7064
  }
6929
- const legalMoney = this.safeValue(this.options, 'legalMoney', {});
7065
+ const legalMoney = this.safeDict(this.options, 'legalMoney', {});
6930
7066
  const fiatOnly = this.safeBool(params, 'fiat', false);
6931
7067
  params = this.omit(params, 'fiatOnly');
6932
7068
  const request = {};
@@ -7070,7 +7206,7 @@ export default class binance extends Exchange {
7070
7206
  'Refund Failed': 'failed',
7071
7207
  },
7072
7208
  };
7073
- const statuses = this.safeValue(statusesByType, type, {});
7209
+ const statuses = this.safeDict(statusesByType, type, {});
7074
7210
  return this.safeString(statuses, status, status);
7075
7211
  }
7076
7212
  parseTransaction(transaction, currency = undefined) {
@@ -7235,7 +7371,7 @@ export default class binance extends Exchange {
7235
7371
  const type = this.safeString(transfer, 'type');
7236
7372
  let fromAccount = undefined;
7237
7373
  let toAccount = undefined;
7238
- const accountsById = this.safeValue(this.options, 'accountsById', {});
7374
+ const accountsById = this.safeDict(this.options, 'accountsById', {});
7239
7375
  if (type !== undefined) {
7240
7376
  const parts = type.split('_');
7241
7377
  fromAccount = this.safeValue(parts, 0);
@@ -7271,20 +7407,16 @@ export default class binance extends Exchange {
7271
7407
  // }
7272
7408
  //
7273
7409
  const marketId = this.safeString(income, 'symbol');
7274
- const symbol = this.safeSymbol(marketId, market, undefined, 'swap');
7275
- const amount = this.safeNumber(income, 'income');
7276
7410
  const currencyId = this.safeString(income, 'asset');
7277
- const code = this.safeCurrencyCode(currencyId);
7278
- const id = this.safeString(income, 'tranId');
7279
7411
  const timestamp = this.safeInteger(income, 'time');
7280
7412
  return {
7281
7413
  'info': income,
7282
- 'symbol': symbol,
7283
- 'code': code,
7414
+ 'symbol': this.safeSymbol(marketId, market, undefined, 'swap'),
7415
+ 'code': this.safeCurrencyCode(currencyId),
7284
7416
  'timestamp': timestamp,
7285
7417
  'datetime': this.iso8601(timestamp),
7286
- 'id': id,
7287
- 'amount': amount,
7418
+ 'id': this.safeString(income, 'tranId'),
7419
+ 'amount': this.safeNumber(income, 'income'),
7288
7420
  };
7289
7421
  }
7290
7422
  async transfer(code, amount, fromAccount, toAccount, params = {}) {
@@ -7333,7 +7465,7 @@ export default class binance extends Exchange {
7333
7465
  throw new ArgumentsRequired(this.id + ' transfer () requires params["symbol"] when toAccount is ' + toAccount);
7334
7466
  }
7335
7467
  }
7336
- const accountsById = this.safeValue(this.options, 'accountsById', {});
7468
+ const accountsById = this.safeDict(this.options, 'accountsById', {});
7337
7469
  const fromIsolated = !(fromId in accountsById);
7338
7470
  const toIsolated = !(toId in accountsById);
7339
7471
  if (fromIsolated && (market === undefined)) {
@@ -7423,7 +7555,7 @@ export default class binance extends Exchange {
7423
7555
  const defaultTo = (fromAccount === 'future') ? 'spot' : 'future';
7424
7556
  const toAccount = this.safeString(params, 'toAccount', defaultTo);
7425
7557
  let type = this.safeString(params, 'type');
7426
- const accountsByType = this.safeValue(this.options, 'accountsByType', {});
7558
+ const accountsByType = this.safeDict(this.options, 'accountsByType', {});
7427
7559
  const fromId = this.safeString(accountsByType, fromAccount);
7428
7560
  const toId = this.safeString(accountsByType, toAccount);
7429
7561
  if (type === undefined) {
@@ -7467,7 +7599,7 @@ export default class binance extends Exchange {
7467
7599
  // ]
7468
7600
  // }
7469
7601
  //
7470
- const rows = this.safeValue(response, 'rows', []);
7602
+ const rows = this.safeList(response, 'rows', []);
7471
7603
  return this.parseTransfers(rows, currency, since, limit);
7472
7604
  }
7473
7605
  async fetchDepositAddress(code, params = {}) {
@@ -7486,7 +7618,7 @@ export default class binance extends Exchange {
7486
7618
  'coin': currency['id'],
7487
7619
  // 'network': 'ETH', // 'BSC', 'XMR', you can get network and isDefault in networkList in the response of sapiGetCapitalConfigDetail
7488
7620
  };
7489
- const networks = this.safeValue(this.options, 'networks', {});
7621
+ const networks = this.safeDict(this.options, 'networks', {});
7490
7622
  let network = this.safeStringUpper(params, 'network'); // this line allows the user to specify either ERC20 or ETH
7491
7623
  network = this.safeString(networks, network, network); // handle ERC20>ETH alias
7492
7624
  if (network !== undefined) {
@@ -7513,7 +7645,7 @@ export default class binance extends Exchange {
7513
7645
  const url = this.safeString(response, 'url');
7514
7646
  let impliedNetwork = undefined;
7515
7647
  if (url !== undefined) {
7516
- const reverseNetworks = this.safeValue(this.options, 'reverseNetworks', {});
7648
+ const reverseNetworks = this.safeDict(this.options, 'reverseNetworks', {});
7517
7649
  const parts = url.split('/');
7518
7650
  let topLevel = this.safeString(parts, 2);
7519
7651
  if ((topLevel === 'blockchair.com') || (topLevel === 'viewblock.io')) {
@@ -7528,7 +7660,7 @@ export default class binance extends Exchange {
7528
7660
  'TRX': { 'TRC20': 'TRX' },
7529
7661
  });
7530
7662
  if (code in impliedNetworks) {
7531
- const conversion = this.safeValue(impliedNetworks, code, {});
7663
+ const conversion = this.safeDict(impliedNetworks, code, {});
7532
7664
  impliedNetwork = this.safeString(conversion, impliedNetwork, impliedNetwork);
7533
7665
  }
7534
7666
  }
@@ -7644,7 +7776,7 @@ export default class binance extends Exchange {
7644
7776
  const entry = response[i];
7645
7777
  const currencyId = this.safeString(entry, 'coin');
7646
7778
  const code = this.safeCurrencyCode(currencyId);
7647
- const networkList = this.safeValue(entry, 'networkList', []);
7779
+ const networkList = this.safeList(entry, 'networkList', []);
7648
7780
  withdrawFees[code] = {};
7649
7781
  for (let j = 0; j < networkList.length; j++) {
7650
7782
  const networkEntry = networkList[j];
@@ -7757,14 +7889,14 @@ export default class binance extends Exchange {
7757
7889
  // ]
7758
7890
  // }
7759
7891
  //
7760
- const networkList = this.safeValue(fee, 'networkList', []);
7892
+ const networkList = this.safeList(fee, 'networkList', []);
7761
7893
  const result = this.depositWithdrawFee(fee);
7762
7894
  for (let j = 0; j < networkList.length; j++) {
7763
7895
  const networkEntry = networkList[j];
7764
7896
  const networkId = this.safeString(networkEntry, 'network');
7765
7897
  const networkCode = this.networkIdToCode(networkId);
7766
7898
  const withdrawFee = this.safeNumber(networkEntry, 'withdrawFee');
7767
- const isDefault = this.safeValue(networkEntry, 'isDefault');
7899
+ const isDefault = this.safeBool(networkEntry, 'isDefault');
7768
7900
  if (isDefault === true) {
7769
7901
  result['withdraw'] = {
7770
7902
  'fee': withdrawFee,
@@ -7812,7 +7944,7 @@ export default class binance extends Exchange {
7812
7944
  if (tag !== undefined) {
7813
7945
  request['addressTag'] = tag;
7814
7946
  }
7815
- const networks = this.safeValue(this.options, 'networks', {});
7947
+ const networks = this.safeDict(this.options, 'networks', {});
7816
7948
  let network = this.safeStringUpper(params, 'network'); // this line allows the user to specify either ERC20 or ETH
7817
7949
  network = this.safeString(networks, network, network); // handle ERC20>ETH alias
7818
7950
  if (network !== undefined) {
@@ -7904,7 +8036,7 @@ export default class binance extends Exchange {
7904
8036
  //
7905
8037
  let data = response;
7906
8038
  if (Array.isArray(data)) {
7907
- data = this.safeValue(data, 0, {});
8039
+ data = this.safeDict(data, 0, {});
7908
8040
  }
7909
8041
  return this.parseTradingFee(data);
7910
8042
  }
@@ -8318,8 +8450,8 @@ export default class binance extends Exchange {
8318
8450
  };
8319
8451
  }
8320
8452
  parseAccountPositions(account) {
8321
- const positions = this.safeValue(account, 'positions');
8322
- const assets = this.safeValue(account, 'assets', []);
8453
+ const positions = this.safeList(account, 'positions');
8454
+ const assets = this.safeList(account, 'assets', []);
8323
8455
  const balances = {};
8324
8456
  for (let i = 0; i < assets.length; i++) {
8325
8457
  const entry = assets[i];
@@ -8338,13 +8470,17 @@ export default class binance extends Exchange {
8338
8470
  const marketId = this.safeString(position, 'symbol');
8339
8471
  const market = this.safeMarket(marketId, undefined, undefined, 'contract');
8340
8472
  const code = market['linear'] ? market['quote'] : market['base'];
8341
- // sometimes not all the codes are correctly returned...
8342
- if (code in balances) {
8343
- const parsed = this.parseAccountPosition(this.extend(position, {
8344
- 'crossMargin': balances[code]['crossMargin'],
8345
- 'crossWalletBalance': balances[code]['crossWalletBalance'],
8346
- }), market);
8347
- result.push(parsed);
8473
+ const maintenanceMargin = this.safeString(position, 'maintMargin');
8474
+ // check for maintenance margin so empty positions are not returned
8475
+ if ((maintenanceMargin !== '0') && (maintenanceMargin !== '0.00000000')) {
8476
+ // sometimes not all the codes are correctly returned...
8477
+ if (code in balances) {
8478
+ const parsed = this.parseAccountPosition(this.extend(position, {
8479
+ 'crossMargin': balances[code]['crossMargin'],
8480
+ 'crossWalletBalance': balances[code]['crossWalletBalance'],
8481
+ }), market);
8482
+ result.push(parsed);
8483
+ }
8348
8484
  }
8349
8485
  }
8350
8486
  return result;
@@ -8352,6 +8488,7 @@ export default class binance extends Exchange {
8352
8488
  parseAccountPosition(position, market = undefined) {
8353
8489
  //
8354
8490
  // usdm
8491
+ //
8355
8492
  // {
8356
8493
  // "symbol": "BTCBUSD",
8357
8494
  // "initialMargin": "0",
@@ -8372,6 +8509,7 @@ export default class binance extends Exchange {
8372
8509
  // }
8373
8510
  //
8374
8511
  // coinm
8512
+ //
8375
8513
  // {
8376
8514
  // "symbol": "BTCUSD_210625",
8377
8515
  // "initialMargin": "0.00024393",
@@ -8390,6 +8528,46 @@ export default class binance extends Exchange {
8390
8528
  // "crossWalletBalance": "34",
8391
8529
  // }
8392
8530
  //
8531
+ // linear portfolio margin
8532
+ //
8533
+ // {
8534
+ // "symbol": "CTSIUSDT",
8535
+ // "initialMargin": "0",
8536
+ // "maintMargin": "0",
8537
+ // "unrealizedProfit": "0.00000000",
8538
+ // "positionInitialMargin": "0",
8539
+ // "openOrderInitialMargin": "0",
8540
+ // "leverage": "20",
8541
+ // "entryPrice": "0.0",
8542
+ // "maxNotional": "25000",
8543
+ // "bidNotional": "0",
8544
+ // "askNotional": "0",
8545
+ // "positionSide": "SHORT",
8546
+ // "positionAmt": "0",
8547
+ // "updateTime": 0,
8548
+ // "notional": "0",
8549
+ // "breakEvenPrice": "0.0"
8550
+ // }
8551
+ //
8552
+ // inverse portoflio margin
8553
+ //
8554
+ // {
8555
+ // "symbol": "TRXUSD_PERP",
8556
+ // "initialMargin": "0",
8557
+ // "maintMargin": "0",
8558
+ // "unrealizedProfit": "0.00000000",
8559
+ // "positionInitialMargin": "0",
8560
+ // "openOrderInitialMargin": "0",
8561
+ // "leverage": "20",
8562
+ // "entryPrice": "0.00000000",
8563
+ // "positionSide": "SHORT",
8564
+ // "positionAmt": "0",
8565
+ // "maxQty": "5000000",
8566
+ // "updateTime": 0,
8567
+ // "notionalValue": "0",
8568
+ // "breakEvenPrice": "0.00000000"
8569
+ // }
8570
+ //
8393
8571
  const marketId = this.safeString(position, 'symbol');
8394
8572
  market = this.safeMarket(marketId, market, undefined, 'contract');
8395
8573
  const symbol = this.safeString(market, 'symbol');
@@ -8420,8 +8598,8 @@ export default class binance extends Exchange {
8420
8598
  contractsStringAbs = Precise.stringDiv(Precise.stringAdd(contractsString, '0.5'), '1', 0);
8421
8599
  }
8422
8600
  const contracts = this.parseNumber(contractsStringAbs);
8423
- const leverageBrackets = this.safeValue(this.options, 'leverageBrackets', {});
8424
- const leverageBracket = this.safeValue(leverageBrackets, symbol, []);
8601
+ const leverageBrackets = this.safeDict(this.options, 'leverageBrackets', {});
8602
+ const leverageBracket = this.safeList(leverageBrackets, symbol, []);
8425
8603
  let maintenanceMarginPercentageString = undefined;
8426
8604
  for (let i = 0; i < leverageBracket.length; i++) {
8427
8605
  const bracket = leverageBracket[i];
@@ -8437,7 +8615,7 @@ export default class binance extends Exchange {
8437
8615
  if (timestamp === 0) {
8438
8616
  timestamp = undefined;
8439
8617
  }
8440
- const isolated = this.safeValue(position, 'isolated');
8618
+ const isolated = this.safeBool(position, 'isolated');
8441
8619
  let marginMode = undefined;
8442
8620
  let collateralString = undefined;
8443
8621
  let walletBalance = undefined;
@@ -8590,11 +8768,45 @@ export default class binance extends Exchange {
8590
8768
  // "isolatedWallet": "0.00268058"
8591
8769
  // }
8592
8770
  //
8771
+ // inverse portfolio margin
8772
+ //
8773
+ // {
8774
+ // "symbol": "ETHUSD_PERP",
8775
+ // "positionAmt": "1",
8776
+ // "entryPrice": "2422.400000007",
8777
+ // "markPrice": "2424.51267823",
8778
+ // "unRealizedProfit": "0.0000036",
8779
+ // "liquidationPrice": "293.57678898",
8780
+ // "leverage": "100",
8781
+ // "positionSide": "LONG",
8782
+ // "updateTime": 1707371941861,
8783
+ // "maxQty": "15",
8784
+ // "notionalValue": "0.00412454",
8785
+ // "breakEvenPrice": "2423.368960034"
8786
+ // }
8787
+ //
8788
+ // linear portfolio margin
8789
+ //
8790
+ // {
8791
+ // "symbol": "BTCUSDT",
8792
+ // "positionAmt": "0.01",
8793
+ // "entryPrice": "44525.0",
8794
+ // "markPrice": "45464.1735922",
8795
+ // "unRealizedProfit": "9.39173592",
8796
+ // "liquidationPrice": "38007.16308568",
8797
+ // "leverage": "100",
8798
+ // "positionSide": "LONG",
8799
+ // "updateTime": 1707371879042,
8800
+ // "maxNotionalValue": "500000.0",
8801
+ // "notional": "454.64173592",
8802
+ // "breakEvenPrice": "44542.81"
8803
+ // }
8804
+ //
8593
8805
  const marketId = this.safeString(position, 'symbol');
8594
8806
  market = this.safeMarket(marketId, market, undefined, 'contract');
8595
8807
  const symbol = this.safeString(market, 'symbol');
8596
- const leverageBrackets = this.safeValue(this.options, 'leverageBrackets', {});
8597
- const leverageBracket = this.safeValue(leverageBrackets, symbol, []);
8808
+ const leverageBrackets = this.safeDict(this.options, 'leverageBrackets', {});
8809
+ const leverageBracket = this.safeList(leverageBrackets, symbol, []);
8598
8810
  const notionalString = this.safeString2(position, 'notional', 'notionalValue');
8599
8811
  const notionalStringAbs = Precise.stringAbs(notionalString);
8600
8812
  let maintenanceMarginPercentageString = undefined;
@@ -8631,7 +8843,7 @@ export default class binance extends Exchange {
8631
8843
  const linear = ('notional' in position);
8632
8844
  if (marginMode === 'cross') {
8633
8845
  // calculate collateral
8634
- const precision = this.safeValue(market, 'precision', {});
8846
+ const precision = this.safeDict(market, 'precision', {});
8635
8847
  if (linear) {
8636
8848
  // walletBalance = (liquidationPrice * (±1 + mmp) ± entryPrice) * contracts
8637
8849
  let onePlusMaintenanceMarginPercentageString = undefined;
@@ -8738,12 +8950,24 @@ export default class binance extends Exchange {
8738
8950
  const query = this.omit(params, 'type');
8739
8951
  let subType = undefined;
8740
8952
  [subType, params] = this.handleSubTypeAndParams('loadLeverageBrackets', undefined, params, 'linear');
8953
+ let isPortfolioMargin = undefined;
8954
+ [isPortfolioMargin, params] = this.handleOptionAndParams2(params, 'loadLeverageBrackets', 'papi', 'portfolioMargin', false);
8741
8955
  let response = undefined;
8742
8956
  if (this.isLinear(type, subType)) {
8743
- response = await this.fapiPrivateGetLeverageBracket(query);
8957
+ if (isPortfolioMargin) {
8958
+ response = await this.papiGetUmLeverageBracket(query);
8959
+ }
8960
+ else {
8961
+ response = await this.fapiPrivateGetLeverageBracket(query);
8962
+ }
8744
8963
  }
8745
8964
  else if (this.isInverse(type, subType)) {
8746
- response = await this.dapiPrivateV2GetLeverageBracket(query);
8965
+ if (isPortfolioMargin) {
8966
+ response = await this.papiGetCmLeverageBracket(query);
8967
+ }
8968
+ else {
8969
+ response = await this.dapiPrivateV2GetLeverageBracket(query);
8970
+ }
8747
8971
  }
8748
8972
  else {
8749
8973
  throw new NotSupported(this.id + ' loadLeverageBrackets() supports linear and inverse contracts only');
@@ -8753,7 +8977,7 @@ export default class binance extends Exchange {
8753
8977
  const entry = response[i];
8754
8978
  const marketId = this.safeString(entry, 'symbol');
8755
8979
  const symbol = this.safeSymbol(marketId, undefined, undefined, 'contract');
8756
- const brackets = this.safeValue(entry, 'brackets', []);
8980
+ const brackets = this.safeList(entry, 'brackets', []);
8757
8981
  const result = [];
8758
8982
  for (let j = 0; j < brackets.length; j++) {
8759
8983
  const bracket = brackets[j];
@@ -8773,8 +8997,11 @@ export default class binance extends Exchange {
8773
8997
  * @description retrieve information on the maximum leverage, and maintenance margin for trades of varying trade sizes
8774
8998
  * @see https://binance-docs.github.io/apidocs/futures/en/#notional-and-leverage-brackets-user_data
8775
8999
  * @see https://binance-docs.github.io/apidocs/delivery/en/#notional-bracket-for-symbol-user_data
9000
+ * @see https://binance-docs.github.io/apidocs/pm/en/#um-notional-and-leverage-brackets-user_data
9001
+ * @see https://binance-docs.github.io/apidocs/pm/en/#cm-notional-and-leverage-brackets-user_data
8776
9002
  * @param {string[]|undefined} symbols list of unified market symbols
8777
9003
  * @param {object} [params] extra parameters specific to the exchange API endpoint
9004
+ * @param {boolean} [params.portfolioMargin] set to true if you would like to fetch the leverage tiers for a portfolio margin account
8778
9005
  * @returns {object} a dictionary of [leverage tiers structures]{@link https://docs.ccxt.com/#/?id=leverage-tiers-structure}, indexed by market symbols
8779
9006
  */
8780
9007
  await this.loadMarkets();
@@ -8782,12 +9009,24 @@ export default class binance extends Exchange {
8782
9009
  [type, params] = this.handleMarketTypeAndParams('fetchLeverageTiers', undefined, params);
8783
9010
  let subType = undefined;
8784
9011
  [subType, params] = this.handleSubTypeAndParams('fetchLeverageTiers', undefined, params, 'linear');
9012
+ let isPortfolioMargin = undefined;
9013
+ [isPortfolioMargin, params] = this.handleOptionAndParams2(params, 'fetchLeverageTiers', 'papi', 'portfolioMargin', false);
8785
9014
  let response = undefined;
8786
9015
  if (this.isLinear(type, subType)) {
8787
- response = await this.fapiPrivateGetLeverageBracket(params);
9016
+ if (isPortfolioMargin) {
9017
+ response = await this.papiGetUmLeverageBracket(params);
9018
+ }
9019
+ else {
9020
+ response = await this.fapiPrivateGetLeverageBracket(params);
9021
+ }
8788
9022
  }
8789
9023
  else if (this.isInverse(type, subType)) {
8790
- response = await this.dapiPrivateV2GetLeverageBracket(params);
9024
+ if (isPortfolioMargin) {
9025
+ response = await this.papiGetCmLeverageBracket(params);
9026
+ }
9027
+ else {
9028
+ response = await this.dapiPrivateV2GetLeverageBracket(params);
9029
+ }
8791
9030
  }
8792
9031
  else {
8793
9032
  throw new NotSupported(this.id + ' fetchLeverageTiers() supports linear and inverse contracts only');
@@ -8857,7 +9096,7 @@ export default class binance extends Exchange {
8857
9096
  //
8858
9097
  const marketId = this.safeString(info, 'symbol');
8859
9098
  market = this.safeMarket(marketId, market, undefined, 'contract');
8860
- const brackets = this.safeValue(info, 'brackets', []);
9099
+ const brackets = this.safeList(info, 'brackets', []);
8861
9100
  const tiers = [];
8862
9101
  for (let j = 0; j < brackets.length; j++) {
8863
9102
  const bracket = brackets[j];
@@ -9072,8 +9311,11 @@ export default class binance extends Exchange {
9072
9311
  * @description fetch account positions
9073
9312
  * @see https://binance-docs.github.io/apidocs/futures/en/#account-information-v2-user_data
9074
9313
  * @see https://binance-docs.github.io/apidocs/delivery/en/#account-information-user_data
9314
+ * @see https://binance-docs.github.io/apidocs/pm/en/#get-um-account-detail-user_data
9315
+ * @see https://binance-docs.github.io/apidocs/pm/en/#get-cm-account-detail-user_data
9075
9316
  * @param {string[]|undefined} symbols list of unified market symbols
9076
9317
  * @param {object} [params] extra parameters specific to the exchange API endpoint
9318
+ * @param {boolean} [params.portfolioMargin] set to true if you would like to fetch positions in a portfolio margin account
9077
9319
  * @returns {object} data on account positions
9078
9320
  */
9079
9321
  if (symbols !== undefined) {
@@ -9085,15 +9327,27 @@ export default class binance extends Exchange {
9085
9327
  await this.loadLeverageBrackets(false, params);
9086
9328
  const defaultType = this.safeString(this.options, 'defaultType', 'future');
9087
9329
  const type = this.safeString(params, 'type', defaultType);
9088
- let query = this.omit(params, 'type');
9330
+ params = this.omit(params, 'type');
9089
9331
  let subType = undefined;
9090
- [subType, query] = this.handleSubTypeAndParams('fetchAccountPositions', undefined, params, 'linear');
9332
+ [subType, params] = this.handleSubTypeAndParams('fetchAccountPositions', undefined, params, 'linear');
9333
+ let isPortfolioMargin = undefined;
9334
+ [isPortfolioMargin, params] = this.handleOptionAndParams2(params, 'fetchAccountPositions', 'papi', 'portfolioMargin', false);
9091
9335
  let response = undefined;
9092
9336
  if (this.isLinear(type, subType)) {
9093
- response = await this.fapiPrivateV2GetAccount(query);
9337
+ if (isPortfolioMargin) {
9338
+ response = await this.papiGetUmAccount(params);
9339
+ }
9340
+ else {
9341
+ response = await this.fapiPrivateV2GetAccount(params);
9342
+ }
9094
9343
  }
9095
9344
  else if (this.isInverse(type, subType)) {
9096
- response = await this.dapiPrivateGetAccount(query);
9345
+ if (isPortfolioMargin) {
9346
+ response = await this.papiGetCmAccount(params);
9347
+ }
9348
+ else {
9349
+ response = await this.dapiPrivateGetAccount(params);
9350
+ }
9097
9351
  }
9098
9352
  else {
9099
9353
  throw new NotSupported(this.id + ' fetchPositions() supports linear and inverse contracts only');
@@ -9110,8 +9364,11 @@ export default class binance extends Exchange {
9110
9364
  * @description fetch positions risk
9111
9365
  * @see https://binance-docs.github.io/apidocs/futures/en/#position-information-v2-user_data
9112
9366
  * @see https://binance-docs.github.io/apidocs/delivery/en/#position-information-user_data
9367
+ * @see https://binance-docs.github.io/apidocs/pm/en/#query-um-position-information-user_data
9368
+ * @see https://binance-docs.github.io/apidocs/pm/en/#query-cm-position-information-user_data
9113
9369
  * @param {string[]|undefined} symbols list of unified market symbols
9114
9370
  * @param {object} [params] extra parameters specific to the exchange API endpoint
9371
+ * @param {boolean} [params.portfolioMargin] set to true if you would like to fetch positions for a portfolio margin account
9115
9372
  * @returns {object} data on the positions risk
9116
9373
  */
9117
9374
  if (symbols !== undefined) {
@@ -9127,71 +9384,124 @@ export default class binance extends Exchange {
9127
9384
  const type = this.safeString(params, 'type', defaultType);
9128
9385
  let subType = undefined;
9129
9386
  [subType, params] = this.handleSubTypeAndParams('fetchPositionsRisk', undefined, params, 'linear');
9387
+ let isPortfolioMargin = undefined;
9388
+ [isPortfolioMargin, params] = this.handleOptionAndParams2(params, 'fetchPositionsRisk', 'papi', 'portfolioMargin', false);
9130
9389
  params = this.omit(params, 'type');
9131
9390
  let response = undefined;
9132
9391
  if (this.isLinear(type, subType)) {
9133
- response = await this.fapiPrivateV2GetPositionRisk(this.extend(request, params));
9134
- // ### Response examples ###
9135
- //
9136
- // For One-way position mode:
9137
- // [
9138
- // {
9139
- // "entryPrice": "0.00000",
9140
- // "marginType": "isolated",
9141
- // "isAutoAddMargin": "false",
9142
- // "isolatedMargin": "0.00000000",
9143
- // "leverage": "10",
9144
- // "liquidationPrice": "0",
9145
- // "markPrice": "6679.50671178",
9146
- // "maxNotionalValue": "20000000",
9147
- // "positionAmt": "0.000",
9148
- // "symbol": "BTCUSDT",
9149
- // "unRealizedProfit": "0.00000000",
9150
- // "positionSide": "BOTH",
9151
- // "updateTime": 0
9152
- // }
9153
- // ]
9154
- //
9155
- // For Hedge position mode:
9156
- // [
9157
- // {
9158
- // "entryPrice": "6563.66500",
9159
- // "marginType": "isolated",
9160
- // "isAutoAddMargin": "false",
9161
- // "isolatedMargin": "15517.54150468",
9162
- // "leverage": "10",
9163
- // "liquidationPrice": "5930.78",
9164
- // "markPrice": "6679.50671178",
9165
- // "maxNotionalValue": "20000000",
9166
- // "positionAmt": "20.000",
9167
- // "symbol": "BTCUSDT",
9168
- // "unRealizedProfit": "2316.83423560"
9169
- // "positionSide": "LONG",
9170
- // "updateTime": 1625474304765
9171
- // },
9172
- // {
9173
- // "entryPrice": "0.00000",
9174
- // "marginType": "isolated",
9175
- // "isAutoAddMargin": "false",
9176
- // "isolatedMargin": "5413.95799991",
9177
- // "leverage": "10",
9178
- // "liquidationPrice": "7189.95",
9179
- // "markPrice": "6679.50671178",
9180
- // "maxNotionalValue": "20000000",
9181
- // "positionAmt": "-10.000",
9182
- // "symbol": "BTCUSDT",
9183
- // "unRealizedProfit": "-1156.46711780",
9184
- // "positionSide": "SHORT",
9185
- // "updateTime": 0
9186
- // }
9187
- // ]
9392
+ if (isPortfolioMargin) {
9393
+ response = await this.papiGetUmPositionRisk(this.extend(request, params));
9394
+ }
9395
+ else {
9396
+ response = await this.fapiPrivateV2GetPositionRisk(this.extend(request, params));
9397
+ }
9188
9398
  }
9189
9399
  else if (this.isInverse(type, subType)) {
9190
- response = await this.dapiPrivateGetPositionRisk(this.extend(request, params));
9400
+ if (isPortfolioMargin) {
9401
+ response = await this.papiGetCmPositionRisk(this.extend(request, params));
9402
+ }
9403
+ else {
9404
+ response = await this.dapiPrivateGetPositionRisk(this.extend(request, params));
9405
+ }
9191
9406
  }
9192
9407
  else {
9193
9408
  throw new NotSupported(this.id + ' fetchPositionsRisk() supports linear and inverse contracts only');
9194
9409
  }
9410
+ // ### Response examples ###
9411
+ //
9412
+ // For One-way position mode:
9413
+ //
9414
+ // [
9415
+ // {
9416
+ // "entryPrice": "0.00000",
9417
+ // "marginType": "isolated",
9418
+ // "isAutoAddMargin": "false",
9419
+ // "isolatedMargin": "0.00000000",
9420
+ // "leverage": "10",
9421
+ // "liquidationPrice": "0",
9422
+ // "markPrice": "6679.50671178",
9423
+ // "maxNotionalValue": "20000000",
9424
+ // "positionAmt": "0.000",
9425
+ // "symbol": "BTCUSDT",
9426
+ // "unRealizedProfit": "0.00000000",
9427
+ // "positionSide": "BOTH",
9428
+ // "updateTime": 0
9429
+ // }
9430
+ // ]
9431
+ //
9432
+ // For Hedge position mode:
9433
+ //
9434
+ // [
9435
+ // {
9436
+ // "entryPrice": "6563.66500",
9437
+ // "marginType": "isolated",
9438
+ // "isAutoAddMargin": "false",
9439
+ // "isolatedMargin": "15517.54150468",
9440
+ // "leverage": "10",
9441
+ // "liquidationPrice": "5930.78",
9442
+ // "markPrice": "6679.50671178",
9443
+ // "maxNotionalValue": "20000000",
9444
+ // "positionAmt": "20.000",
9445
+ // "symbol": "BTCUSDT",
9446
+ // "unRealizedProfit": "2316.83423560"
9447
+ // "positionSide": "LONG",
9448
+ // "updateTime": 1625474304765
9449
+ // },
9450
+ // {
9451
+ // "entryPrice": "0.00000",
9452
+ // "marginType": "isolated",
9453
+ // "isAutoAddMargin": "false",
9454
+ // "isolatedMargin": "5413.95799991",
9455
+ // "leverage": "10",
9456
+ // "liquidationPrice": "7189.95",
9457
+ // "markPrice": "6679.50671178",
9458
+ // "maxNotionalValue": "20000000",
9459
+ // "positionAmt": "-10.000",
9460
+ // "symbol": "BTCUSDT",
9461
+ // "unRealizedProfit": "-1156.46711780",
9462
+ // "positionSide": "SHORT",
9463
+ // "updateTime": 0
9464
+ // }
9465
+ // ]
9466
+ //
9467
+ // inverse portfolio margin:
9468
+ //
9469
+ // [
9470
+ // {
9471
+ // "symbol": "ETHUSD_PERP",
9472
+ // "positionAmt": "1",
9473
+ // "entryPrice": "2422.400000007",
9474
+ // "markPrice": "2424.51267823",
9475
+ // "unRealizedProfit": "0.0000036",
9476
+ // "liquidationPrice": "293.57678898",
9477
+ // "leverage": "100",
9478
+ // "positionSide": "LONG",
9479
+ // "updateTime": 1707371941861,
9480
+ // "maxQty": "15",
9481
+ // "notionalValue": "0.00412454",
9482
+ // "breakEvenPrice": "2423.368960034"
9483
+ // }
9484
+ // ]
9485
+ //
9486
+ // linear portfolio margin:
9487
+ //
9488
+ // [
9489
+ // {
9490
+ // "symbol": "BTCUSDT",
9491
+ // "positionAmt": "0.01",
9492
+ // "entryPrice": "44525.0",
9493
+ // "markPrice": "45464.1735922",
9494
+ // "unRealizedProfit": "9.39173592",
9495
+ // "liquidationPrice": "38007.16308568",
9496
+ // "leverage": "100",
9497
+ // "positionSide": "LONG",
9498
+ // "updateTime": 1707371879042,
9499
+ // "maxNotionalValue": "500000.0",
9500
+ // "notional": "454.64173592",
9501
+ // "breakEvenPrice": "44542.81"
9502
+ // }
9503
+ // ]
9504
+ //
9195
9505
  const result = [];
9196
9506
  for (let i = 0; i < response.length; i++) {
9197
9507
  const parsed = this.parsePositionRisk(response[i]);
@@ -9207,15 +9517,19 @@ export default class binance extends Exchange {
9207
9517
  * @description fetch the history of funding payments paid and received on this account
9208
9518
  * @see https://binance-docs.github.io/apidocs/futures/en/#get-income-history-user_data
9209
9519
  * @see https://binance-docs.github.io/apidocs/delivery/en/#get-income-history-user_data
9520
+ * @see https://binance-docs.github.io/apidocs/pm/en/#get-um-income-history-user_data
9521
+ * @see https://binance-docs.github.io/apidocs/pm/en/#get-cm-income-history-user_data
9210
9522
  * @param {string} symbol unified market symbol
9211
9523
  * @param {int} [since] the earliest time in ms to fetch funding history for
9212
9524
  * @param {int} [limit] the maximum number of funding history structures to retrieve
9213
9525
  * @param {object} [params] extra parameters specific to the exchange API endpoint
9526
+ * @param {int} [params.until] timestamp in ms of the latest funding history entry
9527
+ * @param {boolean} [params.portfolioMargin] set to true if you would like to fetch the funding history for a portfolio margin account
9214
9528
  * @returns {object} a [funding history structure]{@link https://docs.ccxt.com/#/?id=funding-history-structure}
9215
9529
  */
9216
9530
  await this.loadMarkets();
9217
9531
  let market = undefined;
9218
- const request = {
9532
+ let request = {
9219
9533
  'incomeType': 'FUNDING_FEE', // "TRANSFER","WELCOME_BONUS", "REALIZED_PNL","FUNDING_FEE", "COMMISSION" and "INSURANCE_CLEAR"
9220
9534
  };
9221
9535
  if (symbol !== undefined) {
@@ -9227,6 +9541,9 @@ export default class binance extends Exchange {
9227
9541
  }
9228
9542
  let subType = undefined;
9229
9543
  [subType, params] = this.handleSubTypeAndParams('fetchFundingHistory', market, params, 'linear');
9544
+ let isPortfolioMargin = undefined;
9545
+ [isPortfolioMargin, params] = this.handleOptionAndParams2(params, 'fetchFundingHistory', 'papi', 'portfolioMargin', false);
9546
+ [request, params] = this.handleUntilOption('endTime', request, params);
9230
9547
  if (since !== undefined) {
9231
9548
  request['startTime'] = since;
9232
9549
  }
@@ -9238,10 +9555,20 @@ export default class binance extends Exchange {
9238
9555
  params = this.omit(params, 'type');
9239
9556
  let response = undefined;
9240
9557
  if (this.isLinear(type, subType)) {
9241
- response = await this.fapiPrivateGetIncome(this.extend(request, params));
9558
+ if (isPortfolioMargin) {
9559
+ response = await this.papiGetUmIncome(this.extend(request, params));
9560
+ }
9561
+ else {
9562
+ response = await this.fapiPrivateGetIncome(this.extend(request, params));
9563
+ }
9242
9564
  }
9243
9565
  else if (this.isInverse(type, subType)) {
9244
- response = await this.dapiPrivateGetIncome(this.extend(request, params));
9566
+ if (isPortfolioMargin) {
9567
+ response = await this.papiGetCmIncome(this.extend(request, params));
9568
+ }
9569
+ else {
9570
+ response = await this.dapiPrivateGetIncome(this.extend(request, params));
9571
+ }
9245
9572
  }
9246
9573
  else {
9247
9574
  throw new NotSupported(this.id + ' fetchFundingHistory() supports linear and inverse contracts only');
@@ -9616,12 +9943,15 @@ export default class binance extends Exchange {
9616
9943
  * @see https://binance-docs.github.io/apidocs/voptions/en/#account-funding-flow-user_data
9617
9944
  * @see https://binance-docs.github.io/apidocs/futures/en/#get-income-history-user_data
9618
9945
  * @see https://binance-docs.github.io/apidocs/delivery/en/#get-income-history-user_data
9946
+ * @see https://binance-docs.github.io/apidocs/pm/en/#get-um-income-history-user_data
9947
+ * @see https://binance-docs.github.io/apidocs/pm/en/#get-cm-income-history-user_data
9619
9948
  * @param {string} code unified currency code
9620
9949
  * @param {int} [since] timestamp in ms of the earliest ledger entry
9621
9950
  * @param {int} [limit] max number of ledger entrys to return
9622
9951
  * @param {object} [params] extra parameters specific to the exchange API endpoint
9623
9952
  * @param {int} [params.until] timestamp in ms of the latest ledger entry
9624
- * @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)
9953
+ * @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)
9954
+ * @param {boolean} [params.portfolioMargin] set to true if you would like to fetch the ledger for a portfolio margin account
9625
9955
  * @returns {object} a [ledger structure]{@link https://docs.ccxt.com/#/?id=ledger-structure}
9626
9956
  */
9627
9957
  await this.loadMarkets();
@@ -9650,6 +9980,8 @@ export default class binance extends Exchange {
9650
9980
  params = this.omit(params, 'until');
9651
9981
  request['endTime'] = until;
9652
9982
  }
9983
+ let isPortfolioMargin = undefined;
9984
+ [isPortfolioMargin, params] = this.handleOptionAndParams2(params, 'fetchLedger', 'papi', 'portfolioMargin', false);
9653
9985
  let response = undefined;
9654
9986
  if (type === 'option') {
9655
9987
  this.checkRequiredArgument('fetchLedger', code, 'code');
@@ -9657,10 +9989,20 @@ export default class binance extends Exchange {
9657
9989
  response = await this.eapiPrivateGetBill(this.extend(request, params));
9658
9990
  }
9659
9991
  else if (this.isLinear(type, subType)) {
9660
- response = await this.fapiPrivateGetIncome(this.extend(request, params));
9992
+ if (isPortfolioMargin) {
9993
+ response = await this.papiGetUmIncome(this.extend(request, params));
9994
+ }
9995
+ else {
9996
+ response = await this.fapiPrivateGetIncome(this.extend(request, params));
9997
+ }
9661
9998
  }
9662
9999
  else if (this.isInverse(type, subType)) {
9663
- response = await this.dapiPrivateGetIncome(this.extend(request, params));
10000
+ if (isPortfolioMargin) {
10001
+ response = await this.papiGetCmIncome(this.extend(request, params));
10002
+ }
10003
+ else {
10004
+ response = await this.dapiPrivateGetIncome(this.extend(request, params));
10005
+ }
9664
10006
  }
9665
10007
  else {
9666
10008
  throw new NotSupported(this.id + ' fetchLedger() supports contract wallets only');
@@ -9678,7 +10020,7 @@ export default class binance extends Exchange {
9678
10020
  // }
9679
10021
  // ]
9680
10022
  //
9681
- // futures (fapi, dapi)
10023
+ // futures (fapi, dapi, papi)
9682
10024
  //
9683
10025
  // [
9684
10026
  // {
@@ -9707,7 +10049,7 @@ export default class binance extends Exchange {
9707
10049
  // "createDate": 1676621042489
9708
10050
  // }
9709
10051
  //
9710
- // futures (fapi, dapi)
10052
+ // futures (fapi, dapi, papi)
9711
10053
  //
9712
10054
  // {
9713
10055
  // "symbol": "",
@@ -9816,7 +10158,7 @@ export default class binance extends Exchange {
9816
10158
  const isSpotOrMargin = (api.indexOf('sapi') > -1 || api === 'private');
9817
10159
  const marketType = isSpotOrMargin ? 'spot' : 'future';
9818
10160
  const defaultId = (!isSpotOrMargin) ? 'x-xcKtGhcu' : 'x-R4BD3S82';
9819
- const broker = this.safeValue(this.options, 'broker', {});
10161
+ const broker = this.safeDict(this.options, 'broker', {});
9820
10162
  const brokerId = this.safeString(broker, marketType, defaultId);
9821
10163
  params['newClientOrderId'] = brokerId + this.uuid22();
9822
10164
  }
@@ -9844,8 +10186,8 @@ export default class binance extends Exchange {
9844
10186
  }
9845
10187
  else if ((path === 'batchOrders') || (path.indexOf('sub-account') >= 0) || (path === 'capital/withdraw/apply') || (path.indexOf('staking') >= 0)) {
9846
10188
  if ((method === 'DELETE') && (path === 'batchOrders')) {
9847
- const orderidlist = this.safeValue(extendedParams, 'orderidlist', []);
9848
- const origclientorderidlist = this.safeValue(extendedParams, 'origclientorderidlist', []);
10189
+ const orderidlist = this.safeList(extendedParams, 'orderidlist', []);
10190
+ const origclientorderidlist = this.safeList(extendedParams, 'origclientorderidlist', []);
9849
10191
  extendedParams = this.omit(extendedParams, ['orderidlist', 'origclientorderidlist']);
9850
10192
  query = this.rawencode(extendedParams);
9851
10193
  const orderidlistLength = orderidlist.length;
@@ -9914,8 +10256,8 @@ export default class binance extends Exchange {
9914
10256
  marketType = 'portfoliomargin';
9915
10257
  }
9916
10258
  if (marketType !== undefined) {
9917
- const exceptionsForMarketType = this.safeValue(this.exceptions, marketType, {});
9918
- return this.safeValue(exceptionsForMarketType, exactOrBroad, {});
10259
+ const exceptionsForMarketType = this.safeDict(this.exceptions, marketType, {});
10260
+ return this.safeDict(exceptionsForMarketType, exactOrBroad, {});
9919
10261
  }
9920
10262
  return {};
9921
10263
  }
@@ -10149,7 +10491,7 @@ export default class binance extends Exchange {
10149
10491
  // },
10150
10492
  // ]
10151
10493
  //
10152
- const rate = this.safeValue(response, 0);
10494
+ const rate = this.safeDict(response, 0);
10153
10495
  return this.parseBorrowRate(rate);
10154
10496
  }
10155
10497
  async fetchBorrowRateHistory(code, since = undefined, limit = undefined, params = {}) {
@@ -10253,7 +10595,7 @@ export default class binance extends Exchange {
10253
10595
  // "success": true
10254
10596
  // }
10255
10597
  //
10256
- const data = this.safeValue(response, 'data');
10598
+ const data = this.safeDict(response, 'data');
10257
10599
  const giftcardCode = this.safeString(data, 'code');
10258
10600
  const id = this.safeString(data, 'referenceNo');
10259
10601
  return {
@@ -10321,15 +10663,19 @@ export default class binance extends Exchange {
10321
10663
  * @name binance#fetchBorrowInterest
10322
10664
  * @description fetch the interest owed by the user for borrowing currency for margin trading
10323
10665
  * @see https://binance-docs.github.io/apidocs/spot/en/#get-interest-history-user_data
10324
- * @param {string} code unified currency code
10325
- * @param {string} symbol unified market symbol when fetch interest in isolated markets
10666
+ * @see https://binance-docs.github.io/apidocs/pm/en/#get-margin-borrow-loan-interest-history-user_data
10667
+ * @param {string} [code] unified currency code
10668
+ * @param {string} [symbol] unified market symbol when fetch interest in isolated markets
10326
10669
  * @param {int} [since] the earliest time in ms to fetch borrrow interest for
10327
10670
  * @param {int} [limit] the maximum number of structures to retrieve
10328
10671
  * @param {object} [params] extra parameters specific to the exchange API endpoint
10672
+ * @param {boolean} [params.portfolioMargin] set to true if you would like to fetch the borrow interest in a portfolio margin account
10329
10673
  * @returns {object[]} a list of [borrow interest structures]{@link https://docs.ccxt.com/#/?id=borrow-interest-structure}
10330
10674
  */
10331
10675
  await this.loadMarkets();
10332
- const request = {};
10676
+ let isPortfolioMargin = undefined;
10677
+ [isPortfolioMargin, params] = this.handleOptionAndParams2(params, 'fetchBorrowInterest', 'papi', 'portfolioMargin', false);
10678
+ let request = {};
10333
10679
  let market = undefined;
10334
10680
  if (code !== undefined) {
10335
10681
  const currency = this.currency(code);
@@ -10341,11 +10687,20 @@ export default class binance extends Exchange {
10341
10687
  if (limit !== undefined) {
10342
10688
  request['size'] = limit;
10343
10689
  }
10344
- if (symbol !== undefined) { // Isolated
10345
- market = this.market(symbol);
10346
- request['isolatedSymbol'] = market['id'];
10690
+ [request, params] = this.handleUntilOption('endTime', request, params);
10691
+ let response = undefined;
10692
+ if (isPortfolioMargin) {
10693
+ response = await this.papiGetMarginMarginInterestHistory(this.extend(request, params));
10694
+ }
10695
+ else {
10696
+ if (symbol !== undefined) {
10697
+ market = this.market(symbol);
10698
+ request['isolatedSymbol'] = market['id'];
10699
+ }
10700
+ response = await this.sapiGetMarginInterestHistory(this.extend(request, params));
10347
10701
  }
10348
- const response = await this.sapiGetMarginInterestHistory(this.extend(request, params));
10702
+ //
10703
+ // spot margin
10349
10704
  //
10350
10705
  // {
10351
10706
  // "rows":[
@@ -10362,13 +10717,31 @@ export default class binance extends Exchange {
10362
10717
  // "total": 1
10363
10718
  // }
10364
10719
  //
10365
- const rows = this.safeValue(response, 'rows');
10720
+ // spot margin portfolio margin
10721
+ //
10722
+ // {
10723
+ // "total": 49,
10724
+ // "rows": [
10725
+ // {
10726
+ // "txId": 1656187724899910076,
10727
+ // "interestAccuredTime": 1707541200000,
10728
+ // "asset": "USDT",
10729
+ // "rawAsset": "USDT",
10730
+ // "principal": "0.00011146",
10731
+ // "interest": "0.00000001",
10732
+ // "interestRate": "0.00089489",
10733
+ // "type": "PERIODIC"
10734
+ // },
10735
+ // ]
10736
+ // }
10737
+ //
10738
+ const rows = this.safeList(response, 'rows');
10366
10739
  const interest = this.parseBorrowInterests(rows, market);
10367
10740
  return this.filterByCurrencySinceLimit(interest, code, since, limit);
10368
10741
  }
10369
10742
  parseBorrowInterest(info, market = undefined) {
10370
10743
  const symbol = this.safeString(info, 'isolatedSymbol');
10371
- const timestamp = this.safeNumber(info, 'interestAccuredTime');
10744
+ const timestamp = this.safeInteger(info, 'interestAccuredTime');
10372
10745
  const marginMode = (symbol === undefined) ? 'cross' : 'isolated';
10373
10746
  return {
10374
10747
  'account': (symbol === undefined) ? 'cross' : symbol,
@@ -10389,9 +10762,11 @@ export default class binance extends Exchange {
10389
10762
  * @name binance#repayCrossMargin
10390
10763
  * @description repay borrowed margin and interest
10391
10764
  * @see https://binance-docs.github.io/apidocs/spot/en/#margin-account-borrow-repay-margin
10765
+ * @see https://binance-docs.github.io/apidocs/pm/en/#margin-account-repay-margin
10392
10766
  * @param {string} code unified currency code of the currency to repay
10393
10767
  * @param {float} amount the amount to repay
10394
10768
  * @param {object} [params] extra parameters specific to the exchange API endpoint
10769
+ * @param {boolean} [params.portfolioMargin] set to true if you would like to repay margin in a portfolio margin account
10395
10770
  * @returns {object} a [margin loan structure]{@link https://docs.ccxt.com/#/?id=margin-loan-structure}
10396
10771
  */
10397
10772
  await this.loadMarkets();
@@ -10399,10 +10774,18 @@ export default class binance extends Exchange {
10399
10774
  const request = {
10400
10775
  'asset': currency['id'],
10401
10776
  'amount': this.currencyToPrecision(code, amount),
10402
- 'isIsolated': 'FALSE',
10403
- 'type': 'REPAY',
10404
10777
  };
10405
- const response = await this.sapiPostMarginBorrowRepay(this.extend(request, params));
10778
+ let response = undefined;
10779
+ let isPortfolioMargin = undefined;
10780
+ [isPortfolioMargin, params] = this.handleOptionAndParams2(params, 'repayCrossMargin', 'papi', 'portfolioMargin', false);
10781
+ if (isPortfolioMargin) {
10782
+ response = await this.papiPostRepayLoan(this.extend(request, params));
10783
+ }
10784
+ else {
10785
+ request['isIsolated'] = 'FALSE';
10786
+ request['type'] = 'REPAY';
10787
+ response = await this.sapiPostMarginBorrowRepay(this.extend(request, params));
10788
+ }
10406
10789
  //
10407
10790
  // {
10408
10791
  // "tranId": 108988250265,
@@ -10448,9 +10831,11 @@ export default class binance extends Exchange {
10448
10831
  * @name binance#borrowCrossMargin
10449
10832
  * @description create a loan to borrow margin
10450
10833
  * @see https://binance-docs.github.io/apidocs/spot/en/#margin-account-borrow-repay-margin
10834
+ * @see https://binance-docs.github.io/apidocs/pm/en/#margin-account-borrow-margin
10451
10835
  * @param {string} code unified currency code of the currency to borrow
10452
10836
  * @param {float} amount the amount to borrow
10453
10837
  * @param {object} [params] extra parameters specific to the exchange API endpoint
10838
+ * @param {boolean} [params.portfolioMargin] set to true if you would like to borrow margin in a portfolio margin account
10454
10839
  * @returns {object} a [margin loan structure]{@link https://docs.ccxt.com/#/?id=margin-loan-structure}
10455
10840
  */
10456
10841
  await this.loadMarkets();
@@ -10458,10 +10843,18 @@ export default class binance extends Exchange {
10458
10843
  const request = {
10459
10844
  'asset': currency['id'],
10460
10845
  'amount': this.currencyToPrecision(code, amount),
10461
- 'isIsolated': 'FALSE',
10462
- 'type': 'BORROW',
10463
10846
  };
10464
- const response = await this.sapiPostMarginBorrowRepay(this.extend(request, params));
10847
+ let response = undefined;
10848
+ let isPortfolioMargin = undefined;
10849
+ [isPortfolioMargin, params] = this.handleOptionAndParams2(params, 'borrowCrossMargin', 'papi', 'portfolioMargin', false);
10850
+ if (isPortfolioMargin) {
10851
+ response = await this.papiPostMarginLoan(this.extend(request, params));
10852
+ }
10853
+ else {
10854
+ request['isIsolated'] = 'FALSE';
10855
+ request['type'] = 'BORROW';
10856
+ response = await this.sapiPostMarginBorrowRepay(this.extend(request, params));
10857
+ }
10465
10858
  //
10466
10859
  // {
10467
10860
  // "tranId": 108988250265,