ccxt 4.4.40__py2.py3-none-any.whl → 4.4.42__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/binance.py +3 -0
- ccxt/abstract/binancecoinm.py +3 -0
- ccxt/abstract/binanceus.py +3 -0
- ccxt/abstract/binanceusdm.py +3 -0
- ccxt/abstract/bitmart.py +2 -0
- ccxt/abstract/okx.py +5 -0
- ccxt/ace.py +1 -1
- ccxt/alpaca.py +0 -1
- ccxt/ascendex.py +0 -1
- ccxt/async_support/__init__.py +1 -1
- ccxt/async_support/ace.py +1 -1
- ccxt/async_support/alpaca.py +0 -1
- ccxt/async_support/ascendex.py +0 -1
- ccxt/async_support/base/exchange.py +24 -17
- ccxt/async_support/bigone.py +0 -1
- ccxt/async_support/binance.py +27 -24
- ccxt/async_support/bingx.py +5 -1
- ccxt/async_support/bitfinex.py +123 -1
- ccxt/async_support/bitget.py +1 -0
- ccxt/async_support/bitmart.py +243 -2
- ccxt/async_support/blofin.py +16 -7
- ccxt/async_support/bybit.py +8 -8
- ccxt/async_support/cex.py +1 -1
- ccxt/async_support/coinbase.py +8 -9
- ccxt/async_support/coinbaseexchange.py +5 -6
- ccxt/async_support/coinbaseinternational.py +7 -8
- ccxt/async_support/coincatch.py +0 -1
- ccxt/async_support/coincheck.py +0 -1
- ccxt/async_support/coinex.py +91 -6
- ccxt/async_support/coinlist.py +3 -4
- ccxt/async_support/coinmate.py +1 -3
- ccxt/async_support/coinmetro.py +4 -5
- ccxt/async_support/coinone.py +0 -1
- ccxt/async_support/coinsph.py +7 -8
- ccxt/async_support/cryptocom.py +3 -0
- ccxt/async_support/currencycom.py +3 -4
- ccxt/async_support/defx.py +6 -7
- ccxt/async_support/deribit.py +1 -3
- ccxt/async_support/digifinex.py +0 -1
- ccxt/async_support/ellipx.py +0 -2
- ccxt/async_support/exmo.py +61 -6
- ccxt/async_support/gate.py +2 -3
- ccxt/async_support/gemini.py +4 -5
- ccxt/async_support/hashkey.py +79 -67
- ccxt/async_support/hitbtc.py +47 -5
- ccxt/async_support/hollaex.py +4 -6
- ccxt/async_support/htx.py +2 -4
- ccxt/async_support/huobijp.py +0 -1
- ccxt/async_support/hyperliquid.py +60 -1
- ccxt/async_support/idex.py +8 -8
- ccxt/async_support/independentreserve.py +0 -1
- ccxt/async_support/indodax.py +0 -1
- ccxt/async_support/kraken.py +186 -28
- ccxt/async_support/krakenfutures.py +75 -3
- ccxt/async_support/kucoin.py +6 -4
- ccxt/async_support/kucoinfutures.py +10 -9
- ccxt/async_support/kuna.py +1 -3
- ccxt/async_support/latoken.py +1 -3
- ccxt/async_support/lbank.py +0 -1
- ccxt/async_support/luno.py +0 -1
- ccxt/async_support/lykke.py +0 -1
- ccxt/async_support/mercado.py +0 -1
- ccxt/async_support/mexc.py +6 -7
- ccxt/async_support/ndax.py +1 -1
- ccxt/async_support/novadax.py +4 -6
- ccxt/async_support/oceanex.py +0 -1
- ccxt/async_support/okcoin.py +1 -3
- ccxt/async_support/okx.py +7 -4
- ccxt/async_support/onetrading.py +1 -3
- ccxt/async_support/p2b.py +1 -1
- ccxt/async_support/paradex.py +5 -7
- ccxt/async_support/phemex.py +8 -10
- ccxt/async_support/poloniex.py +1 -3
- ccxt/async_support/poloniexfutures.py +6 -6
- ccxt/async_support/probit.py +0 -1
- ccxt/async_support/timex.py +0 -1
- ccxt/async_support/tokocrypto.py +11 -14
- ccxt/async_support/tradeogre.py +1 -1
- ccxt/async_support/upbit.py +0 -1
- ccxt/async_support/wavesexchange.py +4 -5
- ccxt/async_support/whitebit.py +8 -9
- ccxt/async_support/woo.py +98 -12
- ccxt/async_support/woofipro.py +96 -15
- ccxt/async_support/xt.py +6 -3
- ccxt/async_support/yobit.py +0 -1
- ccxt/async_support/zaif.py +0 -1
- ccxt/async_support/zonda.py +1 -2
- ccxt/base/exchange.py +39 -20
- ccxt/base/types.py +10 -0
- ccxt/bigone.py +0 -1
- ccxt/binance.py +27 -24
- ccxt/bingx.py +5 -1
- ccxt/bitfinex.py +123 -1
- ccxt/bitget.py +1 -0
- ccxt/bitmart.py +243 -2
- ccxt/blofin.py +16 -7
- ccxt/bybit.py +8 -8
- ccxt/cex.py +1 -1
- ccxt/coinbase.py +8 -9
- ccxt/coinbaseexchange.py +5 -6
- ccxt/coinbaseinternational.py +7 -8
- ccxt/coincatch.py +0 -1
- ccxt/coincheck.py +0 -1
- ccxt/coinex.py +91 -6
- ccxt/coinlist.py +3 -4
- ccxt/coinmate.py +1 -3
- ccxt/coinmetro.py +4 -5
- ccxt/coinone.py +0 -1
- ccxt/coinsph.py +7 -8
- ccxt/cryptocom.py +3 -0
- ccxt/currencycom.py +3 -4
- ccxt/defx.py +6 -7
- ccxt/deribit.py +1 -3
- ccxt/digifinex.py +0 -1
- ccxt/ellipx.py +0 -2
- ccxt/exmo.py +61 -6
- ccxt/gate.py +2 -3
- ccxt/gemini.py +4 -5
- ccxt/hashkey.py +79 -67
- ccxt/hitbtc.py +47 -5
- ccxt/hollaex.py +4 -6
- ccxt/htx.py +2 -4
- ccxt/huobijp.py +0 -1
- ccxt/hyperliquid.py +60 -1
- ccxt/idex.py +8 -8
- ccxt/independentreserve.py +0 -1
- ccxt/indodax.py +0 -1
- ccxt/kraken.py +186 -28
- ccxt/krakenfutures.py +75 -3
- ccxt/kucoin.py +6 -4
- ccxt/kucoinfutures.py +10 -9
- ccxt/kuna.py +1 -3
- ccxt/latoken.py +1 -3
- ccxt/lbank.py +0 -1
- ccxt/luno.py +0 -1
- ccxt/lykke.py +0 -1
- ccxt/mercado.py +0 -1
- ccxt/mexc.py +6 -7
- ccxt/ndax.py +1 -1
- ccxt/novadax.py +4 -6
- ccxt/oceanex.py +0 -1
- ccxt/okcoin.py +1 -3
- ccxt/okx.py +7 -4
- ccxt/onetrading.py +1 -3
- ccxt/p2b.py +1 -1
- ccxt/paradex.py +5 -7
- ccxt/phemex.py +8 -10
- ccxt/poloniex.py +1 -3
- ccxt/poloniexfutures.py +6 -6
- ccxt/pro/__init__.py +1 -1
- ccxt/probit.py +0 -1
- ccxt/timex.py +0 -1
- ccxt/tokocrypto.py +11 -14
- ccxt/tradeogre.py +1 -1
- ccxt/upbit.py +0 -1
- ccxt/wavesexchange.py +4 -5
- ccxt/whitebit.py +8 -9
- ccxt/woo.py +98 -12
- ccxt/woofipro.py +96 -15
- ccxt/xt.py +6 -3
- ccxt/yobit.py +0 -1
- ccxt/zaif.py +0 -1
- ccxt/zonda.py +1 -2
- {ccxt-4.4.40.dist-info → ccxt-4.4.42.dist-info}/METADATA +5 -5
- {ccxt-4.4.40.dist-info → ccxt-4.4.42.dist-info}/RECORD +169 -173
- ccxt/bitbay.py +0 -17
- ccxt/bitfinex2.py +0 -3624
- ccxt/hitbtc3.py +0 -16
- ccxt/pro/bitfinex2.py +0 -1086
- {ccxt-4.4.40.dist-info → ccxt-4.4.42.dist-info}/LICENSE.txt +0 -0
- {ccxt-4.4.40.dist-info → ccxt-4.4.42.dist-info}/WHEEL +0 -0
- {ccxt-4.4.40.dist-info → ccxt-4.4.42.dist-info}/top_level.txt +0 -0
ccxt/binance.py
CHANGED
@@ -657,6 +657,8 @@ class binance(Exchange, ImplicitAPI):
|
|
657
657
|
'portfolio/bnb-transfer': 150, # Weight(IP): 1500 => cost = 0.1 * 1500 = 150
|
658
658
|
'portfolio/repay-futures-switch': 150, # Weight(IP): 1500 => cost = 0.1 * 1500 = 150
|
659
659
|
'portfolio/repay-futures-negative-balance': 150, # Weight(IP): 1500 => cost = 0.1 * 1500 = 150
|
660
|
+
'portfolio/mint': 20,
|
661
|
+
'portfolio/redeem': 20,
|
660
662
|
'lending/auto-invest/plan/add': 0.1, # Weight(IP): 1 => cost = 0.1 * 1 = 0.1
|
661
663
|
'lending/auto-invest/plan/edit': 0.1, # Weight(IP): 1 => cost = 0.1 * 1 = 0.1
|
662
664
|
'lending/auto-invest/plan/edit-status': 0.1, # Weight(IP): 1 => cost = 0.1 * 1 = 0.1
|
@@ -985,6 +987,7 @@ class binance(Exchange, ImplicitAPI):
|
|
985
987
|
'block/order/orders': 5,
|
986
988
|
'block/order/execute': 5,
|
987
989
|
'block/user-trades': 5,
|
990
|
+
'blockTrades': 5,
|
988
991
|
},
|
989
992
|
'post': {
|
990
993
|
'order': 1,
|
@@ -5062,8 +5065,8 @@ class binance(Exchange, ImplicitAPI):
|
|
5062
5065
|
if postOnly:
|
5063
5066
|
uppercaseType = 'LIMIT_MAKER'
|
5064
5067
|
request['type'] = uppercaseType
|
5065
|
-
|
5066
|
-
if
|
5068
|
+
triggerPrice = self.safe_number_2(params, 'stopPrice', 'triggerPrice')
|
5069
|
+
if triggerPrice is not None:
|
5067
5070
|
if uppercaseType == 'MARKET':
|
5068
5071
|
uppercaseType = 'STOP_LOSS'
|
5069
5072
|
elif uppercaseType == 'LIMIT':
|
@@ -5071,7 +5074,7 @@ class binance(Exchange, ImplicitAPI):
|
|
5071
5074
|
validOrderTypes = self.safe_list(market['info'], 'orderTypes')
|
5072
5075
|
if not self.in_array(uppercaseType, validOrderTypes):
|
5073
5076
|
if initialUppercaseType != uppercaseType:
|
5074
|
-
raise InvalidOrder(self.id + '
|
5077
|
+
raise InvalidOrder(self.id + ' triggerPrice parameter is not allowed for ' + symbol + ' ' + type + ' orders')
|
5075
5078
|
else:
|
5076
5079
|
raise InvalidOrder(self.id + ' ' + type + ' is not a valid order type for the ' + symbol + ' market')
|
5077
5080
|
if clientOrderId is None:
|
@@ -5085,7 +5088,7 @@ class binance(Exchange, ImplicitAPI):
|
|
5085
5088
|
request['newOrderRespType'] = self.safe_value(self.options['newOrderRespType'], type, 'RESULT') # 'ACK' for order id, 'RESULT' for full order or 'FULL' for order with fills
|
5086
5089
|
timeInForceIsRequired = False
|
5087
5090
|
priceIsRequired = False
|
5088
|
-
|
5091
|
+
triggerPriceIsRequired = False
|
5089
5092
|
quantityIsRequired = False
|
5090
5093
|
if uppercaseType == 'MARKET':
|
5091
5094
|
quoteOrderQty = self.safe_bool(self.options, 'quoteOrderQty', True)
|
@@ -5108,11 +5111,11 @@ class binance(Exchange, ImplicitAPI):
|
|
5108
5111
|
timeInForceIsRequired = True
|
5109
5112
|
quantityIsRequired = True
|
5110
5113
|
elif (uppercaseType == 'STOP_LOSS') or (uppercaseType == 'TAKE_PROFIT'):
|
5111
|
-
|
5114
|
+
triggerPriceIsRequired = True
|
5112
5115
|
quantityIsRequired = True
|
5113
5116
|
elif (uppercaseType == 'STOP_LOSS_LIMIT') or (uppercaseType == 'TAKE_PROFIT_LIMIT'):
|
5114
5117
|
quantityIsRequired = True
|
5115
|
-
|
5118
|
+
triggerPriceIsRequired = True
|
5116
5119
|
priceIsRequired = True
|
5117
5120
|
timeInForceIsRequired = True
|
5118
5121
|
elif uppercaseType == 'LIMIT_MAKER':
|
@@ -5126,11 +5129,11 @@ class binance(Exchange, ImplicitAPI):
|
|
5126
5129
|
request['price'] = self.price_to_precision(symbol, price)
|
5127
5130
|
if timeInForceIsRequired and (self.safe_string(params, 'timeInForce') is None):
|
5128
5131
|
request['timeInForce'] = self.options['defaultTimeInForce'] # 'GTC' = Good To Cancel(default), 'IOC' = Immediate Or Cancel
|
5129
|
-
if
|
5130
|
-
if
|
5131
|
-
raise InvalidOrder(self.id + ' editOrder() requires a
|
5132
|
+
if triggerPriceIsRequired:
|
5133
|
+
if triggerPrice is None:
|
5134
|
+
raise InvalidOrder(self.id + ' editOrder() requires a triggerPrice extra param for a ' + type + ' order')
|
5132
5135
|
else:
|
5133
|
-
request['stopPrice'] = self.price_to_precision(symbol,
|
5136
|
+
request['stopPrice'] = self.price_to_precision(symbol, triggerPrice)
|
5134
5137
|
request['cancelReplaceMode'] = 'STOP_ON_FAILURE' # If the cancel request fails, the new order placement will not be attempted.
|
5135
5138
|
cancelId = self.safe_string_2(params, 'cancelNewClientOrderId', 'cancelOrigClientOrderId')
|
5136
5139
|
if cancelId is None:
|
@@ -5775,7 +5778,7 @@ class binance(Exchange, ImplicitAPI):
|
|
5775
5778
|
if type == 'limit_maker':
|
5776
5779
|
type = 'limit'
|
5777
5780
|
stopPriceString = self.safe_string(order, 'stopPrice')
|
5778
|
-
|
5781
|
+
triggerPrice = self.parse_number(self.omit_zero(stopPriceString))
|
5779
5782
|
feeCost = self.safe_number(order, 'fee')
|
5780
5783
|
fee = None
|
5781
5784
|
if feeCost is not None:
|
@@ -5799,7 +5802,7 @@ class binance(Exchange, ImplicitAPI):
|
|
5799
5802
|
'reduceOnly': self.safe_bool(order, 'reduceOnly'),
|
5800
5803
|
'side': side,
|
5801
5804
|
'price': price,
|
5802
|
-
'triggerPrice':
|
5805
|
+
'triggerPrice': triggerPrice,
|
5803
5806
|
'amount': amount,
|
5804
5807
|
'cost': cost,
|
5805
5808
|
'average': average,
|
@@ -6071,7 +6074,7 @@ class binance(Exchange, ImplicitAPI):
|
|
6071
6074
|
validOrderTypes = self.safe_list(market['info'], 'orderTypes')
|
6072
6075
|
if not self.in_array(uppercaseType, validOrderTypes):
|
6073
6076
|
if initialUppercaseType != uppercaseType:
|
6074
|
-
raise InvalidOrder(self.id + '
|
6077
|
+
raise InvalidOrder(self.id + ' triggerPrice parameter is not allowed for ' + symbol + ' ' + type + ' orders')
|
6075
6078
|
else:
|
6076
6079
|
raise InvalidOrder(self.id + ' ' + type + ' is not a valid order type for the ' + symbol + ' market')
|
6077
6080
|
clientOrderIdRequest = 'newClientStrategyId' if isPortfolioMarginConditional else 'newClientOrderId'
|
@@ -6110,7 +6113,7 @@ class binance(Exchange, ImplicitAPI):
|
|
6110
6113
|
closePosition = self.safe_bool(params, 'closePosition', False)
|
6111
6114
|
timeInForceIsRequired = False
|
6112
6115
|
priceIsRequired = False
|
6113
|
-
|
6116
|
+
triggerPriceIsRequired = False
|
6114
6117
|
quantityIsRequired = False
|
6115
6118
|
#
|
6116
6119
|
# spot/margin
|
@@ -6156,13 +6159,13 @@ class binance(Exchange, ImplicitAPI):
|
|
6156
6159
|
timeInForceIsRequired = True
|
6157
6160
|
quantityIsRequired = True
|
6158
6161
|
elif (uppercaseType == 'STOP_LOSS') or (uppercaseType == 'TAKE_PROFIT'):
|
6159
|
-
|
6162
|
+
triggerPriceIsRequired = True
|
6160
6163
|
quantityIsRequired = True
|
6161
6164
|
if market['linear'] or market['inverse']:
|
6162
6165
|
priceIsRequired = True
|
6163
6166
|
elif (uppercaseType == 'STOP_LOSS_LIMIT') or (uppercaseType == 'TAKE_PROFIT_LIMIT'):
|
6164
6167
|
quantityIsRequired = True
|
6165
|
-
|
6168
|
+
triggerPriceIsRequired = True
|
6166
6169
|
priceIsRequired = True
|
6167
6170
|
timeInForceIsRequired = True
|
6168
6171
|
elif uppercaseType == 'LIMIT_MAKER':
|
@@ -6170,12 +6173,12 @@ class binance(Exchange, ImplicitAPI):
|
|
6170
6173
|
quantityIsRequired = True
|
6171
6174
|
elif uppercaseType == 'STOP':
|
6172
6175
|
quantityIsRequired = True
|
6173
|
-
|
6176
|
+
triggerPriceIsRequired = True
|
6174
6177
|
priceIsRequired = True
|
6175
6178
|
elif (uppercaseType == 'STOP_MARKET') or (uppercaseType == 'TAKE_PROFIT_MARKET'):
|
6176
6179
|
if not closePosition:
|
6177
6180
|
quantityIsRequired = True
|
6178
|
-
|
6181
|
+
triggerPriceIsRequired = True
|
6179
6182
|
elif uppercaseType == 'TRAILING_STOP_MARKET':
|
6180
6183
|
if not closePosition:
|
6181
6184
|
quantityIsRequired = True
|
@@ -6201,14 +6204,14 @@ class binance(Exchange, ImplicitAPI):
|
|
6201
6204
|
request['price'] = self.price_to_precision(symbol, price)
|
6202
6205
|
else:
|
6203
6206
|
request['price'] = self.parse_to_numeric(price) # some options don't have the precision available
|
6204
|
-
if
|
6207
|
+
if triggerPriceIsRequired:
|
6205
6208
|
if market['contract']:
|
6206
6209
|
if stopPrice is None:
|
6207
|
-
raise InvalidOrder(self.id + ' createOrder() requires a
|
6210
|
+
raise InvalidOrder(self.id + ' createOrder() requires a triggerPrice extra param for a ' + type + ' order')
|
6208
6211
|
else:
|
6209
6212
|
# check for delta price
|
6210
6213
|
if trailingDelta is None and stopPrice is None and trailingPercent is None:
|
6211
|
-
raise InvalidOrder(self.id + ' createOrder() requires a
|
6214
|
+
raise InvalidOrder(self.id + ' createOrder() requires a triggerPrice, trailingDelta or trailingPercent param for a ' + type + ' order')
|
6212
6215
|
if stopPrice is not None:
|
6213
6216
|
request['stopPrice'] = self.price_to_precision(symbol, stopPrice)
|
6214
6217
|
if timeInForceIsRequired and (self.safe_string(params, 'timeInForce') is None) and (self.safe_string(request, 'timeInForce') is None):
|
@@ -10887,7 +10890,7 @@ class binance(Exchange, ImplicitAPI):
|
|
10887
10890
|
paginate = False
|
10888
10891
|
paginate, params = self.handle_option_and_params(params, 'fetchLedger', 'paginate')
|
10889
10892
|
if paginate:
|
10890
|
-
return self.fetch_paginated_call_dynamic('fetchLedger', code, since, limit, params)
|
10893
|
+
return self.fetch_paginated_call_dynamic('fetchLedger', code, since, limit, params, None, False)
|
10891
10894
|
type = None
|
10892
10895
|
subType = None
|
10893
10896
|
currency = None
|
@@ -11962,7 +11965,7 @@ class binance(Exchange, ImplicitAPI):
|
|
11962
11965
|
# ...
|
11963
11966
|
# ]
|
11964
11967
|
#
|
11965
|
-
return self.
|
11968
|
+
return self.parse_open_interests_history(response, market, since, limit)
|
11966
11969
|
|
11967
11970
|
def fetch_open_interest(self, symbol: str, params={}):
|
11968
11971
|
"""
|
@@ -12025,7 +12028,7 @@ class binance(Exchange, ImplicitAPI):
|
|
12025
12028
|
#
|
12026
12029
|
if market['option']:
|
12027
12030
|
symbol = market['symbol']
|
12028
|
-
result = self.
|
12031
|
+
result = self.parse_open_interests_history(response, market)
|
12029
12032
|
for i in range(0, len(result)):
|
12030
12033
|
item = result[i]
|
12031
12034
|
if item['symbol'] == symbol:
|
ccxt/bingx.py
CHANGED
@@ -63,6 +63,7 @@ class bingx(Exchange, ImplicitAPI):
|
|
63
63
|
'createTrailingAmountOrder': True,
|
64
64
|
'createTrailingPercentOrder': True,
|
65
65
|
'createTriggerOrder': True,
|
66
|
+
'editOrder': True,
|
66
67
|
'fetchBalance': True,
|
67
68
|
'fetchCanceledOrders': True,
|
68
69
|
'fetchClosedOrders': True,
|
@@ -85,6 +86,7 @@ class bingx(Exchange, ImplicitAPI):
|
|
85
86
|
'fetchMarkPrice': True,
|
86
87
|
'fetchMarkPrices': True,
|
87
88
|
'fetchMyLiquidations': True,
|
89
|
+
'fetchMyTrades': True,
|
88
90
|
'fetchOHLCV': True,
|
89
91
|
'fetchOpenInterest': True,
|
90
92
|
'fetchOpenOrders': True,
|
@@ -1036,7 +1038,7 @@ class bingx(Exchange, ImplicitAPI):
|
|
1036
1038
|
}
|
1037
1039
|
request['interval'] = self.safe_string(self.timeframes, timeframe, timeframe)
|
1038
1040
|
if since is not None:
|
1039
|
-
request['startTime'] = since
|
1041
|
+
request['startTime'] = max(since - 1, 0)
|
1040
1042
|
if limit is not None:
|
1041
1043
|
request['limit'] = limit
|
1042
1044
|
until = self.safe_integer_2(params, 'until', 'endTime')
|
@@ -5342,6 +5344,8 @@ class bingx(Exchange, ImplicitAPI):
|
|
5342
5344
|
elif market['swap']:
|
5343
5345
|
request['endTs'] = now
|
5344
5346
|
if market['spot']:
|
5347
|
+
if limit is not None:
|
5348
|
+
request['limit'] = limit # default 500, maximum 1000
|
5345
5349
|
response = self.spotV1PrivateGetTradeMyTrades(self.extend(request, params))
|
5346
5350
|
data = self.safe_dict(response, 'data', {})
|
5347
5351
|
fills = self.safe_list(data, 'fills', [])
|
ccxt/bitfinex.py
CHANGED
@@ -100,6 +100,7 @@ class bitfinex(Exchange, ImplicitAPI):
|
|
100
100
|
'fetchOHLCV': True,
|
101
101
|
'fetchOpenInterest': True,
|
102
102
|
'fetchOpenInterestHistory': True,
|
103
|
+
'fetchOpenInterests': True,
|
103
104
|
'fetchOpenOrder': True,
|
104
105
|
'fetchOpenOrders': True,
|
105
106
|
'fetchOrder': True,
|
@@ -419,6 +420,75 @@ class bitfinex(Exchange, ImplicitAPI):
|
|
419
420
|
'TETHERUSE': 'ERC20',
|
420
421
|
},
|
421
422
|
},
|
423
|
+
'features': {
|
424
|
+
'default': {
|
425
|
+
'sandbox': False,
|
426
|
+
'createOrder': {
|
427
|
+
'marginMode': True,
|
428
|
+
'triggerPrice': True,
|
429
|
+
'triggerPriceType': None,
|
430
|
+
'triggerDirection': False,
|
431
|
+
'stopLossPrice': True,
|
432
|
+
'takeProfitPrice': True,
|
433
|
+
'attachedStopLossTakeProfit': None,
|
434
|
+
'timeInForce': {
|
435
|
+
'IOC': True,
|
436
|
+
'FOK': True,
|
437
|
+
'PO': True,
|
438
|
+
'GTD': False,
|
439
|
+
},
|
440
|
+
'hedged': False,
|
441
|
+
'trailing': True, # todo: unify
|
442
|
+
# todo: leverage unify
|
443
|
+
},
|
444
|
+
'createOrders': {
|
445
|
+
'max': 75,
|
446
|
+
},
|
447
|
+
'fetchMyTrades': {
|
448
|
+
'marginMode': False,
|
449
|
+
'limit': 2500,
|
450
|
+
'daysBack': None,
|
451
|
+
'untilDays': 100000, # todo: implement
|
452
|
+
},
|
453
|
+
'fetchOrder': {
|
454
|
+
'marginMode': False,
|
455
|
+
'trigger': False,
|
456
|
+
'trailing': False,
|
457
|
+
},
|
458
|
+
'fetchOpenOrders': {
|
459
|
+
'marginMode': False,
|
460
|
+
'limit': None,
|
461
|
+
'trigger': False,
|
462
|
+
'trailing': False,
|
463
|
+
},
|
464
|
+
'fetchOrders': None,
|
465
|
+
'fetchClosedOrders': {
|
466
|
+
'marginMode': False,
|
467
|
+
'limit': None,
|
468
|
+
'daysBackClosed': None,
|
469
|
+
'daysBackCanceled': None,
|
470
|
+
'untilDays': 100000,
|
471
|
+
'trigger': False,
|
472
|
+
'trailing': False,
|
473
|
+
},
|
474
|
+
'fetchOHLCV': {
|
475
|
+
'limit': 10000,
|
476
|
+
},
|
477
|
+
},
|
478
|
+
'spot': {
|
479
|
+
'extends': 'default',
|
480
|
+
},
|
481
|
+
'swap': {
|
482
|
+
'linear': {
|
483
|
+
'extends': 'default',
|
484
|
+
},
|
485
|
+
'inverse': None,
|
486
|
+
},
|
487
|
+
'future': {
|
488
|
+
'linear': None,
|
489
|
+
'inverse': None,
|
490
|
+
},
|
491
|
+
},
|
422
492
|
'exceptions': {
|
423
493
|
'exact': {
|
424
494
|
'11010': RateLimitExceeded,
|
@@ -3116,6 +3186,58 @@ class bitfinex(Exchange, ImplicitAPI):
|
|
3116
3186
|
'previousFundingDatetime': None,
|
3117
3187
|
}
|
3118
3188
|
|
3189
|
+
def fetch_open_interests(self, symbols: Strings = None, params={}):
|
3190
|
+
"""
|
3191
|
+
Retrieves the open interest for a list of symbols
|
3192
|
+
|
3193
|
+
https://docs.bitfinex.com/reference/rest-public-derivatives-status
|
3194
|
+
|
3195
|
+
:param str[] [symbols]: a list of unified CCXT market symbols
|
3196
|
+
:param dict [params]: exchange specific parameters
|
3197
|
+
:returns dict[]: a list of `open interest structures <https://docs.ccxt.com/#/?id=open-interest-structure>`
|
3198
|
+
"""
|
3199
|
+
self.load_markets()
|
3200
|
+
symbols = self.market_symbols(symbols)
|
3201
|
+
marketIds = ['ALL']
|
3202
|
+
if symbols is not None:
|
3203
|
+
marketIds = self.market_ids(symbols)
|
3204
|
+
request: dict = {
|
3205
|
+
'keys': ','.join(marketIds),
|
3206
|
+
}
|
3207
|
+
response = self.publicGetStatusDeriv(self.extend(request, params))
|
3208
|
+
#
|
3209
|
+
# [
|
3210
|
+
# [
|
3211
|
+
# "tXRPF0:USTF0", # market id
|
3212
|
+
# 1706256986000, # millisecond timestamp
|
3213
|
+
# null,
|
3214
|
+
# 0.512705, # derivative mid price
|
3215
|
+
# 0.512395, # underlying spot mid price
|
3216
|
+
# null,
|
3217
|
+
# 37671483.04, # insurance fund balance
|
3218
|
+
# null,
|
3219
|
+
# 1706284800000, # timestamp of next funding
|
3220
|
+
# 0.00002353, # accrued funding for next period
|
3221
|
+
# 317, # next funding step
|
3222
|
+
# null,
|
3223
|
+
# 0, # current funding
|
3224
|
+
# null,
|
3225
|
+
# null,
|
3226
|
+
# 0.5123016, # mark price
|
3227
|
+
# null,
|
3228
|
+
# null,
|
3229
|
+
# 2233562.03115, # open interest in contracts
|
3230
|
+
# null,
|
3231
|
+
# null,
|
3232
|
+
# null,
|
3233
|
+
# 0.0005, # average spread without funding payment
|
3234
|
+
# 0.0025 # funding payment cap
|
3235
|
+
# ]
|
3236
|
+
# ]
|
3237
|
+
#
|
3238
|
+
result = self.parse_open_interests(response)
|
3239
|
+
return self.filter_by_array(result, 'symbol', symbols)
|
3240
|
+
|
3119
3241
|
def fetch_open_interest(self, symbol: str, params={}):
|
3120
3242
|
"""
|
3121
3243
|
retrieves the open interest of a contract trading pair
|
@@ -3224,7 +3346,7 @@ class bitfinex(Exchange, ImplicitAPI):
|
|
3224
3346
|
# ],
|
3225
3347
|
# ]
|
3226
3348
|
#
|
3227
|
-
return self.
|
3349
|
+
return self.parse_open_interests_history(response, market, since, limit)
|
3228
3350
|
|
3229
3351
|
def parse_open_interest(self, interest, market: Market = None):
|
3230
3352
|
#
|
ccxt/bitget.py
CHANGED
@@ -1264,6 +1264,7 @@ class bitget(Exchange, ImplicitAPI):
|
|
1264
1264
|
'41103': InvalidOrder, # {"code":"41103","msg":"param price scale error error","requestTime":1725635883561,"data":null}
|
1265
1265
|
'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}
|
1266
1266
|
'43011': InvalidOrder, # The parameter does not meet the specification executePrice <= 0
|
1267
|
+
'43001': OrderNotFound,
|
1267
1268
|
'43012': InsufficientFunds, # {"code":"43012","msg":"Insufficient balance","requestTime":1711648951774,"data":null}
|
1268
1269
|
'43025': InvalidOrder, # Plan order does not exist
|
1269
1270
|
'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/bitmart.py
CHANGED
@@ -6,7 +6,7 @@
|
|
6
6
|
from ccxt.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
|
+
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
|
+
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 = 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
|
+
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
|
+
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 = 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
|
+
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
|
+
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 = 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
|
|