ccxt 4.3.66__py2.py3-none-any.whl → 4.3.68__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/bingx.py +7 -0
- ccxt/async_support/__init__.py +1 -1
- ccxt/async_support/base/exchange.py +1 -1
- ccxt/async_support/bingx.py +462 -159
- ccxt/async_support/bitget.py +3 -2
- ccxt/async_support/bithumb.py +60 -17
- ccxt/async_support/whitebit.py +1 -1
- ccxt/async_support/zonda.py +1 -1
- ccxt/base/exchange.py +14 -13
- ccxt/bingx.py +462 -159
- ccxt/bitget.py +3 -2
- ccxt/bithumb.py +59 -17
- ccxt/pro/__init__.py +1 -1
- ccxt/pro/bitget.py +1 -1
- ccxt/pro/bybit.py +1 -1
- ccxt/pro/coinone.py +1 -1
- ccxt/pro/currencycom.py +1 -1
- ccxt/pro/hollaex.py +1 -1
- ccxt/pro/hyperliquid.py +1 -1
- ccxt/pro/krakenfutures.py +7 -6
- ccxt/pro/kucoin.py +1 -1
- ccxt/pro/kucoinfutures.py +1 -1
- ccxt/pro/mexc.py +1 -1
- ccxt/pro/okcoin.py +1 -1
- ccxt/pro/okx.py +16 -4
- ccxt/pro/oxfun.py +1 -1
- ccxt/pro/p2b.py +1 -1
- ccxt/pro/poloniex.py +1 -1
- ccxt/pro/whitebit.py +1 -1
- ccxt/test/tests_async.py +58 -28
- ccxt/test/tests_helpers.py +8 -1
- ccxt/test/tests_sync.py +58 -28
- ccxt/whitebit.py +1 -1
- ccxt/zonda.py +1 -1
- {ccxt-4.3.66.dist-info → ccxt-4.3.68.dist-info}/METADATA +4 -4
- {ccxt-4.3.66.dist-info → ccxt-4.3.68.dist-info}/RECORD +40 -40
- {ccxt-4.3.66.dist-info → ccxt-4.3.68.dist-info}/LICENSE.txt +0 -0
- {ccxt-4.3.66.dist-info → ccxt-4.3.68.dist-info}/WHEEL +0 -0
- {ccxt-4.3.66.dist-info → ccxt-4.3.68.dist-info}/top_level.txt +0 -0
ccxt/bitget.py
CHANGED
@@ -4867,8 +4867,9 @@ class bitget(Exchange, ImplicitAPI):
|
|
4867
4867
|
if isinstance(response, str):
|
4868
4868
|
response = json.loads(response)
|
4869
4869
|
data = self.safe_dict(response, 'data')
|
4870
|
-
if (data is not None)
|
4871
|
-
|
4870
|
+
if (data is not None):
|
4871
|
+
if not isinstance(data, list):
|
4872
|
+
return self.parse_order(data, market)
|
4872
4873
|
dataList = self.safe_list(response, 'data', [])
|
4873
4874
|
first = self.safe_dict(dataList, 0, {})
|
4874
4875
|
return self.parse_order(first, market)
|
ccxt/bithumb.py
CHANGED
@@ -212,17 +212,56 @@ class bithumb(Exchange, ImplicitAPI):
|
|
212
212
|
:returns dict[]: an array of objects representing market data
|
213
213
|
"""
|
214
214
|
result = []
|
215
|
-
quoteCurrencies = self.
|
215
|
+
quoteCurrencies = self.safe_dict(self.options, 'quoteCurrencies', {})
|
216
216
|
quotes = list(quoteCurrencies.keys())
|
217
|
+
promises = []
|
218
|
+
for i in range(0, len(quotes)):
|
219
|
+
request = {
|
220
|
+
'quoteId': quotes[i],
|
221
|
+
}
|
222
|
+
promises.append(self.publicGetTickerALLQuoteId(self.extend(request, params)))
|
223
|
+
#
|
224
|
+
# {
|
225
|
+
# "status": "0000",
|
226
|
+
# "data": {
|
227
|
+
# "ETH": {
|
228
|
+
# "opening_price": "0.05153399",
|
229
|
+
# "closing_price": "0.05145144",
|
230
|
+
# "min_price": "0.05145144",
|
231
|
+
# "max_price": "0.05160781",
|
232
|
+
# "units_traded": "6.541124172077830855",
|
233
|
+
# "acc_trade_value": "0.33705472498492329997697755",
|
234
|
+
# "prev_closing_price": "0.0515943",
|
235
|
+
# "units_traded_24H": "43.368879902677400513",
|
236
|
+
# "acc_trade_value_24H": "2.24165339555398079994373342",
|
237
|
+
# "fluctate_24H": "-0.00018203",
|
238
|
+
# "fluctate_rate_24H": "-0.35"
|
239
|
+
# },
|
240
|
+
# "XRP": {
|
241
|
+
# "opening_price": "0.00000918",
|
242
|
+
# "closing_price": "0.0000092",
|
243
|
+
# "min_price": "0.00000918",
|
244
|
+
# "max_price": "0.0000092",
|
245
|
+
# "units_traded": "6516.949363",
|
246
|
+
# "acc_trade_value": "0.0598792533602796",
|
247
|
+
# "prev_closing_price": "0.00000916",
|
248
|
+
# "units_traded_24H": "229161.50354738",
|
249
|
+
# "acc_trade_value_24H": "2.0446589371637117",
|
250
|
+
# "fluctate_24H": "0.00000049",
|
251
|
+
# "fluctate_rate_24H": "5.63"
|
252
|
+
# },
|
253
|
+
# ...
|
254
|
+
# "date": "1721675913145"
|
255
|
+
# }
|
256
|
+
# }
|
257
|
+
#
|
258
|
+
results = promises
|
217
259
|
for i in range(0, len(quotes)):
|
218
260
|
quote = quotes[i]
|
219
261
|
quoteId = quote
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
}
|
224
|
-
response = self.publicGetTickerALLQuoteId(self.extend(request, params))
|
225
|
-
data = self.safe_value(response, 'data')
|
262
|
+
response = results[i]
|
263
|
+
data = self.safe_dict(response, 'data')
|
264
|
+
extension = self.safe_dict(quoteCurrencies, quote, {})
|
226
265
|
currencyIds = list(data.keys())
|
227
266
|
for j in range(0, len(currencyIds)):
|
228
267
|
currencyId = currencyIds[j]
|
@@ -286,7 +325,7 @@ class bithumb(Exchange, ImplicitAPI):
|
|
286
325
|
|
287
326
|
def parse_balance(self, response) -> Balances:
|
288
327
|
result: dict = {'info': response}
|
289
|
-
balances = self.
|
328
|
+
balances = self.safe_dict(response, 'data')
|
290
329
|
codes = list(self.currencies.keys())
|
291
330
|
for i in range(0, len(codes)):
|
292
331
|
code = codes[i]
|
@@ -351,7 +390,7 @@ class bithumb(Exchange, ImplicitAPI):
|
|
351
390
|
# }
|
352
391
|
# }
|
353
392
|
#
|
354
|
-
data = self.
|
393
|
+
data = self.safe_dict(response, 'data', {})
|
355
394
|
timestamp = self.safe_integer(data, 'timestamp')
|
356
395
|
return self.parse_order_book(data, symbol, timestamp, 'bids', 'asks', 'price', 'quantity')
|
357
396
|
|
@@ -413,15 +452,18 @@ class bithumb(Exchange, ImplicitAPI):
|
|
413
452
|
"""
|
414
453
|
self.load_markets()
|
415
454
|
result: dict = {}
|
416
|
-
quoteCurrencies = self.
|
455
|
+
quoteCurrencies = self.safe_dict(self.options, 'quoteCurrencies', {})
|
417
456
|
quotes = list(quoteCurrencies.keys())
|
457
|
+
promises = []
|
418
458
|
for i in range(0, len(quotes)):
|
419
|
-
quote = quotes[i]
|
420
|
-
quoteId = quote
|
421
459
|
request: dict = {
|
422
|
-
'quoteId':
|
460
|
+
'quoteId': quotes[i],
|
423
461
|
}
|
424
|
-
|
462
|
+
promises.append(self.publicGetTickerALLQuoteId(self.extend(request, params)))
|
463
|
+
responses = promises
|
464
|
+
for i in range(0, len(quotes)):
|
465
|
+
quote = quotes[i]
|
466
|
+
response = responses[i]
|
425
467
|
#
|
426
468
|
# {
|
427
469
|
# "status":"0000",
|
@@ -443,7 +485,7 @@ class bithumb(Exchange, ImplicitAPI):
|
|
443
485
|
# }
|
444
486
|
# }
|
445
487
|
#
|
446
|
-
data = self.
|
488
|
+
data = self.safe_dict(response, 'data', {})
|
447
489
|
timestamp = self.safe_integer(data, 'date')
|
448
490
|
tickers = self.omit(data, 'date')
|
449
491
|
currencyIds = list(tickers.keys())
|
@@ -805,7 +847,7 @@ class bithumb(Exchange, ImplicitAPI):
|
|
805
847
|
# }
|
806
848
|
#
|
807
849
|
timestamp = self.safe_integer_product(order, 'order_date', 0.001)
|
808
|
-
sideProperty = self.
|
850
|
+
sideProperty = self.safe_string_2(order, 'type', 'side')
|
809
851
|
side = 'buy' if (sideProperty == 'bid') else 'sell'
|
810
852
|
status = self.parse_order_status(self.safe_string(order, 'order_status'))
|
811
853
|
price = self.safe_string_2(order, 'order_price', 'price')
|
@@ -830,7 +872,7 @@ class bithumb(Exchange, ImplicitAPI):
|
|
830
872
|
market = self.safe_market(None, market)
|
831
873
|
symbol = market['symbol']
|
832
874
|
id = self.safe_string(order, 'order_id')
|
833
|
-
rawTrades = self.
|
875
|
+
rawTrades = self.safe_list(order, 'contract', [])
|
834
876
|
return self.safe_order({
|
835
877
|
'info': order,
|
836
878
|
'id': id,
|
ccxt/pro/__init__.py
CHANGED
ccxt/pro/bitget.py
CHANGED
@@ -1678,7 +1678,7 @@ class bitget(ccxt.async_support.bitget):
|
|
1678
1678
|
if topic.find('books') >= 0:
|
1679
1679
|
self.handle_order_book(client, message)
|
1680
1680
|
|
1681
|
-
def ping(self, client):
|
1681
|
+
def ping(self, client: Client):
|
1682
1682
|
return 'ping'
|
1683
1683
|
|
1684
1684
|
def handle_pong(self, client: Client, message):
|
ccxt/pro/bybit.py
CHANGED
@@ -1962,7 +1962,7 @@ class bybit(ccxt.async_support.bybit):
|
|
1962
1962
|
if type == 'AUTH_RESP':
|
1963
1963
|
self.handle_authenticate(client, message)
|
1964
1964
|
|
1965
|
-
def ping(self, client):
|
1965
|
+
def ping(self, client: Client):
|
1966
1966
|
return {
|
1967
1967
|
'req_id': self.request_id(),
|
1968
1968
|
'op': 'ping',
|
ccxt/pro/coinone.py
CHANGED
ccxt/pro/currencycom.py
CHANGED
ccxt/pro/hollaex.py
CHANGED
@@ -546,7 +546,7 @@ class hollaex(ccxt.async_support.hollaex):
|
|
546
546
|
if method is not None:
|
547
547
|
method(client, message)
|
548
548
|
|
549
|
-
def ping(self, client):
|
549
|
+
def ping(self, client: Client):
|
550
550
|
# hollaex does not support built-in ws protocol-level ping-pong
|
551
551
|
return {'op': 'ping'}
|
552
552
|
|
ccxt/pro/hyperliquid.py
CHANGED
ccxt/pro/krakenfutures.py
CHANGED
@@ -82,16 +82,16 @@ class krakenfutures(ccxt.async_support.krakenfutures):
|
|
82
82
|
url = self.urls['api']['ws']
|
83
83
|
messageHash = 'challenge'
|
84
84
|
client = self.client(url)
|
85
|
-
future =
|
86
|
-
|
85
|
+
future = client.future(messageHash)
|
86
|
+
authenticated = self.safe_value(client.subscriptions, messageHash)
|
87
|
+
if authenticated is None:
|
87
88
|
request: dict = {
|
88
89
|
'event': 'challenge',
|
89
90
|
'api_key': self.apiKey,
|
90
91
|
}
|
91
92
|
message = self.extend(request, params)
|
92
|
-
|
93
|
-
|
94
|
-
return future
|
93
|
+
self.watch(url, messageHash, message, messageHash)
|
94
|
+
return await future
|
95
95
|
|
96
96
|
async def watch_order_book_for_symbols(self, symbols: List[str], limit: Int = None, params={}) -> OrderBook:
|
97
97
|
"""
|
@@ -1483,7 +1483,8 @@ class krakenfutures(ccxt.async_support.krakenfutures):
|
|
1483
1483
|
signature = self.hmac(hashedChallenge, base64Secret, hashlib.sha512, 'base64')
|
1484
1484
|
self.options['challenge'] = challenge
|
1485
1485
|
self.options['signedChallenge'] = signature
|
1486
|
-
client.
|
1486
|
+
future = self.safe_value(client.futures, messageHash)
|
1487
|
+
future.resolve(True)
|
1487
1488
|
else:
|
1488
1489
|
error = AuthenticationError(self.id + ' ' + self.json(message))
|
1489
1490
|
client.reject(error, messageHash)
|
ccxt/pro/kucoin.py
CHANGED
@@ -1155,7 +1155,7 @@ class kucoin(ccxt.async_support.kucoin):
|
|
1155
1155
|
if method is not None:
|
1156
1156
|
method(client, message)
|
1157
1157
|
|
1158
|
-
def ping(self, client):
|
1158
|
+
def ping(self, client: Client):
|
1159
1159
|
# kucoin does not support built-in ws protocol-level ping-pong
|
1160
1160
|
# instead it requires a custom json-based text ping-pong
|
1161
1161
|
# https://docs.kucoin.com/#ping
|
ccxt/pro/kucoinfutures.py
CHANGED
@@ -1035,7 +1035,7 @@ class kucoinfutures(ccxt.async_support.kucoinfutures):
|
|
1035
1035
|
else:
|
1036
1036
|
return elementName + 's@all'
|
1037
1037
|
|
1038
|
-
def ping(self, client):
|
1038
|
+
def ping(self, client: Client):
|
1039
1039
|
# kucoin does not support built-in ws protocol-level ping-pong
|
1040
1040
|
# instead it requires a custom json-based text ping-pong
|
1041
1041
|
# https://docs.kucoin.com/#ping
|
ccxt/pro/mexc.py
CHANGED
ccxt/pro/okcoin.py
CHANGED
@@ -573,7 +573,7 @@ class okcoin(ccxt.async_support.okcoin):
|
|
573
573
|
client.resolve(message, 'authenticated')
|
574
574
|
return message
|
575
575
|
|
576
|
-
def ping(self, client):
|
576
|
+
def ping(self, client: Client):
|
577
577
|
# okex does not support built-in ws protocol-level ping-pong
|
578
578
|
# instead it requires custom text-based ping-pong
|
579
579
|
return 'ping'
|
ccxt/pro/okx.py
CHANGED
@@ -13,6 +13,7 @@ from ccxt.base.errors import ExchangeError
|
|
13
13
|
from ccxt.base.errors import AuthenticationError
|
14
14
|
from ccxt.base.errors import ArgumentsRequired
|
15
15
|
from ccxt.base.errors import BadRequest
|
16
|
+
from ccxt.base.errors import InvalidNonce
|
16
17
|
from ccxt.base.errors import ChecksumError
|
17
18
|
|
18
19
|
|
@@ -836,7 +837,7 @@ class okx(ccxt.async_support.okx):
|
|
836
837
|
for i in range(0, len(deltas)):
|
837
838
|
self.handle_delta(bookside, deltas[i])
|
838
839
|
|
839
|
-
def handle_order_book_message(self, client: Client, message, orderbook, messageHash):
|
840
|
+
def handle_order_book_message(self, client: Client, message, orderbook, messageHash, market=None):
|
840
841
|
#
|
841
842
|
# {
|
842
843
|
# "asks": [
|
@@ -851,6 +852,9 @@ class okx(ccxt.async_support.okx):
|
|
851
852
|
# ],
|
852
853
|
# "instId": "BTC-USDT",
|
853
854
|
# "ts": "1626537446491"
|
855
|
+
# "checksum": -855196043,
|
856
|
+
# "prevSeqId": 123456,
|
857
|
+
# "seqId": 123457
|
854
858
|
# }
|
855
859
|
#
|
856
860
|
asks = self.safe_value(message, 'asks', [])
|
@@ -860,9 +864,12 @@ class okx(ccxt.async_support.okx):
|
|
860
864
|
self.handle_deltas(storedAsks, asks)
|
861
865
|
self.handle_deltas(storedBids, bids)
|
862
866
|
marketId = self.safe_string(message, 'instId')
|
863
|
-
symbol = self.safe_symbol(marketId)
|
867
|
+
symbol = self.safe_symbol(marketId, market)
|
864
868
|
checksum = self.handle_option('watchOrderBook', 'checksum', True)
|
869
|
+
seqId = self.safe_integer(message, 'seqId')
|
865
870
|
if checksum:
|
871
|
+
prevSeqId = self.safe_integer(message, 'prevSeqId')
|
872
|
+
nonce = orderbook['nonce']
|
866
873
|
asksLength = len(storedAsks)
|
867
874
|
bidsLength = len(storedBids)
|
868
875
|
payloadArray = []
|
@@ -876,12 +883,17 @@ class okx(ccxt.async_support.okx):
|
|
876
883
|
payload = ':'.join(payloadArray)
|
877
884
|
responseChecksum = self.safe_integer(message, 'checksum')
|
878
885
|
localChecksum = self.crc32(payload, True)
|
886
|
+
error = None
|
887
|
+
if prevSeqId != -1 and nonce != prevSeqId:
|
888
|
+
error = InvalidNonce(self.id + ' watchOrderBook received invalid nonce')
|
879
889
|
if responseChecksum != localChecksum:
|
880
890
|
error = ChecksumError(self.id + ' ' + self.orderbook_checksum_message(symbol))
|
891
|
+
if error is not None:
|
881
892
|
del client.subscriptions[messageHash]
|
882
893
|
del self.orderbooks[symbol]
|
883
894
|
client.reject(error, messageHash)
|
884
895
|
timestamp = self.safe_integer(message, 'ts')
|
896
|
+
orderbook['nonce'] = seqId
|
885
897
|
orderbook['timestamp'] = timestamp
|
886
898
|
orderbook['datetime'] = self.iso8601(timestamp)
|
887
899
|
return orderbook
|
@@ -1001,7 +1013,7 @@ class okx(ccxt.async_support.okx):
|
|
1001
1013
|
orderbook = self.orderbooks[symbol]
|
1002
1014
|
for i in range(0, len(data)):
|
1003
1015
|
update = data[i]
|
1004
|
-
self.handle_order_book_message(client, update, orderbook, messageHash)
|
1016
|
+
self.handle_order_book_message(client, update, orderbook, messageHash, market)
|
1005
1017
|
client.resolve(orderbook, messageHash)
|
1006
1018
|
elif (channel == 'books5') or (channel == 'bbo-tbt'):
|
1007
1019
|
if not (symbol in self.orderbooks):
|
@@ -1728,7 +1740,7 @@ class okx(ccxt.async_support.okx):
|
|
1728
1740
|
future = self.safe_value(client.futures, 'authenticated')
|
1729
1741
|
future.resolve(True)
|
1730
1742
|
|
1731
|
-
def ping(self, client):
|
1743
|
+
def ping(self, client: Client):
|
1732
1744
|
# OKX does not support the built-in WebSocket protocol-level ping-pong.
|
1733
1745
|
# Instead, it requires a custom text-based ping-pong mechanism.
|
1734
1746
|
return 'ping'
|
ccxt/pro/oxfun.py
CHANGED
@@ -914,7 +914,7 @@ class oxfun(ccxt.async_support.oxfun):
|
|
914
914
|
if messageHash in client.subscriptions:
|
915
915
|
del client.subscriptions[messageHash]
|
916
916
|
|
917
|
-
def ping(self, client):
|
917
|
+
def ping(self, client: Client):
|
918
918
|
return 'ping'
|
919
919
|
|
920
920
|
def handle_pong(self, client: Client, message):
|
ccxt/pro/p2b.py
CHANGED
@@ -388,7 +388,7 @@ class p2b(ccxt.async_support.p2b):
|
|
388
388
|
raise ExchangeError(self.id + ' error: ' + self.json(error))
|
389
389
|
return False
|
390
390
|
|
391
|
-
def ping(self, client):
|
391
|
+
def ping(self, client: Client):
|
392
392
|
"""
|
393
393
|
:see: https://github.com/P2B-team/P2B-WSS-Public/blob/main/wss_documentation.md#ping
|
394
394
|
* @param client
|
ccxt/pro/poloniex.py
CHANGED