diff --git a/freqtrade/exchange/exchange.py b/freqtrade/exchange/exchange.py index 4b2d52a68..85a77fe5e 100644 --- a/freqtrade/exchange/exchange.py +++ b/freqtrade/exchange/exchange.py @@ -23,7 +23,7 @@ from freqtrade.constants import (DEFAULT_AMOUNT_RESERVE_PERCENT, NON_OPEN_EXCHAN BuySell, Config, EntryExit, ExchangeConfig, ListPairsWithTimeframes, MakerTaker, OBLiteral, PairWithTimeframe) from freqtrade.data.converter import clean_ohlcv_dataframe, ohlcv_to_dataframe, trades_dict_to_list -from freqtrade.enums import OPTIMIZE_MODES, CandleType, MarginMode, PriceType, TradingMode +from freqtrade.enums import OPTIMIZE_MODES, CandleType, MarginMode, PriceType, RunMode, TradingMode from freqtrade.exceptions import (DDosProtection, ExchangeError, InsufficientFundsError, InvalidOrderException, OperationalException, PricingError, RetryableOrderError, TemporaryError) @@ -595,7 +595,11 @@ class Exchange: raise OperationalException( f"Invalid timeframe '{timeframe}'. This exchange supports: {self.timeframes}") - if timeframe and timeframe_to_minutes(timeframe) < 1: + if ( + timeframe + and self._config['runmode'] != RunMode.UTIL_EXCHANGE + and timeframe_to_minutes(timeframe) < 1 + ): raise OperationalException("Timeframes < 1m are currently not supported by Freqtrade.") def validate_ordertypes(self, order_types: Dict) -> None: diff --git a/tests/exchange/test_exchange.py b/tests/exchange/test_exchange.py index f686959fc..29e458cdd 100644 --- a/tests/exchange/test_exchange.py +++ b/tests/exchange/test_exchange.py @@ -9,7 +9,7 @@ import ccxt import pytest from pandas import DataFrame -from freqtrade.enums import CandleType, MarginMode, TradingMode +from freqtrade.enums import CandleType, MarginMode, RunMode, TradingMode from freqtrade.exceptions import (DDosProtection, DependencyException, ExchangeError, InsufficientFundsError, InvalidOrderException, OperationalException, PricingError, TemporaryError) @@ -796,7 +796,9 @@ def test_validate_timeframes_failed(default_conf, mocker): mocker.patch(f'{EXMS}._init_ccxt', MagicMock(return_value=api_mock)) mocker.patch(f'{EXMS}._load_markets', MagicMock(return_value={})) - mocker.patch(f'{EXMS}.validate_pairs', MagicMock()) + mocker.patch(f'{EXMS}.validate_pairs') + mocker.patch(f'{EXMS}.validate_stakecurrency') + mocker.patch(f'{EXMS}.validate_pricing') with pytest.raises(OperationalException, match=r"Invalid timeframe '3m'. This exchange supports.*"): Exchange(default_conf) @@ -806,6 +808,10 @@ def test_validate_timeframes_failed(default_conf, mocker): match=r"Timeframes < 1m are currently not supported by Freqtrade."): Exchange(default_conf) + # Will not raise an exception in util mode. + default_conf['runmode'] = RunMode.UTIL_EXCHANGE + Exchange(default_conf) + def test_validate_timeframes_emulated_ohlcv_1(default_conf, mocker): default_conf["timeframe"] = "3m"