ccxt 4.4.31__py2.py3-none-any.whl → 4.4.33__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.
Files changed (70) hide show
  1. ccxt/__init__.py +1 -1
  2. ccxt/abstract/coinbaseexchange.py +1 -0
  3. ccxt/abstract/kraken.py +1 -0
  4. ccxt/async_support/__init__.py +1 -1
  5. ccxt/async_support/base/exchange.py +1 -1
  6. ccxt/async_support/base/ws/aiohttp_client.py +25 -3
  7. ccxt/async_support/binance.py +153 -0
  8. ccxt/async_support/bitvavo.py +0 -3
  9. ccxt/async_support/bybit.py +134 -6
  10. ccxt/async_support/cex.py +4 -2
  11. ccxt/async_support/coinbase.py +2 -22
  12. ccxt/async_support/coinbaseexchange.py +2 -1
  13. ccxt/async_support/coinex.py +2 -1
  14. ccxt/async_support/deribit.py +2 -2
  15. ccxt/async_support/gate.py +15 -2
  16. ccxt/async_support/hitbtc.py +3 -3
  17. ccxt/async_support/htx.py +1 -1
  18. ccxt/async_support/hyperliquid.py +11 -2
  19. ccxt/async_support/indodax.py +1 -1
  20. ccxt/async_support/kraken.py +3 -2
  21. ccxt/async_support/kucoin.py +5 -3
  22. ccxt/async_support/kucoinfutures.py +94 -26
  23. ccxt/async_support/lbank.py +1 -0
  24. ccxt/async_support/okx.py +94 -3
  25. ccxt/async_support/phemex.py +34 -21
  26. ccxt/async_support/wavesexchange.py +3 -0
  27. ccxt/async_support/woofipro.py +2 -2
  28. ccxt/base/exchange.py +92 -2
  29. ccxt/binance.py +153 -0
  30. ccxt/bitvavo.py +0 -3
  31. ccxt/bybit.py +134 -6
  32. ccxt/cex.py +4 -2
  33. ccxt/coinbase.py +2 -22
  34. ccxt/coinbaseexchange.py +2 -1
  35. ccxt/coinex.py +2 -1
  36. ccxt/deribit.py +2 -2
  37. ccxt/gate.py +15 -2
  38. ccxt/hitbtc.py +3 -3
  39. ccxt/htx.py +1 -1
  40. ccxt/hyperliquid.py +11 -2
  41. ccxt/indodax.py +1 -1
  42. ccxt/kraken.py +3 -2
  43. ccxt/kucoin.py +5 -3
  44. ccxt/kucoinfutures.py +94 -26
  45. ccxt/lbank.py +1 -0
  46. ccxt/okx.py +94 -3
  47. ccxt/phemex.py +34 -21
  48. ccxt/pro/__init__.py +1 -1
  49. ccxt/pro/binance.py +8 -8
  50. ccxt/pro/bitget.py +4 -4
  51. ccxt/pro/bitmart.py +2 -2
  52. ccxt/pro/bitmex.py +2 -2
  53. ccxt/pro/bitvavo.py +46 -45
  54. ccxt/pro/blofin.py +2 -2
  55. ccxt/pro/bybit.py +2 -2
  56. ccxt/pro/cryptocom.py +4 -4
  57. ccxt/pro/gate.py +4 -4
  58. ccxt/pro/hashkey.py +3 -3
  59. ccxt/pro/mexc.py +1 -2
  60. ccxt/pro/okx.py +8 -0
  61. ccxt/test/tests_async.py +3 -1
  62. ccxt/test/tests_helpers.py +1 -1
  63. ccxt/test/tests_sync.py +3 -1
  64. ccxt/wavesexchange.py +3 -0
  65. ccxt/woofipro.py +2 -2
  66. {ccxt-4.4.31.dist-info → ccxt-4.4.33.dist-info}/METADATA +10 -4
  67. {ccxt-4.4.31.dist-info → ccxt-4.4.33.dist-info}/RECORD +70 -70
  68. {ccxt-4.4.31.dist-info → ccxt-4.4.33.dist-info}/LICENSE.txt +0 -0
  69. {ccxt-4.4.31.dist-info → ccxt-4.4.33.dist-info}/WHEEL +0 -0
  70. {ccxt-4.4.31.dist-info → ccxt-4.4.33.dist-info}/top_level.txt +0 -0
