ccxt 4.2.69__py2.py3-none-any.whl → 4.2.71__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.

Files changed (105) hide show
  1. ccxt/__init__.py +1 -1
  2. ccxt/abstract/coinbase.py +2 -0
  3. ccxt/ascendex.py +1 -1
  4. ccxt/async_support/__init__.py +1 -1
  5. ccxt/async_support/ascendex.py +1 -1
  6. ccxt/async_support/base/exchange.py +1 -1
  7. ccxt/async_support/bigone.py +1 -1
  8. ccxt/async_support/binance.py +1 -1
  9. ccxt/async_support/bingx.py +1 -1
  10. ccxt/async_support/bitfinex.py +1 -1
  11. ccxt/async_support/bitfinex2.py +1 -1
  12. ccxt/async_support/bitget.py +13 -7
  13. ccxt/async_support/bitmart.py +1 -1
  14. ccxt/async_support/bitmex.py +1 -1
  15. ccxt/async_support/bitrue.py +1 -1
  16. ccxt/async_support/bitstamp.py +1 -1
  17. ccxt/async_support/bl3p.py +1 -1
  18. ccxt/async_support/blofin.py +1 -1
  19. ccxt/async_support/btcalpha.py +1 -1
  20. ccxt/async_support/bybit.py +1 -1
  21. ccxt/async_support/coinbase.py +104 -89
  22. ccxt/async_support/coinex.py +1 -1
  23. ccxt/async_support/coinlist.py +1 -1
  24. ccxt/async_support/coinmetro.py +1 -1
  25. ccxt/async_support/deribit.py +1 -1
  26. ccxt/async_support/digifinex.py +3 -2
  27. ccxt/async_support/gate.py +163 -2
  28. ccxt/async_support/hitbtc.py +1 -1
  29. ccxt/async_support/htx.py +1 -1
  30. ccxt/async_support/hyperliquid.py +2 -2
  31. ccxt/async_support/kraken.py +2 -1
  32. ccxt/async_support/krakenfutures.py +1 -1
  33. ccxt/async_support/kucoin.py +1 -1
  34. ccxt/async_support/kucoinfutures.py +1 -1
  35. ccxt/async_support/latoken.py +1 -1
  36. ccxt/async_support/lykke.py +1 -1
  37. ccxt/async_support/mexc.py +10 -1
  38. ccxt/async_support/ndax.py +1 -1
  39. ccxt/async_support/novadax.py +1 -1
  40. ccxt/async_support/okcoin.py +1 -1
  41. ccxt/async_support/okx.py +1 -1
  42. ccxt/async_support/paymium.py +1 -1
  43. ccxt/async_support/phemex.py +1 -1
  44. ccxt/async_support/poloniex.py +1 -1
  45. ccxt/async_support/wazirx.py +1 -1
  46. ccxt/async_support/whitebit.py +1 -1
  47. ccxt/async_support/woo.py +1 -1
  48. ccxt/async_support/zonda.py +1 -1
  49. ccxt/base/exchange.py +1 -1
  50. ccxt/bigone.py +1 -1
  51. ccxt/binance.py +1 -1
  52. ccxt/bingx.py +1 -1
  53. ccxt/bitfinex.py +1 -1
  54. ccxt/bitfinex2.py +1 -1
  55. ccxt/bitget.py +13 -7
  56. ccxt/bitmart.py +1 -1
  57. ccxt/bitmex.py +1 -1
  58. ccxt/bitrue.py +1 -1
  59. ccxt/bitstamp.py +1 -1
  60. ccxt/bl3p.py +1 -1
  61. ccxt/blofin.py +1 -1
  62. ccxt/btcalpha.py +1 -1
  63. ccxt/bybit.py +1 -1
  64. ccxt/coinbase.py +104 -89
  65. ccxt/coinex.py +1 -1
  66. ccxt/coinlist.py +1 -1
  67. ccxt/coinmetro.py +1 -1
  68. ccxt/deribit.py +1 -1
  69. ccxt/digifinex.py +3 -2
  70. ccxt/gate.py +163 -2
  71. ccxt/hitbtc.py +1 -1
  72. ccxt/htx.py +1 -1
  73. ccxt/hyperliquid.py +2 -2
  74. ccxt/kraken.py +2 -1
  75. ccxt/krakenfutures.py +1 -1
  76. ccxt/kucoin.py +1 -1
  77. ccxt/kucoinfutures.py +1 -1
  78. ccxt/latoken.py +1 -1
  79. ccxt/lykke.py +1 -1
  80. ccxt/mexc.py +10 -1
  81. ccxt/ndax.py +1 -1
  82. ccxt/novadax.py +1 -1
  83. ccxt/okcoin.py +1 -1
  84. ccxt/okx.py +1 -1
  85. ccxt/paymium.py +1 -1
  86. ccxt/phemex.py +1 -1
  87. ccxt/poloniex.py +1 -1
  88. ccxt/pro/__init__.py +3 -1
  89. ccxt/pro/hyperliquid.py +524 -0
  90. ccxt/pro/luno.py +1 -1
  91. ccxt/test/base/test_balance.py +3 -0
  92. ccxt/test/base/test_market.py +1 -1
  93. ccxt/test/base/test_order_book.py +1 -0
  94. ccxt/test/base/test_shared_methods.py +12 -2
  95. ccxt/test/base/test_trade.py +1 -1
  96. ccxt/test/test_async.py +78 -39
  97. ccxt/test/test_sync.py +78 -39
  98. ccxt/wazirx.py +1 -1
  99. ccxt/whitebit.py +1 -1
  100. ccxt/woo.py +1 -1
  101. ccxt/zonda.py +1 -1
  102. {ccxt-4.2.69.dist-info → ccxt-4.2.71.dist-info}/METADATA +5 -5
  103. {ccxt-4.2.69.dist-info → ccxt-4.2.71.dist-info}/RECORD +105 -104
  104. {ccxt-4.2.69.dist-info → ccxt-4.2.71.dist-info}/WHEEL +0 -0
  105. {ccxt-4.2.69.dist-info → ccxt-4.2.71.dist-info}/top_level.txt +0 -0
ccxt/test/test_async.py CHANGED
@@ -449,13 +449,30 @@ class testMainClass(baseMainTestClass):
449
449
  if self.info:
