diff --git a/freqtrade/exchange/exchange.py b/freqtrade/exchange/exchange.py index b649a7b65..2350c752f 100644 --- a/freqtrade/exchange/exchange.py +++ b/freqtrade/exchange/exchange.py @@ -269,6 +269,12 @@ class Exchange(object): """ Checks if ticker interval from config is a supported timeframe on the exchange """ + if not hasattr(self._api, "timeframes"): + # If timeframes is missing, the exchange probably has no fetchOHLCV method. + # Therefore we also show that. + raise OperationalException( + f"This exchange ({self.name}) does not have a `timeframes` attribute and " + f"is therefore not supported. fetchOHLCV: {self.exchange_has('fetchOHLCV')}") timeframes = self._api.timeframes if timeframe not in timeframes: raise OperationalException( diff --git a/freqtrade/resolvers/exchange_resolver.py b/freqtrade/resolvers/exchange_resolver.py index 25a86dd0e..089f6306f 100644 --- a/freqtrade/resolvers/exchange_resolver.py +++ b/freqtrade/resolvers/exchange_resolver.py @@ -28,6 +28,7 @@ class ExchangeResolver(IResolver): except ImportError: logger.info( f"No {exchange_name} specific subclass found. Using the generic class instead.") + if not hasattr(self, "exchange"): self.exchange = Exchange(config) def _load_exchange( diff --git a/freqtrade/tests/exchange/test_exchange.py b/freqtrade/tests/exchange/test_exchange.py index 48a8538a9..b74882ad4 100644 --- a/freqtrade/tests/exchange/test_exchange.py +++ b/freqtrade/tests/exchange/test_exchange.py @@ -396,6 +396,23 @@ def test_validate_timeframes_failed(default_conf, mocker): Exchange(default_conf) +def test_validate_timeframes_emulated_ohlcv(default_conf, mocker): + default_conf["ticker_interval"] = "3m" + api_mock = MagicMock() + id_mock = PropertyMock(return_value='test_exchange') + type(api_mock).id = id_mock + + # delete timeframes so magicmock does not autocreate it + del api_mock.timeframes + + mocker.patch('freqtrade.exchange.Exchange._init_ccxt', MagicMock(return_value=api_mock)) + mocker.patch('freqtrade.exchange.Exchange._load_markets', MagicMock(return_value={})) + mocker.patch('freqtrade.exchange.Exchange.validate_pairs', MagicMock()) + with pytest.raises(OperationalException, + match=r'This exchange (.*) does not have a `timeframes` attribute and*'): + Exchange(default_conf) + + def test_validate_timeframes_not_in_config(default_conf, mocker): del default_conf["ticker_interval"] api_mock = MagicMock()