ccxt 4.4.40__py2.py3-none-any.whl → 4.4.41__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.
- ccxt/__init__.py +1 -1
- ccxt/abstract/bitmart.py +2 -0
- ccxt/abstract/okx.py +5 -0
- ccxt/async_support/__init__.py +1 -1
- ccxt/async_support/base/exchange.py +10 -3
- ccxt/async_support/binance.py +24 -24
- ccxt/async_support/bingx.py +3 -1
- ccxt/async_support/bitfinex.py +1 -1
- ccxt/async_support/bitget.py +1 -0
- ccxt/async_support/bitmart.py +243 -2
- ccxt/async_support/bybit.py +8 -8
- ccxt/async_support/exmo.py +60 -4
- ccxt/async_support/gate.py +1 -1
- ccxt/async_support/htx.py +1 -1
- ccxt/async_support/hyperliquid.py +60 -1
- ccxt/async_support/kraken.py +123 -25
- ccxt/async_support/kucoin.py +5 -1
- ccxt/async_support/mexc.py +3 -3
- ccxt/async_support/okx.py +6 -1
- ccxt/async_support/xt.py +3 -1
- ccxt/base/exchange.py +19 -4
- ccxt/base/types.py +10 -0
- ccxt/binance.py +24 -24
- ccxt/bingx.py +3 -1
- ccxt/bitfinex.py +1 -1
- ccxt/bitget.py +1 -0
- ccxt/bitmart.py +243 -2
- ccxt/bybit.py +8 -8
- ccxt/exmo.py +60 -4
- ccxt/gate.py +1 -1
- ccxt/htx.py +1 -1
- ccxt/hyperliquid.py +60 -1
- ccxt/kraken.py +123 -25
- ccxt/kucoin.py +5 -1
- ccxt/mexc.py +3 -3
- ccxt/okx.py +6 -1
- ccxt/pro/__init__.py +1 -1
- ccxt/xt.py +3 -1
- {ccxt-4.4.40.dist-info → ccxt-4.4.41.dist-info}/METADATA +4 -4
- {ccxt-4.4.40.dist-info → ccxt-4.4.41.dist-info}/RECORD +43 -43
- {ccxt-4.4.40.dist-info → ccxt-4.4.41.dist-info}/LICENSE.txt +0 -0
- {ccxt-4.4.40.dist-info → ccxt-4.4.41.dist-info}/WHEEL +0 -0
- {ccxt-4.4.40.dist-info → ccxt-4.4.41.dist-info}/top_level.txt +0 -0
ccxt/__init__.py
CHANGED
ccxt/abstract/bitmart.py
CHANGED
@@ -25,6 +25,7 @@ class ImplicitAPI:
|
|
25
25
|
public_get_contract_public_depth = publicGetContractPublicDepth = Entry('contract/public/depth', 'public', 'GET', {'cost': 5})
|
26
26
|
public_get_contract_public_open_interest = publicGetContractPublicOpenInterest = Entry('contract/public/open-interest', 'public', 'GET', {'cost': 30})
|
27
27
|
public_get_contract_public_funding_rate = publicGetContractPublicFundingRate = Entry('contract/public/funding-rate', 'public', 'GET', {'cost': 30})
|
28
|
+
public_get_contract_public_funding_rate_history = publicGetContractPublicFundingRateHistory = Entry('contract/public/funding-rate-history', 'public', 'GET', {'cost': 30})
|
28
29
|
public_get_contract_public_kline = publicGetContractPublicKline = Entry('contract/public/kline', 'public', 'GET', {'cost': 6})
|
29
30
|
public_get_account_v1_currencies = publicGetAccountV1Currencies = Entry('account/v1/currencies', 'public', 'GET', {'cost': 30})
|
30
31
|
private_get_account_sub_account_v1_transfer_list = privateGetAccountSubAccountV1TransferList = Entry('account/sub-account/v1/transfer-list', 'private', 'GET', {'cost': 7.5})
|
@@ -64,6 +65,7 @@ class ImplicitAPI:
|
|
64
65
|
private_get_contract_private_position_risk = privateGetContractPrivatePositionRisk = Entry('contract/private/position-risk', 'private', 'GET', {'cost': 10})
|
65
66
|
private_get_contract_private_affilate_rebate_list = privateGetContractPrivateAffilateRebateList = Entry('contract/private/affilate/rebate-list', 'private', 'GET', {'cost': 10})
|
66
67
|
private_get_contract_private_affilate_trade_list = privateGetContractPrivateAffilateTradeList = Entry('contract/private/affilate/trade-list', 'private', 'GET', {'cost': 10})
|
68
|
+
private_get_contract_private_transaction_history = privateGetContractPrivateTransactionHistory = Entry('contract/private/transaction-history', 'private', 'GET', {'cost': 10})
|
67
69
|
private_post_account_sub_account_main_v1_sub_to_main = privatePostAccountSubAccountMainV1SubToMain = Entry('account/sub-account/main/v1/sub-to-main', 'private', 'POST', {'cost': 30})
|
68
70
|
private_post_account_sub_account_sub_v1_sub_to_main = privatePostAccountSubAccountSubV1SubToMain = Entry('account/sub-account/sub/v1/sub-to-main', 'private', 'POST', {'cost': 30})
|
69
71
|
private_post_account_sub_account_main_v1_main_to_sub = privatePostAccountSubAccountMainV1MainToSub = Entry('account/sub-account/main/v1/main-to-sub', 'private', 'POST', {'cost': 30})
|
ccxt/abstract/okx.py
CHANGED
@@ -68,6 +68,7 @@ class ImplicitAPI:
|
|
68
68
|
public_get_tradingbot_public_rsi_back_testing = publicGetTradingBotPublicRsiBackTesting = Entry('tradingBot/public/rsi-back-testing', 'public', 'GET', {'cost': 1})
|
69
69
|
public_get_asset_exchange_list = publicGetAssetExchangeList = Entry('asset/exchange-list', 'public', 'GET', {'cost': 1.6666666666666667})
|
70
70
|
public_get_finance_staking_defi_eth_apy_history = publicGetFinanceStakingDefiEthApyHistory = Entry('finance/staking-defi/eth/apy-history', 'public', 'GET', {'cost': 1.6666666666666667})
|
71
|
+
public_get_finance_staking_defi_sol_apy_history = publicGetFinanceStakingDefiSolApyHistory = Entry('finance/staking-defi/sol/apy-history', 'public', 'GET', {'cost': 1.6666666666666667})
|
71
72
|
public_get_finance_savings_lending_rate_summary = publicGetFinanceSavingsLendingRateSummary = Entry('finance/savings/lending-rate-summary', 'public', 'GET', {'cost': 1.6666666666666667})
|
72
73
|
public_get_finance_savings_lending_rate_history = publicGetFinanceSavingsLendingRateHistory = Entry('finance/savings/lending-rate-history', 'public', 'GET', {'cost': 1.6666666666666667})
|
73
74
|
public_get_finance_fixed_loan_lending_offers = publicGetFinanceFixedLoanLendingOffers = Entry('finance/fixed-loan/lending-offers', 'public', 'GET', {'cost': 3.3333333333333335})
|
@@ -191,6 +192,8 @@ class ImplicitAPI:
|
|
191
192
|
private_get_finance_staking_defi_eth_balance = privateGetFinanceStakingDefiEthBalance = Entry('finance/staking-defi/eth/balance', 'private', 'GET', {'cost': 1.6666666666666667})
|
192
193
|
private_get_finance_staking_defi_eth_purchase_redeem_history = privateGetFinanceStakingDefiEthPurchaseRedeemHistory = Entry('finance/staking-defi/eth/purchase-redeem-history', 'private', 'GET', {'cost': 1.6666666666666667})
|
193
194
|
private_get_finance_staking_defi_eth_product_info = privateGetFinanceStakingDefiEthProductInfo = Entry('finance/staking-defi/eth/product-info', 'private', 'GET', {'cost': 3})
|
195
|
+
private_get_finance_staking_defi_sol_balance = privateGetFinanceStakingDefiSolBalance = Entry('finance/staking-defi/sol/balance', 'private', 'GET', {'cost': 1.6666666666666667})
|
196
|
+
private_get_finance_staking_defi_sol_purchase_redeem_history = privateGetFinanceStakingDefiSolPurchaseRedeemHistory = Entry('finance/staking-defi/sol/purchase-redeem-history', 'private', 'GET', {'cost': 1.6666666666666667})
|
194
197
|
private_get_copytrading_current_subpositions = privateGetCopytradingCurrentSubpositions = Entry('copytrading/current-subpositions', 'private', 'GET', {'cost': 1})
|
195
198
|
private_get_copytrading_subpositions_history = privateGetCopytradingSubpositionsHistory = Entry('copytrading/subpositions-history', 'private', 'GET', {'cost': 1})
|
196
199
|
private_get_copytrading_instruments = privateGetCopytradingInstruments = Entry('copytrading/instruments', 'private', 'GET', {'cost': 4})
|
@@ -311,6 +314,8 @@ class ImplicitAPI:
|
|
311
314
|
private_post_finance_staking_defi_cancel = privatePostFinanceStakingDefiCancel = Entry('finance/staking-defi/cancel', 'private', 'POST', {'cost': 3})
|
312
315
|
private_post_finance_staking_defi_eth_purchase = privatePostFinanceStakingDefiEthPurchase = Entry('finance/staking-defi/eth/purchase', 'private', 'POST', {'cost': 5})
|
313
316
|
private_post_finance_staking_defi_eth_redeem = privatePostFinanceStakingDefiEthRedeem = Entry('finance/staking-defi/eth/redeem', 'private', 'POST', {'cost': 5})
|
317
|
+
private_post_finance_staking_defi_sol_purchase = privatePostFinanceStakingDefiSolPurchase = Entry('finance/staking-defi/sol/purchase', 'private', 'POST', {'cost': 5})
|
318
|
+
private_post_finance_staking_defi_sol_redeem = privatePostFinanceStakingDefiSolRedeem = Entry('finance/staking-defi/sol/redeem', 'private', 'POST', {'cost': 5})
|
314
319
|
private_post_copytrading_algo_order = privatePostCopytradingAlgoOrder = Entry('copytrading/algo-order', 'private', 'POST', {'cost': 1})
|
315
320
|
private_post_copytrading_close_subposition = privatePostCopytradingCloseSubposition = Entry('copytrading/close-subposition', 'private', 'POST', {'cost': 1})
|
316
321
|
private_post_copytrading_set_instruments = privatePostCopytradingSetInstruments = Entry('copytrading/set-instruments', 'private', 'POST', {'cost': 4})
|
ccxt/async_support/__init__.py
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
# -----------------------------------------------------------------------------
|
4
4
|
|
5
|
-
__version__ = '4.4.
|
5
|
+
__version__ = '4.4.41'
|
6
6
|
|
7
7
|
# -----------------------------------------------------------------------------
|
8
8
|
|
@@ -755,6 +755,9 @@ class Exchange(BaseExchange):
|
|
755
755
|
async def fetch_open_interest(self, symbol: str, params={}):
|
756
756
|
raise NotSupported(self.id + ' fetchOpenInterest() is not supported yet')
|
757
757
|
|
758
|
+
async def fetch_open_interests(self, symbols: Strings = None, params={}):
|
759
|
+
raise NotSupported(self.id + ' fetchOpenInterests() is not supported yet')
|
760
|
+
|
758
761
|
async def sign_in(self, params={}):
|
759
762
|
raise NotSupported(self.id + ' signIn() is not supported yet')
|
760
763
|
|
@@ -1809,7 +1812,7 @@ class Exchange(BaseExchange):
|
|
1809
1812
|
else:
|
1810
1813
|
raise NotSupported(self.id + ' fetchTransactions() is not supported yet')
|
1811
1814
|
|
1812
|
-
async def fetch_paginated_call_dynamic(self, method: str, symbol: Str = None, since: Int = None, limit: Int = None, params={}, maxEntriesPerRequest: Int = None):
|
1815
|
+
async def fetch_paginated_call_dynamic(self, method: str, symbol: Str = None, since: Int = None, limit: Int = None, params={}, maxEntriesPerRequest: Int = None, removeRepeated=True):
|
1813
1816
|
maxCalls = None
|
1814
1817
|
maxCalls, params = self.handle_option_and_params(params, method, 'paginationCalls', 10)
|
1815
1818
|
maxRetries = None
|
@@ -1817,6 +1820,8 @@ class Exchange(BaseExchange):
|
|
1817
1820
|
paginationDirection = None
|
1818
1821
|
paginationDirection, params = self.handle_option_and_params(params, method, 'paginationDirection', 'backward')
|
1819
1822
|
paginationTimestamp = None
|
1823
|
+
removeRepeatedOption = removeRepeated
|
1824
|
+
removeRepeatedOption, params = self.handle_option_and_params(params, method, 'removeRepeated', removeRepeated)
|
1820
1825
|
calls = 0
|
1821
1826
|
result = []
|
1822
1827
|
errors = 0
|
@@ -1870,7 +1875,9 @@ class Exchange(BaseExchange):
|
|
1870
1875
|
errors += 1
|
1871
1876
|
if errors > maxRetries:
|
1872
1877
|
raise e
|
1873
|
-
uniqueResults =
|
1878
|
+
uniqueResults = result
|
1879
|
+
if removeRepeatedOption:
|
1880
|
+
uniqueResults = self.remove_repeated_elements_from_array(result)
|
1874
1881
|
key = 0 if (method == 'fetchOHLCV') else 'timestamp'
|
1875
1882
|
return self.filter_by_since_limit(uniqueResults, since, limit, key)
|
1876
1883
|
|
ccxt/async_support/binance.py
CHANGED
@@ -5063,8 +5063,8 @@ class binance(Exchange, ImplicitAPI):
|
|
5063
5063
|
if postOnly:
|
5064
5064
|
uppercaseType = 'LIMIT_MAKER'
|
5065
5065
|
request['type'] = uppercaseType
|
5066
|
-
|
5067
|
-
if
|
5066
|
+
triggerPrice = self.safe_number_2(params, 'stopPrice', 'triggerPrice')
|
5067
|
+
if triggerPrice is not None:
|
5068
5068
|
if uppercaseType == 'MARKET':
|
5069
5069
|
uppercaseType = 'STOP_LOSS'
|
5070
5070
|
elif uppercaseType == 'LIMIT':
|
@@ -5072,7 +5072,7 @@ class binance(Exchange, ImplicitAPI):
|
|
5072
5072
|
validOrderTypes = self.safe_list(market['info'], 'orderTypes')
|
5073
5073
|
if not self.in_array(uppercaseType, validOrderTypes):
|
5074
5074
|
if initialUppercaseType != uppercaseType:
|
5075
|
-
raise InvalidOrder(self.id + '
|
5075
|
+
raise InvalidOrder(self.id + ' triggerPrice parameter is not allowed for ' + symbol + ' ' + type + ' orders')
|
5076
5076
|
else:
|
5077
5077
|
raise InvalidOrder(self.id + ' ' + type + ' is not a valid order type for the ' + symbol + ' market')
|
5078
5078
|
if clientOrderId is None:
|
@@ -5086,7 +5086,7 @@ class binance(Exchange, ImplicitAPI):
|
|
5086
5086
|
request['newOrderRespType'] = self.safe_value(self.options['newOrderRespType'], type, 'RESULT') # 'ACK' for order id, 'RESULT' for full order or 'FULL' for order with fills
|
5087
5087
|
timeInForceIsRequired = False
|
5088
5088
|
priceIsRequired = False
|
5089
|
-
|
5089
|
+
triggerPriceIsRequired = False
|
5090
5090
|
quantityIsRequired = False
|
5091
5091
|
if uppercaseType == 'MARKET':
|
5092
5092
|
quoteOrderQty = self.safe_bool(self.options, 'quoteOrderQty', True)
|
@@ -5109,11 +5109,11 @@ class binance(Exchange, ImplicitAPI):
|
|
5109
5109
|
timeInForceIsRequired = True
|
5110
5110
|
quantityIsRequired = True
|
5111
5111
|
elif (uppercaseType == 'STOP_LOSS') or (uppercaseType == 'TAKE_PROFIT'):
|
5112
|
-
|
5112
|
+
triggerPriceIsRequired = True
|
5113
5113
|
quantityIsRequired = True
|
5114
5114
|
elif (uppercaseType == 'STOP_LOSS_LIMIT') or (uppercaseType == 'TAKE_PROFIT_LIMIT'):
|
5115
5115
|
quantityIsRequired = True
|
5116
|
-
|
5116
|
+
triggerPriceIsRequired = True
|
5117
5117
|
priceIsRequired = True
|
5118
5118
|
timeInForceIsRequired = True
|
5119
5119
|
elif uppercaseType == 'LIMIT_MAKER':
|
@@ -5127,11 +5127,11 @@ class binance(Exchange, ImplicitAPI):
|
|
5127
5127
|
request['price'] = self.price_to_precision(symbol, price)
|
5128
5128
|
if timeInForceIsRequired and (self.safe_string(params, 'timeInForce') is None):
|
5129
5129
|
request['timeInForce'] = self.options['defaultTimeInForce'] # 'GTC' = Good To Cancel(default), 'IOC' = Immediate Or Cancel
|
5130
|
-
if
|
5131
|
-
if
|
5132
|
-
raise InvalidOrder(self.id + ' editOrder() requires a
|
5130
|
+
if triggerPriceIsRequired:
|
5131
|
+
if triggerPrice is None:
|
5132
|
+
raise InvalidOrder(self.id + ' editOrder() requires a triggerPrice extra param for a ' + type + ' order')
|
5133
5133
|
else:
|
5134
|
-
request['stopPrice'] = self.price_to_precision(symbol,
|
5134
|
+
request['stopPrice'] = self.price_to_precision(symbol, triggerPrice)
|
5135
5135
|
request['cancelReplaceMode'] = 'STOP_ON_FAILURE' # If the cancel request fails, the new order placement will not be attempted.
|
5136
5136
|
cancelId = self.safe_string_2(params, 'cancelNewClientOrderId', 'cancelOrigClientOrderId')
|
5137
5137
|
if cancelId is None:
|
@@ -5776,7 +5776,7 @@ class binance(Exchange, ImplicitAPI):
|
|
5776
5776
|
if type == 'limit_maker':
|
5777
5777
|
type = 'limit'
|
5778
5778
|
stopPriceString = self.safe_string(order, 'stopPrice')
|
5779
|
-
|
5779
|
+
triggerPrice = self.parse_number(self.omit_zero(stopPriceString))
|
5780
5780
|
feeCost = self.safe_number(order, 'fee')
|
5781
5781
|
fee = None
|
5782
5782
|
if feeCost is not None:
|
@@ -5800,7 +5800,7 @@ class binance(Exchange, ImplicitAPI):
|
|
5800
5800
|
'reduceOnly': self.safe_bool(order, 'reduceOnly'),
|
5801
5801
|
'side': side,
|
5802
5802
|
'price': price,
|
5803
|
-
'triggerPrice':
|
5803
|
+
'triggerPrice': triggerPrice,
|
5804
5804
|
'amount': amount,
|
5805
5805
|
'cost': cost,
|
5806
5806
|
'average': average,
|
@@ -6072,7 +6072,7 @@ class binance(Exchange, ImplicitAPI):
|
|
6072
6072
|
validOrderTypes = self.safe_list(market['info'], 'orderTypes')
|
6073
6073
|
if not self.in_array(uppercaseType, validOrderTypes):
|
6074
6074
|
if initialUppercaseType != uppercaseType:
|
6075
|
-
raise InvalidOrder(self.id + '
|
6075
|
+
raise InvalidOrder(self.id + ' triggerPrice parameter is not allowed for ' + symbol + ' ' + type + ' orders')
|
6076
6076
|
else:
|
6077
6077
|
raise InvalidOrder(self.id + ' ' + type + ' is not a valid order type for the ' + symbol + ' market')
|
6078
6078
|
clientOrderIdRequest = 'newClientStrategyId' if isPortfolioMarginConditional else 'newClientOrderId'
|
@@ -6111,7 +6111,7 @@ class binance(Exchange, ImplicitAPI):
|
|
6111
6111
|
closePosition = self.safe_bool(params, 'closePosition', False)
|
6112
6112
|
timeInForceIsRequired = False
|
6113
6113
|
priceIsRequired = False
|
6114
|
-
|
6114
|
+
triggerPriceIsRequired = False
|
6115
6115
|
quantityIsRequired = False
|
6116
6116
|
#
|
6117
6117
|
# spot/margin
|
@@ -6157,13 +6157,13 @@ class binance(Exchange, ImplicitAPI):
|
|
6157
6157
|
timeInForceIsRequired = True
|
6158
6158
|
quantityIsRequired = True
|
6159
6159
|
elif (uppercaseType == 'STOP_LOSS') or (uppercaseType == 'TAKE_PROFIT'):
|
6160
|
-
|
6160
|
+
triggerPriceIsRequired = True
|
6161
6161
|
quantityIsRequired = True
|
6162
6162
|
if market['linear'] or market['inverse']:
|
6163
6163
|
priceIsRequired = True
|
6164
6164
|
elif (uppercaseType == 'STOP_LOSS_LIMIT') or (uppercaseType == 'TAKE_PROFIT_LIMIT'):
|
6165
6165
|
quantityIsRequired = True
|
6166
|
-
|
6166
|
+
triggerPriceIsRequired = True
|
6167
6167
|
priceIsRequired = True
|
6168
6168
|
timeInForceIsRequired = True
|
6169
6169
|
elif uppercaseType == 'LIMIT_MAKER':
|
@@ -6171,12 +6171,12 @@ class binance(Exchange, ImplicitAPI):
|
|
6171
6171
|
quantityIsRequired = True
|
6172
6172
|
elif uppercaseType == 'STOP':
|
6173
6173
|
quantityIsRequired = True
|
6174
|
-
|
6174
|
+
triggerPriceIsRequired = True
|
6175
6175
|
priceIsRequired = True
|
6176
6176
|
elif (uppercaseType == 'STOP_MARKET') or (uppercaseType == 'TAKE_PROFIT_MARKET'):
|
6177
6177
|
if not closePosition:
|
6178
6178
|
quantityIsRequired = True
|
6179
|
-
|
6179
|
+
triggerPriceIsRequired = True
|
6180
6180
|
elif uppercaseType == 'TRAILING_STOP_MARKET':
|
6181
6181
|
if not closePosition:
|
6182
6182
|
quantityIsRequired = True
|
@@ -6202,14 +6202,14 @@ class binance(Exchange, ImplicitAPI):
|
|
6202
6202
|
request['price'] = self.price_to_precision(symbol, price)
|
6203
6203
|
else:
|
6204
6204
|
request['price'] = self.parse_to_numeric(price) # some options don't have the precision available
|
6205
|
-
if
|
6205
|
+
if triggerPriceIsRequired:
|
6206
6206
|
if market['contract']:
|
6207
6207
|
if stopPrice is None:
|
6208
|
-
raise InvalidOrder(self.id + ' createOrder() requires a
|
6208
|
+
raise InvalidOrder(self.id + ' createOrder() requires a triggerPrice extra param for a ' + type + ' order')
|
6209
6209
|
else:
|
6210
6210
|
# check for delta price
|
6211
6211
|
if trailingDelta is None and stopPrice is None and trailingPercent is None:
|
6212
|
-
raise InvalidOrder(self.id + ' createOrder() requires a
|
6212
|
+
raise InvalidOrder(self.id + ' createOrder() requires a triggerPrice, trailingDelta or trailingPercent param for a ' + type + ' order')
|
6213
6213
|
if stopPrice is not None:
|
6214
6214
|
request['stopPrice'] = self.price_to_precision(symbol, stopPrice)
|
6215
6215
|
if timeInForceIsRequired and (self.safe_string(params, 'timeInForce') is None) and (self.safe_string(request, 'timeInForce') is None):
|
@@ -10888,7 +10888,7 @@ class binance(Exchange, ImplicitAPI):
|
|
10888
10888
|
paginate = False
|
10889
10889
|
paginate, params = self.handle_option_and_params(params, 'fetchLedger', 'paginate')
|
10890
10890
|
if paginate:
|
10891
|
-
return await self.fetch_paginated_call_dynamic('fetchLedger', code, since, limit, params)
|
10891
|
+
return await self.fetch_paginated_call_dynamic('fetchLedger', code, since, limit, params, None, False)
|
10892
10892
|
type = None
|
10893
10893
|
subType = None
|
10894
10894
|
currency = None
|
@@ -11963,7 +11963,7 @@ class binance(Exchange, ImplicitAPI):
|
|
11963
11963
|
# ...
|
11964
11964
|
# ]
|
11965
11965
|
#
|
11966
|
-
return self.
|
11966
|
+
return self.parse_open_interests_history(response, market, since, limit)
|
11967
11967
|
|
11968
11968
|
async def fetch_open_interest(self, symbol: str, params={}):
|
11969
11969
|
"""
|
@@ -12026,7 +12026,7 @@ class binance(Exchange, ImplicitAPI):
|
|
12026
12026
|
#
|
12027
12027
|
if market['option']:
|
12028
12028
|
symbol = market['symbol']
|
12029
|
-
result = self.
|
12029
|
+
result = self.parse_open_interests_history(response, market)
|
12030
12030
|
for i in range(0, len(result)):
|
12031
12031
|
item = result[i]
|
12032
12032
|
if item['symbol'] == symbol:
|
ccxt/async_support/bingx.py
CHANGED
@@ -64,6 +64,7 @@ class bingx(Exchange, ImplicitAPI):
|
|
64
64
|
'createTrailingAmountOrder': True,
|
65
65
|
'createTrailingPercentOrder': True,
|
66
66
|
'createTriggerOrder': True,
|
67
|
+
'editOrder': True,
|
67
68
|
'fetchBalance': True,
|
68
69
|
'fetchCanceledOrders': True,
|
69
70
|
'fetchClosedOrders': True,
|
@@ -86,6 +87,7 @@ class bingx(Exchange, ImplicitAPI):
|
|
86
87
|
'fetchMarkPrice': True,
|
87
88
|
'fetchMarkPrices': True,
|
88
89
|
'fetchMyLiquidations': True,
|
90
|
+
'fetchMyTrades': True,
|
89
91
|
'fetchOHLCV': True,
|
90
92
|
'fetchOpenInterest': True,
|
91
93
|
'fetchOpenOrders': True,
|
@@ -1037,7 +1039,7 @@ class bingx(Exchange, ImplicitAPI):
|
|
1037
1039
|
}
|
1038
1040
|
request['interval'] = self.safe_string(self.timeframes, timeframe, timeframe)
|
1039
1041
|
if since is not None:
|
1040
|
-
request['startTime'] = since
|
1042
|
+
request['startTime'] = max(since - 1, 0)
|
1041
1043
|
if limit is not None:
|
1042
1044
|
request['limit'] = limit
|
1043
1045
|
until = self.safe_integer_2(params, 'until', 'endTime')
|
ccxt/async_support/bitfinex.py
CHANGED
@@ -3225,7 +3225,7 @@ class bitfinex(Exchange, ImplicitAPI):
|
|
3225
3225
|
# ],
|
3226
3226
|
# ]
|
3227
3227
|
#
|
3228
|
-
return self.
|
3228
|
+
return self.parse_open_interests_history(response, market, since, limit)
|
3229
3229
|
|
3230
3230
|
def parse_open_interest(self, interest, market: Market = None):
|
3231
3231
|
#
|
ccxt/async_support/bitget.py
CHANGED
@@ -1265,6 +1265,7 @@ class bitget(Exchange, ImplicitAPI):
|
|
1265
1265
|
'41103': InvalidOrder, # {"code":"41103","msg":"param price scale error error","requestTime":1725635883561,"data":null}
|
1266
1266
|
'41114': OnMaintenance, # {"code":"41114","msg":"The current trading pair is under maintenance, please refer to the official announcement for the opening time","requestTime":1679196062544,"data":null}
|
1267
1267
|
'43011': InvalidOrder, # The parameter does not meet the specification executePrice <= 0
|
1268
|
+
'43001': OrderNotFound,
|
1268
1269
|
'43012': InsufficientFunds, # {"code":"43012","msg":"Insufficient balance","requestTime":1711648951774,"data":null}
|
1269
1270
|
'43025': InvalidOrder, # Plan order does not exist
|
1270
1271
|
'43115': OnMaintenance, # {"code":"43115","msg":"The current trading pair is opening soon, please refer to the official announcement for the opening time","requestTime":1688907202434,"data":null}
|
ccxt/async_support/bitmart.py
CHANGED
@@ -6,7 +6,7 @@
|
|
6
6
|
from ccxt.async_support.base.exchange import Exchange
|
7
7
|
from ccxt.abstract.bitmart import ImplicitAPI
|
8
8
|
import hashlib
|
9
|
-
from ccxt.base.types import Balances, BorrowInterest, Currencies, Currency, DepositAddress, Int, IsolatedBorrowRate, IsolatedBorrowRates, Market, Num, Order, OrderBook, OrderRequest, OrderSide, OrderType, Str, Strings, Ticker, Tickers, FundingRate, Trade, TradingFeeInterface, Transaction, TransferEntry
|
9
|
+
from ccxt.base.types import Balances, BorrowInterest, Currencies, Currency, DepositAddress, FundingHistory, Int, IsolatedBorrowRate, IsolatedBorrowRates, LedgerEntry, Market, Num, Order, OrderBook, OrderRequest, OrderSide, OrderType, Str, Strings, Ticker, Tickers, FundingRate, Trade, TradingFeeInterface, Transaction, TransferEntry
|
10
10
|
from typing import List
|
11
11
|
from ccxt.base.errors import ExchangeError
|
12
12
|
from ccxt.base.errors import AuthenticationError
|
@@ -81,12 +81,13 @@ class bitmart(Exchange, ImplicitAPI):
|
|
81
81
|
'fetchDeposits': True,
|
82
82
|
'fetchDepositWithdrawFee': True,
|
83
83
|
'fetchDepositWithdrawFees': False,
|
84
|
-
'fetchFundingHistory':
|
84
|
+
'fetchFundingHistory': True,
|
85
85
|
'fetchFundingRate': True,
|
86
86
|
'fetchFundingRateHistory': False,
|
87
87
|
'fetchFundingRates': False,
|
88
88
|
'fetchIsolatedBorrowRate': True,
|
89
89
|
'fetchIsolatedBorrowRates': True,
|
90
|
+
'fetchLedger': True,
|
90
91
|
'fetchLiquidations': False,
|
91
92
|
'fetchMarginMode': False,
|
92
93
|
'fetchMarkets': True,
|
@@ -173,6 +174,7 @@ class bitmart(Exchange, ImplicitAPI):
|
|
173
174
|
'contract/public/depth': 5,
|
174
175
|
'contract/public/open-interest': 30,
|
175
176
|
'contract/public/funding-rate': 30,
|
177
|
+
'contract/public/funding-rate-history': 30,
|
176
178
|
'contract/public/kline': 6, # should be 5 but errors
|
177
179
|
'account/v1/currencies': 30,
|
178
180
|
},
|
@@ -223,6 +225,7 @@ class bitmart(Exchange, ImplicitAPI):
|
|
223
225
|
'contract/private/position-risk': 10,
|
224
226
|
'contract/private/affilate/rebate-list': 10,
|
225
227
|
'contract/private/affilate/trade-list': 10,
|
228
|
+
'contract/private/transaction-history': 10,
|
226
229
|
},
|
227
230
|
'post': {
|
228
231
|
# sub-account endpoints
|
@@ -4375,6 +4378,62 @@ class bitmart(Exchange, ImplicitAPI):
|
|
4375
4378
|
data = self.safe_dict(response, 'data', {})
|
4376
4379
|
return self.parse_funding_rate(data, market)
|
4377
4380
|
|
4381
|
+
async def fetch_funding_rate_history(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
|
4382
|
+
"""
|
4383
|
+
fetches historical funding rate prices
|
4384
|
+
|
4385
|
+
https://developer-pro.bitmart.com/en/futuresv2/#get-funding-rate-history
|
4386
|
+
|
4387
|
+
:param str symbol: unified symbol of the market to fetch the funding rate history for
|
4388
|
+
:param int [since]: timestamp in ms of the earliest funding rate to fetch
|
4389
|
+
:param int [limit]: the maximum amount of funding rate structures to fetch
|
4390
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
4391
|
+
:returns dict[]: a list of `funding rate structures <https://docs.ccxt.com/#/?id=funding-rate-history-structure>`
|
4392
|
+
"""
|
4393
|
+
if symbol is None:
|
4394
|
+
raise ArgumentsRequired(self.id + ' fetchFundingRateHistory() requires a symbol argument')
|
4395
|
+
await self.load_markets()
|
4396
|
+
market = self.market(symbol)
|
4397
|
+
request: dict = {
|
4398
|
+
'symbol': market['id'],
|
4399
|
+
}
|
4400
|
+
if limit is not None:
|
4401
|
+
request['limit'] = limit
|
4402
|
+
response = await self.publicGetContractPublicFundingRateHistory(self.extend(request, params))
|
4403
|
+
#
|
4404
|
+
# {
|
4405
|
+
# "code": 1000,
|
4406
|
+
# "message": "Ok",
|
4407
|
+
# "data": {
|
4408
|
+
# "list": [
|
4409
|
+
# {
|
4410
|
+
# "symbol": "BTCUSDT",
|
4411
|
+
# "funding_rate": "0.000091412174",
|
4412
|
+
# "funding_time": "1734336000000"
|
4413
|
+
# },
|
4414
|
+
# ]
|
4415
|
+
# },
|
4416
|
+
# "trace": "fg73d949fgfdf6a40c8fc7f5ae6738.54.345345345345"
|
4417
|
+
# }
|
4418
|
+
#
|
4419
|
+
data = self.safe_dict(response, 'data', {})
|
4420
|
+
result = self.safe_list(data, 'list', [])
|
4421
|
+
rates = []
|
4422
|
+
for i in range(0, len(result)):
|
4423
|
+
entry = result[i]
|
4424
|
+
marketId = self.safe_string(entry, 'symbol')
|
4425
|
+
symbolInner = self.safe_symbol(marketId, market, '-', 'swap')
|
4426
|
+
timestamp = self.safe_integer(entry, 'funding_time')
|
4427
|
+
rates.append({
|
4428
|
+
'info': entry,
|
4429
|
+
'symbol': symbolInner,
|
4430
|
+
'fundingRate': self.safe_number(entry, 'funding_rate'),
|
4431
|
+
'timestamp': timestamp,
|
4432
|
+
'datetime': self.iso8601(timestamp),
|
4433
|
+
})
|
4434
|
+
sorted = self.sort_by(rates, 'timestamp')
|
4435
|
+
return self.filter_by_symbol_since_limit(sorted, market['symbol'], since, limit)
|
4436
|
+
|
4378
4437
|
def parse_funding_rate(self, contract, market: Market = None) -> FundingRate:
|
4379
4438
|
#
|
4380
4439
|
# {
|
@@ -4788,6 +4847,188 @@ class bitmart(Exchange, ImplicitAPI):
|
|
4788
4847
|
data = self.safe_dict(response, 'data', {})
|
4789
4848
|
return self.parse_order(data, market)
|
4790
4849
|
|
4850
|
+
async def fetch_ledger(self, code: Str = None, since: Int = None, limit: Int = None, params={}) -> List[LedgerEntry]:
|
4851
|
+
"""
|
4852
|
+
fetch the history of changes, actions done by the user or operations that altered the balance of the user
|
4853
|
+
|
4854
|
+
https://developer-pro.bitmart.com/en/futuresv2/#get-transaction-history-keyed
|
4855
|
+
|
4856
|
+
:param str [code]: unified currency code
|
4857
|
+
:param int [since]: timestamp in ms of the earliest ledger entry
|
4858
|
+
:param int [limit]: max number of ledger entries to return
|
4859
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
4860
|
+
:param int [params.until]: timestamp in ms of the latest ledger entry
|
4861
|
+
:returns dict[]: a list of `ledger structures <https://docs.ccxt.com/#/?id=ledger>`
|
4862
|
+
"""
|
4863
|
+
await self.load_markets()
|
4864
|
+
currency = None
|
4865
|
+
if code is not None:
|
4866
|
+
currency = self.currency(code)
|
4867
|
+
request: dict = {}
|
4868
|
+
request, params = self.handle_until_option('end_time', request, params)
|
4869
|
+
transactionsRequest = self.fetch_transactions_request(0, None, since, limit, params)
|
4870
|
+
response = await self.privateGetContractPrivateTransactionHistory(transactionsRequest)
|
4871
|
+
#
|
4872
|
+
# {
|
4873
|
+
# "code": 1000,
|
4874
|
+
# "message": "Ok",
|
4875
|
+
# "data": [
|
4876
|
+
# {
|
4877
|
+
# "time": "1734422402121",
|
4878
|
+
# "type": "Funding Fee",
|
4879
|
+
# "amount": "-0.00008253",
|
4880
|
+
# "asset": "USDT",
|
4881
|
+
# "symbol": "LTCUSDT",
|
4882
|
+
# "tran_id": "1734422402121",
|
4883
|
+
# "flow_type": 3
|
4884
|
+
# },
|
4885
|
+
# ],
|
4886
|
+
# "trace": "4cd11f83c71egfhfgh842790f07241e.23.173442343427772866"
|
4887
|
+
# }
|
4888
|
+
#
|
4889
|
+
data = self.safe_list(response, 'data', [])
|
4890
|
+
return self.parse_ledger(data, currency, since, limit)
|
4891
|
+
|
4892
|
+
def parse_ledger_entry(self, item: dict, currency: Currency = None) -> LedgerEntry:
|
4893
|
+
#
|
4894
|
+
# {
|
4895
|
+
# "time": "1734422402121",
|
4896
|
+
# "type": "Funding Fee",
|
4897
|
+
# "amount": "-0.00008253",
|
4898
|
+
# "asset": "USDT",
|
4899
|
+
# "symbol": "LTCUSDT",
|
4900
|
+
# "tran_id": "1734422402121",
|
4901
|
+
# "flow_type": 3
|
4902
|
+
# }
|
4903
|
+
#
|
4904
|
+
amount = self.safe_string(item, 'amount')
|
4905
|
+
direction = None
|
4906
|
+
if Precise.string_le(amount, '0'):
|
4907
|
+
direction = 'out'
|
4908
|
+
amount = Precise.string_mul('-1', amount)
|
4909
|
+
else:
|
4910
|
+
direction = 'in'
|
4911
|
+
currencyId = self.safe_string(item, 'asset')
|
4912
|
+
timestamp = self.safe_integer(item, 'time')
|
4913
|
+
type = self.safe_string(item, 'type')
|
4914
|
+
return self.safe_ledger_entry({
|
4915
|
+
'info': item,
|
4916
|
+
'id': self.safe_string(item, 'tran_id'),
|
4917
|
+
'direction': direction,
|
4918
|
+
'account': None,
|
4919
|
+
'referenceAccount': None,
|
4920
|
+
'referenceId': self.safe_string(item, 'tradeId'),
|
4921
|
+
'type': self.parse_ledger_entry_type(type),
|
4922
|
+
'currency': self.safe_currency_code(currencyId, currency),
|
4923
|
+
'amount': self.parse_number(amount),
|
4924
|
+
'timestamp': timestamp,
|
4925
|
+
'datetime': self.iso8601(timestamp),
|
4926
|
+
'before': None,
|
4927
|
+
'after': None,
|
4928
|
+
'status': None,
|
4929
|
+
'fee': None,
|
4930
|
+
}, currency)
|
4931
|
+
|
4932
|
+
def parse_ledger_entry_type(self, type):
|
4933
|
+
ledgerType: dict = {
|
4934
|
+
'Commission Fee': 'fee',
|
4935
|
+
'Funding Fee': 'fee',
|
4936
|
+
'Realized PNL': 'trade',
|
4937
|
+
'Transfer': 'transfer',
|
4938
|
+
'Liquidation Clearance': 'settlement',
|
4939
|
+
}
|
4940
|
+
return self.safe_string(ledgerType, type, type)
|
4941
|
+
|
4942
|
+
def fetch_transactions_request(self, flowType: Int = None, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
|
4943
|
+
request: dict = {}
|
4944
|
+
if flowType is not None:
|
4945
|
+
request['flow_type'] = flowType
|
4946
|
+
market = None
|
4947
|
+
if symbol is not None:
|
4948
|
+
market = self.market(symbol)
|
4949
|
+
request['symbol'] = market['id']
|
4950
|
+
if since is not None:
|
4951
|
+
request['start_time'] = since
|
4952
|
+
if limit is not None:
|
4953
|
+
request['page_size'] = limit
|
4954
|
+
request, params = self.handle_until_option('end_time', request, params)
|
4955
|
+
return self.extend(request, params)
|
4956
|
+
|
4957
|
+
async def fetch_funding_history(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[FundingHistory]:
|
4958
|
+
"""
|
4959
|
+
fetch the history of funding payments paid and received on self account
|
4960
|
+
|
4961
|
+
https://developer-pro.bitmart.com/en/futuresv2/#get-transaction-history-keyed
|
4962
|
+
|
4963
|
+
:param str [symbol]: unified market symbol
|
4964
|
+
:param int [since]: the starting timestamp in milliseconds
|
4965
|
+
:param int [limit]: the number of entries to return
|
4966
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
4967
|
+
:param int [params.until]: the latest time in ms to fetch funding history for
|
4968
|
+
:returns dict[]: a list of `funding history structures <https://docs.ccxt.com/#/?id=funding-history-structure>`
|
4969
|
+
"""
|
4970
|
+
await self.load_markets()
|
4971
|
+
market = None
|
4972
|
+
if symbol is not None:
|
4973
|
+
market = self.market(symbol)
|
4974
|
+
request: dict = {}
|
4975
|
+
request, params = self.handle_until_option('end_time', request, params)
|
4976
|
+
transactionsRequest = self.fetch_transactions_request(3, symbol, since, limit, params)
|
4977
|
+
response = await self.privateGetContractPrivateTransactionHistory(transactionsRequest)
|
4978
|
+
#
|
4979
|
+
# {
|
4980
|
+
# "code": 1000,
|
4981
|
+
# "message": "Ok",
|
4982
|
+
# "data": [
|
4983
|
+
# {
|
4984
|
+
# "time": "1734422402121",
|
4985
|
+
# "type": "Funding Fee",
|
4986
|
+
# "amount": "-0.00008253",
|
4987
|
+
# "asset": "USDT",
|
4988
|
+
# "symbol": "LTCUSDT",
|
4989
|
+
# "tran_id": "1734422402121",
|
4990
|
+
# "flow_type": 3
|
4991
|
+
# },
|
4992
|
+
# ],
|
4993
|
+
# "trace": "4cd11f83c71egfhfgh842790f07241e.23.173442343427772866"
|
4994
|
+
# }
|
4995
|
+
#
|
4996
|
+
data = self.safe_list(response, 'data', [])
|
4997
|
+
return self.parse_funding_histories(data, market, since, limit)
|
4998
|
+
|
4999
|
+
def parse_funding_history(self, contract, market: Market = None):
|
5000
|
+
#
|
5001
|
+
# {
|
5002
|
+
# "time": "1734422402121",
|
5003
|
+
# "type": "Funding Fee",
|
5004
|
+
# "amount": "-0.00008253",
|
5005
|
+
# "asset": "USDT",
|
5006
|
+
# "symbol": "LTCUSDT",
|
5007
|
+
# "tran_id": "1734422402121",
|
5008
|
+
# "flow_type": 3
|
5009
|
+
# }
|
5010
|
+
#
|
5011
|
+
marketId = self.safe_string(contract, 'symbol')
|
5012
|
+
currencyId = self.safe_string(contract, 'asset')
|
5013
|
+
timestamp = self.safe_integer(contract, 'time')
|
5014
|
+
return {
|
5015
|
+
'info': contract,
|
5016
|
+
'symbol': self.safe_symbol(marketId, market, None, 'swap'),
|
5017
|
+
'code': self.safe_currency_code(currencyId),
|
5018
|
+
'timestamp': timestamp,
|
5019
|
+
'datetime': self.iso8601(timestamp),
|
5020
|
+
'id': self.safe_string(contract, 'tran_id'),
|
5021
|
+
'amount': self.safe_number(contract, 'amount'),
|
5022
|
+
}
|
5023
|
+
|
5024
|
+
def parse_funding_histories(self, contracts, market=None, since: Int = None, limit: Int = None) -> List[FundingHistory]:
|
5025
|
+
result = []
|
5026
|
+
for i in range(0, len(contracts)):
|
5027
|
+
contract = contracts[i]
|
5028
|
+
result.append(self.parse_funding_history(contract, market))
|
5029
|
+
sorted = self.sort_by(result, 'timestamp')
|
5030
|
+
return self.filter_by_since_limit(sorted, since, limit)
|
5031
|
+
|
4791
5032
|
def nonce(self):
|
4792
5033
|
return self.milliseconds()
|
4793
5034
|
|