ccxt/pro/bitget.py CHANGED
@@ -431,7 +431,7 @@ class bitget(ccxt.async_support.bitget):
431
431
  https://www.bitget.com/api-doc/contract/websocket/public/Candlesticks-Channel
432
432
 
433
433
  :param str symbol: unified symbol of the market to unwatch the ohlcv for
434
- :param str timeframe:
434
+ :param str [timeframe]: the period for the ratio, default is 1 minute
435
435
  :param dict [params]: extra parameters specific to the exchange API endpoint
436
436
  :returns dict: A dictionary of `order book structures <https://docs.ccxt.com/#/?id=order-book-structure>` indexed by market symbols
437
437
  """
@@ -664,7 +664,7 @@ class bitget(ccxt.async_support.bitget):
664
664
  self.handle_deltas(storedOrderBook['bids'], bids)
665
665
  storedOrderBook['timestamp'] = timestamp
666
666
  storedOrderBook['datetime'] = self.iso8601(timestamp)
667
- checksum = self.safe_bool(self.options, 'checksum', True)
667
+ checksum = self.handle_option('watchOrderBook', 'checksum', True)
668
668
  isSnapshot = self.safe_string(message, 'action') == 'snapshot' # snapshot does not have a checksum
669
669
  if not isSnapshot and checksum:
670
670
  storedAsks = storedOrderBook['asks']
@@ -916,8 +916,8 @@ class bitget(ccxt.async_support.bitget):
916
916
  https://www.bitget.com/api-doc/contract/websocket/private/Positions-Channel
917
917
 
918
918
  :param str[]|None symbols: list of unified market symbols
919
- @param since
920
- @param limit
919
+ :param int [since]: the earliest time in ms to fetch positions for
920
+ :param int [limit]: the maximum number of positions to retrieve
921
921
  :param dict params: extra parameters specific to the exchange API endpoint
922
922
  :param str [params.instType]: one of 'USDT-FUTURES', 'USDC-FUTURES', 'COIN-FUTURES', 'SUSDT-FUTURES', 'SUSDC-FUTURES' or 'SCOIN-FUTURES', default is 'USDT-FUTURES'
923
923
  :returns dict[]: a list of `position structure <https://docs.ccxt.com/en/latest/manual.html#position-structure>`
ccxt/pro/bitmart.py CHANGED
@@ -695,8 +695,8 @@ class bitmart(ccxt.async_support.bitmart):
695
695
 
696
696
  watch all open positions
697
697
  :param str[]|None symbols: list of unified market symbols
698
- @param since
699
- @param limit
698
+ :param int [since]: the earliest time in ms to fetch positions
699
+ :param int [limit]: the maximum number of positions to retrieve
700
700
  :param dict params: extra parameters specific to the exchange API endpoint
701
701
  :returns dict[]: a list of `position structure <https://docs.ccxt.com/en/latest/manual.html#position-structure>`
702
702
  """
ccxt/pro/bitmex.py CHANGED
@@ -718,8 +718,8 @@ class bitmex(ccxt.async_support.bitmex):
718
718
  https://www.bitmex.com/app/wsAPI#Subscriptions
719
719
 
720
720
  :param str[]|None symbols: list of unified market symbols
721
- @param since
722
- @param limit
721
+ :param int [since]: the earliest time in ms to watch positions for
722
+ :param int [limit]: the maximum number of positions to retrieve
723
723
  :param dict params: extra parameters specific to the exchange API endpoint
724
724
  :returns dict[]: a list of `position structure <https://docs.ccxt.com/en/latest/manual.html#position-structure>`
