allow subdaily retraining for backtesting
This commit is contained in:
parent
0aa7162055
commit
4eb4753e20
@ -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
|
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
|
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
|
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
|
a new model, and begin making predictions with the updated model. FreqAI backtesting and live both
|
||||||
the user to use fractional days (i.e. 0.1) in the `backtest_period`, which enables more frequent
|
permit the user to use fractional days (i.e. 0.1) in the `backtest_period`, which enables more frequent
|
||||||
retraining.
|
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
|
If the user wishes to start dry/live from a backtested saved model, the user only needs to reuse
|
||||||
the same `identifier` parameter
|
the same `identifier` parameter
|
||||||
|
@ -60,11 +60,11 @@ class FreqaiDataKitchen:
|
|||||||
self.pair = pair
|
self.pair = pair
|
||||||
self.svm_model: linear_model.SGDOneClassSVM = None
|
self.svm_model: linear_model.SGDOneClassSVM = None
|
||||||
if not self.live:
|
if not self.live:
|
||||||
if config.get('freqai', {}).get('backtest_period') < 1:
|
# if config.get('freqai', {}).get('backtest_period') < 1:
|
||||||
raise OperationalException('backtest_period < 1,'
|
# raise OperationalException('backtest_period < 1,'
|
||||||
'Can only backtest on full day increments'
|
# 'Can only backtest on full day increments'
|
||||||
'backtest_period. Only live/dry mode'
|
# 'backtest_period. Only live/dry mode'
|
||||||
'allows fractions of days')
|
# 'allows fractions of days')
|
||||||
self.full_timerange = self.create_fulltimerange(self.config["timerange"],
|
self.full_timerange = self.create_fulltimerange(self.config["timerange"],
|
||||||
self.freqai_config.get("train_period")
|
self.freqai_config.get("train_period")
|
||||||
)
|
)
|
||||||
@ -401,6 +401,8 @@ class FreqaiDataKitchen:
|
|||||||
|
|
||||||
tr_training_list = []
|
tr_training_list = []
|
||||||
tr_backtesting_list = []
|
tr_backtesting_list = []
|
||||||
|
tr_training_list_timerange = []
|
||||||
|
tr_backtesting_list_timerange = []
|
||||||
first = True
|
first = True
|
||||||
# within_config_timerange = True
|
# within_config_timerange = True
|
||||||
while True:
|
while True:
|
||||||
@ -412,6 +414,7 @@ class FreqaiDataKitchen:
|
|||||||
start = datetime.datetime.utcfromtimestamp(timerange_train.startts)
|
start = datetime.datetime.utcfromtimestamp(timerange_train.startts)
|
||||||
stop = datetime.datetime.utcfromtimestamp(timerange_train.stopts)
|
stop = datetime.datetime.utcfromtimestamp(timerange_train.stopts)
|
||||||
tr_training_list.append(start.strftime("%Y%m%d") + "-" + stop.strftime("%Y%m%d"))
|
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
|
# associated backtest period
|
||||||
|
|
||||||
@ -425,16 +428,17 @@ class FreqaiDataKitchen:
|
|||||||
start = datetime.datetime.utcfromtimestamp(timerange_backtest.startts)
|
start = datetime.datetime.utcfromtimestamp(timerange_backtest.startts)
|
||||||
stop = datetime.datetime.utcfromtimestamp(timerange_backtest.stopts)
|
stop = datetime.datetime.utcfromtimestamp(timerange_backtest.stopts)
|
||||||
tr_backtesting_list.append(start.strftime("%Y%m%d") + "-" + stop.strftime("%Y%m%d"))
|
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
|
# ensure we are predicting on exactly same amount of data as requested by user defined
|
||||||
# --timerange
|
# --timerange
|
||||||
if timerange_backtest.stopts == config_timerange.stopts:
|
if timerange_backtest.stopts == config_timerange.stopts:
|
||||||
break
|
break
|
||||||
|
|
||||||
print(tr_training_list, tr_backtesting_list)
|
# print(tr_training_list, tr_backtesting_list)
|
||||||
return 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
|
Given a full dataframe, extract the user desired window
|
||||||
:params:
|
:params:
|
||||||
@ -442,7 +446,7 @@ class FreqaiDataKitchen:
|
|||||||
:df: Dataframe containing all candles to run the entire backtest. Here
|
:df: Dataframe containing all candles to run the entire backtest. Here
|
||||||
it is sliced down to just the present training period.
|
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)
|
start = datetime.datetime.fromtimestamp(timerange.startts, tz=datetime.timezone.utc)
|
||||||
stop = datetime.datetime.fromtimestamp(timerange.stopts, tz=datetime.timezone.utc)
|
stop = datetime.datetime.fromtimestamp(timerange.stopts, tz=datetime.timezone.utc)
|
||||||
df = df.loc[df["date"] >= start, :]
|
df = df.loc[df["date"] >= start, :]
|
||||||
|
@ -142,10 +142,11 @@ class IFreqaiModel(ABC):
|
|||||||
gc.collect()
|
gc.collect()
|
||||||
dh.data = {} # clean the pair specific data between training window sliding
|
dh.data = {} # clean the pair specific data between training window sliding
|
||||||
self.training_timerange = tr_train
|
self.training_timerange = tr_train
|
||||||
|
# self.training_timerange_timerange = tr_train
|
||||||
dataframe_train = dh.slice_dataframe(tr_train, dataframe)
|
dataframe_train = dh.slice_dataframe(tr_train, dataframe)
|
||||||
dataframe_backtest = dh.slice_dataframe(tr_backtest, dataframe)
|
dataframe_backtest = dh.slice_dataframe(tr_backtest, dataframe)
|
||||||
logger.info("training %s for %s", metadata["pair"], tr_train)
|
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 /
|
dh.data_path = Path(dh.full_path /
|
||||||
str("sub-train" + "-" + metadata['pair'].split("/")[0] +
|
str("sub-train" + "-" + metadata['pair'].split("/")[0] +
|
||||||
str(int(trained_timestamp.stopts))))
|
str(int(trained_timestamp.stopts))))
|
||||||
|
Loading…
Reference in New Issue
Block a user