ccxt 4.3.66__py2.py3-none-any.whl → 4.3.67__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 +147 -19
- 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 +10 -10
- ccxt/bingx.py +147 -19
- 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/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.67.dist-info}/METADATA +4 -4
- {ccxt-4.3.66.dist-info → ccxt-4.3.67.dist-info}/RECORD +37 -37
- {ccxt-4.3.66.dist-info → ccxt-4.3.67.dist-info}/LICENSE.txt +0 -0
- {ccxt-4.3.66.dist-info → ccxt-4.3.67.dist-info}/WHEEL +0 -0
- {ccxt-4.3.66.dist-info → ccxt-4.3.67.dist-info}/top_level.txt +0 -0
ccxt/test/tests_async.py
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
import asyncio
|
4
4
|
|
5
5
|
|
6
|
-
from tests_helpers import
|
6
|
+
from tests_helpers import AuthenticationError, NotSupported, InvalidProxySettings, ExchangeNotAvailable, OperationFailed, OnMaintenance, get_cli_arg_value, baseMainTestClass, dump, json_parse, json_stringify, convert_ascii, io_file_exists, io_file_read, io_dir_read, call_method, call_method_sync, call_exchange_method_dynamically, call_exchange_method_dynamically_sync, exception_message, exit_script, get_exchange_prop, set_exchange_prop, init_exchange, get_test_files_sync, get_test_files, set_fetch_response, is_null_value, close # noqa: F401
|
7
7
|
|
8
8
|
class testMainClass(baseMainTestClass):
|
9
9
|
def parse_cli_args(self):
|
@@ -72,7 +72,10 @@ class testMainClass(baseMainTestClass):
|
|
72
72
|
async def import_files(self, exchange):
|
73
73
|
properties = list(exchange.has.keys())
|
74
74
|
properties.append('loadMarkets')
|
75
|
-
|
75
|
+
if self.is_synchronous:
|
76
|
+
self.test_files = get_test_files_sync(properties, self.ws_tests)
|
77
|
+
else:
|
78
|
+
self.test_files = await get_test_files(properties, self.ws_tests)
|
76
79
|
|
77
80
|
def load_credentials_from_env(self, exchange):
|
78
81
|
exchange_id = exchange.id
|
@@ -192,7 +195,10 @@ class testMainClass(baseMainTestClass):
|
|
192
195
|
if self.info:
|
193
196
|
args_stringified = '(' + exchange.json(args) + ')' # args.join() breaks when we provide a list of symbols or multidimensional array; "args.toString()" breaks bcz of "array to string conversion"
|
194
197
|
dump(self.add_padding('[INFO] TESTING', 25), self.exchange_hint(exchange), method_name, args_stringified)
|
195
|
-
|
198
|
+
if self.is_synchronous:
|
199
|
+
call_method_sync(self.test_files, method_name, exchange, skipped_properties_for_method, args)
|
200
|
+
else:
|
201
|
+
await call_method(self.test_files, method_name, exchange, skipped_properties_for_method, args)
|
196
202
|
if self.info:
|
197
203
|
dump(self.add_padding('[INFO] TESTING DONE', 25), self.exchange_hint(exchange), method_name)
|
198
204
|
# add to the list of successed tests
|
@@ -587,7 +593,7 @@ class testMainClass(baseMainTestClass):
|
|
587
593
|
if exception is not None:
|
588
594
|
error_message = '[TEST_FAILURE] Failed ' + proxy_test_name + ' : ' + exception_message(exception)
|
589
595
|
# temporary comment the below, because c# transpilation failure
|
590
|
-
# throw new
|
596
|
+
# throw new Exchange Error (errorMessage.toString ());
|
591
597
|
dump('[TEST_WARNING]' + str(error_message))
|
592
598
|
|
593
599
|
async def start_test(self, exchange, symbol):
|
@@ -599,16 +605,19 @@ class testMainClass(baseMainTestClass):
|
|
599
605
|
try:
|
600
606
|
result = await self.load_exchange(exchange)
|
601
607
|
if not result:
|
602
|
-
|
608
|
+
if not self.is_synchronous:
|
609
|
+
await close(exchange)
|
603
610
|
return
|
604
611
|
# if (exchange.id === 'binance') {
|
605
612
|
# # we test proxies functionality just for one random exchange on each build, because proxy functionality is not exchange-specific, instead it's all done from base methods, so just one working sample would mean it works for all ccxt exchanges
|
606
613
|
# # await this.testProxies (exchange);
|
607
614
|
# }
|
608
615
|
await self.test_exchange(exchange, symbol)
|
609
|
-
|
616
|
+
if not self.is_synchronous:
|
617
|
+
await close(exchange)
|
610
618
|
except Exception as e:
|
611
|
-
|
619
|
+
if not self.is_synchronous:
|
620
|
+
await close(exchange)
|
612
621
|
raise e
|
613
622
|
|
614
623
|
def assert_static_error(self, cond, message, calculated_output, stored_output, key=None):
|
@@ -1076,7 +1085,8 @@ class testMainClass(baseMainTestClass):
|
|
1076
1085
|
assert client_order_id_swap.startswith(swap_id_string), 'binance - swap clientOrderId: ' + client_order_id_swap + ' does not start with swapId' + swap_id_string
|
1077
1086
|
client_order_id_inverse = swap_inverse_order_request['newClientOrderId']
|
1078
1087
|
assert client_order_id_inverse.startswith(swap_id_string), 'binance - swap clientOrderIdInverse: ' + client_order_id_inverse + ' does not start with swapId' + swap_id_string
|
1079
|
-
|
1088
|
+
if not self.is_synchronous:
|
1089
|
+
await close(exchange)
|
1080
1090
|
return True
|
1081
1091
|
|
1082
1092
|
async def test_okx(self):
|
@@ -1101,7 +1111,8 @@ class testMainClass(baseMainTestClass):
|
|
1101
1111
|
assert client_order_id_swap.startswith(id_string), 'okx - swap clientOrderId: ' + client_order_id_swap + ' does not start with id: ' + id_string
|
1102
1112
|
swap_tag = swap_order_request[0]['tag']
|
1103
1113
|
assert swap_tag == id, 'okx - id: ' + id + ' different from swap tag: ' + swap_tag
|
1104
|
-
|
1114
|
+
if not self.is_synchronous:
|
1115
|
+
await close(exchange)
|
1105
1116
|
return True
|
1106
1117
|
|
1107
1118
|
async def test_cryptocom(self):
|
@@ -1115,7 +1126,8 @@ class testMainClass(baseMainTestClass):
|
|
1115
1126
|
request = json_parse(exchange.last_request_body)
|
1116
1127
|
broker_id = request['params']['broker_id']
|
1117
1128
|
assert broker_id == id, 'cryptocom - id: ' + id + ' different from broker_id: ' + broker_id
|
1118
|
-
|
1129
|
+
if not self.is_synchronous:
|
1130
|
+
await close(exchange)
|
1119
1131
|
return True
|
1120
1132
|
|
1121
1133
|
async def test_bybit(self):
|
@@ -1129,7 +1141,8 @@ class testMainClass(baseMainTestClass):
|
|
1129
1141
|
# we expect an error here, we're only interested in the headers
|
1130
1142
|
req_headers = exchange.last_request_headers
|
1131
1143
|
assert req_headers['Referer'] == id, 'bybit - id: ' + id + ' not in headers.'
|
1132
|
-
|
1144
|
+
if not self.is_synchronous:
|
1145
|
+
await close(exchange)
|
1133
1146
|
return True
|
1134
1147
|
|
1135
1148
|
async def test_kucoin(self):
|
@@ -1146,7 +1159,8 @@ class testMainClass(baseMainTestClass):
|
|
1146
1159
|
req_headers = exchange.last_request_headers
|
1147
1160
|
id = 'ccxt'
|
1148
1161
|
assert req_headers['KC-API-PARTNER'] == id, 'kucoin - id: ' + id + ' not in headers.'
|
1149
|
-
|
1162
|
+
if not self.is_synchronous:
|
1163
|
+
await close(exchange)
|
1150
1164
|
return True
|
1151
1165
|
|
1152
1166
|
async def test_kucoinfutures(self):
|
@@ -1162,7 +1176,8 @@ class testMainClass(baseMainTestClass):
|
|
1162
1176
|
except Exception as e:
|
1163
1177
|
req_headers = exchange.last_request_headers
|
1164
1178
|
assert req_headers['KC-API-PARTNER'] == id, 'kucoinfutures - id: ' + id + ' not in headers.'
|
1165
|
-
|
1179
|
+
if not self.is_synchronous:
|
1180
|
+
await close(exchange)
|
1166
1181
|
return True
|
1167
1182
|
|
1168
1183
|
async def test_bitget(self):
|
@@ -1175,7 +1190,8 @@ class testMainClass(baseMainTestClass):
|
|
1175
1190
|
except Exception as e:
|
1176
1191
|
req_headers = exchange.last_request_headers
|
1177
1192
|
assert req_headers['X-CHANNEL-API-CODE'] == id, 'bitget - id: ' + id + ' not in headers.'
|
1178
|
-
|
1193
|
+
if not self.is_synchronous:
|
1194
|
+
await close(exchange)
|
1179
1195
|
return True
|
1180
1196
|
|
1181
1197
|
async def test_mexc(self):
|
@@ -1189,7 +1205,8 @@ class testMainClass(baseMainTestClass):
|
|
1189
1205
|
except Exception as e:
|
1190
1206
|
req_headers = exchange.last_request_headers
|
1191
1207
|
assert req_headers['source'] == id, 'mexc - id: ' + id + ' not in headers.'
|
1192
|
-
|
1208
|
+
if not self.is_synchronous:
|
1209
|
+
await close(exchange)
|
1193
1210
|
return True
|
1194
1211
|
|
1195
1212
|
async def test_htx(self):
|
@@ -1219,7 +1236,8 @@ class testMainClass(baseMainTestClass):
|
|
1219
1236
|
assert client_order_id_swap.startswith(id_string), 'htx - swap channel_code ' + client_order_id_swap + ' does not start with id: ' + id_string
|
1220
1237
|
client_order_id_inverse = swap_inverse_order_request['channel_code']
|
1221
1238
|
assert client_order_id_inverse.startswith(id_string), 'htx - swap inverse channel_code ' + client_order_id_inverse + ' does not start with id: ' + id_string
|
1222
|
-
|
1239
|
+
if not self.is_synchronous:
|
1240
|
+
await close(exchange)
|
1223
1241
|
return True
|
1224
1242
|
|
1225
1243
|
async def test_woo(self):
|
@@ -1244,7 +1262,8 @@ class testMainClass(baseMainTestClass):
|
|
1244
1262
|
stop_order_request = json_parse(exchange.last_request_body)
|
1245
1263
|
client_order_id_stop = stop_order_request['brokerId']
|
1246
1264
|
assert client_order_id_stop.startswith(id_string), 'woo - brokerId: ' + client_order_id_stop + ' does not start with id: ' + id_string
|
1247
|
-
|
1265
|
+
if not self.is_synchronous:
|
1266
|
+
await close(exchange)
|
1248
1267
|
return True
|
1249
1268
|
|
1250
1269
|
async def test_bitmart(self):
|
@@ -1258,7 +1277,8 @@ class testMainClass(baseMainTestClass):
|
|
1258
1277
|
except Exception as e:
|
1259
1278
|
req_headers = exchange.last_request_headers
|
1260
1279
|
assert req_headers['X-BM-BROKER-ID'] == id, 'bitmart - id: ' + id + ' not in headers'
|
1261
|
-
|
1280
|
+
if not self.is_synchronous:
|
1281
|
+
await close(exchange)
|
1262
1282
|
return True
|
1263
1283
|
|
1264
1284
|
async def test_coinex(self):
|
@@ -1273,7 +1293,8 @@ class testMainClass(baseMainTestClass):
|
|
1273
1293
|
client_order_id = spot_order_request['client_id']
|
1274
1294
|
id_string = str(id)
|
1275
1295
|
assert client_order_id.startswith(id_string), 'coinex - clientOrderId: ' + client_order_id + ' does not start with id: ' + id_string
|
1276
|
-
|
1296
|
+
if not self.is_synchronous:
|
1297
|
+
await close(exchange)
|
1277
1298
|
return True
|
1278
1299
|
|
1279
1300
|
async def test_bingx(self):
|
@@ -1287,7 +1308,8 @@ class testMainClass(baseMainTestClass):
|
|
1287
1308
|
# we expect an error here, we're only interested in the headers
|
1288
1309
|
req_headers = exchange.last_request_headers
|
1289
1310
|
assert req_headers['X-SOURCE-KEY'] == id, 'bingx - id: ' + id + ' not in headers.'
|
1290
|
-
|
1311
|
+
if not self.is_synchronous:
|
1312
|
+
await close(exchange)
|
1291
1313
|
|
1292
1314
|
async def test_phemex(self):
|
1293
1315
|
exchange = self.init_offline_exchange('phemex')
|
@@ -1300,7 +1322,8 @@ class testMainClass(baseMainTestClass):
|
|
1300
1322
|
client_order_id = request['clOrdID']
|
1301
1323
|
id_string = str(id)
|
1302
1324
|
assert client_order_id.startswith(id_string), 'phemex - clOrdID: ' + client_order_id + ' does not start with id: ' + id_string
|
1303
|
-
|
1325
|
+
if not self.is_synchronous:
|
1326
|
+
await close(exchange)
|
1304
1327
|
|
1305
1328
|
async def test_blofin(self):
|
1306
1329
|
exchange = self.init_offline_exchange('blofin')
|
@@ -1313,7 +1336,8 @@ class testMainClass(baseMainTestClass):
|
|
1313
1336
|
broker_id = request['brokerId']
|
1314
1337
|
id_string = str(id)
|
1315
1338
|
assert broker_id.startswith(id_string), 'blofin - brokerId: ' + broker_id + ' does not start with id: ' + id_string
|
1316
|
-
|
1339
|
+
if not self.is_synchronous:
|
1340
|
+
await close(exchange)
|
1317
1341
|
|
1318
1342
|
async def test_hyperliquid(self):
|
1319
1343
|
exchange = self.init_offline_exchange('hyperliquid')
|
@@ -1325,7 +1349,8 @@ class testMainClass(baseMainTestClass):
|
|
1325
1349
|
request = json_parse(exchange.last_request_body)
|
1326
1350
|
broker_id = str((request['action']['brokerCode']))
|
1327
1351
|
assert broker_id == id, 'hyperliquid - brokerId: ' + broker_id + ' does not start with id: ' + id
|
1328
|
-
|
1352
|
+
if not self.is_synchronous:
|
1353
|
+
await close(exchange)
|
1329
1354
|
|
1330
1355
|
async def test_coinbaseinternational(self):
|
1331
1356
|
exchange = self.init_offline_exchange('coinbaseinternational')
|
@@ -1339,7 +1364,8 @@ class testMainClass(baseMainTestClass):
|
|
1339
1364
|
request = json_parse(exchange.last_request_body)
|
1340
1365
|
client_order_id = request['client_order_id']
|
1341
1366
|
assert client_order_id.startswith(str(id)), 'clientOrderId does not start with id'
|
1342
|
-
|
1367
|
+
if not self.is_synchronous:
|
1368
|
+
await close(exchange)
|
1343
1369
|
return True
|
1344
1370
|
|
1345
1371
|
async def test_coinbase_advanced(self):
|
@@ -1353,7 +1379,8 @@ class testMainClass(baseMainTestClass):
|
|
1353
1379
|
request = json_parse(exchange.last_request_body)
|
1354
1380
|
client_order_id = request['client_order_id']
|
1355
1381
|
assert client_order_id.startswith(str(id)), 'clientOrderId does not start with id'
|
1356
|
-
|
1382
|
+
if not self.is_synchronous:
|
1383
|
+
await close(exchange)
|
1357
1384
|
return True
|
1358
1385
|
|
1359
1386
|
async def test_woofi_pro(self):
|
@@ -1368,7 +1395,8 @@ class testMainClass(baseMainTestClass):
|
|
1368
1395
|
request = json_parse(exchange.last_request_body)
|
1369
1396
|
broker_id = request['order_tag']
|
1370
1397
|
assert broker_id == id, 'woofipro - id: ' + id + ' different from broker_id: ' + broker_id
|
1371
|
-
|
1398
|
+
if not self.is_synchronous:
|
1399
|
+
await close(exchange)
|
1372
1400
|
return True
|
1373
1401
|
|
1374
1402
|
async def test_oxfun(self):
|
@@ -1404,7 +1432,8 @@ class testMainClass(baseMainTestClass):
|
|
1404
1432
|
swap_order_request = json_parse(exchange.last_request_body)
|
1405
1433
|
swap_media = swap_order_request['clientMedia']
|
1406
1434
|
assert swap_media == id, 'xt - id: ' + id + ' different from swap tag: ' + swap_media
|
1407
|
-
|
1435
|
+
if not self.is_synchronous:
|
1436
|
+
await close(exchange)
|
1408
1437
|
return True
|
1409
1438
|
|
1410
1439
|
async def test_vertex(self):
|
@@ -1426,5 +1455,6 @@ class testMainClass(baseMainTestClass):
|
|
1426
1455
|
order = request['place_order']
|
1427
1456
|
broker_id = order['id']
|
1428
1457
|
assert broker_id == id, 'vertex - id: ' + str(id) + ' different from broker_id: ' + str(broker_id)
|
1429
|
-
|
1458
|
+
if not self.is_synchronous:
|
1459
|
+
await close(exchange)
|
1430
1460
|
return True
|
ccxt/test/tests_helpers.py
CHANGED
@@ -191,6 +191,10 @@ def io_dir_read(path):
|
|
191
191
|
return os.listdir(path)
|
192
192
|
|
193
193
|
|
194
|
+
def call_method_sync(test_files, methodName, exchange, skippedProperties, args):
|
195
|
+
methodNameToCall = 'test_' + convert_to_snake_case(methodName)
|
196
|
+
return getattr(test_files[methodName], methodNameToCall)(exchange, skippedProperties, *args)
|
197
|
+
|
194
198
|
async def call_method(test_files, methodName, exchange, skippedProperties, args):
|
195
199
|
methodNameToCall = 'test_' + convert_to_snake_case(methodName)
|
196
200
|
return await getattr(test_files[methodName], methodNameToCall)(exchange, skippedProperties, *args)
|
@@ -240,7 +244,7 @@ def init_exchange(exchangeId, args, is_ws=False):
|
|
240
244
|
return getattr(ccxt, exchangeId)(args)
|
241
245
|
|
242
246
|
|
243
|
-
|
247
|
+
def get_test_files_sync(properties, ws=False):
|
244
248
|
tests = {}
|
245
249
|
finalPropList = properties + [proxyTestFileName]
|
246
250
|
for i in range(0, len(finalPropList)):
|
@@ -259,6 +263,9 @@ async def get_test_files(properties, ws=False):
|
|
259
263
|
tests[methodName] = imp # getattr(imp, finalName)
|
260
264
|
return tests
|
261
265
|
|
266
|
+
async def get_test_files(properties, ws=False):
|
267
|
+
return get_test_files_sync(properties, ws)
|
268
|
+
|
262
269
|
async def close(exchange):
|
263
270
|
if (not is_synchronous and hasattr(exchange, 'close')):
|
264
271
|
await exchange.close()
|
ccxt/test/tests_sync.py
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# -*- coding: utf-8 -*-
|
2
2
|
|
3
|
-
from tests_helpers import
|
3
|
+
from tests_helpers import AuthenticationError, NotSupported, InvalidProxySettings, ExchangeNotAvailable, OperationFailed, OnMaintenance, get_cli_arg_value, baseMainTestClass, dump, json_parse, json_stringify, convert_ascii, io_file_exists, io_file_read, io_dir_read, call_method, call_method_sync, call_exchange_method_dynamically, call_exchange_method_dynamically_sync, exception_message, exit_script, get_exchange_prop, set_exchange_prop, init_exchange, get_test_files_sync, get_test_files, set_fetch_response, is_null_value, close # noqa: F401
|
4
4
|
|
5
5
|
class testMainClass(baseMainTestClass):
|
6
6
|
def parse_cli_args(self):
|
@@ -69,7 +69,10 @@ class testMainClass(baseMainTestClass):
|
|
69
69
|
def import_files(self, exchange):
|
70
70
|
properties = list(exchange.has.keys())
|
71
71
|
properties.append('loadMarkets')
|
72
|
-
|
72
|
+
if self.is_synchronous:
|
73
|
+
self.test_files = get_test_files_sync(properties, self.ws_tests)
|
74
|
+
else:
|
75
|
+
self.test_files = get_test_files(properties, self.ws_tests)
|
73
76
|
|
74
77
|
def load_credentials_from_env(self, exchange):
|
75
78
|
exchange_id = exchange.id
|
@@ -189,7 +192,10 @@ class testMainClass(baseMainTestClass):
|
|
189
192
|
if self.info:
|
190
193
|
args_stringified = '(' + exchange.json(args) + ')' # args.join() breaks when we provide a list of symbols or multidimensional array; "args.toString()" breaks bcz of "array to string conversion"
|
191
194
|
dump(self.add_padding('[INFO] TESTING', 25), self.exchange_hint(exchange), method_name, args_stringified)
|
192
|
-
|
195
|
+
if self.is_synchronous:
|
196
|
+
call_method_sync(self.test_files, method_name, exchange, skipped_properties_for_method, args)
|
197
|
+
else:
|
198
|
+
call_method(self.test_files, method_name, exchange, skipped_properties_for_method, args)
|
193
199
|
if self.info:
|
194
200
|
dump(self.add_padding('[INFO] TESTING DONE', 25), self.exchange_hint(exchange), method_name)
|
195
201
|
# add to the list of successed tests
|
@@ -584,7 +590,7 @@ class testMainClass(baseMainTestClass):
|
|
584
590
|
if exception is not None:
|
585
591
|
error_message = '[TEST_FAILURE] Failed ' + proxy_test_name + ' : ' + exception_message(exception)
|
586
592
|
# temporary comment the below, because c# transpilation failure
|
587
|
-
# throw new
|
593
|
+
# throw new Exchange Error (errorMessage.toString ());
|
588
594
|
dump('[TEST_WARNING]' + str(error_message))
|
589
595
|
|
590
596
|
def start_test(self, exchange, symbol):
|
@@ -596,16 +602,19 @@ class testMainClass(baseMainTestClass):
|
|
596
602
|
try:
|
597
603
|
result = self.load_exchange(exchange)
|
598
604
|
if not result:
|
599
|
-
|
605
|
+
if not self.is_synchronous:
|
606
|
+
close(exchange)
|
600
607
|
return
|
601
608
|
# if (exchange.id === 'binance') {
|
602
609
|
# # we test proxies functionality just for one random exchange on each build, because proxy functionality is not exchange-specific, instead it's all done from base methods, so just one working sample would mean it works for all ccxt exchanges
|
603
610
|
# # this.testProxies (exchange);
|
604
611
|
# }
|
605
612
|
self.test_exchange(exchange, symbol)
|
606
|
-
|
613
|
+
if not self.is_synchronous:
|
614
|
+
close(exchange)
|
607
615
|
except Exception as e:
|
608
|
-
|
616
|
+
if not self.is_synchronous:
|
617
|
+
close(exchange)
|
609
618
|
raise e
|
610
619
|
|
611
620
|
def assert_static_error(self, cond, message, calculated_output, stored_output, key=None):
|
@@ -1073,7 +1082,8 @@ class testMainClass(baseMainTestClass):
|
|
1073
1082
|
assert client_order_id_swap.startswith(swap_id_string), 'binance - swap clientOrderId: ' + client_order_id_swap + ' does not start with swapId' + swap_id_string
|
1074
1083
|
client_order_id_inverse = swap_inverse_order_request['newClientOrderId']
|
1075
1084
|
assert client_order_id_inverse.startswith(swap_id_string), 'binance - swap clientOrderIdInverse: ' + client_order_id_inverse + ' does not start with swapId' + swap_id_string
|
1076
|
-
|
1085
|
+
if not self.is_synchronous:
|
1086
|
+
close(exchange)
|
1077
1087
|
return True
|
1078
1088
|
|
1079
1089
|
def test_okx(self):
|
@@ -1098,7 +1108,8 @@ class testMainClass(baseMainTestClass):
|
|
1098
1108
|
assert client_order_id_swap.startswith(id_string), 'okx - swap clientOrderId: ' + client_order_id_swap + ' does not start with id: ' + id_string
|
1099
1109
|
swap_tag = swap_order_request[0]['tag']
|
1100
1110
|
assert swap_tag == id, 'okx - id: ' + id + ' different from swap tag: ' + swap_tag
|
1101
|
-
|
1111
|
+
if not self.is_synchronous:
|
1112
|
+
close(exchange)
|
1102
1113
|
return True
|
1103
1114
|
|
1104
1115
|
def test_cryptocom(self):
|
@@ -1112,7 +1123,8 @@ class testMainClass(baseMainTestClass):
|
|
1112
1123
|
request = json_parse(exchange.last_request_body)
|
1113
1124
|
broker_id = request['params']['broker_id']
|
1114
1125
|
assert broker_id == id, 'cryptocom - id: ' + id + ' different from broker_id: ' + broker_id
|
1115
|
-
|
1126
|
+
if not self.is_synchronous:
|
1127
|
+
close(exchange)
|
1116
1128
|
return True
|
1117
1129
|
|
1118
1130
|
def test_bybit(self):
|
@@ -1126,7 +1138,8 @@ class testMainClass(baseMainTestClass):
|
|
1126
1138
|
# we expect an error here, we're only interested in the headers
|
1127
1139
|
req_headers = exchange.last_request_headers
|
1128
1140
|
assert req_headers['Referer'] == id, 'bybit - id: ' + id + ' not in headers.'
|
1129
|
-
|
1141
|
+
if not self.is_synchronous:
|
1142
|
+
close(exchange)
|
1130
1143
|
return True
|
1131
1144
|
|
1132
1145
|
def test_kucoin(self):
|
@@ -1143,7 +1156,8 @@ class testMainClass(baseMainTestClass):
|
|
1143
1156
|
req_headers = exchange.last_request_headers
|
1144
1157
|
id = 'ccxt'
|
1145
1158
|
assert req_headers['KC-API-PARTNER'] == id, 'kucoin - id: ' + id + ' not in headers.'
|
1146
|
-
|
1159
|
+
if not self.is_synchronous:
|
1160
|
+
close(exchange)
|
1147
1161
|
return True
|
1148
1162
|
|
1149
1163
|
def test_kucoinfutures(self):
|
@@ -1159,7 +1173,8 @@ class testMainClass(baseMainTestClass):
|
|
1159
1173
|
except Exception as e:
|
1160
1174
|
req_headers = exchange.last_request_headers
|
1161
1175
|
assert req_headers['KC-API-PARTNER'] == id, 'kucoinfutures - id: ' + id + ' not in headers.'
|
1162
|
-
|
1176
|
+
if not self.is_synchronous:
|
1177
|
+
close(exchange)
|
1163
1178
|
return True
|
1164
1179
|
|
1165
1180
|
def test_bitget(self):
|
@@ -1172,7 +1187,8 @@ class testMainClass(baseMainTestClass):
|
|
1172
1187
|
except Exception as e:
|
1173
1188
|
req_headers = exchange.last_request_headers
|
1174
1189
|
assert req_headers['X-CHANNEL-API-CODE'] == id, 'bitget - id: ' + id + ' not in headers.'
|
1175
|
-
|
1190
|
+
if not self.is_synchronous:
|
1191
|
+
close(exchange)
|
1176
1192
|
return True
|
1177
1193
|
|
1178
1194
|
def test_mexc(self):
|
@@ -1186,7 +1202,8 @@ class testMainClass(baseMainTestClass):
|
|
1186
1202
|
except Exception as e:
|
1187
1203
|
req_headers = exchange.last_request_headers
|
1188
1204
|
assert req_headers['source'] == id, 'mexc - id: ' + id + ' not in headers.'
|
1189
|
-
|
1205
|
+
if not self.is_synchronous:
|
1206
|
+
close(exchange)
|
1190
1207
|
return True
|
1191
1208
|
|
1192
1209
|
def test_htx(self):
|
@@ -1216,7 +1233,8 @@ class testMainClass(baseMainTestClass):
|
|
1216
1233
|
assert client_order_id_swap.startswith(id_string), 'htx - swap channel_code ' + client_order_id_swap + ' does not start with id: ' + id_string
|
1217
1234
|
client_order_id_inverse = swap_inverse_order_request['channel_code']
|
1218
1235
|
assert client_order_id_inverse.startswith(id_string), 'htx - swap inverse channel_code ' + client_order_id_inverse + ' does not start with id: ' + id_string
|
1219
|
-
|
1236
|
+
if not self.is_synchronous:
|
1237
|
+
close(exchange)
|
1220
1238
|
return True
|
1221
1239
|
|
1222
1240
|
def test_woo(self):
|
@@ -1241,7 +1259,8 @@ class testMainClass(baseMainTestClass):
|
|
1241
1259
|
stop_order_request = json_parse(exchange.last_request_body)
|
1242
1260
|
client_order_id_stop = stop_order_request['brokerId']
|
1243
1261
|
assert client_order_id_stop.startswith(id_string), 'woo - brokerId: ' + client_order_id_stop + ' does not start with id: ' + id_string
|
1244
|
-
|
1262
|
+
if not self.is_synchronous:
|
1263
|
+
close(exchange)
|
1245
1264
|
return True
|
1246
1265
|
|
1247
1266
|
def test_bitmart(self):
|
@@ -1255,7 +1274,8 @@ class testMainClass(baseMainTestClass):
|
|
1255
1274
|
except Exception as e:
|
1256
1275
|
req_headers = exchange.last_request_headers
|
1257
1276
|
assert req_headers['X-BM-BROKER-ID'] == id, 'bitmart - id: ' + id + ' not in headers'
|
1258
|
-
|
1277
|
+
if not self.is_synchronous:
|
1278
|
+
close(exchange)
|
1259
1279
|
return True
|
1260
1280
|
|
1261
1281
|
def test_coinex(self):
|
@@ -1270,7 +1290,8 @@ class testMainClass(baseMainTestClass):
|
|
1270
1290
|
client_order_id = spot_order_request['client_id']
|
1271
1291
|
id_string = str(id)
|
1272
1292
|
assert client_order_id.startswith(id_string), 'coinex - clientOrderId: ' + client_order_id + ' does not start with id: ' + id_string
|
1273
|
-
|
1293
|
+
if not self.is_synchronous:
|
1294
|
+
close(exchange)
|
1274
1295
|
return True
|
1275
1296
|
|
1276
1297
|
def test_bingx(self):
|
@@ -1284,7 +1305,8 @@ class testMainClass(baseMainTestClass):
|
|
1284
1305
|
# we expect an error here, we're only interested in the headers
|
1285
1306
|
req_headers = exchange.last_request_headers
|
1286
1307
|
assert req_headers['X-SOURCE-KEY'] == id, 'bingx - id: ' + id + ' not in headers.'
|
1287
|
-
|
1308
|
+
if not self.is_synchronous:
|
1309
|
+
close(exchange)
|
1288
1310
|
|
1289
1311
|
def test_phemex(self):
|
1290
1312
|
exchange = self.init_offline_exchange('phemex')
|
@@ -1297,7 +1319,8 @@ class testMainClass(baseMainTestClass):
|
|
1297
1319
|
client_order_id = request['clOrdID']
|
1298
1320
|
id_string = str(id)
|
1299
1321
|
assert client_order_id.startswith(id_string), 'phemex - clOrdID: ' + client_order_id + ' does not start with id: ' + id_string
|
1300
|
-
|
1322
|
+
if not self.is_synchronous:
|
1323
|
+
close(exchange)
|
1301
1324
|
|
1302
1325
|
def test_blofin(self):
|
1303
1326
|
exchange = self.init_offline_exchange('blofin')
|
@@ -1310,7 +1333,8 @@ class testMainClass(baseMainTestClass):
|
|
1310
1333
|
broker_id = request['brokerId']
|
1311
1334
|
id_string = str(id)
|
1312
1335
|
assert broker_id.startswith(id_string), 'blofin - brokerId: ' + broker_id + ' does not start with id: ' + id_string
|
1313
|
-
|
1336
|
+
if not self.is_synchronous:
|
1337
|
+
close(exchange)
|
1314
1338
|
|
1315
1339
|
def test_hyperliquid(self):
|
1316
1340
|
exchange = self.init_offline_exchange('hyperliquid')
|
@@ -1322,7 +1346,8 @@ class testMainClass(baseMainTestClass):
|
|
1322
1346
|
request = json_parse(exchange.last_request_body)
|
1323
1347
|
broker_id = str((request['action']['brokerCode']))
|
1324
1348
|
assert broker_id == id, 'hyperliquid - brokerId: ' + broker_id + ' does not start with id: ' + id
|
1325
|
-
|
1349
|
+
if not self.is_synchronous:
|
1350
|
+
close(exchange)
|
1326
1351
|
|
1327
1352
|
def test_coinbaseinternational(self):
|
1328
1353
|
exchange = self.init_offline_exchange('coinbaseinternational')
|
@@ -1336,7 +1361,8 @@ class testMainClass(baseMainTestClass):
|
|
1336
1361
|
request = json_parse(exchange.last_request_body)
|
1337
1362
|
client_order_id = request['client_order_id']
|
1338
1363
|
assert client_order_id.startswith(str(id)), 'clientOrderId does not start with id'
|
1339
|
-
|
1364
|
+
if not self.is_synchronous:
|
1365
|
+
close(exchange)
|
1340
1366
|
return True
|
1341
1367
|
|
1342
1368
|
def test_coinbase_advanced(self):
|
@@ -1350,7 +1376,8 @@ class testMainClass(baseMainTestClass):
|
|
1350
1376
|
request = json_parse(exchange.last_request_body)
|
1351
1377
|
client_order_id = request['client_order_id']
|
1352
1378
|
assert client_order_id.startswith(str(id)), 'clientOrderId does not start with id'
|
1353
|
-
|
1379
|
+
if not self.is_synchronous:
|
1380
|
+
close(exchange)
|
1354
1381
|
return True
|
1355
1382
|
|
1356
1383
|
def test_woofi_pro(self):
|
@@ -1365,7 +1392,8 @@ class testMainClass(baseMainTestClass):
|
|
1365
1392
|
request = json_parse(exchange.last_request_body)
|
1366
1393
|
broker_id = request['order_tag']
|
1367
1394
|
assert broker_id == id, 'woofipro - id: ' + id + ' different from broker_id: ' + broker_id
|
1368
|
-
|
1395
|
+
if not self.is_synchronous:
|
1396
|
+
close(exchange)
|
1369
1397
|
return True
|
1370
1398
|
|
1371
1399
|
def test_oxfun(self):
|
@@ -1401,7 +1429,8 @@ class testMainClass(baseMainTestClass):
|
|
1401
1429
|
swap_order_request = json_parse(exchange.last_request_body)
|
1402
1430
|
swap_media = swap_order_request['clientMedia']
|
1403
1431
|
assert swap_media == id, 'xt - id: ' + id + ' different from swap tag: ' + swap_media
|
1404
|
-
|
1432
|
+
if not self.is_synchronous:
|
1433
|
+
close(exchange)
|
1405
1434
|
return True
|
1406
1435
|
|
1407
1436
|
def test_vertex(self):
|
@@ -1423,5 +1452,6 @@ class testMainClass(baseMainTestClass):
|
|
1423
1452
|
order = request['place_order']
|
1424
1453
|
broker_id = order['id']
|
1425
1454
|
assert broker_id == id, 'vertex - id: ' + str(id) + ' different from broker_id: ' + str(broker_id)
|
1426
|
-
|
1455
|
+
if not self.is_synchronous:
|
1456
|
+
close(exchange)
|
1427
1457
|
return True
|
ccxt/whitebit.py
CHANGED
@@ -2404,7 +2404,7 @@ class whitebit(Exchange, ImplicitAPI):
|
|
2404
2404
|
records = self.safe_list(response, 'records')
|
2405
2405
|
return self.parse_transactions(records, currency, since, limit)
|
2406
2406
|
|
2407
|
-
def is_fiat(self, currency: str):
|
2407
|
+
def is_fiat(self, currency: str) -> bool:
|
2408
2408
|
fiatCurrencies = self.safe_value(self.options, 'fiatCurrencies', [])
|
2409
2409
|
return self.in_array(currency, fiatCurrencies)
|
2410
2410
|
|
ccxt/zonda.py
CHANGED
@@ -1467,7 +1467,7 @@ class zonda(Exchange, ImplicitAPI):
|
|
1467
1467
|
# {status: "Ok", errors: []}
|
1468
1468
|
return self.parse_order(response)
|
1469
1469
|
|
1470
|
-
def is_fiat(self, currency: str):
|
1470
|
+
def is_fiat(self, currency: str) -> bool:
|
1471
1471
|
fiatCurrencies: dict = {
|
1472
1472
|
'USD': True,
|
1473
1473
|
'EUR': True,
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: ccxt
|
3
|
-
Version: 4.3.
|
3
|
+
Version: 4.3.67
|
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
|
@@ -269,13 +269,13 @@ console.log(version, Object.keys(exchanges));
|
|
269
269
|
|
270
270
|
All-in-one browser bundle (dependencies included), served from a CDN of your choice:
|
271
271
|
|
272
|
-
* jsDelivr: https://cdn.jsdelivr.net/npm/ccxt@4.3.
|
273
|
-
* unpkg: https://unpkg.com/ccxt@4.3.
|
272
|
+
* jsDelivr: https://cdn.jsdelivr.net/npm/ccxt@4.3.67/dist/ccxt.browser.min.js
|
273
|
+
* unpkg: https://unpkg.com/ccxt@4.3.67/dist/ccxt.browser.min.js
|
274
274
|
|
275
275
|
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.
|
276
276
|
|
277
277
|
```HTML
|
278
|
-
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/ccxt@4.3.
|
278
|
+
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/ccxt@4.3.67/dist/ccxt.browser.min.js"></script>
|
279
279
|
```
|
280
280
|
|
281
281
|
Creates a global `ccxt` object:
|