ccxt 4.2.39 → 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 (47) hide show
  1. package/README.md +3 -3
  2. package/dist/ccxt.browser.js +923 -310
  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 +372 -146
  8. package/dist/cjs/src/bingx.js +250 -23
  9. package/dist/cjs/src/bitget.js +13 -2
  10. package/dist/cjs/src/bybit.js +3 -1
  11. package/dist/cjs/src/coinbase.js +8 -6
  12. package/dist/cjs/src/coinbasepro.js +1 -0
  13. package/dist/cjs/src/coinlist.js +9 -7
  14. package/dist/cjs/src/coinmetro.js +2 -1
  15. package/dist/cjs/src/krakenfutures.js +126 -2
  16. package/dist/cjs/src/mexc.js +43 -43
  17. package/dist/cjs/src/okx.js +9 -15
  18. package/dist/cjs/src/phemex.js +1 -0
  19. package/dist/cjs/src/pro/bitmart.js +38 -20
  20. package/dist/cjs/src/pro/bybit.js +5 -5
  21. package/js/ccxt.d.ts +1 -1
  22. package/js/ccxt.js +1 -1
  23. package/js/src/abstract/bingx.d.ts +4 -0
  24. package/js/src/abstract/coinbasepro.d.ts +1 -0
  25. package/js/src/ascendex.js +28 -24
  26. package/js/src/base/Exchange.d.ts +8 -8
  27. package/js/src/base/Exchange.js +14 -14
  28. package/js/src/binance.d.ts +1 -1
  29. package/js/src/binance.js +372 -146
  30. package/js/src/bingx.d.ts +1 -0
  31. package/js/src/bingx.js +250 -23
  32. package/js/src/bitget.js +13 -2
  33. package/js/src/bybit.js +3 -1
  34. package/js/src/coinbase.js +8 -6
  35. package/js/src/coinbasepro.js +1 -0
  36. package/js/src/coinlist.js +9 -7
  37. package/js/src/coinmetro.js +2 -1
  38. package/js/src/krakenfutures.d.ts +2 -0
  39. package/js/src/krakenfutures.js +126 -2
  40. package/js/src/mexc.js +43 -43
  41. package/js/src/okx.js +9 -15
  42. package/js/src/phemex.js +1 -0
  43. package/js/src/pro/bitmart.d.ts +2 -0
  44. package/js/src/pro/bitmart.js +38 -20
  45. package/js/src/pro/bybit.d.ts +1 -1
  46. package/js/src/pro/bybit.js +5 -5
  47. 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);
