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/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) and not isinstance(data, list):
4871
- return self.parse_order(data, market)
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.safe_value(self.options, 'quoteCurrencies', {})
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
- extension = self.safe_value(quoteCurrencies, quote, {})
221
- request: dict = {
222
- 'quoteId': quoteId,
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.safe_value(response, 'data')
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.safe_value(response, 'data', {})
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.safe_value(self.options, 'quoteCurrencies', {})
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': quoteId,
460
+ 'quoteId': quotes[i],
423
461
  }
424
- response = self.publicGetTickerALLQuoteId(self.extend(request, params))
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.safe_value(response, 'data', {})
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.safe_value_2(order, 'type', 'side')
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.safe_value(order, 'contract', [])
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
@@ -4,7 +4,7 @@
4
4
 
5
5
  # ----------------------------------------------------------------------------
6
6
 
7
- __version__ = '4.3.66'
7
+ __version__ = '4.3.68'
8
8
 
9
9
  # ----------------------------------------------------------------------------
10
10
 
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
@@ -380,7 +380,7 @@ class coinone(ccxt.async_support.coinone):
380
380
  method(client, message)
381
381
  return
382
382
 
383
- def ping(self, client):
383
+ def ping(self, client: Client):
384
384
  return {
385
385
  'request_type': 'PING',
386
386
  }
ccxt/pro/currencycom.py CHANGED
@@ -56,7 +56,7 @@ class currencycom(ccxt.async_support.currencycom):
56
56
  },
57
57
  })
58
58
 
59
- def ping(self, client):
59
+ def ping(self, client: Client):
60
60
  # custom ping-pong
61
61
  requestId = str(self.request_id())
62
62
  return {
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
@@ -610,7 +610,7 @@ class hyperliquid(ccxt.async_support.hyperliquid):
610
610
  method(client, message)
611
611
  return
612
612
 
613
- def ping(self, client):
613
+ def ping(self, client: Client):
614
614
  return {
615
615
  'method': 'ping',
616
616
  }
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 = self.safe_value(client.subscriptions, messageHash)
86
- if future is None:
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
- future = await self.watch(url, messageHash, message, messageHash)
93
- client.subscriptions[messageHash] = future
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.resolve(message, messageHash)
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
@@ -1118,5 +1118,5 @@ class mexc(ccxt.async_support.mexc):
1118
1118
  method = methods[channel]
1119
1119
  method(client, message)
1120
1120
 
1121
- def ping(self, client):
1121
+ def ping(self, client: Client):
1122
1122
  return {'method': 'ping'}
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
@@ -1160,7 +1160,7 @@ class poloniex(ccxt.async_support.poloniex):
1160
1160
  del client.subscriptions[messageHash]
1161
1161
  return message
1162
1162
 
1163
- def ping(self, client):
1163
+ def ping(self, client: Client):
1164
1164
  return {
1165
1165
  'event': 'ping',
1166
1166
  }
ccxt/pro/whitebit.py CHANGED
@@ -856,7 +856,7 @@ class whitebit(ccxt.async_support.whitebit):
856
856
  client.lastPong = self.milliseconds()
857
857
  return message
858
858
 
859
- def ping(self, client):
859
+ def ping(self, client: Client):
860
860
  return {
861
861
  'id': 0,
862
862
  'method': 'ping',