Slice dataframe in backtesting, preventing access to rows past current time.

This commit is contained in:
Rokas Kupstys 2021-05-08 16:06:19 +03:00
parent f1eb653545
commit 8d8c782bd0
2 changed files with 24 additions and 5 deletions

View File

@ -20,6 +20,7 @@ from freqtrade.state import RunMode
logger = logging.getLogger(__name__)
NO_EXCHANGE_EXCEPTION = 'Exchange is not available to DataProvider.'
MAX_DATAFRAME_CANDLES = 1000
class DataProvider:
@ -29,6 +30,14 @@ class DataProvider:
self._exchange = exchange
self._pairlists = pairlists
self.__cached_pairs: Dict[PairWithTimeframe, Tuple[DataFrame, datetime]] = {}
self.__slice_index = None
def _set_dataframe_max_index(self, limit_index: int):
"""
Limit analyzed dataframe to max specified index.
:param limit_index: dataframe index.
"""
self.__slice_index = limit_index
def _set_cached_df(self, pair: str, timeframe: str, dataframe: DataFrame) -> None:
"""
@ -85,10 +94,16 @@ class DataProvider:
combination.
Returns empty dataframe and Epoch 0 (1970-01-01) if no dataframe was cached.
"""
if (pair, timeframe) in self.__cached_pairs:
return self.__cached_pairs[(pair, timeframe)]
pair_key = (pair, timeframe)
if pair_key in self.__cached_pairs:
if self.runmode in (RunMode.DRY_RUN, RunMode.LIVE):
df, date = self.__cached_pairs[pair_key]
else:
max_index = self.__slice_index
df, date = self.__cached_pairs[pair_key]
df = df.iloc[max(0, max_index - MAX_DATAFRAME_CANDLES):max_index]
return df, date
else:
return (DataFrame(), datetime.fromtimestamp(0, tz=timezone.utc))
@property

View File

@ -373,8 +373,9 @@ class Backtesting:
open_trade_count_start = open_trade_count
for i, pair in enumerate(data):
row_index = indexes[pair]
try:
row = data[pair][indexes[pair]]
row = data[pair][row_index]
except IndexError:
# missing Data for one pair at the end.
# Warnings for this are shown during data loading
@ -383,7 +384,10 @@ class Backtesting:
# Waits until the time-counter reaches the start of the data for this pair.
if row[DATE_IDX] > tmp:
continue
indexes[pair] += 1
row_index += 1
self.dataprovider._set_dataframe_max_index(row_index) # noqa
indexes[pair] = row_index
# without positionstacking, we can only have one open trade per pair.
# max_open_trades must be respected