allow subdaily retraining for backtesting

This commit is contained in:
robcaulk 2022-05-29 17:44:35 +02:00
parent 0aa7162055
commit 4eb4753e20
3 changed files with 19 additions and 13 deletions

View File

@ -280,9 +280,10 @@ freqtrade trade --strategy FreqaiExampleStrategy --config config_freqai.example.
By default, Freqai will not find find any existing models and will start by training a new one
given the user configuration settings. Following training, it will use that model to predict for the
duration of `backtest_period`. After a full `backtest_period` has elapsed, Freqai will auto retrain
a new model, and begin making predictions with the updated model. FreqAI in live mode permits
the user to use fractional days (i.e. 0.1) in the `backtest_period`, which enables more frequent
retraining.
a new model, and begin making predictions with the updated model. FreqAI backtesting and live both
permit the user to use fractional days (i.e. 0.1) in the `backtest_period`, which enables more frequent
retraining. But the user should be careful that using a fractional `backtest_period` with a large
`--timerange` in backtesting will result in a huge amount of required trainings/models.
If the user wishes to start dry/live from a backtested saved model, the user only needs to reuse
the same `identifier` parameter

View File

@ -60,11 +60,11 @@ class FreqaiDataKitchen:
self.pair = pair
self.svm_model: linear_model.SGDOneClassSVM = None
if not self.live:
if config.get('freqai', {}).get('backtest_period') < 1:
raise OperationalException('backtest_period < 1,'
'Can only backtest on full day increments'
'backtest_period. Only live/dry mode'
'allows fractions of days')
# if config.get('freqai', {}).get('backtest_period') < 1:
# raise OperationalException('backtest_period < 1,'
# 'Can only backtest on full day increments'
# 'backtest_period. Only live/dry mode'
# 'allows fractions of days')
self.full_timerange = self.create_fulltimerange(self.config["timerange"],
self.freqai_config.get("train_period")
)
@ -401,6 +401,8 @@ class FreqaiDataKitchen:
tr_training_list = []
tr_backtesting_list = []
tr_training_list_timerange = []
tr_backtesting_list_timerange = []
first = True
# within_config_timerange = True
while True:
@ -412,6 +414,7 @@ class FreqaiDataKitchen:
start = datetime.datetime.utcfromtimestamp(timerange_train.startts)
stop = datetime.datetime.utcfromtimestamp(timerange_train.stopts)
tr_training_list.append(start.strftime("%Y%m%d") + "-" + stop.strftime("%Y%m%d"))
tr_training_list_timerange.append(copy.deepcopy(timerange_train))
# associated backtest period
@ -425,16 +428,17 @@ class FreqaiDataKitchen:
start = datetime.datetime.utcfromtimestamp(timerange_backtest.startts)
stop = datetime.datetime.utcfromtimestamp(timerange_backtest.stopts)
tr_backtesting_list.append(start.strftime("%Y%m%d") + "-" + stop.strftime("%Y%m%d"))
tr_backtesting_list_timerange.append(copy.deepcopy(timerange_backtest))
# ensure we are predicting on exactly same amount of data as requested by user defined
# --timerange
if timerange_backtest.stopts == config_timerange.stopts:
break
print(tr_training_list, tr_backtesting_list)
return tr_training_list, tr_backtesting_list
# print(tr_training_list, tr_backtesting_list)
return tr_training_list_timerange, tr_backtesting_list_timerange
def slice_dataframe(self, tr: str, df: DataFrame) -> DataFrame:
def slice_dataframe(self, timerange: TimeRange, df: DataFrame) -> DataFrame:
"""
Given a full dataframe, extract the user desired window
:params:
@ -442,7 +446,7 @@ class FreqaiDataKitchen:
:df: Dataframe containing all candles to run the entire backtest. Here
it is sliced down to just the present training period.
"""
timerange = TimeRange.parse_timerange(tr)
# timerange = TimeRange.parse_timerange(tr)
start = datetime.datetime.fromtimestamp(timerange.startts, tz=datetime.timezone.utc)
stop = datetime.datetime.fromtimestamp(timerange.stopts, tz=datetime.timezone.utc)
df = df.loc[df["date"] >= start, :]

View File

@ -142,10 +142,11 @@ class IFreqaiModel(ABC):
gc.collect()
dh.data = {} # clean the pair specific data between training window sliding
self.training_timerange = tr_train
# self.training_timerange_timerange = tr_train
dataframe_train = dh.slice_dataframe(tr_train, dataframe)
dataframe_backtest = dh.slice_dataframe(tr_backtest, dataframe)
logger.info("training %s for %s", metadata["pair"], tr_train)
trained_timestamp = TimeRange.parse_timerange(tr_train)
trained_timestamp = tr_train # TimeRange.parse_timerange(tr_train)
dh.data_path = Path(dh.full_path /
str("sub-train" + "-" + metadata['pair'].split("/")[0] +
str(int(trained_timestamp.stopts))))