Add progress tracking for backtesting

This commit is contained in:
Matthias
2021-03-11 19:16:18 +01:00
parent 06b6726029
commit 048008756f
5 changed files with 56 additions and 3 deletions

View File

@@ -17,7 +17,7 @@ from freqtrade.data import history
from freqtrade.data.btanalysis import trade_list_to_dataframe
from freqtrade.data.converter import trim_dataframes
from freqtrade.data.dataprovider import DataProvider
from freqtrade.enums import SellType
from freqtrade.enums import BacktestState, SellType
from freqtrade.exceptions import DependencyException, OperationalException
from freqtrade.exchange import timeframe_to_minutes, timeframe_to_seconds
from freqtrade.mixins import LoggingMixin
@@ -118,11 +118,26 @@ class Backtesting:
# Get maximum required startup period
self.required_startup = max([strat.startup_candle_count for strat in self.strategylist])
self._progress = 0
self._max_steps = 0
self._action = BacktestState.STARTUP
def __del__(self):
LoggingMixin.show_output = True
PairLocks.use_db = True
Trade.use_db = True
def set_progress(self, action: BacktestState, progress: float):
self._progress = 0
self._action = action
def get_progress(self) -> float:
return round(self._progress / self._max_steps, 5) if self._max_steps > 0 else 0
def get_action(self) -> str:
return str(self._action)
def _set_strategy(self, strategy: IStrategy):
"""
Load strategy into backtesting
@@ -145,6 +160,8 @@ class Backtesting:
Loads backtest data and returns the data combined with the timerange
as tuple.
"""
self.set_progress(BacktestState.DATALOAD, 0)
timerange = TimeRange.parse_timerange(None if self.config.get(
'timerange') is None else str(self.config.get('timerange')))
@@ -168,6 +185,7 @@ class Backtesting:
timerange.adjust_start_if_necessary(timeframe_to_seconds(self.timeframe),
self.required_startup, min_date)
self.set_progress(BacktestState.DATALOAD, 1)
return data, timerange
def prepare_backtest(self, enable_protections):
@@ -404,6 +422,9 @@ class Backtesting:
open_trades: Dict[str, List[LocalTrade]] = defaultdict(list)
open_trade_count = 0
self.set_progress(BacktestState.BACKTEST, 0)
self._max_steps = int((end_date - start_date) / timedelta(minutes=self.timeframe_min))
# Loop timerange and get candle for each pair at that point in time
while tmp <= end_date:
open_trade_count_start = open_trade_count
@@ -463,6 +484,7 @@ class Backtesting:
self.protections.global_stop(tmp)
# Move time one configured time_interval ahead.
self._progress += 1
tmp += timedelta(minutes=self.timeframe_min)
trades += self.handle_left_open(open_trades, data=data)
@@ -478,6 +500,8 @@ class Backtesting:
}
def backtest_one_strategy(self, strat: IStrategy, data: Dict[str, Any], timerange: TimeRange):
self.set_progress(BacktestState.ANALYZE, 0)
self._max_steps = 0
logger.info("Running backtesting for Strategy %s", strat.get_strategy_name())
backtest_start_time = datetime.now(timezone.utc)
self._set_strategy(strat)
@@ -504,6 +528,8 @@ class Backtesting:
"No data left after adjusting for startup candles.")
min_date, max_date = history.get_timerange(preprocessed)
self.set_progress(BacktestState.BACKTEST, 0)
logger.info(f'Backtesting with data from {min_date.strftime(DATETIME_PRINT_FORMAT)} '
f'up to {max_date.strftime(DATETIME_PRINT_FORMAT)} '
f'({(max_date - min_date).days} days).')