@@ -5244,7 +5244,7 @@ export default class binance extends Exchange {
5244
5244
  cost = this.safeString(order, 'cumBase', cost);
5245
5245
  let type = this.safeStringLower(order, 'type');
5246
5246
  const side = this.safeStringLower(order, 'side');
5247
- const fills = this.safeValue(order, 'fills', []);
5247
+ const fills = this.safeList(order, 'fills', []);
5248
5248
  let timeInForce = this.safeString(order, 'timeInForce');
5249
5249
  if (timeInForce === 'GTX') {
5250
5250
  // GTX means "Good Till Crossing" and is an equivalent way of saying Post Only
@@ -5277,7 +5277,7 @@ export default class binance extends Exchange {
5277
5277
  'type': type,
5278
5278
  'timeInForce': timeInForce,
5279
5279
  'postOnly': postOnly,
5280
- 'reduceOnly': this.safeValue(order, 'reduceOnly'),
5280
+ 'reduceOnly': this.safeBool(order, 'reduceOnly'),
5281
5281
  'side': side,
5282
5282
  'price': price,
5283
5283
  'triggerPrice': stopPrice,
@@ -5311,7 +5311,7 @@ export default class binance extends Exchange {
5311
5311
  const side = this.safeString(rawOrder, 'side');
5312
5312
  const amount = this.safeValue(rawOrder, 'amount');
5313
5313
  const price = this.safeValue(rawOrder, 'price');
5314
- const orderParams = this.safeValue(rawOrder, 'params', {});
5314
+ const orderParams = this.safeDict(rawOrder, 'params', {});
5315
5315
  const orderRequest = this.createOrderRequest(marketId, type, side, amount, price, orderParams);
5316
5316
  ordersRequests.push(orderRequest);
5317
5317
  }
@@ -6703,11 +6703,11 @@ export default class binance extends Exchange {
6703
6703
  // },
6704
6704
  // ]
6705
6705
  // }
6706
- const results = this.safeValue(response, 'userAssetDribblets', []);
6706
+ const results = this.safeList(response, 'userAssetDribblets', []);
6707
6707
  const rows = this.safeInteger(response, 'total', 0);
6708
6708
  const data = [];
6709
6709
  for (let i = 0; i < rows; i++) {
6710
- const logs = this.safeValue(results[i], 'userAssetDribbletDetails', []);
6710
+ const logs = this.safeList(results[i], 'userAssetDribbletDetails', []);
6711
6711
  for (let j = 0; j < logs.length; j++) {
6712
6712
  logs[j]['isDustTrade'] = true;
6713
6713
  data.push(logs[j]);
@@ -6814,7 +6814,7 @@ export default class binance extends Exchange {
6814
6814
  let currency = undefined;
6815
6815
  let response = undefined;
6816
6816
  const request = {};
6817
- const legalMoney = this.safeValue(this.options, 'legalMoney', {});
6817
+ const legalMoney = this.safeDict(this.options, 'legalMoney', {});
6818
6818
  const fiatOnly = this.safeBool(params, 'fiat', false);
6819
6819
  params = this.omit(params, 'fiatOnly');
6820
6820
  const until = this.safeInteger(params, 'until');
@@ -6926,7 +6926,7 @@ export default class binance extends Exchange {
6926
6926
  if (paginate) {
6927
6927
  return await this.fetchPaginatedCallDynamic('fetchWithdrawals', code, since, limit, params);
6928
6928
  }
6929
- const legalMoney = this.safeValue(this.options, 'legalMoney', {});
6929
+ const legalMoney = this.safeDict(this.options, 'legalMoney', {});
6930
6930
  const fiatOnly = this.safeBool(params, 'fiat', false);
6931
6931
  params = this.omit(params, 'fiatOnly');
6932
6932
  const request = {};
@@ -7070,7 +7070,7 @@ export default class binance extends Exchange {
7070
7070
  'Refund Failed': 'failed',
7071
7071
  },
7072
7072
  };
7073
- const statuses = this.safeValue(statusesByType, type, {});
7073
+ const statuses = this.safeDict(statusesByType, type, {});
7074
7074
  return this.safeString(statuses, status, status);
7075
7075
  }
7076
7076
  parseTransaction(transaction, currency = undefined) {
@@ -7235,7 +7235,7 @@ export default class binance extends Exchange {
7235
7235
  const type = this.safeString(transfer, 'type');
7236
7236
  let fromAccount = undefined;
7237
7237
  let toAccount = undefined;
7238
- const accountsById = this.safeValue(this.options, 'accountsById', {});
7238
+ const accountsById = this.safeDict(this.options, 'accountsById', {});
7239
7239
  if (type !== undefined) {
7240
7240
  const parts = type.split('_');
7241
7241
  fromAccount = this.safeValue(parts, 0);
@@ -7271,20 +7271,16 @@ export default class binance extends Exchange {
7271
7271
  // }
7272
7272
  //
7273
7273
  const marketId = this.safeString(income, 'symbol');
7274
- const symbol = this.safeSymbol(marketId, market, undefined, 'swap');
7275
- const amount = this.safeNumber(income, 'income');
7276
7274
  const currencyId = this.safeString(income, 'asset');
7277
- const code = this.safeCurrencyCode(currencyId);
7278
- const id = this.safeString(income, 'tranId');
7279
7275
  const timestamp = this.safeInteger(income, 'time');
7280
7276
  return {
7281
7277
  'info': income,
7282
- 'symbol': symbol,
7283
- 'code': code,
7278
+ 'symbol': this.safeSymbol(marketId, market, undefined, 'swap'),
7279
+ 'code': this.safeCurrencyCode(currencyId),
7284
7280
  'timestamp': timestamp,
7285
7281
  'datetime': this.iso8601(timestamp),
7286
- 'id': id,
7287
- 'amount': amount,
7282
+ 'id': this.safeString(income, 'tranId'),
7283
+ 'amount': this.safeNumber(income, 'income'),
7288
7284
  };
7289
7285
  }
7290
7286
  async transfer(code, amount, fromAccount, toAccount, params = {}) {
@@ -7333,7 +7329,7 @@ export default class binance extends Exchange {
7333
7329
  throw new ArgumentsRequired(this.id + ' transfer () requires params["symbol"] when toAccount is ' + toAccount);
7334
7330
  }
7335
7331
  }
7336
- const accountsById = this.safeValue(this.options, 'accountsById', {});
7332
+ const accountsById = this.safeDict(this.options, 'accountsById', {});
7337
7333
  const fromIsolated = !(fromId in accountsById);
7338
7334
  const toIsolated = !(toId in accountsById);
7339
7335
  if (fromIsolated && (market === undefined)) {
@@ -7423,7 +7419,7 @@ export default class binance extends Exchange {
7423
7419
  const defaultTo = (fromAccount === 'future') ? 'spot' : 'future';
7424
7420
  const toAccount = this.safeString(params, 'toAccount', defaultTo);
7425
7421
  let type = this.safeString(params, 'type');
7426
- const accountsByType = this.safeValue(this.options, 'accountsByType', {});
7422
+ const accountsByType = this.safeDict(this.options, 'accountsByType', {});
7427
7423
  const fromId = this.safeString(accountsByType, fromAccount);
7428
7424
  const toId = this.safeString(accountsByType, toAccount);
7429
7425
  if (type === undefined) {
@@ -7467,7 +7463,7 @@ export default class binance extends Exchange {
7467
7463
  // ]
7468
7464
  // }
7469
7465
  //
7470
- const rows = this.safeValue(response, 'rows', []);
7466
+ const rows = this.safeList(response, 'rows', []);
7471
7467
  return this.parseTransfers(rows, currency, since, limit);
7472
7468
  }
7473
7469
  async fetchDepositAddress(code, params = {}) {
@@ -7486,7 +7482,7 @@ export default class binance extends Exchange {
7486
7482
  'coin': currency['id'],
7487
7483
  // 'network': 'ETH', // 'BSC', 'XMR', you can get network and isDefault in networkList in the response of sapiGetCapitalConfigDetail
7488
7484
  };
7489
- const networks = this.safeValue(this.options, 'networks', {});
7485
+ const networks = this.safeDict(this.options, 'networks', {});
7490
7486
  let network = this.safeStringUpper(params, 'network'); // this line allows the user to specify either ERC20 or ETH
7491
7487
  network = this.safeString(networks, network, network); // handle ERC20>ETH alias
7492
7488
  if (network !== undefined) {
@@ -7513,7 +7509,7 @@ export default class binance extends Exchange {
7513
7509
  const url = this.safeString(response, 'url');
7514
7510
  let impliedNetwork = undefined;
7515
7511
  if (url !== undefined) {
7516
- const reverseNetworks = this.safeValue(this.options, 'reverseNetworks', {});
7512
+ const reverseNetworks = this.safeDict(this.options, 'reverseNetworks', {});
7517
7513
  const parts = url.split('/');
7518
7514
  let topLevel = this.safeString(parts, 2);
7519
7515
  if ((topLevel === 'blockchair.com') || (topLevel === 'viewblock.io')) {
@@ -7528,7 +7524,7 @@ export default class binance extends Exchange {
7528
7524
  'TRX': { 'TRC20': 'TRX' },
7529
7525
  });
7530
7526
  if (code in impliedNetworks) {
7531
- const conversion = this.safeValue(impliedNetworks, code, {});
7527
+ const conversion = this.safeDict(impliedNetworks, code, {});
7532
7528
  impliedNetwork = this.safeString(conversion, impliedNetwork, impliedNetwork);
7533
7529
  }
7534
7530
  }
@@ -7644,7 +7640,7 @@ export default class binance extends Exchange {
7644
7640
  const entry = response[i];
7645
7641
  const currencyId = this.safeString(entry, 'coin');
7646
7642
  const code = this.safeCurrencyCode(currencyId);
7647
- const networkList = this.safeValue(entry, 'networkList', []);
7643
+ const networkList = this.safeList(entry, 'networkList', []);
7648
7644
  withdrawFees[code] = {};
7649
7645
  for (let j = 0; j < networkList.length; j++) {
7650
7646
  const networkEntry = networkList[j];
@@ -7757,14 +7753,14 @@ export default class binance extends Exchange {
7757
7753
  // ]
7758
7754
  // }
7759
7755
  //
7760
- const networkList = this.safeValue(fee, 'networkList', []);
7756
+ const networkList = this.safeList(fee, 'networkList', []);
7761
7757
  const result = this.depositWithdrawFee(fee);
7762
7758
  for (let j = 0; j < networkList.length; j++) {
7763
7759
  const networkEntry = networkList[j];
7764
7760
  const networkId = this.safeString(networkEntry, 'network');
7765
7761
  const networkCode = this.networkIdToCode(networkId);
7766
7762
  const withdrawFee = this.safeNumber(networkEntry, 'withdrawFee');
7767
- const isDefault = this.safeValue(networkEntry, 'isDefault');
7763
+ const isDefault = this.safeBool(networkEntry, 'isDefault');
7768
7764
  if (isDefault === true) {
7769
7765
  result['withdraw'] = {
7770
7766
  'fee': withdrawFee,
@@ -7812,7 +7808,7 @@ export default class binance extends Exchange {
7812
7808
  if (tag !== undefined) {
7813
7809
  request['addressTag'] = tag;
7814
7810
  }
7815
- const networks = this.safeValue(this.options, 'networks', {});
7811
+ const networks = this.safeDict(this.options, 'networks', {});
7816
7812
  let network = this.safeStringUpper(params, 'network'); // this line allows the user to specify either ERC20 or ETH
7817
7813
  network = this.safeString(networks, network, network); // handle ERC20>ETH alias
7818
7814
  if (network !== undefined) {
@@ -7904,7 +7900,7 @@ export default class binance extends Exchange {
7904
7900
  //
7905
7901
  let data = response;
7906
7902
  if (Array.isArray(data)) {
7907
- data = this.safeValue(data, 0, {});
7903
+ data = this.safeDict(data, 0, {});
7908
7904
  }
7909
7905
  return this.parseTradingFee(data);
7910
7906
  }
@@ -8318,8 +8314,8 @@ export default class binance extends Exchange {
8318
8314
  };
8319
8315
  }
8320
8316
  parseAccountPositions(account) {
8321
- const positions = this.safeValue(account, 'positions');
8322
- const assets = this.safeValue(account, 'assets', []);
8317
+ const positions = this.safeList(account, 'positions');
8318
+ const assets = this.safeList(account, 'assets', []);
8323
8319
  const balances = {};
8324
8320
  for (let i = 0; i < assets.length; i++) {
8325
8321
  const entry = assets[i];
@@ -8338,13 +8334,17 @@ export default class binance extends Exchange {
8338
8334
  const marketId = this.safeString(position, 'symbol');
8339
8335
  const market = this.safeMarket(marketId, undefined, undefined, 'contract');
8340
8336
  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);
8337
+ const maintenanceMargin = this.safeString(position, 'maintMargin');
8338
+ // check for maintenance margin so empty positions are not returned
8339
+ if ((maintenanceMargin !== '0') && (maintenanceMargin !== '0.00000000')) {
8340
+ // sometimes not all the codes are correctly returned...
8341
+ if (code in balances) {
8342
+ const parsed = this.parseAccountPosition(this.extend(position, {
8343
+ 'crossMargin': balances[code]['crossMargin'],
8344
+ 'crossWalletBalance': balances[code]['crossWalletBalance'],
8345
+ }), market);
8346
+ result.push(parsed);
8347
+ }
8348
8348
  }
8349
8349
  }
8350
8350
  return result;
@@ -8352,6 +8352,7 @@ export default class binance extends Exchange {
8352
8352
  parseAccountPosition(position, market = undefined) {
8353
8353
  //
8354
8354
  // usdm
8355
+ //
8355
8356
  // {
8356
8357
  // "symbol": "BTCBUSD",
8357
8358
  // "initialMargin": "0",
@@ -8372,6 +8373,7 @@ export default class binance extends Exchange {
8372
8373
  // }
8373
8374
  //
8374
8375
  // coinm
8376
+ //
8375
8377
  // {
8376
8378
  // "symbol": "BTCUSD_210625",
8377
8379
  // "initialMargin": "0.00024393",
@@ -8390,6 +8392,46 @@ export default class binance extends Exchange {
8390
8392
  // "crossWalletBalance": "34",
8391
8393
  // }
8392
8394
  //
8395
+ // linear portfolio margin
8396
+ //
8397
+ // {
8398
+ // "symbol": "CTSIUSDT",
8399
+ // "initialMargin": "0",
8400
+ // "maintMargin": "0",
8401
+ // "unrealizedProfit": "0.00000000",
8402
+ // "positionInitialMargin": "0",
8403
+ // "openOrderInitialMargin": "0",
8404
+ // "leverage": "20",
8405
+ // "entryPrice": "0.0",
8406
+ // "maxNotional": "25000",
8407
+ // "bidNotional": "0",
8408
+ // "askNotional": "0",
8409
+ // "positionSide": "SHORT",
8410
+ // "positionAmt": "0",
8411
+ // "updateTime": 0,
8412
+ // "notional": "0",
8413
+ // "breakEvenPrice": "0.0"
8414
+ // }
8415
+ //
8416
+ // inverse portoflio margin
8417
+ //
8418
+ // {
8419
+ // "symbol": "TRXUSD_PERP",
8420
+ // "initialMargin": "0",
8421
+ // "maintMargin": "0",
8422
+ // "unrealizedProfit": "0.00000000",
8423
+ // "positionInitialMargin": "0",
8424
+ // "openOrderInitialMargin": "0",
8425
+ // "leverage": "20",
8426
+ // "entryPrice": "0.00000000",
8427
+ // "positionSide": "SHORT",
8428
+ // "positionAmt": "0",
8429
+ // "maxQty": "5000000",
8430
+ // "updateTime": 0,
8431
+ // "notionalValue": "0",
8432
+ // "breakEvenPrice": "0.00000000"
8433
+ // }
8434
+ //
8393
8435
  const marketId = this.safeString(position, 'symbol');
8394
8436
  market = this.safeMarket(marketId, market, undefined, 'contract');
8395
8437
  const symbol = this.safeString(market, 'symbol');
@@ -8420,8 +8462,8 @@ export default class binance extends Exchange {
8420
8462
  contractsStringAbs = Precise.stringDiv(Precise.stringAdd(contractsString, '0.5'), '1', 0);
8421
8463
  }
8422
8464
  const contracts = this.parseNumber(contractsStringAbs);
8423
- const leverageBrackets = this.safeValue(this.options, 'leverageBrackets', {});
8424
- const leverageBracket = this.safeValue(leverageBrackets, symbol, []);
8465
+ const leverageBrackets = this.safeDict(this.options, 'leverageBrackets', {});
8466
+ const leverageBracket = this.safeList(leverageBrackets, symbol, []);
8425
8467
  let maintenanceMarginPercentageString = undefined;
8426
8468
  for (let i = 0; i < leverageBracket.length; i++) {
8427
8469
  const bracket = leverageBracket[i];
@@ -8437,7 +8479,7 @@ export default class binance extends Exchange {
8437
8479
  if (timestamp === 0) {
8438
8480
  timestamp = undefined;
8439
8481
  }
8440
- const isolated = this.safeValue(position, 'isolated');
8482
+ const isolated = this.safeBool(position, 'isolated');
8441
8483
  let marginMode = undefined;
8442
8484
  let collateralString = undefined;
8443
8485
  let walletBalance = undefined;
@@ -8590,11 +8632,45 @@ export default class binance extends Exchange {
8590
8632
  // "isolatedWallet": "0.00268058"
8591
8633
  // }
8592
8634
  //
8635
+ // inverse portfolio margin
8636
+ //
8637
+ // {
8638
+ // "symbol": "ETHUSD_PERP",
8639
+ // "positionAmt": "1",
8640
+ // "entryPrice": "2422.400000007",
8641
+ // "markPrice": "2424.51267823",
8642
+ // "unRealizedProfit": "0.0000036",
8643
+ // "liquidationPrice": "293.57678898",
8644
+ // "leverage": "100",
8645
+ // "positionSide": "LONG",
8646
+ // "updateTime": 1707371941861,
8647
+ // "maxQty": "15",
8648
+ // "notionalValue": "0.00412454",
8649
+ // "breakEvenPrice": "2423.368960034"
8650
+ // }
8651
+ //
8652
+ // linear portfolio margin
8653
+ //
8654
+ // {
8655
+ // "symbol": "BTCUSDT",
8656
+ // "positionAmt": "0.01",
8657
+ // "entryPrice": "44525.0",
8658
+ // "markPrice": "45464.1735922",
8659
+ // "unRealizedProfit": "9.39173592",
8660
+ // "liquidationPrice": "38007.16308568",
8661
+ // "leverage": "100",
8662
+ // "positionSide": "LONG",
8663
+ // "updateTime": 1707371879042,
8664
+ // "maxNotionalValue": "500000.0",
8665
+ // "notional": "454.64173592",
8666
+ // "breakEvenPrice": "44542.81"
8667
+ // }
8668
+ //
8593
8669
  const marketId = this.safeString(position, 'symbol');
8594
8670
  market = this.safeMarket(marketId, market, undefined, 'contract');
8595
8671
  const symbol = this.safeString(market, 'symbol');
8596
- const leverageBrackets = this.safeValue(this.options, 'leverageBrackets', {});
8597
- const leverageBracket = this.safeValue(leverageBrackets, symbol, []);
8672
+ const leverageBrackets = this.safeDict(this.options, 'leverageBrackets', {});
8673
+ const leverageBracket = this.safeList(leverageBrackets, symbol, []);
8598
8674
  const notionalString = this.safeString2(position, 'notional', 'notionalValue');
8599
8675
  const notionalStringAbs = Precise.stringAbs(notionalString);
8600
8676
  let maintenanceMarginPercentageString = undefined;
@@ -8631,7 +8707,7 @@ export default class binance extends Exchange {
8631
8707
  const linear = ('notional' in position);
8632
8708
  if (marginMode === 'cross') {
8633
8709
  // calculate collateral
8634
- const precision = this.safeValue(market, 'precision', {});
8710
+ const precision = this.safeDict(market, 'precision', {});
8635
8711
  if (linear) {
8636
8712
  // walletBalance = (liquidationPrice * (±1 + mmp) ± entryPrice) * contracts
8637
8713
  let onePlusMaintenanceMarginPercentageString = undefined;
@@ -8738,12 +8814,24 @@ export default class binance extends Exchange {
8738
8814
  const query = this.omit(params, 'type');
8739
8815
  let subType = undefined;
8740
8816
  [subType, params] = this.handleSubTypeAndParams('loadLeverageBrackets', undefined, params, 'linear');
8817
+ let isPortfolioMargin = undefined;
8818
+ [isPortfolioMargin, params] = this.handleOptionAndParams2(params, 'loadLeverageBrackets', 'papi', 'portfolioMargin', false);
8741
8819
  let response = undefined;
8742
8820
  if (this.isLinear(type, subType)) {
8743
- response = await this.fapiPrivateGetLeverageBracket(query);
8821
+ if (isPortfolioMargin) {
8822
+ response = await this.papiGetUmLeverageBracket(query);
8823
+ }
8824
+ else {
8825
+ response = await this.fapiPrivateGetLeverageBracket(query);
8826
+ }
8744
8827
  }
8745
8828
  else if (this.isInverse(type, subType)) {
8746
- response = await this.dapiPrivateV2GetLeverageBracket(query);
8829
+ if (isPortfolioMargin) {
8830
+ response = await this.papiGetCmLeverageBracket(query);
8831
+ }
8832
+ else {
8833
+ response = await this.dapiPrivateV2GetLeverageBracket(query);
8834
+ }
8747
8835
  }
8748
8836
  else {
8749
8837
  throw new NotSupported(this.id + ' loadLeverageBrackets() supports linear and inverse contracts only');
@@ -8753,7 +8841,7 @@ export default class binance extends Exchange {
8753
8841
  const entry = response[i];
8754
8842
  const marketId = this.safeString(entry, 'symbol');
8755
8843
  const symbol = this.safeSymbol(marketId, undefined, undefined, 'contract');
8756
- const brackets = this.safeValue(entry, 'brackets', []);
8844
+ const brackets = this.safeList(entry, 'brackets', []);
8757
8845
  const result = [];
8758
8846
  for (let j = 0; j < brackets.length; j++) {
8759
8847
  const bracket = brackets[j];
@@ -8773,8 +8861,11 @@ export default class binance extends Exchange {
8773
8861
  * @description retrieve information on the maximum leverage, and maintenance margin for trades of varying trade sizes
8774
8862
  * @see https://binance-docs.github.io/apidocs/futures/en/#notional-and-leverage-brackets-user_data
8775
8863
  * @see https://binance-docs.github.io/apidocs/delivery/en/#notional-bracket-for-symbol-user_data
8864
+ * @see https://binance-docs.github.io/apidocs/pm/en/#um-notional-and-leverage-brackets-user_data
8865
+ * @see https://binance-docs.github.io/apidocs/pm/en/#cm-notional-and-leverage-brackets-user_data
8776
8866
  * @param {string[]|undefined} symbols list of unified market symbols
8777
8867
  * @param {object} [params] extra parameters specific to the exchange API endpoint
8868
+ * @param {boolean} [params.portfolioMargin] set to true if you would like to fetch the leverage tiers for a portfolio margin account
8778
8869
  * @returns {object} a dictionary of [leverage tiers structures]{@link https://docs.ccxt.com/#/?id=leverage-tiers-structure}, indexed by market symbols
8779
8870
  */
8780
8871
  await this.loadMarkets();
@@ -8782,12 +8873,24 @@ export default class binance extends Exchange {
8782
8873
  [type, params] = this.handleMarketTypeAndParams('fetchLeverageTiers', undefined, params);
8783
8874
  let subType = undefined;
8784
8875
  [subType, params] = this.handleSubTypeAndParams('fetchLeverageTiers', undefined, params, 'linear');
8876
+ let isPortfolioMargin = undefined;
8877
+ [isPortfolioMargin, params] = this.handleOptionAndParams2(params, 'fetchLeverageTiers', 'papi', 'portfolioMargin', false);
8785
8878
  let response = undefined;
8786
8879
  if (this.isLinear(type, subType)) {
8787
- response = await this.fapiPrivateGetLeverageBracket(params);
8880
+ if (isPortfolioMargin) {
8881
+ response = await this.papiGetUmLeverageBracket(params);
8882
+ }
8883
+ else {
8884
+ response = await this.fapiPrivateGetLeverageBracket(params);
8885
+ }
8788
8886
  }
8789
8887
  else if (this.isInverse(type, subType)) {
8790
- response = await this.dapiPrivateV2GetLeverageBracket(params);
8888
+ if (isPortfolioMargin) {
8889
+ response = await this.papiGetCmLeverageBracket(params);
8890
+ }
8891
+ else {
8892
+ response = await this.dapiPrivateV2GetLeverageBracket(params);
8893
+ }
8791
8894
  }
8792
8895
  else {
8793
8896
  throw new NotSupported(this.id + ' fetchLeverageTiers() supports linear and inverse contracts only');
@@ -8857,7 +8960,7 @@ export default class binance extends Exchange {
8857
8960
  //
8858
8961
  const marketId = this.safeString(info, 'symbol');
8859
8962
  market = this.safeMarket(marketId, market, undefined, 'contract');
8860
- const brackets = this.safeValue(info, 'brackets', []);
8963
+ const brackets = this.safeList(info, 'brackets', []);
8861
8964
  const tiers = [];
8862
8965
  for (let j = 0; j < brackets.length; j++) {
8863
8966
  const bracket = brackets[j];
@@ -9072,8 +9175,11 @@ export default class binance extends Exchange {
9072
9175
  * @description fetch account positions
9073
9176
  * @see https://binance-docs.github.io/apidocs/futures/en/#account-information-v2-user_data
9074
9177
  * @see https://binance-docs.github.io/apidocs/delivery/en/#account-information-user_data
9178
+ * @see https://binance-docs.github.io/apidocs/pm/en/#get-um-account-detail-user_data
9179
+ * @see https://binance-docs.github.io/apidocs/pm/en/#get-cm-account-detail-user_data
9075
9180
  * @param {string[]|undefined} symbols list of unified market symbols
9076
9181
  * @param {object} [params] extra parameters specific to the exchange API endpoint
9182
+ * @param {boolean} [params.portfolioMargin] set to true if you would like to fetch positions in a portfolio margin account
9077
9183
  * @returns {object} data on account positions
9078
9184
  */
9079
9185
  if (symbols !== undefined) {
@@ -9085,15 +9191,27 @@ export default class binance extends Exchange {
9085
9191
  await this.loadLeverageBrackets(false, params);
9086
9192
  const defaultType = this.safeString(this.options, 'defaultType', 'future');
9087
9193
  const type = this.safeString(params, 'type', defaultType);
9088
- let query = this.omit(params, 'type');
9194
+ params = this.omit(params, 'type');
9089
9195
  let subType = undefined;
9090
- [subType, query] = this.handleSubTypeAndParams('fetchAccountPositions', undefined, params, 'linear');
9196
+ [subType, params] = this.handleSubTypeAndParams('fetchAccountPositions', undefined, params, 'linear');
9197
+ let isPortfolioMargin = undefined;
9198
+ [isPortfolioMargin, params] = this.handleOptionAndParams2(params, 'fetchAccountPositions', 'papi', 'portfolioMargin', false);
9091
9199
  let response = undefined;
9092
9200
  if (this.isLinear(type, subType)) {
9093
- response = await this.fapiPrivateV2GetAccount(query);
9201
+ if (isPortfolioMargin) {
9202
+ response = await this.papiGetUmAccount(params);
9203
+ }
9204
+ else {
9205
+ response = await this.fapiPrivateV2GetAccount(params);
9206
+ }
9094
9207
  }
9095
9208
  else if (this.isInverse(type, subType)) {
9096
- response = await this.dapiPrivateGetAccount(query);
9209
+ if (isPortfolioMargin) {
9210
+ response = await this.papiGetCmAccount(params);
9211
+ }
9212
+ else {
9213
+ response = await this.dapiPrivateGetAccount(params);
9214
+ }
9097
9215
  }
9098
9216
  else {
9099
9217
  throw new NotSupported(this.id + ' fetchPositions() supports linear and inverse contracts only');
@@ -9110,8 +9228,11 @@ export default class binance extends Exchange {
9110
9228
  * @description fetch positions risk
9111
9229
  * @see https://binance-docs.github.io/apidocs/futures/en/#position-information-v2-user_data
9112
9230
  * @see https://binance-docs.github.io/apidocs/delivery/en/#position-information-user_data
9231
+ * @see https://binance-docs.github.io/apidocs/pm/en/#query-um-position-information-user_data
9232
+ * @see https://binance-docs.github.io/apidocs/pm/en/#query-cm-position-information-user_data
9113
9233
  * @param {string[]|undefined} symbols list of unified market symbols
9114
9234
  * @param {object} [params] extra parameters specific to the exchange API endpoint
9235
+ * @param {boolean} [params.portfolioMargin] set to true if you would like to fetch positions for a portfolio margin account
9115
9236
  * @returns {object} data on the positions risk
9116
9237
  */
9117
9238
  if (symbols !== undefined) {
@@ -9127,71 +9248,124 @@ export default class binance extends Exchange {
9127
9248
  const type = this.safeString(params, 'type', defaultType);
9128
9249
  let subType = undefined;
9129
9250
  [subType, params] = this.handleSubTypeAndParams('fetchPositionsRisk', undefined, params, 'linear');
9251
+ let isPortfolioMargin = undefined;
9252
+ [isPortfolioMargin, params] = this.handleOptionAndParams2(params, 'fetchPositionsRisk', 'papi', 'portfolioMargin', false);
9130
9253
  params = this.omit(params, 'type');
9131
9254
  let response = undefined;
9132
9255
  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
- // ]
9256
+ if (isPortfolioMargin) {
9257
+ response = await this.papiGetUmPositionRisk(this.extend(request, params));
9258
+ }
9259
+ else {
9260
+ response = await this.fapiPrivateV2GetPositionRisk(this.extend(request, params));
9261
+ }
9188
9262
  }
9189
9263
  else if (this.isInverse(type, subType)) {
9190
- response = await this.dapiPrivateGetPositionRisk(this.extend(request, params));
9264
+ if (isPortfolioMargin) {
9265
+ response = await this.papiGetCmPositionRisk(this.extend(request, params));
9266
+ }
9267
+ else {
9268
+ response = await this.dapiPrivateGetPositionRisk(this.extend(request, params));
9269
+ }
9191
9270
  }
9192
9271
  else {
9193
9272
  throw new NotSupported(this.id + ' fetchPositionsRisk() supports linear and inverse contracts only');
9194
9273
  }
9274
+ // ### Response examples ###
9275
+ //
9276
+ // For One-way position mode:
9277
+ //
9278
+ // [
9279
+ // {
9280
+ // "entryPrice": "0.00000",
9281
+ // "marginType": "isolated",
9282
+ // "isAutoAddMargin": "false",
9283
+ // "isolatedMargin": "0.00000000",
9284
+ // "leverage": "10",
9285
+ // "liquidationPrice": "0",
9286
+ // "markPrice": "6679.50671178",
9287
+ // "maxNotionalValue": "20000000",
9288
+ // "positionAmt": "0.000",
9289
+ // "symbol": "BTCUSDT",
9290
+ // "unRealizedProfit": "0.00000000",
9291
+ // "positionSide": "BOTH",
9292
+ // "updateTime": 0
9293
+ // }
9294
+ // ]
9295
+ //
9296
+ // For Hedge position mode:
9297
+ //
9298
+ // [
9299
+ // {
9300
+ // "entryPrice": "6563.66500",
9301
+ // "marginType": "isolated",
9302
+ // "isAutoAddMargin": "false",
9303
+ // "isolatedMargin": "15517.54150468",
9304
+ // "leverage": "10",
9305
+ // "liquidationPrice": "5930.78",
9306
+ // "markPrice": "6679.50671178",
9307
+ // "maxNotionalValue": "20000000",
9308
+ // "positionAmt": "20.000",
9309
+ // "symbol": "BTCUSDT",
9310
+ // "unRealizedProfit": "2316.83423560"
9311
+ // "positionSide": "LONG",
9312
+ // "updateTime": 1625474304765
9313
+ // },
9314
+ // {
9315
+ // "entryPrice": "0.00000",
9316
+ // "marginType": "isolated",
9317
+ // "isAutoAddMargin": "false",
9318
+ // "isolatedMargin": "5413.95799991",
9319
+ // "leverage": "10",
9320
+ // "liquidationPrice": "7189.95",
9321
+ // "markPrice": "6679.50671178",
9322
+ // "maxNotionalValue": "20000000",
9323
+ // "positionAmt": "-10.000",
9324
+ // "symbol": "BTCUSDT",
9325
+ // "unRealizedProfit": "-1156.46711780",
9326
+ // "positionSide": "SHORT",
9327
+ // "updateTime": 0
9328
+ // }
9329
+ // ]
9330
+ //
9331
+ // inverse portfolio margin:
9332
+ //
9333
+ // [
9334
+ // {
9335
+ // "symbol": "ETHUSD_PERP",
9336
+ // "positionAmt": "1",
9337
+ // "entryPrice": "2422.400000007",
9338
+ // "markPrice": "2424.51267823",
9339
+ // "unRealizedProfit": "0.0000036",
9340
+ // "liquidationPrice": "293.57678898",
9341
+ // "leverage": "100",
9342
+ // "positionSide": "LONG",
9343
+ // "updateTime": 1707371941861,
9344
+ // "maxQty": "15",
9345
+ // "notionalValue": "0.00412454",
9346
+ // "breakEvenPrice": "2423.368960034"
9347
+ // }
9348
+ // ]
9349
+ //
9350
+ // linear portfolio margin:
9351
+ //
9352
+ // [
9353
+ // {
9354
+ // "symbol": "BTCUSDT",
9355
+ // "positionAmt": "0.01",
9356
+ // "entryPrice": "44525.0",
9357
+ // "markPrice": "45464.1735922",
9358
+ // "unRealizedProfit": "9.39173592",
9359
+ // "liquidationPrice": "38007.16308568",
9360
+ // "leverage": "100",
9361
+ // "positionSide": "LONG",
9362
+ // "updateTime": 1707371879042,
9363
+ // "maxNotionalValue": "500000.0",
9364
+ // "notional": "454.64173592",
9365
+ // "breakEvenPrice": "44542.81"
9366
+ // }
9367
+ // ]
9368
+ //
9195
9369
  const result = [];
9196
9370
  for (let i = 0; i < response.length; i++) {
9197
9371
  const parsed = this.parsePositionRisk(response[i]);
@@ -9207,15 +9381,19 @@ export default class binance extends Exchange {
9207
9381
  * @description fetch the history of funding payments paid and received on this account
9208
9382
  * @see https://binance-docs.github.io/apidocs/futures/en/#get-income-history-user_data
9209
9383
  * @see https://binance-docs.github.io/apidocs/delivery/en/#get-income-history-user_data
9384
+ * @see https://binance-docs.github.io/apidocs/pm/en/#get-um-income-history-user_data
9385
+ * @see https://binance-docs.github.io/apidocs/pm/en/#get-cm-income-history-user_data
9210
9386
  * @param {string} symbol unified market symbol
9211
9387
  * @param {int} [since] the earliest time in ms to fetch funding history for
9212
9388
  * @param {int} [limit] the maximum number of funding history structures to retrieve
9213
9389
  * @param {object} [params] extra parameters specific to the exchange API endpoint
9390
+ * @param {int} [params.until] timestamp in ms of the latest funding history entry
9391
+ * @param {boolean} [params.portfolioMargin] set to true if you would like to fetch the funding history for a portfolio margin account
9214
9392
  * @returns {object} a [funding history structure]{@link https://docs.ccxt.com/#/?id=funding-history-structure}
9215
9393
  */
9216
9394
  await this.loadMarkets();
9217
9395
  let market = undefined;
9218
- const request = {
9396
+ let request = {
9219
9397
  'incomeType': 'FUNDING_FEE', // "TRANSFER","WELCOME_BONUS", "REALIZED_PNL","FUNDING_FEE", "COMMISSION" and "INSURANCE_CLEAR"
9220
9398
  };
9221
9399
  if (symbol !== undefined) {
@@ -9227,6 +9405,9 @@ export default class binance extends Exchange {
9227
9405
  }
9228
9406
  let subType = undefined;
9229
9407
  [subType, params] = this.handleSubTypeAndParams('fetchFundingHistory', market, params, 'linear');
9408
+ let isPortfolioMargin = undefined;
9409
+ [isPortfolioMargin, params] = this.handleOptionAndParams2(params, 'fetchFundingHistory', 'papi', 'portfolioMargin', false);
9410
+ [request, params] = this.handleUntilOption('endTime', request, params);
9230
9411
  if (since !== undefined) {
9231
9412
  request['startTime'] = since;
9232
9413
  }
@@ -9238,10 +9419,20 @@ export default class binance extends Exchange {
9238
9419
  params = this.omit(params, 'type');
9239
9420
  let response = undefined;
9240
9421
  if (this.isLinear(type, subType)) {
9241
- response = await this.fapiPrivateGetIncome(this.extend(request, params));
9422
+ if (isPortfolioMargin) {
9423
+ response = await this.papiGetUmIncome(this.extend(request, params));
9424
+ }
9425
+ else {
9426
+ response = await this.fapiPrivateGetIncome(this.extend(request, params));
9427
+ }
9242
9428
  }
9243
9429
  else if (this.isInverse(type, subType)) {
9244
- response = await this.dapiPrivateGetIncome(this.extend(request, params));
9430
+ if (isPortfolioMargin) {
9431
+ response = await this.papiGetCmIncome(this.extend(request, params));
9432
+ }
9433
+ else {
9434
+ response = await this.dapiPrivateGetIncome(this.extend(request, params));
9435
+ }
9245
9436
  }
9246
9437
  else {
9247
9438
  throw new NotSupported(this.id + ' fetchFundingHistory() supports linear and inverse contracts only');
@@ -9616,12 +9807,15 @@ export default class binance extends Exchange {
9616
9807
  * @see https://binance-docs.github.io/apidocs/voptions/en/#account-funding-flow-user_data
9617
9808
  * @see https://binance-docs.github.io/apidocs/futures/en/#get-income-history-user_data
9618
9809
  * @see https://binance-docs.github.io/apidocs/delivery/en/#get-income-history-user_data
9810
+ * @see https://binance-docs.github.io/apidocs/pm/en/#get-um-income-history-user_data
9811
+ * @see https://binance-docs.github.io/apidocs/pm/en/#get-cm-income-history-user_data
9619
9812
  * @param {string} code unified currency code
9620
9813
  * @param {int} [since] timestamp in ms of the earliest ledger entry
9621
9814
  * @param {int} [limit] max number of ledger entrys to return
9622
9815
  * @param {object} [params] extra parameters specific to the exchange API endpoint
9623
9816
  * @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)
9817
+ * @param {boolean} [params.paginate] default false, when true will automatically paginate by calling this endpoint multiple times. See in the docs all the [available parameters](https://github.com/ccxt/ccxt/wiki/Manual#pagination-params)
9818
+ * @param {boolean} [params.portfolioMargin] set to true if you would like to fetch the ledger for a portfolio margin account
9625
9819
  * @returns {object} a [ledger structure]{@link https://docs.ccxt.com/#/?id=ledger-structure}
9626
9820
  */
9627
9821
  await this.loadMarkets();
@@ -9650,6 +9844,8 @@ export default class binance extends Exchange {
9650
9844
  params = this.omit(params, 'until');
9651
9845
  request['endTime'] = until;
9652
9846
  }
9847
+ let isPortfolioMargin = undefined;
9848
+ [isPortfolioMargin, params] = this.handleOptionAndParams2(params, 'fetchLedger', 'papi', 'portfolioMargin', false);
9653
9849
  let response = undefined;
9654
9850
  if (type === 'option') {
9655
9851
  this.checkRequiredArgument('fetchLedger', code, 'code');
@@ -9657,10 +9853,20 @@ export default class binance extends Exchange {
9657
9853
  response = await this.eapiPrivateGetBill(this.extend(request, params));
9658
9854
  }
9659
9855
  else if (this.isLinear(type, subType)) {
9660
- response = await this.fapiPrivateGetIncome(this.extend(request, params));
9856
+ if (isPortfolioMargin) {
9857
+ response = await this.papiGetUmIncome(this.extend(request, params));
9858
+ }
9859
+ else {
9860
+ response = await this.fapiPrivateGetIncome(this.extend(request, params));
9861
+ }
9661
9862
  }
9662
9863
  else if (this.isInverse(type, subType)) {
9663
- response = await this.dapiPrivateGetIncome(this.extend(request, params));
9864
+ if (isPortfolioMargin) {
9865
+ response = await this.papiGetCmIncome(this.extend(request, params));
9866
+ }
9867
+ else {
9868
+ response = await this.dapiPrivateGetIncome(this.extend(request, params));
9869
+ }
9664
9870
  }
9665
9871
  else {
9666
9872
  throw new NotSupported(this.id + ' fetchLedger() supports contract wallets only');
@@ -9678,7 +9884,7 @@ export default class binance extends Exchange {
9678
9884
  // }
9679
9885
  // ]
9680
9886
  //
9681
- // futures (fapi, dapi)
9887
+ // futures (fapi, dapi, papi)
9682
9888
  //
9683
9889
  // [
9684
9890
  // {
@@ -9707,7 +9913,7 @@ export default class binance extends Exchange {
9707
9913
  // "createDate": 1676621042489
9708
9914
  // }
9709
9915
  //
9710
- // futures (fapi, dapi)
9916
+ // futures (fapi, dapi, papi)
9711
9917
  //
9712
9918
  // {
9713
9919
  // "symbol": "",
@@ -9816,7 +10022,7 @@ export default class binance extends Exchange {
9816
10022
  const isSpotOrMargin = (api.indexOf('sapi') > -1 || api === 'private');
9817
10023
  const marketType = isSpotOrMargin ? 'spot' : 'future';
9818
10024
  const defaultId = (!isSpotOrMargin) ? 'x-xcKtGhcu' : 'x-R4BD3S82';
9819
- const broker = this.safeValue(this.options, 'broker', {});
10025
+ const broker = this.safeDict(this.options, 'broker', {});
9820
10026
  const brokerId = this.safeString(broker, marketType, defaultId);
9821
10027
  params['newClientOrderId'] = brokerId + this.uuid22();
9822
10028
  }
@@ -9844,8 +10050,8 @@ export default class binance extends Exchange {
9844
10050
  }
9845
10051
  else if ((path === 'batchOrders') || (path.indexOf('sub-account') >= 0) || (path === 'capital/withdraw/apply') || (path.indexOf('staking') >= 0)) {
9846
10052
  if ((method === 'DELETE') && (path === 'batchOrders')) {
9847
- const orderidlist = this.safeValue(extendedParams, 'orderidlist', []);
9848
- const origclientorderidlist = this.safeValue(extendedParams, 'origclientorderidlist', []);
10053
+ const orderidlist = this.safeList(extendedParams, 'orderidlist', []);
10054
+ const origclientorderidlist = this.safeList(extendedParams, 'origclientorderidlist', []);
9849
10055
  extendedParams = this.omit(extendedParams, ['orderidlist', 'origclientorderidlist']);
9850
10056
  query = this.rawencode(extendedParams);
9851
10057
  const orderidlistLength = orderidlist.length;
@@ -9914,8 +10120,8 @@ export default class binance extends Exchange {
9914
10120
  marketType = 'portfoliomargin';
9915
10121
  }
9916
10122
  if (marketType !== undefined) {
9917
- const exceptionsForMarketType = this.safeValue(this.exceptions, marketType, {});
9918
- return this.safeValue(exceptionsForMarketType, exactOrBroad, {});
10123
+ const exceptionsForMarketType = this.safeDict(this.exceptions, marketType, {});
10124
+ return this.safeDict(exceptionsForMarketType, exactOrBroad, {});
9919
10125
  }
9920
10126
  return {};
9921
10127
  }
@@ -10149,7 +10355,7 @@ export default class binance extends Exchange {
10149
10355
  // },
10150
10356
  // ]
10151
10357
  //
10152
- const rate = this.safeValue(response, 0);
10358
+ const rate = this.safeDict(response, 0);
10153
10359
  return this.parseBorrowRate(rate);
10154
10360
  }
10155
10361
  async fetchBorrowRateHistory(code, since = undefined, limit = undefined, params = {}) {
@@ -10253,7 +10459,7 @@ export default class binance extends Exchange {
10253
10459
  // "success": true
10254
10460
  // }
10255
10461
  //
10256
- const data = this.safeValue(response, 'data');
10462
+ const data = this.safeDict(response, 'data');
10257
10463
  const giftcardCode = this.safeString(data, 'code');
10258
10464
  const id = this.safeString(data, 'referenceNo');
10259
10465
  return {
@@ -10362,7 +10568,7 @@ export default class binance extends Exchange {
10362
10568
  // "total": 1
10363
10569
  // }
10364
10570
  //
10365
- const rows = this.safeValue(response, 'rows');
10571
+ const rows = this.safeList(response, 'rows');
10366
10572
  const interest = this.parseBorrowInterests(rows, market);
10367
10573
  return this.filterByCurrencySinceLimit(interest, code, since, limit);
10368
10574
  }
@@ -10389,9 +10595,11 @@ export default class binance extends Exchange {
10389
10595
  * @name binance#repayCrossMargin
10390
10596
  * @description repay borrowed margin and interest
10391
10597
  * @see https://binance-docs.github.io/apidocs/spot/en/#margin-account-borrow-repay-margin
10598
+ * @see https://binance-docs.github.io/apidocs/pm/en/#margin-account-repay-margin
10392
10599
  * @param {string} code unified currency code of the currency to repay
10393
10600
  * @param {float} amount the amount to repay
10394
10601
  * @param {object} [params] extra parameters specific to the exchange API endpoint
10602
+ * @param {boolean} [params.portfolioMargin] set to true if you would like to repay margin in a portfolio margin account
10395
10603
  * @returns {object} a [margin loan structure]{@link https://docs.ccxt.com/#/?id=margin-loan-structure}
10396
10604
  */
10397
10605
  await this.loadMarkets();
@@ -10399,10 +10607,18 @@ export default class binance extends Exchange {
10399
10607
  const request = {
10400
10608
  'asset': currency['id'],
10401
10609
  'amount': this.currencyToPrecision(code, amount),
10402
- 'isIsolated': 'FALSE',
10403
- 'type': 'REPAY',
10404
10610
  };
10405
- const response = await this.sapiPostMarginBorrowRepay(this.extend(request, params));
10611
+ let response = undefined;
10612
+ let isPortfolioMargin = undefined;
10613
+ [isPortfolioMargin, params] = this.handleOptionAndParams2(params, 'repayCrossMargin', 'papi', 'portfolioMargin', false);
10614
+ if (isPortfolioMargin) {
10615
+ response = await this.papiPostRepayLoan(this.extend(request, params));
10616
+ }
10617
+ else {
10618
+ request['isIsolated'] = 'FALSE';
10619
+ request['type'] = 'REPAY';
10620
+ response = await this.sapiPostMarginBorrowRepay(this.extend(request, params));
10621
+ }
10406
10622
  //
10407
10623
  // {
10408
10624
  // "tranId": 108988250265,
@@ -10448,9 +10664,11 @@ export default class binance extends Exchange {
10448
10664
  * @name binance#borrowCrossMargin
10449
10665
  * @description create a loan to borrow margin
10450
10666
  * @see https://binance-docs.github.io/apidocs/spot/en/#margin-account-borrow-repay-margin
10667
+ * @see https://binance-docs.github.io/apidocs/pm/en/#margin-account-borrow-margin
10451
10668
  * @param {string} code unified currency code of the currency to borrow
10452
10669
  * @param {float} amount the amount to borrow
10453
10670
  * @param {object} [params] extra parameters specific to the exchange API endpoint
10671
+ * @param {boolean} [params.portfolioMargin] set to true if you would like to borrow margin in a portfolio margin account
10454
10672
  * @returns {object} a [margin loan structure]{@link https://docs.ccxt.com/#/?id=margin-loan-structure}
10455
10673
  */
10456
10674
  await this.loadMarkets();
@@ -10458,10 +10676,18 @@ export default class binance extends Exchange {
10458
10676
  const request = {
10459
10677
  'asset': currency['id'],
10460
10678
  'amount': this.currencyToPrecision(code, amount),
10461
- 'isIsolated': 'FALSE',
10462
- 'type': 'BORROW',
10463
10679
  };
10464
- const response = await this.sapiPostMarginBorrowRepay(this.extend(request, params));
10680
+ let response = undefined;
10681
+ let isPortfolioMargin = undefined;
10682
+ [isPortfolioMargin, params] = this.handleOptionAndParams2(params, 'borrowCrossMargin', 'papi', 'portfolioMargin', false);
10683
+ if (isPortfolioMargin) {
10684
+ response = await this.papiPostMarginLoan(this.extend(request, params));
10685
+ }
10686
+ else {
10687
+ request['isIsolated'] = 'FALSE';
10688
+ request['type'] = 'BORROW';
10689
+ response = await this.sapiPostMarginBorrowRepay(this.extend(request, params));
10690
+ }
10465
10691
  //
10466
10692
  // {
10467
10693
  // "tranId": 108988250265,