refactoring freqai backtesting - remove duplicate code
This commit is contained in:
parent
44d3a9140d
commit
d6e115178a
@ -69,6 +69,8 @@ class FreqaiDataKitchen:
|
|||||||
self.label_list: List = []
|
self.label_list: List = []
|
||||||
self.training_features_list: List = []
|
self.training_features_list: List = []
|
||||||
self.model_filename: str = ""
|
self.model_filename: str = ""
|
||||||
|
self.backtesting_results_path = Path()
|
||||||
|
self.backtesting_prediction_folder: str = "backtesting_predictions"
|
||||||
self.live = live
|
self.live = live
|
||||||
self.pair = pair
|
self.pair = pair
|
||||||
|
|
||||||
@ -808,8 +810,6 @@ class FreqaiDataKitchen:
|
|||||||
else:
|
else:
|
||||||
self.full_df = pd.concat([self.full_df, append_df], axis=0)
|
self.full_df = pd.concat([self.full_df, append_df], axis=0)
|
||||||
|
|
||||||
return append_df
|
|
||||||
|
|
||||||
def fill_predictions(self, dataframe):
|
def fill_predictions(self, dataframe):
|
||||||
"""
|
"""
|
||||||
Back fill values to before the backtesting range so that the dataframe matches size
|
Back fill values to before the backtesting range so that the dataframe matches size
|
||||||
@ -1070,33 +1070,25 @@ class FreqaiDataKitchen:
|
|||||||
self.unique_class_list += list(self.unique_classes[label])
|
self.unique_class_list += list(self.unique_classes[label])
|
||||||
|
|
||||||
def save_backtesting_prediction(
|
def save_backtesting_prediction(
|
||||||
self, file_name: str, root_folder: str, append_df: DataFrame
|
self, append_df: DataFrame
|
||||||
) -> None:
|
) -> None:
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Save prediction dataframe from backtesting to h5 file format
|
Save prediction dataframe from backtesting to h5 file format
|
||||||
:param file_name: h5 file name
|
:param append_df: dataframe for backtesting period
|
||||||
:param root_folder: folder to save h5 file
|
|
||||||
"""
|
"""
|
||||||
backtesting_root = Path(
|
full_predictions_folder = Path(self.full_path / self.backtesting_prediction_folder)
|
||||||
self.full_path
|
if not full_predictions_folder.is_dir():
|
||||||
/ root_folder
|
full_predictions_folder.mkdir(parents=True, exist_ok=True)
|
||||||
)
|
|
||||||
if not backtesting_root.is_dir():
|
|
||||||
backtesting_root.mkdir(parents=True, exist_ok=True)
|
|
||||||
|
|
||||||
full_file_path = Path(self.full_path / root_folder / file_name)
|
append_df.to_hdf(self.backtesting_results_path, key='append_df', mode='w')
|
||||||
append_df.to_hdf(full_file_path, key='append_df', mode='w')
|
|
||||||
|
|
||||||
def get_backtesting_prediction(
|
def get_backtesting_prediction(
|
||||||
self, root_prediction: str, prediction_file_name: str
|
self
|
||||||
) -> DataFrame:
|
) -> DataFrame:
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Retrive from disk the prediction dataframe
|
Get prediction dataframe from h5 file format
|
||||||
:param prediction_file_name: prediction file full path
|
|
||||||
:return:
|
|
||||||
:Dataframe: Backtesting prediction from current backtesting period
|
|
||||||
"""
|
"""
|
||||||
prediction_path = Path(self.full_path / root_prediction / prediction_file_name)
|
append_df = pd.read_hdf(self.backtesting_results_path)
|
||||||
append_df = pd.read_hdf(prediction_path)
|
|
||||||
return append_df
|
return append_df
|
||||||
|
@ -231,15 +231,11 @@ class IFreqaiModel(ABC):
|
|||||||
f"sub-train-{metadata['pair'].split('/')[0]}_{trained_timestamp_int}"
|
f"sub-train-{metadata['pair'].split('/')[0]}_{trained_timestamp_int}"
|
||||||
)
|
)
|
||||||
|
|
||||||
if self.backtest_prediction_exists(
|
coin, _ = metadata["pair"].split("/")
|
||||||
metadata["pair"], dk, trained_timestamp=trained_timestamp_int
|
dk.model_filename = f"cb_{coin.lower()}_{trained_timestamp_int}"
|
||||||
):
|
|
||||||
prediction_filename, root_prediction = self.get_backtesting_prediction_file_name(
|
|
||||||
metadata["pair"],
|
|
||||||
dk,
|
|
||||||
trained_timestamp=int(trained_timestamp.stopts))
|
|
||||||
|
|
||||||
append_df = dk.get_backtesting_prediction(root_prediction, prediction_filename)
|
if self.backtest_prediction_exists(dk):
|
||||||
|
append_df = dk.get_backtesting_prediction()
|
||||||
dk.append_predictions(append_df)
|
dk.append_predictions(append_df)
|
||||||
else:
|
else:
|
||||||
if not self.model_exists(
|
if not self.model_exists(
|
||||||
@ -259,15 +255,7 @@ class IFreqaiModel(ABC):
|
|||||||
pred_df, do_preds = self.predict(dataframe_backtest, dk)
|
pred_df, do_preds = self.predict(dataframe_backtest, dk)
|
||||||
append_df = dk.get_predictions_to_append(pred_df, do_preds)
|
append_df = dk.get_predictions_to_append(pred_df, do_preds)
|
||||||
dk.append_predictions(append_df)
|
dk.append_predictions(append_df)
|
||||||
|
dk.save_backtesting_prediction(append_df)
|
||||||
prediction_file_name, root_prediction = self.get_backtesting_prediction_file_name(
|
|
||||||
metadata["pair"],
|
|
||||||
dk,
|
|
||||||
trained_timestamp_int)
|
|
||||||
|
|
||||||
dk.save_backtesting_prediction(prediction_file_name,
|
|
||||||
root_prediction,
|
|
||||||
append_df)
|
|
||||||
|
|
||||||
dk.fill_predictions(dataframe)
|
dk.fill_predictions(dataframe)
|
||||||
|
|
||||||
@ -478,11 +466,6 @@ class IFreqaiModel(ABC):
|
|||||||
:return:
|
:return:
|
||||||
:boolean: whether the model file exists or not.
|
:boolean: whether the model file exists or not.
|
||||||
"""
|
"""
|
||||||
coin, _ = pair.split("/")
|
|
||||||
|
|
||||||
if not self.live:
|
|
||||||
dk.model_filename = model_filename = f"cb_{coin.lower()}_{trained_timestamp}"
|
|
||||||
|
|
||||||
path_to_modelfile = Path(dk.data_path / f"{model_filename}_model.joblib")
|
path_to_modelfile = Path(dk.data_path / f"{model_filename}_model.joblib")
|
||||||
file_exists = path_to_modelfile.is_file()
|
file_exists = path_to_modelfile.is_file()
|
||||||
if file_exists and not scanning:
|
if file_exists and not scanning:
|
||||||
@ -661,23 +644,21 @@ class IFreqaiModel(ABC):
|
|||||||
|
|
||||||
def backtest_prediction_exists(
|
def backtest_prediction_exists(
|
||||||
self,
|
self,
|
||||||
pair: str,
|
|
||||||
dk: FreqaiDataKitchen,
|
dk: FreqaiDataKitchen,
|
||||||
trained_timestamp: int,
|
|
||||||
scanning: bool = False,
|
scanning: bool = False,
|
||||||
) -> bool:
|
) -> bool:
|
||||||
"""
|
"""
|
||||||
Given a pair and path, check if a backtesting prediction already exists
|
Check if a backtesting prediction already exists
|
||||||
:param pair: pair e.g. BTC/USD
|
:param dk: FreqaiDataKitchen
|
||||||
:param path: path to prediction
|
|
||||||
:return:
|
:return:
|
||||||
:boolean: whether the prediction file exists or not.
|
:boolean: whether the prediction file exists or not.
|
||||||
"""
|
"""
|
||||||
if not self.live:
|
if not self.live:
|
||||||
prediction_file_name, root_prediction = self.get_backtesting_prediction_file_name(
|
prediction_file_name = dk.model_filename
|
||||||
pair, dk, trained_timestamp
|
path_to_predictionfile = Path(dk.full_path /
|
||||||
)
|
dk.backtesting_prediction_folder /
|
||||||
path_to_predictionfile = Path(dk.full_path / root_prediction / prediction_file_name)
|
f"{prediction_file_name}_prediction.h5")
|
||||||
|
dk.backtesting_results_path = path_to_predictionfile
|
||||||
|
|
||||||
file_exists = path_to_predictionfile.is_file()
|
file_exists = path_to_predictionfile.is_file()
|
||||||
if file_exists and not scanning:
|
if file_exists and not scanning:
|
||||||
@ -690,25 +671,6 @@ class IFreqaiModel(ABC):
|
|||||||
else:
|
else:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def get_backtesting_prediction_file_name(
|
|
||||||
self, pair: str, dk: FreqaiDataKitchen, trained_timestamp: int
|
|
||||||
):
|
|
||||||
"""
|
|
||||||
Given a pair, path and a trained timestamp,
|
|
||||||
returns the path and name of the predictions file
|
|
||||||
:param pair: pair e.g. BTC/USD
|
|
||||||
:param dk: FreqaiDataKitchen
|
|
||||||
:trained_timestamp: current backtesting timestamp period
|
|
||||||
:return:
|
|
||||||
:str: prediction file name
|
|
||||||
:str: prediction root path
|
|
||||||
"""
|
|
||||||
coin, _ = pair.split("/")
|
|
||||||
prediction_base_filename = f"{coin.lower()}_{trained_timestamp}"
|
|
||||||
root_prediction = 'backtesting_predictions'
|
|
||||||
prediction_file_name = f"{prediction_base_filename}_predictions.h5"
|
|
||||||
return prediction_file_name, root_prediction
|
|
||||||
|
|
||||||
# Following methods which are overridden by user made prediction models.
|
# Following methods which are overridden by user made prediction models.
|
||||||
# See freqai/prediction_models/CatboostPredictionModel.py for an example.
|
# See freqai/prediction_models/CatboostPredictionModel.py for an example.
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user