450
450
  args_stringified = '(' + ','.join(args) + ')'
451
451
  dump(self.add_padding('[INFO] TESTING', 25), self.exchange_hint(exchange), method_name, args_stringified)
452
- skipped_properties = exchange.safe_value(self.skipped_methods, method_name, {})
453
- await call_method(self.test_files, method_name, exchange, skipped_properties, args)
452
+ await call_method(self.test_files, method_name, exchange, self.get_skips(exchange, method_name), args)
454
453
  # if it was passed successfully, add to the list of successfull tests
455
454
  if is_public:
456
455
  self.checked_public_tests[method_name] = True
457
456
  return
458
457
 
458
+ def get_skips(self, exchange, method_name):
459
+ # get "method-specific" skips
460
+ skips_for_method = exchange.safe_value(self.skipped_methods, method_name, {})
461
+ # get "object-specific" skips
462
+ if exchange.in_array(method_name, ['fetchOrderBook', 'fetchOrderBooks', 'fetchL2OrderBook', 'watchOrderBook', 'watchOrderBookForSymbols']):
463
+ skips = exchange.safe_value(self.skipped_methods, 'orderBook', {})
464
+ return exchange.deep_extend(skips_for_method, skips)
465
+ elif exchange.in_array(method_name, ['fetchTicker', 'fetchTickers', 'watchTicker', 'watchTickers']):
466
+ skips = exchange.safe_value(self.skipped_methods, 'ticker', {})
467
+ return exchange.deep_extend(skips_for_method, skips)
468
+ elif exchange.in_array(method_name, ['fetchTrades', 'watchTrades', 'watchTradesForSymbols']):
469
+ skips = exchange.safe_value(self.skipped_methods, 'trade', {})
470
+ return exchange.deep_extend(skips_for_method, skips)
471
+ elif exchange.in_array(method_name, ['fetchOHLCV', 'watchOHLCV', 'watchOHLCVForSymbols']):
472
+ skips = exchange.safe_value(self.skipped_methods, 'ohlcv', {})
473
+ return exchange.deep_extend(skips_for_method, skips)
474
+ return skips_for_method
475
+
459
476
  async def test_safe(self, method_name, exchange, args=[], is_public=False):
460
477
  # `testSafe` method does not throw an exception, instead mutes it. The reason we
461
478
  # mute the thrown exceptions here is because we don't want to stop the whole
@@ -1215,7 +1232,8 @@ class testMainClass(baseMainTestClass):
1215
1232
  except Exception as e:
1216
1233
  spot_order_request = self.urlencoded_to_dict(exchange.last_request_body)
1217
1234
  client_order_id = spot_order_request['newClientOrderId']
1218
- assert client_order_id.startswith(str(spot_id)), 'spot clientOrderId does not start with spotId'
1235
+ spot_id_string = str(spot_id)
1236
+ assert client_order_id.startswith(spot_id_string), 'binance - spot clientOrderId: ' + client_order_id + ' does not start with spotId' + spot_id_string
1219
1237
  swap_id = 'x-xcKtGhcu'
1220
1238
  swap_order_request = None
1221
1239
  try:
@@ -1227,10 +1245,11 @@ class testMainClass(baseMainTestClass):
1227
1245
  await exchange.create_order('BTC/USD:BTC', 'limit', 'buy', 1, 20000)
1228
1246
  except Exception as e:
1229
1247
  swap_inverse_order_request = self.urlencoded_to_dict(exchange.last_request_body)
1230
- client_order_id_spot = swap_order_request['newClientOrderId']
1231
- assert client_order_id_spot.startswith(str(swap_id)), 'swap clientOrderId does not start with swapId'
1248
+ client_order_id_swap = swap_order_request['newClientOrderId']
1249
+ swap_id_string = str(swap_id)
1250
+ assert client_order_id_swap.startswith(swap_id_string), 'binance - swap clientOrderId: ' + client_order_id_swap + ' does not start with swapId' + swap_id_string
1232
1251
  client_order_id_inverse = swap_inverse_order_request['newClientOrderId']
1233
- assert client_order_id_inverse.startswith(str(swap_id)), 'swap clientOrderIdInverse does not start with swapId'
1252
+ assert client_order_id_inverse.startswith(swap_id_string), 'binance - swap clientOrderIdInverse: ' + client_order_id_inverse + ' does not start with swapId' + swap_id_string
1234
1253
  await close(exchange)
1235
1254
  return True
1236
1255
 
@@ -1243,16 +1262,19 @@ class testMainClass(baseMainTestClass):
1243
1262
  except Exception as e:
1244
1263
  spot_order_request = json_parse(exchange.last_request_body)
1245
1264
  client_order_id = spot_order_request[0]['clOrdId'] # returns order inside array
1246
- assert client_order_id.startswith(str(id)), 'spot clientOrderId does not start with id'
1247
- assert spot_order_request[0]['tag'] == id, 'id different from spot tag'
1265
+ id_string = str(id)
1266
+ assert client_order_id.startswith(id_string), 'okx - spot clientOrderId: ' + client_order_id + ' does not start with id: ' + id_string
1267
+ spot_tag = spot_order_request[0]['tag']
1268
+ assert spot_tag == id, 'okx - id: ' + id + ' different from spot tag: ' + spot_tag
1248
1269
  swap_order_request = None
1249
1270
  try:
1250
1271
  await exchange.create_order('BTC/USDT:USDT', 'limit', 'buy', 1, 20000)
1251
1272
  except Exception as e:
1252
1273
  swap_order_request = json_parse(exchange.last_request_body)
1253
- client_order_id_spot = swap_order_request[0]['clOrdId']
1254
- assert client_order_id_spot.startswith(str(id)), 'swap clientOrderId does not start with id'
1255
- assert swap_order_request[0]['tag'] == id, 'id different from swap tag'
1274
+ client_order_id_swap = swap_order_request[0]['clOrdId']
1275
+ assert client_order_id_swap.startswith(id_string), 'okx - swap clientOrderId: ' + client_order_id_swap + ' does not start with id: ' + id_string
1276
+ swap_tag = swap_order_request[0]['tag']
1277
+ assert swap_tag == id, 'okx - id: ' + id + ' different from swap tag: ' + swap_tag
1256
1278
  await close(exchange)