725
725
  """
ccxt/pro/bitvavo.py CHANGED
@@ -306,10 +306,9 @@ class bitvavo(ccxt.async_support.bitvavo):
306
306
  # ]
307
307
  # }
308
308
  #
309
- action = self.safe_string(message, 'action')
310
309
  response = self.safe_value(message, 'response')
311
310
  ohlcv = self.parse_ohlcvs(response, None, None, None)
312
- messageHash = self.build_message_hash(action)
311
+ messageHash = self.safe_string(message, 'requestId')
313
312
  client.resolve(ohlcv, messageHash)
314
313
 
315
314
  def handle_ohlcv(self, client: Client, message):
@@ -687,14 +686,15 @@ class bitvavo(ccxt.async_support.bitvavo):
687
686
  # }]
688
687
  # }
689
688
  #
690
- action = self.safe_string(message, 'action')
691
- response = self.safe_value(message, 'response')
692
- firstRawOrder = self.safe_value(response, 0, {})
693
- marketId = self.safe_string(firstRawOrder, 'market')
689
+ # action = self.safe_string(message, 'action')
690
+ response = self.safe_list(message, 'response')
691
+ # firstRawOrder = self.safe_value(response, 0, {})
692
+ # marketId = self.safe_string(firstRawOrder, 'market')
694
693
  orders = self.parse_orders(response)
695
- messageHash = self.build_message_hash(action, {'market': marketId})
696
- client.resolve(orders, messageHash)
697
- messageHash = self.build_message_hash(action, message)
694
+ # messageHash = self.build_message_hash(action, {'market': marketId})
695
+ # client.resolve(orders, messageHash)
696
+ # messageHash = self.build_message_hash(action, message)
697
+ messageHash = self.safe_string(message, 'requestId')
698
698
  client.resolve(orders, messageHash)
699
699
 
700
700
  async def fetch_order_ws(self, id: str, symbol: Str = None, params={}) -> Order:
@@ -739,13 +739,19 @@ class bitvavo(ccxt.async_support.bitvavo):
739
739
  orders = await self.watch_request('privateGetOrders', request)
740
740
  return self.filter_by_symbol_since_limit(orders, symbol, since, limit)
741
741
 
742
+ def request_id(self):
743
+ ts = str(self.milliseconds())
744
+ randomNumber = self.rand_number(4)
745
+ randomPart = str(randomNumber)
746
+ return int(ts + randomPart)
747
+
742
748
  async def watch_request(self, action, request):
749
+ messageHash = self.request_id()
750
+ messageHashStr = str(messageHash)
743
751
  request['action'] = action
744
- messageHash = self.build_message_hash(action, request)
745
- self.check_message_hash_does_not_exist(messageHash)
752
+ request['requestId'] = messageHash
746
753
  url = self.urls['api']['ws']
747
- randomSubHash = str(self.rand_number(5)) + ':' + messageHash
748
- return await self.watch(url, messageHash, request, randomSubHash)
754
+ return await self.watch(url, messageHashStr, request, messageHashStr)
749
755
 
750
756
  async def fetch_open_orders_ws(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Order]:
751
757
  """
@@ -810,12 +816,12 @@ class bitvavo(ccxt.async_support.bitvavo):
810
816
  # }
811
817
  #
812
818
  #
813
- action = self.safe_string(message, 'action')
814
- response = self.safe_value(message, 'response')
815
- firstRawTrade = self.safe_value(response, 0, {})
816
- marketId = self.safe_string(firstRawTrade, 'market')
819
+ # action = self.safe_string(message, 'action')
820
+ response = self.safe_list(message, 'response')
821
+ # marketId = self.safe_string(firstRawTrade, 'market')
817
822
  trades = self.parse_trades(response, None, None, None)
818
- messageHash = self.build_message_hash(action, {'market': marketId})
823
+ # messageHash = self.build_message_hash(action, {'market': marketId})
824
+ messageHash = self.safe_string(message, 'requestId')
819
825
  client.resolve(trades, messageHash)
820
826
 
821
827
  async def withdraw_ws(self, code: str, amount, address, tag=None, params={}):
@@ -846,8 +852,9 @@ class bitvavo(ccxt.async_support.bitvavo):
846
852
  # }
847
853
  # }
848
854
  #
849
- action = self.safe_string(message, 'action')
850
- messageHash = self.build_message_hash(action, message)
855
+ # action = self.safe_string(message, 'action')
856
+ # messageHash = self.build_message_hash(action, message)
857
+ messageHash = self.safe_string(message, 'requestId')
851
858
  response = self.safe_value(message, 'response')
852
859
  withdraw = self.parse_transaction(response)
853
860
  client.resolve(withdraw, messageHash)
@@ -886,9 +893,10 @@ class bitvavo(ccxt.async_support.bitvavo):
886
893
  # ]
887
894
  # }
888
895
  #
