give users ability to decide how many models to keep in dry/live

This commit is contained in:
robcaulk 2023-02-22 22:27:56 +01:00
parent 9633081c31
commit b8f011a2ab
8 changed files with 15 additions and 10 deletions

View File

@ -48,7 +48,7 @@
], ],
"freqai": { "freqai": {
"enabled": true, "enabled": true,
"purge_old_models": true, "purge_old_models": 2,
"train_period_days": 15, "train_period_days": 15,
"backtest_period_days": 7, "backtest_period_days": 7,
"live_retrain_hours": 0, "live_retrain_hours": 0,

View File

@ -9,7 +9,7 @@ FreqAI is configured through the typical [Freqtrade config file](configuration.m
```json ```json
"freqai": { "freqai": {
"enabled": true, "enabled": true,
"purge_old_models": true, "purge_old_models": 2,
"train_period_days": 30, "train_period_days": 30,
"backtest_period_days": 7, "backtest_period_days": 7,
"identifier" : "unique-id", "identifier" : "unique-id",

View File

@ -15,7 +15,7 @@ Mandatory parameters are marked as **Required** and have to be set in one of the
| `identifier` | **Required.** <br> A unique ID for the current model. If models are saved to disk, the `identifier` allows for reloading specific pre-trained models/data. <br> **Datatype:** String. | `identifier` | **Required.** <br> A unique ID for the current model. If models are saved to disk, the `identifier` allows for reloading specific pre-trained models/data. <br> **Datatype:** String.
| `live_retrain_hours` | Frequency of retraining during dry/live runs. <br> **Datatype:** Float > 0. <br> Default: `0` (models retrain as often as possible). | `live_retrain_hours` | Frequency of retraining during dry/live runs. <br> **Datatype:** Float > 0. <br> Default: `0` (models retrain as often as possible).
| `expiration_hours` | Avoid making predictions if a model is more than `expiration_hours` old. <br> **Datatype:** Positive integer. <br> Default: `0` (models never expire). | `expiration_hours` | Avoid making predictions if a model is more than `expiration_hours` old. <br> **Datatype:** Positive integer. <br> Default: `0` (models never expire).
| `purge_old_models` | Delete all unused models during live runs (not relevant to backtesting). If set to false (not default), dry/live runs will accumulate all unused models to disk. If <br> **Datatype:** Boolean. <br> Default: `True`. | `purge_old_models` | Number of models to keep on disk (not relevant to backtesting). Default is 2, dry/live runs will keep 2 models on disk. Setting to 0 keeps all models. If <br> **Datatype:** Boolean. <br> Default: `2`.
| `save_backtest_models` | Save models to disk when running backtesting. Backtesting operates most efficiently by saving the prediction data and reusing them directly for subsequent runs (when you wish to tune entry/exit parameters). Saving backtesting models to disk also allows to use the same model files for starting a dry/live instance with the same model `identifier`. <br> **Datatype:** Boolean. <br> Default: `False` (no models are saved). | `save_backtest_models` | Save models to disk when running backtesting. Backtesting operates most efficiently by saving the prediction data and reusing them directly for subsequent runs (when you wish to tune entry/exit parameters). Saving backtesting models to disk also allows to use the same model files for starting a dry/live instance with the same model `identifier`. <br> **Datatype:** Boolean. <br> Default: `False` (no models are saved).
| `fit_live_predictions_candles` | Number of historical candles to use for computing target (label) statistics from prediction data, instead of from the training dataset (more information can be found [here](freqai-configuration.md#creating-a-dynamic-target-threshold)). <br> **Datatype:** Positive integer. | `fit_live_predictions_candles` | Number of historical candles to use for computing target (label) statistics from prediction data, instead of from the training dataset (more information can be found [here](freqai-configuration.md#creating-a-dynamic-target-threshold)). <br> **Datatype:** Positive integer.
| `continual_learning` | Use the final state of the most recently trained model as starting point for the new model, allowing for incremental learning (more information can be found [here](freqai-running.md#continual-learning)). <br> **Datatype:** Boolean. <br> Default: `False`. | `continual_learning` | Use the final state of the most recently trained model as starting point for the new model, allowing for incremental learning (more information can be found [here](freqai-running.md#continual-learning)). <br> **Datatype:** Boolean. <br> Default: `False`.

View File

@ -546,7 +546,7 @@ CONF_SCHEMA = {
"enabled": {"type": "boolean", "default": False}, "enabled": {"type": "boolean", "default": False},
"keras": {"type": "boolean", "default": False}, "keras": {"type": "boolean", "default": False},
"write_metrics_to_disk": {"type": "boolean", "default": False}, "write_metrics_to_disk": {"type": "boolean", "default": False},
"purge_old_models": {"type": "boolean", "default": True}, "purge_old_models": {"type": ["boolean", "number"], "default": 2},
"conv_width": {"type": "integer", "default": 1}, "conv_width": {"type": "integer", "default": 1},
"train_period_days": {"type": "integer", "default": 0}, "train_period_days": {"type": "integer", "default": 0},
"backtest_period_days": {"type": "number", "default": 7}, "backtest_period_days": {"type": "number", "default": 7},

View File

@ -366,6 +366,12 @@ class FreqaiDataDrawer:
def purge_old_models(self) -> None: def purge_old_models(self) -> None:
num_keep = self.freqai_info["purge_old_models"]
if not num_keep:
return
elif type(num_keep) == bool:
num_keep = 2
model_folders = [x for x in self.full_path.iterdir() if x.is_dir()] model_folders = [x for x in self.full_path.iterdir() if x.is_dir()]
pattern = re.compile(r"sub-train-(\w+)_(\d{10})") pattern = re.compile(r"sub-train-(\w+)_(\d{10})")
@ -388,11 +394,11 @@ class FreqaiDataDrawer:
delete_dict[coin]["timestamps"][int(timestamp)] = dir delete_dict[coin]["timestamps"][int(timestamp)] = dir
for coin in delete_dict: for coin in delete_dict:
if delete_dict[coin]["num_folders"] > 2: if delete_dict[coin]["num_folders"] > num_keep:
sorted_dict = collections.OrderedDict( sorted_dict = collections.OrderedDict(
sorted(delete_dict[coin]["timestamps"].items()) sorted(delete_dict[coin]["timestamps"].items())
) )
num_delete = len(sorted_dict) - 2 num_delete = len(sorted_dict) - num_keep
deleted = 0 deleted = 0
for k, v in sorted_dict.items(): for k, v in sorted_dict.items():
if deleted >= num_delete: if deleted >= num_delete:

View File

@ -629,8 +629,7 @@ class IFreqaiModel(ABC):
if self.plot_features: if self.plot_features:
plot_feature_importance(model, pair, dk, self.plot_features) plot_feature_importance(model, pair, dk, self.plot_features)
if self.freqai_info.get("purge_old_models", False): self.dd.purge_old_models()
self.dd.purge_old_models()
def set_initial_historic_predictions( def set_initial_historic_predictions(
self, pred_df: DataFrame, dk: FreqaiDataKitchen, pair: str, strat_df: DataFrame self, pred_df: DataFrame, dk: FreqaiDataKitchen, pair: str, strat_df: DataFrame

View File

@ -27,7 +27,7 @@ class FreqaiExampleHybridStrategy(IStrategy):
"freqai": { "freqai": {
"enabled": true, "enabled": true,
"purge_old_models": true, "purge_old_models": 2,
"train_period_days": 15, "train_period_days": 15,
"identifier": "uniqe-id", "identifier": "uniqe-id",
"feature_parameters": { "feature_parameters": {

View File

@ -27,7 +27,7 @@ def freqai_conf(default_conf, tmpdir):
"timerange": "20180110-20180115", "timerange": "20180110-20180115",
"freqai": { "freqai": {
"enabled": True, "enabled": True,
"purge_old_models": True, "purge_old_models": 2,
"train_period_days": 2, "train_period_days": 2,
"backtest_period_days": 10, "backtest_period_days": 10,
"live_retrain_hours": 0, "live_retrain_hours": 0,