diff --git a/freqtrade/commands/data_commands.py b/freqtrade/commands/data_commands.py index bcef1c252..ed1571002 100644 --- a/freqtrade/commands/data_commands.py +++ b/freqtrade/commands/data_commands.py @@ -52,7 +52,7 @@ def start_download_data(args: Dict[str, Any]) -> None: pairs_not_available: List[str] = [] # Init exchange - exchange = ExchangeResolver.load_exchange(config['exchange']['name'], config, validate=False) + exchange = ExchangeResolver.load_exchange(config, validate=False) markets = [p for p, m in exchange.markets.items() if market_is_active(m) or config.get('include_inactive')] @@ -125,7 +125,7 @@ def start_convert_trades(args: Dict[str, Any]) -> None: "Please check the documentation on how to configure this.") # Init exchange - exchange = ExchangeResolver.load_exchange(config['exchange']['name'], config, validate=False) + exchange = ExchangeResolver.load_exchange(config, validate=False) # Manual validations of relevant settings if not config['exchange'].get('skip_pair_validation', False): exchange.validate_pairs(config['pairs']) diff --git a/freqtrade/commands/list_commands.py b/freqtrade/commands/list_commands.py index 4e0623081..3358f8cc8 100644 --- a/freqtrade/commands/list_commands.py +++ b/freqtrade/commands/list_commands.py @@ -114,7 +114,7 @@ def start_list_timeframes(args: Dict[str, Any]) -> None: config['timeframe'] = None # Init exchange - exchange = ExchangeResolver.load_exchange(config['exchange']['name'], config, validate=False) + exchange = ExchangeResolver.load_exchange(config, validate=False) if args['print_one_column']: print('\n'.join(exchange.timeframes)) @@ -133,7 +133,7 @@ def start_list_markets(args: Dict[str, Any], pairs_only: bool = False) -> None: config = setup_utils_configuration(args, RunMode.UTIL_EXCHANGE) # Init exchange - exchange = ExchangeResolver.load_exchange(config['exchange']['name'], config, validate=False) + exchange = ExchangeResolver.load_exchange(config, validate=False) # By default only active pairs/markets are to be shown active_only = not args.get('list_pairs_all', False) diff --git a/freqtrade/commands/pairlist_commands.py b/freqtrade/commands/pairlist_commands.py index 9f7a5958e..a815cd5f3 100644 --- a/freqtrade/commands/pairlist_commands.py +++ b/freqtrade/commands/pairlist_commands.py @@ -18,7 +18,7 @@ def start_test_pairlist(args: Dict[str, Any]) -> None: from freqtrade.plugins.pairlistmanager import PairListManager config = setup_utils_configuration(args, RunMode.UTIL_EXCHANGE) - exchange = ExchangeResolver.load_exchange(config['exchange']['name'], config, validate=False) + exchange = ExchangeResolver.load_exchange(config, validate=False) quote_currencies = args.get('quote_currencies') if not quote_currencies: diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index 5e1e7d5f8..9fb433dc0 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -70,7 +70,7 @@ class FreqtradeBot(LoggingMixin): validate_config_consistency(config) self.exchange = ExchangeResolver.load_exchange( - self.config['exchange']['name'], self.config, load_leverage_tiers=True) + self.config, load_leverage_tiers=True) init_db(self.config['db_url']) diff --git a/freqtrade/optimize/backtesting.py b/freqtrade/optimize/backtesting.py index 622fe4444..d77fc469b 100644 --- a/freqtrade/optimize/backtesting.py +++ b/freqtrade/optimize/backtesting.py @@ -89,8 +89,7 @@ class Backtesting: self.rejected_df: Dict[str, Dict] = {} self._exchange_name = self.config['exchange']['name'] - self.exchange = ExchangeResolver.load_exchange( - self._exchange_name, self.config, load_leverage_tiers=True) + self.exchange = ExchangeResolver.load_exchange(self.config, load_leverage_tiers=True) self.dataprovider = DataProvider(self.config, self.exchange) if self.config.get('strategy_list'): diff --git a/freqtrade/optimize/edge_cli.py b/freqtrade/optimize/edge_cli.py index 2eb1c53f5..07c54d720 100644 --- a/freqtrade/optimize/edge_cli.py +++ b/freqtrade/optimize/edge_cli.py @@ -32,7 +32,7 @@ class EdgeCli: # Ensure using dry-run self.config['dry_run'] = True self.config['stake_amount'] = constants.UNLIMITED_STAKE_AMOUNT - self.exchange = ExchangeResolver.load_exchange(self.config['exchange']['name'], self.config) + self.exchange = ExchangeResolver.load_exchange(self.config) self.strategy = StrategyResolver.load_strategy(self.config) self.strategy.dp = DataProvider(config, self.exchange) diff --git a/freqtrade/plot/plotting.py b/freqtrade/plot/plotting.py index e415c4911..7fd20f041 100644 --- a/freqtrade/plot/plotting.py +++ b/freqtrade/plot/plotting.py @@ -633,7 +633,7 @@ def load_and_plot_trades(config: Config): """ strategy = StrategyResolver.load_strategy(config) - exchange = ExchangeResolver.load_exchange(config['exchange']['name'], config) + exchange = ExchangeResolver.load_exchange(config) IStrategy.dp = DataProvider(config, exchange) strategy.ft_bot_start() strategy.bot_loop_start(datetime.now(timezone.utc)) @@ -678,7 +678,7 @@ def plot_profit(config: Config) -> None: if 'timeframe' not in config: raise OperationalException('Timeframe must be set in either config or via --timeframe.') - exchange = ExchangeResolver.load_exchange(config['exchange']['name'], config) + exchange = ExchangeResolver.load_exchange(config) plot_elements = init_plotscript(config, list(exchange.markets)) trades = plot_elements['trades'] # Filter trades to relevant pairs diff --git a/freqtrade/resolvers/exchange_resolver.py b/freqtrade/resolvers/exchange_resolver.py index 54a488e8d..e888028dc 100644 --- a/freqtrade/resolvers/exchange_resolver.py +++ b/freqtrade/resolvers/exchange_resolver.py @@ -19,13 +19,14 @@ class ExchangeResolver(IResolver): object_type = Exchange @staticmethod - def load_exchange(exchange_name: str, config: Config, validate: bool = True, + def load_exchange(config: Config, validate: bool = True, load_leverage_tiers: bool = False) -> Exchange: """ Load the custom class from config parameter :param exchange_name: name of the Exchange to load :param config: configuration dictionary """ + exchange_name: str = config['exchange']['name'] # Map exchange name to avoid duplicate classes for identical exchanges exchange_name = MAP_EXCHANGE_CHILDCLASS.get(exchange_name, exchange_name) exchange_name = exchange_name.title() diff --git a/freqtrade/rpc/api_server/deps.py b/freqtrade/rpc/api_server/deps.py index f5b1bcd74..bfc1e698c 100644 --- a/freqtrade/rpc/api_server/deps.py +++ b/freqtrade/rpc/api_server/deps.py @@ -46,7 +46,7 @@ def get_exchange(config=Depends(get_config)): if not ApiServer._exchange: from freqtrade.resolvers import ExchangeResolver ApiServer._exchange = ExchangeResolver.load_exchange( - config['exchange']['name'], config, load_leverage_tiers=False) + config, load_leverage_tiers=False) return ApiServer._exchange diff --git a/tests/conftest.py b/tests/conftest.py index 4b725e2db..88fb0bb30 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -181,7 +181,7 @@ def get_patched_exchange(mocker, config, api_mock=None, id='binance', patch_exchange(mocker, api_mock, id, mock_markets, mock_supported_modes) config['exchange']['name'] = id try: - exchange = ExchangeResolver.load_exchange(id, config, load_leverage_tiers=True) + exchange = ExchangeResolver.load_exchange(config, load_leverage_tiers=True) except ImportError: exchange = Exchange(config) return exchange diff --git a/tests/exchange/test_ccxt_compat.py b/tests/exchange/test_ccxt_compat.py index 60855ca54..76a63e57b 100644 --- a/tests/exchange/test_ccxt_compat.py +++ b/tests/exchange/test_ccxt_compat.py @@ -302,7 +302,7 @@ def exchange(request, exchange_conf): exchange_conf, EXCHANGES[request.param].get('use_ci_proxy', False)) exchange_conf['exchange']['name'] = request.param exchange_conf['stake_currency'] = EXCHANGES[request.param]['stake_currency'] - exchange = ExchangeResolver.load_exchange(request.param, exchange_conf, validate=True) + exchange = ExchangeResolver.load_exchange(exchange_conf, validate=True) yield exchange, request.param diff --git a/tests/exchange/test_exchange.py b/tests/exchange/test_exchange.py index 399442b08..bfe3a9b1d 100644 --- a/tests/exchange/test_exchange.py +++ b/tests/exchange/test_exchange.py @@ -228,27 +228,30 @@ def test_exchange_resolver(default_conf, mocker, caplog): mocker.patch(f'{EXMS}.validate_timeframes') mocker.patch(f'{EXMS}.validate_stakecurrency') mocker.patch(f'{EXMS}.validate_pricing') - - exchange = ExchangeResolver.load_exchange('zaif', default_conf) + default_conf['exchange']['name'] = 'zaif' + exchange = ExchangeResolver.load_exchange(default_conf) assert isinstance(exchange, Exchange) assert log_has_re(r"No .* specific subclass found. Using the generic class instead.", caplog) caplog.clear() - exchange = ExchangeResolver.load_exchange('Bittrex', default_conf) + default_conf['exchange']['name'] = 'Bittrex' + exchange = ExchangeResolver.load_exchange(default_conf) assert isinstance(exchange, Exchange) assert isinstance(exchange, Bittrex) assert not log_has_re(r"No .* specific subclass found. Using the generic class instead.", caplog) caplog.clear() - exchange = ExchangeResolver.load_exchange('kraken', default_conf) + default_conf['exchange']['name'] = 'kraken' + exchange = ExchangeResolver.load_exchange(default_conf) assert isinstance(exchange, Exchange) assert isinstance(exchange, Kraken) assert not isinstance(exchange, Binance) assert not log_has_re(r"No .* specific subclass found. Using the generic class instead.", caplog) - exchange = ExchangeResolver.load_exchange('binance', default_conf) + default_conf['exchange']['name'] = 'binance' + exchange = ExchangeResolver.load_exchange(default_conf) assert isinstance(exchange, Exchange) assert isinstance(exchange, Binance) assert not isinstance(exchange, Kraken) @@ -257,7 +260,8 @@ def test_exchange_resolver(default_conf, mocker, caplog): caplog) # Test mapping - exchange = ExchangeResolver.load_exchange('binanceus', default_conf) + default_conf['exchange']['name'] = 'binanceus' + exchange = ExchangeResolver.load_exchange(default_conf) assert isinstance(exchange, Exchange) assert isinstance(exchange, Binance) assert not isinstance(exchange, Kraken) @@ -990,19 +994,20 @@ def test_validate_pricing(default_conf, mocker): mocker.patch(f'{EXMS}.validate_timeframes') mocker.patch(f'{EXMS}.validate_stakecurrency') mocker.patch(f'{EXMS}.name', 'Binance') - ExchangeResolver.load_exchange('binance', default_conf) + default_conf['exchange']['name'] = 'binance' + ExchangeResolver.load_exchange(default_conf) has.update({'fetchTicker': False}) with pytest.raises(OperationalException, match="Ticker pricing not available for .*"): - ExchangeResolver.load_exchange('binance', default_conf) + ExchangeResolver.load_exchange(default_conf) has.update({'fetchTicker': True}) default_conf['exit_pricing']['use_order_book'] = True - ExchangeResolver.load_exchange('binance', default_conf) + ExchangeResolver.load_exchange(default_conf) has.update({'fetchL2OrderBook': False}) with pytest.raises(OperationalException, match="Orderbook not available for .*"): - ExchangeResolver.load_exchange('binance', default_conf) + ExchangeResolver.load_exchange(default_conf) has.update({'fetchL2OrderBook': True}) @@ -1011,7 +1016,7 @@ def test_validate_pricing(default_conf, mocker): default_conf['margin_mode'] = MarginMode.ISOLATED with pytest.raises(OperationalException, match="Ticker pricing not available for .*"): - ExchangeResolver.load_exchange('binance', default_conf) + ExchangeResolver.load_exchange(default_conf) def test_validate_ordertypes(default_conf, mocker): @@ -1091,12 +1096,13 @@ def test_validate_ordertypes_stop_advanced(default_conf, mocker, exchange_name, 'stoploss_on_exchange': True, 'stoploss_price_type': stopadv, } + default_conf['exchange']['name'] = exchange_name if expected: - ExchangeResolver.load_exchange(exchange_name, default_conf) + ExchangeResolver.load_exchange(default_conf) else: with pytest.raises(OperationalException, match=r'On exchange stoploss price type is not supported for .*'): - ExchangeResolver.load_exchange(exchange_name, default_conf) + ExchangeResolver.load_exchange(default_conf) def test_validate_order_types_not_in_config(default_conf, mocker):