1257
1279
  return True
1258
1280
 
@@ -1265,7 +1287,8 @@ class testMainClass(baseMainTestClass):
1265
1287
  await exchange.create_order('BTC/USDT', 'limit', 'buy', 1, 20000)
1266
1288
  except Exception as e:
1267
1289
  request = json_parse(exchange.last_request_body)
1268
- assert request['params']['broker_id'] == id, 'id different from broker_id'
1290
+ broker_id = request['params']['broker_id']
1291
+ assert broker_id == id, 'cryptocom - id: ' + id + ' different from broker_id: ' + broker_id
1269
1292
  await close(exchange)
1270
1293
  return True
1271
1294
 
@@ -1279,22 +1302,25 @@ class testMainClass(baseMainTestClass):
1279
1302
  except Exception as e:
1280
1303
  # we expect an error here, we're only interested in the headers
1281
1304
  req_headers = exchange.last_request_headers
1282
- assert req_headers['Referer'] == id, 'id not in headers'
1305
+ assert req_headers['Referer'] == id, 'bybit - id: ' + id + ' not in headers.'
1283
1306
  await close(exchange)
1284
1307
  return True
1285
1308
 
1286
1309
  async def test_kucoin(self):
1287
1310
  exchange = self.init_offline_exchange('kucoin')
1288
1311
  req_headers = None
1289
- assert exchange.options['partner']['spot']['id'] == 'ccxt', 'id not in options'
1290
- assert exchange.options['partner']['spot']['key'] == '9e58cc35-5b5e-4133-92ec-166e3f077cb8', 'key not in options'
1312
+ options_string = str(exchange.options)
1313
+ spot_id = exchange.options['partner']['spot']['id']
1314
+ spot_key = exchange.options['partner']['spot']['key']
1315
+ assert spot_id == 'ccxt', 'kucoin - id: ' + spot_id + ' not in options: ' + options_string
1316
+ assert spot_key == '9e58cc35-5b5e-4133-92ec-166e3f077cb8', 'kucoin - key: ' + spot_key + ' not in options: ' + options_string
1291
1317
  try:
1292
1318
  await exchange.create_order('BTC/USDT', 'limit', 'buy', 1, 20000)
1293
1319
  except Exception as e:
1294
1320
  # we expect an error here, we're only interested in the headers
1295
1321
  req_headers = exchange.last_request_headers
1296
1322
  id = 'ccxt'
1297
- assert req_headers['KC-API-PARTNER'] == id, 'id not in headers'
1323
+ assert req_headers['KC-API-PARTNER'] == id, 'kucoin - id: ' + id + ' not in headers.'
1298
1324
  await close(exchange)
1299
1325
  return True
1300
1326
 
@@ -1302,13 +1328,16 @@ class testMainClass(baseMainTestClass):
1302
1328
  exchange = self.init_offline_exchange('kucoinfutures')
1303
1329
  req_headers = None
1304
1330
  id = 'ccxtfutures'
1305
- assert exchange.options['partner']['future']['id'] == id, 'id not in options'
1306
- assert exchange.options['partner']['future']['key'] == '1b327198-f30c-4f14-a0ac-918871282f15', 'key not in options'
1331
+ options_string = str(exchange.options['partner']['future'])
1332
+ future_id = exchange.options['partner']['future']['id']
1333
+ future_key = exchange.options['partner']['future']['key']
1334
+ assert future_id == id, 'kucoinfutures - id: ' + future_id + ' not in options: ' + options_string
1335
+ assert future_key == '1b327198-f30c-4f14-a0ac-918871282f15', 'kucoinfutures - key: ' + future_key + ' not in options: ' + options_string
1307
1336
  try:
1308
1337
  await exchange.create_order('BTC/USDT:USDT', 'limit', 'buy', 1, 20000)
1309
1338
  except Exception as e:
1310
1339
  req_headers = exchange.last_request_headers
1311
- assert req_headers['KC-API-PARTNER'] == id, 'id not in headers'
1340
+ assert req_headers['KC-API-PARTNER'] == id, 'kucoinfutures - id: ' + id + ' not in headers.'
1312
1341
  await close(exchange)
1313
1342
  return True
1314
1343
 
@@ -1316,12 +1345,13 @@ class testMainClass(baseMainTestClass):
1316
1345
  exchange = self.init_offline_exchange('bitget')
1317
1346
  req_headers = None
1318
1347
  id = 'p4sve'
1319
- assert exchange.options['broker'] == id, 'id not in options'
1348
+ options_string = str(exchange.options)
1349
+ assert exchange.options['broker'] == id, 'bitget - id: ' + id + ' not in options: ' + options_string
1320
1350
  try:
1321
1351
  await exchange.create_order('BTC/USDT', 'limit', 'buy', 1, 20000)
1322
1352
  except Exception as e:
1323
1353
  req_headers = exchange.last_request_headers
1324
- assert req_headers['X-CHANNEL-API-CODE'] == id, 'id not in headers'
1354
+ assert req_headers['X-CHANNEL-API-CODE'] == id, 'bitget - id: ' + id + ' not in headers.'
1325
1355
  await close(exchange)
1326
1356
  return True
1327
1357
 
@@ -1329,13 +1359,15 @@ class testMainClass(baseMainTestClass):
1329
1359
  exchange = self.init_offline_exchange('mexc')
1330
1360
  req_headers = None
1331
1361
  id = 'CCXT'
1332
- assert exchange.options['broker'] == id, 'id not in options'
1362
+ options_string = str(exchange.options)
1363
+ assert exchange.options['broker'] == id, 'mexc - id: ' + id + ' not in options: ' + options_string
1333
1364
  await exchange.load_markets()
1334
1365
  try:
1335
1366
  await exchange.create_order('BTC/USDT', 'limit', 'buy', 1, 20000)
1336
1367
  except Exception as e:
1337
1368
  req_headers = exchange.last_request_headers
1338
- assert req_headers['source'] == id, 'id not in headers'
1369
+ req_headers_string = str(req_headers) if req_headers is not None else 'undefined'
1370
+ assert req_headers['source'] == id, 'mexc - id: ' + id + ' not in headers: ' + req_headers_string
1339
1371
  await close(exchange)
