ccxt 4.2.39__py2.py3-none-any.whl → 4.2.40__py2.py3-none-any.whl
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.
Potentially problematic release.
This version of ccxt might be problematic. Click here for more details.
- ccxt/__init__.py +1 -1
- ccxt/abstract/bingx.py +4 -0
- ccxt/abstract/coinbasepro.py +1 -0
- ccxt/ascendex.py +29 -25
- ccxt/async_support/__init__.py +1 -1
- ccxt/async_support/ascendex.py +29 -25
- ccxt/async_support/base/exchange.py +7 -7
- ccxt/async_support/binance.py +342 -145
- ccxt/async_support/bingx.py +245 -23
- ccxt/async_support/bitget.py +10 -1
- ccxt/async_support/bybit.py +2 -0
- ccxt/async_support/coinbase.py +8 -6
- ccxt/async_support/coinbasepro.py +1 -0
- ccxt/async_support/coinlist.py +9 -7
- ccxt/async_support/coinmetro.py +2 -1
- ccxt/async_support/krakenfutures.py +108 -2
- ccxt/async_support/mexc.py +1 -1
- ccxt/async_support/okx.py +9 -12
- ccxt/async_support/phemex.py +1 -0
- ccxt/base/exchange.py +23 -23
- ccxt/binance.py +342 -145
- ccxt/bingx.py +245 -23
- ccxt/bitget.py +10 -1
- ccxt/bybit.py +2 -0
- ccxt/coinbase.py +8 -6
- ccxt/coinbasepro.py +1 -0
- ccxt/coinlist.py +9 -7
- ccxt/coinmetro.py +2 -1
- ccxt/krakenfutures.py +108 -2
- ccxt/mexc.py +1 -1
- ccxt/okx.py +9 -12
- ccxt/phemex.py +1 -0
- ccxt/pro/__init__.py +1 -1
- ccxt/pro/bitmart.py +34 -17
- ccxt/pro/bybit.py +6 -6
- ccxt/test/test_async.py +2 -1
- ccxt/test/test_sync.py +2 -1
- {ccxt-4.2.39.dist-info → ccxt-4.2.40.dist-info}/METADATA +4 -4
- {ccxt-4.2.39.dist-info → ccxt-4.2.40.dist-info}/RECORD +41 -41
- {ccxt-4.2.39.dist-info → ccxt-4.2.40.dist-info}/WHEEL +0 -0
- {ccxt-4.2.39.dist-info → ccxt-4.2.40.dist-info}/top_level.txt +0 -0
ccxt/async_support/binance.py
CHANGED
@@ -2638,7 +2638,7 @@ class binance(Exchange, ImplicitAPI):
|
|
2638
2638
|
minPrecision = None
|
2639
2639
|
isWithdrawEnabled = True
|
2640
2640
|
isDepositEnabled = True
|
2641
|
-
networkList = self.
|
2641
|
+
networkList = self.safe_list(entry, 'networkList', [])
|
2642
2642
|
fees = {}
|
2643
2643
|
fee = None
|
2644
2644
|
for j in range(0, len(networkList)):
|
@@ -2646,12 +2646,12 @@ class binance(Exchange, ImplicitAPI):
|
|
2646
2646
|
network = self.safe_string(networkItem, 'network')
|
2647
2647
|
# name = self.safe_string(networkItem, 'name')
|
2648
2648
|
withdrawFee = self.safe_number(networkItem, 'withdrawFee')
|
2649
|
-
depositEnable = self.
|
2650
|
-
withdrawEnable = self.
|
2649
|
+
depositEnable = self.safe_bool(networkItem, 'depositEnable')
|
2650
|
+
withdrawEnable = self.safe_bool(networkItem, 'withdrawEnable')
|
2651
2651
|
isDepositEnabled = isDepositEnabled or depositEnable
|
2652
2652
|
isWithdrawEnabled = isWithdrawEnabled or withdrawEnable
|
2653
2653
|
fees[network] = withdrawFee
|
2654
|
-
isDefault = self.
|
2654
|
+
isDefault = self.safe_bool(networkItem, 'isDefault')
|
2655
2655
|
if isDefault or (fee is None):
|
2656
2656
|
fee = withdrawFee
|
2657
2657
|
precisionTick = self.safe_string(networkItem, 'withdrawIntegerMultiple')
|
@@ -2659,7 +2659,7 @@ class binance(Exchange, ImplicitAPI):
|
|
2659
2659
|
# so, when there is zero instead of i.e. 0.001, then we skip those cases, because we don't know the precision - it might be because of network is suspended or other reasons
|
2660
2660
|
if not Precise.string_eq(precisionTick, '0'):
|
2661
2661
|
minPrecision = precisionTick if (minPrecision is None) else Precise.string_min(minPrecision, precisionTick)
|
2662
|
-
trading = self.
|
2662
|
+
trading = self.safe_bool(entry, 'trading')
|
2663
2663
|
active = (isWithdrawEnabled and isDepositEnabled and trading)
|
2664
2664
|
maxDecimalPlaces = None
|
2665
2665
|
if minPrecision is not None:
|
@@ -2691,8 +2691,8 @@ class binance(Exchange, ImplicitAPI):
|
|
2691
2691
|
:returns dict[]: an array of objects representing market data
|
2692
2692
|
"""
|
2693
2693
|
promisesRaw = []
|
2694
|
-
rawFetchMarkets = self.
|
2695
|
-
sandboxMode = self.
|
2694
|
+
rawFetchMarkets = self.safe_list(self.options, 'fetchMarkets', ['spot', 'linear', 'inverse'])
|
2695
|
+
sandboxMode = self.safe_bool(self.options, 'sandboxMode', False)
|
2696
2696
|
fetchMarkets = []
|
2697
2697
|
for i in range(0, len(rawFetchMarkets)):
|
2698
2698
|
type = rawFetchMarkets[i]
|
@@ -2957,7 +2957,7 @@ class binance(Exchange, ImplicitAPI):
|
|
2957
2957
|
future = True
|
2958
2958
|
settle = self.safe_currency_code(settleId)
|
2959
2959
|
spot = not contract
|
2960
|
-
filters = self.
|
2960
|
+
filters = self.safe_list(market, 'filters', [])
|
2961
2961
|
filtersByType = self.index_by(filters, 'filterType')
|
2962
2962
|
status = self.safe_string_2(market, 'status', 'contractStatus')
|
2963
2963
|
contractSize = None
|
@@ -2977,10 +2977,10 @@ class binance(Exchange, ImplicitAPI):
|
|
2977
2977
|
linear = settle == quote
|
2978
2978
|
inverse = settle == base
|
2979
2979
|
feesType = 'linear' if linear else 'inverse'
|
2980
|
-
fees = self.
|
2980
|
+
fees = self.safe_dict(self.fees, feesType, {})
|
2981
2981
|
active = (status == 'TRADING')
|
2982
2982
|
if spot:
|
2983
|
-
permissions = self.
|
2983
|
+
permissions = self.safe_list(market, 'permissions', [])
|
2984
2984
|
for j in range(0, len(permissions)):
|
2985
2985
|
if permissions[j] == 'TRD_GRP_003':
|
2986
2986
|
active = False
|
@@ -3051,7 +3051,7 @@ class binance(Exchange, ImplicitAPI):
|
|
3051
3051
|
'created': self.safe_integer(market, 'onboardDate'), # present in inverse & linear apis
|
3052
3052
|
}
|
3053
3053
|
if 'PRICE_FILTER' in filtersByType:
|
3054
|
-
filter = self.
|
3054
|
+
filter = self.safe_dict(filtersByType, 'PRICE_FILTER', {})
|
3055
3055
|
# PRICE_FILTER reports zero values for maxPrice
|
3056
3056
|
# since they updated filter types in November 2018
|
3057
3057
|
# https://github.com/ccxt/ccxt/issues/4286
|
@@ -3062,7 +3062,7 @@ class binance(Exchange, ImplicitAPI):
|
|
3062
3062
|
}
|
3063
3063
|
entry['precision']['price'] = self.precision_from_string(filter['tickSize'])
|
3064
3064
|
if 'LOT_SIZE' in filtersByType:
|
3065
|
-
filter = self.
|
3065
|
+
filter = self.safe_dict(filtersByType, 'LOT_SIZE', {})
|
3066
3066
|
stepSize = self.safe_string(filter, 'stepSize')
|
3067
3067
|
entry['precision']['amount'] = self.precision_from_string(stepSize)
|
3068
3068
|
entry['limits']['amount'] = {
|
@@ -3070,13 +3070,13 @@ class binance(Exchange, ImplicitAPI):
|
|
3070
3070
|
'max': self.safe_number(filter, 'maxQty'),
|
3071
3071
|
}
|
3072
3072
|
if 'MARKET_LOT_SIZE' in filtersByType:
|
3073
|
-
filter = self.
|
3073
|
+
filter = self.safe_dict(filtersByType, 'MARKET_LOT_SIZE', {})
|
3074
3074
|
entry['limits']['market'] = {
|
3075
3075
|
'min': self.safe_number(filter, 'minQty'),
|
3076
3076
|
'max': self.safe_number(filter, 'maxQty'),
|
3077
3077
|
}
|
3078
3078
|
if ('MIN_NOTIONAL' in filtersByType) or ('NOTIONAL' in filtersByType): # notional added in 12/04/23 to spot testnet
|
3079
|
-
filter = self.
|
3079
|
+
filter = self.safe_dict_2(filtersByType, 'MIN_NOTIONAL', 'NOTIONAL', {})
|
3080
3080
|
entry['limits']['cost']['min'] = self.safe_number_2(filter, 'minNotional', 'notional')
|
3081
3081
|
entry['limits']['cost']['max'] = self.safe_number(filter, 'maxNotional')
|
3082
3082
|
return entry
|
@@ -3720,7 +3720,7 @@ class binance(Exchange, ImplicitAPI):
|
|
3720
3720
|
else:
|
3721
3721
|
response = await self.publicGetTicker24hr(self.extend(request, params))
|
3722
3722
|
if isinstance(response, list):
|
3723
|
-
firstTicker = self.
|
3723
|
+
firstTicker = self.safe_dict(response, 0, {})
|
3724
3724
|
return self.parse_ticker(firstTicker, market)
|
3725
3725
|
return self.parse_ticker(response, market)
|
3726
3726
|
|
@@ -5029,7 +5029,7 @@ class binance(Exchange, ImplicitAPI):
|
|
5029
5029
|
cost = self.safe_string(order, 'cumBase', cost)
|
5030
5030
|
type = self.safe_string_lower(order, 'type')
|
5031
5031
|
side = self.safe_string_lower(order, 'side')
|
5032
|
-
fills = self.
|
5032
|
+
fills = self.safe_list(order, 'fills', [])
|
5033
5033
|
timeInForce = self.safe_string(order, 'timeInForce')
|
5034
5034
|
if timeInForce == 'GTX':
|
5035
5035
|
# GTX means "Good Till Crossing" and is an equivalent way of saying Post Only
|
@@ -5059,7 +5059,7 @@ class binance(Exchange, ImplicitAPI):
|
|
5059
5059
|
'type': type,
|
5060
5060
|
'timeInForce': timeInForce,
|
5061
5061
|
'postOnly': postOnly,
|
5062
|
-
'reduceOnly': self.
|
5062
|
+
'reduceOnly': self.safe_bool(order, 'reduceOnly'),
|
5063
5063
|
'side': side,
|
5064
5064
|
'price': price,
|
5065
5065
|
'triggerPrice': stopPrice,
|
@@ -5091,7 +5091,7 @@ class binance(Exchange, ImplicitAPI):
|
|
5091
5091
|
side = self.safe_string(rawOrder, 'side')
|
5092
5092
|
amount = self.safe_value(rawOrder, 'amount')
|
5093
5093
|
price = self.safe_value(rawOrder, 'price')
|
5094
|
-
orderParams = self.
|
5094
|
+
orderParams = self.safe_dict(rawOrder, 'params', {})
|
5095
5095
|
orderRequest = self.create_order_request(marketId, type, side, amount, price, orderParams)
|
5096
5096
|
ordersRequests.append(orderRequest)
|
5097
5097
|
orderSymbols = self.market_symbols(orderSymbols, None, False, True, True)
|
@@ -6242,11 +6242,11 @@ class binance(Exchange, ImplicitAPI):
|
|
6242
6242
|
# },
|
6243
6243
|
# ]
|
6244
6244
|
# }
|
6245
|
-
results = self.
|
6245
|
+
results = self.safe_list(response, 'userAssetDribblets', [])
|
6246
6246
|
rows = self.safe_integer(response, 'total', 0)
|
6247
6247
|
data = []
|
6248
6248
|
for i in range(0, rows):
|
6249
|
-
logs = self.
|
6249
|
+
logs = self.safe_list(results[i], 'userAssetDribbletDetails', [])
|
6250
6250
|
for j in range(0, len(logs)):
|
6251
6251
|
logs[j]['isDustTrade'] = True
|
6252
6252
|
data.append(logs[j])
|
@@ -6343,7 +6343,7 @@ class binance(Exchange, ImplicitAPI):
|
|
6343
6343
|
currency = None
|
6344
6344
|
response = None
|
6345
6345
|
request = {}
|
6346
|
-
legalMoney = self.
|
6346
|
+
legalMoney = self.safe_dict(self.options, 'legalMoney', {})
|
6347
6347
|
fiatOnly = self.safe_bool(params, 'fiat', False)
|
6348
6348
|
params = self.omit(params, 'fiatOnly')
|
6349
6349
|
until = self.safe_integer(params, 'until')
|
@@ -6442,7 +6442,7 @@ class binance(Exchange, ImplicitAPI):
|
|
6442
6442
|
paginate, params = self.handle_option_and_params(params, 'fetchWithdrawals', 'paginate')
|
6443
6443
|
if paginate:
|
6444
6444
|
return await self.fetch_paginated_call_dynamic('fetchWithdrawals', code, since, limit, params)
|
6445
|
-
legalMoney = self.
|
6445
|
+
legalMoney = self.safe_dict(self.options, 'legalMoney', {})
|
6446
6446
|
fiatOnly = self.safe_bool(params, 'fiat', False)
|
6447
6447
|
params = self.omit(params, 'fiatOnly')
|
6448
6448
|
request = {}
|
@@ -6577,7 +6577,7 @@ class binance(Exchange, ImplicitAPI):
|
|
6577
6577
|
'Refund Failed': 'failed',
|
6578
6578
|
},
|
6579
6579
|
}
|
6580
|
-
statuses = self.
|
6580
|
+
statuses = self.safe_dict(statusesByType, type, {})
|
6581
6581
|
return self.safe_string(statuses, status, status)
|
6582
6582
|
|
6583
6583
|
def parse_transaction(self, transaction, currency: Currency = None) -> Transaction:
|
@@ -6734,7 +6734,7 @@ class binance(Exchange, ImplicitAPI):
|
|
6734
6734
|
type = self.safe_string(transfer, 'type')
|
6735
6735
|
fromAccount = None
|
6736
6736
|
toAccount = None
|
6737
|
-
accountsById = self.
|
6737
|
+
accountsById = self.safe_dict(self.options, 'accountsById', {})
|
6738
6738
|
if type is not None:
|
6739
6739
|
parts = type.split('_')
|
6740
6740
|
fromAccount = self.safe_value(parts, 0)
|
@@ -6769,20 +6769,16 @@ class binance(Exchange, ImplicitAPI):
|
|
6769
6769
|
# }
|
6770
6770
|
#
|
6771
6771
|
marketId = self.safe_string(income, 'symbol')
|
6772
|
-
symbol = self.safe_symbol(marketId, market, None, 'swap')
|
6773
|
-
amount = self.safe_number(income, 'income')
|
6774
6772
|
currencyId = self.safe_string(income, 'asset')
|
6775
|
-
code = self.safe_currency_code(currencyId)
|
6776
|
-
id = self.safe_string(income, 'tranId')
|
6777
6773
|
timestamp = self.safe_integer(income, 'time')
|
6778
6774
|
return {
|
6779
6775
|
'info': income,
|
6780
|
-
'symbol':
|
6781
|
-
'code':
|
6776
|
+
'symbol': self.safe_symbol(marketId, market, None, 'swap'),
|
6777
|
+
'code': self.safe_currency_code(currencyId),
|
6782
6778
|
'timestamp': timestamp,
|
6783
6779
|
'datetime': self.iso8601(timestamp),
|
6784
|
-
'id':
|
6785
|
-
'amount':
|
6780
|
+
'id': self.safe_string(income, 'tranId'),
|
6781
|
+
'amount': self.safe_number(income, 'income'),
|
6786
6782
|
}
|
6787
6783
|
|
6788
6784
|
async def transfer(self, code: str, amount: float, fromAccount: str, toAccount: str, params={}) -> TransferEntry:
|
@@ -6823,7 +6819,7 @@ class binance(Exchange, ImplicitAPI):
|
|
6823
6819
|
if toId == 'ISOLATED':
|
6824
6820
|
if symbol is None:
|
6825
6821
|
raise ArgumentsRequired(self.id + ' transfer() requires params["symbol"] when toAccount is ' + toAccount)
|
6826
|
-
accountsById = self.
|
6822
|
+
accountsById = self.safe_dict(self.options, 'accountsById', {})
|
6827
6823
|
fromIsolated = not (fromId in accountsById)
|
6828
6824
|
toIsolated = not (toId in accountsById)
|
6829
6825
|
if fromIsolated and (market is None):
|
@@ -6896,7 +6892,7 @@ class binance(Exchange, ImplicitAPI):
|
|
6896
6892
|
defaultTo = 'spot' if (fromAccount == 'future') else 'future'
|
6897
6893
|
toAccount = self.safe_string(params, 'toAccount', defaultTo)
|
6898
6894
|
type = self.safe_string(params, 'type')
|
6899
|
-
accountsByType = self.
|
6895
|
+
accountsByType = self.safe_dict(self.options, 'accountsByType', {})
|
6900
6896
|
fromId = self.safe_string(accountsByType, fromAccount)
|
6901
6897
|
toId = self.safe_string(accountsByType, toAccount)
|
6902
6898
|
if type is None:
|
@@ -6934,7 +6930,7 @@ class binance(Exchange, ImplicitAPI):
|
|
6934
6930
|
# ]
|
6935
6931
|
# }
|
6936
6932
|
#
|
6937
|
-
rows = self.
|
6933
|
+
rows = self.safe_list(response, 'rows', [])
|
6938
6934
|
return self.parse_transfers(rows, currency, since, limit)
|
6939
6935
|
|
6940
6936
|
async def fetch_deposit_address(self, code: str, params={}):
|
@@ -6951,7 +6947,7 @@ class binance(Exchange, ImplicitAPI):
|
|
6951
6947
|
'coin': currency['id'],
|
6952
6948
|
# 'network': 'ETH', # 'BSC', 'XMR', you can get network and isDefault in networkList in the response of sapiGetCapitalConfigDetail
|
6953
6949
|
}
|
6954
|
-
networks = self.
|
6950
|
+
networks = self.safe_dict(self.options, 'networks', {})
|
6955
6951
|
network = self.safe_string_upper(params, 'network') # self line allows the user to specify either ERC20 or ETH
|
6956
6952
|
network = self.safe_string(networks, network, network) # handle ERC20>ETH alias
|
6957
6953
|
if network is not None:
|
@@ -6977,7 +6973,7 @@ class binance(Exchange, ImplicitAPI):
|
|
6977
6973
|
url = self.safe_string(response, 'url')
|
6978
6974
|
impliedNetwork = None
|
6979
6975
|
if url is not None:
|
6980
|
-
reverseNetworks = self.
|
6976
|
+
reverseNetworks = self.safe_dict(self.options, 'reverseNetworks', {})
|
6981
6977
|
parts = url.split('/')
|
6982
6978
|
topLevel = self.safe_string(parts, 2)
|
6983
6979
|
if (topLevel == 'blockchair.com') or (topLevel == 'viewblock.io'):
|
@@ -6990,7 +6986,7 @@ class binance(Exchange, ImplicitAPI):
|
|
6990
6986
|
'TRX': {'TRC20': 'TRX'},
|
6991
6987
|
})
|
6992
6988
|
if code in impliedNetworks:
|
6993
|
-
conversion = self.
|
6989
|
+
conversion = self.safe_dict(impliedNetworks, code, {})
|
6994
6990
|
impliedNetwork = self.safe_string(conversion, impliedNetwork, impliedNetwork)
|
6995
6991
|
tag = self.safe_string(response, 'tag', '')
|
6996
6992
|
if len(tag) == 0:
|
@@ -7101,7 +7097,7 @@ class binance(Exchange, ImplicitAPI):
|
|
7101
7097
|
entry = response[i]
|
7102
7098
|
currencyId = self.safe_string(entry, 'coin')
|
7103
7099
|
code = self.safe_currency_code(currencyId)
|
7104
|
-
networkList = self.
|
7100
|
+
networkList = self.safe_list(entry, 'networkList', [])
|
7105
7101
|
withdrawFees[code] = {}
|
7106
7102
|
for j in range(0, len(networkList)):
|
7107
7103
|
networkEntry = networkList[j]
|
@@ -7210,14 +7206,14 @@ class binance(Exchange, ImplicitAPI):
|
|
7210
7206
|
# ]
|
7211
7207
|
# }
|
7212
7208
|
#
|
7213
|
-
networkList = self.
|
7209
|
+
networkList = self.safe_list(fee, 'networkList', [])
|
7214
7210
|
result = self.deposit_withdraw_fee(fee)
|
7215
7211
|
for j in range(0, len(networkList)):
|
7216
7212
|
networkEntry = networkList[j]
|
7217
7213
|
networkId = self.safe_string(networkEntry, 'network')
|
7218
7214
|
networkCode = self.network_id_to_code(networkId)
|
7219
7215
|
withdrawFee = self.safe_number(networkEntry, 'withdrawFee')
|
7220
|
-
isDefault = self.
|
7216
|
+
isDefault = self.safe_bool(networkEntry, 'isDefault')
|
7221
7217
|
if isDefault is True:
|
7222
7218
|
result['withdraw'] = {
|
7223
7219
|
'fee': withdrawFee,
|
@@ -7260,7 +7256,7 @@ class binance(Exchange, ImplicitAPI):
|
|
7260
7256
|
}
|
7261
7257
|
if tag is not None:
|
7262
7258
|
request['addressTag'] = tag
|
7263
|
-
networks = self.
|
7259
|
+
networks = self.safe_dict(self.options, 'networks', {})
|
7264
7260
|
network = self.safe_string_upper(params, 'network') # self line allows the user to specify either ERC20 or ETH
|
7265
7261
|
network = self.safe_string(networks, network, network) # handle ERC20>ETH alias
|
7266
7262
|
if network is not None:
|
@@ -7346,7 +7342,7 @@ class binance(Exchange, ImplicitAPI):
|
|
7346
7342
|
#
|
7347
7343
|
data = response
|
7348
7344
|
if isinstance(data, list):
|
7349
|
-
data = self.
|
7345
|
+
data = self.safe_dict(data, 0, {})
|
7350
7346
|
return self.parse_trading_fee(data)
|
7351
7347
|
|
7352
7348
|
async def fetch_trading_fees(self, params={}):
|
@@ -7720,8 +7716,8 @@ class binance(Exchange, ImplicitAPI):
|
|
7720
7716
|
}
|
7721
7717
|
|
7722
7718
|
def parse_account_positions(self, account):
|
7723
|
-
positions = self.
|
7724
|
-
assets = self.
|
7719
|
+
positions = self.safe_list(account, 'positions')
|
7720
|
+
assets = self.safe_list(account, 'assets', [])
|
7725
7721
|
balances = {}
|
7726
7722
|
for i in range(0, len(assets)):
|
7727
7723
|
entry = assets[i]
|
@@ -7739,18 +7735,22 @@ class binance(Exchange, ImplicitAPI):
|
|
7739
7735
|
marketId = self.safe_string(position, 'symbol')
|
7740
7736
|
market = self.safe_market(marketId, None, None, 'contract')
|
7741
7737
|
code = market['quote'] if market['linear'] else market['base']
|
7742
|
-
|
7743
|
-
|
7744
|
-
|
7745
|
-
|
7746
|
-
|
7747
|
-
|
7748
|
-
|
7738
|
+
maintenanceMargin = self.safe_string(position, 'maintMargin')
|
7739
|
+
# check for maintenance margin so empty positions are not returned
|
7740
|
+
if (maintenanceMargin != '0') and (maintenanceMargin != '0.00000000'):
|
7741
|
+
# sometimes not all the codes are correctly returned...
|
7742
|
+
if code in balances:
|
7743
|
+
parsed = self.parse_account_position(self.extend(position, {
|
7744
|
+
'crossMargin': balances[code]['crossMargin'],
|
7745
|
+
'crossWalletBalance': balances[code]['crossWalletBalance'],
|
7746
|
+
}), market)
|
7747
|
+
result.append(parsed)
|
7749
7748
|
return result
|
7750
7749
|
|
7751
7750
|
def parse_account_position(self, position, market: Market = None):
|
7752
7751
|
#
|
7753
7752
|
# usdm
|
7753
|
+
#
|
7754
7754
|
# {
|
7755
7755
|
# "symbol": "BTCBUSD",
|
7756
7756
|
# "initialMargin": "0",
|
@@ -7771,6 +7771,7 @@ class binance(Exchange, ImplicitAPI):
|
|
7771
7771
|
# }
|
7772
7772
|
#
|
7773
7773
|
# coinm
|
7774
|
+
#
|
7774
7775
|
# {
|
7775
7776
|
# "symbol": "BTCUSD_210625",
|
7776
7777
|
# "initialMargin": "0.00024393",
|
@@ -7789,6 +7790,46 @@ class binance(Exchange, ImplicitAPI):
|
|
7789
7790
|
# "crossWalletBalance": "34",
|
7790
7791
|
# }
|
7791
7792
|
#
|
7793
|
+
# linear portfolio margin
|
7794
|
+
#
|
7795
|
+
# {
|
7796
|
+
# "symbol": "CTSIUSDT",
|
7797
|
+
# "initialMargin": "0",
|
7798
|
+
# "maintMargin": "0",
|
7799
|
+
# "unrealizedProfit": "0.00000000",
|
7800
|
+
# "positionInitialMargin": "0",
|
7801
|
+
# "openOrderInitialMargin": "0",
|
7802
|
+
# "leverage": "20",
|
7803
|
+
# "entryPrice": "0.0",
|
7804
|
+
# "maxNotional": "25000",
|
7805
|
+
# "bidNotional": "0",
|
7806
|
+
# "askNotional": "0",
|
7807
|
+
# "positionSide": "SHORT",
|
7808
|
+
# "positionAmt": "0",
|
7809
|
+
# "updateTime": 0,
|
7810
|
+
# "notional": "0",
|
7811
|
+
# "breakEvenPrice": "0.0"
|
7812
|
+
# }
|
7813
|
+
#
|
7814
|
+
# inverse portoflio margin
|
7815
|
+
#
|
7816
|
+
# {
|
7817
|
+
# "symbol": "TRXUSD_PERP",
|
7818
|
+
# "initialMargin": "0",
|
7819
|
+
# "maintMargin": "0",
|
7820
|
+
# "unrealizedProfit": "0.00000000",
|
7821
|
+
# "positionInitialMargin": "0",
|
7822
|
+
# "openOrderInitialMargin": "0",
|
7823
|
+
# "leverage": "20",
|
7824
|
+
# "entryPrice": "0.00000000",
|
7825
|
+
# "positionSide": "SHORT",
|
7826
|
+
# "positionAmt": "0",
|
7827
|
+
# "maxQty": "5000000",
|
7828
|
+
# "updateTime": 0,
|
7829
|
+
# "notionalValue": "0",
|
7830
|
+
# "breakEvenPrice": "0.00000000"
|
7831
|
+
# }
|
7832
|
+
#
|
7792
7833
|
marketId = self.safe_string(position, 'symbol')
|
7793
7834
|
market = self.safe_market(marketId, market, None, 'contract')
|
7794
7835
|
symbol = self.safe_string(market, 'symbol')
|
@@ -7817,8 +7858,8 @@ class binance(Exchange, ImplicitAPI):
|
|
7817
7858
|
contractsString = Precise.string_div(entryNotional, contractSizeNew)
|
7818
7859
|
contractsStringAbs = Precise.string_div(Precise.string_add(contractsString, '0.5'), '1', 0)
|
7819
7860
|
contracts = self.parse_number(contractsStringAbs)
|
7820
|
-
leverageBrackets = self.
|
7821
|
-
leverageBracket = self.
|
7861
|
+
leverageBrackets = self.safe_dict(self.options, 'leverageBrackets', {})
|
7862
|
+
leverageBracket = self.safe_list(leverageBrackets, symbol, [])
|
7822
7863
|
maintenanceMarginPercentageString = None
|
7823
7864
|
for i in range(0, len(leverageBracket)):
|
7824
7865
|
bracket = leverageBracket[i]
|
@@ -7831,7 +7872,7 @@ class binance(Exchange, ImplicitAPI):
|
|
7831
7872
|
timestamp = self.safe_integer(position, 'updateTime')
|
7832
7873
|
if timestamp == 0:
|
7833
7874
|
timestamp = None
|
7834
|
-
isolated = self.
|
7875
|
+
isolated = self.safe_bool(position, 'isolated')
|
7835
7876
|
marginMode = None
|
7836
7877
|
collateralString = None
|
7837
7878
|
walletBalance = None
|
@@ -7973,11 +8014,45 @@ class binance(Exchange, ImplicitAPI):
|
|
7973
8014
|
# "isolatedWallet": "0.00268058"
|
7974
8015
|
# }
|
7975
8016
|
#
|
8017
|
+
# inverse portfolio margin
|
8018
|
+
#
|
8019
|
+
# {
|
8020
|
+
# "symbol": "ETHUSD_PERP",
|
8021
|
+
# "positionAmt": "1",
|
8022
|
+
# "entryPrice": "2422.400000007",
|
8023
|
+
# "markPrice": "2424.51267823",
|
8024
|
+
# "unRealizedProfit": "0.0000036",
|
8025
|
+
# "liquidationPrice": "293.57678898",
|
8026
|
+
# "leverage": "100",
|
8027
|
+
# "positionSide": "LONG",
|
8028
|
+
# "updateTime": 1707371941861,
|
8029
|
+
# "maxQty": "15",
|
8030
|
+
# "notionalValue": "0.00412454",
|
8031
|
+
# "breakEvenPrice": "2423.368960034"
|
8032
|
+
# }
|
8033
|
+
#
|
8034
|
+
# linear portfolio margin
|
8035
|
+
#
|
8036
|
+
# {
|
8037
|
+
# "symbol": "BTCUSDT",
|
8038
|
+
# "positionAmt": "0.01",
|
8039
|
+
# "entryPrice": "44525.0",
|
8040
|
+
# "markPrice": "45464.1735922",
|
8041
|
+
# "unRealizedProfit": "9.39173592",
|
8042
|
+
# "liquidationPrice": "38007.16308568",
|
8043
|
+
# "leverage": "100",
|
8044
|
+
# "positionSide": "LONG",
|
8045
|
+
# "updateTime": 1707371879042,
|
8046
|
+
# "maxNotionalValue": "500000.0",
|
8047
|
+
# "notional": "454.64173592",
|
8048
|
+
# "breakEvenPrice": "44542.81"
|
8049
|
+
# }
|
8050
|
+
#
|
7976
8051
|
marketId = self.safe_string(position, 'symbol')
|
7977
8052
|
market = self.safe_market(marketId, market, None, 'contract')
|
7978
8053
|
symbol = self.safe_string(market, 'symbol')
|
7979
|
-
leverageBrackets = self.
|
7980
|
-
leverageBracket = self.
|
8054
|
+
leverageBrackets = self.safe_dict(self.options, 'leverageBrackets', {})
|
8055
|
+
leverageBracket = self.safe_list(leverageBrackets, symbol, [])
|
7981
8056
|
notionalString = self.safe_string_2(position, 'notional', 'notionalValue')
|
7982
8057
|
notionalStringAbs = Precise.string_abs(notionalString)
|
7983
8058
|
maintenanceMarginPercentageString = None
|
@@ -8010,7 +8085,7 @@ class binance(Exchange, ImplicitAPI):
|
|
8010
8085
|
linear = ('notional' in position)
|
8011
8086
|
if marginMode == 'cross':
|
8012
8087
|
# calculate collateral
|
8013
|
-
precision = self.
|
8088
|
+
precision = self.safe_dict(market, 'precision', {})
|
8014
8089
|
if linear:
|
8015
8090
|
# walletBalance = (liquidationPrice * (±1 + mmp) ± entryPrice) * contracts
|
8016
8091
|
onePlusMaintenanceMarginPercentageString = None
|
@@ -8104,11 +8179,19 @@ class binance(Exchange, ImplicitAPI):
|
|
8104
8179
|
query = self.omit(params, 'type')
|
8105
8180
|
subType = None
|
8106
8181
|
subType, params = self.handle_sub_type_and_params('loadLeverageBrackets', None, params, 'linear')
|
8182
|
+
isPortfolioMargin = None
|
8183
|
+
isPortfolioMargin, params = self.handle_option_and_params_2(params, 'loadLeverageBrackets', 'papi', 'portfolioMargin', False)
|
8107
8184
|
response = None
|
8108
8185
|
if self.is_linear(type, subType):
|
8109
|
-
|
8186
|
+
if isPortfolioMargin:
|
8187
|
+
response = await self.papiGetUmLeverageBracket(query)
|
8188
|
+
else:
|
8189
|
+
response = await self.fapiPrivateGetLeverageBracket(query)
|
8110
8190
|
elif self.is_inverse(type, subType):
|
8111
|
-
|
8191
|
+
if isPortfolioMargin:
|
8192
|
+
response = await self.papiGetCmLeverageBracket(query)
|
8193
|
+
else:
|
8194
|
+
response = await self.dapiPrivateV2GetLeverageBracket(query)
|
8112
8195
|
else:
|
8113
8196
|
raise NotSupported(self.id + ' loadLeverageBrackets() supports linear and inverse contracts only')
|
8114
8197
|
self.options['leverageBrackets'] = {}
|
@@ -8116,7 +8199,7 @@ class binance(Exchange, ImplicitAPI):
|
|
8116
8199
|
entry = response[i]
|
8117
8200
|
marketId = self.safe_string(entry, 'symbol')
|
8118
8201
|
symbol = self.safe_symbol(marketId, None, None, 'contract')
|
8119
|
-
brackets = self.
|
8202
|
+
brackets = self.safe_list(entry, 'brackets', [])
|
8120
8203
|
result = []
|
8121
8204
|
for j in range(0, len(brackets)):
|
8122
8205
|
bracket = brackets[j]
|
@@ -8131,8 +8214,11 @@ class binance(Exchange, ImplicitAPI):
|
|
8131
8214
|
retrieve information on the maximum leverage, and maintenance margin for trades of varying trade sizes
|
8132
8215
|
:see: https://binance-docs.github.io/apidocs/futures/en/#notional-and-leverage-brackets-user_data
|
8133
8216
|
:see: https://binance-docs.github.io/apidocs/delivery/en/#notional-bracket-for-symbol-user_data
|
8217
|
+
:see: https://binance-docs.github.io/apidocs/pm/en/#um-notional-and-leverage-brackets-user_data
|
8218
|
+
:see: https://binance-docs.github.io/apidocs/pm/en/#cm-notional-and-leverage-brackets-user_data
|
8134
8219
|
:param str[]|None symbols: list of unified market symbols
|
8135
8220
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
8221
|
+
:param boolean [params.portfolioMargin]: set to True if you would like to fetch the leverage tiers for a portfolio margin account
|
8136
8222
|
:returns dict: a dictionary of `leverage tiers structures <https://docs.ccxt.com/#/?id=leverage-tiers-structure>`, indexed by market symbols
|
8137
8223
|
"""
|
8138
8224
|
await self.load_markets()
|
@@ -8140,11 +8226,19 @@ class binance(Exchange, ImplicitAPI):
|
|
8140
8226
|
type, params = self.handle_market_type_and_params('fetchLeverageTiers', None, params)
|
8141
8227
|
subType = None
|
8142
8228
|
subType, params = self.handle_sub_type_and_params('fetchLeverageTiers', None, params, 'linear')
|
8229
|
+
isPortfolioMargin = None
|
8230
|
+
isPortfolioMargin, params = self.handle_option_and_params_2(params, 'fetchLeverageTiers', 'papi', 'portfolioMargin', False)
|
8143
8231
|
response = None
|
8144
8232
|
if self.is_linear(type, subType):
|
8145
|
-
|
8233
|
+
if isPortfolioMargin:
|
8234
|
+
response = await self.papiGetUmLeverageBracket(params)
|
8235
|
+
else:
|
8236
|
+
response = await self.fapiPrivateGetLeverageBracket(params)
|
8146
8237
|
elif self.is_inverse(type, subType):
|
8147
|
-
|
8238
|
+
if isPortfolioMargin:
|
8239
|
+
response = await self.papiGetCmLeverageBracket(params)
|
8240
|
+
else:
|
8241
|
+
response = await self.dapiPrivateV2GetLeverageBracket(params)
|
8148
8242
|
else:
|
8149
8243
|
raise NotSupported(self.id + ' fetchLeverageTiers() supports linear and inverse contracts only')
|
8150
8244
|
#
|
@@ -8211,7 +8305,7 @@ class binance(Exchange, ImplicitAPI):
|
|
8211
8305
|
#
|
8212
8306
|
marketId = self.safe_string(info, 'symbol')
|
8213
8307
|
market = self.safe_market(marketId, market, None, 'contract')
|
8214
|
-
brackets = self.
|
8308
|
+
brackets = self.safe_list(info, 'brackets', [])
|
8215
8309
|
tiers = []
|
8216
8310
|
for j in range(0, len(brackets)):
|
8217
8311
|
bracket = brackets[j]
|
@@ -8406,8 +8500,11 @@ class binance(Exchange, ImplicitAPI):
|
|
8406
8500
|
fetch account positions
|
8407
8501
|
:see: https://binance-docs.github.io/apidocs/futures/en/#account-information-v2-user_data
|
8408
8502
|
:see: https://binance-docs.github.io/apidocs/delivery/en/#account-information-user_data
|
8503
|
+
:see: https://binance-docs.github.io/apidocs/pm/en/#get-um-account-detail-user_data
|
8504
|
+
:see: https://binance-docs.github.io/apidocs/pm/en/#get-cm-account-detail-user_data
|
8409
8505
|
:param str[]|None symbols: list of unified market symbols
|
8410
8506
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
8507
|
+
:param boolean [params.portfolioMargin]: set to True if you would like to fetch positions in a portfolio margin account
|
8411
8508
|
:returns dict: data on account positions
|
8412
8509
|
"""
|
8413
8510
|
if symbols is not None:
|
@@ -8417,14 +8514,22 @@ class binance(Exchange, ImplicitAPI):
|
|
8417
8514
|
await self.load_leverage_brackets(False, params)
|
8418
8515
|
defaultType = self.safe_string(self.options, 'defaultType', 'future')
|
8419
8516
|
type = self.safe_string(params, 'type', defaultType)
|
8420
|
-
|
8517
|
+
params = self.omit(params, 'type')
|
8421
8518
|
subType = None
|
8422
|
-
subType,
|
8519
|
+
subType, params = self.handle_sub_type_and_params('fetchAccountPositions', None, params, 'linear')
|
8520
|
+
isPortfolioMargin = None
|
8521
|
+
isPortfolioMargin, params = self.handle_option_and_params_2(params, 'fetchAccountPositions', 'papi', 'portfolioMargin', False)
|
8423
8522
|
response = None
|
8424
8523
|
if self.is_linear(type, subType):
|
8425
|
-
|
8524
|
+
if isPortfolioMargin:
|
8525
|
+
response = await self.papiGetUmAccount(params)
|
8526
|
+
else:
|
8527
|
+
response = await self.fapiPrivateV2GetAccount(params)
|
8426
8528
|
elif self.is_inverse(type, subType):
|
8427
|
-
|
8529
|
+
if isPortfolioMargin:
|
8530
|
+
response = await self.papiGetCmAccount(params)
|
8531
|
+
else:
|
8532
|
+
response = await self.dapiPrivateGetAccount(params)
|
8428
8533
|
else:
|
8429
8534
|
raise NotSupported(self.id + ' fetchPositions() supports linear and inverse contracts only')
|
8430
8535
|
result = self.parse_account_positions(response)
|
@@ -8437,8 +8542,11 @@ class binance(Exchange, ImplicitAPI):
|
|
8437
8542
|
fetch positions risk
|
8438
8543
|
:see: https://binance-docs.github.io/apidocs/futures/en/#position-information-v2-user_data
|
8439
8544
|
:see: https://binance-docs.github.io/apidocs/delivery/en/#position-information-user_data
|
8545
|
+
:see: https://binance-docs.github.io/apidocs/pm/en/#query-um-position-information-user_data
|
8546
|
+
:see: https://binance-docs.github.io/apidocs/pm/en/#query-cm-position-information-user_data
|
8440
8547
|
:param str[]|None symbols: list of unified market symbols
|
8441
8548
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
8549
|
+
:param boolean [params.portfolioMargin]: set to True if you would like to fetch positions for a portfolio margin account
|
8442
8550
|
:returns dict: data on the positions risk
|
8443
8551
|
"""
|
8444
8552
|
if symbols is not None:
|
@@ -8452,68 +8560,117 @@ class binance(Exchange, ImplicitAPI):
|
|
8452
8560
|
type = self.safe_string(params, 'type', defaultType)
|
8453
8561
|
subType = None
|
8454
8562
|
subType, params = self.handle_sub_type_and_params('fetchPositionsRisk', None, params, 'linear')
|
8563
|
+
isPortfolioMargin = None
|
8564
|
+
isPortfolioMargin, params = self.handle_option_and_params_2(params, 'fetchPositionsRisk', 'papi', 'portfolioMargin', False)
|
8455
8565
|
params = self.omit(params, 'type')
|
8456
8566
|
response = None
|
8457
8567
|
if self.is_linear(type, subType):
|
8458
|
-
|
8459
|
-
|
8460
|
-
|
8461
|
-
|
8462
|
-
# [
|
8463
|
-
# {
|
8464
|
-
# "entryPrice": "0.00000",
|
8465
|
-
# "marginType": "isolated",
|
8466
|
-
# "isAutoAddMargin": "false",
|
8467
|
-
# "isolatedMargin": "0.00000000",
|
8468
|
-
# "leverage": "10",
|
8469
|
-
# "liquidationPrice": "0",
|
8470
|
-
# "markPrice": "6679.50671178",
|
8471
|
-
# "maxNotionalValue": "20000000",
|
8472
|
-
# "positionAmt": "0.000",
|
8473
|
-
# "symbol": "BTCUSDT",
|
8474
|
-
# "unRealizedProfit": "0.00000000",
|
8475
|
-
# "positionSide": "BOTH",
|
8476
|
-
# "updateTime": 0
|
8477
|
-
# }
|
8478
|
-
# ]
|
8479
|
-
#
|
8480
|
-
# For Hedge position mode:
|
8481
|
-
# [
|
8482
|
-
# {
|
8483
|
-
# "entryPrice": "6563.66500",
|
8484
|
-
# "marginType": "isolated",
|
8485
|
-
# "isAutoAddMargin": "false",
|
8486
|
-
# "isolatedMargin": "15517.54150468",
|
8487
|
-
# "leverage": "10",
|
8488
|
-
# "liquidationPrice": "5930.78",
|
8489
|
-
# "markPrice": "6679.50671178",
|
8490
|
-
# "maxNotionalValue": "20000000",
|
8491
|
-
# "positionAmt": "20.000",
|
8492
|
-
# "symbol": "BTCUSDT",
|
8493
|
-
# "unRealizedProfit": "2316.83423560"
|
8494
|
-
# "positionSide": "LONG",
|
8495
|
-
# "updateTime": 1625474304765
|
8496
|
-
# },
|
8497
|
-
# {
|
8498
|
-
# "entryPrice": "0.00000",
|
8499
|
-
# "marginType": "isolated",
|
8500
|
-
# "isAutoAddMargin": "false",
|
8501
|
-
# "isolatedMargin": "5413.95799991",
|
8502
|
-
# "leverage": "10",
|
8503
|
-
# "liquidationPrice": "7189.95",
|
8504
|
-
# "markPrice": "6679.50671178",
|
8505
|
-
# "maxNotionalValue": "20000000",
|
8506
|
-
# "positionAmt": "-10.000",
|
8507
|
-
# "symbol": "BTCUSDT",
|
8508
|
-
# "unRealizedProfit": "-1156.46711780",
|
8509
|
-
# "positionSide": "SHORT",
|
8510
|
-
# "updateTime": 0
|
8511
|
-
# }
|
8512
|
-
# ]
|
8568
|
+
if isPortfolioMargin:
|
8569
|
+
response = await self.papiGetUmPositionRisk(self.extend(request, params))
|
8570
|
+
else:
|
8571
|
+
response = await self.fapiPrivateV2GetPositionRisk(self.extend(request, params))
|
8513
8572
|
elif self.is_inverse(type, subType):
|
8514
|
-
|
8573
|
+
if isPortfolioMargin:
|
8574
|
+
response = await self.papiGetCmPositionRisk(self.extend(request, params))
|
8575
|
+
else:
|
8576
|
+
response = await self.dapiPrivateGetPositionRisk(self.extend(request, params))
|
8515
8577
|
else:
|
8516
8578
|
raise NotSupported(self.id + ' fetchPositionsRisk() supports linear and inverse contracts only')
|
8579
|
+
# ### Response examples ###
|
8580
|
+
#
|
8581
|
+
# For One-way position mode:
|
8582
|
+
#
|
8583
|
+
# [
|
8584
|
+
# {
|
8585
|
+
# "entryPrice": "0.00000",
|
8586
|
+
# "marginType": "isolated",
|
8587
|
+
# "isAutoAddMargin": "false",
|
8588
|
+
# "isolatedMargin": "0.00000000",
|
8589
|
+
# "leverage": "10",
|
8590
|
+
# "liquidationPrice": "0",
|
8591
|
+
# "markPrice": "6679.50671178",
|
8592
|
+
# "maxNotionalValue": "20000000",
|
8593
|
+
# "positionAmt": "0.000",
|
8594
|
+
# "symbol": "BTCUSDT",
|
8595
|
+
# "unRealizedProfit": "0.00000000",
|
8596
|
+
# "positionSide": "BOTH",
|
8597
|
+
# "updateTime": 0
|
8598
|
+
# }
|
8599
|
+
# ]
|
8600
|
+
#
|
8601
|
+
# For Hedge position mode:
|
8602
|
+
#
|
8603
|
+
# [
|
8604
|
+
# {
|
8605
|
+
# "entryPrice": "6563.66500",
|
8606
|
+
# "marginType": "isolated",
|
8607
|
+
# "isAutoAddMargin": "false",
|
8608
|
+
# "isolatedMargin": "15517.54150468",
|
8609
|
+
# "leverage": "10",
|
8610
|
+
# "liquidationPrice": "5930.78",
|
8611
|
+
# "markPrice": "6679.50671178",
|
8612
|
+
# "maxNotionalValue": "20000000",
|
8613
|
+
# "positionAmt": "20.000",
|
8614
|
+
# "symbol": "BTCUSDT",
|
8615
|
+
# "unRealizedProfit": "2316.83423560"
|
8616
|
+
# "positionSide": "LONG",
|
8617
|
+
# "updateTime": 1625474304765
|
8618
|
+
# },
|
8619
|
+
# {
|
8620
|
+
# "entryPrice": "0.00000",
|
8621
|
+
# "marginType": "isolated",
|
8622
|
+
# "isAutoAddMargin": "false",
|
8623
|
+
# "isolatedMargin": "5413.95799991",
|
8624
|
+
# "leverage": "10",
|
8625
|
+
# "liquidationPrice": "7189.95",
|
8626
|
+
# "markPrice": "6679.50671178",
|
8627
|
+
# "maxNotionalValue": "20000000",
|
8628
|
+
# "positionAmt": "-10.000",
|
8629
|
+
# "symbol": "BTCUSDT",
|
8630
|
+
# "unRealizedProfit": "-1156.46711780",
|
8631
|
+
# "positionSide": "SHORT",
|
8632
|
+
# "updateTime": 0
|
8633
|
+
# }
|
8634
|
+
# ]
|
8635
|
+
#
|
8636
|
+
# inverse portfolio margin:
|
8637
|
+
#
|
8638
|
+
# [
|
8639
|
+
# {
|
8640
|
+
# "symbol": "ETHUSD_PERP",
|
8641
|
+
# "positionAmt": "1",
|
8642
|
+
# "entryPrice": "2422.400000007",
|
8643
|
+
# "markPrice": "2424.51267823",
|
8644
|
+
# "unRealizedProfit": "0.0000036",
|
8645
|
+
# "liquidationPrice": "293.57678898",
|
8646
|
+
# "leverage": "100",
|
8647
|
+
# "positionSide": "LONG",
|
8648
|
+
# "updateTime": 1707371941861,
|
8649
|
+
# "maxQty": "15",
|
8650
|
+
# "notionalValue": "0.00412454",
|
8651
|
+
# "breakEvenPrice": "2423.368960034"
|
8652
|
+
# }
|
8653
|
+
# ]
|
8654
|
+
#
|
8655
|
+
# linear portfolio margin:
|
8656
|
+
#
|
8657
|
+
# [
|
8658
|
+
# {
|
8659
|
+
# "symbol": "BTCUSDT",
|
8660
|
+
# "positionAmt": "0.01",
|
8661
|
+
# "entryPrice": "44525.0",
|
8662
|
+
# "markPrice": "45464.1735922",
|
8663
|
+
# "unRealizedProfit": "9.39173592",
|
8664
|
+
# "liquidationPrice": "38007.16308568",
|
8665
|
+
# "leverage": "100",
|
8666
|
+
# "positionSide": "LONG",
|
8667
|
+
# "updateTime": 1707371879042,
|
8668
|
+
# "maxNotionalValue": "500000.0",
|
8669
|
+
# "notional": "454.64173592",
|
8670
|
+
# "breakEvenPrice": "44542.81"
|
8671
|
+
# }
|
8672
|
+
# ]
|
8673
|
+
#
|
8517
8674
|
result = []
|
8518
8675
|
for i in range(0, len(response)):
|
8519
8676
|
parsed = self.parse_position_risk(response[i])
|
@@ -8526,10 +8683,14 @@ class binance(Exchange, ImplicitAPI):
|
|
8526
8683
|
fetch the history of funding payments paid and received on self account
|
8527
8684
|
:see: https://binance-docs.github.io/apidocs/futures/en/#get-income-history-user_data
|
8528
8685
|
:see: https://binance-docs.github.io/apidocs/delivery/en/#get-income-history-user_data
|
8686
|
+
:see: https://binance-docs.github.io/apidocs/pm/en/#get-um-income-history-user_data
|
8687
|
+
:see: https://binance-docs.github.io/apidocs/pm/en/#get-cm-income-history-user_data
|
8529
8688
|
:param str symbol: unified market symbol
|
8530
8689
|
:param int [since]: the earliest time in ms to fetch funding history for
|
8531
8690
|
:param int [limit]: the maximum number of funding history structures to retrieve
|
8532
8691
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
8692
|
+
:param int [params.until]: timestamp in ms of the latest funding history entry
|
8693
|
+
:param boolean [params.portfolioMargin]: set to True if you would like to fetch the funding history for a portfolio margin account
|
8533
8694
|
:returns dict: a `funding history structure <https://docs.ccxt.com/#/?id=funding-history-structure>`
|
8534
8695
|
"""
|
8535
8696
|
await self.load_markets()
|
@@ -8544,6 +8705,9 @@ class binance(Exchange, ImplicitAPI):
|
|
8544
8705
|
raise NotSupported(self.id + ' fetchFundingHistory() supports swap contracts only')
|
8545
8706
|
subType = None
|
8546
8707
|
subType, params = self.handle_sub_type_and_params('fetchFundingHistory', market, params, 'linear')
|
8708
|
+
isPortfolioMargin = None
|
8709
|
+
isPortfolioMargin, params = self.handle_option_and_params_2(params, 'fetchFundingHistory', 'papi', 'portfolioMargin', False)
|
8710
|
+
request, params = self.handle_until_option('endTime', request, params)
|
8547
8711
|
if since is not None:
|
8548
8712
|
request['startTime'] = since
|
8549
8713
|
if limit is not None:
|
@@ -8553,9 +8717,15 @@ class binance(Exchange, ImplicitAPI):
|
|
8553
8717
|
params = self.omit(params, 'type')
|
8554
8718
|
response = None
|
8555
8719
|
if self.is_linear(type, subType):
|
8556
|
-
|
8720
|
+
if isPortfolioMargin:
|
8721
|
+
response = await self.papiGetUmIncome(self.extend(request, params))
|
8722
|
+
else:
|
8723
|
+
response = await self.fapiPrivateGetIncome(self.extend(request, params))
|
8557
8724
|
elif self.is_inverse(type, subType):
|
8558
|
-
|
8725
|
+
if isPortfolioMargin:
|
8726
|
+
response = await self.papiGetCmIncome(self.extend(request, params))
|
8727
|
+
else:
|
8728
|
+
response = await self.dapiPrivateGetIncome(self.extend(request, params))
|
8559
8729
|
else:
|
8560
8730
|
raise NotSupported(self.id + ' fetchFundingHistory() supports linear and inverse contracts only')
|
8561
8731
|
return self.parse_incomes(response, market, since, limit)
|
@@ -8878,12 +9048,15 @@ class binance(Exchange, ImplicitAPI):
|
|
8878
9048
|
:see: https://binance-docs.github.io/apidocs/voptions/en/#account-funding-flow-user_data
|
8879
9049
|
:see: https://binance-docs.github.io/apidocs/futures/en/#get-income-history-user_data
|
8880
9050
|
:see: https://binance-docs.github.io/apidocs/delivery/en/#get-income-history-user_data
|
9051
|
+
:see: https://binance-docs.github.io/apidocs/pm/en/#get-um-income-history-user_data
|
9052
|
+
:see: https://binance-docs.github.io/apidocs/pm/en/#get-cm-income-history-user_data
|
8881
9053
|
:param str code: unified currency code
|
8882
9054
|
:param int [since]: timestamp in ms of the earliest ledger entry
|
8883
9055
|
:param int [limit]: max number of ledger entrys to return
|
8884
9056
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
8885
9057
|
:param int [params.until]: timestamp in ms of the latest ledger entry
|
8886
|
-
:param boolean [params.paginate]: default False, when True will automatically paginate by calling self endpoint multiple times. See in the docs all the [
|
9058
|
+
:param boolean [params.paginate]: default False, when True will automatically paginate by calling self endpoint multiple times. See in the docs all the [available parameters](https://github.com/ccxt/ccxt/wiki/Manual#pagination-params)
|
9059
|
+
:param boolean [params.portfolioMargin]: set to True if you would like to fetch the ledger for a portfolio margin account
|
8887
9060
|
:returns dict: a `ledger structure <https://docs.ccxt.com/#/?id=ledger-structure>`
|
8888
9061
|
"""
|
8889
9062
|
await self.load_markets()
|
@@ -8907,15 +9080,23 @@ class binance(Exchange, ImplicitAPI):
|
|
8907
9080
|
if until is not None:
|
8908
9081
|
params = self.omit(params, 'until')
|
8909
9082
|
request['endTime'] = until
|
9083
|
+
isPortfolioMargin = None
|
9084
|
+
isPortfolioMargin, params = self.handle_option_and_params_2(params, 'fetchLedger', 'papi', 'portfolioMargin', False)
|
8910
9085
|
response = None
|
8911
9086
|
if type == 'option':
|
8912
9087
|
self.check_required_argument('fetchLedger', code, 'code')
|
8913
9088
|
request['currency'] = currency['id']
|
8914
9089
|
response = await self.eapiPrivateGetBill(self.extend(request, params))
|
8915
9090
|
elif self.is_linear(type, subType):
|
8916
|
-
|
9091
|
+
if isPortfolioMargin:
|
9092
|
+
response = await self.papiGetUmIncome(self.extend(request, params))
|
9093
|
+
else:
|
9094
|
+
response = await self.fapiPrivateGetIncome(self.extend(request, params))
|
8917
9095
|
elif self.is_inverse(type, subType):
|
8918
|
-
|
9096
|
+
if isPortfolioMargin:
|
9097
|
+
response = await self.papiGetCmIncome(self.extend(request, params))
|
9098
|
+
else:
|
9099
|
+
response = await self.dapiPrivateGetIncome(self.extend(request, params))
|
8919
9100
|
else:
|
8920
9101
|
raise NotSupported(self.id + ' fetchLedger() supports contract wallets only')
|
8921
9102
|
#
|
@@ -8931,7 +9112,7 @@ class binance(Exchange, ImplicitAPI):
|
|
8931
9112
|
# }
|
8932
9113
|
# ]
|
8933
9114
|
#
|
8934
|
-
# futures(fapi, dapi)
|
9115
|
+
# futures(fapi, dapi, papi)
|
8935
9116
|
#
|
8936
9117
|
# [
|
8937
9118
|
# {
|
@@ -8960,7 +9141,7 @@ class binance(Exchange, ImplicitAPI):
|
|
8960
9141
|
# "createDate": 1676621042489
|
8961
9142
|
# }
|
8962
9143
|
#
|
8963
|
-
# futures(fapi, dapi)
|
9144
|
+
# futures(fapi, dapi, papi)
|
8964
9145
|
#
|
8965
9146
|
# {
|
8966
9147
|
# "symbol": "",
|
@@ -9059,7 +9240,7 @@ class binance(Exchange, ImplicitAPI):
|
|
9059
9240
|
isSpotOrMargin = (api.find('sapi') > -1 or api == 'private')
|
9060
9241
|
marketType = 'spot' if isSpotOrMargin else 'future'
|
9061
9242
|
defaultId = 'x-xcKtGhcu' if (not isSpotOrMargin) else 'x-R4BD3S82'
|
9062
|
-
broker = self.
|
9243
|
+
broker = self.safe_dict(self.options, 'broker', {})
|
9063
9244
|
brokerId = self.safe_string(broker, marketType, defaultId)
|
9064
9245
|
params['newClientOrderId'] = brokerId + self.uuid22()
|
9065
9246
|
query = None
|
@@ -9081,8 +9262,8 @@ class binance(Exchange, ImplicitAPI):
|
|
9081
9262
|
query = self.urlencode_with_array_repeat(extendedParams)
|
9082
9263
|
elif (path == 'batchOrders') or (path.find('sub-account') >= 0) or (path == 'capital/withdraw/apply') or (path.find('staking') >= 0):
|
9083
9264
|
if (method == 'DELETE') and (path == 'batchOrders'):
|
9084
|
-
orderidlist = self.
|
9085
|
-
origclientorderidlist = self.
|
9265
|
+
orderidlist = self.safe_list(extendedParams, 'orderidlist', [])
|
9266
|
+
origclientorderidlist = self.safe_list(extendedParams, 'origclientorderidlist', [])
|
9086
9267
|
extendedParams = self.omit(extendedParams, ['orderidlist', 'origclientorderidlist'])
|
9087
9268
|
query = self.rawencode(extendedParams)
|
9088
9269
|
orderidlistLength = len(orderidlist)
|
@@ -9131,8 +9312,8 @@ class binance(Exchange, ImplicitAPI):
|
|
9131
9312
|
elif url.startswith('https://papi.' + hostname + '/'):
|
9132
9313
|
marketType = 'portfoliomargin'
|
9133
9314
|
if marketType is not None:
|
9134
|
-
exceptionsForMarketType = self.
|
9135
|
-
return self.
|
9315
|
+
exceptionsForMarketType = self.safe_dict(self.exceptions, marketType, {})
|
9316
|
+
return self.safe_dict(exceptionsForMarketType, exactOrBroad, {})
|
9136
9317
|
return {}
|
9137
9318
|
|
9138
9319
|
def handle_errors(self, code, reason, url, method, headers, body, response, requestHeaders, requestBody):
|
@@ -9328,7 +9509,7 @@ class binance(Exchange, ImplicitAPI):
|
|
9328
9509
|
# },
|
9329
9510
|
# ]
|
9330
9511
|
#
|
9331
|
-
rate = self.
|
9512
|
+
rate = self.safe_dict(response, 0)
|
9332
9513
|
return self.parse_borrow_rate(rate)
|
9333
9514
|
|
9334
9515
|
async def fetch_borrow_rate_history(self, code: str, since: Int = None, limit: Int = None, params={}):
|
@@ -9424,7 +9605,7 @@ class binance(Exchange, ImplicitAPI):
|
|
9424
9605
|
# "success": True
|
9425
9606
|
# }
|
9426
9607
|
#
|
9427
|
-
data = self.
|
9608
|
+
data = self.safe_dict(response, 'data')
|
9428
9609
|
giftcardCode = self.safe_string(data, 'code')
|
9429
9610
|
id = self.safe_string(data, 'referenceNo')
|
9430
9611
|
return {
|
@@ -9523,7 +9704,7 @@ class binance(Exchange, ImplicitAPI):
|
|
9523
9704
|
# "total": 1
|
9524
9705
|
# }
|
9525
9706
|
#
|
9526
|
-
rows = self.
|
9707
|
+
rows = self.safe_list(response, 'rows')
|
9527
9708
|
interest = self.parse_borrow_interests(rows, market)
|
9528
9709
|
return self.filter_by_currency_since_limit(interest, code, since, limit)
|
9529
9710
|
|
@@ -9548,9 +9729,11 @@ class binance(Exchange, ImplicitAPI):
|
|
9548
9729
|
"""
|
9549
9730
|
repay borrowed margin and interest
|
9550
9731
|
:see: https://binance-docs.github.io/apidocs/spot/en/#margin-account-borrow-repay-margin
|
9732
|
+
:see: https://binance-docs.github.io/apidocs/pm/en/#margin-account-repay-margin
|
9551
9733
|
:param str code: unified currency code of the currency to repay
|
9552
9734
|
:param float amount: the amount to repay
|
9553
9735
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
9736
|
+
:param boolean [params.portfolioMargin]: set to True if you would like to repay margin in a portfolio margin account
|
9554
9737
|
:returns dict: a `margin loan structure <https://docs.ccxt.com/#/?id=margin-loan-structure>`
|
9555
9738
|
"""
|
9556
9739
|
await self.load_markets()
|
@@ -9558,10 +9741,16 @@ class binance(Exchange, ImplicitAPI):
|
|
9558
9741
|
request = {
|
9559
9742
|
'asset': currency['id'],
|
9560
9743
|
'amount': self.currency_to_precision(code, amount),
|
9561
|
-
'isIsolated': 'FALSE',
|
9562
|
-
'type': 'REPAY',
|
9563
9744
|
}
|
9564
|
-
response =
|
9745
|
+
response = None
|
9746
|
+
isPortfolioMargin = None
|
9747
|
+
isPortfolioMargin, params = self.handle_option_and_params_2(params, 'repayCrossMargin', 'papi', 'portfolioMargin', False)
|
9748
|
+
if isPortfolioMargin:
|
9749
|
+
response = await self.papiPostRepayLoan(self.extend(request, params))
|
9750
|
+
else:
|
9751
|
+
request['isIsolated'] = 'FALSE'
|
9752
|
+
request['type'] = 'REPAY'
|
9753
|
+
response = await self.sapiPostMarginBorrowRepay(self.extend(request, params))
|
9565
9754
|
#
|
9566
9755
|
# {
|
9567
9756
|
# "tranId": 108988250265,
|
@@ -9603,9 +9792,11 @@ class binance(Exchange, ImplicitAPI):
|
|
9603
9792
|
"""
|
9604
9793
|
create a loan to borrow margin
|
9605
9794
|
:see: https://binance-docs.github.io/apidocs/spot/en/#margin-account-borrow-repay-margin
|
9795
|
+
:see: https://binance-docs.github.io/apidocs/pm/en/#margin-account-borrow-margin
|
9606
9796
|
:param str code: unified currency code of the currency to borrow
|
9607
9797
|
:param float amount: the amount to borrow
|
9608
9798
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
9799
|
+
:param boolean [params.portfolioMargin]: set to True if you would like to borrow margin in a portfolio margin account
|
9609
9800
|
:returns dict: a `margin loan structure <https://docs.ccxt.com/#/?id=margin-loan-structure>`
|
9610
9801
|
"""
|
9611
9802
|
await self.load_markets()
|
@@ -9613,10 +9804,16 @@ class binance(Exchange, ImplicitAPI):
|
|
9613
9804
|
request = {
|
9614
9805
|
'asset': currency['id'],
|
9615
9806
|
'amount': self.currency_to_precision(code, amount),
|
9616
|
-
'isIsolated': 'FALSE',
|
9617
|
-
'type': 'BORROW',
|
9618
9807
|
}
|
9619
|
-
response =
|
9808
|
+
response = None
|
9809
|
+
isPortfolioMargin = None
|
9810
|
+
isPortfolioMargin, params = self.handle_option_and_params_2(params, 'borrowCrossMargin', 'papi', 'portfolioMargin', False)
|
9811
|
+
if isPortfolioMargin:
|
9812
|
+
response = await self.papiPostMarginLoan(self.extend(request, params))
|
9813
|
+
else:
|
9814
|
+
request['isIsolated'] = 'FALSE'
|
9815
|
+
request['type'] = 'BORROW'
|
9816
|
+
response = await self.sapiPostMarginBorrowRepay(self.extend(request, params))
|
9620
9817
|
#
|
9621
9818
|
# {
|
9622
9819
|
# "tranId": 108988250265,
|