Update exchange validation to use "validate_exchange".
This commit is contained in:
parent
5ed7828446
commit
a3b4667f7c
@ -2,8 +2,8 @@ import logging
|
|||||||
from typing import Any, Dict
|
from typing import Any, Dict
|
||||||
|
|
||||||
from freqtrade.exceptions import OperationalException
|
from freqtrade.exceptions import OperationalException
|
||||||
from freqtrade.exchange import (available_exchanges, get_exchange_bad_reason, is_exchange_bad,
|
from freqtrade.exchange import (available_exchanges, is_exchange_known_ccxt,
|
||||||
is_exchange_known_ccxt, is_exchange_officially_supported)
|
is_exchange_officially_supported, validate_exchange)
|
||||||
from freqtrade.state import RunMode
|
from freqtrade.state import RunMode
|
||||||
|
|
||||||
|
|
||||||
@ -57,9 +57,13 @@ def check_exchange(config: Dict[str, Any], check_for_bad: bool = True) -> bool:
|
|||||||
f'{", ".join(available_exchanges())}'
|
f'{", ".join(available_exchanges())}'
|
||||||
)
|
)
|
||||||
|
|
||||||
if check_for_bad and is_exchange_bad(exchange):
|
valid, reason = validate_exchange(exchange)
|
||||||
raise OperationalException(f'Exchange "{exchange}" is known to not work with the bot yet. '
|
if not valid:
|
||||||
f'Reason: {get_exchange_bad_reason(exchange)}')
|
if check_for_bad:
|
||||||
|
raise OperationalException(f'Exchange "{exchange}" will not work with Freqtrade. '
|
||||||
|
f'Reason: {reason}')
|
||||||
|
else:
|
||||||
|
logger.warning(f'Exchange "{exchange}" will not work with Freqtrade. Reason: {reason}')
|
||||||
|
|
||||||
if is_exchange_officially_supported(exchange):
|
if is_exchange_officially_supported(exchange):
|
||||||
logger.info(f'Exchange "{exchange}" is officially supported '
|
logger.info(f'Exchange "{exchange}" is officially supported '
|
||||||
|
@ -8,10 +8,10 @@ from freqtrade.exchange.binance import Binance
|
|||||||
from freqtrade.exchange.bittrex import Bittrex
|
from freqtrade.exchange.bittrex import Bittrex
|
||||||
from freqtrade.exchange.bybit import Bybit
|
from freqtrade.exchange.bybit import Bybit
|
||||||
from freqtrade.exchange.exchange import (available_exchanges, ccxt_exchanges,
|
from freqtrade.exchange.exchange import (available_exchanges, ccxt_exchanges,
|
||||||
get_exchange_bad_reason, is_exchange_bad,
|
|
||||||
is_exchange_known_ccxt, is_exchange_officially_supported,
|
is_exchange_known_ccxt, is_exchange_officially_supported,
|
||||||
market_is_active, timeframe_to_minutes, timeframe_to_msecs,
|
market_is_active, timeframe_to_minutes, timeframe_to_msecs,
|
||||||
timeframe_to_next_date, timeframe_to_prev_date,
|
timeframe_to_next_date, timeframe_to_prev_date,
|
||||||
timeframe_to_seconds, validate_exchanges)
|
timeframe_to_seconds, validate_exchange,
|
||||||
|
validate_exchanges)
|
||||||
from freqtrade.exchange.ftx import Ftx
|
from freqtrade.exchange.ftx import Ftx
|
||||||
from freqtrade.exchange.kraken import Kraken
|
from freqtrade.exchange.kraken import Kraken
|
||||||
|
@ -1307,14 +1307,6 @@ class Exchange:
|
|||||||
self.calculate_fee_rate(order))
|
self.calculate_fee_rate(order))
|
||||||
|
|
||||||
|
|
||||||
def is_exchange_bad(exchange_name: str) -> bool:
|
|
||||||
return exchange_name in BAD_EXCHANGES
|
|
||||||
|
|
||||||
|
|
||||||
def get_exchange_bad_reason(exchange_name: str) -> str:
|
|
||||||
return BAD_EXCHANGES.get(exchange_name, "")
|
|
||||||
|
|
||||||
|
|
||||||
def is_exchange_known_ccxt(exchange_name: str, ccxt_module: CcxtModuleType = None) -> bool:
|
def is_exchange_known_ccxt(exchange_name: str, ccxt_module: CcxtModuleType = None) -> bool:
|
||||||
return exchange_name in ccxt_exchanges(ccxt_module)
|
return exchange_name in ccxt_exchanges(ccxt_module)
|
||||||
|
|
||||||
@ -1335,18 +1327,21 @@ def available_exchanges(ccxt_module: CcxtModuleType = None) -> List[str]:
|
|||||||
Return exchanges available to the bot, i.e. non-bad exchanges in the ccxt list
|
Return exchanges available to the bot, i.e. non-bad exchanges in the ccxt list
|
||||||
"""
|
"""
|
||||||
exchanges = ccxt_exchanges(ccxt_module)
|
exchanges = ccxt_exchanges(ccxt_module)
|
||||||
return [x for x in exchanges if not is_exchange_bad(x)]
|
return [x for x in exchanges if validate_exchange(x)[0]]
|
||||||
|
|
||||||
|
|
||||||
def validate_exchange(exchange: str) -> Tuple[bool, str]:
|
def validate_exchange(exchange: str) -> Tuple[bool, str]:
|
||||||
ex_mod = getattr(ccxt, exchange.lower())()
|
ex_mod = getattr(ccxt, exchange.lower())()
|
||||||
if not ex_mod or not ex_mod.has:
|
if not ex_mod or not ex_mod.has:
|
||||||
return False, ''
|
return False, ''
|
||||||
missing = [k for k in EXCHANGE_HAS_REQUIRED if not ex_mod.has.get(k)]
|
missing = [k for k in EXCHANGE_HAS_REQUIRED if ex_mod.has.get(k) is not True]
|
||||||
if missing:
|
if missing:
|
||||||
return False, f"missing: {', '.join(missing)}"
|
return False, f"missing: {', '.join(missing)}"
|
||||||
|
|
||||||
missing_opt = [k for k in EXCHANGE_HAS_OPTIONAL if not ex_mod.has.get(k)]
|
missing_opt = [k for k in EXCHANGE_HAS_OPTIONAL if not ex_mod.has.get(k)]
|
||||||
|
|
||||||
|
if exchange.lower() in BAD_EXCHANGES:
|
||||||
|
return False, BAD_EXCHANGES.get(exchange.lower(), '')
|
||||||
if missing_opt:
|
if missing_opt:
|
||||||
return True, f"missing opt: {', '.join(missing_opt)}"
|
return True, f"missing opt: {', '.join(missing_opt)}"
|
||||||
|
|
||||||
|
@ -565,7 +565,7 @@ def test_check_exchange(default_conf, caplog) -> None:
|
|||||||
# Test a 'bad' exchange, which known to have serious problems
|
# Test a 'bad' exchange, which known to have serious problems
|
||||||
default_conf.get('exchange').update({'name': 'bitmex'})
|
default_conf.get('exchange').update({'name': 'bitmex'})
|
||||||
with pytest.raises(OperationalException,
|
with pytest.raises(OperationalException,
|
||||||
match=r"Exchange .* is known to not work with the bot yet.*"):
|
match=r"Exchange .* will not work with Freqtrade\..*"):
|
||||||
check_exchange(default_conf)
|
check_exchange(default_conf)
|
||||||
caplog.clear()
|
caplog.clear()
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user