From 29fed37df3e92de97cc9a0a75651207fd37c9c3a Mon Sep 17 00:00:00 2001 From: Rokas Kupstys Date: Thu, 13 May 2021 09:47:28 +0300 Subject: [PATCH] Fix exception when few pairs with no data do not result in aborting backtest. Exception is triggered by backtesting 20210301-20210501 range with BAKE/USDT pair (binance). Pair data starts on 2021-04-30 12:00:00 and after adjusting for startup candles pair dataframe is empty. Solution: Since there are other pairs with enough data - skip pairs with no data and issue a warning. Exception: ``` Traceback (most recent call last): File "/home/rk/src/freqtrade/freqtrade/main.py", line 37, in main return_code = args['func'](args) File "/home/rk/src/freqtrade/freqtrade/commands/optimize_commands.py", line 53, in start_backtesting backtesting.start() File "/home/rk/src/freqtrade/freqtrade/optimize/backtesting.py", line 502, in start min_date, max_date = self.backtest_one_strategy(strat, data, timerange) File "/home/rk/src/freqtrade/freqtrade/optimize/backtesting.py", line 474, in backtest_one_strategy results = self.backtest( File "/home/rk/src/freqtrade/freqtrade/optimize/backtesting.py", line 365, in backtest data: Dict = self._get_ohlcv_as_lists(processed) File "/home/rk/src/freqtrade/freqtrade/optimize/backtesting.py", line 199, in _get_ohlcv_as_lists pair_data.loc[:, 'buy'] = 0 # cleanup from previous run File "/home/rk/src/freqtrade/venv/lib/python3.9/site-packages/pandas/core/indexing.py", line 692, in __setitem__ iloc._setitem_with_indexer(indexer, value, self.name) File "/home/rk/src/freqtrade/venv/lib/python3.9/site-packages/pandas/core/indexing.py", line 1587, in _setitem_with_indexer raise ValueError( ValueError: cannot set a frame with no defined index and a scalar ``` --- freqtrade/optimize/backtesting.py | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/freqtrade/optimize/backtesting.py b/freqtrade/optimize/backtesting.py index e057d8189..450b88f3b 100644 --- a/freqtrade/optimize/backtesting.py +++ b/freqtrade/optimize/backtesting.py @@ -9,7 +9,7 @@ from copy import deepcopy from datetime import datetime, timedelta, timezone from typing import Any, Dict, List, Optional, Tuple -from pandas import DataFrame, NaT +from pandas import DataFrame from freqtrade.configuration import TimeRange, remove_credentials, validate_config_consistency from freqtrade.constants import DATETIME_PRINT_FORMAT @@ -457,13 +457,21 @@ class Backtesting: preprocessed = self.strategy.ohlcvdata_to_dataframe(data) # Trim startup period from analyzed dataframe - for pair, df in preprocessed.items(): - preprocessed[pair] = trim_dataframe(df, timerange, - startup_candles=self.required_startup) - min_date, max_date = history.get_timerange(preprocessed) - if min_date is NaT or max_date is NaT: + for pair in list(preprocessed): + df = preprocessed[pair] + df = trim_dataframe(df, timerange, startup_candles=self.required_startup) + if len(df) > 0: + preprocessed[pair] = df + else: + logger.warning(f'{pair} has no data left after adjusting for startup candles, ' + f'skipping.') + del preprocessed[pair] + + if not preprocessed: raise OperationalException( - "No data left after adjusting for startup candles. ") + "No data left after adjusting for startup candles.") + + min_date, max_date = history.get_timerange(preprocessed) 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).')