ccxt 4.4.12__py2.py3-none-any.whl → 4.4.14__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 +37 -1
- ccxt/async_support/bigone.py +2 -0
- ccxt/async_support/binance.py +113 -12
- ccxt/async_support/bingx.py +69 -3
- ccxt/async_support/bitget.py +102 -3
- ccxt/async_support/bitmex.py +1 -0
- ccxt/async_support/bitrue.py +1 -7
- ccxt/async_support/bitvavo.py +1 -3
- ccxt/async_support/bybit.py +2 -0
- ccxt/async_support/coinbaseinternational.py +2 -0
- ccxt/async_support/coinex.py +15 -1
- ccxt/async_support/cryptocom.py +1 -0
- ccxt/async_support/delta.py +2 -0
- ccxt/async_support/deribit.py +2 -0
- ccxt/async_support/digifinex.py +15 -1
- ccxt/async_support/gate.py +2 -0
- ccxt/async_support/htx.py +2 -2
- ccxt/async_support/huobijp.py +1 -3
- ccxt/async_support/krakenfutures.py +2 -0
- ccxt/async_support/kucoin.py +36 -1
- ccxt/async_support/kucoinfutures.py +56 -3
- ccxt/async_support/mexc.py +52 -8
- ccxt/async_support/okx.py +48 -0
- ccxt/async_support/oxfun.py +1 -0
- ccxt/async_support/paradex.py +1 -0
- ccxt/async_support/poloniex.py +1 -0
- ccxt/async_support/poloniexfutures.py +35 -11
- 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 +44 -2
- ccxt/base/types.py +2 -0
- ccxt/bigone.py +2 -0
- ccxt/binance.py +113 -12
- ccxt/bingx.py +69 -3
- ccxt/bitget.py +102 -3
- ccxt/bitmex.py +1 -0
- ccxt/bitrue.py +1 -7
- ccxt/bitvavo.py +1 -3
- ccxt/bybit.py +2 -0
- ccxt/coinbaseinternational.py +2 -0
- ccxt/coinex.py +15 -1
- ccxt/cryptocom.py +1 -0
- ccxt/delta.py +2 -0
- ccxt/deribit.py +2 -0
- ccxt/digifinex.py +15 -1
- ccxt/gate.py +2 -0
- ccxt/htx.py +2 -2
- ccxt/huobijp.py +1 -3
- ccxt/krakenfutures.py +2 -0
- ccxt/kucoin.py +36 -1
- ccxt/kucoinfutures.py +56 -3
- ccxt/mexc.py +52 -8
- ccxt/okx.py +48 -0
- ccxt/oxfun.py +1 -0
- ccxt/paradex.py +1 -0
- ccxt/poloniex.py +1 -0
- ccxt/poloniexfutures.py +35 -11
- ccxt/pro/__init__.py +1 -1
- ccxt/pro/binance.py +72 -5
- ccxt/pro/bitfinex.py +8 -8
- ccxt/pro/krakenfutures.py +2 -0
- ccxt/pro/okx.py +38 -0
- ccxt/pro/phemex.py +2 -0
- ccxt/pro/woo.py +69 -0
- ccxt/test/tests_async.py +76 -48
- ccxt/test/tests_helpers.py +27 -36
- ccxt/test/tests_init.py +6 -2
- ccxt/test/tests_sync.py +76 -48
- ccxt/woo.py +12 -0
- ccxt/woofipro.py +12 -0
- ccxt/xt.py +12 -0
- {ccxt-4.4.12.dist-info → ccxt-4.4.14.dist-info}/METADATA +4 -5
- {ccxt-4.4.12.dist-info → ccxt-4.4.14.dist-info}/RECORD +84 -84
- {ccxt-4.4.12.dist-info → ccxt-4.4.14.dist-info}/LICENSE.txt +0 -0
- {ccxt-4.4.12.dist-info → ccxt-4.4.14.dist-info}/WHEEL +0 -0
- {ccxt-4.4.12.dist-info → ccxt-4.4.14.dist-info}/top_level.txt +0 -0
ccxt/test/tests_sync.py
CHANGED
@@ -1,9 +1,33 @@
|
|
1
1
|
# -*- coding: utf-8 -*-
|
2
2
|
|
3
|
-
from tests_helpers import AuthenticationError, NotSupported, InvalidProxySettings, ExchangeNotAvailable, OperationFailed, OnMaintenance, get_cli_arg_value,
|
4
|
-
|
5
|
-
class testMainClass
|
6
|
-
|
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
|
+
|
5
|
+
class testMainClass:
|
6
|
+
id_tests = False
|
7
|
+
request_tests_failed = False
|
8
|
+
response_tests_failed = False
|
9
|
+
request_tests = False
|
10
|
+
ws_tests = False
|
11
|
+
response_tests = False
|
12
|
+
static_tests = False
|
13
|
+
info = False
|
14
|
+
verbose = False
|
15
|
+
debug = False
|
16
|
+
private_test = False
|
17
|
+
private_test_only = False
|
18
|
+
load_keys = False
|
19
|
+
sandbox = False
|
20
|
+
only_specific_tests = []
|
21
|
+
skipped_settings_for_exchange = {}
|
22
|
+
skipped_methods = {}
|
23
|
+
checked_public_tests = {}
|
24
|
+
test_files = {}
|
25
|
+
public_tests = {}
|
26
|
+
ext = ''
|
27
|
+
lang = ''
|
28
|
+
proxy_test_file_name = 'proxies'
|
29
|
+
|
30
|
+
def parse_cli_args_and_props(self):
|
7
31
|
self.response_tests = get_cli_arg_value('--responseTests')
|
8
32
|
self.id_tests = get_cli_arg_value('--idTests')
|
9
33
|
self.request_tests = get_cli_arg_value('--requestTests')
|
@@ -15,9 +39,11 @@ class testMainClass(baseMainTestClass):
|
|
15
39
|
self.sandbox = get_cli_arg_value('--sandbox')
|
16
40
|
self.load_keys = get_cli_arg_value('--loadKeys')
|
17
41
|
self.ws_tests = get_cli_arg_value('--ws')
|
42
|
+
self.lang = get_lang()
|
43
|
+
self.ext = get_ext()
|
18
44
|
|
19
45
|
def init(self, exchange_id, symbol_argv, method_argv):
|
20
|
-
self.
|
46
|
+
self.parse_cli_args_and_props()
|
21
47
|
if self.request_tests and self.response_tests:
|
22
48
|
self.run_static_request_tests(exchange_id, symbol_argv)
|
23
49
|
self.run_static_response_tests(exchange_id, symbol_argv)
|
@@ -31,12 +57,13 @@ class testMainClass(baseMainTestClass):
|
|
31
57
|
if self.id_tests:
|
32
58
|
self.run_broker_id_tests()
|
33
59
|
return
|
34
|
-
|
60
|
+
new_line = '\n'
|
61
|
+
dump(new_line + '' + new_line + '' + '[INFO] TESTING ', self.ext, {
|
35
62
|
'exchange': exchange_id,
|
36
63
|
'symbol': symbol_argv,
|
37
64
|
'method': method_argv,
|
38
65
|
'isWs': self.ws_tests,
|
39
|
-
},
|
66
|
+
}, new_line)
|
40
67
|
exchange_args = {
|
41
68
|
'verbose': self.verbose,
|
42
69
|
'debug': self.debug,
|
@@ -69,7 +96,7 @@ class testMainClass(baseMainTestClass):
|
|
69
96
|
def import_files(self, exchange):
|
70
97
|
properties = list(exchange.has.keys())
|
71
98
|
properties.append('loadMarkets')
|
72
|
-
if
|
99
|
+
if is_sync():
|
73
100
|
self.test_files = get_test_files_sync(properties, self.ws_tests)
|
74
101
|
else:
|
75
102
|
self.test_files = get_test_files(properties, self.ws_tests)
|
@@ -84,14 +111,15 @@ class testMainClass(baseMainTestClass):
|
|
84
111
|
if is_required and get_exchange_prop(exchange, credential) is None:
|
85
112
|
full_key = exchange_id + '_' + credential
|
86
113
|
credential_env_name = full_key.upper() # example: KRAKEN_APIKEY
|
87
|
-
|
114
|
+
env_vars = get_env_vars()
|
115
|
+
credential_value = env_vars[credential_env_name] if (credential_env_name in env_vars) else None
|
88
116
|
if credential_value:
|
89
117
|
set_exchange_prop(exchange, credential, credential_value)
|
90
118
|
|
91
119
|
def expand_settings(self, exchange):
|
92
120
|
exchange_id = exchange.id
|
93
|
-
keys_global =
|
94
|
-
keys_local =
|
121
|
+
keys_global = get_root_dir() + 'keys.json'
|
122
|
+
keys_local = get_root_dir() + 'keys.local.json'
|
95
123
|
keys_global_exists = io_file_exists(keys_global)
|
96
124
|
keys_local_exists = io_file_exists(keys_local)
|
97
125
|
global_settings = io_file_read(keys_global) if keys_global_exists else {}
|
@@ -114,7 +142,7 @@ class testMainClass(baseMainTestClass):
|
|
114
142
|
if self.load_keys:
|
115
143
|
self.load_credentials_from_env(exchange)
|
116
144
|
# skipped tests
|
117
|
-
skipped_file =
|
145
|
+
skipped_file = get_root_dir() + 'skip-tests.json'
|
118
146
|
skipped_settings = io_file_read(skipped_file)
|
119
147
|
self.skipped_settings_for_exchange = exchange.safe_value(skipped_settings, exchange_id, {})
|
120
148
|
skipped_settings_for_exchange = self.skipped_settings_for_exchange
|
@@ -175,7 +203,7 @@ class testMainClass(baseMainTestClass):
|
|
175
203
|
if self.info:
|
176
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"
|
177
205
|
dump(self.add_padding('[INFO] TESTING', 25), name, method_name, args_stringified)
|
178
|
-
if
|
206
|
+
if is_sync():
|
179
207
|
call_method_sync(self.test_files, method_name, exchange, skipped_properties_for_method, args)
|
180
208
|
else:
|
181
209
|
call_method(self.test_files, method_name, exchange, skipped_properties_for_method, args)
|
@@ -558,7 +586,7 @@ class testMainClass(baseMainTestClass):
|
|
558
586
|
# these tests should be synchronously executed, because of conflicting nature of proxy settings
|
559
587
|
proxy_test_name = self.proxy_test_file_name
|
560
588
|
# todo: temporary skip for sync py
|
561
|
-
if self.ext == 'py' and
|
589
|
+
if self.ext == 'py' and is_sync():
|
562
590
|
return
|
563
591
|
# try proxy several times
|
564
592
|
max_retries = 3
|
@@ -586,7 +614,7 @@ class testMainClass(baseMainTestClass):
|
|
586
614
|
try:
|
587
615
|
result = self.load_exchange(exchange)
|
588
616
|
if not result:
|
589
|
-
if not
|
617
|
+
if not is_sync():
|
590
618
|
close(exchange)
|
591
619
|
return
|
592
620
|
# if (exchange.id === 'binance') {
|
@@ -594,10 +622,10 @@ class testMainClass(baseMainTestClass):
|
|
594
622
|
# # this.testProxies (exchange);
|
595
623
|
# }
|
596
624
|
self.test_exchange(exchange, symbol)
|
597
|
-
if not
|
625
|
+
if not is_sync():
|
598
626
|
close(exchange)
|
599
627
|
except Exception as e:
|
600
|
-
if not
|
628
|
+
if not is_sync():
|
601
629
|
close(exchange)
|
602
630
|
raise e
|
603
631
|
|
@@ -617,12 +645,12 @@ class testMainClass(baseMainTestClass):
|
|
617
645
|
# to make this test as fast as possible
|
618
646
|
# and basically independent from the exchange
|
619
647
|
# so we can run it offline
|
620
|
-
filename =
|
648
|
+
filename = get_root_dir() + './ts/src/test/static/markets/' + id + '.json'
|
621
649
|
content = io_file_read(filename)
|
622
650
|
return content
|
623
651
|
|
624
652
|
def load_currencies_from_file(self, id):
|
625
|
-
filename =
|
653
|
+
filename = get_root_dir() + './ts/src/test/static/currencies/' + id + '.json'
|
626
654
|
content = io_file_read(filename)
|
627
655
|
return content
|
628
656
|
|
@@ -812,7 +840,7 @@ class testMainClass(baseMainTestClass):
|
|
812
840
|
output = None
|
813
841
|
request_url = None
|
814
842
|
try:
|
815
|
-
if not
|
843
|
+
if not is_sync():
|
816
844
|
call_exchange_method_dynamically(exchange, method, self.sanitize_data_input(data['input']))
|
817
845
|
else:
|
818
846
|
call_exchange_method_dynamically_sync(exchange, method, self.sanitize_data_input(data['input']))
|
@@ -833,7 +861,7 @@ class testMainClass(baseMainTestClass):
|
|
833
861
|
expected_result = exchange.safe_value(data, 'parsedResponse')
|
834
862
|
mocked_exchange = set_fetch_response(exchange, data['httpResponse'])
|
835
863
|
try:
|
836
|
-
if not
|
864
|
+
if not is_sync():
|
837
865
|
unified_result = call_exchange_method_dynamically(exchange, method, self.sanitize_data_input(data['input']))
|
838
866
|
self.assert_static_response_output(mocked_exchange, skip_keys, unified_result, expected_result)
|
839
867
|
else:
|
@@ -929,7 +957,7 @@ class testMainClass(baseMainTestClass):
|
|
929
957
|
# reset options
|
930
958
|
# exchange.options = exchange.deepExtend (oldExchangeOptions, {});
|
931
959
|
exchange.extend_exchange_options(exchange.deep_extend(old_exchange_options, {}))
|
932
|
-
if not
|
960
|
+
if not is_sync():
|
933
961
|
close(exchange)
|
934
962
|
return True # in c# methods that will be used with promiseAll need to return something
|
935
963
|
|
@@ -979,7 +1007,7 @@ class testMainClass(baseMainTestClass):
|
|
979
1007
|
# reset options
|
980
1008
|
# exchange.options = exchange.deepExtend (oldExchangeOptions, {});
|
981
1009
|
exchange.extend_exchange_options(exchange.deep_extend(old_exchange_options, {}))
|
982
|
-
if not
|
1010
|
+
if not is_sync():
|
983
1011
|
close(exchange)
|
984
1012
|
return True # in c# methods that will be used with promiseAll need to return something
|
985
1013
|
|
@@ -1000,7 +1028,7 @@ class testMainClass(baseMainTestClass):
|
|
1000
1028
|
self.run_static_tests('request', target_exchange, test_name)
|
1001
1029
|
|
1002
1030
|
def run_static_tests(self, type, target_exchange=None, test_name=None):
|
1003
|
-
folder =
|
1031
|
+
folder = get_root_dir() + './ts/src/test/static/' + type + '/'
|
1004
1032
|
static_data = self.load_static_data(folder, target_exchange)
|
1005
1033
|
if static_data is None:
|
1006
1034
|
return
|
@@ -1025,7 +1053,7 @@ class testMainClass(baseMainTestClass):
|
|
1025
1053
|
if self.request_tests_failed or self.response_tests_failed:
|
1026
1054
|
exit_script(1)
|
1027
1055
|
else:
|
1028
|
-
prefix = '[SYNC]' if (
|
1056
|
+
prefix = '[SYNC]' if (is_sync()) else ''
|
1029
1057
|
success_message = '[' + self.lang + ']' + prefix + '[TEST_SUCCESS] ' + str(sum) + ' static ' + type + ' tests passed.'
|
1030
1058
|
dump('[INFO]' + success_message)
|
1031
1059
|
|
@@ -1072,7 +1100,7 @@ class testMainClass(baseMainTestClass):
|
|
1072
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
|
1073
1101
|
client_order_id_inverse = swap_inverse_order_request['newClientOrderId']
|
1074
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
|
1075
|
-
if not
|
1103
|
+
if not is_sync():
|
1076
1104
|
close(exchange)
|
1077
1105
|
return True
|
1078
1106
|
|
@@ -1098,7 +1126,7 @@ class testMainClass(baseMainTestClass):
|
|
1098
1126
|
assert client_order_id_swap.startswith(id_string), 'okx - swap clientOrderId: ' + client_order_id_swap + ' does not start with id: ' + id_string
|
1099
1127
|
swap_tag = swap_order_request[0]['tag']
|
1100
1128
|
assert swap_tag == id, 'okx - id: ' + id + ' different from swap tag: ' + swap_tag
|
1101
|
-
if not
|
1129
|
+
if not is_sync():
|
1102
1130
|
close(exchange)
|
1103
1131
|
return True
|
1104
1132
|
|
@@ -1113,7 +1141,7 @@ class testMainClass(baseMainTestClass):
|
|
1113
1141
|
request = json_parse(exchange.last_request_body)
|
1114
1142
|
broker_id = request['params']['broker_id']
|
1115
1143
|
assert broker_id == id, 'cryptocom - id: ' + id + ' different from broker_id: ' + broker_id
|
1116
|
-
if not
|
1144
|
+
if not is_sync():
|
1117
1145
|
close(exchange)
|
1118
1146
|
return True
|
1119
1147
|
|
@@ -1128,7 +1156,7 @@ class testMainClass(baseMainTestClass):
|
|
1128
1156
|
# we expect an error here, we're only interested in the headers
|
1129
1157
|
req_headers = exchange.last_request_headers
|
1130
1158
|
assert req_headers['Referer'] == id, 'bybit - id: ' + id + ' not in headers.'
|
1131
|
-
if not
|
1159
|
+
if not is_sync():
|
1132
1160
|
close(exchange)
|
1133
1161
|
return True
|
1134
1162
|
|
@@ -1146,7 +1174,7 @@ class testMainClass(baseMainTestClass):
|
|
1146
1174
|
req_headers = exchange.last_request_headers
|
1147
1175
|
id = 'ccxt'
|
1148
1176
|
assert req_headers['KC-API-PARTNER'] == id, 'kucoin - id: ' + id + ' not in headers.'
|
1149
|
-
if not
|
1177
|
+
if not is_sync():
|
1150
1178
|
close(exchange)
|
1151
1179
|
return True
|
1152
1180
|
|
@@ -1163,7 +1191,7 @@ class testMainClass(baseMainTestClass):
|
|
1163
1191
|
except Exception as e:
|
1164
1192
|
req_headers = exchange.last_request_headers
|
1165
1193
|
assert req_headers['KC-API-PARTNER'] == id, 'kucoinfutures - id: ' + id + ' not in headers.'
|
1166
|
-
if not
|
1194
|
+
if not is_sync():
|
1167
1195
|
close(exchange)
|
1168
1196
|
return True
|
1169
1197
|
|
@@ -1177,7 +1205,7 @@ class testMainClass(baseMainTestClass):
|
|
1177
1205
|
except Exception as e:
|
1178
1206
|
req_headers = exchange.last_request_headers
|
1179
1207
|
assert req_headers['X-CHANNEL-API-CODE'] == id, 'bitget - id: ' + id + ' not in headers.'
|
1180
|
-
if not
|
1208
|
+
if not is_sync():
|
1181
1209
|
close(exchange)
|
1182
1210
|
return True
|
1183
1211
|
|
@@ -1192,7 +1220,7 @@ class testMainClass(baseMainTestClass):
|
|
1192
1220
|
except Exception as e:
|
1193
1221
|
req_headers = exchange.last_request_headers
|
1194
1222
|
assert req_headers['source'] == id, 'mexc - id: ' + id + ' not in headers.'
|
1195
|
-
if not
|
1223
|
+
if not is_sync():
|
1196
1224
|
close(exchange)
|
1197
1225
|
return True
|
1198
1226
|
|
@@ -1223,7 +1251,7 @@ class testMainClass(baseMainTestClass):
|
|
1223
1251
|
assert client_order_id_swap.startswith(id_string), 'htx - swap channel_code ' + client_order_id_swap + ' does not start with id: ' + id_string
|
1224
1252
|
client_order_id_inverse = swap_inverse_order_request['channel_code']
|
1225
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
|
1226
|
-
if not
|
1254
|
+
if not is_sync():
|
1227
1255
|
close(exchange)
|
1228
1256
|
return True
|
1229
1257
|
|
@@ -1249,7 +1277,7 @@ class testMainClass(baseMainTestClass):
|
|
1249
1277
|
stop_order_request = json_parse(exchange.last_request_body)
|
1250
1278
|
client_order_id_stop = stop_order_request['brokerId']
|
1251
1279
|
assert client_order_id_stop.startswith(id_string), 'woo - brokerId: ' + client_order_id_stop + ' does not start with id: ' + id_string
|
1252
|
-
if not
|
1280
|
+
if not is_sync():
|
1253
1281
|
close(exchange)
|
1254
1282
|
return True
|
1255
1283
|
|
@@ -1264,7 +1292,7 @@ class testMainClass(baseMainTestClass):
|
|
1264
1292
|
except Exception as e:
|
1265
1293
|
req_headers = exchange.last_request_headers
|
1266
1294
|
assert req_headers['X-BM-BROKER-ID'] == id, 'bitmart - id: ' + id + ' not in headers'
|
1267
|
-
if not
|
1295
|
+
if not is_sync():
|
1268
1296
|
close(exchange)
|
1269
1297
|
return True
|
1270
1298
|
|
@@ -1280,7 +1308,7 @@ class testMainClass(baseMainTestClass):
|
|
1280
1308
|
client_order_id = spot_order_request['client_id']
|
1281
1309
|
id_string = str(id)
|
1282
1310
|
assert client_order_id.startswith(id_string), 'coinex - clientOrderId: ' + client_order_id + ' does not start with id: ' + id_string
|
1283
|
-
if not
|
1311
|
+
if not is_sync():
|
1284
1312
|
close(exchange)
|
1285
1313
|
return True
|
1286
1314
|
|
@@ -1295,7 +1323,7 @@ class testMainClass(baseMainTestClass):
|
|
1295
1323
|
# we expect an error here, we're only interested in the headers
|
1296
1324
|
req_headers = exchange.last_request_headers
|
1297
1325
|
assert req_headers['X-SOURCE-KEY'] == id, 'bingx - id: ' + id + ' not in headers.'
|
1298
|
-
if not
|
1326
|
+
if not is_sync():
|
1299
1327
|
close(exchange)
|
1300
1328
|
|
1301
1329
|
def test_phemex(self):
|
@@ -1309,7 +1337,7 @@ class testMainClass(baseMainTestClass):
|
|
1309
1337
|
client_order_id = request['clOrdID']
|
1310
1338
|
id_string = str(id)
|
1311
1339
|
assert client_order_id.startswith(id_string), 'phemex - clOrdID: ' + client_order_id + ' does not start with id: ' + id_string
|
1312
|
-
if not
|
1340
|
+
if not is_sync():
|
1313
1341
|
close(exchange)
|
1314
1342
|
|
1315
1343
|
def test_blofin(self):
|
@@ -1323,7 +1351,7 @@ class testMainClass(baseMainTestClass):
|
|
1323
1351
|
broker_id = request['brokerId']
|
1324
1352
|
id_string = str(id)
|
1325
1353
|
assert broker_id.startswith(id_string), 'blofin - brokerId: ' + broker_id + ' does not start with id: ' + id_string
|
1326
|
-
if not
|
1354
|
+
if not is_sync():
|
1327
1355
|
close(exchange)
|
1328
1356
|
|
1329
1357
|
def test_hyperliquid(self):
|
@@ -1336,7 +1364,7 @@ class testMainClass(baseMainTestClass):
|
|
1336
1364
|
request = json_parse(exchange.last_request_body)
|
1337
1365
|
broker_id = str((request['action']['brokerCode']))
|
1338
1366
|
assert broker_id == id, 'hyperliquid - brokerId: ' + broker_id + ' does not start with id: ' + id
|
1339
|
-
if not
|
1367
|
+
if not is_sync():
|
1340
1368
|
close(exchange)
|
1341
1369
|
|
1342
1370
|
def test_coinbaseinternational(self):
|
@@ -1351,7 +1379,7 @@ class testMainClass(baseMainTestClass):
|
|
1351
1379
|
request = json_parse(exchange.last_request_body)
|
1352
1380
|
client_order_id = request['client_order_id']
|
1353
1381
|
assert client_order_id.startswith(str(id)), 'clientOrderId does not start with id'
|
1354
|
-
if not
|
1382
|
+
if not is_sync():
|
1355
1383
|
close(exchange)
|
1356
1384
|
return True
|
1357
1385
|
|
@@ -1366,7 +1394,7 @@ class testMainClass(baseMainTestClass):
|
|
1366
1394
|
request = json_parse(exchange.last_request_body)
|
1367
1395
|
client_order_id = request['client_order_id']
|
1368
1396
|
assert client_order_id.startswith(str(id)), 'clientOrderId does not start with id'
|
1369
|
-
if not
|
1397
|
+
if not is_sync():
|
1370
1398
|
close(exchange)
|
1371
1399
|
return True
|
1372
1400
|
|
@@ -1382,7 +1410,7 @@ class testMainClass(baseMainTestClass):
|
|
1382
1410
|
request = json_parse(exchange.last_request_body)
|
1383
1411
|
broker_id = request['order_tag']
|
1384
1412
|
assert broker_id == id, 'woofipro - id: ' + id + ' different from broker_id: ' + broker_id
|
1385
|
-
if not
|
1413
|
+
if not is_sync():
|
1386
1414
|
close(exchange)
|
1387
1415
|
return True
|
1388
1416
|
|
@@ -1419,7 +1447,7 @@ class testMainClass(baseMainTestClass):
|
|
1419
1447
|
swap_order_request = json_parse(exchange.last_request_body)
|
1420
1448
|
swap_media = swap_order_request['clientMedia']
|
1421
1449
|
assert swap_media == id, 'xt - id: ' + id + ' different from swap tag: ' + swap_media
|
1422
|
-
if not
|
1450
|
+
if not is_sync():
|
1423
1451
|
close(exchange)
|
1424
1452
|
return True
|
1425
1453
|
|
@@ -1442,7 +1470,7 @@ class testMainClass(baseMainTestClass):
|
|
1442
1470
|
order = request['place_order']
|
1443
1471
|
broker_id = order['id']
|
1444
1472
|
assert broker_id == id, 'vertex - id: ' + str(id) + ' different from broker_id: ' + str(broker_id)
|
1445
|
-
if not
|
1473
|
+
if not is_sync():
|
1446
1474
|
close(exchange)
|
1447
1475
|
return True
|
1448
1476
|
|
@@ -1484,7 +1512,7 @@ class testMainClass(baseMainTestClass):
|
|
1484
1512
|
except Exception as e:
|
1485
1513
|
req_headers = exchange.last_request_headers
|
1486
1514
|
assert req_headers['PARADEX-PARTNER'] == id, 'paradex - id: ' + id + ' not in headers'
|
1487
|
-
if not
|
1515
|
+
if not is_sync():
|
1488
1516
|
close(exchange)
|
1489
1517
|
return True
|
1490
1518
|
|
@@ -1498,6 +1526,6 @@ class testMainClass(baseMainTestClass):
|
|
1498
1526
|
# we expect an error here, we're only interested in the headers
|
1499
1527
|
req_headers = exchange.last_request_headers
|
1500
1528
|
assert req_headers['INPUT-SOURCE'] == id, 'hashkey - id: ' + id + ' not in headers.'
|
1501
|
-
if not
|
1529
|
+
if not is_sync():
|
1502
1530
|
close(exchange)
|
1503
1531
|
return True
|
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.14
|
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
|
@@ -70,7 +70,6 @@ Current feature list:
|
|
70
70
|
|
71
71
|
|
72
72
|
## Sponsored Promotion
|
73
|
-
[](https://www.bitmart.com/activity/BitMartxCCXT/en-US)
|
74
73
|
|
75
74
|
## See Also
|
76
75
|
|
@@ -272,13 +271,13 @@ console.log(version, Object.keys(exchanges));
|
|
272
271
|
|
273
272
|
All-in-one browser bundle (dependencies included), served from a CDN of your choice:
|
274
273
|
|
275
|
-
* jsDelivr: https://cdn.jsdelivr.net/npm/ccxt@4.4.
|
276
|
-
* unpkg: https://unpkg.com/ccxt@4.4.
|
274
|
+
* jsDelivr: https://cdn.jsdelivr.net/npm/ccxt@4.4.14/dist/ccxt.browser.min.js
|
275
|
+
* unpkg: https://unpkg.com/ccxt@4.4.14/dist/ccxt.browser.min.js
|
277
276
|
|
278
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.
|
279
278
|
|
280
279
|
```HTML
|
281
|
-
<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.14/dist/ccxt.browser.min.js"></script>
|
282
281
|
```
|
283
282
|
|
284
283
|
Creates a global `ccxt` object:
|