889
- action = self.safe_string(message, 'action')
890
- messageHash = self.build_message_hash(action, message)
891
- response = self.safe_value(message, 'response')
896
+ # action = self.safe_string(message, 'action')
897
+ # messageHash = self.build_message_hash(action, message)
898
+ response = self.safe_list(message, 'response')
899
+ messageHash = self.safe_string(message, 'requestId')
892
900
  withdrawals = self.parse_transactions(response, None, None, None, {'type': 'withdrawal'})
893
901
  client.resolve(withdrawals, messageHash)
894
902
 
@@ -945,10 +953,9 @@ class bitvavo(ccxt.async_support.bitvavo):
945
953
  # ]
946
954
  # }
947
955
  #
948
- action = self.safe_string(message, 'action')
949
- messageHash = self.build_message_hash(action, message)
950
956
  response = self.safe_value(message, 'response')
951
957
  deposits = self.parse_transactions(response, None, None, None, {'type': 'deposit'})
958
+ messageHash = self.safe_string(message, 'requestId')
952
959
  client.resolve(deposits, messageHash)
953
960
 
954
961
  async def fetch_trading_fees_ws(self, params={}) -> TradingFees:
@@ -1008,8 +1015,7 @@ class bitvavo(ccxt.async_support.bitvavo):
1008
1015
  # ]
1009
1016
  # }
1010
1017
  #
1011
- action = self.safe_string(message, 'action')
1012
- messageHash = self.build_message_hash(action, message)
1018
+ messageHash = self.safe_string(message, 'requestId')
1013
1019
  response = self.safe_value(message, 'response')
1014
1020
  currencies = self.parse_currencies(response)
1015
1021
  client.resolve(currencies, messageHash)
@@ -1027,8 +1033,7 @@ class bitvavo(ccxt.async_support.bitvavo):
1027
1033
  # }
1028
1034
  # }
1029
1035
  #
1030
- action = self.safe_string(message, 'action')
1031
- messageHash = self.build_message_hash(action, message)
1036
+ messageHash = self.safe_string(message, 'requestId')
1032
1037
  response = self.safe_value(message, 'response')
1033
1038
  fees = self.parse_trading_fees(response)
1034
1039
  client.resolve(fees, messageHash)
@@ -1059,8 +1064,7 @@ class bitvavo(ccxt.async_support.bitvavo):
1059
1064
  # ]
1060
1065
  # }
1061
1066
  #
1062
- action = self.safe_string(message, 'action', 'privateGetBalance')
1063
- messageHash = self.build_message_hash(action, message)
1067
+ messageHash = self.safe_string(message, 'requestId')
1064
1068
  response = self.safe_value(message, 'response', [])
1065
1069
  balance = self.parse_balance(response)
1066
1070
  client.resolve(balance, messageHash)
@@ -1094,10 +1098,9 @@ class bitvavo(ccxt.async_support.bitvavo):
1094
1098
  # }
1095
1099
  # }
1096
1100
  #
1097
- action = self.safe_string(message, 'action')
1098
1101
  response = self.safe_value(message, 'response', {})
1099
1102
  order = self.parse_order(response)
1100
- messageHash = self.build_message_hash(action, response)
1103
+ messageHash = self.safe_string(message, 'requestId')
1101
1104
  client.resolve(order, messageHash)
1102
1105
 
1103
1106
  def handle_markets(self, client: Client, message):
@@ -1120,10 +1123,9 @@ class bitvavo(ccxt.async_support.bitvavo):
1120
1123
  # ]
1121
1124
  # }
1122
1125
  #
1123
- action = self.safe_string(message, 'action')
1124
1126
  response = self.safe_value(message, 'response', {})
1125
1127
  markets = self.parse_markets(response)
1126
- messageHash = self.build_message_hash(action, response)
1128
+ messageHash = self.safe_string(message, 'requestId')
1127
1129
  client.resolve(markets, messageHash)
1128
1130
 
1129
1131
  def build_message_hash(self, action, params={}):
@@ -1140,15 +1142,6 @@ class bitvavo(ccxt.async_support.bitvavo):
1140
1142
  messageHash = method(action, params)
1141
1143
  return messageHash
1142
1144
 