1340
1372
  return True
1341
1373
 
@@ -1349,7 +1381,8 @@ class testMainClass(baseMainTestClass):
1349
1381
  except Exception as e:
1350
1382
  spot_order_request = json_parse(exchange.last_request_body)
1351
1383
  client_order_id = spot_order_request['client-order-id']
1352
- assert client_order_id.startswith(str(id)), 'spot clientOrderId does not start with id'
1384
+ id_string = str(id)
1385
+ assert client_order_id.startswith(id_string), 'htx - spot clientOrderId ' + client_order_id + ' does not start with id: ' + id_string
1353
1386
  # swap test
1354
1387
  swap_order_request = None
1355
1388
  try:
@@ -1361,10 +1394,10 @@ class testMainClass(baseMainTestClass):
1361
1394
  await exchange.create_order('BTC/USD:BTC', 'limit', 'buy', 1, 20000)
1362
1395
  except Exception as e:
1363
1396
  swap_inverse_order_request = json_parse(exchange.last_request_body)
1364
- client_order_id_spot = swap_order_request['channel_code']
1365
- assert client_order_id_spot.startswith(str(id)), 'swap channel_code does not start with id'
1397
+ client_order_id_swap = swap_order_request['channel_code']
1398
+ assert client_order_id_swap.startswith(id_string), 'htx - swap channel_code ' + client_order_id_swap + ' does not start with id: ' + id_string
1366
1399
  client_order_id_inverse = swap_inverse_order_request['channel_code']
1367
- assert client_order_id_inverse.startswith(str(id)), 'swap inverse channel_code does not start with id'
1400
+ assert client_order_id_inverse.startswith(id_string), 'htx - swap inverse channel_code ' + client_order_id_inverse + ' does not start with id: ' + id_string
1368
1401
  await close(exchange)
1369
1402
  return True
1370
1403
 
@@ -1378,7 +1411,8 @@ class testMainClass(baseMainTestClass):
1378
1411
  except Exception as e:
1379
1412
  spot_order_request = self.urlencoded_to_dict(exchange.last_request_body)
1380
1413
  broker_id = spot_order_request['broker_id']
1381
- assert broker_id.startswith(str(id)), 'broker_id does not start with id'
1414
+ id_string = str(id)
1415
+ assert broker_id.startswith(id_string), 'woo - broker_id: ' + broker_id + ' does not start with id: ' + id_string
1382
1416
  # swap test
1383
1417
  stop_order_request = None
1384
1418
  try:
@@ -1387,8 +1421,8 @@ class testMainClass(baseMainTestClass):
1387
1421
  })
1388
1422
  except Exception as e:
1389
1423
  stop_order_request = json_parse(exchange.last_request_body)
1390
- client_order_id_spot = stop_order_request['brokerId']
1391
- assert client_order_id_spot.startswith(str(id)), 'brokerId does not start with id'
1424
+ client_order_id_stop = stop_order_request['brokerId']
1425
+ assert client_order_id_stop.startswith(id_string), 'woo - brokerId: ' + client_order_id_stop + ' does not start with id: ' + id_string
1392
1426
  await close(exchange)
1393
1427
  return True
1394
1428
 
@@ -1396,27 +1430,28 @@ class testMainClass(baseMainTestClass):
1396
1430
  exchange = self.init_offline_exchange('bitmart')
1397
1431
  req_headers = None
1398
1432
  id = 'CCXTxBitmart000'
1399
- assert exchange.options['brokerId'] == id, 'id not in options'
1433
+ assert exchange.options['brokerId'] == id, 'bitmart - id: ' + id + ' not in options'
1400
1434
  await exchange.load_markets()
1401
1435
  try:
1402
1436
  await exchange.create_order('BTC/USDT', 'limit', 'buy', 1, 20000)
1403
1437
  except Exception as e:
1404
1438
  req_headers = exchange.last_request_headers
1405
- assert req_headers['X-BM-BROKER-ID'] == id, 'id not in headers'
1439
+ assert req_headers['X-BM-BROKER-ID'] == id, 'bitmart - id: ' + id + ' not in headers'
1406
1440
  await close(exchange)
1407
1441
  return True
1408
1442
 
1409
1443
  async def test_coinex(self):
1410
1444
  exchange = self.init_offline_exchange('coinex')
1411
1445
  id = 'x-167673045'
1412
- assert exchange.options['brokerId'] == id, 'id not in options'
1446
+ assert exchange.options['brokerId'] == id, 'coinex - id: ' + id + ' not in options'
1413
1447
  spot_order_request = None
1414
1448
  try:
1415
1449
  await exchange.create_order('BTC/USDT', 'limit', 'buy', 1, 20000)
1416
1450
  except Exception as e:
1417
1451
  spot_order_request = json_parse(exchange.last_request_body)
1418
1452
  client_order_id = spot_order_request['client_id']
1419
- assert client_order_id.startswith(str(id)), 'clientOrderId does not start with id'
1453
+ id_string = str(id)
1454
+ assert client_order_id.startswith(id_string), 'coinex - clientOrderId: ' + client_order_id + ' does not start with id: ' + id_string
1420
1455
  await close(exchange)
1421
1456
  return True
1422
1457
 
@@ -1424,13 +1459,15 @@ class testMainClass(baseMainTestClass):
1424
1459
  exchange = self.init_offline_exchange('bingx')
1425
1460
  req_headers = None
1426
1461
  id = 'CCXT'
1427
- assert exchange.options['broker'] == id, 'id not in options'
1462
+ options_string = str(exchange.options)
1463
+ assert exchange.options['broker'] == id, 'bingx - id: ' + id + ' not in options: ' + options_string
1428
1464
  try:
1429
1465
  await exchange.create_order('BTC/USDT', 'limit', 'buy', 1, 20000)
1430
1466
  except Exception as e:
1431
1467
  # we expect an error here, we're only interested in the headers
1432
1468
  req_headers = exchange.last_request_headers
1433
- assert req_headers['X-SOURCE-KEY'] == id, 'id not in headers'
1469
+ req_headers_string = str(req_headers) if req_headers is not None else 'undefined'
1470
+ assert req_headers['X-SOURCE-KEY'] == id, 'bingx - id: ' + id + ' not in headers: ' + req_headers_string
1434
1471
  await close(exchange)
