ccxt 4.4.13__py2.py3-none-any.whl → 4.4.15__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/binance.py +1 -0
- ccxt/abstract/binancecoinm.py +1 -0
- ccxt/abstract/binanceus.py +1 -0
- ccxt/abstract/binanceusdm.py +1 -0
- ccxt/abstract/cryptocom.py +1 -0
- ccxt/async_support/__init__.py +1 -1
- ccxt/async_support/base/exchange.py +34 -1
- ccxt/async_support/binance.py +69 -11
- ccxt/async_support/bitget.py +101 -3
- ccxt/async_support/bitrue.py +1 -7
- ccxt/async_support/bitvavo.py +1 -3
- ccxt/async_support/coinex.py +13 -1
- ccxt/async_support/cryptocom.py +1 -0
- ccxt/async_support/digifinex.py +13 -1
- ccxt/async_support/htx.py +1 -1
- ccxt/async_support/huobijp.py +1 -3
- ccxt/async_support/kucoin.py +36 -1
- ccxt/async_support/kucoinfutures.py +55 -4
- ccxt/async_support/mexc.py +52 -8
- ccxt/async_support/okx.py +12 -0
- ccxt/async_support/onetrading.py +2 -2
- ccxt/async_support/poloniexfutures.py +35 -11
- ccxt/async_support/vertex.py +8 -0
- ccxt/async_support/woo.py +12 -0
- ccxt/async_support/woofipro.py +12 -0
- ccxt/async_support/xt.py +12 -0
- ccxt/base/exchange.py +38 -2
- ccxt/binance.py +69 -11
- ccxt/bitget.py +101 -3
- ccxt/bitrue.py +1 -7
- ccxt/bitvavo.py +1 -3
- ccxt/coinex.py +13 -1
- ccxt/cryptocom.py +1 -0
- ccxt/digifinex.py +13 -1
- ccxt/htx.py +1 -1
- ccxt/huobijp.py +1 -3
- ccxt/kucoin.py +36 -1
- ccxt/kucoinfutures.py +55 -4
- ccxt/mexc.py +52 -8
- ccxt/okx.py +12 -0
- ccxt/onetrading.py +2 -2
- ccxt/poloniexfutures.py +35 -11
- ccxt/pro/__init__.py +1 -1
- ccxt/pro/binance.py +1 -1
- ccxt/pro/okx.py +38 -0
- ccxt/pro/upbit.py +42 -1
- ccxt/pro/vertex.py +11 -0
- ccxt/test/tests_async.py +53 -53
- ccxt/test/tests_helpers.py +14 -0
- ccxt/test/tests_sync.py +53 -53
- ccxt/vertex.py +8 -0
- ccxt/woo.py +12 -0
- ccxt/woofipro.py +12 -0
- ccxt/xt.py +12 -0
- {ccxt-4.4.13.dist-info → ccxt-4.4.15.dist-info}/METADATA +4 -4
- {ccxt-4.4.13.dist-info → ccxt-4.4.15.dist-info}/RECORD +60 -60
- {ccxt-4.4.13.dist-info → ccxt-4.4.15.dist-info}/LICENSE.txt +0 -0
- {ccxt-4.4.13.dist-info → ccxt-4.4.15.dist-info}/WHEEL +0 -0
- {ccxt-4.4.13.dist-info → ccxt-4.4.15.dist-info}/top_level.txt +0 -0
ccxt/test/tests_helpers.py
CHANGED
@@ -264,6 +264,20 @@ def set_fetch_response(exchange: ccxt.Exchange, data):
|
|
264
264
|
exchange.fetch = fetch
|
265
265
|
return exchange
|
266
266
|
|
267
|
+
def get_lang():
|
268
|
+
return LANG
|
269
|
+
|
270
|
+
def get_ext():
|
271
|
+
return EXT
|
272
|
+
|
273
|
+
def get_root_dir():
|
274
|
+
return ROOT_DIR
|
275
|
+
|
276
|
+
def get_env_vars():
|
277
|
+
return ENV_VARS
|
278
|
+
|
279
|
+
def is_sync():
|
280
|
+
return IS_SYNCHRONOUS
|
267
281
|
|
268
282
|
argvExchange = argv.exchange
|
269
283
|
argvSymbol = argv.symbol if argv.symbol and '/' in argv.symbol else None
|
ccxt/test/tests_sync.py
CHANGED
@@ -1,9 +1,8 @@
|
|
1
1
|
# -*- coding: utf-8 -*-
|
2
2
|
|
3
|
-
from tests_helpers import AuthenticationError, NotSupported, InvalidProxySettings, ExchangeNotAvailable, OperationFailed, OnMaintenance, get_cli_arg_value,
|
3
|
+
from tests_helpers import AuthenticationError, NotSupported, InvalidProxySettings, ExchangeNotAvailable, OperationFailed, OnMaintenance, get_cli_arg_value, get_root_dir, is_sync, 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, get_root_exception, 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, get_env_vars, get_lang, get_ext # noqa: F401
|
4
4
|
|
5
5
|
class testMainClass:
|
6
|
-
is_synchronous = IS_SYNCHRONOUS
|
7
6
|
id_tests = False
|
8
7
|
request_tests_failed = False
|
9
8
|
response_tests_failed = False
|
@@ -18,20 +17,17 @@ class testMainClass:
|
|
18
17
|
private_test_only = False
|
19
18
|
load_keys = False
|
20
19
|
sandbox = False
|
21
|
-
proxy_test_file_name = PROXY_TEST_FILE_NAME
|
22
20
|
only_specific_tests = []
|
23
21
|
skipped_settings_for_exchange = {}
|
24
22
|
skipped_methods = {}
|
25
23
|
checked_public_tests = {}
|
26
24
|
test_files = {}
|
27
25
|
public_tests = {}
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
ext = EXT
|
32
|
-
lang = LANG
|
26
|
+
ext = ''
|
27
|
+
lang = ''
|
28
|
+
proxy_test_file_name = 'proxies'
|
33
29
|
|
34
|
-
def
|
30
|
+
def parse_cli_args_and_props(self):
|
35
31
|
self.response_tests = get_cli_arg_value('--responseTests')
|
36
32
|
self.id_tests = get_cli_arg_value('--idTests')
|
37
33
|
self.request_tests = get_cli_arg_value('--requestTests')
|
@@ -43,9 +39,11 @@ class testMainClass:
|
|
43
39
|
self.sandbox = get_cli_arg_value('--sandbox')
|
44
40
|
self.load_keys = get_cli_arg_value('--loadKeys')
|
45
41
|
self.ws_tests = get_cli_arg_value('--ws')
|
42
|
+
self.lang = get_lang()
|
43
|
+
self.ext = get_ext()
|
46
44
|
|
47
45
|
def init(self, exchange_id, symbol_argv, method_argv):
|
48
|
-
self.
|
46
|
+
self.parse_cli_args_and_props()
|
49
47
|
if self.request_tests and self.response_tests:
|
50
48
|
self.run_static_request_tests(exchange_id, symbol_argv)
|
51
49
|
self.run_static_response_tests(exchange_id, symbol_argv)
|
@@ -59,12 +57,13 @@ class testMainClass:
|
|
59
57
|
if self.id_tests:
|
60
58
|
self.run_broker_id_tests()
|
61
59
|
return
|
62
|
-
|
60
|
+
new_line = '\n'
|
61
|
+
dump(new_line + '' + new_line + '' + '[INFO] TESTING ', self.ext, {
|
63
62
|
'exchange': exchange_id,
|
64
63
|
'symbol': symbol_argv,
|
65
64
|
'method': method_argv,
|
66
65
|
'isWs': self.ws_tests,
|
67
|
-
},
|
66
|
+
}, new_line)
|
68
67
|
exchange_args = {
|
69
68
|
'verbose': self.verbose,
|
70
69
|
'debug': self.debug,
|
@@ -97,7 +96,7 @@ class testMainClass:
|
|
97
96
|
def import_files(self, exchange):
|
98
97
|
properties = list(exchange.has.keys())
|
99
98
|
properties.append('loadMarkets')
|
100
|
-
if
|
99
|
+
if is_sync():
|
101
100
|
self.test_files = get_test_files_sync(properties, self.ws_tests)
|
102
101
|
else:
|
103
102
|
self.test_files = get_test_files(properties, self.ws_tests)
|
@@ -112,14 +111,15 @@ class testMainClass:
|
|
112
111
|
if is_required and get_exchange_prop(exchange, credential) is None:
|
113
112
|
full_key = exchange_id + '_' + credential
|
114
113
|
credential_env_name = full_key.upper() # example: KRAKEN_APIKEY
|
115
|
-
|
114
|
+
env_vars = get_env_vars()
|
115
|
+
credential_value = env_vars[credential_env_name] if (credential_env_name in env_vars) else None
|
116
116
|
if credential_value:
|
117
117
|
set_exchange_prop(exchange, credential, credential_value)
|
118
118
|
|
119
119
|
def expand_settings(self, exchange):
|
120
120
|
exchange_id = exchange.id
|
121
|
-
keys_global =
|
122
|
-
keys_local =
|
121
|
+
keys_global = get_root_dir() + 'keys.json'
|
122
|
+
keys_local = get_root_dir() + 'keys.local.json'
|
123
123
|
keys_global_exists = io_file_exists(keys_global)
|
124
124
|
keys_local_exists = io_file_exists(keys_local)
|
125
125
|
global_settings = io_file_read(keys_global) if keys_global_exists else {}
|
@@ -142,7 +142,7 @@ class testMainClass:
|
|
142
142
|
if self.load_keys:
|
143
143
|
self.load_credentials_from_env(exchange)
|
144
144
|
# skipped tests
|
145
|
-
skipped_file =
|
145
|
+
skipped_file = get_root_dir() + 'skip-tests.json'
|
146
146
|
skipped_settings = io_file_read(skipped_file)
|
147
147
|
self.skipped_settings_for_exchange = exchange.safe_value(skipped_settings, exchange_id, {})
|
148
148
|
skipped_settings_for_exchange = self.skipped_settings_for_exchange
|
@@ -203,7 +203,7 @@ class testMainClass:
|
|
203
203
|
if self.info:
|
204
204
|
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"
|
205
205
|
dump(self.add_padding('[INFO] TESTING', 25), name, method_name, args_stringified)
|
206
|
-
if
|
206
|
+
if is_sync():
|
207
207
|
call_method_sync(self.test_files, method_name, exchange, skipped_properties_for_method, args)
|
208
208
|
else:
|
209
209
|
call_method(self.test_files, method_name, exchange, skipped_properties_for_method, args)
|
@@ -586,7 +586,7 @@ class testMainClass:
|
|
586
586
|
# these tests should be synchronously executed, because of conflicting nature of proxy settings
|
587
587
|
proxy_test_name = self.proxy_test_file_name
|
588
588
|
# todo: temporary skip for sync py
|
589
|
-
if self.ext == 'py' and
|
589
|
+
if self.ext == 'py' and is_sync():
|
590
590
|
return
|
591
591
|
# try proxy several times
|
592
592
|
max_retries = 3
|
@@ -614,7 +614,7 @@ class testMainClass:
|
|
614
614
|
try:
|
615
615
|
result = self.load_exchange(exchange)
|
616
616
|
if not result:
|
617
|
-
if not
|
617
|
+
if not is_sync():
|
618
618
|
close(exchange)
|
619
619
|
return
|
620
620
|
# if (exchange.id === 'binance') {
|
@@ -622,10 +622,10 @@ class testMainClass:
|
|
622
622
|
# # this.testProxies (exchange);
|
623
623
|
# }
|
624
624
|
self.test_exchange(exchange, symbol)
|
625
|
-
if not
|
625
|
+
if not is_sync():
|
626
626
|
close(exchange)
|
627
627
|
except Exception as e:
|
628
|
-
if not
|
628
|
+
if not is_sync():
|
629
629
|
close(exchange)
|
630
630
|
raise e
|
631
631
|
|
@@ -645,12 +645,12 @@ class testMainClass:
|
|
645
645
|
# to make this test as fast as possible
|
646
646
|
# and basically independent from the exchange
|
647
647
|
# so we can run it offline
|
648
|
-
filename =
|
648
|
+
filename = get_root_dir() + './ts/src/test/static/markets/' + id + '.json'
|
649
649
|
content = io_file_read(filename)
|
650
650
|
return content
|
651
651
|
|
652
652
|
def load_currencies_from_file(self, id):
|
653
|
-
filename =
|
653
|
+
filename = get_root_dir() + './ts/src/test/static/currencies/' + id + '.json'
|
654
654
|
content = io_file_read(filename)
|
655
655
|
return content
|
656
656
|
|
@@ -840,7 +840,7 @@ class testMainClass:
|
|
840
840
|
output = None
|
841
841
|
request_url = None
|
842
842
|
try:
|
843
|
-
if not
|
843
|
+
if not is_sync():
|
844
844
|
call_exchange_method_dynamically(exchange, method, self.sanitize_data_input(data['input']))
|
845
845
|
else:
|
846
846
|
call_exchange_method_dynamically_sync(exchange, method, self.sanitize_data_input(data['input']))
|
@@ -861,7 +861,7 @@ class testMainClass:
|
|
861
861
|
expected_result = exchange.safe_value(data, 'parsedResponse')
|
862
862
|
mocked_exchange = set_fetch_response(exchange, data['httpResponse'])
|
863
863
|
try:
|
864
|
-
if not
|
864
|
+
if not is_sync():
|
865
865
|
unified_result = call_exchange_method_dynamically(exchange, method, self.sanitize_data_input(data['input']))
|
866
866
|
self.assert_static_response_output(mocked_exchange, skip_keys, unified_result, expected_result)
|
867
867
|
else:
|
@@ -957,7 +957,7 @@ class testMainClass:
|
|
957
957
|
# reset options
|
958
958
|
# exchange.options = exchange.deepExtend (oldExchangeOptions, {});
|
959
959
|
exchange.extend_exchange_options(exchange.deep_extend(old_exchange_options, {}))
|
960
|
-
if not
|
960
|
+
if not is_sync():
|
961
961
|
close(exchange)
|
962
962
|
return True # in c# methods that will be used with promiseAll need to return something
|
963
963
|
|
@@ -1007,7 +1007,7 @@ class testMainClass:
|
|
1007
1007
|
# reset options
|
1008
1008
|
# exchange.options = exchange.deepExtend (oldExchangeOptions, {});
|
1009
1009
|
exchange.extend_exchange_options(exchange.deep_extend(old_exchange_options, {}))
|
1010
|
-
if not
|
1010
|
+
if not is_sync():
|
1011
1011
|
close(exchange)
|
1012
1012
|
return True # in c# methods that will be used with promiseAll need to return something
|
1013
1013
|
|
@@ -1028,7 +1028,7 @@ class testMainClass:
|
|
1028
1028
|
self.run_static_tests('request', target_exchange, test_name)
|
1029
1029
|
|
1030
1030
|
def run_static_tests(self, type, target_exchange=None, test_name=None):
|
1031
|
-
folder =
|
1031
|
+
folder = get_root_dir() + './ts/src/test/static/' + type + '/'
|
1032
1032
|
static_data = self.load_static_data(folder, target_exchange)
|
1033
1033
|
if static_data is None:
|
1034
1034
|
return
|
@@ -1053,7 +1053,7 @@ class testMainClass:
|
|
1053
1053
|
if self.request_tests_failed or self.response_tests_failed:
|
1054
1054
|
exit_script(1)
|
1055
1055
|
else:
|
1056
|
-
prefix = '[SYNC]' if (
|
1056
|
+
prefix = '[SYNC]' if (is_sync()) else ''
|
1057
1057
|
success_message = '[' + self.lang + ']' + prefix + '[TEST_SUCCESS] ' + str(sum) + ' static ' + type + ' tests passed.'
|
1058
1058
|
dump('[INFO]' + success_message)
|
1059
1059
|
|
@@ -1100,7 +1100,7 @@ class testMainClass:
|
|
1100
1100
|
assert client_order_id_swap.startswith(swap_id_string), 'binance - swap clientOrderId: ' + client_order_id_swap + ' does not start with swapId' + swap_id_string
|
1101
1101
|
client_order_id_inverse = swap_inverse_order_request['newClientOrderId']
|
1102
1102
|
assert client_order_id_inverse.startswith(swap_id_string), 'binance - swap clientOrderIdInverse: ' + client_order_id_inverse + ' does not start with swapId' + swap_id_string
|
1103
|
-
if not
|
1103
|
+
if not is_sync():
|
1104
1104
|
close(exchange)
|
1105
1105
|
return True
|
1106
1106
|
|
@@ -1126,7 +1126,7 @@ class testMainClass:
|
|
1126
1126
|
assert client_order_id_swap.startswith(id_string), 'okx - swap clientOrderId: ' + client_order_id_swap + ' does not start with id: ' + id_string
|
1127
1127
|
swap_tag = swap_order_request[0]['tag']
|
1128
1128
|
assert swap_tag == id, 'okx - id: ' + id + ' different from swap tag: ' + swap_tag
|
1129
|
-
if not
|
1129
|
+
if not is_sync():
|
1130
1130
|
close(exchange)
|
1131
1131
|
return True
|
1132
1132
|
|
@@ -1141,7 +1141,7 @@ class testMainClass:
|
|
1141
1141
|
request = json_parse(exchange.last_request_body)
|
1142
1142
|
broker_id = request['params']['broker_id']
|
1143
1143
|
assert broker_id == id, 'cryptocom - id: ' + id + ' different from broker_id: ' + broker_id
|
1144
|
-
if not
|
1144
|
+
if not is_sync():
|
1145
1145
|
close(exchange)
|
1146
1146
|
return True
|
1147
1147
|
|
@@ -1156,7 +1156,7 @@ class testMainClass:
|
|
1156
1156
|
# we expect an error here, we're only interested in the headers
|
1157
1157
|
req_headers = exchange.last_request_headers
|
1158
1158
|
assert req_headers['Referer'] == id, 'bybit - id: ' + id + ' not in headers.'
|
1159
|
-
if not
|
1159
|
+
if not is_sync():
|
1160
1160
|
close(exchange)
|
1161
1161
|
return True
|
1162
1162
|
|
@@ -1174,7 +1174,7 @@ class testMainClass:
|
|
1174
1174
|
req_headers = exchange.last_request_headers
|
1175
1175
|
id = 'ccxt'
|
1176
1176
|
assert req_headers['KC-API-PARTNER'] == id, 'kucoin - id: ' + id + ' not in headers.'
|
1177
|
-
if not
|
1177
|
+
if not is_sync():
|
1178
1178
|
close(exchange)
|
1179
1179
|
return True
|
1180
1180
|
|
@@ -1191,7 +1191,7 @@ class testMainClass:
|
|
1191
1191
|
except Exception as e:
|
1192
1192
|
req_headers = exchange.last_request_headers
|
1193
1193
|
assert req_headers['KC-API-PARTNER'] == id, 'kucoinfutures - id: ' + id + ' not in headers.'
|
1194
|
-
if not
|
1194
|
+
if not is_sync():
|
1195
1195
|
close(exchange)
|
1196
1196
|
return True
|
1197
1197
|
|
@@ -1205,7 +1205,7 @@ class testMainClass:
|
|
1205
1205
|
except Exception as e:
|
1206
1206
|
req_headers = exchange.last_request_headers
|
1207
1207
|
assert req_headers['X-CHANNEL-API-CODE'] == id, 'bitget - id: ' + id + ' not in headers.'
|
1208
|
-
if not
|
1208
|
+
if not is_sync():
|
1209
1209
|
close(exchange)
|
1210
1210
|
return True
|
1211
1211
|
|
@@ -1220,7 +1220,7 @@ class testMainClass:
|
|
1220
1220
|
except Exception as e:
|
1221
1221
|
req_headers = exchange.last_request_headers
|
1222
1222
|
assert req_headers['source'] == id, 'mexc - id: ' + id + ' not in headers.'
|
1223
|
-
if not
|
1223
|
+
if not is_sync():
|
1224
1224
|
close(exchange)
|
1225
1225
|
return True
|
1226
1226
|
|
@@ -1251,7 +1251,7 @@ class testMainClass:
|
|
1251
1251
|
assert client_order_id_swap.startswith(id_string), 'htx - swap channel_code ' + client_order_id_swap + ' does not start with id: ' + id_string
|
1252
1252
|
client_order_id_inverse = swap_inverse_order_request['channel_code']
|
1253
1253
|
assert client_order_id_inverse.startswith(id_string), 'htx - swap inverse channel_code ' + client_order_id_inverse + ' does not start with id: ' + id_string
|
1254
|
-
if not
|
1254
|
+
if not is_sync():
|
1255
1255
|
close(exchange)
|
1256
1256
|
return True
|
1257
1257
|
|
@@ -1277,7 +1277,7 @@ class testMainClass:
|
|
1277
1277
|
stop_order_request = json_parse(exchange.last_request_body)
|
1278
1278
|
client_order_id_stop = stop_order_request['brokerId']
|
1279
1279
|
assert client_order_id_stop.startswith(id_string), 'woo - brokerId: ' + client_order_id_stop + ' does not start with id: ' + id_string
|
1280
|
-
if not
|
1280
|
+
if not is_sync():
|
1281
1281
|
close(exchange)
|
1282
1282
|
return True
|
1283
1283
|
|
@@ -1292,7 +1292,7 @@ class testMainClass:
|
|
1292
1292
|
except Exception as e:
|
1293
1293
|
req_headers = exchange.last_request_headers
|
1294
1294
|
assert req_headers['X-BM-BROKER-ID'] == id, 'bitmart - id: ' + id + ' not in headers'
|
1295
|
-
if not
|
1295
|
+
if not is_sync():
|
1296
1296
|
close(exchange)
|
1297
1297
|
return True
|
1298
1298
|
|
@@ -1308,7 +1308,7 @@ class testMainClass:
|
|
1308
1308
|
client_order_id = spot_order_request['client_id']
|
1309
1309
|
id_string = str(id)
|
1310
1310
|
assert client_order_id.startswith(id_string), 'coinex - clientOrderId: ' + client_order_id + ' does not start with id: ' + id_string
|
1311
|
-
if not
|
1311
|
+
if not is_sync():
|
1312
1312
|
close(exchange)
|
1313
1313
|
return True
|
1314
1314
|
|
@@ -1323,7 +1323,7 @@ class testMainClass:
|
|
1323
1323
|
# we expect an error here, we're only interested in the headers
|
1324
1324
|
req_headers = exchange.last_request_headers
|
1325
1325
|
assert req_headers['X-SOURCE-KEY'] == id, 'bingx - id: ' + id + ' not in headers.'
|
1326
|
-
if not
|
1326
|
+
if not is_sync():
|
1327
1327
|
close(exchange)
|
1328
1328
|
|
1329
1329
|
def test_phemex(self):
|
@@ -1337,7 +1337,7 @@ class testMainClass:
|
|
1337
1337
|
client_order_id = request['clOrdID']
|
1338
1338
|
id_string = str(id)
|
1339
1339
|
assert client_order_id.startswith(id_string), 'phemex - clOrdID: ' + client_order_id + ' does not start with id: ' + id_string
|
1340
|
-
if not
|
1340
|
+
if not is_sync():
|
1341
1341
|
close(exchange)
|
1342
1342
|
|
1343
1343
|
def test_blofin(self):
|
@@ -1351,7 +1351,7 @@ class testMainClass:
|
|
1351
1351
|
broker_id = request['brokerId']
|
1352
1352
|
id_string = str(id)
|
1353
1353
|
assert broker_id.startswith(id_string), 'blofin - brokerId: ' + broker_id + ' does not start with id: ' + id_string
|
1354
|
-
if not
|
1354
|
+
if not is_sync():
|
1355
1355
|
close(exchange)
|
1356
1356
|
|
1357
1357
|
def test_hyperliquid(self):
|
@@ -1364,7 +1364,7 @@ class testMainClass:
|
|
1364
1364
|
request = json_parse(exchange.last_request_body)
|
1365
1365
|
broker_id = str((request['action']['brokerCode']))
|
1366
1366
|
assert broker_id == id, 'hyperliquid - brokerId: ' + broker_id + ' does not start with id: ' + id
|
1367
|
-
if not
|
1367
|
+
if not is_sync():
|
1368
1368
|
close(exchange)
|
1369
1369
|
|
1370
1370
|
def test_coinbaseinternational(self):
|
@@ -1379,7 +1379,7 @@ class testMainClass:
|
|
1379
1379
|
request = json_parse(exchange.last_request_body)
|
1380
1380
|
client_order_id = request['client_order_id']
|
1381
1381
|
assert client_order_id.startswith(str(id)), 'clientOrderId does not start with id'
|
1382
|
-
if not
|
1382
|
+
if not is_sync():
|
1383
1383
|
close(exchange)
|
1384
1384
|
return True
|
1385
1385
|
|
@@ -1394,7 +1394,7 @@ class testMainClass:
|
|
1394
1394
|
request = json_parse(exchange.last_request_body)
|
1395
1395
|
client_order_id = request['client_order_id']
|
1396
1396
|
assert client_order_id.startswith(str(id)), 'clientOrderId does not start with id'
|
1397
|
-
if not
|
1397
|
+
if not is_sync():
|
1398
1398
|
close(exchange)
|
1399
1399
|
return True
|
1400
1400
|
|
@@ -1410,7 +1410,7 @@ class testMainClass:
|
|
1410
1410
|
request = json_parse(exchange.last_request_body)
|
1411
1411
|
broker_id = request['order_tag']
|
1412
1412
|
assert broker_id == id, 'woofipro - id: ' + id + ' different from broker_id: ' + broker_id
|
1413
|
-
if not
|
1413
|
+
if not is_sync():
|
1414
1414
|
close(exchange)
|
1415
1415
|
return True
|
1416
1416
|
|
@@ -1447,7 +1447,7 @@ class testMainClass:
|
|
1447
1447
|
swap_order_request = json_parse(exchange.last_request_body)
|
1448
1448
|
swap_media = swap_order_request['clientMedia']
|
1449
1449
|
assert swap_media == id, 'xt - id: ' + id + ' different from swap tag: ' + swap_media
|
1450
|
-
if not
|
1450
|
+
if not is_sync():
|
1451
1451
|
close(exchange)
|
1452
1452
|
return True
|
1453
1453
|
|
@@ -1470,7 +1470,7 @@ class testMainClass:
|
|
1470
1470
|
order = request['place_order']
|
1471
1471
|
broker_id = order['id']
|
1472
1472
|
assert broker_id == id, 'vertex - id: ' + str(id) + ' different from broker_id: ' + str(broker_id)
|
1473
|
-
if not
|
1473
|
+
if not is_sync():
|
1474
1474
|
close(exchange)
|
1475
1475
|
return True
|
1476
1476
|
|
@@ -1512,7 +1512,7 @@ class testMainClass:
|
|
1512
1512
|
except Exception as e:
|
1513
1513
|
req_headers = exchange.last_request_headers
|
1514
1514
|
assert req_headers['PARADEX-PARTNER'] == id, 'paradex - id: ' + id + ' not in headers'
|
1515
|
-
if not
|
1515
|
+
if not is_sync():
|
1516
1516
|
close(exchange)
|
1517
1517
|
return True
|
1518
1518
|
|
@@ -1526,6 +1526,6 @@ class testMainClass:
|
|
1526
1526
|
# we expect an error here, we're only interested in the headers
|
1527
1527
|
req_headers = exchange.last_request_headers
|
1528
1528
|
assert req_headers['INPUT-SOURCE'] == id, 'hashkey - id: ' + id + ' not in headers.'
|
1529
|
-
if not
|
1529
|
+
if not is_sync():
|
1530
1530
|
close(exchange)
|
1531
1531
|
return True
|
ccxt/vertex.py
CHANGED
@@ -2821,4 +2821,12 @@ class vertex(Exchange, ImplicitAPI):
|
|
2821
2821
|
else:
|
2822
2822
|
if params:
|
2823
2823
|
url += '?' + self.urlencode(params)
|
2824
|
+
if path != 'execute':
|
2825
|
+
# required encoding for public methods
|
2826
|
+
if headers is not None:
|
2827
|
+
headers['Accept-Encoding'] = 'gzip'
|
2828
|
+
else:
|
2829
|
+
headers = {
|
2830
|
+
'Accept-Encoding': 'gzip',
|
2831
|
+
}
|
2824
2832
|
return {'url': url, 'method': method, 'body': body, 'headers': headers}
|
ccxt/woo.py
CHANGED
@@ -79,6 +79,8 @@ class woo(Exchange, ImplicitAPI):
|
|
79
79
|
'fetchDeposits': True,
|
80
80
|
'fetchDepositsWithdrawals': True,
|
81
81
|
'fetchFundingHistory': True,
|
82
|
+
'fetchFundingInterval': True,
|
83
|
+
'fetchFundingIntervals': False,
|
82
84
|
'fetchFundingRate': True,
|
83
85
|
'fetchFundingRateHistory': True,
|
84
86
|
'fetchFundingRates': True,
|
@@ -2590,6 +2592,16 @@ class woo(Exchange, ImplicitAPI):
|
|
2590
2592
|
'interval': intervalString + 'h',
|
2591
2593
|
}
|
2592
2594
|
|
2595
|
+
def fetch_funding_interval(self, symbol: str, params={}) -> FundingRate:
|
2596
|
+
"""
|
2597
|
+
fetch the current funding rate interval
|
2598
|
+
:see: https://docs.woox.io/#get-predicted-funding-rate-for-one-market-public
|
2599
|
+
:param str symbol: unified market symbol
|
2600
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
2601
|
+
:returns dict: a `funding rate structure <https://docs.ccxt.com/#/?id=funding-rate-structure>`
|
2602
|
+
"""
|
2603
|
+
return self.fetch_funding_rate(symbol, params)
|
2604
|
+
|
2593
2605
|
def fetch_funding_rate(self, symbol: str, params={}) -> FundingRate:
|
2594
2606
|
"""
|
2595
2607
|
fetch the current funding rate
|
ccxt/woofipro.py
CHANGED
@@ -77,6 +77,8 @@ class woofipro(Exchange, ImplicitAPI):
|
|
77
77
|
'fetchDeposits': True,
|
78
78
|
'fetchDepositsWithdrawals': True,
|
79
79
|
'fetchFundingHistory': True,
|
80
|
+
'fetchFundingInterval': True,
|
81
|
+
'fetchFundingIntervals': False,
|
80
82
|
'fetchFundingRate': True,
|
81
83
|
'fetchFundingRateHistory': True,
|
82
84
|
'fetchFundingRates': True,
|
@@ -787,6 +789,16 @@ class woofipro(Exchange, ImplicitAPI):
|
|
787
789
|
}
|
788
790
|
return self.safe_string(intervals, interval, interval)
|
789
791
|
|
792
|
+
def fetch_funding_interval(self, symbol: str, params={}) -> FundingRate:
|
793
|
+
"""
|
794
|
+
fetch the current funding rate interval
|
795
|
+
:see: https://orderly.network/docs/build-on-evm/evm-api/restful-api/public/get-predicted-funding-rate-for-one-market
|
796
|
+
:param str symbol: unified market symbol
|
797
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
798
|
+
:returns dict: a `funding rate structure <https://docs.ccxt.com/#/?id=funding-rate-structure>`
|
799
|
+
"""
|
800
|
+
return self.fetch_funding_rate(symbol, params)
|
801
|
+
|
790
802
|
def fetch_funding_rate(self, symbol: str, params={}) -> FundingRate:
|
791
803
|
"""
|
792
804
|
fetch the current funding rate
|
ccxt/xt.py
CHANGED
@@ -77,6 +77,8 @@ class xt(Exchange, ImplicitAPI):
|
|
77
77
|
'fetchDepositWithdrawFee': False,
|
78
78
|
'fetchDepositWithdrawFees': False,
|
79
79
|
'fetchFundingHistory': True,
|
80
|
+
'fetchFundingInterval': True,
|
81
|
+
'fetchFundingIntervals': False,
|
80
82
|
'fetchFundingRate': True,
|
81
83
|
'fetchFundingRateHistory': True,
|
82
84
|
'fetchFundingRates': False,
|
@@ -4029,6 +4031,16 @@ class xt(Exchange, ImplicitAPI):
|
|
4029
4031
|
sorted = self.sort_by(rates, 'timestamp')
|
4030
4032
|
return self.filter_by_symbol_since_limit(sorted, market['symbol'], since, limit)
|
4031
4033
|
|
4034
|
+
def fetch_funding_interval(self, symbol: str, params={}) -> FundingRate:
|
4035
|
+
"""
|
4036
|
+
fetch the current funding rate interval
|
4037
|
+
:see: https://doc.xt.com/#futures_quotesgetFundingRate
|
4038
|
+
:param str symbol: unified market symbol
|
4039
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
4040
|
+
:returns dict: a `funding rate structure <https://docs.ccxt.com/#/?id=funding-rate-structure>`
|
4041
|
+
"""
|
4042
|
+
return self.fetch_funding_rate(symbol, params)
|
4043
|
+
|
4032
4044
|
def fetch_funding_rate(self, symbol: str, params={}) -> FundingRate:
|
4033
4045
|
"""
|
4034
4046
|
fetch the current funding rate
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: ccxt
|
3
|
-
Version: 4.4.
|
3
|
+
Version: 4.4.15
|
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
|
@@ -271,13 +271,13 @@ console.log(version, Object.keys(exchanges));
|
|
271
271
|
|
272
272
|
All-in-one browser bundle (dependencies included), served from a CDN of your choice:
|
273
273
|
|
274
|
-
* jsDelivr: https://cdn.jsdelivr.net/npm/ccxt@4.4.
|
275
|
-
* unpkg: https://unpkg.com/ccxt@4.4.
|
274
|
+
* jsDelivr: https://cdn.jsdelivr.net/npm/ccxt@4.4.15/dist/ccxt.browser.min.js
|
275
|
+
* unpkg: https://unpkg.com/ccxt@4.4.15/dist/ccxt.browser.min.js
|
276
276
|
|
277
277
|
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.
|
278
278
|
|
279
279
|
```HTML
|
280
|
-
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/ccxt@4.4.
|
280
|
+
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/ccxt@4.4.15/dist/ccxt.browser.min.js"></script>
|
281
281
|
```
|
282
282
|
|
283
283
|
Creates a global `ccxt` object:
|