ccxt 4.2.78__py2.py3-none-any.whl → 4.2.80__py2.py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- ccxt/__init__.py +1 -1
- ccxt/abstract/bingx.py +1 -0
- ccxt/abstract/gate.py +1 -0
- ccxt/abstract/gateio.py +1 -0
- ccxt/abstract/upbit.py +1 -0
- ccxt/async_support/__init__.py +1 -1
- ccxt/async_support/base/exchange.py +10 -1
- ccxt/async_support/base/ws/functions.py +1 -1
- ccxt/async_support/binance.py +3 -3
- ccxt/async_support/bingx.py +37 -5
- ccxt/async_support/bitstamp.py +20 -26
- ccxt/async_support/bybit.py +92 -0
- ccxt/async_support/coinbaseinternational.py +2 -2
- ccxt/async_support/deribit.py +152 -1
- ccxt/async_support/gate.py +11 -4
- ccxt/async_support/hyperliquid.py +42 -9
- ccxt/async_support/mexc.py +2 -2
- ccxt/async_support/upbit.py +2 -0
- ccxt/base/exchange.py +38 -9
- ccxt/base/types.py +23 -0
- ccxt/binance.py +3 -3
- ccxt/bingx.py +37 -5
- ccxt/bitstamp.py +20 -26
- ccxt/bybit.py +92 -0
- ccxt/coinbaseinternational.py +2 -2
- ccxt/deribit.py +152 -1
- ccxt/gate.py +11 -4
- ccxt/hyperliquid.py +42 -9
- ccxt/mexc.py +2 -2
- ccxt/pro/__init__.py +1 -1
- ccxt/pro/alpaca.py +1 -1
- ccxt/pro/binance.py +5 -5
- ccxt/pro/bitfinex2.py +1 -1
- ccxt/pro/bitget.py +1 -1
- ccxt/pro/bitmart.py +1 -1
- ccxt/pro/bitmex.py +1 -1
- ccxt/pro/bitopro.py +2 -1
- ccxt/pro/blockchaincom.py +1 -1
- ccxt/pro/bybit.py +14 -1
- ccxt/pro/cex.py +9 -5
- ccxt/pro/cryptocom.py +1 -1
- ccxt/pro/gemini.py +4 -3
- ccxt/pro/hitbtc.py +1 -1
- ccxt/pro/htx.py +1 -1
- ccxt/pro/okcoin.py +1 -1
- ccxt/pro/onetrading.py +1 -1
- ccxt/pro/phemex.py +6 -1
- ccxt/pro/woo.py +30 -0
- ccxt/test/base/test_ohlcv.py +3 -2
- ccxt/test/base/test_shared_methods.py +8 -0
- ccxt/test/base/test_ticker.py +7 -1
- ccxt/test/test_async.py +26 -25
- ccxt/test/test_sync.py +26 -25
- ccxt/upbit.py +2 -0
- {ccxt-4.2.78.dist-info → ccxt-4.2.80.dist-info}/METADATA +6 -6
- {ccxt-4.2.78.dist-info → ccxt-4.2.80.dist-info}/RECORD +58 -58
- {ccxt-4.2.78.dist-info → ccxt-4.2.80.dist-info}/WHEEL +0 -0
- {ccxt-4.2.78.dist-info → ccxt-4.2.80.dist-info}/top_level.txt +0 -0
ccxt/pro/phemex.py
CHANGED
@@ -27,6 +27,10 @@ class phemex(ccxt.async_support.phemex):
|
|
27
27
|
'watchOrderBook': True,
|
28
28
|
'watchOHLCV': True,
|
29
29
|
'watchPositions': None, # TODO
|
30
|
+
# mutli-endpoints are not supported: https://github.com/ccxt/ccxt/pull/21490
|
31
|
+
'watchOrderBookForSymbols': False,
|
32
|
+
'watchTradesForSymbols': False,
|
33
|
+
'watchOHLCVForSymbols': False,
|
30
34
|
},
|
31
35
|
'urls': {
|
32
36
|
'test': {
|
@@ -536,9 +540,10 @@ class phemex(ccxt.async_support.phemex):
|
|
536
540
|
|
537
541
|
async def watch_order_book(self, symbol: str, limit: Int = None, params={}) -> OrderBook:
|
538
542
|
"""
|
543
|
+
:see: https://github.com/phemex/phemex-api-docs/blob/master/Public-Spot-API-en.md#subscribe-orderbook
|
539
544
|
:see: https://github.com/phemex/phemex-api-docs/blob/master/Public-Hedged-Perpetual-API.md#subscribe-orderbook-for-new-model
|
540
545
|
:see: https://github.com/phemex/phemex-api-docs/blob/master/Public-Contract-API-en.md#subscribe-30-levels-orderbook
|
541
|
-
:see: https://github.com/phemex/phemex-api-docs/blob/master/Public-
|
546
|
+
:see: https://github.com/phemex/phemex-api-docs/blob/master/Public-Contract-API-en.md#subscribe-full-orderbook
|
542
547
|
watches information on open orders with bid(buy) and ask(sell) prices, volumes and other data
|
543
548
|
:param str symbol: unified symbol of the market to fetch the order book for
|
544
549
|
:param int [limit]: the maximum amount of order book entries to return
|
ccxt/pro/woo.py
CHANGED
@@ -89,6 +89,13 @@ class woo(ccxt.async_support.woo):
|
|
89
89
|
return await self.watch(url, messageHash, request, messageHash, subscribe)
|
90
90
|
|
91
91
|
async def watch_order_book(self, symbol: str, limit: Int = None, params={}) -> OrderBook:
|
92
|
+
"""
|
93
|
+
watches information on open orders with bid(buy) and ask(sell) prices, volumes and other data
|
94
|
+
:param str symbol: unified symbol of the market to fetch the order book for
|
95
|
+
:param int [limit]: the maximum amount of order book entries to return.
|
96
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
97
|
+
:returns dict: A dictionary of `order book structures <https://docs.ccxt.com/#/?id=order-book-structure>` indexed by market symbols
|
98
|
+
"""
|
92
99
|
await self.load_markets()
|
93
100
|
name = 'orderbook'
|
94
101
|
market = self.market(symbol)
|
@@ -137,9 +144,16 @@ class woo(ccxt.async_support.woo):
|
|
137
144
|
client.resolve(orderbook, topic)
|
138
145
|
|
139
146
|
async def watch_ticker(self, symbol: str, params={}) -> Ticker:
|
147
|
+
"""
|
148
|
+
watches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
|
149
|
+
:param str symbol: unified symbol of the market to fetch the ticker for
|
150
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
151
|
+
:returns dict: a `ticker structure <https://docs.ccxt.com/#/?id=ticker-structure>`
|
152
|
+
"""
|
140
153
|
await self.load_markets()
|
141
154
|
name = 'ticker'
|
142
155
|
market = self.market(symbol)
|
156
|
+
symbol = market['symbol']
|
143
157
|
topic = market['id'] + '@' + name
|
144
158
|
request = {
|
145
159
|
'event': 'subscribe',
|
@@ -214,7 +228,14 @@ class woo(ccxt.async_support.woo):
|
|
214
228
|
return message
|
215
229
|
|
216
230
|
async def watch_tickers(self, symbols: Strings = None, params={}) -> Tickers:
|
231
|
+
"""
|
232
|
+
n watches a price ticker, a statistical calculation with the information calculated over the past 24 hours for all markets of a specific list
|
233
|
+
:param str[] symbols: unified symbol of the market to fetch the ticker for
|
234
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
235
|
+
:returns dict: a `ticker structure <https://docs.ccxt.com/#/?id=ticker-structure>`
|
236
|
+
"""
|
217
237
|
await self.load_markets()
|
238
|
+
symbols = self.market_symbols(symbols)
|
218
239
|
name = 'tickers'
|
219
240
|
topic = name
|
220
241
|
request = {
|
@@ -329,8 +350,17 @@ class woo(ccxt.async_support.woo):
|
|
329
350
|
client.resolve(stored, topic)
|
330
351
|
|
331
352
|
async def watch_trades(self, symbol: str, since: Int = None, limit: Int = None, params={}) -> List[Trade]:
|
353
|
+
"""
|
354
|
+
watches information on multiple trades made in a market
|
355
|
+
:param str symbol: unified market symbol of the market trades were made in
|
356
|
+
:param int [since]: the earliest time in ms to fetch trades for
|
357
|
+
:param int [limit]: the maximum number of trade structures to retrieve
|
358
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
359
|
+
:returns dict[]: a list of [trade structures]{@link https://docs.ccxt.com/#/?id=trade-structure
|
360
|
+
"""
|
332
361
|
await self.load_markets()
|
333
362
|
market = self.market(symbol)
|
363
|
+
symbol = market['symbol']
|
334
364
|
topic = market['id'] + '@trade'
|
335
365
|
request = {
|
336
366
|
'event': 'subscribe',
|
ccxt/test/base/test_ohlcv.py
CHANGED
@@ -21,8 +21,9 @@ def test_ohlcv(exchange, skipped_properties, method, entry, symbol, now):
|
|
21
21
|
test_shared_methods.assert_timestamp_and_datetime(exchange, skipped_properties, method, entry, now, 0)
|
22
22
|
log_text = test_shared_methods.log_template(exchange, method, entry)
|
23
23
|
#
|
24
|
-
|
25
|
-
|
24
|
+
assert len(entry) >= 6, 'ohlcv array length should be >= 6;' + log_text
|
25
|
+
if not ('roundTimestamp' in skipped_properties):
|
26
|
+
test_shared_methods.assert_round_minute_timestamp(exchange, skipped_properties, method, entry, 0)
|
26
27
|
high = exchange.safe_string(entry, 2)
|
27
28
|
low = exchange.safe_string(entry, 3)
|
28
29
|
test_shared_methods.assert_less_or_equal(exchange, skipped_properties, method, entry, '1', high)
|
@@ -343,3 +343,11 @@ def assert_non_emtpy_array(exchange, skipped_properties, method, entry, hint=Non
|
|
343
343
|
if not ('emptyResponse' in skipped_properties):
|
344
344
|
return
|
345
345
|
assert len(entry) > 0, 'response is expected to be a non-empty array' + log_text + ' (add \"emptyResponse\" in skip-tests.json to skip this check)'
|
346
|
+
|
347
|
+
|
348
|
+
def assert_round_minute_timestamp(exchange, skipped_properties, method, entry, key):
|
349
|
+
if key in skipped_properties:
|
350
|
+
return
|
351
|
+
log_text = log_template(exchange, method, entry)
|
352
|
+
ts = exchange.safe_string(entry, key)
|
353
|
+
assert Precise.string_mod(ts, '60000') == '0', 'timestamp should be a multiple of 60 seconds (1 minute)' + log_text
|
ccxt/test/base/test_ticker.py
CHANGED
@@ -39,7 +39,13 @@ def test_ticker(exchange, skipped_properties, method, entry, symbol):
|
|
39
39
|
'quoteVolume': exchange.parse_number('1.234'),
|
40
40
|
}
|
41
41
|
# todo: atm, many exchanges fail, so temporarily decrease stict mode
|
42
|
-
empty_allowed_for = ['timestamp', 'datetime', 'open', 'high', 'low', 'close', 'last', '
|
42
|
+
empty_allowed_for = ['timestamp', 'datetime', 'open', 'high', 'low', 'close', 'last', 'baseVolume', 'quoteVolume', 'previousClose', 'vwap', 'change', 'percentage', 'average']
|
43
|
+
# trick csharp-transpiler for string
|
44
|
+
if not 'BidsAsks' in str(method):
|
45
|
+
empty_allowed_for.append('bid')
|
46
|
+
empty_allowed_for.append('ask')
|
47
|
+
empty_allowed_for.append('bidVolume')
|
48
|
+
empty_allowed_for.append('askVolume')
|
43
49
|
test_shared_methods.assert_structure(exchange, skipped_properties, method, entry, format, empty_allowed_for)
|
44
50
|
test_shared_methods.assert_timestamp_and_datetime(exchange, skipped_properties, method, entry)
|
45
51
|
log_text = test_shared_methods.log_template(exchange, method, entry)
|
ccxt/test/test_async.py
CHANGED
@@ -129,6 +129,7 @@ class baseMainTestClass():
|
|
129
129
|
response_tests = False
|
130
130
|
ws_tests = False
|
131
131
|
load_keys = False
|
132
|
+
skipped_settings_for_exchange = {}
|
132
133
|
skipped_methods = {}
|
133
134
|
check_public_tests = {}
|
134
135
|
test_files = {}
|
@@ -378,7 +379,8 @@ class testMainClass(baseMainTestClass):
|
|
378
379
|
# skipped tests
|
379
380
|
skipped_file = self.root_dir_for_skips + 'skip-tests.json'
|
380
381
|
skipped_settings = io_file_read(skipped_file)
|
381
|
-
skipped_settings_for_exchange = exchange.safe_value(skipped_settings, exchange_id, {})
|
382
|
+
self.skipped_settings_for_exchange = exchange.safe_value(skipped_settings, exchange_id, {})
|
383
|
+
skipped_settings_for_exchange = self.skipped_settings_for_exchange
|
382
384
|
# others
|
383
385
|
timeout = exchange.safe_value(skipped_settings_for_exchange, 'timeout')
|
384
386
|
if timeout is not None:
|
@@ -569,6 +571,7 @@ class testMainClass(baseMainTestClass):
|
|
569
571
|
'watchOHLCV': [symbol],
|
570
572
|
'watchTicker': [symbol],
|
571
573
|
'watchTickers': [symbol],
|
574
|
+
'watchBidsAsks': [symbol],
|
572
575
|
'watchOrderBook': [symbol],
|
573
576
|
'watchTrades': [symbol],
|
574
577
|
}
|
@@ -615,26 +618,18 @@ class testMainClass(baseMainTestClass):
|
|
615
618
|
result = await self.test_safe('loadMarkets', exchange, [], True)
|
616
619
|
if not result:
|
617
620
|
return False
|
618
|
-
symbols = ['BTC/USDT', 'BTC/USDC', 'BTC/CNY', 'BTC/USD', 'BTC/EUR', 'BTC/ETH', 'ETH/BTC', 'BTC/JPY', 'ETH/EUR', 'ETH/JPY', 'ETH/CNY', 'ETH/USD', 'LTC/CNY', 'DASH/BTC', 'DOGE/BTC', 'BTC/AUD', 'BTC/PLN', 'USD/SLL', 'BTC/RUB', 'BTC/UAH', 'LTC/BTC', 'EUR/USD']
|
619
|
-
result_symbols = []
|
620
|
-
exchange_specific_symbols = exchange.symbols
|
621
|
-
for i in range(0, len(exchange_specific_symbols)):
|
622
|
-
symbol = exchange_specific_symbols[i]
|
623
|
-
if exchange.in_array(symbol, symbols):
|
624
|
-
result_symbols.append(symbol)
|
625
|
-
result_msg = ''
|
626
|
-
result_length = len(result_symbols)
|
627
621
|
exchange_symbols_length = len(exchange.symbols)
|
628
|
-
|
629
|
-
if exchange_symbols_length > result_length:
|
630
|
-
result_msg = ', '.join(result_symbols) + ' + more...'
|
631
|
-
else:
|
632
|
-
result_msg = ', '.join(result_symbols)
|
633
|
-
dump('[INFO:MAIN] Exchange loaded', exchange_symbols_length, 'symbols', result_msg)
|
622
|
+
dump('[INFO:MAIN] Exchange loaded', exchange_symbols_length, 'symbols')
|
634
623
|
return True
|
635
624
|
|
636
625
|
def get_test_symbol(self, exchange, is_spot, symbols):
|
637
626
|
symbol = None
|
627
|
+
preferred_spot_symbol = exchange.safe_string(self.skipped_settings_for_exchange, 'preferredSpotSymbol')
|
628
|
+
preferred_swap_symbol = exchange.safe_string(self.skipped_settings_for_exchange, 'preferredSwapSymbol')
|
629
|
+
if is_spot and preferred_spot_symbol:
|
630
|
+
return preferred_spot_symbol
|
631
|
+
elif not is_spot and preferred_swap_symbol:
|
632
|
+
return preferred_swap_symbol
|
638
633
|
for i in range(0, len(symbols)):
|
639
634
|
s = symbols[i]
|
640
635
|
market = exchange.safe_value(exchange.markets, s)
|
@@ -669,9 +664,9 @@ class testMainClass(baseMainTestClass):
|
|
669
664
|
|
670
665
|
def get_valid_symbol(self, exchange, spot=True):
|
671
666
|
current_type_markets = self.get_markets_from_exchange(exchange, spot)
|
672
|
-
codes = ['BTC', 'ETH', 'XRP', 'LTC', '
|
673
|
-
spot_symbols = ['BTC/USDT', 'BTC/USDC', 'BTC/USD', 'BTC/CNY', 'BTC/EUR', 'BTC/ETH', 'ETH/
|
674
|
-
swap_symbols = ['BTC/USDT:USDT', 'BTC/USDC:USDC', 'BTC/USD:USD', 'ETH/USDT:USDT', 'ETH/
|
667
|
+
codes = ['BTC', 'ETH', 'XRP', 'LTC', 'BNB', 'DASH', 'DOGE', 'ETC', 'TRX', 'USDT', 'USDC', 'USD', 'EUR', 'TUSD', 'CNY', 'JPY', 'BRL']
|
668
|
+
spot_symbols = ['BTC/USDT', 'BTC/USDC', 'BTC/USD', 'BTC/CNY', 'BTC/EUR', 'BTC/AUD', 'BTC/BRL', 'BTC/JPY', 'ETH/USDT', 'ETH/USDC', 'ETH/USD', 'ETH/CNY', 'ETH/EUR', 'ETH/AUD', 'ETH/BRL', 'ETH/JPY', 'EUR/USDT', 'EUR/USD', 'EUR/USDC', 'USDT/EUR', 'USD/EUR', 'USDC/EUR', 'BTC/ETH', 'ETH/BTC']
|
669
|
+
swap_symbols = ['BTC/USDT:USDT', 'BTC/USDC:USDC', 'BTC/USD:USD', 'ETH/USDT:USDT', 'ETH/USDC:USDC', 'ETH/USD:USD', 'BTC/USD:BTC', 'ETH/USD:ETH']
|
675
670
|
target_symbols = spot_symbols if spot else swap_symbols
|
676
671
|
symbol = self.get_test_symbol(exchange, spot, target_symbols)
|
677
672
|
# if symbols wasn't found from above hardcoded list, then try to locate any symbol which has our target hardcoded 'base' code
|
@@ -1121,7 +1116,8 @@ class testMainClass(baseMainTestClass):
|
|
1121
1116
|
# instantiate the exchange and make sure that we sink the requests to avoid an actual request
|
1122
1117
|
exchange = self.init_offline_exchange(exchange_name)
|
1123
1118
|
global_options = exchange.safe_dict(exchange_data, 'options', {})
|
1124
|
-
exchange.options = exchange.
|
1119
|
+
# exchange.options = exchange.deepExtend (exchange.options, globalOptions); # custom options to be used in the tests
|
1120
|
+
exchange.extend_exchange_options(global_options)
|
1125
1121
|
methods = exchange.safe_value(exchange_data, 'methods', {})
|
1126
1122
|
methods_names = list(methods.keys())
|
1127
1123
|
for i in range(0, len(methods_names)):
|
@@ -1131,7 +1127,8 @@ class testMainClass(baseMainTestClass):
|
|
1131
1127
|
result = results[j]
|
1132
1128
|
old_exchange_options = exchange.options # snapshot options;
|
1133
1129
|
test_exchange_options = exchange.safe_value(result, 'options', {})
|
1134
|
-
exchange.options = exchange.
|
1130
|
+
# exchange.options = exchange.deepExtend (oldExchangeOptions, testExchangeOptions); # custom options to be used in the tests
|
1131
|
+
exchange.extend_exchange_options(exchange.deep_extend(old_exchange_options, test_exchange_options))
|
1135
1132
|
description = exchange.safe_value(result, 'description')
|
1136
1133
|
if (test_name is not None) and (test_name != description):
|
1137
1134
|
continue
|
@@ -1142,7 +1139,8 @@ class testMainClass(baseMainTestClass):
|
|
1142
1139
|
skip_keys = exchange.safe_value(exchange_data, 'skipKeys', [])
|
1143
1140
|
await self.test_method_statically(exchange, method, result, type, skip_keys)
|
1144
1141
|
# reset options
|
1145
|
-
exchange.options = exchange.
|
1142
|
+
# exchange.options = exchange.deepExtend (oldExchangeOptions, {});
|
1143
|
+
exchange.extend_exchange_options(exchange.deep_extend(old_exchange_options, {}))
|
1146
1144
|
await close(exchange)
|
1147
1145
|
return True # in c# methods that will be used with promiseAll need to return something
|
1148
1146
|
|
@@ -1150,7 +1148,8 @@ class testMainClass(baseMainTestClass):
|
|
1150
1148
|
exchange = self.init_offline_exchange(exchange_name)
|
1151
1149
|
methods = exchange.safe_value(exchange_data, 'methods', {})
|
1152
1150
|
options = exchange.safe_value(exchange_data, 'options', {})
|
1153
|
-
exchange.options = exchange.
|
1151
|
+
# exchange.options = exchange.deepExtend (exchange.options, options); # custom options to be used in the tests
|
1152
|
+
exchange.extend_exchange_options(options)
|
1154
1153
|
methods_names = list(methods.keys())
|
1155
1154
|
for i in range(0, len(methods_names)):
|
1156
1155
|
method = methods_names[i]
|
@@ -1160,7 +1159,8 @@ class testMainClass(baseMainTestClass):
|
|
1160
1159
|
description = exchange.safe_value(result, 'description')
|
1161
1160
|
old_exchange_options = exchange.options # snapshot options;
|
1162
1161
|
test_exchange_options = exchange.safe_value(result, 'options', {})
|
1163
|
-
exchange.options = exchange.
|
1162
|
+
# exchange.options = exchange.deepExtend (oldExchangeOptions, testExchangeOptions); # custom options to be used in the tests
|
1163
|
+
exchange.extend_exchange_options(exchange.deep_extend(old_exchange_options, test_exchange_options))
|
1164
1164
|
is_disabled = exchange.safe_bool(result, 'disabled', False)
|
1165
1165
|
if is_disabled:
|
1166
1166
|
continue
|
@@ -1175,7 +1175,8 @@ class testMainClass(baseMainTestClass):
|
|
1175
1175
|
skip_keys = exchange.safe_value(exchange_data, 'skipKeys', [])
|
1176
1176
|
await self.test_response_statically(exchange, method, skip_keys, result)
|
1177
1177
|
# reset options
|
1178
|
-
exchange.options = exchange.
|
1178
|
+
# exchange.options = exchange.deepExtend (oldExchangeOptions, {});
|
1179
|
+
exchange.extend_exchange_options(exchange.deep_extend(old_exchange_options, {}))
|
1179
1180
|
await close(exchange)
|
1180
1181
|
return True # in c# methods that will be used with promiseAll need to return something
|
1181
1182
|
|
ccxt/test/test_sync.py
CHANGED
@@ -128,6 +128,7 @@ class baseMainTestClass():
|
|
128
128
|
response_tests = False
|
129
129
|
ws_tests = False
|
130
130
|
load_keys = False
|
131
|
+
skipped_settings_for_exchange = {}
|
131
132
|
skipped_methods = {}
|
132
133
|
check_public_tests = {}
|
133
134
|
test_files = {}
|
@@ -377,7 +378,8 @@ class testMainClass(baseMainTestClass):
|
|
377
378
|
# skipped tests
|
378
379
|
skipped_file = self.root_dir_for_skips + 'skip-tests.json'
|
379
380
|
skipped_settings = io_file_read(skipped_file)
|
380
|
-
skipped_settings_for_exchange = exchange.safe_value(skipped_settings, exchange_id, {})
|
381
|
+
self.skipped_settings_for_exchange = exchange.safe_value(skipped_settings, exchange_id, {})
|
382
|
+
skipped_settings_for_exchange = self.skipped_settings_for_exchange
|
381
383
|
# others
|
382
384
|
timeout = exchange.safe_value(skipped_settings_for_exchange, 'timeout')
|
383
385
|
if timeout is not None:
|
@@ -568,6 +570,7 @@ class testMainClass(baseMainTestClass):
|
|
568
570
|
'watchOHLCV': [symbol],
|
569
571
|
'watchTicker': [symbol],
|
570
572
|
'watchTickers': [symbol],
|
573
|
+
'watchBidsAsks': [symbol],
|
571
574
|
'watchOrderBook': [symbol],
|
572
575
|
'watchTrades': [symbol],
|
573
576
|
}
|
@@ -614,26 +617,18 @@ class testMainClass(baseMainTestClass):
|
|
614
617
|
result = self.test_safe('loadMarkets', exchange, [], True)
|
615
618
|
if not result:
|
616
619
|
return False
|
617
|
-
symbols = ['BTC/USDT', 'BTC/USDC', 'BTC/CNY', 'BTC/USD', 'BTC/EUR', 'BTC/ETH', 'ETH/BTC', 'BTC/JPY', 'ETH/EUR', 'ETH/JPY', 'ETH/CNY', 'ETH/USD', 'LTC/CNY', 'DASH/BTC', 'DOGE/BTC', 'BTC/AUD', 'BTC/PLN', 'USD/SLL', 'BTC/RUB', 'BTC/UAH', 'LTC/BTC', 'EUR/USD']
|
618
|
-
result_symbols = []
|
619
|
-
exchange_specific_symbols = exchange.symbols
|
620
|
-
for i in range(0, len(exchange_specific_symbols)):
|
621
|
-
symbol = exchange_specific_symbols[i]
|
622
|
-
if exchange.in_array(symbol, symbols):
|
623
|
-
result_symbols.append(symbol)
|
624
|
-
result_msg = ''
|
625
|
-
result_length = len(result_symbols)
|
626
620
|
exchange_symbols_length = len(exchange.symbols)
|
627
|
-
|
628
|
-
if exchange_symbols_length > result_length:
|
629
|
-
result_msg = ', '.join(result_symbols) + ' + more...'
|
630
|
-
else:
|
631
|
-
result_msg = ', '.join(result_symbols)
|
632
|
-
dump('[INFO:MAIN] Exchange loaded', exchange_symbols_length, 'symbols', result_msg)
|
621
|
+
dump('[INFO:MAIN] Exchange loaded', exchange_symbols_length, 'symbols')
|
633
622
|
return True
|
634
623
|
|
635
624
|
def get_test_symbol(self, exchange, is_spot, symbols):
|
636
625
|
symbol = None
|
626
|
+
preferred_spot_symbol = exchange.safe_string(self.skipped_settings_for_exchange, 'preferredSpotSymbol')
|
627
|
+
preferred_swap_symbol = exchange.safe_string(self.skipped_settings_for_exchange, 'preferredSwapSymbol')
|
628
|
+
if is_spot and preferred_spot_symbol:
|
629
|
+
return preferred_spot_symbol
|
630
|
+
elif not is_spot and preferred_swap_symbol:
|
631
|
+
return preferred_swap_symbol
|
637
632
|
for i in range(0, len(symbols)):
|
638
633
|
s = symbols[i]
|
639
634
|
market = exchange.safe_value(exchange.markets, s)
|
@@ -668,9 +663,9 @@ class testMainClass(baseMainTestClass):
|
|
668
663
|
|
669
664
|
def get_valid_symbol(self, exchange, spot=True):
|
670
665
|
current_type_markets = self.get_markets_from_exchange(exchange, spot)
|
671
|
-
codes = ['BTC', 'ETH', 'XRP', 'LTC', '
|
672
|
-
spot_symbols = ['BTC/USDT', 'BTC/USDC', 'BTC/USD', 'BTC/CNY', 'BTC/EUR', 'BTC/ETH', 'ETH/
|
673
|
-
swap_symbols = ['BTC/USDT:USDT', 'BTC/USDC:USDC', 'BTC/USD:USD', 'ETH/USDT:USDT', 'ETH/
|
666
|
+
codes = ['BTC', 'ETH', 'XRP', 'LTC', 'BNB', 'DASH', 'DOGE', 'ETC', 'TRX', 'USDT', 'USDC', 'USD', 'EUR', 'TUSD', 'CNY', 'JPY', 'BRL']
|
667
|
+
spot_symbols = ['BTC/USDT', 'BTC/USDC', 'BTC/USD', 'BTC/CNY', 'BTC/EUR', 'BTC/AUD', 'BTC/BRL', 'BTC/JPY', 'ETH/USDT', 'ETH/USDC', 'ETH/USD', 'ETH/CNY', 'ETH/EUR', 'ETH/AUD', 'ETH/BRL', 'ETH/JPY', 'EUR/USDT', 'EUR/USD', 'EUR/USDC', 'USDT/EUR', 'USD/EUR', 'USDC/EUR', 'BTC/ETH', 'ETH/BTC']
|
668
|
+
swap_symbols = ['BTC/USDT:USDT', 'BTC/USDC:USDC', 'BTC/USD:USD', 'ETH/USDT:USDT', 'ETH/USDC:USDC', 'ETH/USD:USD', 'BTC/USD:BTC', 'ETH/USD:ETH']
|
674
669
|
target_symbols = spot_symbols if spot else swap_symbols
|
675
670
|
symbol = self.get_test_symbol(exchange, spot, target_symbols)
|
676
671
|
# if symbols wasn't found from above hardcoded list, then try to locate any symbol which has our target hardcoded 'base' code
|
@@ -1120,7 +1115,8 @@ class testMainClass(baseMainTestClass):
|
|
1120
1115
|
# instantiate the exchange and make sure that we sink the requests to avoid an actual request
|
1121
1116
|
exchange = self.init_offline_exchange(exchange_name)
|
1122
1117
|
global_options = exchange.safe_dict(exchange_data, 'options', {})
|
1123
|
-
exchange.options = exchange.
|
1118
|
+
# exchange.options = exchange.deepExtend (exchange.options, globalOptions); # custom options to be used in the tests
|
1119
|
+
exchange.extend_exchange_options(global_options)
|
1124
1120
|
methods = exchange.safe_value(exchange_data, 'methods', {})
|
1125
1121
|
methods_names = list(methods.keys())
|
1126
1122
|
for i in range(0, len(methods_names)):
|
@@ -1130,7 +1126,8 @@ class testMainClass(baseMainTestClass):
|
|
1130
1126
|
result = results[j]
|
1131
1127
|
old_exchange_options = exchange.options # snapshot options;
|
1132
1128
|
test_exchange_options = exchange.safe_value(result, 'options', {})
|
1133
|
-
exchange.options = exchange.
|
1129
|
+
# exchange.options = exchange.deepExtend (oldExchangeOptions, testExchangeOptions); # custom options to be used in the tests
|
1130
|
+
exchange.extend_exchange_options(exchange.deep_extend(old_exchange_options, test_exchange_options))
|
1134
1131
|
description = exchange.safe_value(result, 'description')
|
1135
1132
|
if (test_name is not None) and (test_name != description):
|
1136
1133
|
continue
|
@@ -1141,7 +1138,8 @@ class testMainClass(baseMainTestClass):
|
|
1141
1138
|
skip_keys = exchange.safe_value(exchange_data, 'skipKeys', [])
|
1142
1139
|
self.test_method_statically(exchange, method, result, type, skip_keys)
|
1143
1140
|
# reset options
|
1144
|
-
exchange.options = exchange.
|
1141
|
+
# exchange.options = exchange.deepExtend (oldExchangeOptions, {});
|
1142
|
+
exchange.extend_exchange_options(exchange.deep_extend(old_exchange_options, {}))
|
1145
1143
|
close(exchange)
|
1146
1144
|
return True # in c# methods that will be used with promiseAll need to return something
|
1147
1145
|
|
@@ -1149,7 +1147,8 @@ class testMainClass(baseMainTestClass):
|
|
1149
1147
|
exchange = self.init_offline_exchange(exchange_name)
|
1150
1148
|
methods = exchange.safe_value(exchange_data, 'methods', {})
|
1151
1149
|
options = exchange.safe_value(exchange_data, 'options', {})
|
1152
|
-
exchange.options = exchange.
|
1150
|
+
# exchange.options = exchange.deepExtend (exchange.options, options); # custom options to be used in the tests
|
1151
|
+
exchange.extend_exchange_options(options)
|
1153
1152
|
methods_names = list(methods.keys())
|
1154
1153
|
for i in range(0, len(methods_names)):
|
1155
1154
|
method = methods_names[i]
|
@@ -1159,7 +1158,8 @@ class testMainClass(baseMainTestClass):
|
|
1159
1158
|
description = exchange.safe_value(result, 'description')
|
1160
1159
|
old_exchange_options = exchange.options # snapshot options;
|
1161
1160
|
test_exchange_options = exchange.safe_value(result, 'options', {})
|
1162
|
-
exchange.options = exchange.
|
1161
|
+
# exchange.options = exchange.deepExtend (oldExchangeOptions, testExchangeOptions); # custom options to be used in the tests
|
1162
|
+
exchange.extend_exchange_options(exchange.deep_extend(old_exchange_options, test_exchange_options))
|
1163
1163
|
is_disabled = exchange.safe_bool(result, 'disabled', False)
|
1164
1164
|
if is_disabled:
|
1165
1165
|
continue
|
@@ -1174,7 +1174,8 @@ class testMainClass(baseMainTestClass):
|
|
1174
1174
|
skip_keys = exchange.safe_value(exchange_data, 'skipKeys', [])
|
1175
1175
|
self.test_response_statically(exchange, method, skip_keys, result)
|
1176
1176
|
# reset options
|
1177
|
-
exchange.options = exchange.
|
1177
|
+
# exchange.options = exchange.deepExtend (oldExchangeOptions, {});
|
1178
|
+
exchange.extend_exchange_options(exchange.deep_extend(old_exchange_options, {}))
|
1178
1179
|
close(exchange)
|
1179
1180
|
return True # in c# methods that will be used with promiseAll need to return something
|
1180
1181
|
|
ccxt/upbit.py
CHANGED
@@ -85,6 +85,7 @@ class upbit(Exchange, ImplicitAPI):
|
|
85
85
|
'1m': 'minutes',
|
86
86
|
'3m': 'minutes',
|
87
87
|
'5m': 'minutes',
|
88
|
+
'10m': 'minutes',
|
88
89
|
'15m': 'minutes',
|
89
90
|
'30m': 'minutes',
|
90
91
|
'1h': 'minutes',
|
@@ -114,6 +115,7 @@ class upbit(Exchange, ImplicitAPI):
|
|
114
115
|
'candles/minutes/1',
|
115
116
|
'candles/minutes/3',
|
116
117
|
'candles/minutes/5',
|
118
|
+
'candles/minutes/10',
|
117
119
|
'candles/minutes/15',
|
118
120
|
'candles/minutes/30',
|
119
121
|
'candles/minutes/60',
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: ccxt
|
3
|
-
Version: 4.2.
|
3
|
+
Version: 4.2.80
|
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
|
@@ -91,7 +91,7 @@ Current feature list:
|
|
91
91
|
| [](http://www.bitmart.com/?r=rQCFLh) | bitmart | [BitMart](http://www.bitmart.com/?r=rQCFLh) | [](https://developer-pro.bitmart.com/) | [](https://github.com/ccxt/ccxt/wiki/Certification) | [](https://ccxt.pro) | [](http://www.bitmart.com/?r=rQCFLh) |
|
92
92
|
| [](https://www.bitmex.com/app/register/NZTR1q) | bitmex | [BitMEX](https://www.bitmex.com/app/register/NZTR1q) | [](https://www.bitmex.com/app/apiOverview) | [](https://github.com/ccxt/ccxt/wiki/Certification) | [](https://ccxt.pro) | [](https://www.bitmex.com/app/register/NZTR1q) |
|
93
93
|
| [](https://www.bybit.com/register?affiliate_id=35953) | bybit | [Bybit](https://www.bybit.com/register?affiliate_id=35953) | [](https://bybit-exchange.github.io/docs/inverse/) | [](https://github.com/ccxt/ccxt/wiki/Certification) | [](https://ccxt.pro) | |
|
94
|
-
| [](https://international.coinbase.com) | coinbaseinternational | [Coinbase International](https://international.coinbase.com) | [](https://docs.cloud.
|
94
|
+
| [](https://international.coinbase.com) | coinbaseinternational | [Coinbase International](https://international.coinbase.com) | [](https://docs.cloud.coinbase.com/intx/docs) | [](https://github.com/ccxt/ccxt/wiki/Certification) | [](https://ccxt.pro) | |
|
95
95
|
| [](https://www.coinex.com/register?refer_code=yw5fz) | coinex | [CoinEx](https://www.coinex.com/register?refer_code=yw5fz) | [](https://viabtc.github.io/coinex_api_en_doc) | [](https://github.com/ccxt/ccxt/wiki/Certification) | [](https://ccxt.pro) | |
|
96
96
|
| [](https://crypto.com/exch/kdacthrnxt) | cryptocom | [Crypto.com](https://crypto.com/exch/kdacthrnxt) | [](https://exchange-docs.crypto.com/exchange/v1/rest-ws/index.html) | [](https://github.com/ccxt/ccxt/wiki/Certification) | [](https://ccxt.pro) | [](https://crypto.com/exch/kdacthrnxt) |
|
97
97
|
| [](https://www.gate.io/signup/2436035) | gate | [Gate.io](https://www.gate.io/signup/2436035) | [](https://www.gate.io/docs/developers/apiv4/en/) | [](https://github.com/ccxt/ccxt/wiki/Certification) | [](https://ccxt.pro) | [](https://www.gate.io/signup/2436035) |
|
@@ -144,7 +144,7 @@ The CCXT library currently supports the following 97 cryptocurrency exchange mar
|
|
144
144
|
| [](https://www.bybit.com/register?affiliate_id=35953) | bybit | [Bybit](https://www.bybit.com/register?affiliate_id=35953) | [](https://bybit-exchange.github.io/docs/inverse/) | [](https://github.com/ccxt/ccxt/wiki/Certification) | [](https://ccxt.pro) |
|
145
145
|
| [](https://cex.io/r/0/up105393824/0/) | cex | [CEX.IO](https://cex.io/r/0/up105393824/0/) | [](https://cex.io/cex-api) | | [](https://ccxt.pro) |
|
146
146
|
| [](https://www.coinbase.com/join/58cbe25a355148797479dbd2) | coinbase | [Coinbase](https://www.coinbase.com/join/58cbe25a355148797479dbd2) | [](https://developers.coinbase.com/api/v2) | | [](https://ccxt.pro) |
|
147
|
-
| [](https://international.coinbase.com) | coinbaseinternational | [Coinbase International](https://international.coinbase.com) | [](https://docs.cloud.
|
147
|
+
| [](https://international.coinbase.com) | coinbaseinternational | [Coinbase International](https://international.coinbase.com) | [](https://docs.cloud.coinbase.com/intx/docs) | [](https://github.com/ccxt/ccxt/wiki/Certification) | [](https://ccxt.pro) |
|
148
148
|
| [](https://pro.coinbase.com/) | coinbasepro | [Coinbase Pro](https://pro.coinbase.com/) | [](https://docs.pro.coinbase.com) | | [](https://ccxt.pro) |
|
149
149
|
| [](https://coincheck.com) | coincheck | [coincheck](https://coincheck.com) | [](https://coincheck.com/documents/exchange/api) | | |
|
150
150
|
| [](https://www.coinex.com/register?refer_code=yw5fz) | coinex | [CoinEx](https://www.coinex.com/register?refer_code=yw5fz) | [](https://viabtc.github.io/coinex_api_en_doc) | [](https://github.com/ccxt/ccxt/wiki/Certification) | [](https://ccxt.pro) |
|
@@ -262,13 +262,13 @@ console.log(version, Object.keys(exchanges));
|
|
262
262
|
|
263
263
|
All-in-one browser bundle (dependencies included), served from a CDN of your choice:
|
264
264
|
|
265
|
-
* jsDelivr: https://cdn.jsdelivr.net/npm/ccxt@4.2.
|
266
|
-
* unpkg: https://unpkg.com/ccxt@4.2.
|
265
|
+
* jsDelivr: https://cdn.jsdelivr.net/npm/ccxt@4.2.80/dist/ccxt.browser.js
|
266
|
+
* unpkg: https://unpkg.com/ccxt@4.2.80/dist/ccxt.browser.js
|
267
267
|
|
268
268
|
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.
|
269
269
|
|
270
270
|
```HTML
|
271
|
-
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/ccxt@4.2.
|
271
|
+
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/ccxt@4.2.80/dist/ccxt.browser.js"></script>
|
272
272
|
```
|
273
273
|
|
274
274
|
Creates a global `ccxt` object:
|