1435
1472
 
1436
1473
  async def test_phemex(self):
@@ -1442,7 +1479,8 @@ class testMainClass(baseMainTestClass):
1442
1479
  except Exception as e:
1443
1480
  request = json_parse(exchange.last_request_body)
1444
1481
  client_order_id = request['clOrdID']
1445
- assert client_order_id.startswith(str(id)), 'clOrdID does not start with id'
1482
+ id_string = str(id)
1483
+ assert client_order_id.startswith(id_string), 'phemex - clOrdID: ' + client_order_id + ' does not start with id: ' + id_string
1446
1484
  await close(exchange)
1447
1485
 
1448
1486
  async def test_blofin(self):
@@ -1454,7 +1492,8 @@ class testMainClass(baseMainTestClass):
1454
1492
  except Exception as e:
1455
1493
  request = json_parse(exchange.last_request_body)
1456
1494
  broker_id = request['brokerId']
1457
- assert broker_id.startswith(str(id)), 'brokerId does not start with id'
1495
+ id_string = str(id)
1496
+ assert broker_id.startswith(id_string), 'blofin - brokerId: ' + broker_id + ' does not start with id: ' + id_string
1458
1497
  await close(exchange)
1459
1498
 
1460
1499
  async def test_hyperliquid(self):
@@ -1466,7 +1505,7 @@ class testMainClass(baseMainTestClass):
1466
1505
  except Exception as e:
1467
1506
  request = json_parse(exchange.last_request_body)
1468
1507
  broker_id = str((request['action']['brokerCode']))
1469
- assert broker_id == id, 'brokerId does not start with id'
1508
+ assert broker_id == id, 'hyperliquid - brokerId: ' + broker_id + ' does not start with id: ' + id
1470
1509
  await close(exchange)
1471
1510
 
1472
1511
  # ***** AUTO-TRANSPILER-END *****
ccxt/test/test_sync.py CHANGED
@@ -448,13 +448,30 @@ class testMainClass(baseMainTestClass):
448
448
  if self.info:
449
449
  args_stringified = '(' + ','.join(args) + ')'
450
450
  dump(self.add_padding('[INFO] TESTING', 25), self.exchange_hint(exchange), method_name, args_stringified)
451
- skipped_properties = exchange.safe_value(self.skipped_methods, method_name, {})
452
- call_method(self.test_files, method_name, exchange, skipped_properties, args)
451
+ call_method(self.test_files, method_name, exchange, self.get_skips(exchange, method_name), args)
453
452
  # if it was passed successfully, add to the list of successfull tests
454
453
  if is_public:
455
454
  self.checked_public_tests[method_name] = True
456
455
  return
457
456
 
457
+ def get_skips(self, exchange, method_name):
458
+ # get "method-specific" skips
459
+ skips_for_method = exchange.safe_value(self.skipped_methods, method_name, {})
460
+ # get "object-specific" skips
461
+ if exchange.in_array(method_name, ['fetchOrderBook', 'fetchOrderBooks', 'fetchL2OrderBook', 'watchOrderBook', 'watchOrderBookForSymbols']):
462
+ skips = exchange.safe_value(self.skipped_methods, 'orderBook', {})
463
+ return exchange.deep_extend(skips_for_method, skips)
464
+ elif exchange.in_array(method_name, ['fetchTicker', 'fetchTickers', 'watchTicker', 'watchTickers']):
465
+ skips = exchange.safe_value(self.skipped_methods, 'ticker', {})
466
+ return exchange.deep_extend(skips_for_method, skips)
467
+ elif exchange.in_array(method_name, ['fetchTrades', 'watchTrades', 'watchTradesForSymbols']):
468
+ skips = exchange.safe_value(self.skipped_methods, 'trade', {})
469
+ return exchange.deep_extend(skips_for_method, skips)
470
+ elif exchange.in_array(method_name, ['fetchOHLCV', 'watchOHLCV', 'watchOHLCVForSymbols']):
471
+ skips = exchange.safe_value(self.skipped_methods, 'ohlcv', {})
472
+ return exchange.deep_extend(skips_for_method, skips)
473
+ return skips_for_method
474
+
458
475
  def test_safe(self, method_name, exchange, args=[], is_public=False):
459
476
  # `testSafe` method does not throw an exception, instead mutes it. The reason we
460
477
  # mute the thrown exceptions here is because we don't want to stop the whole
@@ -1214,7 +1231,8 @@ class testMainClass(baseMainTestClass):
1214
1231
  except Exception as e:
1215
1232
  spot_order_request = self.urlencoded_to_dict(exchange.last_request_body)
1216
1233
  client_order_id = spot_order_request['newClientOrderId']
1217
- assert client_order_id.startswith(str(spot_id)), 'spot clientOrderId does not start with spotId'
1234
+ spot_id_string = str(spot_id)
1235
+ assert client_order_id.startswith(spot_id_string), 'binance - spot clientOrderId: ' + client_order_id + ' does not start with spotId' + spot_id_string
1218
1236
  swap_id = 'x-xcKtGhcu'
1219
1237
  swap_order_request = None
1220
1238
  try:
@@ -1226,10 +1244,11 @@ class testMainClass(baseMainTestClass):
1226
1244
  exchange.create_order('BTC/USD:BTC', 'limit', 'buy', 1, 20000)
1227
1245
  except Exception as e:
1228
1246
  swap_inverse_order_request = self.urlencoded_to_dict(exchange.last_request_body)
1229
- client_order_id_spot = swap_order_request['newClientOrderId']
1230
- assert client_order_id_spot.startswith(str(swap_id)), 'swap clientOrderId does not start with swapId'
1247
+ client_order_id_swap = swap_order_request['newClientOrderId']
1248
+ swap_id_string = str(swap_id)
1249
+ assert client_order_id_swap.startswith(swap_id_string), 'binance - swap clientOrderId: ' + client_order_id_swap + ' does not start with swapId' + swap_id_string
1231
1250
  client_order_id_inverse = swap_inverse_order_request['newClientOrderId']
