Merge pull request #3453 from freqtrade/fix/3363

Backtesting should load pairlists after the strategy
This commit is contained in:
hroff-1902 2020-06-29 21:53:33 +03:00 committed by GitHub
commit 02c0488d45
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 67 additions and 15 deletions

View File

@ -65,20 +65,6 @@ class Backtesting:
self.strategylist: List[IStrategy] = []
self.exchange = ExchangeResolver.load_exchange(self.config['exchange']['name'], self.config)
self.pairlists = PairListManager(self.exchange, self.config)
if 'VolumePairList' in self.pairlists.name_list:
raise OperationalException("VolumePairList not allowed for backtesting.")
self.pairlists.refresh_pairlist()
if len(self.pairlists.whitelist) == 0:
raise OperationalException("No pair in whitelist.")
if config.get('fee'):
self.fee = config['fee']
else:
self.fee = self.exchange.get_fee(symbol=self.pairlists.whitelist[0])
if self.config.get('runmode') != RunMode.HYPEROPT:
self.dataprovider = DataProvider(self.config, self.exchange)
IStrategy.dp = self.dataprovider
@ -101,6 +87,25 @@ class Backtesting:
self.timeframe = str(self.config.get('timeframe'))
self.timeframe_min = timeframe_to_minutes(self.timeframe)
self.pairlists = PairListManager(self.exchange, self.config)
if 'VolumePairList' in self.pairlists.name_list:
raise OperationalException("VolumePairList not allowed for backtesting.")
if len(self.strategylist) > 1 and 'PrecisionFilter' in self.pairlists.name_list:
raise OperationalException(
"PrecisionFilter not allowed for backtesting multiple strategies."
)
self.pairlists.refresh_pairlist()
if len(self.pairlists.whitelist) == 0:
raise OperationalException("No pair in whitelist.")
if config.get('fee'):
self.fee = config['fee']
else:
self.fee = self.exchange.get_fee(symbol=self.pairlists.whitelist[0])
# Get maximum required startup period
self.required_startup = max([strat.startup_candle_count for strat in self.strategylist])
# Load one (first) strategy

View File

@ -5,7 +5,7 @@ import logging
from typing import Any, Dict
from freqtrade.pairlist.IPairList import IPairList
from freqtrade.exceptions import OperationalException
logger = logging.getLogger(__name__)
@ -17,6 +17,10 @@ class PrecisionFilter(IPairList):
pairlist_pos: int) -> None:
super().__init__(exchange, pairlistmanager, config, pairlistconfig, pairlist_pos)
if 'stoploss' not in self._config:
raise OperationalException(
'PrecisionFilter can only work with stoploss defined. Please add the '
'stoploss key to your configuration (overwrites eventual strategy settings).')
self._stoploss = self._config['stoploss']
self._enabled = self._stoploss != 0

View File

@ -401,6 +401,38 @@ def test_backtesting_no_pair_left(default_conf, mocker, caplog, testdatadir) ->
Backtesting(default_conf)
def test_backtesting_pairlist_list(default_conf, mocker, caplog, testdatadir, tickers) -> None:
mocker.patch('freqtrade.exchange.Exchange.exchange_has', MagicMock(return_value=True))
mocker.patch('freqtrade.exchange.Exchange.get_tickers', tickers)
mocker.patch('freqtrade.exchange.Exchange.price_to_precision', lambda s, x, y: y)
mocker.patch('freqtrade.data.history.get_timerange', get_timerange)
patch_exchange(mocker)
mocker.patch('freqtrade.optimize.backtesting.Backtesting.backtest')
mocker.patch('freqtrade.pairlist.pairlistmanager.PairListManager.whitelist',
PropertyMock(return_value=['XRP/BTC']))
mocker.patch('freqtrade.pairlist.pairlistmanager.PairListManager.refresh_pairlist')
default_conf['ticker_interval'] = "1m"
default_conf['datadir'] = testdatadir
default_conf['export'] = None
# Use stoploss from strategy
del default_conf['stoploss']
default_conf['timerange'] = '20180101-20180102'
default_conf['pairlists'] = [{"method": "VolumePairList", "number_assets": 5}]
with pytest.raises(OperationalException, match='VolumePairList not allowed for backtesting.'):
Backtesting(default_conf)
default_conf['pairlists'] = [{"method": "StaticPairList"}, {"method": "PrecisionFilter"}, ]
Backtesting(default_conf)
# Multiple strategies
default_conf['strategy_list'] = ['DefaultStrategy', 'TestStrategyLegacy']
with pytest.raises(OperationalException,
match='PrecisionFilter not allowed for backtesting multiple strategies.'):
Backtesting(default_conf)
def test_backtest(default_conf, fee, mocker, testdatadir) -> None:
default_conf['ask_strategy']['use_sell_signal'] = False
mocker.patch('freqtrade.exchange.Exchange.get_fee', fee)

View File

@ -407,6 +407,17 @@ def test_VolumePairList_whitelist_gen(mocker, whitelist_conf, shitcoinmarkets, t
assert not log_has(logmsg, caplog)
def test_PrecisionFilter_error(mocker, whitelist_conf, tickers) -> None:
whitelist_conf['pairlists'] = [{"method": "StaticPairList"}, {"method": "PrecisionFilter"}]
del whitelist_conf['stoploss']
mocker.patch('freqtrade.exchange.Exchange.exchange_has', MagicMock(return_value=True))
with pytest.raises(OperationalException,
match=r"PrecisionFilter can only work with stoploss defined\..*"):
PairListManager(MagicMock, whitelist_conf)
def test_gen_pair_whitelist_not_supported(mocker, default_conf, tickers) -> None:
default_conf['pairlists'] = [{'method': 'VolumePairList', 'number_assets': 10}]