1143
- def check_message_hash_does_not_exist(self, messageHash):
1144
- supressMultipleWsRequestsError = self.safe_bool(self.options, 'supressMultipleWsRequestsError', False)
1145
- if not supressMultipleWsRequestsError:
1146
- client = self.safe_value(self.clients, self.urls['api']['ws'])
1147
- if client is not None:
1148
- future = self.safe_value(client.futures, messageHash)
1149
- if future is not None:
1150
- raise ExchangeError(self.id + ' a similar request with messageHash ' + messageHash + ' is already pending, you must wait for a response, or turn off self error by setting supressMultipleWsRequestsError in the options to True')
1151
-
1152
1145
  def action_and_market_message_hash(self, action, params={}):
1153
1146
  symbol = self.safe_string(params, 'market', '')
1154
1147
  return action + symbol
@@ -1292,11 +1285,19 @@ class bitvavo(ccxt.async_support.bitvavo):
1292
1285
  # errorCode: 217,
1293
1286
  # error: 'Minimum order size in quote currency is 5 EUR or 0.001 BTC.'
1294
1287
  # }
1288
+ # {
1289
+ # action: 'privateCreateOrder',
1290
+ # requestId: '17317539426571916',
1291
+ # market: 'USDT-EUR',
1292
+ # errorCode: 216,
1293
+ # error: 'You do not have sufficient balance to complete self operation.'
1294
+ # }
1295
1295
  #
1296
1296
  error = self.safe_string(message, 'error')
1297
1297
  code = self.safe_integer(error, 'errorCode')
1298
1298
  action = self.safe_string(message, 'action')
1299
- messageHash = self.build_message_hash(action, message)
1299
+ buildMessage = self.build_message_hash(action, message)
1300
+ messageHash = self.safe_string(message, 'requestId', buildMessage)
1300
1301
  rejected = False
1301
1302
  try:
1302
1303
  self.handle_errors(code, error, client.url, None, None, error, message, None, None)
ccxt/pro/blofin.py CHANGED
@@ -525,8 +525,8 @@ class blofin(ccxt.async_support.blofin):
525
525
 
526
526
  watch all open positions
527
527
  :param str[]|None symbols: list of unified market symbols
528
- @param since
529
- @param limit
528
+ :param int [since]: the earliest time in ms to fetch positions for
529
+ :param int [limit]: the maximum number of positions to retrieve
530
530
  :param dict params: extra parameters specific to the exchange API endpoint
531
531
  :returns dict[]: a list of `position structure <https://docs.ccxt.com/en/latest/manual.html#position-structure>`
532
532
  """
ccxt/pro/bybit.py CHANGED
@@ -1331,8 +1331,8 @@ class bybit(ccxt.async_support.bybit):
1331
1331
 
1332
1332
  watch all open positions
1333
1333
  :param str[] [symbols]: list of unified market symbols
1334
- @param since
1335
- @param limit
1334
+ :param int [since]: the earliest time in ms to fetch positions for
1335
+ :param int [limit]: the maximum number of positions to retrieve
1336
1336
  :param dict params: extra parameters specific to the exchange API endpoint
1337
1337
  :returns dict[]: a list of `position structure <https://docs.ccxt.com/en/latest/manual.html#position-structure>`
1338
1338
  """
ccxt/pro/cryptocom.py CHANGED
@@ -349,7 +349,7 @@ class cryptocom(ccxt.async_support.cryptocom):
349
349
 
350
350
  https://exchange-docs.crypto.com/exchange/v1/rest-ws/index.html#trade-instrument_name
351
351
 
352
- @param symbols
352
+ :param str[] [symbols]: list of unified market symbols to unwatch trades for
353
353
  :param dict [params]: extra parameters specific to the exchange API endpoint
354
354
  :returns dict[]: a list of `trade structures <https://docs.ccxt.com/#/?id=public-trades>`
355
355
  """
@@ -815,9 +815,9 @@ class cryptocom(ccxt.async_support.cryptocom):
815
815
 
816
816
  https://exchange-docs.crypto.com/exchange/v1/rest-ws/index.html#user-position_balance
817
817
 
818
- :param str[]|None symbols: list of unified market symbols
819
- @param since
820
- @param limit
818
+ :param str[] [symbols]: list of unified market symbols to watch positions for
819
+ :param int [since]: the earliest time in ms to fetch positions for
820
+ :param int [limit]: the maximum number of positions to retrieve
821
821
  :param dict params: extra parameters specific to the exchange API endpoint
822
822
  :returns dict[]: a list of `position structure <https://docs.ccxt.com/en/latest/manual.html#position-structure>`
823
823
  """