1232
- assert client_order_id_inverse.startswith(str(swap_id)), 'swap clientOrderIdInverse does not start with swapId'
1251
+ assert client_order_id_inverse.startswith(swap_id_string), 'binance - swap clientOrderIdInverse: ' + client_order_id_inverse + ' does not start with swapId' + swap_id_string
1233
1252
  close(exchange)
1234
1253
  return True
1235
1254
 
@@ -1242,16 +1261,19 @@ class testMainClass(baseMainTestClass):
1242
1261
  except Exception as e:
1243
1262
  spot_order_request = json_parse(exchange.last_request_body)
1244
1263
  client_order_id = spot_order_request[0]['clOrdId'] # returns order inside array
1245
- assert client_order_id.startswith(str(id)), 'spot clientOrderId does not start with id'
1246
- assert spot_order_request[0]['tag'] == id, 'id different from spot tag'
1264
+ id_string = str(id)
1265
+ assert client_order_id.startswith(id_string), 'okx - spot clientOrderId: ' + client_order_id + ' does not start with id: ' + id_string
1266
+ spot_tag = spot_order_request[0]['tag']
1267
+ assert spot_tag == id, 'okx - id: ' + id + ' different from spot tag: ' + spot_tag
1247
1268
  swap_order_request = None
1248
1269
  try:
1249
1270
  exchange.create_order('BTC/USDT:USDT', 'limit', 'buy', 1, 20000)
1250
1271
  except Exception as e:
1251
1272
  swap_order_request = json_parse(exchange.last_request_body)
1252
- client_order_id_spot = swap_order_request[0]['clOrdId']
1253
- assert client_order_id_spot.startswith(str(id)), 'swap clientOrderId does not start with id'
1254
- assert swap_order_request[0]['tag'] == id, 'id different from swap tag'
1273
+ client_order_id_swap = swap_order_request[0]['clOrdId']
1274
+ assert client_order_id_swap.startswith(id_string), 'okx - swap clientOrderId: ' + client_order_id_swap + ' does not start with id: ' + id_string
1275
+ swap_tag = swap_order_request[0]['tag']
1276
+ assert swap_tag == id, 'okx - id: ' + id + ' different from swap tag: ' + swap_tag
1255
1277
  close(exchange)
1256
1278
  return True
1257
1279
 
@@ -1264,7 +1286,8 @@ class testMainClass(baseMainTestClass):
1264
1286
  exchange.create_order('BTC/USDT', 'limit', 'buy', 1, 20000)
1265
1287
  except Exception as e:
1266
1288
  request = json_parse(exchange.last_request_body)
1267
- assert request['params']['broker_id'] == id, 'id different from broker_id'
1289
+ broker_id = request['params']['broker_id']
1290
+ assert broker_id == id, 'cryptocom - id: ' + id + ' different from broker_id: ' + broker_id
1268
1291
  close(exchange)
1269
1292
  return True
1270
1293
 
@@ -1278,22 +1301,25 @@ class testMainClass(baseMainTestClass):
1278
1301
  except Exception as e:
1279
1302
  # we expect an error here, we're only interested in the headers
1280
1303
  req_headers = exchange.last_request_headers
1281
- assert req_headers['Referer'] == id, 'id not in headers'
1304
+ assert req_headers['Referer'] == id, 'bybit - id: ' + id + ' not in headers.'
1282
1305
  close(exchange)
1283
1306
  return True
1284
1307
 
1285
1308
  def test_kucoin(self):
1286
1309
  exchange = self.init_offline_exchange('kucoin')
1287
1310
  req_headers = None
1288
- assert exchange.options['partner']['spot']['id'] == 'ccxt', 'id not in options'
1289
- assert exchange.options['partner']['spot']['key'] == '9e58cc35-5b5e-4133-92ec-166e3f077cb8', 'key not in options'
1311
+ options_string = str(exchange.options)
1312
+ spot_id = exchange.options['partner']['spot']['id']
1313
+ spot_key = exchange.options['partner']['spot']['key']
1314
+ assert spot_id == 'ccxt', 'kucoin - id: ' + spot_id + ' not in options: ' + options_string
1315
+ assert spot_key == '9e58cc35-5b5e-4133-92ec-166e3f077cb8', 'kucoin - key: ' + spot_key + ' not in options: ' + options_string
1290
1316
  try:
1291
1317
  exchange.create_order('BTC/USDT', 'limit', 'buy', 1, 20000)
1292
1318
  except Exception as e:
1293
1319
  # we expect an error here, we're only interested in the headers
1294
1320
  req_headers = exchange.last_request_headers
1295
1321
  id = 'ccxt'
1296
- assert req_headers['KC-API-PARTNER'] == id, 'id not in headers'
1322
+ assert req_headers['KC-API-PARTNER'] == id, 'kucoin - id: ' + id + ' not in headers.'
1297
1323
  close(exchange)
1298
1324
  return True
1299
1325
 
@@ -1301,13 +1327,16 @@ class testMainClass(baseMainTestClass):
1301
1327
  exchange = self.init_offline_exchange('kucoinfutures')
1302
1328
  req_headers = None
1303
1329
  id = 'ccxtfutures'
1304
- assert exchange.options['partner']['future']['id'] == id, 'id not in options'
1305
- assert exchange.options['partner']['future']['key'] == '1b327198-f30c-4f14-a0ac-918871282f15', 'key not in options'
1330
+ options_string = str(exchange.options['partner']['future'])
1331
+ future_id = exchange.options['partner']['future']['id']
1332
+ future_key = exchange.options['partner']['future']['key']
1333
+ assert future_id == id, 'kucoinfutures - id: ' + future_id + ' not in options: ' + options_string
1334
+ assert future_key == '1b327198-f30c-4f14-a0ac-918871282f15', 'kucoinfutures - key: ' + future_key + ' not in options: ' + options_string
1306
1335
  try:
1307
1336
  exchange.create_order('BTC/USDT:USDT', 'limit', 'buy', 1, 20000)
1308
1337
  except Exception as e:
1309
1338
  req_headers = exchange.last_request_headers
1310
- assert req_headers['KC-API-PARTNER'] == id, 'id not in headers'
1339
+ assert req_headers['KC-API-PARTNER'] == id, 'kucoinfutures - id: ' + id + ' not in headers.'
1311
1340
  close(exchange)
1312
1341
  return True
1313
1342
 
