diff --git a/freqtrade/configuration/arguments.py b/freqtrade/configuration/arguments.py index 89c86bdca..da9bef0b0 100644 --- a/freqtrade/configuration/arguments.py +++ b/freqtrade/configuration/arguments.py @@ -29,7 +29,7 @@ ARGS_HYPEROPT = ARGS_COMMON_OPTIMIZE + ["hyperopt", "hyperopt_path", ARGS_EDGE = ARGS_COMMON_OPTIMIZE + ["stoploss_range"] -ARGS_LIST_EXCHANGES = ["print_one_column"] +ARGS_LIST_EXCHANGES = ["print_one_column", "list_exchanges_all"] ARGS_CREATE_USERDIR = ["user_data_dir"] diff --git a/freqtrade/configuration/check_exchange.py b/freqtrade/configuration/check_exchange.py index 19c377732..5e811fb81 100644 --- a/freqtrade/configuration/check_exchange.py +++ b/freqtrade/configuration/check_exchange.py @@ -3,7 +3,7 @@ from typing import Any, Dict from freqtrade import OperationalException from freqtrade.exchange import (available_exchanges, get_exchange_bad_reason, - is_exchange_available, is_exchange_bad, + is_exchange_known_ccxt, is_exchange_bad, is_exchange_officially_supported) from freqtrade.state import RunMode @@ -31,15 +31,15 @@ def check_exchange(config: Dict[str, Any], check_for_bad: bool = True) -> bool: raise OperationalException( f'This command requires a configured exchange. You should either use ' f'`--exchange ` or specify a configuration file via `--config`.\n' - f'The following exchanges are supported by ccxt: ' + f'The following exchanges are available for Freqtrade: ' f'{", ".join(available_exchanges())}' ) - if not is_exchange_available(exchange): + if not is_exchange_known_ccxt(exchange): raise OperationalException( - f'Exchange "{exchange}" is not supported by ccxt ' + f'Exchange "{exchange}" is not known to the ccxt library ' f'and therefore not available for the bot.\n' - f'The following exchanges are supported by ccxt: ' + f'The following exchanges are available for Freqtrade: ' f'{", ".join(available_exchanges())}' ) @@ -51,8 +51,8 @@ def check_exchange(config: Dict[str, Any], check_for_bad: bool = True) -> bool: logger.info(f'Exchange "{exchange}" is officially supported ' f'by the Freqtrade development team.') else: - logger.warning(f'Exchange "{exchange}" is supported by ccxt ' - f'and therefore available for the bot but not officially supported ' + logger.warning(f'Exchange "{exchange}" is known to the the ccxt library, ' + f'available for the bot, but not officially supported ' f'by the Freqtrade development team. ' f'It may work flawlessly (please report back) or have serious issues. ' f'Use it at your own discretion.') diff --git a/freqtrade/configuration/cli_options.py b/freqtrade/configuration/cli_options.py index cb07dbdba..caf34b5e3 100644 --- a/freqtrade/configuration/cli_options.py +++ b/freqtrade/configuration/cli_options.py @@ -244,6 +244,11 @@ AVAILABLE_CLI_OPTIONS = { help='Print exchanges in one column.', action='store_true', ), + "list_exchanges_all": Arg( + '-a', '--all', + help='Print all exchanges known to the ccxt library.', + action='store_true', + ), # Script options "pairs": Arg( '-p', '--pairs', diff --git a/freqtrade/exchange/__init__.py b/freqtrade/exchange/__init__.py index 4037ca704..29971c897 100644 --- a/freqtrade/exchange/__init__.py +++ b/freqtrade/exchange/__init__.py @@ -1,8 +1,9 @@ from freqtrade.exchange.exchange import Exchange # noqa: F401 from freqtrade.exchange.exchange import (get_exchange_bad_reason, # noqa: F401 is_exchange_bad, - is_exchange_available, + is_exchange_known_ccxt, is_exchange_officially_supported, + ccxt_exchanges, available_exchanges) from freqtrade.exchange.exchange import (timeframe_to_seconds, # noqa: F401 timeframe_to_minutes, diff --git a/freqtrade/exchange/exchange.py b/freqtrade/exchange/exchange.py index 3c313ab54..0c307e7ed 100644 --- a/freqtrade/exchange/exchange.py +++ b/freqtrade/exchange/exchange.py @@ -235,7 +235,7 @@ class Exchange: # Find matching class for the given exchange name name = exchange_config['name'] - if not is_exchange_available(name, ccxt_module): + if not is_exchange_known_ccxt(name, ccxt_module): raise OperationalException(f'Exchange {name} is not supported by ccxt') ex_config = { @@ -838,18 +838,29 @@ def get_exchange_bad_reason(exchange_name: str) -> str: return BAD_EXCHANGES.get(exchange_name, "") -def is_exchange_available(exchange_name: str, ccxt_module=None) -> bool: - return exchange_name in available_exchanges(ccxt_module) +def is_exchange_known_ccxt(exchange_name: str, ccxt_module=None) -> bool: + return exchange_name in ccxt_exchanges(ccxt_module) def is_exchange_officially_supported(exchange_name: str) -> bool: return exchange_name in ['bittrex', 'binance'] -def available_exchanges(ccxt_module=None) -> List[str]: +def ccxt_exchanges(ccxt_module=None) -> List[str]: + """ + Return the list of all exchanges known to ccxt + """ return ccxt_module.exchanges if ccxt_module is not None else ccxt.exchanges +def available_exchanges(ccxt_module=None) -> List[str]: + """ + Return exchanges available to the bot, i.e. non-bad exchanges in the ccxt list + """ + exchanges = ccxt_exchanges(ccxt_module) + return [x for x in exchanges if not is_exchange_bad(x)] + + def timeframe_to_seconds(ticker_interval: str) -> int: """ Translates the timeframe interval value written in the human readable diff --git a/freqtrade/utils.py b/freqtrade/utils.py index 6ce5e888c..3a11ca4fc 100644 --- a/freqtrade/utils.py +++ b/freqtrade/utils.py @@ -9,7 +9,7 @@ from freqtrade import OperationalException from freqtrade.configuration import Configuration, TimeRange from freqtrade.configuration.directory_operations import create_userdata_dir from freqtrade.data.history import refresh_backtest_ohlcv_data -from freqtrade.exchange import available_exchanges +from freqtrade.exchange import available_exchanges, ccxt_exchanges from freqtrade.resolvers import ExchangeResolver from freqtrade.state import RunMode @@ -39,12 +39,14 @@ def start_list_exchanges(args: Dict[str, Any]) -> None: :param args: Cli args from Arguments() :return: None """ - + exchanges = ccxt_exchanges() if args['list_exchanges_all'] else available_exchanges() if args['print_one_column']: - print('\n'.join(available_exchanges())) + print('\n'.join(exchanges)) else: - print(f"Exchanges supported by ccxt and available for Freqtrade: " - f"{', '.join(available_exchanges())}") + if args['list_exchanges_all']: + print(f"All exchanges supported by the ccxt library: {', '.join(exchanges)}") + else: + print(f"Exchanges available for Freqtrade: {', '.join(exchanges)}") def start_create_userdir(args: Dict[str, Any]) -> None: