Slice dataframe in backtesting, preventing access to rows past current time.
This commit is contained in:
parent
f1eb653545
commit
8d8c782bd0
@ -20,6 +20,7 @@ from freqtrade.state import RunMode
|
|||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
NO_EXCHANGE_EXCEPTION = 'Exchange is not available to DataProvider.'
|
NO_EXCHANGE_EXCEPTION = 'Exchange is not available to DataProvider.'
|
||||||
|
MAX_DATAFRAME_CANDLES = 1000
|
||||||
|
|
||||||
|
|
||||||
class DataProvider:
|
class DataProvider:
|
||||||
@ -29,6 +30,14 @@ class DataProvider:
|
|||||||
self._exchange = exchange
|
self._exchange = exchange
|
||||||
self._pairlists = pairlists
|
self._pairlists = pairlists
|
||||||
self.__cached_pairs: Dict[PairWithTimeframe, Tuple[DataFrame, datetime]] = {}
|
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:
|
def _set_cached_df(self, pair: str, timeframe: str, dataframe: DataFrame) -> None:
|
||||||
"""
|
"""
|
||||||
@ -85,10 +94,16 @@ class DataProvider:
|
|||||||
combination.
|
combination.
|
||||||
Returns empty dataframe and Epoch 0 (1970-01-01) if no dataframe was cached.
|
Returns empty dataframe and Epoch 0 (1970-01-01) if no dataframe was cached.
|
||||||
"""
|
"""
|
||||||
if (pair, timeframe) in self.__cached_pairs:
|
pair_key = (pair, timeframe)
|
||||||
return self.__cached_pairs[(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:
|
else:
|
||||||
|
|
||||||
return (DataFrame(), datetime.fromtimestamp(0, tz=timezone.utc))
|
return (DataFrame(), datetime.fromtimestamp(0, tz=timezone.utc))
|
||||||
|
|
||||||
@property
|
@property
|
||||||
|
@ -373,8 +373,9 @@ class Backtesting:
|
|||||||
open_trade_count_start = open_trade_count
|
open_trade_count_start = open_trade_count
|
||||||
|
|
||||||
for i, pair in enumerate(data):
|
for i, pair in enumerate(data):
|
||||||
|
row_index = indexes[pair]
|
||||||
try:
|
try:
|
||||||
row = data[pair][indexes[pair]]
|
row = data[pair][row_index]
|
||||||
except IndexError:
|
except IndexError:
|
||||||
# missing Data for one pair at the end.
|
# missing Data for one pair at the end.
|
||||||
# Warnings for this are shown during data loading
|
# 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.
|
# Waits until the time-counter reaches the start of the data for this pair.
|
||||||
if row[DATE_IDX] > tmp:
|
if row[DATE_IDX] > tmp:
|
||||||
continue
|
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.
|
# without positionstacking, we can only have one open trade per pair.
|
||||||
# max_open_trades must be respected
|
# max_open_trades must be respected
|
||||||
|
Loading…
Reference in New Issue
Block a user