@@ -1315,12 +1344,13 @@ class testMainClass(baseMainTestClass):
1315
1344
  exchange = self.init_offline_exchange('bitget')
1316
1345
  req_headers = None
1317
1346
  id = 'p4sve'
1318
- assert exchange.options['broker'] == id, 'id not in options'
1347
+ options_string = str(exchange.options)
1348
+ assert exchange.options['broker'] == id, 'bitget - id: ' + id + ' not in options: ' + options_string
1319
1349
  try:
1320
1350
  exchange.create_order('BTC/USDT', 'limit', 'buy', 1, 20000)
1321
1351
  except Exception as e:
1322
1352
  req_headers = exchange.last_request_headers
1323
- assert req_headers['X-CHANNEL-API-CODE'] == id, 'id not in headers'
1353
+ assert req_headers['X-CHANNEL-API-CODE'] == id, 'bitget - id: ' + id + ' not in headers.'
1324
1354
  close(exchange)
1325
1355
  return True
1326
1356
 
@@ -1328,13 +1358,15 @@ class testMainClass(baseMainTestClass):
1328
1358
  exchange = self.init_offline_exchange('mexc')
1329
1359
  req_headers = None
1330
1360
  id = 'CCXT'
1331
- assert exchange.options['broker'] == id, 'id not in options'
1361
+ options_string = str(exchange.options)
1362
+ assert exchange.options['broker'] == id, 'mexc - id: ' + id + ' not in options: ' + options_string
1332
1363
  exchange.load_markets()
1333
1364
  try:
1334
1365
  exchange.create_order('BTC/USDT', 'limit', 'buy', 1, 20000)
1335
1366
  except Exception as e:
1336
1367
  req_headers = exchange.last_request_headers
1337
- assert req_headers['source'] == id, 'id not in headers'
1368
+ req_headers_string = str(req_headers) if req_headers is not None else 'undefined'
1369
+ assert req_headers['source'] == id, 'mexc - id: ' + id + ' not in headers: ' + req_headers_string
1338
1370
  close(exchange)
1339
1371
  return True
1340
1372
 
@@ -1348,7 +1380,8 @@ class testMainClass(baseMainTestClass):
1348
1380
  except Exception as e:
1349
1381
  spot_order_request = json_parse(exchange.last_request_body)
1350
1382
  client_order_id = spot_order_request['client-order-id']
1351
- assert client_order_id.startswith(str(id)), 'spot clientOrderId does not start with id'
1383
+ id_string = str(id)
1384
+ assert client_order_id.startswith(id_string), 'htx - spot clientOrderId ' + client_order_id + ' does not start with id: ' + id_string
1352
1385
  # swap test
1353
1386
  swap_order_request = None
1354
1387
  try:
@@ -1360,10 +1393,10 @@ class testMainClass(baseMainTestClass):
1360
1393
  exchange.create_order('BTC/USD:BTC', 'limit', 'buy', 1, 20000)
1361
1394
  except Exception as e:
1362
1395
  swap_inverse_order_request = json_parse(exchange.last_request_body)
1363
- client_order_id_spot = swap_order_request['channel_code']
1364
- assert client_order_id_spot.startswith(str(id)), 'swap channel_code does not start with id'
1396
+ client_order_id_swap = swap_order_request['channel_code']
1397
+ assert client_order_id_swap.startswith(id_string), 'htx - swap channel_code ' + client_order_id_swap + ' does not start with id: ' + id_string
1365
1398
  client_order_id_inverse = swap_inverse_order_request['channel_code']
1366
- assert client_order_id_inverse.startswith(str(id)), 'swap inverse channel_code does not start with id'
1399
+ assert client_order_id_inverse.startswith(id_string), 'htx - swap inverse channel_code ' + client_order_id_inverse + ' does not start with id: ' + id_string
1367
1400
  close(exchange)
1368
1401
  return True
1369
1402
 
@@ -1377,7 +1410,8 @@ class testMainClass(baseMainTestClass):
1377
1410
  except Exception as e:
1378
1411
  spot_order_request = self.urlencoded_to_dict(exchange.last_request_body)
1379
1412
  broker_id = spot_order_request['broker_id']
1380
- assert broker_id.startswith(str(id)), 'broker_id does not start with id'
1413
+ id_string = str(id)
1414
+ assert broker_id.startswith(id_string), 'woo - broker_id: ' + broker_id + ' does not start with id: ' + id_string
1381
1415
  # swap test
1382
1416
  stop_order_request = None
1383
1417
  try:
@@ -1386,8 +1420,8 @@ class testMainClass(baseMainTestClass):
1386
1420
  })
1387
1421
  except Exception as e:
1388
1422
  stop_order_request = json_parse(exchange.last_request_body)
1389
- client_order_id_spot = stop_order_request['brokerId']
1390
- assert client_order_id_spot.startswith(str(id)), 'brokerId does not start with id'
1423
+ client_order_id_stop = stop_order_request['brokerId']
1424
+ assert client_order_id_stop.startswith(id_string), 'woo - brokerId: ' + client_order_id_stop + ' does not start with id: ' + id_string
1391
1425
  close(exchange)
1392
1426
  return True
1393
1427
 
@@ -1395,27 +1429,28 @@ class testMainClass(baseMainTestClass):
1395
1429
  exchange = self.init_offline_exchange('bitmart')
1396
1430
  req_headers = None
1397
1431
  id = 'CCXTxBitmart000'
1398
- assert exchange.options['brokerId'] == id, 'id not in options'
1432
+ assert exchange.options['brokerId'] == id, 'bitmart - id: ' + id + ' not in options'
1399
1433
  exchange.load_markets()
1400
1434
  try:
1401
1435
  exchange.create_order('BTC/USDT', 'limit', 'buy', 1, 20000)
1402
1436
  except Exception as e:
1403
1437
  req_headers = exchange.last_request_headers
1404
- assert req_headers['X-BM-BROKER-ID'] == id, 'id not in headers'
1438
+ assert req_headers['X-BM-BROKER-ID'] == id, 'bitmart - id: ' + id + ' not in headers'
1405
1439
  close(exchange)
1406
1440
  return True
1407
1441
 
1408
1442
  def test_coinex(self):
1409
1443
  exchange = self.init_offline_exchange('coinex')
