ccxt 4.1.68__py2.py3-none-any.whl → 4.1.70__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/phemex.py +8 -0
- ccxt/ascendex.py +69 -68
- ccxt/async_support/__init__.py +1 -1
- ccxt/async_support/ascendex.py +69 -68
- ccxt/async_support/base/exchange.py +1 -1
- ccxt/async_support/coinex.py +348 -59
- ccxt/async_support/phemex.py +14 -2
- ccxt/base/exchange.py +1 -1
- ccxt/coinex.py +348 -59
- ccxt/phemex.py +14 -2
- ccxt/pro/__init__.py +1 -1
- ccxt/pro/binance.py +2 -2
- ccxt/pro/htx.py +3 -2
- ccxt/test/test_async.py +51 -29
- ccxt/test/test_sync.py +51 -29
- {ccxt-4.1.68.dist-info → ccxt-4.1.70.dist-info}/METADATA +5 -5
- {ccxt-4.1.68.dist-info → ccxt-4.1.70.dist-info}/RECORD +20 -20
- {ccxt-4.1.68.dist-info → ccxt-4.1.70.dist-info}/WHEEL +0 -0
- {ccxt-4.1.68.dist-info → ccxt-4.1.70.dist-info}/top_level.txt +0 -0
ccxt/test/test_async.py
CHANGED
@@ -8,14 +8,13 @@ import sys
|
|
8
8
|
from traceback import format_tb, format_exception
|
9
9
|
|
10
10
|
import importlib # noqa: E402
|
11
|
-
import glob # noqa: E402
|
12
11
|
import re
|
13
12
|
|
14
13
|
# ------------------------------------------------------------------------------
|
15
14
|
# logging.basicConfig(level=logging.INFO)
|
16
15
|
# ------------------------------------------------------------------------------
|
17
|
-
|
18
|
-
root = os.path.dirname(os.path.dirname(
|
16
|
+
DIR_NAME = os.path.dirname(os.path.abspath(__file__))
|
17
|
+
root = os.path.dirname(os.path.dirname(DIR_NAME))
|
19
18
|
sys.path.append(root)
|
20
19
|
|
21
20
|
import ccxt.async_support as ccxt # noqa: E402
|
@@ -96,8 +95,8 @@ sys.excepthook = handle_all_unhandled_exceptions
|
|
96
95
|
|
97
96
|
is_synchronous = 'async' not in os.path.basename(__file__)
|
98
97
|
|
99
|
-
rootDir =
|
100
|
-
rootDirForSkips =
|
98
|
+
rootDir = DIR_NAME + '/../../../'
|
99
|
+
rootDirForSkips = DIR_NAME + '/../../../'
|
101
100
|
envVars = os.environ
|
102
101
|
LOG_CHARS_LENGTH = 10000
|
103
102
|
ext = 'py'
|
@@ -117,6 +116,7 @@ class baseMainTestClass():
|
|
117
116
|
env_vars = envVars
|
118
117
|
ext = ext
|
119
118
|
root_dir_for_skips = rootDirForSkips
|
119
|
+
only_specific_tests = []
|
120
120
|
proxy_test_file_name = proxyTestFileName
|
121
121
|
pass
|
122
122
|
|
@@ -141,12 +141,12 @@ def get_cli_arg_value(arg):
|
|
141
141
|
arg_exists_wo_hyphen = getattr(argv, without_hyphen) if hasattr(argv, without_hyphen) else False
|
142
142
|
return arg_exists or arg_exists_with_hyphen or arg_exists_wo_hyphen
|
143
143
|
|
144
|
+
def convert_to_snake_case(conent):
|
145
|
+
return re.sub(r'(?<!^)(?=[A-Z])', '_', conent).lower()
|
144
146
|
|
145
147
|
def get_test_name(methodName):
|
146
|
-
|
147
|
-
|
148
|
-
full_name = 'test_' + snake_cased
|
149
|
-
return full_name
|
148
|
+
# stub
|
149
|
+
return methodName
|
150
150
|
|
151
151
|
|
152
152
|
def io_file_exists(path):
|
@@ -166,8 +166,10 @@ def io_dir_read(path):
|
|
166
166
|
return os.listdir(path)
|
167
167
|
|
168
168
|
|
169
|
-
async def call_method(
|
170
|
-
|
169
|
+
async def call_method(test_files, methodName, exchange, skippedProperties, args):
|
170
|
+
methodNameToCall = convert_to_snake_case(methodName)
|
171
|
+
methodNameToCall = 'test_' + methodNameToCall.replace('o_h_l_c_v', 'ohlcv')
|
172
|
+
return await getattr(test_files[methodName], methodNameToCall)(exchange, skippedProperties, *args)
|
171
173
|
|
172
174
|
|
173
175
|
async def call_exchange_method_dynamically(exchange, methodName, args):
|
@@ -206,14 +208,15 @@ def init_exchange(exchangeId, args):
|
|
206
208
|
|
207
209
|
|
208
210
|
async def set_test_files(holderClass, properties):
|
209
|
-
|
210
|
-
setattr(holderClass, 'testFiles', {})
|
211
|
+
finalPropList = properties + [proxyTestFileName]
|
211
212
|
syncAsync = 'async' if not is_synchronous else 'sync'
|
212
|
-
for
|
213
|
-
name =
|
214
|
-
|
215
|
-
|
216
|
-
|
213
|
+
for i in range(0, len(finalPropList)):
|
214
|
+
name = finalPropList[i]
|
215
|
+
name_snake_case = convert_to_snake_case(name)
|
216
|
+
filePathWithExt = DIR_NAME + '/' + syncAsync + '/test_' + name_snake_case + '.py'
|
217
|
+
if (io_file_exists (filePathWithExt)):
|
218
|
+
imp = importlib.import_module('ccxt.test.' + syncAsync + '.test_' + name_snake_case)
|
219
|
+
holderClass.test_files[name] = imp # getattr(imp, finalName)
|
217
220
|
|
218
221
|
|
219
222
|
async def close(exchange):
|
@@ -243,18 +246,18 @@ class testMainClass(baseMainTestClass):
|
|
243
246
|
self.private_test_only = get_cli_arg_value('--privateOnly')
|
244
247
|
self.sandbox = get_cli_arg_value('--sandbox')
|
245
248
|
|
246
|
-
async def init(self, exchange_id,
|
249
|
+
async def init(self, exchange_id, symbol_argv):
|
247
250
|
self.parse_cli_args()
|
248
251
|
if self.response_tests:
|
249
|
-
await self.run_static_response_tests(exchange_id,
|
252
|
+
await self.run_static_response_tests(exchange_id, symbol_argv)
|
250
253
|
return
|
251
254
|
if self.request_tests:
|
252
|
-
await self.run_static_request_tests(exchange_id,
|
255
|
+
await self.run_static_request_tests(exchange_id, symbol_argv) # symbol here is the testname
|
253
256
|
return
|
254
257
|
if self.id_tests:
|
255
258
|
await self.run_broker_id_tests()
|
256
259
|
return
|
257
|
-
symbol_str =
|
260
|
+
symbol_str = symbol_argv if symbol_argv is not None else 'all'
|
258
261
|
dump('\nTESTING ', self.ext, {
|
259
262
|
'exchange': exchange_id,
|
260
263
|
'symbol': symbol_str,
|
@@ -267,8 +270,25 @@ class testMainClass(baseMainTestClass):
|
|
267
270
|
}
|
268
271
|
exchange = init_exchange(exchange_id, exchange_args)
|
269
272
|
await self.import_files(exchange)
|
270
|
-
self.expand_settings(exchange
|
271
|
-
|
273
|
+
self.expand_settings(exchange)
|
274
|
+
symbol_or_undefined = self.check_if_specific_test_is_chosen(symbol_argv)
|
275
|
+
await self.start_test(exchange, symbol_or_undefined)
|
276
|
+
|
277
|
+
def check_if_specific_test_is_chosen(self, symbol_argv):
|
278
|
+
if symbol_argv is not None:
|
279
|
+
test_file_names = list(self.test_files.keys())
|
280
|
+
possible_method_names = symbol_argv.split(',') # i.e. `test.ts binance fetchBalance,fetchDeposits`
|
281
|
+
if len(possible_method_names) >= 1:
|
282
|
+
for i in range(0, len(test_file_names)):
|
283
|
+
test_file_name = test_file_names[i]
|
284
|
+
for j in range(0, len(possible_method_names)):
|
285
|
+
method_name = possible_method_names[j]
|
286
|
+
if test_file_name == method_name:
|
287
|
+
self.only_specific_tests.append(test_file_name)
|
288
|
+
# if method names were found, then remove them from symbolArgv
|
289
|
+
if len(self.only_specific_tests) > 0:
|
290
|
+
return None
|
291
|
+
return symbol_argv
|
272
292
|
|
273
293
|
async def import_files(self, exchange):
|
274
294
|
# exchange tests
|
@@ -277,7 +297,7 @@ class testMainClass(baseMainTestClass):
|
|
277
297
|
properties.append('loadMarkets')
|
278
298
|
await set_test_files(self, properties)
|
279
299
|
|
280
|
-
def expand_settings(self, exchange
|
300
|
+
def expand_settings(self, exchange):
|
281
301
|
exchange_id = exchange.id
|
282
302
|
keys_global = self.root_dir + 'keys.json'
|
283
303
|
keys_local = self.root_dir + 'keys.local.json'
|
@@ -343,7 +363,9 @@ class testMainClass(baseMainTestClass):
|
|
343
363
|
skip_message = None
|
344
364
|
is_proxy_test = method_name == self.proxy_test_file_name
|
345
365
|
supported_by_exchange = (method_name in exchange.has) and exchange.has[method_name]
|
346
|
-
if not is_load_markets and
|
366
|
+
if not is_load_markets and (len(self.only_specific_tests) > 0 and not exchange.in_array(method_name_in_test, self.only_specific_tests)):
|
367
|
+
skip_message = '[INFO:IGNORED_TEST]'
|
368
|
+
elif not is_load_markets and not supported_by_exchange and not is_proxy_test:
|
347
369
|
skip_message = '[INFO:UNSUPPORTED_TEST]' # keep it aligned with the longest message
|
348
370
|
elif (method_name in self.skipped_methods) and (isinstance(self.skipped_methods[method_name], str)):
|
349
371
|
skip_message = '[INFO:SKIPPED_TEST]'
|
@@ -458,7 +480,7 @@ class testMainClass(baseMainTestClass):
|
|
458
480
|
errors.append(test_names[i])
|
459
481
|
# we don't throw exception for public-tests, see comments under 'testSafe' method
|
460
482
|
errors_in_message = ''
|
461
|
-
if errors:
|
483
|
+
if len(errors):
|
462
484
|
failed_msg = ', '.join(errors)
|
463
485
|
errors_in_message = ' | Failed methods : ' + failed_msg
|
464
486
|
message_content = '[INFO:PUBLIC_TESTS_END] ' + market['type'] + errors_in_message
|
@@ -576,12 +598,12 @@ class testMainClass(baseMainTestClass):
|
|
576
598
|
if not self.private_test_only:
|
577
599
|
if exchange.has['spot'] and spot_symbol is not None:
|
578
600
|
if self.info:
|
579
|
-
dump('[INFO:SPOT TESTS]')
|
601
|
+
dump('[INFO: ### SPOT TESTS ###]')
|
580
602
|
exchange.options['type'] = 'spot'
|
581
603
|
await self.run_public_tests(exchange, spot_symbol)
|
582
604
|
if exchange.has['swap'] and swap_symbol is not None:
|
583
605
|
if self.info:
|
584
|
-
dump('[INFO:SWAP TESTS]')
|
606
|
+
dump('[INFO: ### SWAP TESTS ###]')
|
585
607
|
exchange.options['type'] = 'swap'
|
586
608
|
await self.run_public_tests(exchange, swap_symbol)
|
587
609
|
if self.private_test or self.private_test_only:
|
ccxt/test/test_sync.py
CHANGED
@@ -8,14 +8,13 @@ import sys
|
|
8
8
|
from traceback import format_tb, format_exception
|
9
9
|
|
10
10
|
import importlib # noqa: E402
|
11
|
-
import glob # noqa: E402
|
12
11
|
import re
|
13
12
|
|
14
13
|
# ------------------------------------------------------------------------------
|
15
14
|
# logging.basicConfig(level=logging.INFO)
|
16
15
|
# ------------------------------------------------------------------------------
|
17
|
-
|
18
|
-
root = os.path.dirname(os.path.dirname(
|
16
|
+
DIR_NAME = os.path.dirname(os.path.abspath(__file__))
|
17
|
+
root = os.path.dirname(os.path.dirname(DIR_NAME))
|
19
18
|
sys.path.append(root)
|
20
19
|
|
21
20
|
import ccxt # noqa: E402
|
@@ -95,8 +94,8 @@ sys.excepthook = handle_all_unhandled_exceptions
|
|
95
94
|
|
96
95
|
is_synchronous = 'async' not in os.path.basename(__file__)
|
97
96
|
|
98
|
-
rootDir =
|
99
|
-
rootDirForSkips =
|
97
|
+
rootDir = DIR_NAME + '/../../../'
|
98
|
+
rootDirForSkips = DIR_NAME + '/../../../'
|
100
99
|
envVars = os.environ
|
101
100
|
LOG_CHARS_LENGTH = 10000
|
102
101
|
ext = 'py'
|
@@ -116,6 +115,7 @@ class baseMainTestClass():
|
|
116
115
|
env_vars = envVars
|
117
116
|
ext = ext
|
118
117
|
root_dir_for_skips = rootDirForSkips
|
118
|
+
only_specific_tests = []
|
119
119
|
proxy_test_file_name = proxyTestFileName
|
120
120
|
pass
|
121
121
|
|
@@ -140,12 +140,12 @@ def get_cli_arg_value(arg):
|
|
140
140
|
arg_exists_wo_hyphen = getattr(argv, without_hyphen) if hasattr(argv, without_hyphen) else False
|
141
141
|
return arg_exists or arg_exists_with_hyphen or arg_exists_wo_hyphen
|
142
142
|
|
143
|
+
def convert_to_snake_case(conent):
|
144
|
+
return re.sub(r'(?<!^)(?=[A-Z])', '_', conent).lower()
|
143
145
|
|
144
146
|
def get_test_name(methodName):
|
145
|
-
|
146
|
-
|
147
|
-
full_name = 'test_' + snake_cased
|
148
|
-
return full_name
|
147
|
+
# stub
|
148
|
+
return methodName
|
149
149
|
|
150
150
|
|
151
151
|
def io_file_exists(path):
|
@@ -165,8 +165,10 @@ def io_dir_read(path):
|
|
165
165
|
return os.listdir(path)
|
166
166
|
|
167
167
|
|
168
|
-
def call_method(
|
169
|
-
|
168
|
+
def call_method(test_files, methodName, exchange, skippedProperties, args):
|
169
|
+
methodNameToCall = convert_to_snake_case(methodName)
|
170
|
+
methodNameToCall = 'test_' + methodNameToCall.replace('o_h_l_c_v', 'ohlcv')
|
171
|
+
return getattr(test_files[methodName], methodNameToCall)(exchange, skippedProperties, *args)
|
170
172
|
|
171
173
|
|
172
174
|
def call_exchange_method_dynamically(exchange, methodName, args):
|
@@ -205,14 +207,15 @@ def init_exchange(exchangeId, args):
|
|
205
207
|
|
206
208
|
|
207
209
|
def set_test_files(holderClass, properties):
|
208
|
-
|
209
|
-
setattr(holderClass, 'testFiles', {})
|
210
|
+
finalPropList = properties + [proxyTestFileName]
|
210
211
|
syncAsync = 'async' if not is_synchronous else 'sync'
|
211
|
-
for
|
212
|
-
name =
|
213
|
-
|
214
|
-
|
215
|
-
|
212
|
+
for i in range(0, len(finalPropList)):
|
213
|
+
name = finalPropList[i]
|
214
|
+
name_snake_case = convert_to_snake_case(name)
|
215
|
+
filePathWithExt = DIR_NAME + '/' + syncAsync + '/test_' + name_snake_case + '.py'
|
216
|
+
if (io_file_exists (filePathWithExt)):
|
217
|
+
imp = importlib.import_module('ccxt.test.' + syncAsync + '.test_' + name_snake_case)
|
218
|
+
holderClass.test_files[name] = imp # getattr(imp, finalName)
|
216
219
|
|
217
220
|
|
218
221
|
def close(exchange):
|
@@ -242,18 +245,18 @@ class testMainClass(baseMainTestClass):
|
|
242
245
|
self.private_test_only = get_cli_arg_value('--privateOnly')
|
243
246
|
self.sandbox = get_cli_arg_value('--sandbox')
|
244
247
|
|
245
|
-
def init(self, exchange_id,
|
248
|
+
def init(self, exchange_id, symbol_argv):
|
246
249
|
self.parse_cli_args()
|
247
250
|
if self.response_tests:
|
248
|
-
self.run_static_response_tests(exchange_id,
|
251
|
+
self.run_static_response_tests(exchange_id, symbol_argv)
|
249
252
|
return
|
250
253
|
if self.request_tests:
|
251
|
-
self.run_static_request_tests(exchange_id,
|
254
|
+
self.run_static_request_tests(exchange_id, symbol_argv) # symbol here is the testname
|
252
255
|
return
|
253
256
|
if self.id_tests:
|
254
257
|
self.run_broker_id_tests()
|
255
258
|
return
|
256
|
-
symbol_str =
|
259
|
+
symbol_str = symbol_argv if symbol_argv is not None else 'all'
|
257
260
|
dump('\nTESTING ', self.ext, {
|
258
261
|
'exchange': exchange_id,
|
259
262
|
'symbol': symbol_str,
|
@@ -266,8 +269,25 @@ class testMainClass(baseMainTestClass):
|
|
266
269
|
}
|
267
270
|
exchange = init_exchange(exchange_id, exchange_args)
|
268
271
|
self.import_files(exchange)
|
269
|
-
self.expand_settings(exchange
|
270
|
-
self.
|
272
|
+
self.expand_settings(exchange)
|
273
|
+
symbol_or_undefined = self.check_if_specific_test_is_chosen(symbol_argv)
|
274
|
+
self.start_test(exchange, symbol_or_undefined)
|
275
|
+
|
276
|
+
def check_if_specific_test_is_chosen(self, symbol_argv):
|
277
|
+
if symbol_argv is not None:
|
278
|
+
test_file_names = list(self.test_files.keys())
|
279
|
+
possible_method_names = symbol_argv.split(',') # i.e. `test.ts binance fetchBalance,fetchDeposits`
|
280
|
+
if len(possible_method_names) >= 1:
|
281
|
+
for i in range(0, len(test_file_names)):
|
282
|
+
test_file_name = test_file_names[i]
|
283
|
+
for j in range(0, len(possible_method_names)):
|
284
|
+
method_name = possible_method_names[j]
|
285
|
+
if test_file_name == method_name:
|
286
|
+
self.only_specific_tests.append(test_file_name)
|
287
|
+
# if method names were found, then remove them from symbolArgv
|
288
|
+
if len(self.only_specific_tests) > 0:
|
289
|
+
return None
|
290
|
+
return symbol_argv
|
271
291
|
|
272
292
|
def import_files(self, exchange):
|
273
293
|
# exchange tests
|
@@ -276,7 +296,7 @@ class testMainClass(baseMainTestClass):
|
|
276
296
|
properties.append('loadMarkets')
|
277
297
|
set_test_files(self, properties)
|
278
298
|
|
279
|
-
def expand_settings(self, exchange
|
299
|
+
def expand_settings(self, exchange):
|
280
300
|
exchange_id = exchange.id
|
281
301
|
keys_global = self.root_dir + 'keys.json'
|
282
302
|
keys_local = self.root_dir + 'keys.local.json'
|
@@ -342,7 +362,9 @@ class testMainClass(baseMainTestClass):
|
|
342
362
|
skip_message = None
|
343
363
|
is_proxy_test = method_name == self.proxy_test_file_name
|
344
364
|
supported_by_exchange = (method_name in exchange.has) and exchange.has[method_name]
|
345
|
-
if not is_load_markets and
|
365
|
+
if not is_load_markets and (len(self.only_specific_tests) > 0 and not exchange.in_array(method_name_in_test, self.only_specific_tests)):
|
366
|
+
skip_message = '[INFO:IGNORED_TEST]'
|
367
|
+
elif not is_load_markets and not supported_by_exchange and not is_proxy_test:
|
346
368
|
skip_message = '[INFO:UNSUPPORTED_TEST]' # keep it aligned with the longest message
|
347
369
|
elif (method_name in self.skipped_methods) and (isinstance(self.skipped_methods[method_name], str)):
|
348
370
|
skip_message = '[INFO:SKIPPED_TEST]'
|
@@ -457,7 +479,7 @@ class testMainClass(baseMainTestClass):
|
|
457
479
|
errors.append(test_names[i])
|
458
480
|
# we don't throw exception for public-tests, see comments under 'testSafe' method
|
459
481
|
errors_in_message = ''
|
460
|
-
if errors:
|
482
|
+
if len(errors):
|
461
483
|
failed_msg = ', '.join(errors)
|
462
484
|
errors_in_message = ' | Failed methods : ' + failed_msg
|
463
485
|
message_content = '[INFO:PUBLIC_TESTS_END] ' + market['type'] + errors_in_message
|
@@ -575,12 +597,12 @@ class testMainClass(baseMainTestClass):
|
|
575
597
|
if not self.private_test_only:
|
576
598
|
if exchange.has['spot'] and spot_symbol is not None:
|
577
599
|
if self.info:
|
578
|
-
dump('[INFO:SPOT TESTS]')
|
600
|
+
dump('[INFO: ### SPOT TESTS ###]')
|
579
601
|
exchange.options['type'] = 'spot'
|
580
602
|
self.run_public_tests(exchange, spot_symbol)
|
581
603
|
if exchange.has['swap'] and swap_symbol is not None:
|
582
604
|
if self.info:
|
583
|
-
dump('[INFO:SWAP TESTS]')
|
605
|
+
dump('[INFO: ### SWAP TESTS ###]')
|
584
606
|
exchange.options['type'] = 'swap'
|
585
607
|
self.run_public_tests(exchange, swap_symbol)
|
586
608
|
if self.private_test or self.private_test_only:
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: ccxt
|
3
|
-
Version: 4.1.
|
3
|
+
Version: 4.1.70
|
4
4
|
Summary: A JavaScript / TypeScript / Python / C# / PHP cryptocurrency trading library with support for 130+ exchanges
|
5
5
|
Home-page: https://ccxt.com
|
6
6
|
Author: Igor Kroitor
|
@@ -41,9 +41,9 @@ Requires-Dist: typing-extensions >=4.4.0
|
|
41
41
|
Requires-Dist: aiohttp >=3.8 ; python_version>="3.5.2"
|
42
42
|
Requires-Dist: aiodns >=1.1.1 ; python_version>="3.5.2"
|
43
43
|
Requires-Dist: yarl >=1.7.2 ; python_version>="3.5.2"
|
44
|
-
Requires-Dist: tox >=4.8.0 ; python_version>="3.5.2"
|
45
44
|
Provides-Extra: qa
|
46
45
|
Requires-Dist: ruff ==0.0.292 ; extra == 'qa'
|
46
|
+
Requires-Dist: tox >=4.8.0 ; extra == 'qa'
|
47
47
|
Provides-Extra: type
|
48
48
|
Requires-Dist: mypy ==1.6.1 ; extra == 'type'
|
49
49
|
|
@@ -260,13 +260,13 @@ console.log(version, Object.keys(exchanges));
|
|
260
260
|
|
261
261
|
All-in-one browser bundle (dependencies included), served from a CDN of your choice:
|
262
262
|
|
263
|
-
* jsDelivr: https://cdn.jsdelivr.net/npm/ccxt@4.1.
|
264
|
-
* unpkg: https://unpkg.com/ccxt@4.1.
|
263
|
+
* jsDelivr: https://cdn.jsdelivr.net/npm/ccxt@4.1.70/dist/ccxt.browser.js
|
264
|
+
* unpkg: https://unpkg.com/ccxt@4.1.70/dist/ccxt.browser.js
|
265
265
|
|
266
266
|
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.
|
267
267
|
|
268
268
|
```HTML
|
269
|
-
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/ccxt@4.1.
|
269
|
+
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/ccxt@4.1.70/dist/ccxt.browser.js"></script>
|
270
270
|
```
|
271
271
|
|
272
272
|
Creates a global `ccxt` object:
|
@@ -1,7 +1,7 @@
|
|
1
|
-
ccxt/__init__.py,sha256=
|
1
|
+
ccxt/__init__.py,sha256=O0y7MONwUqyB-0mNdz5qSEJv4PRykG9GoGfWaEMTK10,15177
|
2
2
|
ccxt/ace.py,sha256=BWWFoSfDar1k8SuqIuupgs8BLfZyu8w6BEdGZxWVR7M,41264
|
3
3
|
ccxt/alpaca.py,sha256=4MSi6SDyes3lNvGKmWgXWEIB2CacwfbVdhLxchv3m7k,45944
|
4
|
-
ccxt/ascendex.py,sha256=
|
4
|
+
ccxt/ascendex.py,sha256=EQjZX2RRa2vBCIPnKsfaRpam9MCEGHe_zWOwMkGJ_b0,143331
|
5
5
|
ccxt/bequant.py,sha256=O9tDvk7O1De-k3-G5lwXUVoNqzgfo_AJqQy4bXifdhM,1148
|
6
6
|
ccxt/bigone.py,sha256=TEtUsu2EeXyqfxCYsSkNjFV6QqfkxirJWWvL_UxIVtc,78006
|
7
7
|
ccxt/binance.py,sha256=fT5SUUKUC-4qlQlnjYF_1kQE8z1me99pVbgCmJU6YRU,443977
|
@@ -41,7 +41,7 @@ ccxt/coinbase.py,sha256=yAJr50ql9Jg84dubNvHxdjRRXbTwFYIzwCvezeeDJzE,143324
|
|
41
41
|
ccxt/coinbaseprime.py,sha256=Ygvljulxb2uKdei5yimCj1LMjLlUJNvP-G7ns1HpUFk,1219
|
42
42
|
ccxt/coinbasepro.py,sha256=gpe6UVg4pDDpvzjVGE_fKeoDmkdIyzNucANptY9FeH8,80087
|
43
43
|
ccxt/coincheck.py,sha256=91mcnxBYEpaEjqb-q_jvWSfient50_dLncnpXISNrdA,34543
|
44
|
-
ccxt/coinex.py,sha256=
|
44
|
+
ccxt/coinex.py,sha256=DxautcoxydR21ywuliVwn1kNKu0xYbBKLNmNrMoz9I8,214363
|
45
45
|
ccxt/coinlist.py,sha256=WxUtdebmVD5so6vtldeHXUhpuh_cxGt3EKGu4vKPBFM,102150
|
46
46
|
ccxt/coinmate.py,sha256=1Qd8MQ0gxL4ppjxkuwIP-TSiQJWNK6dhEFZA8tDzoVg,39870
|
47
47
|
ccxt/coinone.py,sha256=4YZVII8t-87KJ6PQ85qxVNzXnTe7Ga-2jOaBpJ9YC1g,35624
|
@@ -89,7 +89,7 @@ ccxt/okex5.py,sha256=LKTogVF1svNkqW_-Cx0AuAopu6esgFf7ucbv7CaodUg,441
|
|
89
89
|
ccxt/okx.py,sha256=teHKeR7ITAsua4qhk0wVHGBM8tUNWhXSbID1-QumiEU,319639
|
90
90
|
ccxt/p2b.py,sha256=bu993TUzBslB-oqTP4NMpDCx-n3RL_0OpPJ1jXfn7vw,53959
|
91
91
|
ccxt/paymium.py,sha256=oH4zQkMF7IGkq9co953Riz8wuhUj6xxKSmqs7Rz2n1s,24122
|
92
|
-
ccxt/phemex.py,sha256=
|
92
|
+
ccxt/phemex.py,sha256=LgkusilxAEpZazFkIaiUbRX4RF4hOMHlpYctVtqZQ1Q,205280
|
93
93
|
ccxt/poloniex.py,sha256=7CoIT_QfNoOmV2peGpW7B1yWrFmzMVnF9ZP4Q_9OjUE,99892
|
94
94
|
ccxt/poloniexfutures.py,sha256=T35rN-4OvNbTHmDgZCIpSclK8jophgbeVoVi4At0vv4,76628
|
95
95
|
ccxt/probit.py,sha256=NsvDUgQNLeebwgyrMxGSrwoEXdPnJia5lb8WBpFfLa8,75384
|
@@ -190,7 +190,7 @@ ccxt/abstract/okcoin.py,sha256=3NmYh-68W_4AXmkqjkf9dRaJcPgNYQG5mKZssJKT4gs,9414
|
|
190
190
|
ccxt/abstract/okx.py,sha256=8m9UMSrPPI-E9_LQ7puVhU6qwnISthb_yNFINd8sMco,40707
|
191
191
|
ccxt/abstract/p2b.py,sha256=XwaH1hLIi2T6RHltUwFj28Y5fbo6dc0jbjI01sVeOJw,2054
|
192
192
|
ccxt/abstract/paymium.py,sha256=Bol6PEkHg_47betqBnL4aQQ4IhIp4owID_12VfDqn0E,2843
|
193
|
-
ccxt/abstract/phemex.py,sha256=
|
193
|
+
ccxt/abstract/phemex.py,sha256=9zBDpowV_XBT4KJAnwueclMHnvO7lq3LhIwIRcj74Cs,14918
|
194
194
|
ccxt/abstract/poloniex.py,sha256=dtTdTobCR2mMhCKJRqSxa1bjl9T94QiF0y31RoaqR_Y,8073
|
195
195
|
ccxt/abstract/poloniexfutures.py,sha256=MlPqv9DdaJn9U4eW1MYjzwtL2WI_EEaYT6607hGI4SA,5219
|
196
196
|
ccxt/abstract/probit.py,sha256=PxQkrvv3EQ2TvOxJmc_mAF_aH8xFFw6pZaVVjjUo5_4,1969
|
@@ -205,10 +205,10 @@ ccxt/abstract/woo.py,sha256=Z3ua45hKE0Tf9rtfSEYYgGEztaTO1Ri3mKl_hIo3OHs,8768
|
|
205
205
|
ccxt/abstract/yobit.py,sha256=8ycfCO8ORFly9hc0Aa47sZyX4_ZKPXS9h9yJzI-uQ7Q,1339
|
206
206
|
ccxt/abstract/zaif.py,sha256=m15WHdl3gYy0GOXNZ8NEH8eE7sVh8c0T_ITNuU8vXeU,3935
|
207
207
|
ccxt/abstract/zonda.py,sha256=aSfewvRojzmuymX6QbOnDR8v9VFqWTULMHX9Y7kKD1M,5820
|
208
|
-
ccxt/async_support/__init__.py,sha256=
|
208
|
+
ccxt/async_support/__init__.py,sha256=3GyP00xgtbGUi-ipamiwlIFRYX729fSIGxjPuc0hmvM,14900
|
209
209
|
ccxt/async_support/ace.py,sha256=H3BMrCEUPt86k1nFZnuTbcGPtgzzTii5V0OQeRK8x4U,41488
|
210
210
|
ccxt/async_support/alpaca.py,sha256=q8s3omyklOv0grJ6kDJxmPkt9kqKHwes_fuYkP_Nhf8,46156
|
211
|
-
ccxt/async_support/ascendex.py,sha256=
|
211
|
+
ccxt/async_support/ascendex.py,sha256=GHeezJpE30VFKhVC-AKtLM5GJsGav0nNgCrvlRkN5gE,144071
|
212
212
|
ccxt/async_support/bequant.py,sha256=kLA0e9URC1rDEHgpb61pEGAn5jZXzE715lEcJjPdLRo,1162
|
213
213
|
ccxt/async_support/bigone.py,sha256=tgVK927gt7hDabpZyt-Sf72fJSHjyBc4IOUGrugcvUo,78392
|
214
214
|
ccxt/async_support/binance.py,sha256=2xdLK07rdyZNAz8mNBXOOoMN2YUYq94lkX-K9C0Nlhk,445523
|
@@ -248,7 +248,7 @@ ccxt/async_support/coinbase.py,sha256=-GQCGYqy2YX36VTpIcBJZZEajnHBtSfnsTxp4EzysZ
|
|
248
248
|
ccxt/async_support/coinbaseprime.py,sha256=M5Ez1DsFcW3-vJ-4QoZzwYBAKjAAtJnJpkfnV4sWAIc,1233
|
249
249
|
ccxt/async_support/coinbasepro.py,sha256=yfHm6Hx0afMSogFlNLtKPc38YPip1l211285XYewRfk,80611
|
250
250
|
ccxt/async_support/coincheck.py,sha256=tfdumxzqeQxLYtaEsYv1EtkVHySxF_6-79EftZvQcZQ,34749
|
251
|
-
ccxt/async_support/coinex.py,sha256=
|
251
|
+
ccxt/async_support/coinex.py,sha256=GqoGMD1pWqh7UQJvDXX_Hn8nSwjBu93QuP_AoJQbH2I,215399
|
252
252
|
ccxt/async_support/coinlist.py,sha256=l5ufcRAEA7la3Xpliuwocvv09wDF-51u5hZTBI5Gvso,102638
|
253
253
|
ccxt/async_support/coinmate.py,sha256=hGCkulm5wiQBNW8ZbMXRunEMruQ7rv2rqxQBH_fGRn4,40118
|
254
254
|
ccxt/async_support/coinone.py,sha256=W3Bx0IZ92dhtc5Ugx9n3PSyjhx7flBjcN_FIPy0auOc,35848
|
@@ -296,7 +296,7 @@ ccxt/async_support/okex5.py,sha256=tq41tKx06j3DDO9pu9iKInpjayVprbobVNTK8qb7hoM,4
|
|
296
296
|
ccxt/async_support/okx.py,sha256=jVoH70QXbIwk6niwx4QtgmwNPeBw2NdV1UtVdnFa8Og,320902
|
297
297
|
ccxt/async_support/p2b.py,sha256=6I0BuZ9MCCg4oTMvme2jxorr5bMmK4JzxFsNz5H_mro,54201
|
298
298
|
ccxt/async_support/paymium.py,sha256=ytSECSpo34-Uz_AcKYmcXgfewmymtBEspkHlVyHLPAE,24310
|
299
|
-
ccxt/async_support/phemex.py,sha256=
|
299
|
+
ccxt/async_support/phemex.py,sha256=bwvM7vG3aQ4aWYa07LnOyvaopaRS94rXp9dmz6XmQiI,206062
|
300
300
|
ccxt/async_support/poloniex.py,sha256=KmRrciU8w7WGh-Em__yp1vvBPCQ8KxElFwPBCQiUR5M,100440
|
301
301
|
ccxt/async_support/poloniexfutures.py,sha256=MhEvZecnoy95lgv1kex4O-WkM3X2xqM-MZwqgoiKlf0,76996
|
302
302
|
ccxt/async_support/probit.py,sha256=o6gmdu5lH4VGKH9P_OjRo2QiYt-NsEsRibWsxmnAqZ4,75776
|
@@ -312,7 +312,7 @@ ccxt/async_support/yobit.py,sha256=Sr_o0G6zpBB2YHRClnD6FUzPBW74cukKl-cvjILW7YQ,5
|
|
312
312
|
ccxt/async_support/zaif.py,sha256=-YCjZLw87m9m-JXxUCr6AEC8KfnNX8b7IVSv5caW3QQ,28158
|
313
313
|
ccxt/async_support/zonda.py,sha256=DSrmvHZ4_uAwRzQQl_C6KGy3UK2kaTjJVohNg0SNbPQ,80592
|
314
314
|
ccxt/async_support/base/__init__.py,sha256=aVYSsFi--b4InRs9zDN_wtCpj8odosAB726JdUHavrk,67
|
315
|
-
ccxt/async_support/base/exchange.py,sha256=
|
315
|
+
ccxt/async_support/base/exchange.py,sha256=Ct3l0hbkEOKf6uIQU6BFPTjNdaZFuBjgiottvj5t2ZY,67412
|
316
316
|
ccxt/async_support/base/throttler.py,sha256=tvDVcdRUVYi8fZRlEcnqtgzcgB_KMUMRs5Pu8tuU-tU,1847
|
317
317
|
ccxt/async_support/base/ws/__init__.py,sha256=uockzpLuwntKGZbs5EOWFe-Zg-k6Cj7GhNJLc_RX0so,1791
|
318
318
|
ccxt/async_support/base/ws/aiohttp_client.py,sha256=_qjsl_x-rd88QmzQeGVWovMDK0XoD3f4m5GHqxZRajs,5203
|
@@ -326,14 +326,14 @@ ccxt/async_support/base/ws/order_book_side.py,sha256=Pxrq22nCODckJ6G1OXkYEmUunIu
|
|
326
326
|
ccxt/base/__init__.py,sha256=eTx1OE3HJjspFUQjGm6LBhaQiMKJnXjkdP-JUXknyQ0,1320
|
327
327
|
ccxt/base/decimal_to_precision.py,sha256=fgWRBzRTtsf3r2INyS4f7WHlzgjB5YM1ekiwqD21aac,6634
|
328
328
|
ccxt/base/errors.py,sha256=1C38u76jlNGq06N_uwfw8b8FZHK8_3_90wM1rKfU_Rg,3878
|
329
|
-
ccxt/base/exchange.py,sha256=
|
329
|
+
ccxt/base/exchange.py,sha256=Juw-n3IJOp_v9FlTf0qwDtirtszQs9o7lhvSAbnubDA,213806
|
330
330
|
ccxt/base/precise.py,sha256=_xfu54sV0vWNnOfGTKRFykeuWP8mn4K1m9lk1tcllX4,8565
|
331
331
|
ccxt/base/types.py,sha256=LN8MOE5oGr8ATL6VNuMAnE9f6o2fZ9zbeLLyXLndlEk,5528
|
332
|
-
ccxt/pro/__init__.py,sha256=
|
332
|
+
ccxt/pro/__init__.py,sha256=cl52DqUszddmvLAw6R-9CQ_bN1cM_2R1qLlOC0jesg4,6376
|
333
333
|
ccxt/pro/alpaca.py,sha256=fy1mLmw4yac7DKvGPpaqEBuA8briQqaRwPbvKsKUJwY,26974
|
334
334
|
ccxt/pro/ascendex.py,sha256=GqH6QOPZfQtbAYhdB65zJ9iIMQDGsXugSyAPUsKXk40,34730
|
335
335
|
ccxt/pro/bequant.py,sha256=3IeQ0vPg-eVqPiGMfX7yqH9qtXKm1ZqocQDeLwpA8EE,1093
|
336
|
-
ccxt/pro/binance.py,sha256=
|
336
|
+
ccxt/pro/binance.py,sha256=O7skVuVN1J9bVEJgDogX2JDjXSbz8k9HQFkQQR6a7lc,125635
|
337
337
|
ccxt/pro/binancecoinm.py,sha256=vu5SUgP70T1Dax-Am3rch7ZldGrmUwxr_rI51Y38xjw,724
|
338
338
|
ccxt/pro/binanceus.py,sha256=xKL-1cOHyqlLTwLGg-DPf6g3JMM1oU2Kv708FiGJwrY,2016
|
339
339
|
ccxt/pro/binanceusdm.py,sha256=S0eT662O2ReplsihWk42nhJWqw1XsODpeDQa9eFVVt8,1357
|
@@ -366,7 +366,7 @@ ccxt/pro/gateio.py,sha256=_uBWXYQbmsHRivKnZOJDmxJ9tWLO_0HAxmOjAEUy9nE,391
|
|
366
366
|
ccxt/pro/gemini.py,sha256=ie3JT4y0hzfrsFYYYIvS0G4iFDY0htDxW2tU7xfj1pk,25316
|
367
367
|
ccxt/pro/hitbtc.py,sha256=T3oLG0n7xijlSvvRO74O1-8fPThABOAPnRC4RNQ-OY0,55498
|
368
368
|
ccxt/pro/hollaex.py,sha256=E-1TkC5DH4WQ8JATCMISuHTdtw9jxsTtyhc3OBiXWMs,21832
|
369
|
-
ccxt/pro/htx.py,sha256=
|
369
|
+
ccxt/pro/htx.py,sha256=_ppk6sk6McGMTifPEHsa2iWdD4E1wqsez-klQnAGres,95249
|
370
370
|
ccxt/pro/huobi.py,sha256=rKZVgYqEr-MmZzTqAk4FoJt8qWFjCi_FY0ci_mWZrL0,385
|
371
371
|
ccxt/pro/huobijp.py,sha256=5Qkq4C9QHTjx0rcR-fTUWW4xERyciGADq_fe4tqoyrY,23104
|
372
372
|
ccxt/pro/huobipro.py,sha256=JqLbm74WLluxAjWDAGGwY4bx8_ShCwOOqQ0476LfnHs,400
|
@@ -405,8 +405,8 @@ ccxt/static_dependencies/ecdsa/util.py,sha256=M0NQZ4dDQFTd8afSkF-7YyP9KbsXzOn-VU
|
|
405
405
|
ccxt/static_dependencies/keccak/__init__.py,sha256=mfcrTChnMXsr-JmfN2VbzscTRt9XA2RRGchfHRMYncU,45
|
406
406
|
ccxt/static_dependencies/keccak/keccak.py,sha256=RblmQEQkGpMhug0EU3hyE0kBjs1NDfGQqbwrBK7ZycY,6934
|
407
407
|
ccxt/test/__init__.py,sha256=GKPbEcj0Rrz5HG-GUm-iY1IHhDYmlvcBXZAGk6-m2CI,141
|
408
|
-
ccxt/test/test_async.py,sha256=
|
409
|
-
ccxt/test/test_sync.py,sha256=
|
408
|
+
ccxt/test/test_async.py,sha256=sGKqVszbW7otxNCQDWthzHdfYZYl13SdsCO0Or9Zehs,61279
|
409
|
+
ccxt/test/test_sync.py,sha256=oHtrUySxpeIdASaIaVinA2SbbywNNO-2yK1jzlYkwYQ,60377
|
410
410
|
ccxt/test/base/__init__.py,sha256=hQPmjR9gxzFFd-nZRo-ICCD89Yk4hoQjQSnEKGHvhVM,1745
|
411
411
|
ccxt/test/base/test_account.py,sha256=aPhLDxPTaK51x-a72mmjXHNPnrk8NvOGqJju2fzATfA,980
|
412
412
|
ccxt/test/base/test_balance.py,sha256=x_IJFoQW9bkXNqL7ueLFyCHOvhxKp4ZRqe0y-6AhXVI,2616
|
@@ -439,7 +439,7 @@ ccxt/test/base/test_ticker.py,sha256=5J8KHgFhJLgcWyFwt3bhJ-tldMho3K7LD5yJnnUyrT4
|
|
439
439
|
ccxt/test/base/test_trade.py,sha256=AN3emAdEPhdFyunap43cKqZTS1cbaShZKTjYue67jEU,2297
|
440
440
|
ccxt/test/base/test_trading_fee.py,sha256=2_WCp3qJ2UpraQQoGFlGJYwHD-T0Bm5W7KIw4zpFvSM,1068
|
441
441
|
ccxt/test/base/test_transaction.py,sha256=BTbB4UHHXkrvYgwbrhh867nVRlevmIkIrz1W_odlQJI,1434
|
442
|
-
ccxt-4.1.
|
443
|
-
ccxt-4.1.
|
444
|
-
ccxt-4.1.
|
445
|
-
ccxt-4.1.
|
442
|
+
ccxt-4.1.70.dist-info/METADATA,sha256=KucSPgIlXfXu9FLUC64s2HfQPymRSJ5rKCFTxpzDfoo,106775
|
443
|
+
ccxt-4.1.70.dist-info/WHEEL,sha256=P2T-6epvtXQ2cBOE_U1K4_noqlJFN3tj15djMgEu4NM,110
|
444
|
+
ccxt-4.1.70.dist-info/top_level.txt,sha256=CkQDuCTDKNcImPV60t36G6MdYfxsAPNiSaEwifVoVMo,5
|
445
|
+
ccxt-4.1.70.dist-info/RECORD,,
|
File without changes
|
File without changes
|