ccxt 4.4.51__py2.py3-none-any.whl → 4.4.53__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 +0 -1
- ccxt/abstract/binancecoinm.py +0 -1
- ccxt/abstract/binanceus.py +0 -1
- ccxt/abstract/binanceusdm.py +0 -1
- ccxt/ace.py +3 -0
- ccxt/alpaca.py +5 -0
- ccxt/ascendex.py +2 -1
- ccxt/async_support/__init__.py +1 -1
- ccxt/async_support/ace.py +3 -0
- ccxt/async_support/alpaca.py +5 -0
- ccxt/async_support/ascendex.py +2 -1
- ccxt/async_support/base/exchange.py +20 -3
- ccxt/async_support/bigone.py +5 -0
- ccxt/async_support/binance.py +55 -69
- ccxt/async_support/bingx.py +25 -29
- ccxt/async_support/bit2c.py +3 -0
- ccxt/async_support/bitbank.py +3 -0
- ccxt/async_support/bitbns.py +3 -0
- ccxt/async_support/bitfinex.py +6 -1
- ccxt/async_support/bitflyer.py +6 -1
- ccxt/async_support/bitget.py +8 -4
- ccxt/async_support/bithumb.py +3 -1
- ccxt/async_support/bitmart.py +22 -12
- ccxt/async_support/bitmex.py +99 -93
- ccxt/async_support/bitopro.py +7 -2
- ccxt/async_support/bitrue.py +4 -0
- ccxt/async_support/bitso.py +5 -2
- ccxt/async_support/bitstamp.py +3 -0
- ccxt/async_support/bitteam.py +5 -0
- ccxt/async_support/bitvavo.py +4 -0
- ccxt/async_support/blockchaincom.py +4 -0
- ccxt/async_support/blofin.py +3 -0
- ccxt/async_support/btcalpha.py +5 -0
- ccxt/async_support/btcbox.py +3 -2
- ccxt/async_support/btcmarkets.py +5 -0
- ccxt/async_support/btcturk.py +3 -0
- ccxt/async_support/bybit.py +10 -4
- ccxt/async_support/cex.py +2 -0
- ccxt/async_support/coinbase.py +19 -12
- ccxt/async_support/coinbaseexchange.py +5 -0
- ccxt/async_support/coinbaseinternational.py +21 -2
- ccxt/async_support/coincatch.py +3 -0
- ccxt/async_support/coincheck.py +2 -0
- ccxt/async_support/coinex.py +5 -1
- ccxt/async_support/coinlist.py +5 -0
- ccxt/async_support/coinmate.py +4 -0
- ccxt/async_support/coinmetro.py +9 -5
- ccxt/async_support/coinone.py +3 -0
- ccxt/async_support/coinsph.py +4 -0
- ccxt/async_support/coinspot.py +1 -0
- ccxt/async_support/cryptocom.py +5 -0
- ccxt/async_support/currencycom.py +3 -0
- ccxt/async_support/defx.py +5 -0
- ccxt/async_support/delta.py +4 -1
- ccxt/async_support/deribit.py +16 -5
- ccxt/async_support/digifinex.py +10 -5
- ccxt/async_support/ellipx.py +9 -5
- ccxt/async_support/exmo.py +6 -3
- ccxt/async_support/gate.py +5 -1
- ccxt/async_support/gemini.py +3 -0
- ccxt/async_support/hashkey.py +5 -4
- ccxt/async_support/hitbtc.py +6 -2
- ccxt/async_support/hollaex.py +7 -2
- ccxt/async_support/htx.py +8 -1
- ccxt/async_support/huobijp.py +5 -0
- ccxt/async_support/hyperliquid.py +6 -1
- ccxt/async_support/idex.py +5 -1
- ccxt/async_support/independentreserve.py +4 -0
- ccxt/async_support/indodax.py +3 -0
- ccxt/async_support/kraken.py +6 -4
- ccxt/async_support/krakenfutures.py +5 -2
- ccxt/async_support/kucoin.py +13 -6
- ccxt/async_support/kucoinfutures.py +5 -1
- ccxt/async_support/kuna.py +3 -0
- ccxt/async_support/latoken.py +4 -0
- ccxt/async_support/lbank.py +6 -1
- ccxt/async_support/luno.py +6 -1
- ccxt/async_support/lykke.py +4 -0
- ccxt/async_support/mercado.py +4 -0
- ccxt/async_support/mexc.py +10 -9
- ccxt/async_support/ndax.py +6 -1
- ccxt/async_support/novadax.py +5 -0
- ccxt/async_support/oceanex.py +6 -2
- ccxt/async_support/okcoin.py +4 -0
- ccxt/async_support/okx.py +17 -5
- ccxt/async_support/onetrading.py +4 -0
- ccxt/async_support/oxfun.py +3 -0
- ccxt/async_support/p2b.py +3 -0
- ccxt/async_support/paradex.py +8 -2
- ccxt/async_support/phemex.py +10 -4
- ccxt/async_support/poloniex.py +6 -3
- ccxt/async_support/poloniexfutures.py +5 -1
- ccxt/async_support/probit.py +4 -0
- ccxt/async_support/timex.py +4 -0
- ccxt/async_support/tokocrypto.py +5 -0
- ccxt/async_support/tradeogre.py +2 -0
- ccxt/async_support/upbit.py +5 -2
- ccxt/async_support/vertex.py +6 -2
- ccxt/async_support/wavesexchange.py +20 -3
- ccxt/async_support/wazirx.py +2 -0
- ccxt/async_support/whitebit.py +5 -4
- ccxt/async_support/woo.py +15 -5
- ccxt/async_support/woofipro.py +21 -7
- ccxt/async_support/xt.py +5 -0
- ccxt/async_support/yobit.py +5 -2
- ccxt/async_support/zaif.py +2 -0
- ccxt/async_support/zonda.py +2 -0
- ccxt/base/exchange.py +113 -50
- ccxt/base/types.py +1 -1
- ccxt/bigone.py +5 -0
- ccxt/binance.py +55 -69
- ccxt/bingx.py +25 -29
- ccxt/bit2c.py +3 -0
- ccxt/bitbank.py +3 -0
- ccxt/bitbns.py +3 -0
- ccxt/bitfinex.py +6 -1
- ccxt/bitflyer.py +6 -1
- ccxt/bitget.py +8 -4
- ccxt/bithumb.py +3 -1
- ccxt/bitmart.py +22 -12
- ccxt/bitmex.py +99 -93
- ccxt/bitopro.py +7 -2
- ccxt/bitrue.py +4 -0
- ccxt/bitso.py +5 -2
- ccxt/bitstamp.py +3 -0
- ccxt/bitteam.py +5 -0
- ccxt/bitvavo.py +4 -0
- ccxt/blockchaincom.py +4 -0
- ccxt/blofin.py +3 -0
- ccxt/btcalpha.py +5 -0
- ccxt/btcbox.py +3 -2
- ccxt/btcmarkets.py +5 -0
- ccxt/btcturk.py +3 -0
- ccxt/bybit.py +10 -4
- ccxt/cex.py +2 -0
- ccxt/coinbase.py +19 -12
- ccxt/coinbaseexchange.py +5 -0
- ccxt/coinbaseinternational.py +21 -2
- ccxt/coincatch.py +3 -0
- ccxt/coincheck.py +2 -0
- ccxt/coinex.py +5 -1
- ccxt/coinlist.py +5 -0
- ccxt/coinmate.py +4 -0
- ccxt/coinmetro.py +9 -5
- ccxt/coinone.py +3 -0
- ccxt/coinsph.py +4 -0
- ccxt/coinspot.py +1 -0
- ccxt/cryptocom.py +5 -0
- ccxt/currencycom.py +3 -0
- ccxt/defx.py +5 -0
- ccxt/delta.py +4 -1
- ccxt/deribit.py +16 -5
- ccxt/digifinex.py +10 -5
- ccxt/ellipx.py +9 -5
- ccxt/exmo.py +6 -3
- ccxt/gate.py +5 -1
- ccxt/gemini.py +3 -0
- ccxt/hashkey.py +5 -4
- ccxt/hitbtc.py +6 -2
- ccxt/hollaex.py +7 -2
- ccxt/htx.py +8 -1
- ccxt/huobijp.py +5 -0
- ccxt/hyperliquid.py +6 -1
- ccxt/idex.py +5 -1
- ccxt/independentreserve.py +4 -0
- ccxt/indodax.py +3 -0
- ccxt/kraken.py +6 -4
- ccxt/krakenfutures.py +5 -2
- ccxt/kucoin.py +13 -6
- ccxt/kucoinfutures.py +5 -1
- ccxt/kuna.py +3 -0
- ccxt/latoken.py +4 -0
- ccxt/lbank.py +6 -1
- ccxt/luno.py +6 -1
- ccxt/lykke.py +4 -0
- ccxt/mercado.py +4 -0
- ccxt/mexc.py +10 -9
- ccxt/ndax.py +6 -1
- ccxt/novadax.py +5 -0
- ccxt/oceanex.py +6 -2
- ccxt/okcoin.py +4 -0
- ccxt/okx.py +17 -5
- ccxt/onetrading.py +4 -0
- ccxt/oxfun.py +3 -0
- ccxt/p2b.py +3 -0
- ccxt/paradex.py +8 -2
- ccxt/phemex.py +10 -4
- ccxt/poloniex.py +6 -3
- ccxt/poloniexfutures.py +5 -1
- ccxt/pro/__init__.py +1 -1
- ccxt/pro/bitcoincom.py +1 -4
- ccxt/pro/bitopro.py +1 -1
- ccxt/probit.py +4 -0
- ccxt/test/tests_async.py +57 -31
- ccxt/test/tests_sync.py +57 -31
- ccxt/timex.py +4 -0
- ccxt/tokocrypto.py +5 -0
- ccxt/tradeogre.py +2 -0
- ccxt/upbit.py +5 -2
- ccxt/vertex.py +6 -2
- ccxt/wavesexchange.py +20 -3
- ccxt/wazirx.py +2 -0
- ccxt/whitebit.py +5 -4
- ccxt/woo.py +15 -5
- ccxt/woofipro.py +21 -7
- ccxt/xt.py +5 -0
- ccxt/yobit.py +5 -2
- ccxt/zaif.py +2 -0
- ccxt/zonda.py +2 -0
- {ccxt-4.4.51.dist-info → ccxt-4.4.53.dist-info}/METADATA +225 -140
- {ccxt-4.4.51.dist-info → ccxt-4.4.53.dist-info}/RECORD +215 -224
- ccxt/static_dependencies/ethereum/abi/py.typed +0 -0
- ccxt/static_dependencies/ethereum/account/py.typed +0 -0
- ccxt/static_dependencies/ethereum/hexbytes/py.typed +0 -0
- ccxt/static_dependencies/ethereum/typing/py.typed +0 -0
- ccxt/static_dependencies/ethereum/utils/py.typed +0 -0
- ccxt/static_dependencies/lark/py.typed +0 -0
- ccxt/static_dependencies/marshmallow/py.typed +0 -0
- ccxt/static_dependencies/marshmallow_dataclass/py.typed +0 -0
- ccxt/static_dependencies/marshmallow_oneofschema/py.typed +0 -0
- {ccxt-4.4.51.dist-info → ccxt-4.4.53.dist-info}/LICENSE.txt +0 -0
- {ccxt-4.4.51.dist-info → ccxt-4.4.53.dist-info}/WHEEL +0 -0
- {ccxt-4.4.51.dist-info → ccxt-4.4.53.dist-info}/top_level.txt +0 -0
ccxt/poloniexfutures.py
CHANGED
@@ -226,17 +226,20 @@ class poloniexfutures(Exchange, ImplicitAPI):
|
|
226
226
|
'limit': None,
|
227
227
|
'daysBack': 100000,
|
228
228
|
'untilDays': 7,
|
229
|
+
'symbolRequired': False,
|
229
230
|
},
|
230
231
|
'fetchOrder': {
|
231
232
|
'marginMode': False,
|
232
233
|
'trigger': False,
|
233
234
|
'trailing': False,
|
235
|
+
'symbolRequired': False,
|
234
236
|
},
|
235
237
|
'fetchOpenOrders': {
|
236
238
|
'marginMode': True,
|
237
239
|
'limit': None,
|
238
240
|
'trigger': False,
|
239
241
|
'trailing': False,
|
242
|
+
'symbolRequired': False,
|
240
243
|
},
|
241
244
|
'fetchOrders': None, # todo
|
242
245
|
'fetchClosedOrders': {
|
@@ -247,6 +250,7 @@ class poloniexfutures(Exchange, ImplicitAPI):
|
|
247
250
|
'untilDays': 100000,
|
248
251
|
'trigger': False,
|
249
252
|
'trailing': False,
|
253
|
+
'symbolRequired': False,
|
250
254
|
},
|
251
255
|
'fetchOHLCV': {
|
252
256
|
'limit': 200, # todo implement
|
@@ -1445,7 +1449,7 @@ class poloniexfutures(Exchange, ImplicitAPI):
|
|
1445
1449
|
"""
|
1446
1450
|
return self.fetch_orders_by_status('closed', symbol, since, limit, params)
|
1447
1451
|
|
1448
|
-
def fetch_order(self, id: Str
|
1452
|
+
def fetch_order(self, id: Str, symbol: Str = None, params={}):
|
1449
1453
|
"""
|
1450
1454
|
fetches information on an order made by the user
|
1451
1455
|
|
ccxt/pro/__init__.py
CHANGED
ccxt/pro/bitcoincom.py
CHANGED
@@ -22,10 +22,7 @@ class bitcoincom(hitbtc):
|
|
22
22
|
'urls': {
|
23
23
|
'logo': 'https://user-images.githubusercontent.com/1294454/97296144-514fa300-1861-11eb-952b-3d55d492200b.jpg',
|
24
24
|
'api': {
|
25
|
-
'ws':
|
26
|
-
'public': 'wss://api.fmfw.io/api/3/ws/public',
|
27
|
-
'private': 'wss://api.fmfw.io/api/3/ws/trading',
|
28
|
-
},
|
25
|
+
'ws': 'wss://api.fmfw.io/api/2/ws',
|
29
26
|
},
|
30
27
|
},
|
31
28
|
'fees': {
|
ccxt/pro/bitopro.py
CHANGED
@@ -77,7 +77,7 @@ class bitopro(ccxt.async_support.bitopro):
|
|
77
77
|
if limit is None:
|
78
78
|
endPart = market['id']
|
79
79
|
else:
|
80
|
-
endPart = market['id'] + ':' +
|
80
|
+
endPart = market['id'] + ':' + limit
|
81
81
|
orderbook = await self.watch_public('order-books', messageHash, endPart)
|
82
82
|
return orderbook.limit()
|
83
83
|
|
ccxt/probit.py
CHANGED
@@ -217,17 +217,20 @@ class probit(Exchange, ImplicitAPI):
|
|
217
217
|
'limit': 1000,
|
218
218
|
'daysBack': 100000, # todo
|
219
219
|
'untilDays': 100000, # todo
|
220
|
+
'symbolRequired': False,
|
220
221
|
},
|
221
222
|
'fetchOrder': {
|
222
223
|
'marginMode': False,
|
223
224
|
'trigger': False,
|
224
225
|
'trailing': False,
|
226
|
+
'symbolRequired': True,
|
225
227
|
},
|
226
228
|
'fetchOpenOrders': {
|
227
229
|
'marginMode': False,
|
228
230
|
'limit': None,
|
229
231
|
'trigger': False,
|
230
232
|
'trailing': False,
|
233
|
+
'symbolRequired': False,
|
231
234
|
},
|
232
235
|
'fetchOrders': None,
|
233
236
|
'fetchClosedOrders': {
|
@@ -238,6 +241,7 @@ class probit(Exchange, ImplicitAPI):
|
|
238
241
|
'untilDays': 90,
|
239
242
|
'trigger': False,
|
240
243
|
'trailing': False,
|
244
|
+
'symbolRequired': False,
|
241
245
|
},
|
242
246
|
'fetchOHLCV': {
|
243
247
|
'limit': 4000,
|
ccxt/test/tests_async.py
CHANGED
@@ -12,7 +12,6 @@ class testMainClass:
|
|
12
12
|
request_tests = False
|
13
13
|
ws_tests = False
|
14
14
|
response_tests = False
|
15
|
-
static_tests = False
|
16
15
|
info = False
|
17
16
|
verbose = False
|
18
17
|
debug = False
|
@@ -50,16 +49,16 @@ class testMainClass:
|
|
50
49
|
if self.request_tests and self.response_tests:
|
51
50
|
await self.run_static_request_tests(exchange_id, symbol_argv)
|
52
51
|
await self.run_static_response_tests(exchange_id, symbol_argv)
|
53
|
-
return
|
52
|
+
return True
|
54
53
|
if self.response_tests:
|
55
54
|
await self.run_static_response_tests(exchange_id, symbol_argv)
|
56
|
-
return
|
55
|
+
return True
|
57
56
|
if self.request_tests:
|
58
57
|
await self.run_static_request_tests(exchange_id, symbol_argv) # symbol here is the testname
|
59
|
-
return
|
58
|
+
return True
|
60
59
|
if self.id_tests:
|
61
60
|
await self.run_broker_id_tests()
|
62
|
-
return
|
61
|
+
return True
|
63
62
|
new_line = '\n'
|
64
63
|
dump(new_line + '' + new_line + '' + '[INFO] TESTING ', self.ext, {
|
65
64
|
'exchange': exchange_id,
|
@@ -104,6 +103,7 @@ class testMainClass:
|
|
104
103
|
self.test_files = get_test_files_sync(properties, self.ws_tests)
|
105
104
|
else:
|
106
105
|
self.test_files = await get_test_files(properties, self.ws_tests)
|
106
|
+
return True
|
107
107
|
|
108
108
|
def load_credentials_from_env(self, exchange):
|
109
109
|
exchange_id = exchange.id
|
@@ -126,8 +126,12 @@ class testMainClass:
|
|
126
126
|
keys_local = get_root_dir() + 'keys.local.json'
|
127
127
|
keys_global_exists = io_file_exists(keys_global)
|
128
128
|
keys_local_exists = io_file_exists(keys_local)
|
129
|
-
global_settings =
|
130
|
-
|
129
|
+
global_settings = {}
|
130
|
+
if keys_global_exists:
|
131
|
+
global_settings = io_file_read(keys_global)
|
132
|
+
local_settings = {}
|
133
|
+
if keys_local_exists:
|
134
|
+
local_settings = io_file_read(keys_local)
|
131
135
|
all_settings = exchange.deep_extend(global_settings, local_settings)
|
132
136
|
exchange_settings = exchange.safe_value(all_settings, exchange_id, {})
|
133
137
|
if exchange_settings:
|
@@ -178,7 +182,7 @@ class testMainClass:
|
|
178
182
|
exchange.options['checksum'] = False
|
179
183
|
# todo: temporary skip for php
|
180
184
|
if 'OrderBook' in method_name and self.ext == 'php':
|
181
|
-
return
|
185
|
+
return True
|
182
186
|
skipped_properties_for_method = self.get_skips(exchange, method_name)
|
183
187
|
is_load_markets = (method_name == 'loadMarkets')
|
184
188
|
is_fetch_currencies = (method_name == 'fetchCurrencies')
|
@@ -186,7 +190,7 @@ class testMainClass:
|
|
186
190
|
is_feature_test = (method_name == 'features')
|
187
191
|
# if this is a private test, and the implementation was already tested in public, then no need to re-test it in private test (exception is fetchCurrencies, because our approach in base exchange)
|
188
192
|
if not is_public and (method_name in self.checked_public_tests) and not is_fetch_currencies:
|
189
|
-
return
|
193
|
+
return True
|
190
194
|
skip_message = None
|
191
195
|
supported_by_exchange = (method_name in exchange.has) and exchange.has[method_name]
|
192
196
|
if not is_load_markets and (len(self.only_specific_tests) > 0 and not exchange.in_array(method_name, self.only_specific_tests)):
|
@@ -204,7 +208,7 @@ class testMainClass:
|
|
204
208
|
if skip_message:
|
205
209
|
if self.info:
|
206
210
|
dump(self.add_padding(skip_message, 25), name, method_name)
|
207
|
-
return
|
211
|
+
return True
|
208
212
|
if self.info:
|
209
213
|
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"
|
210
214
|
dump(self.add_padding('[INFO] TESTING', 25), name, method_name, args_stringified)
|
@@ -217,7 +221,7 @@ class testMainClass:
|
|
217
221
|
# add to the list of successed tests
|
218
222
|
if is_public:
|
219
223
|
self.checked_public_tests[method_name] = True
|
220
|
-
return
|
224
|
+
return True
|
221
225
|
|
222
226
|
def get_skips(self, exchange, method_name):
|
223
227
|
final_skips = {}
|
@@ -286,10 +290,10 @@ class testMainClass:
|
|
286
290
|
is_on_maintenance = (isinstance(e, OnMaintenance))
|
287
291
|
is_exchange_not_available = (isinstance(e, ExchangeNotAvailable))
|
288
292
|
should_fail = None
|
289
|
-
|
293
|
+
ret_success = None
|
290
294
|
if is_load_markets:
|
291
295
|
# if "loadMarkets" does not succeed, we must return "false" to caller method, to stop tests continual
|
292
|
-
|
296
|
+
ret_success = False
|
293
297
|
# we might not break exchange tests, if exchange is on maintenance at this moment
|
294
298
|
if is_on_maintenance:
|
295
299
|
should_fail = False
|
@@ -300,20 +304,19 @@ class testMainClass:
|
|
300
304
|
if is_exchange_not_available and not is_on_maintenance:
|
301
305
|
# break exchange tests if "ExchangeNotAvailable" exception is thrown, but it's not maintenance
|
302
306
|
should_fail = True
|
303
|
-
|
307
|
+
ret_success = False
|
304
308
|
else:
|
305
309
|
# in all other cases of OperationFailed, show Warning, but don't mark test as failed
|
306
310
|
should_fail = False
|
307
|
-
|
311
|
+
ret_success = True
|
308
312
|
# output the message
|
309
313
|
fail_type = '[TEST_FAILURE]' if should_fail else '[TEST_WARNING]'
|
310
314
|
dump(fail_type, 'Method could not be tested due to a repeated Network/Availability issues', ' | ', exchange.id, method_name, args_stringified, exception_message(e))
|
311
|
-
return
|
315
|
+
return ret_success
|
312
316
|
else:
|
313
317
|
# wait and retry again
|
314
318
|
# (increase wait time on every retry)
|
315
319
|
await exchange.sleep((i + 1) * 1000)
|
316
|
-
continue
|
317
320
|
else:
|
318
321
|
# if it's loadMarkets, then fail test, because it's mandatory for tests
|
319
322
|
if is_load_markets:
|
@@ -377,6 +380,7 @@ class testMainClass:
|
|
377
380
|
tests['fetchPremiumIndexOHLCV'] = [symbol]
|
378
381
|
self.public_tests = tests
|
379
382
|
await self.run_tests(exchange, tests, True)
|
383
|
+
return True
|
380
384
|
|
381
385
|
async def run_tests(self, exchange, tests, is_public_test):
|
382
386
|
test_names = list(tests.keys())
|
@@ -401,6 +405,7 @@ class testMainClass:
|
|
401
405
|
dump('[TEST_FAILURE]', exchange.id, test_prefix_string, 'Failed methods : ' + errors_string)
|
402
406
|
if self.info:
|
403
407
|
dump(self.add_padding('[INFO] END ' + test_prefix_string + ' ' + exchange.id, 25))
|
408
|
+
return True
|
404
409
|
|
405
410
|
async def load_exchange(self, exchange):
|
406
411
|
result = await self.test_safe('loadMarkets', exchange, [], True)
|
@@ -521,11 +526,12 @@ class testMainClass:
|
|
521
526
|
if exchange.has['swap'] and swap_symbol is not None:
|
522
527
|
exchange.options['defaultType'] = 'swap'
|
523
528
|
await self.run_private_tests(exchange, swap_symbol)
|
529
|
+
return True
|
524
530
|
|
525
531
|
async def run_private_tests(self, exchange, symbol):
|
526
532
|
if not exchange.check_required_credentials(False):
|
527
533
|
dump('[INFO] Skipping private tests', 'Keys not found')
|
528
|
-
return
|
534
|
+
return True
|
529
535
|
code = self.get_exchange_code(exchange)
|
530
536
|
# if (exchange.deepExtendedTest) {
|
531
537
|
# await test ('InvalidNonce', exchange, symbol);
|
@@ -595,14 +601,14 @@ class testMainClass:
|
|
595
601
|
proxy_test_name = self.proxy_test_file_name
|
596
602
|
# todo: temporary skip for sync py
|
597
603
|
if self.ext == 'py' and is_sync():
|
598
|
-
return
|
604
|
+
return True
|
599
605
|
# try proxy several times
|
600
606
|
max_retries = 3
|
601
607
|
exception = None
|
602
608
|
for j in range(0, max_retries):
|
603
609
|
try:
|
604
610
|
await self.test_method(proxy_test_name, exchange, [], True)
|
605
|
-
return # if successfull, then end the test
|
611
|
+
return True # if successfull, then end the test
|
606
612
|
except Exception as e:
|
607
613
|
exception = e
|
608
614
|
await exchange.sleep(j * 1000)
|
@@ -611,12 +617,13 @@ class testMainClass:
|
|
611
617
|
error_message = '[TEST_FAILURE] Failed ' + proxy_test_name + ' : ' + exception_message(exception)
|
612
618
|
# temporary comment the below, because c# transpilation failure
|
613
619
|
# throw new Exchange Error (errorMessage.toString ());
|
614
|
-
dump('[TEST_WARNING]' +
|
620
|
+
dump('[TEST_WARNING]' + error_message)
|
621
|
+
return True
|
615
622
|
|
616
623
|
async def start_test(self, exchange, symbol):
|
617
624
|
# we do not need to test aliases
|
618
625
|
if exchange.alias:
|
619
|
-
return
|
626
|
+
return True
|
620
627
|
if self.sandbox or get_exchange_prop(exchange, 'sandbox'):
|
621
628
|
exchange.set_sandbox_mode(True)
|
622
629
|
try:
|
@@ -624,7 +631,7 @@ class testMainClass:
|
|
624
631
|
if not result:
|
625
632
|
if not is_sync():
|
626
633
|
await close(exchange)
|
627
|
-
return
|
634
|
+
return True
|
628
635
|
# if (exchange.id === 'binance') {
|
629
636
|
# # 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
|
630
637
|
# # await this.testProxies (exchange);
|
@@ -799,13 +806,15 @@ class testMainClass:
|
|
799
806
|
return True # c# requ
|
800
807
|
|
801
808
|
def assert_new_and_stored_output(self, exchange, skip_keys, new_output, stored_output, strict_type_check=True, asserting_key=None):
|
809
|
+
res = True
|
802
810
|
try:
|
803
|
-
|
811
|
+
res = self.assert_new_and_stored_output_inner(exchange, skip_keys, new_output, stored_output, strict_type_check, asserting_key)
|
804
812
|
except Exception as e:
|
805
813
|
if self.info:
|
806
814
|
error_message = self.var_to_string(new_output) + '(calculated)' + ' != ' + self.var_to_string(stored_output) + '(stored)'
|
807
815
|
dump('[TEST_FAILURE_DETAIL]' + error_message)
|
808
816
|
raise e
|
817
|
+
return res
|
809
818
|
|
810
819
|
def var_to_string(self, obj=None):
|
811
820
|
new_string = None
|
@@ -834,11 +843,11 @@ class testMainClass:
|
|
834
843
|
if (stored_url_query is None) and (new_url_query is None):
|
835
844
|
# might be a get request without any query parameters
|
836
845
|
# example: https://api.gateio.ws/api/v4/delivery/usdt/positions
|
837
|
-
return
|
846
|
+
return True
|
838
847
|
stored_url_params = self.urlencoded_to_dict(stored_url_query)
|
839
848
|
new_url_params = self.urlencoded_to_dict(new_url_query)
|
840
849
|
self.assert_new_and_stored_output(exchange, skip_keys, new_url_params, stored_url_params)
|
841
|
-
return
|
850
|
+
return True
|
842
851
|
if type == 'json' and (stored_output is not None) and (new_output is not None):
|
843
852
|
if isinstance(stored_output, str):
|
844
853
|
stored_output = json_parse(stored_output)
|
@@ -855,6 +864,7 @@ class testMainClass:
|
|
855
864
|
stored_output = self.urlencoded_to_dict(stored_output)
|
856
865
|
new_output = self.urlencoded_to_dict(new_output)
|
857
866
|
self.assert_new_and_stored_output(exchange, skip_keys, new_output, stored_output)
|
867
|
+
return True
|
858
868
|
|
859
869
|
def assert_static_response_output(self, exchange, skip_keys, computed_result, stored_result):
|
860
870
|
self.assert_new_and_stored_output(exchange, skip_keys, computed_result, stored_result, False)
|
@@ -890,8 +900,9 @@ class testMainClass:
|
|
890
900
|
self.assert_static_request_output(exchange, type, skip_keys, data['url'], request_url, call_output, output)
|
891
901
|
except Exception as e:
|
892
902
|
self.request_tests_failed = True
|
893
|
-
error_message = '[' + self.lang + '][STATIC_REQUEST]' + '[' + exchange.id + ']' + '[' + method + ']' + '[' + data['description'] + ']' +
|
903
|
+
error_message = '[' + self.lang + '][STATIC_REQUEST]' + '[' + exchange.id + ']' + '[' + method + ']' + '[' + data['description'] + ']' + exception_message(e)
|
894
904
|
dump('[TEST_FAILURE]' + error_message)
|
905
|
+
return True
|
895
906
|
|
896
907
|
async def test_response_statically(self, exchange, method, skip_keys, data):
|
897
908
|
expected_result = exchange.safe_value(data, 'parsedResponse')
|
@@ -905,9 +916,10 @@ class testMainClass:
|
|
905
916
|
self.assert_static_response_output(mocked_exchange, skip_keys, unified_result_sync, expected_result)
|
906
917
|
except Exception as e:
|
907
918
|
self.response_tests_failed = True
|
908
|
-
error_message = '[' + self.lang + '][STATIC_RESPONSE]' + '[' + exchange.id + ']' + '[' + method + ']' + '[' + data['description'] + ']' +
|
919
|
+
error_message = '[' + self.lang + '][STATIC_RESPONSE]' + '[' + exchange.id + ']' + '[' + method + ']' + '[' + data['description'] + ']' + exception_message(e)
|
909
920
|
dump('[TEST_FAILURE]' + error_message)
|
910
921
|
set_fetch_response(exchange, None) # reset state
|
922
|
+
return True
|
911
923
|
|
912
924
|
def init_offline_exchange(self, exchange_name):
|
913
925
|
markets = self.load_markets_from_file(exchange_name)
|
@@ -943,7 +955,8 @@ class testMainClass:
|
|
943
955
|
'leverageBrackets': {},
|
944
956
|
},
|
945
957
|
})
|
946
|
-
exchange.currencies = currencies
|
958
|
+
exchange.currencies = currencies
|
959
|
+
# not working in python if assigned in the config dict
|
947
960
|
return exchange
|
948
961
|
|
949
962
|
async def test_exchange_request_statically(self, exchange_name, exchange_data, test_name=None):
|
@@ -991,6 +1004,9 @@ class testMainClass:
|
|
991
1004
|
is_disabled_c_sharp = exchange.safe_bool(result, 'disabledCS', False)
|
992
1005
|
if is_disabled_c_sharp and (self.lang == 'C#'):
|
993
1006
|
continue
|
1007
|
+
is_disabled_go = exchange.safe_bool(result, 'disabledGO', False)
|
1008
|
+
if is_disabled_go and (self.lang == 'GO'):
|
1009
|
+
continue
|
994
1010
|
type = exchange.safe_string(exchange_data, 'outputType')
|
995
1011
|
skip_keys = exchange.safe_value(exchange_data, 'skipKeys', [])
|
996
1012
|
await self.test_request_statically(exchange, method, result, type, skip_keys)
|
@@ -1042,6 +1058,9 @@ class testMainClass:
|
|
1042
1058
|
continue
|
1043
1059
|
if (test_name is not None) and (test_name != description):
|
1044
1060
|
continue
|
1061
|
+
is_disabled_go = exchange.safe_bool(result, 'disabledGO', False)
|
1062
|
+
if is_disabled_go and (self.lang == 'GO'):
|
1063
|
+
continue
|
1045
1064
|
skip_keys = exchange.safe_value(exchange_data, 'skipKeys', [])
|
1046
1065
|
await self.test_response_statically(exchange, method, skip_keys, result)
|
1047
1066
|
# reset options
|
@@ -1066,12 +1085,13 @@ class testMainClass:
|
|
1066
1085
|
|
1067
1086
|
async def run_static_request_tests(self, target_exchange=None, test_name=None):
|
1068
1087
|
await self.run_static_tests('request', target_exchange, test_name)
|
1088
|
+
return True
|
1069
1089
|
|
1070
1090
|
async def run_static_tests(self, type, target_exchange=None, test_name=None):
|
1071
1091
|
folder = get_root_dir() + './ts/src/test/static/' + type + '/'
|
1072
1092
|
static_data = self.load_static_data(folder, target_exchange)
|
1073
1093
|
if static_data is None:
|
1074
|
-
return
|
1094
|
+
return True
|
1075
1095
|
exchanges = list(static_data.keys())
|
1076
1096
|
exchange = init_exchange('Exchange', {}) # tmp to do the calculations until we have the ast-transpiler transpiling this code
|
1077
1097
|
promises = []
|
@@ -1096,7 +1116,7 @@ class testMainClass:
|
|
1096
1116
|
self.request_tests_failed = True
|
1097
1117
|
else:
|
1098
1118
|
self.response_tests_failed = True
|
1099
|
-
error_message = '[' + self.lang + '][STATIC_REQUEST]' +
|
1119
|
+
error_message = '[' + self.lang + '][STATIC_REQUEST]' + exception_message(e)
|
1100
1120
|
dump('[TEST_FAILURE]' + error_message)
|
1101
1121
|
if self.request_tests_failed or self.response_tests_failed:
|
1102
1122
|
exit_script(1)
|
@@ -1110,6 +1130,7 @@ class testMainClass:
|
|
1110
1130
|
# --- Init of mockResponses tests functions------------------------------------
|
1111
1131
|
# -----------------------------------------------------------------------------
|
1112
1132
|
await self.run_static_tests('response', exchange_name, test)
|
1133
|
+
return True
|
1113
1134
|
|
1114
1135
|
async def run_broker_id_tests(self):
|
1115
1136
|
# -----------------------------------------------------------------------------
|
@@ -1120,6 +1141,7 @@ class testMainClass:
|
|
1120
1141
|
success_message = '[' + self.lang + '][TEST_SUCCESS] brokerId tests passed.'
|
1121
1142
|
dump('[INFO]' + success_message)
|
1122
1143
|
exit_script(0)
|
1144
|
+
return True
|
1123
1145
|
|
1124
1146
|
async def test_binance(self):
|
1125
1147
|
exchange = self.init_offline_exchange('binance')
|
@@ -1373,6 +1395,7 @@ class testMainClass:
|
|
1373
1395
|
assert req_headers['X-SOURCE-KEY'] == id, 'bingx - id: ' + id + ' not in headers.'
|
1374
1396
|
if not is_sync():
|
1375
1397
|
await close(exchange)
|
1398
|
+
return True
|
1376
1399
|
|
1377
1400
|
async def test_phemex(self):
|
1378
1401
|
exchange = self.init_offline_exchange('phemex')
|
@@ -1387,6 +1410,7 @@ class testMainClass:
|
|
1387
1410
|
assert client_order_id.startswith(id_string), 'phemex - clOrdID: ' + client_order_id + ' does not start with id: ' + id_string
|
1388
1411
|
if not is_sync():
|
1389
1412
|
await close(exchange)
|
1413
|
+
return True
|
1390
1414
|
|
1391
1415
|
async def test_blofin(self):
|
1392
1416
|
exchange = self.init_offline_exchange('blofin')
|
@@ -1401,6 +1425,7 @@ class testMainClass:
|
|
1401
1425
|
assert broker_id.startswith(id_string), 'blofin - brokerId: ' + broker_id + ' does not start with id: ' + id_string
|
1402
1426
|
if not is_sync():
|
1403
1427
|
await close(exchange)
|
1428
|
+
return True
|
1404
1429
|
|
1405
1430
|
async def test_hyperliquid(self):
|
1406
1431
|
exchange = self.init_offline_exchange('hyperliquid')
|
@@ -1414,6 +1439,7 @@ class testMainClass:
|
|
1414
1439
|
assert broker_id == id, 'hyperliquid - brokerId: ' + broker_id + ' does not start with id: ' + id
|
1415
1440
|
if not is_sync():
|
1416
1441
|
await close(exchange)
|
1442
|
+
return True
|
1417
1443
|
|
1418
1444
|
async def test_coinbaseinternational(self):
|
1419
1445
|
exchange = self.init_offline_exchange('coinbaseinternational')
|