1410
1444
  id = 'x-167673045'
1411
- assert exchange.options['brokerId'] == id, 'id not in options'
1445
+ assert exchange.options['brokerId'] == id, 'coinex - id: ' + id + ' not in options'
1412
1446
  spot_order_request = None
1413
1447
  try:
1414
1448
  exchange.create_order('BTC/USDT', 'limit', 'buy', 1, 20000)
1415
1449
  except Exception as e:
1416
1450
  spot_order_request = json_parse(exchange.last_request_body)
1417
1451
  client_order_id = spot_order_request['client_id']
1418
- assert client_order_id.startswith(str(id)), 'clientOrderId does not start with id'
1452
+ id_string = str(id)
1453
+ assert client_order_id.startswith(id_string), 'coinex - clientOrderId: ' + client_order_id + ' does not start with id: ' + id_string
1419
1454
  close(exchange)
1420
1455
  return True
1421
1456
 
@@ -1423,13 +1458,15 @@ class testMainClass(baseMainTestClass):
1423
1458
  exchange = self.init_offline_exchange('bingx')
1424
1459
  req_headers = None
1425
1460
  id = 'CCXT'
1426
- assert exchange.options['broker'] == id, 'id not in options'
1461
+ options_string = str(exchange.options)
1462
+ assert exchange.options['broker'] == id, 'bingx - id: ' + id + ' not in options: ' + options_string
1427
1463
  try:
1428
1464
  exchange.create_order('BTC/USDT', 'limit', 'buy', 1, 20000)
1429
1465
  except Exception as e:
1430
1466
  # we expect an error here, we're only interested in the headers
1431
1467
  req_headers = exchange.last_request_headers
1432
- assert req_headers['X-SOURCE-KEY'] == id, 'id not in headers'
1468
+ req_headers_string = str(req_headers) if req_headers is not None else 'undefined'
1469
+ assert req_headers['X-SOURCE-KEY'] == id, 'bingx - id: ' + id + ' not in headers: ' + req_headers_string
1433
1470
  close(exchange)
1434
1471
 
1435
1472
  def test_phemex(self):
@@ -1441,7 +1478,8 @@ class testMainClass(baseMainTestClass):
1441
1478
  except Exception as e:
1442
1479
  request = json_parse(exchange.last_request_body)
1443
1480
  client_order_id = request['clOrdID']
1444
- assert client_order_id.startswith(str(id)), 'clOrdID does not start with id'
1481
+ id_string = str(id)
1482
+ assert client_order_id.startswith(id_string), 'phemex - clOrdID: ' + client_order_id + ' does not start with id: ' + id_string
1445
1483
  close(exchange)
1446
1484
 
1447
1485
  def test_blofin(self):
@@ -1453,7 +1491,8 @@ class testMainClass(baseMainTestClass):
1453
1491
  except Exception as e:
1454
1492
  request = json_parse(exchange.last_request_body)
1455
1493
  broker_id = request['brokerId']
1456
- assert broker_id.startswith(str(id)), 'brokerId does not start with id'
1494
+ id_string = str(id)
1495
+ assert broker_id.startswith(id_string), 'blofin - brokerId: ' + broker_id + ' does not start with id: ' + id_string
1457
1496
  close(exchange)
1458
1497
 
1459
1498
  def test_hyperliquid(self):
@@ -1465,7 +1504,7 @@ class testMainClass(baseMainTestClass):
1465
1504
  except Exception as e:
1466
1505
  request = json_parse(exchange.last_request_body)
1467
1506
  broker_id = str((request['action']['brokerCode']))
1468
- assert broker_id == id, 'brokerId does not start with id'
1507
+ assert broker_id == id, 'hyperliquid - brokerId: ' + broker_id + ' does not start with id: ' + id
1469
1508
  close(exchange)
1470
1509
 
1471
1510
  # ***** AUTO-TRANSPILER-END *****
ccxt/wazirx.py CHANGED
@@ -6,7 +6,7 @@
6
6
  from ccxt.base.exchange import Exchange
7
7
  from ccxt.abstract.wazirx import ImplicitAPI
8
8
  import hashlib
9
- from ccxt.base.types import Balances, Currency, Int, Market, Order, OrderBook, OrderSide, OrderType, Num, Str, Strings, Ticker, Tickers, Trade, Transaction
9
+ from ccxt.base.types import Balances, Currency, Int, Market, Num, Order, OrderBook, OrderSide, OrderType, Str, Strings, Ticker, Tickers, Trade, Transaction
10
10
  from typing import List
11
11
  from ccxt.base.errors import ExchangeError
12
12
  from ccxt.base.errors import PermissionDenied
ccxt/whitebit.py CHANGED
@@ -6,7 +6,7 @@
6
6
  from ccxt.base.exchange import Exchange
7
7
  from ccxt.abstract.whitebit import ImplicitAPI
8
8
  import hashlib
9
- from ccxt.base.types import Balances, Currency, Int, MarketType, Market, Order, TransferEntry, OrderBook, OrderSide, OrderType, Str, Bool, Strings, Ticker, Tickers, Trade, Transaction
9
+ from ccxt.base.types import Balances, Bool, Currency, Int, Market, MarketType, Order, OrderBook, OrderSide, OrderType, Str, Strings, Ticker, Tickers, Trade, Transaction, TransferEntry
10
10
  from typing import List
11
11
  from ccxt.base.errors import ExchangeError
12
12
  from ccxt.base.errors import PermissionDenied
ccxt/woo.py CHANGED
@@ -6,7 +6,7 @@
6
6
  from ccxt.base.exchange import Exchange
7
7
  from ccxt.abstract.woo import ImplicitAPI
8
8
  import hashlib
9
- from ccxt.base.types import Balances, Currency, Int, Leverage, MarketType, Market, Order, TransferEntry, OrderBook, OrderSide, OrderType, Num, Str, Bool, Strings, Trade, Transaction
9
+ from ccxt.base.types import Balances, Bool, Currency, Int, Leverage, Market, MarketType, Num, Order, OrderBook, OrderSide, OrderType, Str, Strings, Trade, Transaction, TransferEntry
10
10
  from typing import List
11
11
  from ccxt.base.errors import ExchangeError
12
12
  from ccxt.base.errors import ArgumentsRequired