ccxt/pro/gate.py CHANGED
@@ -336,7 +336,7 @@ class gate(ccxt.async_support.gate):
336
336
  https://www.gate.io/docs/developers/futures/ws/en/#order-list
337
337
 
338
338
  fetches information on multiple orders made by the user by status
339
- @param status
339
+ :param str status: requested order status
340
340
  :param str symbol: unified market symbol of the market orders were made in
341
341
  :param int|None [since]: the earliest time in ms to fetch orders for
342
342
  :param int|None [limit]: the maximum number of order structures to retrieve
@@ -1067,9 +1067,9 @@ class gate(ccxt.async_support.gate):
1067
1067
  https://www.gate.io/docs/developers/options/ws/en/#positions-channel
1068
1068
 
1069
1069
  watch all open positions
1070
- :param str[]|None symbols: list of unified market symbols
1071
- @param since
1072
- @param limit
1070
+ :param str[] [symbols]: list of unified market symbols to watch positions for
1071
+ :param int [since]: the earliest time in ms to fetch positions for
1072
+ :param int [limit]: the maximum number of positions to retrieve
1073
1073
  :param dict params: extra parameters specific to the exchange API endpoint
1074
1074
  :returns dict[]: a list of `position structure <https://docs.ccxt.com/en/latest/manual.html#position-structure>`
1075
1075
  """
ccxt/pro/hashkey.py CHANGED
@@ -573,9 +573,9 @@ class hashkey(ccxt.async_support.hashkey):
573
573
  https://hashkeyglobal-apidoc.readme.io/reference/websocket-api#private-stream
574
574
 
575
575
  watch all open positions
576
- :param str[]|None symbols: list of unified market symbols
577
- @param since
578
- @param limit
576
+ :param str[] [symbols]: list of unified market symbols to watch positions for
577
+ :param int [since]: the earliest time in ms to fetch positions for
578
+ :param int [limit]: the maximum number of positions to retrieve
579
579
  :param dict params: extra parameters specific to the exchange API endpoint
580
580
  :returns dict[]: a list of `position structure <https://docs.ccxt.com/en/latest/manual.html#position-structure>`
581
581
  """
ccxt/pro/mexc.py CHANGED
@@ -1248,8 +1248,7 @@ class mexc(ccxt.async_support.mexc):
1248
1248
  '2': 'closed', # filled
1249
1249
  '3': 'open', # partially filled
1250
1250
  '4': 'canceled', # canceled
1251
- '5': 'open', # order partially filled
1252
- '6': 'closed', # partially filled then canceled
1251
+ '5': 'closed', # partially filled then canceled
1253
1252
  'NEW': 'open',
1254
1253
  'CANCELED': 'canceled',
1255
1254
  'EXECUTED': 'closed',
ccxt/pro/okx.py CHANGED
@@ -2135,6 +2135,7 @@ class okx(ccxt.async_support.okx):
2135
2135
  #
2136
2136
  # {event: 'error', msg: "Illegal request: {"op":"subscribe","args":["spot/ticker:BTC-USDT"]}", code: "60012"}
2137
2137
  # {event: 'error", msg: "channel:ticker,instId:BTC-USDT doesn"t exist", code: "60018"}
2138
+ # {"event":"error","msg":"Illegal request: {\\"id\\":\\"17321173472466905\\",\\"op\\":\\"amend-order\\",\\"args\\":[{\\"instId\\":\\"ETH-USDC\\",\\"ordId\\":\\"2000345622407479296\\",\\"newSz\\":\\"0.050857\\",\\"newPx\\":\\"2949.4\\",\\"postOnly\\":true}],\\"postOnly\\":true}","code":"60012","connId":"0808af6c"}
2138
2139
  #
2139
2140
  errorCode = self.safe_string(message, 'code')
2140
2141
  try:
@@ -2160,6 +2161,13 @@ class okx(ccxt.async_support.okx):
2160
2161
  # if the message contains an id, it means it is a response to a request
