ccxt 4.4.95__py2.py3-none-any.whl → 4.4.97__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 +3 -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/foxbit.py +26 -0
- ccxt/abstract/hyperliquid.py +1 -1
- ccxt/abstract/phemex.py +1 -0
- ccxt/apex.py +3 -3
- ccxt/ascendex.py +2 -2
- ccxt/async_support/__init__.py +3 -1
- ccxt/async_support/apex.py +3 -3
- ccxt/async_support/ascendex.py +2 -2
- ccxt/async_support/base/exchange.py +10 -5
- ccxt/async_support/base/ws/future.py +5 -3
- ccxt/async_support/binance.py +90 -34
- ccxt/async_support/binancecoinm.py +5 -1
- ccxt/async_support/binanceus.py +3 -1
- ccxt/async_support/binanceusdm.py +3 -1
- ccxt/async_support/bingx.py +1 -1
- ccxt/async_support/bitget.py +30 -143
- ccxt/async_support/bitmart.py +2 -2
- ccxt/async_support/bitrue.py +13 -8
- ccxt/async_support/bybit.py +14 -5
- ccxt/async_support/coinbaseexchange.py +4 -2
- ccxt/async_support/coinbaseinternational.py +2 -2
- ccxt/async_support/coinspot.py +36 -1
- ccxt/async_support/cryptocom.py +78 -3
- ccxt/async_support/cryptomus.py +41 -1
- ccxt/async_support/defx.py +1 -1
- ccxt/async_support/derive.py +1 -1
- ccxt/async_support/ellipx.py +40 -0
- ccxt/async_support/exmo.py +1 -1
- ccxt/async_support/foxbit.py +1935 -0
- ccxt/async_support/gate.py +1 -2
- ccxt/async_support/hashkey.py +39 -0
- ccxt/async_support/hyperliquid.py +42 -27
- ccxt/async_support/independentreserve.py +35 -0
- ccxt/async_support/indodax.py +34 -0
- ccxt/async_support/kucoin.py +3 -2
- ccxt/async_support/kucoinfutures.py +3 -2
- ccxt/async_support/latoken.py +42 -0
- ccxt/async_support/luno.py +36 -0
- ccxt/async_support/mercado.py +34 -0
- ccxt/async_support/mexc.py +31 -32
- ccxt/async_support/modetrade.py +3 -3
- ccxt/async_support/okcoin.py +1 -1
- ccxt/async_support/okx.py +10 -3
- ccxt/async_support/onetrading.py +1 -1
- ccxt/async_support/oxfun.py +2 -1
- ccxt/async_support/paradex.py +2 -2
- ccxt/async_support/phemex.py +36 -31
- ccxt/async_support/vertex.py +3 -2
- ccxt/async_support/woo.py +6 -2
- ccxt/async_support/woofipro.py +2 -2
- ccxt/base/decimal_to_precision.py +16 -10
- ccxt/base/errors.py +6 -0
- ccxt/base/exchange.py +60 -17
- ccxt/binance.py +90 -34
- ccxt/binancecoinm.py +5 -1
- ccxt/binanceus.py +3 -1
- ccxt/binanceusdm.py +3 -1
- ccxt/bingx.py +1 -1
- ccxt/bitget.py +30 -143
- ccxt/bitmart.py +2 -2
- ccxt/bitrue.py +13 -8
- ccxt/bybit.py +14 -5
- ccxt/coinbaseexchange.py +4 -2
- ccxt/coinbaseinternational.py +2 -2
- ccxt/coinspot.py +36 -1
- ccxt/cryptocom.py +78 -3
- ccxt/cryptomus.py +41 -1
- ccxt/defx.py +1 -1
- ccxt/derive.py +1 -1
- ccxt/ellipx.py +40 -0
- ccxt/exmo.py +1 -1
- ccxt/foxbit.py +1935 -0
- ccxt/gate.py +1 -2
- ccxt/hashkey.py +39 -0
- ccxt/hyperliquid.py +42 -27
- ccxt/independentreserve.py +35 -0
- ccxt/indodax.py +34 -0
- ccxt/kucoin.py +3 -2
- ccxt/kucoinfutures.py +3 -2
- ccxt/latoken.py +42 -0
- ccxt/luno.py +36 -0
- ccxt/mercado.py +34 -0
- ccxt/mexc.py +31 -32
- ccxt/modetrade.py +3 -3
- ccxt/okcoin.py +1 -1
- ccxt/okx.py +10 -3
- ccxt/onetrading.py +1 -1
- ccxt/oxfun.py +2 -1
- ccxt/paradex.py +2 -2
- ccxt/phemex.py +36 -31
- ccxt/pro/__init__.py +1 -1
- ccxt/pro/binancecoinm.py +3 -1
- ccxt/pro/binanceus.py +3 -1
- ccxt/pro/binanceusdm.py +3 -1
- ccxt/pro/bybit.py +33 -1
- ccxt/test/tests_async.py +15 -0
- ccxt/test/tests_sync.py +15 -0
- ccxt/vertex.py +3 -2
- ccxt/woo.py +6 -2
- ccxt/woofipro.py +2 -2
- {ccxt-4.4.95.dist-info → ccxt-4.4.97.dist-info}/METADATA +19 -19
- {ccxt-4.4.95.dist-info → ccxt-4.4.97.dist-info}/RECORD +110 -107
- {ccxt-4.4.95.dist-info → ccxt-4.4.97.dist-info}/LICENSE.txt +0 -0
- {ccxt-4.4.95.dist-info → ccxt-4.4.97.dist-info}/WHEEL +0 -0
- {ccxt-4.4.95.dist-info → ccxt-4.4.97.dist-info}/top_level.txt +0 -0
ccxt/async_support/woo.py
CHANGED
@@ -1503,8 +1503,11 @@ class woo(Exchange, ImplicitAPI):
|
|
1503
1503
|
if symbol is not None:
|
1504
1504
|
market = self.market(symbol)
|
1505
1505
|
request['symbol'] = market['id']
|
1506
|
+
response = None
|
1506
1507
|
if trigger:
|
1507
|
-
|
1508
|
+
response = await self.v3PrivateDeleteTradeAlgoOrders(params)
|
1509
|
+
else:
|
1510
|
+
response = await self.v3PrivateDeleteTradeOrders(self.extend(request, params))
|
1508
1511
|
#
|
1509
1512
|
# {
|
1510
1513
|
# "success": True,
|
@@ -1514,7 +1517,8 @@ class woo(Exchange, ImplicitAPI):
|
|
1514
1517
|
# "timestamp": 1751941988134
|
1515
1518
|
# }
|
1516
1519
|
#
|
1517
|
-
|
1520
|
+
data = self.safe_dict(response, 'data', {})
|
1521
|
+
return [self.safe_order({'info': data})]
|
1518
1522
|
|
1519
1523
|
async def cancel_all_orders_after(self, timeout: Int, params={}):
|
1520
1524
|
"""
|
ccxt/async_support/woofipro.py
CHANGED
@@ -33,18 +33,24 @@ NO_PADDING = 5
|
|
33
33
|
PAD_WITH_ZERO = 6
|
34
34
|
|
35
35
|
|
36
|
-
def decimal_to_precision(n, rounding_mode=ROUND,
|
37
|
-
assert
|
36
|
+
def decimal_to_precision(n, rounding_mode=ROUND, numPrecisionDigits=None, counting_mode=DECIMAL_PLACES, padding_mode=NO_PADDING):
|
37
|
+
assert numPrecisionDigits is not None, 'numPrecisionDigits should not be None'
|
38
|
+
|
39
|
+
if isinstance(numPrecisionDigits, str):
|
40
|
+
numPrecisionDigits = float(numPrecisionDigits)
|
41
|
+
assert isinstance(numPrecisionDigits, float) or isinstance(numPrecisionDigits, decimal.Decimal) or isinstance(numPrecisionDigits, numbers.Integral), 'numPrecisionDigits has an invalid number'
|
42
|
+
|
38
43
|
if counting_mode == TICK_SIZE:
|
39
|
-
assert
|
44
|
+
assert numPrecisionDigits > 0, 'negative or zero numPrecisionDigits can not be used with TICK_SIZE precisionMode'
|
40
45
|
else:
|
41
|
-
assert
|
46
|
+
assert isinstance(numPrecisionDigits, numbers.Integral)
|
47
|
+
|
42
48
|
assert rounding_mode in [TRUNCATE, ROUND]
|
43
49
|
assert counting_mode in [DECIMAL_PLACES, SIGNIFICANT_DIGITS, TICK_SIZE]
|
44
50
|
assert padding_mode in [NO_PADDING, PAD_WITH_ZERO]
|
51
|
+
# end of checks
|
45
52
|
|
46
|
-
|
47
|
-
precision = float(precision)
|
53
|
+
precision = numPrecisionDigits # "precision" variable name was in signature, but to make function signature similar to php/js, I had to change the argument name to "numPrecisionDigits". however, the below codes use "precision" variable name, so we have to assign that name here (you can change the usage of 'precision' variable name below everywhere, but i've refrained to do that to avoid many changes)
|
48
54
|
|
49
55
|
context = decimal.getcontext()
|
50
56
|
|
@@ -78,12 +84,12 @@ def decimal_to_precision(n, rounding_mode=ROUND, precision=None, counting_mode=D
|
|
78
84
|
if missing != 0:
|
79
85
|
if rounding_mode == ROUND:
|
80
86
|
if dec > 0:
|
81
|
-
if missing >=
|
87
|
+
if missing >= precision_dec / 2:
|
82
88
|
dec = dec - missing + precision_dec
|
83
89
|
else:
|
84
90
|
dec = dec - missing
|
85
91
|
else:
|
86
|
-
if missing >=
|
92
|
+
if missing >= precision_dec / 2:
|
87
93
|
dec = dec + missing - precision_dec
|
88
94
|
else:
|
89
95
|
dec = dec + missing
|
@@ -117,7 +123,7 @@ def decimal_to_precision(n, rounding_mode=ROUND, precision=None, counting_mode=D
|
|
117
123
|
precise = '{:f}'.format(min((below, above), key=lambda x: abs(x - dec)))
|
118
124
|
else:
|
119
125
|
precise = '{:f}'.format(dec.quantize(sigfig))
|
120
|
-
if precise
|
126
|
+
if precise.startswith('-0') and all(c in '0.' for c in precise[1:]):
|
121
127
|
precise = precise[1:]
|
122
128
|
|
123
129
|
elif rounding_mode == TRUNCATE:
|
@@ -138,7 +144,7 @@ def decimal_to_precision(n, rounding_mode=ROUND, precision=None, counting_mode=D
|
|
138
144
|
precise = string
|
139
145
|
else:
|
140
146
|
precise = string[:end].ljust(dot, '0')
|
141
|
-
if precise
|
147
|
+
if precise.startswith('-0') and all(c in '0.' for c in precise[1:]):
|
142
148
|
precise = precise[1:]
|
143
149
|
precise = precise.rstrip('.')
|
144
150
|
|
ccxt/base/errors.py
CHANGED
@@ -1,3 +1,9 @@
|
|
1
|
+
# ----------------------------------------------------------------------------
|
2
|
+
|
3
|
+
# PLEASE DO NOT EDIT THIS FILE, IT IS GENERATED AND WILL BE OVERWRITTEN:
|
4
|
+
# https://github.com/ccxt/ccxt/blob/master/CONTRIBUTING.md#how-to-contribute-code
|
5
|
+
# EDIT THE CORRESPONDENT .ts FILE INSTEAD
|
6
|
+
|
1
7
|
error_hierarchy = {
|
2
8
|
'BaseError': {
|
3
9
|
'ExchangeError': {
|
ccxt/base/exchange.py
CHANGED
@@ -4,7 +4,7 @@
|
|
4
4
|
|
5
5
|
# -----------------------------------------------------------------------------
|
6
6
|
|
7
|
-
__version__ = '4.4.
|
7
|
+
__version__ = '4.4.97'
|
8
8
|
|
9
9
|
# -----------------------------------------------------------------------------
|
10
10
|
|
@@ -229,6 +229,7 @@ class Exchange(object):
|
|
229
229
|
'chrome100': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.75 Safari/537.36',
|
230
230
|
}
|
231
231
|
headers = None
|
232
|
+
returnResponseHeaders = False
|
232
233
|
origin = '*' # CORS origin
|
233
234
|
MAX_VALUE = float('inf')
|
234
235
|
#
|
@@ -579,6 +580,8 @@ class Exchange(object):
|
|
579
580
|
if self.verbose:
|
580
581
|
self.log("\nfetch Response:", self.id, method, url, http_status_code, "ResponseHeaders:", headers, "ResponseBody:", http_response)
|
581
582
|
self.logger.debug("%s %s, Response: %s %s %s", method, url, http_status_code, headers, http_response)
|
583
|
+
if json_response and not isinstance(json_response, list) and self.returnResponseHeaders:
|
584
|
+
json_response['responseHeaders'] = headers
|
582
585
|
response.raise_for_status()
|
583
586
|
|
584
587
|
except Timeout as e:
|
@@ -2130,6 +2133,17 @@ class Exchange(object):
|
|
2130
2133
|
'watchLiquidations': None,
|
2131
2134
|
'watchLiquidationsForSymbols': None,
|
2132
2135
|
'watchMyLiquidations': None,
|
2136
|
+
'unWatchOrders': None,
|
2137
|
+
'unWatchTrades': None,
|
2138
|
+
'unWatchTradesForSymbols': None,
|
2139
|
+
'unWatchOHLCVForSymbols': None,
|
2140
|
+
'unWatchOrderBookForSymbols': None,
|
2141
|
+
'unWatchPositions': None,
|
2142
|
+
'unWatchOrderBook': None,
|
2143
|
+
'unWatchTickers': None,
|
2144
|
+
'unWatchMyTrades': None,
|
2145
|
+
'unWatchTicker': None,
|
2146
|
+
'unWatchOHLCV': None,
|
2133
2147
|
'watchMyLiquidationsForSymbols': None,
|
2134
2148
|
'withdraw': None,
|
2135
2149
|
'ws': None,
|
@@ -2616,6 +2630,9 @@ class Exchange(object):
|
|
2616
2630
|
def un_watch_order_book_for_symbols(self, symbols: List[str], params={}):
|
2617
2631
|
raise NotSupported(self.id + ' unWatchOrderBookForSymbols() is not supported yet')
|
2618
2632
|
|
2633
|
+
def un_watch_positions(self, symbols: Strings = None, params={}):
|
2634
|
+
raise NotSupported(self.id + ' unWatchPositions() is not supported yet')
|
2635
|
+
|
2619
2636
|
def fetch_deposit_addresses(self, codes: Strings = None, params={}):
|
2620
2637
|
raise NotSupported(self.id + ' fetchDepositAddresses() is not supported yet')
|
2621
2638
|
|
@@ -3584,18 +3601,7 @@ class Exchange(object):
|
|
3584
3601
|
symbol = market['symbol'] if (market is not None) else None
|
3585
3602
|
return self.filter_by_symbol_since_limit(results, symbol, since, limit)
|
3586
3603
|
|
3587
|
-
def
|
3588
|
-
"""
|
3589
|
-
calculates the presumptive fee that would be charged for an order
|
3590
|
-
:param str symbol: unified market symbol
|
3591
|
-
:param str type: 'market' or 'limit'
|
3592
|
-
:param str side: 'buy' or 'sell'
|
3593
|
-
:param float amount: how much you want to trade, in units of the base currency on most exchanges, or number of contracts
|
3594
|
-
:param float price: the price for the order to be filled at, in units of the quote currency
|
3595
|
-
:param str takerOrMaker: 'taker' or 'maker'
|
3596
|
-
:param dict params:
|
3597
|
-
:returns dict: contains the rate, the percentage multiplied to the order amount to obtain the fee amount, and cost, the total value of the fee in units of the quote currency, for the order
|
3598
|
-
"""
|
3604
|
+
def calculate_fee_with_rate(self, symbol: str, type: str, side: str, amount: float, price: float, takerOrMaker='taker', feeRate: Num = None, params={}):
|
3599
3605
|
if type == 'market' and takerOrMaker == 'maker':
|
3600
3606
|
raise ArgumentsRequired(self.id + ' calculateFee() - you have provided incompatible arguments - "market" type order can not be "maker". Change either the "type" or the "takerOrMaker" argument to calculate the fee.')
|
3601
3607
|
market = self.markets[symbol]
|
@@ -3624,7 +3630,7 @@ class Exchange(object):
|
|
3624
3630
|
# even if `takerOrMaker` argument was set to 'maker', for 'market' orders we should forcefully override it to 'taker'
|
3625
3631
|
if type == 'market':
|
3626
3632
|
takerOrMaker = 'taker'
|
3627
|
-
rate = self.safe_string(market, takerOrMaker)
|
3633
|
+
rate = self.number_to_string(feeRate) if (feeRate is not None) else self.safe_string(market, takerOrMaker)
|
3628
3634
|
cost = Precise.string_mul(cost, rate)
|
3629
3635
|
return {
|
3630
3636
|
'type': takerOrMaker,
|
@@ -3633,6 +3639,20 @@ class Exchange(object):
|
|
3633
3639
|
'cost': self.parse_number(cost),
|
3634
3640
|
}
|
3635
3641
|
|
3642
|
+
def calculate_fee(self, symbol: str, type: str, side: str, amount: float, price: float, takerOrMaker='taker', params={}):
|
3643
|
+
"""
|
3644
|
+
calculates the presumptive fee that would be charged for an order
|
3645
|
+
:param str symbol: unified market symbol
|
3646
|
+
:param str type: 'market' or 'limit'
|
3647
|
+
:param str side: 'buy' or 'sell'
|
3648
|
+
:param float amount: how much you want to trade, in units of the base currency on most exchanges, or number of contracts
|
3649
|
+
:param float price: the price for the order to be filled at, in units of the quote currency
|
3650
|
+
:param str takerOrMaker: 'taker' or 'maker'
|
3651
|
+
:param dict params:
|
3652
|
+
:returns dict: contains the rate, the percentage multiplied to the order amount to obtain the fee amount, and cost, the total value of the fee in units of the quote currency, for the order
|
3653
|
+
"""
|
3654
|
+
return self.calculate_fee_with_rate(symbol, type, side, amount, price, takerOrMaker, None, params)
|
3655
|
+
|
3636
3656
|
def safe_liquidation(self, liquidation: dict, market: Market = None):
|
3637
3657
|
contracts = self.safe_string(liquidation, 'contracts')
|
3638
3658
|
contractSize = self.safe_string(market, 'contractSize')
|
@@ -3672,6 +3692,21 @@ class Exchange(object):
|
|
3672
3692
|
trade['cost'] = self.parse_number(cost)
|
3673
3693
|
return trade
|
3674
3694
|
|
3695
|
+
def create_ccxt_trade_id(self, timestamp=None, side=None, amount=None, price=None, takerOrMaker=None):
|
3696
|
+
# self approach is being used by multiple exchanges(mexc, woo, coinsbit, dydx, ...)
|
3697
|
+
id = None
|
3698
|
+
if timestamp is not None:
|
3699
|
+
id = self.number_to_string(timestamp)
|
3700
|
+
if side is not None:
|
3701
|
+
id += '-' + side
|
3702
|
+
if amount is not None:
|
3703
|
+
id += '-' + self.number_to_string(amount)
|
3704
|
+
if price is not None:
|
3705
|
+
id += '-' + self.number_to_string(price)
|
3706
|
+
if takerOrMaker is not None:
|
3707
|
+
id += '-' + takerOrMaker
|
3708
|
+
return id
|
3709
|
+
|
3675
3710
|
def parsed_fee_and_fees(self, container: Any):
|
3676
3711
|
fee = self.safe_dict(container, 'fee')
|
3677
3712
|
fees = self.safe_list(container, 'fees')
|
@@ -5495,10 +5530,10 @@ class Exchange(object):
|
|
5495
5530
|
"""
|
5496
5531
|
raise NotSupported(self.id + ' fetchDepositsWithdrawals() is not supported yet')
|
5497
5532
|
|
5498
|
-
def fetch_deposits(self,
|
5533
|
+
def fetch_deposits(self, code: Str = None, since: Int = None, limit: Int = None, params={}):
|
5499
5534
|
raise NotSupported(self.id + ' fetchDeposits() is not supported yet')
|
5500
5535
|
|
5501
|
-
def fetch_withdrawals(self,
|
5536
|
+
def fetch_withdrawals(self, code: Str = None, since: Int = None, limit: Int = None, params={}):
|
5502
5537
|
raise NotSupported(self.id + ' fetchWithdrawals() is not supported yet')
|
5503
5538
|
|
5504
5539
|
def fetch_deposits_ws(self, code: Str = None, since: Int = None, limit: Int = None, params={}):
|
@@ -6426,7 +6461,7 @@ class Exchange(object):
|
|
6426
6461
|
calls = 0
|
6427
6462
|
result = []
|
6428
6463
|
errors = 0
|
6429
|
-
until = self.
|
6464
|
+
until = self.safe_integer_n(params, ['until', 'untill', 'till']) # do not omit it from params here
|
6430
6465
|
maxEntriesPerRequest, params = self.handle_max_entries_per_request_and_params(method, maxEntriesPerRequest, params)
|
6431
6466
|
if (paginationDirection == 'forward'):
|
6432
6467
|
if since is None:
|
@@ -6988,6 +7023,14 @@ class Exchange(object):
|
|
6988
7023
|
self.myTrades = None
|
6989
7024
|
elif topic == 'orders' and (self.orders is not None):
|
6990
7025
|
self.orders = None
|
7026
|
+
elif topic == 'positions' and (self.positions is not None):
|
7027
|
+
self.positions = None
|
7028
|
+
clients = list(self.clients.values())
|
7029
|
+
for i in range(0, len(clients)):
|
7030
|
+
client = clients[i]
|
7031
|
+
futures = self.safe_dict(client, 'futures')
|
7032
|
+
if (futures is not None) and ('fetchPositionsSnapshot' in futures):
|
7033
|
+
del futures['fetchPositionsSnapshot']
|
6991
7034
|
elif topic == 'ticker' and (self.tickers is not None):
|
6992
7035
|
tickerSymbols = list(self.tickers.keys())
|
6993
7036
|
for i in range(0, len(tickerSymbols)):
|
ccxt/binance.py
CHANGED
@@ -505,6 +505,7 @@ class binance(Exchange, ImplicitAPI):
|
|
505
505
|
'portfolio/balance': 2,
|
506
506
|
'portfolio/negative-balance-exchange-record': 2,
|
507
507
|
'portfolio/pmloan-history': 5,
|
508
|
+
'portfolio/earn-asset-balance': 150, # Weight(IP): 1500 => cost = 0.1 * 1500 = 150
|
508
509
|
# staking
|
509
510
|
'staking/productList': 0.1,
|
510
511
|
'staking/position': 0.1,
|
@@ -663,6 +664,7 @@ class binance(Exchange, ImplicitAPI):
|
|
663
664
|
'portfolio/repay-futures-negative-balance': 150, # Weight(IP): 1500 => cost = 0.1 * 1500 = 150
|
664
665
|
'portfolio/mint': 20,
|
665
666
|
'portfolio/redeem': 20,
|
667
|
+
'portfolio/earn-asset-transfer': 150, # Weight(IP): 1500 => cost = 0.1 * 1500 = 150
|
666
668
|
'lending/auto-invest/plan/add': 0.1, # Weight(IP): 1 => cost = 0.1 * 1 = 0.1
|
667
669
|
'lending/auto-invest/plan/edit': 0.1, # Weight(IP): 1 => cost = 0.1 * 1 = 0.1
|
668
670
|
'lending/auto-invest/plan/edit-status': 0.1, # Weight(IP): 1 => cost = 0.1 * 1 = 0.1
|
@@ -851,6 +853,7 @@ class binance(Exchange, ImplicitAPI):
|
|
851
853
|
'apiTradingStatus': {'cost': 1, 'noSymbol': 10},
|
852
854
|
'lvtKlines': 1,
|
853
855
|
'convert/exchangeInfo': 4,
|
856
|
+
'insuranceBalance': 1,
|
854
857
|
},
|
855
858
|
},
|
856
859
|
'fapiData': {
|
@@ -1288,12 +1291,14 @@ class binance(Exchange, ImplicitAPI):
|
|
1288
1291
|
'options': {
|
1289
1292
|
'sandboxMode': False,
|
1290
1293
|
'fetchMargins': True,
|
1291
|
-
'fetchMarkets':
|
1292
|
-
'
|
1293
|
-
|
1294
|
-
|
1295
|
-
|
1296
|
-
|
1294
|
+
'fetchMarkets': {
|
1295
|
+
'types': [
|
1296
|
+
'spot', # allows CORS in browsers
|
1297
|
+
'linear', # allows CORS in browsers
|
1298
|
+
'inverse', # allows CORS in browsers
|
1299
|
+
# 'option', # does not allow CORS, enable outside of the browser only
|
1300
|
+
],
|
1301
|
+
},
|
1297
1302
|
'loadAllOptions': False,
|
1298
1303
|
'fetchCurrencies': True, # self is a private call and it requires API keys
|
1299
1304
|
# 'fetchTradesMethod': 'publicGetAggTrades', # publicGetTrades, publicGetHistoricalTrades, eapiPublicGetTrades
|
@@ -3021,7 +3026,14 @@ class binance(Exchange, ImplicitAPI):
|
|
3021
3026
|
:returns dict[]: an array of objects representing market data
|
3022
3027
|
"""
|
3023
3028
|
promisesRaw = []
|
3024
|
-
rawFetchMarkets =
|
3029
|
+
rawFetchMarkets = None
|
3030
|
+
defaultTypes = ['spot', 'linear', 'inverse']
|
3031
|
+
fetchMarketsOptions = self.safe_dict(self.options, 'fetchMarkets')
|
3032
|
+
if fetchMarketsOptions is not None:
|
3033
|
+
rawFetchMarkets = self.safe_list(fetchMarketsOptions, 'types', defaultTypes)
|
3034
|
+
else:
|
3035
|
+
# for backward-compatibility
|
3036
|
+
rawFetchMarkets = self.safe_list(self.options, 'fetchMarkets', defaultTypes)
|
3025
3037
|
# handle loadAllOptions option
|
3026
3038
|
loadAllOptions = self.safe_bool(self.options, 'loadAllOptions', False)
|
3027
3039
|
if loadAllOptions:
|
@@ -3913,29 +3925,52 @@ class binance(Exchange, ImplicitAPI):
|
|
3913
3925
|
# "time": 1597370495002
|
3914
3926
|
# }
|
3915
3927
|
#
|
3916
|
-
#
|
3917
|
-
#
|
3918
|
-
#
|
3919
|
-
#
|
3920
|
-
#
|
3921
|
-
#
|
3922
|
-
#
|
3923
|
-
#
|
3924
|
-
#
|
3925
|
-
#
|
3926
|
-
#
|
3927
|
-
#
|
3928
|
-
#
|
3929
|
-
#
|
3930
|
-
#
|
3931
|
-
#
|
3932
|
-
#
|
3933
|
-
#
|
3934
|
-
#
|
3935
|
-
#
|
3936
|
-
#
|
3937
|
-
#
|
3938
|
-
#
|
3928
|
+
# spot - ticker
|
3929
|
+
#
|
3930
|
+
# {
|
3931
|
+
# "symbol": "BTCUSDT",
|
3932
|
+
# "priceChange": "-188.18000000",
|
3933
|
+
# "priceChangePercent": "-0.159",
|
3934
|
+
# "weightedAvgPrice": "118356.64734074",
|
3935
|
+
# "lastPrice": "118449.03000000",
|
3936
|
+
# "prevClosePrice": "118637.22000000", # field absent in rolling ticker
|
3937
|
+
# "lastQty": "0.00731000", # field absent in rolling ticker
|
3938
|
+
# "bidPrice": "118449.02000000", # field absent in rolling ticker
|
3939
|
+
# "bidQty": "7.15931000", # field absent in rolling ticker
|
3940
|
+
# "askPrice": "118449.03000000", # field absent in rolling ticker
|
3941
|
+
# "askQty": "0.09592000", # field absent in rolling ticker
|
3942
|
+
# "openPrice": "118637.21000000",
|
3943
|
+
# "highPrice": "119273.36000000",
|
3944
|
+
# "lowPrice": "117427.50000000",
|
3945
|
+
# "volume": "14741.41491000",
|
3946
|
+
# "quoteVolume": "1744744445.80640740",
|
3947
|
+
# "openTime": "1753701474013",
|
3948
|
+
# "closeTime": "1753787874013",
|
3949
|
+
# "firstId": "5116031635",
|
3950
|
+
# "lastId": "5117964946",
|
3951
|
+
# "count": "1933312"
|
3952
|
+
# }
|
3953
|
+
#
|
3954
|
+
# usdm tickers
|
3955
|
+
#
|
3956
|
+
# {
|
3957
|
+
# "symbol": "SUSDT",
|
3958
|
+
# "priceChange": "-0.0229000",
|
3959
|
+
# "priceChangePercent": "-6.777",
|
3960
|
+
# "weightedAvgPrice": "0.3210035",
|
3961
|
+
# "lastPrice": "0.3150000",
|
3962
|
+
# "lastQty": "16",
|
3963
|
+
# "openPrice": "0.3379000",
|
3964
|
+
# "highPrice": "0.3411000",
|
3965
|
+
# "lowPrice": "0.3071000",
|
3966
|
+
# "volume": "120588225",
|
3967
|
+
# "quoteVolume": "38709237.2289000",
|
3968
|
+
# "openTime": "1753701720000",
|
3969
|
+
# "closeTime": "1753788172414",
|
3970
|
+
# "firstId": "72234973",
|
3971
|
+
# "lastId": "72423677",
|
3972
|
+
# "count": "188700"
|
3973
|
+
# }
|
3939
3974
|
#
|
3940
3975
|
# coinm
|
3941
3976
|
#
|
@@ -4286,16 +4321,37 @@ class binance(Exchange, ImplicitAPI):
|
|
4286
4321
|
elif self.is_inverse(type, subType):
|
4287
4322
|
response = self.dapiPublicGetTicker24hr(params)
|
4288
4323
|
elif type == 'spot':
|
4289
|
-
|
4290
|
-
|
4291
|
-
|
4292
|
-
|
4324
|
+
rolling = self.safe_bool(params, 'rolling', False)
|
4325
|
+
params = self.omit(params, 'rolling')
|
4326
|
+
if rolling:
|
4327
|
+
symbols = self.market_symbols(symbols)
|
4328
|
+
request: dict = {
|
4329
|
+
'symbols': self.json(self.market_ids(symbols)),
|
4330
|
+
}
|
4331
|
+
response = self.publicGetTicker(self.extend(request, params))
|
4332
|
+
# parseTicker is not able to handle marketType for spot-rolling ticker fields, so we need custom parsing
|
4333
|
+
return self.parse_tickers_for_rolling(response, symbols)
|
4334
|
+
else:
|
4335
|
+
request: dict = {}
|
4336
|
+
if symbols is not None:
|
4337
|
+
request['symbols'] = self.json(self.market_ids(symbols))
|
4338
|
+
response = self.publicGetTicker24hr(self.extend(request, params))
|
4293
4339
|
elif type == 'option':
|
4294
4340
|
response = self.eapiPublicGetTicker(params)
|
4295
4341
|
else:
|
4296
4342
|
raise NotSupported(self.id + ' fetchTickers() does not support ' + type + ' markets yet')
|
4297
4343
|
return self.parse_tickers(response, symbols)
|
4298
4344
|
|
4345
|
+
def parse_tickers_for_rolling(self, response, symbols):
|
4346
|
+
results = []
|
4347
|
+
for i in range(0, len(response)):
|
4348
|
+
marketId = self.safe_string(response[i], 'symbol')
|
4349
|
+
tickerMarket = self.safe_market(marketId, None, None, 'spot')
|
4350
|
+
parsedTicker = self.parse_ticker(response[i])
|
4351
|
+
parsedTicker['symbol'] = tickerMarket['symbol']
|
4352
|
+
results.append(parsedTicker)
|
4353
|
+
return self.filter_by_array(results, 'symbol', symbols)
|
4354
|
+
|
4299
4355
|
def fetch_mark_price(self, symbol: str, params={}) -> Ticker:
|
4300
4356
|
"""
|
4301
4357
|
fetches mark price for the market
|
ccxt/binancecoinm.py
CHANGED
@@ -32,7 +32,11 @@ class binancecoinm(binance, ImplicitAPI):
|
|
32
32
|
'createStopMarketOrder': True,
|
33
33
|
},
|
34
34
|
'options': {
|
35
|
-
'fetchMarkets':
|
35
|
+
'fetchMarkets': {
|
36
|
+
'types': [
|
37
|
+
'inverse',
|
38
|
+
],
|
39
|
+
},
|
36
40
|
'defaultSubType': 'inverse',
|
37
41
|
'leverageBrackets': None,
|
38
42
|
},
|
ccxt/binanceus.py
CHANGED
ccxt/binanceusdm.py
CHANGED
@@ -33,7 +33,9 @@ class binanceusdm(binance, ImplicitAPI):
|
|
33
33
|
'createStopMarketOrder': True,
|
34
34
|
},
|
35
35
|
'options': {
|
36
|
-
'fetchMarkets':
|
36
|
+
'fetchMarkets': {
|
37
|
+
'types': ['linear'],
|
38
|
+
},
|
37
39
|
'defaultSubType': 'linear',
|
38
40
|
# https://www.binance.com/en/support/faq/360033162192
|
39
41
|
# tier amount, maintenance margin, initial margin,
|
ccxt/bingx.py
CHANGED
@@ -5057,7 +5057,7 @@ class bingx(Exchange, ImplicitAPI):
|
|
5057
5057
|
id = self.safe_string(transaction, 'id', dataId)
|
5058
5058
|
address = self.safe_string(transaction, 'address')
|
5059
5059
|
tag = self.safe_string(transaction, 'addressTag')
|
5060
|
-
timestamp = self.
|
5060
|
+
timestamp = self.safe_integer_2(transaction, 'insertTime', 'timestamp')
|
5061
5061
|
datetime = self.iso8601(timestamp)
|
5062
5062
|
if timestamp is None:
|
5063
5063
|
datetime = self.safe_string(transaction, 'applyTime')
|