ccxt 4.3.55__py2.py3-none-any.whl → 4.3.57__py2.py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of ccxt might be problematic. Click here for more details.
- ccxt/__init__.py +1 -1
- ccxt/abstract/bingx.py +16 -0
- ccxt/async_support/__init__.py +1 -1
- ccxt/async_support/base/exchange.py +19 -3
- ccxt/async_support/base/ws/client.py +25 -5
- ccxt/async_support/binance.py +7 -7
- ccxt/async_support/bingx.py +78 -7
- ccxt/async_support/bitflyer.py +7 -1
- ccxt/async_support/bitget.py +56 -47
- ccxt/async_support/bitopro.py +18 -3
- ccxt/async_support/btcmarkets.py +27 -26
- ccxt/async_support/bybit.py +8 -5
- ccxt/async_support/coinone.py +15 -19
- ccxt/async_support/delta.py +5 -1
- ccxt/async_support/gate.py +97 -2
- ccxt/async_support/htx.py +84 -25
- ccxt/async_support/huobijp.py +61 -2
- ccxt/async_support/hyperliquid.py +1 -1
- ccxt/async_support/lbank.py +27 -6
- ccxt/base/exchange.py +19 -3
- ccxt/binance.py +7 -7
- ccxt/bingx.py +78 -7
- ccxt/bitflyer.py +7 -1
- ccxt/bitget.py +56 -47
- ccxt/bitopro.py +18 -3
- ccxt/btcmarkets.py +27 -26
- ccxt/bybit.py +8 -5
- ccxt/coinone.py +15 -19
- ccxt/delta.py +5 -1
- ccxt/gate.py +97 -2
- ccxt/htx.py +84 -25
- ccxt/huobijp.py +61 -2
- ccxt/hyperliquid.py +1 -1
- ccxt/lbank.py +27 -6
- ccxt/pro/__init__.py +1 -1
- {ccxt-4.3.55.dist-info → ccxt-4.3.57.dist-info}/METADATA +4 -6
- {ccxt-4.3.55.dist-info → ccxt-4.3.57.dist-info}/RECORD +40 -40
- {ccxt-4.3.55.dist-info → ccxt-4.3.57.dist-info}/LICENSE.txt +0 -0
- {ccxt-4.3.55.dist-info → ccxt-4.3.57.dist-info}/WHEEL +0 -0
- {ccxt-4.3.55.dist-info → ccxt-4.3.57.dist-info}/top_level.txt +0 -0
ccxt/__init__.py
CHANGED
ccxt/abstract/bingx.py
CHANGED
@@ -76,6 +76,22 @@ class ImplicitAPI:
|
|
76
76
|
swap_v2_private_delete_trade_batchorders = swapV2PrivateDeleteTradeBatchOrders = Entry('trade/batchOrders', ['swap', 'v2', 'private'], 'DELETE', {'cost': 2})
|
77
77
|
swap_v2_private_delete_trade_allopenorders = swapV2PrivateDeleteTradeAllOpenOrders = Entry('trade/allOpenOrders', ['swap', 'v2', 'private'], 'DELETE', {'cost': 2})
|
78
78
|
swap_v3_public_get_quote_klines = swapV3PublicGetQuoteKlines = Entry('quote/klines', ['swap', 'v3', 'public'], 'GET', {'cost': 1})
|
79
|
+
cswap_v1_public_get_market_contracts = cswapV1PublicGetMarketContracts = Entry('market/contracts', ['cswap', 'v1', 'public'], 'GET', {'cost': 1})
|
80
|
+
cswap_v1_public_get_market_premiumindex = cswapV1PublicGetMarketPremiumIndex = Entry('market/premiumIndex', ['cswap', 'v1', 'public'], 'GET', {'cost': 1})
|
81
|
+
cswap_v1_public_get_market_openinterest = cswapV1PublicGetMarketOpenInterest = Entry('market/openInterest', ['cswap', 'v1', 'public'], 'GET', {'cost': 1})
|
82
|
+
cswap_v1_public_get_market_klines = cswapV1PublicGetMarketKlines = Entry('market/klines', ['cswap', 'v1', 'public'], 'GET', {'cost': 1})
|
83
|
+
cswap_v1_public_get_market_depth = cswapV1PublicGetMarketDepth = Entry('market/depth', ['cswap', 'v1', 'public'], 'GET', {'cost': 1})
|
84
|
+
cswap_v1_public_get_market_ticker = cswapV1PublicGetMarketTicker = Entry('market/ticker', ['cswap', 'v1', 'public'], 'GET', {'cost': 1})
|
85
|
+
cswap_v1_private_get_trade_leverage = cswapV1PrivateGetTradeLeverage = Entry('trade/leverage', ['cswap', 'v1', 'private'], 'GET', {'cost': 2})
|
86
|
+
cswap_v1_private_get_trade_forceorders = cswapV1PrivateGetTradeForceOrders = Entry('trade/forceOrders', ['cswap', 'v1', 'private'], 'GET', {'cost': 2})
|
87
|
+
cswap_v1_private_get_trade_allfillorders = cswapV1PrivateGetTradeAllFillOrders = Entry('trade/allFillOrders', ['cswap', 'v1', 'private'], 'GET', {'cost': 2})
|
88
|
+
cswap_v1_private_get_user_commissionrate = cswapV1PrivateGetUserCommissionRate = Entry('user/commissionRate', ['cswap', 'v1', 'private'], 'GET', {'cost': 2})
|
89
|
+
cswap_v1_private_get_user_positions = cswapV1PrivateGetUserPositions = Entry('user/positions', ['cswap', 'v1', 'private'], 'GET', {'cost': 2})
|
90
|
+
cswap_v1_private_get_user_balance = cswapV1PrivateGetUserBalance = Entry('user/balance', ['cswap', 'v1', 'private'], 'GET', {'cost': 2})
|
91
|
+
cswap_v1_private_post_trade_order = cswapV1PrivatePostTradeOrder = Entry('trade/order', ['cswap', 'v1', 'private'], 'POST', {'cost': 2})
|
92
|
+
cswap_v1_private_post_trade_leverage = cswapV1PrivatePostTradeLeverage = Entry('trade/leverage', ['cswap', 'v1', 'private'], 'POST', {'cost': 2})
|
93
|
+
cswap_v1_private_post_trade_allopenorders = cswapV1PrivatePostTradeAllOpenOrders = Entry('trade/allOpenOrders', ['cswap', 'v1', 'private'], 'POST', {'cost': 2})
|
94
|
+
cswap_v1_private_post_trade_closeallpositions = cswapV1PrivatePostTradeCloseAllPositions = Entry('trade/closeAllPositions', ['cswap', 'v1', 'private'], 'POST', {'cost': 2})
|
79
95
|
contract_v1_private_get_allposition = contractV1PrivateGetAllPosition = Entry('allPosition', ['contract', 'v1', 'private'], 'GET', {'cost': 2})
|
80
96
|
contract_v1_private_get_allorders = contractV1PrivateGetAllOrders = Entry('allOrders', ['contract', 'v1', 'private'], 'GET', {'cost': 2})
|
81
97
|
contract_v1_private_get_balance = contractV1PrivateGetBalance = Entry('balance', ['contract', 'v1', 'private'], 'GET', {'cost': 2})
|
ccxt/async_support/__init__.py
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
# -----------------------------------------------------------------------------
|
4
4
|
|
5
|
-
__version__ = '4.3.
|
5
|
+
__version__ = '4.3.57'
|
6
6
|
|
7
7
|
# -----------------------------------------------------------------------------
|
8
8
|
|
@@ -24,7 +24,7 @@ from ccxt.async_support.base.throttler import Throttler
|
|
24
24
|
|
25
25
|
# -----------------------------------------------------------------------------
|
26
26
|
|
27
|
-
from ccxt.base.errors import BaseError, BadSymbol, BadRequest, BadResponse, ExchangeError, ExchangeNotAvailable, RequestTimeout, NotSupported, NullResponse, InvalidAddress, RateLimitExceeded
|
27
|
+
from ccxt.base.errors import BaseError, NetworkError, BadSymbol, BadRequest, BadResponse, ExchangeError, ExchangeNotAvailable, RequestTimeout, NotSupported, NullResponse, InvalidAddress, RateLimitExceeded
|
28
28
|
from ccxt.base.types import OrderType, OrderSide, OrderRequest, CancellationRequest
|
29
29
|
|
30
30
|
# -----------------------------------------------------------------------------
|
@@ -826,7 +826,23 @@ class Exchange(BaseExchange):
|
|
826
826
|
self.last_request_headers = request['headers']
|
827
827
|
self.last_request_body = request['body']
|
828
828
|
self.last_request_url = request['url']
|
829
|
-
|
829
|
+
retries = None
|
830
|
+
retries, params = self.handle_option_and_params(params, path, 'maxRetriesOnFailure', 0)
|
831
|
+
retryDelay = None
|
832
|
+
retryDelay, params = self.handle_option_and_params(params, path, 'maxRetriesOnFailureDelay', 0)
|
833
|
+
for i in range(0, retries + 1):
|
834
|
+
try:
|
835
|
+
return await self.fetch(request['url'], request['method'], request['headers'], request['body'])
|
836
|
+
except Exception as e:
|
837
|
+
if isinstance(e, NetworkError):
|
838
|
+
if i < retries:
|
839
|
+
if self.verbose:
|
840
|
+
self.log('Request failed with the error: ' + str(e) + ', retrying ' + (i + str(1)) + ' of ' + str(retries) + '...')
|
841
|
+
if (retryDelay is not None) and (retryDelay != 0):
|
842
|
+
await self.sleep(retryDelay)
|
843
|
+
continue
|
844
|
+
raise e
|
845
|
+
return None # self line is never reached, but exists for c# value return requirement
|
830
846
|
|
831
847
|
async def request(self, path, api: Any = 'public', method='GET', params={}, headers: Any = None, body: Any = None, config={}):
|
832
848
|
return await self.fetch2(path, api, method, params, headers, body, config)
|
@@ -4,7 +4,7 @@ from asyncio import sleep, ensure_future, wait_for, TimeoutError
|
|
4
4
|
from .functions import milliseconds, iso8601, deep_extend
|
5
5
|
from ccxt import NetworkError, RequestTimeout, NotSupported
|
6
6
|
from ccxt.async_support.base.ws.future import Future
|
7
|
-
|
7
|
+
from collections import deque
|
8
8
|
|
9
9
|
class Client(object):
|
10
10
|
|
@@ -14,6 +14,8 @@ class Client(object):
|
|
14
14
|
options = {} # ws-specific options
|
15
15
|
subscriptions = {}
|
16
16
|
rejections = {}
|
17
|
+
message_queue = {}
|
18
|
+
useMessageQueue = True
|
17
19
|
on_message_callback = None
|
18
20
|
on_error_callback = None
|
19
21
|
on_close_callback = None
|
@@ -68,15 +70,32 @@ class Client(object):
|
|
68
70
|
if message_hash in self.rejections:
|
69
71
|
future.reject(self.rejections[message_hash])
|
70
72
|
del self.rejections[message_hash]
|
73
|
+
del self.message_queue[message_hash]
|
74
|
+
return future
|
75
|
+
if self.useMessageQueue and message_hash in self.message_queue:
|
76
|
+
queue = self.message_queue[message_hash]
|
77
|
+
if len(queue):
|
78
|
+
future.resolve(queue.popleft())
|
71
79
|
return future
|
72
80
|
|
73
81
|
def resolve(self, result, message_hash):
|
74
82
|
if self.verbose and message_hash is None:
|
75
83
|
self.log(iso8601(milliseconds()), 'resolve received None messageHash')
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
84
|
+
|
85
|
+
if self.useMessageQueue:
|
86
|
+
if message_hash not in self.message_queue:
|
87
|
+
self.message_queue[message_hash] = deque(maxlen=10)
|
88
|
+
queue = self.message_queue[message_hash]
|
89
|
+
queue.append(result)
|
90
|
+
if message_hash in self.futures:
|
91
|
+
future = self.futures[message_hash]
|
92
|
+
future.resolve(queue.popleft())
|
93
|
+
del self.futures[message_hash]
|
94
|
+
else:
|
95
|
+
if message_hash in self.futures:
|
96
|
+
future = self.futures[message_hash]
|
97
|
+
future.resolve(result)
|
98
|
+
del self.futures[message_hash]
|
80
99
|
return result
|
81
100
|
|
82
101
|
def reject(self, result, message_hash=None):
|
@@ -165,6 +184,7 @@ class Client(object):
|
|
165
184
|
ensure_future(self.close(code), loop=self.asyncio_loop)
|
166
185
|
|
167
186
|
def reset(self, error):
|
187
|
+
self.message_queue = {}
|
168
188
|
self.reject(error)
|
169
189
|
|
170
190
|
async def ping_loop(self):
|
ccxt/async_support/binance.py
CHANGED
@@ -1567,7 +1567,7 @@ class binance(Exchange, ImplicitAPI):
|
|
1567
1567
|
'-3042': BadRequest, # {"code":-3042,"msg":"PriceIndex not available for self margin pair."}
|
1568
1568
|
'-3043': PermissionDenied, # {"code":-3043,"msg":"Transferring in not allowed."}
|
1569
1569
|
'-3044': OperationFailed, # {"code":-3044,"msg":"System busy."}
|
1570
|
-
'-3045':
|
1570
|
+
'-3045': OperationRejected, # {"code":-3045,"msg":"The system doesn't have enough asset now."}
|
1571
1571
|
'-3999': PermissionDenied, # {"code":-3999,"msg":"This function is only available for invited users."}
|
1572
1572
|
#
|
1573
1573
|
# 4xxx(different from contract markets)
|
@@ -1586,7 +1586,7 @@ class binance(Exchange, ImplicitAPI):
|
|
1586
1586
|
'-4011': BadRequest, # {"code":-4011 ,"msg":"White list mail is invalid."}
|
1587
1587
|
'-4012': PermissionDenied, # {"code":-4012 ,"msg":"White list is not opened."}
|
1588
1588
|
'-4013': AuthenticationError, # {"code":-4013 ,"msg":"2FA is not opened."}
|
1589
|
-
'-4014':
|
1589
|
+
'-4014': OperationRejected, # {"code":-4014 ,"msg":"Withdraw is not allowed within 2 min login."}
|
1590
1590
|
'-4015': PermissionDenied, # {"code":-4015 ,"msg":"Withdraw is limited."}
|
1591
1591
|
'-4016': PermissionDenied, # {"code":-4016 ,"msg":"Within 24 hours after password modification, withdrawal is prohibited."}
|
1592
1592
|
'-4017': PermissionDenied, # {"code":-4017 ,"msg":"Within 24 hours after the release of 2FA, withdrawal is prohibited."}
|
@@ -1595,7 +1595,7 @@ class binance(Exchange, ImplicitAPI):
|
|
1595
1595
|
'-4020': ExchangeError, # override commons
|
1596
1596
|
'-4021': BadRequest, # {"code":-4021,"msg":"Asset withdrawal must be an %s multiple of %s."}
|
1597
1597
|
'-4022': BadRequest, # {"code":-4022,"msg":"Not less than the minimum pick-up quantity %s."}
|
1598
|
-
'-4023':
|
1598
|
+
'-4023': OperationRejected, # {"code":-4023,"msg":"Within 24 hours, the withdrawal exceeds the maximum amount."}
|
1599
1599
|
'-4024': InsufficientFunds, # {"code":-4024,"msg":"You don't have self asset."}
|
1600
1600
|
'-4025': InsufficientFunds, # {"code":-4025,"msg":"The number of hold asset is less than zero."}
|
1601
1601
|
'-4026': InsufficientFunds, # {"code":-4026,"msg":"You have insufficient balance."}
|
@@ -1604,7 +1604,7 @@ class binance(Exchange, ImplicitAPI):
|
|
1604
1604
|
'-4029': BadRequest, # {"code":-4029,"msg":"The withdrawal record does not exist."}
|
1605
1605
|
'-4030': BadResponse, # {"code":-4030,"msg":"Confirmation of successful asset withdrawal. [TODO] possible bug in docs"}
|
1606
1606
|
'-4031': OperationFailed, # {"code":-4031,"msg":"Cancellation failed."}
|
1607
|
-
'-4032':
|
1607
|
+
'-4032': OperationRejected, # {"code":-4032,"msg":"Withdraw verification exception."}
|
1608
1608
|
'-4033': BadRequest, # {"code":-4033,"msg":"Illegal address."}
|
1609
1609
|
'-4034': OperationRejected, # {"code":-4034,"msg":"The address is suspected of fake."}
|
1610
1610
|
'-4035': PermissionDenied, # {"code":-4035,"msg":"This address is not on the whitelist. Please join and try again."}
|
@@ -1727,7 +1727,7 @@ class binance(Exchange, ImplicitAPI):
|
|
1727
1727
|
'-5003': InsufficientFunds, # You don't have self asset.
|
1728
1728
|
'-5004': OperationRejected, # The residual balances of %s have exceeded 0.001BTC, Please re-choose.
|
1729
1729
|
'-5005': OperationRejected, # The residual balances of %s is too low, Please re-choose.
|
1730
|
-
'-5006':
|
1730
|
+
'-5006': OperationRejected, # Only transfer once in 24 hours.
|
1731
1731
|
'-5007': BadRequest, # Quantity must be greater than zero.
|
1732
1732
|
'-5008': OperationRejected, # Insufficient amount of returnable assets.
|
1733
1733
|
'-5009': BadSymbol, # Product does not exist.
|
@@ -1745,8 +1745,8 @@ class binance(Exchange, ImplicitAPI):
|
|
1745
1745
|
'-6004': BadRequest, # Product not in purchase status
|
1746
1746
|
'-6005': BadRequest, # Smaller than min purchase limit
|
1747
1747
|
'-6006': BadRequest, # Redeem amount error
|
1748
|
-
'-6007':
|
1749
|
-
'-6008':
|
1748
|
+
'-6007': OperationRejected, # Not in redeem time
|
1749
|
+
'-6008': OperationRejected, # Product not in redeem status
|
1750
1750
|
'-6009': RateLimitExceeded, # Request frequency too high
|
1751
1751
|
'-6011': OperationRejected, # Exceeding the maximum num allowed to purchase per user
|
1752
1752
|
'-6012': InsufficientFunds, # Balance not enough
|
ccxt/async_support/bingx.py
CHANGED
@@ -116,6 +116,7 @@ class bingx(Exchange, ImplicitAPI):
|
|
116
116
|
'subAccount': 'https://open-api.{hostname}/openApi',
|
117
117
|
'account': 'https://open-api.{hostname}/openApi',
|
118
118
|
'copyTrading': 'https://open-api.{hostname}/openApi',
|
119
|
+
'cswap': 'https://open-api.{hostname}/openApi',
|
119
120
|
},
|
120
121
|
'test': {
|
121
122
|
'swap': 'https://open-api-vst.{hostname}/openApi', # only swap is really "test" but since the API keys are the same, we want to keep all the functionalities when the user enables the sandboxmode
|
@@ -278,6 +279,36 @@ class bingx(Exchange, ImplicitAPI):
|
|
278
279
|
},
|
279
280
|
},
|
280
281
|
},
|
282
|
+
'cswap': {
|
283
|
+
'v1': {
|
284
|
+
'public': {
|
285
|
+
'get': {
|
286
|
+
'market/contracts': 1,
|
287
|
+
'market/premiumIndex': 1,
|
288
|
+
'market/openInterest': 1,
|
289
|
+
'market/klines': 1,
|
290
|
+
'market/depth': 1,
|
291
|
+
'market/ticker': 1,
|
292
|
+
},
|
293
|
+
},
|
294
|
+
'private': {
|
295
|
+
'get': {
|
296
|
+
'trade/leverage': 2,
|
297
|
+
'trade/forceOrders': 2,
|
298
|
+
'trade/allFillOrders': 2,
|
299
|
+
'user/commissionRate': 2,
|
300
|
+
'user/positions': 2,
|
301
|
+
'user/balance': 2,
|
302
|
+
},
|
303
|
+
'post': {
|
304
|
+
'trade/order': 2,
|
305
|
+
'trade/leverage': 2,
|
306
|
+
'trade/allOpenOrders': 2,
|
307
|
+
'trade/closeAllPositions': 2,
|
308
|
+
},
|
309
|
+
},
|
310
|
+
},
|
311
|
+
},
|
281
312
|
'contract': {
|
282
313
|
'v1': {
|
283
314
|
'private': {
|
@@ -644,6 +675,29 @@ class bingx(Exchange, ImplicitAPI):
|
|
644
675
|
markets = self.safe_list(response, 'data', [])
|
645
676
|
return self.parse_markets(markets)
|
646
677
|
|
678
|
+
async def fetch_inverse_swap_markets(self, params):
|
679
|
+
response = await self.cswapV1PublicGetMarketContracts(params)
|
680
|
+
#
|
681
|
+
# {
|
682
|
+
# "code": 0,
|
683
|
+
# "msg": "",
|
684
|
+
# "timestamp": 1720074487610,
|
685
|
+
# "data": [
|
686
|
+
# {
|
687
|
+
# "symbol": "BNB-USD",
|
688
|
+
# "pricePrecision": 2,
|
689
|
+
# "minTickSize": "10",
|
690
|
+
# "minTradeValue": "10",
|
691
|
+
# "minQty": "1.00000000",
|
692
|
+
# "status": 1,
|
693
|
+
# "timeOnline": 1713175200000
|
694
|
+
# },
|
695
|
+
# ]
|
696
|
+
# }
|
697
|
+
#
|
698
|
+
markets = self.safe_list(response, 'data', [])
|
699
|
+
return self.parse_markets(markets)
|
700
|
+
|
647
701
|
def parse_market(self, market: dict) -> Market:
|
648
702
|
id = self.safe_string(market, 'symbol')
|
649
703
|
symbolParts = id.split('-')
|
@@ -652,6 +706,14 @@ class bingx(Exchange, ImplicitAPI):
|
|
652
706
|
base = self.safe_currency_code(baseId)
|
653
707
|
quote = self.safe_currency_code(quoteId)
|
654
708
|
currency = self.safe_string(market, 'currency')
|
709
|
+
checkIsInverse = False
|
710
|
+
checkIsLinear = True
|
711
|
+
minTickSize = self.safe_number(market, 'minTickSize')
|
712
|
+
if minTickSize is not None:
|
713
|
+
# inverse swap market
|
714
|
+
currency = baseId
|
715
|
+
checkIsInverse = True
|
716
|
+
checkIsLinear = False
|
655
717
|
settle = self.safe_currency_code(currency)
|
656
718
|
pricePrecision = self.safe_number(market, 'tickSize')
|
657
719
|
if pricePrecision is None:
|
@@ -668,8 +730,11 @@ class bingx(Exchange, ImplicitAPI):
|
|
668
730
|
fees = self.safe_dict(self.fees, type, {})
|
669
731
|
contractSize = self.parse_number('1') if (swap) else None
|
670
732
|
isActive = self.safe_string(market, 'status') == '1'
|
671
|
-
isInverse = None if (spot) else
|
672
|
-
isLinear = None if (spot) else
|
733
|
+
isInverse = None if (spot) else checkIsInverse
|
734
|
+
isLinear = None if (spot) else checkIsLinear
|
735
|
+
timeOnline = self.safe_integer(market, 'timeOnline')
|
736
|
+
if timeOnline == 0:
|
737
|
+
timeOnline = None
|
673
738
|
return self.safe_market_structure({
|
674
739
|
'id': id,
|
675
740
|
'symbol': symbol,
|
@@ -711,15 +776,15 @@ class bingx(Exchange, ImplicitAPI):
|
|
711
776
|
'max': self.safe_number(market, 'maxQty'),
|
712
777
|
},
|
713
778
|
'price': {
|
714
|
-
'min':
|
779
|
+
'min': minTickSize,
|
715
780
|
'max': None,
|
716
781
|
},
|
717
782
|
'cost': {
|
718
|
-
'min': self.
|
783
|
+
'min': self.safe_number_n(market, ['minNotional', 'tradeMinUSDT', 'minTradeValue']),
|
719
784
|
'max': self.safe_number(market, 'maxNotional'),
|
720
785
|
},
|
721
786
|
},
|
722
|
-
'created':
|
787
|
+
'created': timeOnline,
|
723
788
|
'info': market,
|
724
789
|
})
|
725
790
|
|
@@ -728,16 +793,20 @@ class bingx(Exchange, ImplicitAPI):
|
|
728
793
|
retrieves data on all markets for bingx
|
729
794
|
:see: https://bingx-api.github.io/docs/#/spot/market-api.html#Query%20Symbols
|
730
795
|
:see: https://bingx-api.github.io/docs/#/swapV2/market-api.html#Contract%20Information
|
796
|
+
:see: https://bingx-api.github.io/docs/#/en-us/cswap/market-api.html#Contract%20Information
|
731
797
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
732
798
|
:returns dict[]: an array of objects representing market data
|
733
799
|
"""
|
734
800
|
requests = [self.fetch_swap_markets(params)]
|
735
801
|
isSandbox = self.safe_bool(self.options, 'sandboxMode', False)
|
736
802
|
if not isSandbox:
|
803
|
+
requests.append(self.fetch_inverse_swap_markets(params))
|
737
804
|
requests.append(self.fetch_spot_markets(params)) # sandbox is swap only
|
738
805
|
promises = await asyncio.gather(*requests)
|
739
|
-
|
740
|
-
|
806
|
+
linearSwapMarkets = self.safe_list(promises, 0, [])
|
807
|
+
inverseSwapMarkets = self.safe_list(promises, 1, [])
|
808
|
+
spotMarkets = self.safe_list(promises, 2, [])
|
809
|
+
swapMarkets = self.array_concat(linearSwapMarkets, inverseSwapMarkets)
|
741
810
|
return self.array_concat(spotMarkets, swapMarkets)
|
742
811
|
|
743
812
|
async def fetch_ohlcv(self, symbol: str, timeframe='1m', since: Int = None, limit: Int = None, params={}) -> List[list]:
|
@@ -1466,6 +1535,8 @@ class bingx(Exchange, ImplicitAPI):
|
|
1466
1535
|
percentage = percentage.replace('%', '')
|
1467
1536
|
change = self.safe_string(ticker, 'priceChange')
|
1468
1537
|
ts = self.safe_integer(ticker, 'closeTime')
|
1538
|
+
if ts == 0:
|
1539
|
+
ts = None
|
1469
1540
|
datetime = self.iso8601(ts)
|
1470
1541
|
bid = self.safe_string(ticker, 'bidPrice')
|
1471
1542
|
bidVolume = self.safe_string(ticker, 'bidQty')
|
ccxt/async_support/bitflyer.py
CHANGED
@@ -566,7 +566,13 @@ class bitflyer(Exchange, ImplicitAPI):
|
|
566
566
|
'product_code': self.market_id(symbol),
|
567
567
|
'child_order_acceptance_id': id,
|
568
568
|
}
|
569
|
-
|
569
|
+
response = await self.privatePostCancelchildorder(self.extend(request, params))
|
570
|
+
#
|
571
|
+
# 200 OK.
|
572
|
+
#
|
573
|
+
return self.safe_order({
|
574
|
+
'info': response,
|
575
|
+
})
|
570
576
|
|
571
577
|
def parse_order_status(self, status: Str):
|
572
578
|
statuses: dict = {
|
ccxt/async_support/bitget.py
CHANGED
@@ -4692,6 +4692,22 @@ class bitget(Exchange, ImplicitAPI):
|
|
4692
4692
|
response = await self.privateMarginPostMarginV1CrossOrderBatchCancelOrder(self.extend(request, params))
|
4693
4693
|
else:
|
4694
4694
|
response = await self.privateMarginPostMarginV1IsolatedOrderBatchCancelOrder(self.extend(request, params))
|
4695
|
+
#
|
4696
|
+
# {
|
4697
|
+
# "code": "00000",
|
4698
|
+
# "msg": "success",
|
4699
|
+
# "requestTime": 1700717155622,
|
4700
|
+
# "data": {
|
4701
|
+
# "resultList": [
|
4702
|
+
# {
|
4703
|
+
# "orderId": "1111453253721796609",
|
4704
|
+
# "clientOid": "2ae7fc8a4ff949b6b60d770ca3950e2d"
|
4705
|
+
# },
|
4706
|
+
# ],
|
4707
|
+
# "failure": []
|
4708
|
+
# }
|
4709
|
+
# }
|
4710
|
+
#
|
4695
4711
|
else:
|
4696
4712
|
if stop:
|
4697
4713
|
stopRequest: dict = {
|
@@ -4700,6 +4716,27 @@ class bitget(Exchange, ImplicitAPI):
|
|
4700
4716
|
response = await self.privateSpotPostV2SpotTradeBatchCancelPlanOrder(self.extend(stopRequest, params))
|
4701
4717
|
else:
|
4702
4718
|
response = await self.privateSpotPostV2SpotTradeCancelSymbolOrder(self.extend(request, params))
|
4719
|
+
#
|
4720
|
+
# {
|
4721
|
+
# "code": "00000",
|
4722
|
+
# "msg": "success",
|
4723
|
+
# "requestTime": 1700716953996,
|
4724
|
+
# "data": {
|
4725
|
+
# "symbol": "BTCUSDT"
|
4726
|
+
# }
|
4727
|
+
# }
|
4728
|
+
#
|
4729
|
+
timestamp = self.safe_integer(response, 'requestTime')
|
4730
|
+
responseData = self.safe_dict(response, 'data')
|
4731
|
+
marketId = self.safe_string(responseData, 'symbol')
|
4732
|
+
return [
|
4733
|
+
self.safe_order({
|
4734
|
+
'info': response,
|
4735
|
+
'symbol': self.safe_symbol(marketId, None, None, 'spot'),
|
4736
|
+
'timestamp': timestamp,
|
4737
|
+
'datetime': self.iso8601(timestamp),
|
4738
|
+
}),
|
4739
|
+
]
|
4703
4740
|
else:
|
4704
4741
|
productType = None
|
4705
4742
|
productType, params = self.handle_product_type_and_params(market, params)
|
@@ -4708,53 +4745,25 @@ class bitget(Exchange, ImplicitAPI):
|
|
4708
4745
|
response = await self.privateMixPostV2MixOrderCancelPlanOrder(self.extend(request, params))
|
4709
4746
|
else:
|
4710
4747
|
response = await self.privateMixPostV2MixOrderBatchCancelOrders(self.extend(request, params))
|
4711
|
-
|
4712
|
-
|
4713
|
-
|
4714
|
-
|
4715
|
-
|
4716
|
-
|
4717
|
-
|
4718
|
-
|
4719
|
-
|
4720
|
-
|
4721
|
-
|
4722
|
-
|
4723
|
-
|
4724
|
-
|
4725
|
-
|
4726
|
-
|
4727
|
-
|
4728
|
-
|
4729
|
-
|
4730
|
-
# "successList": [
|
4731
|
-
# {
|
4732
|
-
# "orderId": "1024598257429823488",
|
4733
|
-
# "clientOid": "876493ce-c287-4bfc-9f4a-8b1905881313"
|
4734
|
-
# },
|
4735
|
-
# ],
|
4736
|
-
# "failureList": []
|
4737
|
-
# }
|
4738
|
-
# }
|
4739
|
-
#
|
4740
|
-
# spot margin
|
4741
|
-
#
|
4742
|
-
# {
|
4743
|
-
# "code": "00000",
|
4744
|
-
# "msg": "success",
|
4745
|
-
# "requestTime": 1700717155622,
|
4746
|
-
# "data": {
|
4747
|
-
# "resultList": [
|
4748
|
-
# {
|
4749
|
-
# "orderId": "1111453253721796609",
|
4750
|
-
# "clientOid": "2ae7fc8a4ff949b6b60d770ca3950e2d"
|
4751
|
-
# },
|
4752
|
-
# ],
|
4753
|
-
# "failure": []
|
4754
|
-
# }
|
4755
|
-
# }
|
4756
|
-
#
|
4757
|
-
return response
|
4748
|
+
# {
|
4749
|
+
# "code": "00000",
|
4750
|
+
# "msg": "success",
|
4751
|
+
# "requestTime": "1680008815965",
|
4752
|
+
# "data": {
|
4753
|
+
# "successList": [
|
4754
|
+
# {
|
4755
|
+
# "orderId": "1024598257429823488",
|
4756
|
+
# "clientOid": "876493ce-c287-4bfc-9f4a-8b1905881313"
|
4757
|
+
# },
|
4758
|
+
# ],
|
4759
|
+
# "failureList": []
|
4760
|
+
# }
|
4761
|
+
# }
|
4762
|
+
data = self.safe_dict(response, 'data')
|
4763
|
+
resultList = self.safe_list_2(data, 'resultList', 'successList')
|
4764
|
+
failureList = self.safe_list_2(data, 'failure', 'failureList')
|
4765
|
+
responseList = self.array_concat(resultList, failureList)
|
4766
|
+
return self.parse_orders(responseList)
|
4758
4767
|
|
4759
4768
|
async def fetch_order(self, id: str, symbol: Str = None, params={}):
|
4760
4769
|
"""
|
ccxt/async_support/bitopro.py
CHANGED
@@ -1038,6 +1038,20 @@ class bitopro(Exchange, ImplicitAPI):
|
|
1038
1038
|
#
|
1039
1039
|
return self.parse_order(response, market)
|
1040
1040
|
|
1041
|
+
def parse_cancel_orders(self, data):
|
1042
|
+
dataKeys = list(data.keys())
|
1043
|
+
orders = []
|
1044
|
+
for i in range(0, len(dataKeys)):
|
1045
|
+
marketId = dataKeys[i]
|
1046
|
+
orderIds = data[marketId]
|
1047
|
+
for j in range(0, len(orderIds)):
|
1048
|
+
orders.append(self.safe_order({
|
1049
|
+
'info': orderIds[j],
|
1050
|
+
'id': orderIds[j],
|
1051
|
+
'symbol': self.safe_symbol(marketId),
|
1052
|
+
}))
|
1053
|
+
return orders
|
1054
|
+
|
1041
1055
|
async def cancel_orders(self, ids, symbol: Str = None, params={}):
|
1042
1056
|
"""
|
1043
1057
|
cancel multiple orders
|
@@ -1065,7 +1079,8 @@ class bitopro(Exchange, ImplicitAPI):
|
|
1065
1079
|
# }
|
1066
1080
|
# }
|
1067
1081
|
#
|
1068
|
-
|
1082
|
+
data = self.safe_dict(response, 'data')
|
1083
|
+
return self.parse_cancel_orders(data)
|
1069
1084
|
|
1070
1085
|
async def cancel_all_orders(self, symbol: Str = None, params={}):
|
1071
1086
|
"""
|
@@ -1086,7 +1101,7 @@ class bitopro(Exchange, ImplicitAPI):
|
|
1086
1101
|
response = await self.privateDeleteOrdersPair(self.extend(request, params))
|
1087
1102
|
else:
|
1088
1103
|
response = await self.privateDeleteOrdersAll(self.extend(request, params))
|
1089
|
-
|
1104
|
+
data = self.safe_value(response, 'data', {})
|
1090
1105
|
#
|
1091
1106
|
# {
|
1092
1107
|
# "data":{
|
@@ -1097,7 +1112,7 @@ class bitopro(Exchange, ImplicitAPI):
|
|
1097
1112
|
# }
|
1098
1113
|
# }
|
1099
1114
|
#
|
1100
|
-
return
|
1115
|
+
return self.parse_cancel_orders(data)
|
1101
1116
|
|
1102
1117
|
async def fetch_order(self, id: str, symbol: Str = None, params={}):
|
1103
1118
|
"""
|
ccxt/async_support/btcmarkets.py
CHANGED
@@ -14,7 +14,6 @@ from ccxt.base.errors import BadRequest
|
|
14
14
|
from ccxt.base.errors import InsufficientFunds
|
15
15
|
from ccxt.base.errors import InvalidOrder
|
16
16
|
from ccxt.base.errors import OrderNotFound
|
17
|
-
from ccxt.base.errors import DDoSProtection
|
18
17
|
from ccxt.base.decimal_to_precision import TICK_SIZE
|
19
18
|
from ccxt.base.precise import Precise
|
20
19
|
|
@@ -161,16 +160,18 @@ class btcmarkets(Exchange, ImplicitAPI):
|
|
161
160
|
},
|
162
161
|
'precisionMode': TICK_SIZE,
|
163
162
|
'exceptions': {
|
164
|
-
'
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
163
|
+
'exact': {
|
164
|
+
'InsufficientFund': InsufficientFunds,
|
165
|
+
'InvalidPrice': InvalidOrder,
|
166
|
+
'InvalidAmount': InvalidOrder,
|
167
|
+
'MissingArgument': BadRequest,
|
168
|
+
'OrderAlreadyCancelled': InvalidOrder,
|
169
|
+
'OrderNotFound': OrderNotFound,
|
170
|
+
'OrderStatusIsFinal': InvalidOrder,
|
171
|
+
'InvalidPaginationParameter': BadRequest,
|
172
|
+
},
|
173
|
+
'broad': {
|
174
|
+
},
|
174
175
|
},
|
175
176
|
'fees': {
|
176
177
|
'percentage': True,
|
@@ -370,7 +371,8 @@ class btcmarkets(Exchange, ImplicitAPI):
|
|
370
371
|
# "minOrderAmount":"0.00007",
|
371
372
|
# "maxOrderAmount":"1000000",
|
372
373
|
# "amountDecimals":"8",
|
373
|
-
# "priceDecimals":"2"
|
374
|
+
# "priceDecimals":"2",
|
375
|
+
# "status": "Online"
|
374
376
|
# }
|
375
377
|
# ]
|
376
378
|
#
|
@@ -387,6 +389,7 @@ class btcmarkets(Exchange, ImplicitAPI):
|
|
387
389
|
pricePrecision = self.parse_number(self.parse_precision(self.safe_string(market, 'priceDecimals')))
|
388
390
|
minAmount = self.safe_number(market, 'minOrderAmount')
|
389
391
|
maxAmount = self.safe_number(market, 'maxOrderAmount')
|
392
|
+
status = self.safe_string(market, 'status')
|
390
393
|
minPrice = None
|
391
394
|
if quote == 'AUD':
|
392
395
|
minPrice = pricePrecision
|
@@ -405,7 +408,7 @@ class btcmarkets(Exchange, ImplicitAPI):
|
|
405
408
|
'swap': False,
|
406
409
|
'future': False,
|
407
410
|
'option': False,
|
408
|
-
'active':
|
411
|
+
'active': (status == 'Online'),
|
409
412
|
'contract': False,
|
410
413
|
'linear': None,
|
411
414
|
'inverse': None,
|
@@ -1204,18 +1207,16 @@ class btcmarkets(Exchange, ImplicitAPI):
|
|
1204
1207
|
def handle_errors(self, code: int, reason: str, url: str, method: str, headers: dict, body: str, response, requestHeaders, requestBody):
|
1205
1208
|
if response is None:
|
1206
1209
|
return None # fallback to default error handler
|
1207
|
-
|
1208
|
-
|
1209
|
-
|
1210
|
-
|
1211
|
-
|
1212
|
-
|
1213
|
-
|
1214
|
-
if code >= 400:
|
1215
|
-
errorCode = self.safe_string(response, 'code')
|
1216
|
-
message = self.safe_string(response, 'message')
|
1210
|
+
#
|
1211
|
+
# {"code":"UnAuthorized","message":"invalid access token"}
|
1212
|
+
# {"code":"MarketNotFound","message":"invalid marketId"}
|
1213
|
+
#
|
1214
|
+
errorCode = self.safe_string(response, 'code')
|
1215
|
+
message = self.safe_string(response, 'message')
|
1216
|
+
if errorCode is not None:
|
1217
1217
|
feedback = self.id + ' ' + body
|
1218
|
-
self.throw_exactly_matched_exception(self.exceptions,
|
1219
|
-
self.throw_exactly_matched_exception(self.exceptions,
|
1220
|
-
|
1218
|
+
self.throw_exactly_matched_exception(self.exceptions['exact'], message, feedback)
|
1219
|
+
self.throw_exactly_matched_exception(self.exceptions['exact'], errorCode, feedback)
|
1220
|
+
self.throw_broadly_matched_exception(self.exceptions['broad'], message, feedback)
|
1221
|
+
raise ExchangeError(feedback) # unknown message
|
1221
1222
|
return None
|