2161
2162
  # so we only reject that promise, instead of deleting all futures, destroying the authentication future
2162
2163
  id = self.safe_string(message, 'id')
2164
+ if id is None:
2165
+ # try to parse it from the stringified json inside msg
2166
+ msg = self.safe_string(message, 'msg')
2167
+ if msg is not None and msg.startswith('Illegal request: {'):
2168
+ stringifiedJson = msg.replace('Illegal request: ', '')
2169
+ parsedJson = self.parse_json(stringifiedJson)
2170
+ id = self.safe_string(parsedJson, 'id')
2163
2171
  if id is not None:
2164
2172
  client.reject(e, id)
2165
2173
  return False
ccxt/test/tests_async.py CHANGED
@@ -183,6 +183,7 @@ class testMainClass:
183
183
  is_load_markets = (method_name == 'loadMarkets')
184
184
  is_fetch_currencies = (method_name == 'fetchCurrencies')
185
185
  is_proxy_test = (method_name == self.proxy_test_file_name)
186
+ is_feature_test = (method_name == 'features')
186
187
  # if this is a private test, and the implementation was already tested in public, then no need to re-test it in private test (exception is fetchCurrencies, because our approach in base exchange)
187
188
  if not is_public and (method_name in self.checked_public_tests) and not is_fetch_currencies:
188
189
  return
@@ -190,7 +191,7 @@ class testMainClass:
190
191
  supported_by_exchange = (method_name in exchange.has) and exchange.has[method_name]
191
192
  if not is_load_markets and (len(self.only_specific_tests) > 0 and not exchange.in_array(method_name, self.only_specific_tests)):
192
193
  skip_message = '[INFO] IGNORED_TEST'
193
- elif not is_load_markets and not supported_by_exchange and not is_proxy_test:
194
+ elif not is_load_markets and not supported_by_exchange and not is_proxy_test and not is_feature_test:
194
195
  skip_message = '[INFO] UNSUPPORTED_TEST' # keep it aligned with the longest message
195
196
  elif isinstance(skipped_properties_for_method, str):
196
197
  skip_message = '[INFO] SKIPPED_TEST'
@@ -336,6 +337,7 @@ class testMainClass:
336
337
 
337
338
  async def run_public_tests(self, exchange, symbol):
