diff --git a/freqtrade/exchange/exchange.py b/freqtrade/exchange/exchange.py index a3a548176..8aab225c6 100644 --- a/freqtrade/exchange/exchange.py +++ b/freqtrade/exchange/exchange.py @@ -187,6 +187,11 @@ class Exchange: def timeframes(self) -> List[str]: return list((self._api.timeframes or {}).keys()) + @property + def ohlcv_candle_limit(self) -> int: + """exchange ohlcv candle limit""" + return int(self._ohlcv_candle_limit) + @property def markets(self) -> Dict: """exchange ccxt markets""" diff --git a/freqtrade/pairlist/AgeFilter.py b/freqtrade/pairlist/AgeFilter.py index b489a59bc..101f19cbe 100644 --- a/freqtrade/pairlist/AgeFilter.py +++ b/freqtrade/pairlist/AgeFilter.py @@ -23,6 +23,16 @@ class AgeFilter(IPairList): super().__init__(exchange, pairlistmanager, config, pairlistconfig, pairlist_pos) self._min_days_listed = pairlistconfig.get('min_days_listed', 10) + + if self._min_days_listed < 1: + self.log_on_refresh(logger.info, "min_days_listed must be >= 1, " + "ignoring filter") + if self._min_days_listed > exchange.ohlcv_candle_limit: + self._min_days_listed = min(self._min_days_listed, exchange.ohlcv_candle_limit) + self.log_on_refresh(logger.info, "min_days_listed exceeds " + "exchange max request size " + f"({exchange.ohlcv_candle_limit}), using " + f"min_days_listed={self._min_days_listed}") self._enabled = self._min_days_listed >= 1 @property diff --git a/tests/pairlist/test_pairlist.py b/tests/pairlist/test_pairlist.py index a2644fe8c..6b96501c9 100644 --- a/tests/pairlist/test_pairlist.py +++ b/tests/pairlist/test_pairlist.py @@ -524,6 +524,38 @@ def test_volumepairlist_caching(mocker, markets, whitelist_conf, tickers): assert freqtrade.pairlists._pairlist_handlers[0]._last_refresh == lrf +def test_agefilter_min_days_listed_too_small(mocker, default_conf, markets, tickers, caplog) -> None: + default_conf['pairlists'] = [{'method': 'VolumePairList', 'number_assets': 10}, + {'method': 'AgeFilter', 'min_days_listed': -1}] + + mocker.patch.multiple('freqtrade.exchange.Exchange', + markets=PropertyMock(return_value=markets), + exchange_has=MagicMock(return_value=True), + get_tickers=tickers + ) + + get_patched_freqtradebot(mocker, default_conf) + + assert log_has_re(r'min_days_listed must be >= 1, ' + r'ignoring filter', caplog) + + +def test_agefilter_min_days_listed_too_large(mocker, default_conf, markets, tickers, caplog) -> None: + default_conf['pairlists'] = [{'method': 'VolumePairList', 'number_assets': 10}, + {'method': 'AgeFilter', 'min_days_listed': 99999}] + + mocker.patch.multiple('freqtrade.exchange.Exchange', + markets=PropertyMock(return_value=markets), + exchange_has=MagicMock(return_value=True), + get_tickers=tickers + ) + + get_patched_freqtradebot(mocker, default_conf) + + assert log_has_re(r'^min_days_listed exceeds ' + r'exchange max request size', caplog) + + def test_agefilter_caching(mocker, markets, whitelist_conf_3, tickers, ohlcv_history_list): mocker.patch.multiple('freqtrade.exchange.Exchange',