338
339
  tests = {
340
+ 'features': [],
339
341
  'fetchCurrencies': [],
340
342
  'fetchTicker': [symbol],
341
343
  'fetchTickers': [symbol],
@@ -228,7 +228,7 @@ def init_exchange(exchangeId, args, is_ws=False):
228
228
 
229
229
  def get_test_files_sync(properties, ws=False):
230
230
  tests = {}
231
- finalPropList = properties + [PROXY_TEST_FILE_NAME]
231
+ finalPropList = properties + [PROXY_TEST_FILE_NAME, 'features']
232
232
  for i in range(0, len(finalPropList)):
233
233
  methodName = finalPropList[i]
234
234
  name_snake_case = convert_to_snake_case(methodName)
ccxt/test/tests_sync.py CHANGED
@@ -180,6 +180,7 @@ class testMainClass:
180
180
  is_load_markets = (method_name == 'loadMarkets')
181
181
  is_fetch_currencies = (method_name == 'fetchCurrencies')
182
182
  is_proxy_test = (method_name == self.proxy_test_file_name)
183
+ is_feature_test = (method_name == 'features')
183
184
  # if this is a private test, and the implementation was already tested in public, then no need to re-test it in private test (exception is fetchCurrencies, because our approach in base exchange)
184
185
  if not is_public and (method_name in self.checked_public_tests) and not is_fetch_currencies:
185
186
  return
@@ -187,7 +188,7 @@ class testMainClass:
187
188
  supported_by_exchange = (method_name in exchange.has) and exchange.has[method_name]
188
189
  if not is_load_markets and (len(self.only_specific_tests) > 0 and not exchange.in_array(method_name, self.only_specific_tests)):
189
190
  skip_message = '[INFO] IGNORED_TEST'
190
- elif not is_load_markets and not supported_by_exchange and not is_proxy_test:
191
+ elif not is_load_markets and not supported_by_exchange and not is_proxy_test and not is_feature_test:
191
192
  skip_message = '[INFO] UNSUPPORTED_TEST' # keep it aligned with the longest message
192
193
  elif isinstance(skipped_properties_for_method, str):
193
194
  skip_message = '[INFO] SKIPPED_TEST'
@@ -333,6 +334,7 @@ class testMainClass:
333
334
 
334
335
  def run_public_tests(self, exchange, symbol):
335
336
  tests = {
337
+ 'features': [],
336
338
  'fetchCurrencies': [],
337
339
  'fetchTicker': [symbol],
338
340
  'fetchTickers': [symbol],
ccxt/wavesexchange.py CHANGED
@@ -1889,6 +1889,9 @@ class wavesexchange(Exchange, ImplicitAPI):
1889
1889
  def fetch_my_trades(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
1890
1890
  """
1891
1891
  fetch all trades made by the user
1892
+
1893
+ https://api.wavesplatform.com/v0/docs/#/transactions/searchTxsExchange
1894
+
1892
1895
  :param str symbol: unified market symbol
1893
1896
  :param int [since]: the earliest time in ms to fetch trades for
1894
1897
  :param int [limit]: the maximum number of trades structures to retrieve
ccxt/woofipro.py CHANGED
@@ -2379,8 +2379,8 @@ class woofipro(Exchange, ImplicitAPI):
2379
2379
 
2380
2380
  https://orderly.network/docs/build-on-evm/evm-api/restful-api/private/update-leverage-setting
2381
2381
 
2382
- @param leverage
2383
- :param str symbol: unified market symbol
2382
+ :param int [leverage]: the rate of leverage
2383
+ :param str [symbol]: unified market symbol
2384
2384
  :param dict [params]: extra parameters specific to the exchange API endpoint
2385
2385
  :returns dict: response from the exchange
2386
2386
  """
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: ccxt
3
- Version: 4.4.31
3
+ Version: 4.4.33
4
4
  Summary: A JavaScript / TypeScript / Python / C# / PHP cryptocurrency trading library with support for 100+ exchanges
5
5
  Home-page: https://ccxt.com
6
6
  Author: Igor Kroitor
@@ -273,13 +273,13 @@ console.log(version, Object.keys(exchanges));
273
273
 
274
274
  All-in-one browser bundle (dependencies included), served from a CDN of your choice:
275
275
 
276
- * jsDelivr: https://cdn.jsdelivr.net/npm/ccxt@4.4.31/dist/ccxt.browser.min.js
277
- * unpkg: https://unpkg.com/ccxt@4.4.31/dist/ccxt.browser.min.js
276
+ * jsDelivr: https://cdn.jsdelivr.net/npm/ccxt@4.4.33/dist/ccxt.browser.min.js
277
+ * unpkg: https://unpkg.com/ccxt@4.4.33/dist/ccxt.browser.min.js
278
278
 
279
279
  CDNs are not updated in real-time and may have delays. Defaulting to the most recent version without specifying the version number is not recommended. Please, keep in mind that we are not responsible for the correct operation of those CDN servers.
280
280
 
281
281
  ```HTML
282
- <script type="text/javascript" src="https://cdn.jsdelivr.net/npm/ccxt@4.4.31/dist/ccxt.browser.min.js"></script>
282
+ <script type="text/javascript" src="https://cdn.jsdelivr.net/npm/ccxt@4.4.33/dist/ccxt.browser.min.js"></script>
283
283
  ```
284
284
 
285
285
  Creates a global `ccxt` object:
@@ -307,6 +307,12 @@ The library supports concurrent asynchronous mode with asyncio and async/await i
307
307
  import ccxt.async_support as ccxt # link against the asynchronous version of ccxt
308
308
  ```
309
309
 
310
+ #### orjson support
311
+
312
+ CCXT also supports `orjson` for parsing JSON since it is much faster than the builtin library. This is especially important when using websockets because some exchanges return big messages that need to be parsed and dispatched as quickly as possible.
313
+
314
+ However, `orjson` is not enabled by default because it is not supported by every python interpreter. If you want to opt-in, you just need to install it (`pip install orjson`) on your local environment. CCXT will detect the installion and pick it up automatically.
315
+
310
316
  ### PHP
311
317
 
312
318
  [ccxt in PHP with **Packagist/Composer**](https://packagist.org/packages/ccxt/ccxt) (PHP 7.0+)