From b707a6da35f8af7719e256bc3dfda300e9844a4c Mon Sep 17 00:00:00 2001 From: initrv Date: Fri, 16 Sep 2022 19:17:41 +0300 Subject: [PATCH 1/9] Add ability to plot feature importance --- config_examples/config_freqai.example.json | 3 +- freqtrade/freqai/freqai_interface.py | 9 +++ freqtrade/freqai/utils.py | 71 ++++++++++++++++++++++ requirements-plot.txt | 1 + 4 files changed, 83 insertions(+), 1 deletion(-) diff --git a/config_examples/config_freqai.example.json b/config_examples/config_freqai.example.json index 12eb30128..9494ba0e1 100644 --- a/config_examples/config_freqai.example.json +++ b/config_examples/config_freqai.example.json @@ -77,7 +77,8 @@ "indicator_periods_candles": [ 10, 20 - ] + ], + "plot_feature_importance": true }, "data_split_parameters": { "test_size": 0.33, diff --git a/freqtrade/freqai/freqai_interface.py b/freqtrade/freqai/freqai_interface.py index 78931bed4..0cc51fdab 100644 --- a/freqtrade/freqai/freqai_interface.py +++ b/freqtrade/freqai/freqai_interface.py @@ -20,6 +20,7 @@ from freqtrade.exceptions import OperationalException from freqtrade.exchange import timeframe_to_seconds from freqtrade.freqai.data_drawer import FreqaiDataDrawer from freqtrade.freqai.data_kitchen import FreqaiDataKitchen +from freqtrade.freqai.utils import plot_feature_importance from freqtrade.strategy.interface import IStrategy @@ -555,6 +556,14 @@ class IFreqaiModel(ABC): model = self.train(unfiltered_dataframe, pair, dk) + if self.freqai_info["feature_parameters"].get("plot_feature_importance", False): + plot_feature_importance( + model=model, + feature_names=dk.training_features_list, + pair=pair, + train_dir=dk.data_path + ) + self.dd.pair_dict[pair]["trained_timestamp"] = new_trained_timerange.stopts dk.set_new_model_names(pair, new_trained_timerange) self.dd.pair_dict[pair]["first"] = False diff --git a/freqtrade/freqai/utils.py b/freqtrade/freqai/utils.py index 6a70f050f..86d89d4b0 100644 --- a/freqtrade/freqai/utils.py +++ b/freqtrade/freqai/utils.py @@ -1,5 +1,13 @@ import logging from datetime import datetime, timezone +# for plot_feature_importance +from pathlib import Path + +import numpy as np +import pandas as pd +import plotly.graph_objects as go +import plotly.io as pio +from plotly.subplots import make_subplots from freqtrade.configuration import TimeRange from freqtrade.data.dataprovider import DataProvider @@ -132,3 +140,66 @@ def get_required_data_timerange( # trading_mode=config.get("trading_mode", "spot"), # prepend=config.get("prepend_data", False), # ) + + +def plot_feature_importance(model, feature_names, pair, train_dir, count_max=25) -> None: + """ + Plot Best and Worst Features by importance for CatBoost model. + Called once per sub-train. + + Required: pip install kaleido + + Usage: plot_feature_importance( + model=model, + feature_names=dk.training_features_list, + pair=pair, + train_dir=dk.data_path) + """ + + # Gather feature importance from model + if "catboost.core" in str(model.__class__): + fi = model.get_feature_importance() + + elif "lightgbm.sklearn" in str(model.__class__): + fi = model.feature_importances_ + + else: + raise NotImplementedError(f"Cannot extract feature importance for {model.__class__}") + + # Data preparation + fi_df = pd.DataFrame({ + "feature_names": np.array(feature_names), + "feature_importance": np.array(fi) + }) + fi_df_top = fi_df.nlargest(count_max, "feature_importance")[::-1] + fi_df_worst = fi_df.nsmallest(count_max, "feature_importance")[::-1] + + # Plotting + fig = make_subplots(rows=1, cols=2, horizontal_spacing=0.5) + fig.add_trace( + go.Bar( + x=fi_df_top["feature_importance"], + y=fi_df_top["feature_names"], + orientation='h', showlegend=False + ), row=1, col=1 + ) + fig.add_trace( + go.Bar( + x=fi_df_worst["feature_importance"], + y=fi_df_worst["feature_names"], + orientation='h', showlegend=False + ), row=1, col=2 + ) + fig.update_layout( + title_text=f"Best and Worst Features {pair}", + width=1000, height=600 + ) + + # Create directory and save image + model_dir, train_name = str(train_dir).rsplit("/", 1) + fi_dir = Path(f"{model_dir}/feature_importance/{pair.split('/')[0]}") + fi_dir.mkdir(parents=True, exist_ok=True) + + pio.write_image(fig, f"{fi_dir}/{train_name}.png", format="png") + + logger.info(f"Freqai saving feature importance plot {fi_dir}/{train_name}.png") diff --git a/requirements-plot.txt b/requirements-plot.txt index 80cd3f4f2..ef3cf9f24 100644 --- a/requirements-plot.txt +++ b/requirements-plot.txt @@ -2,3 +2,4 @@ -r requirements.txt plotly==5.10.0 +kaleido==0.2.1 From 86aa875bc9d5edeba04f908fe45b011e52045c83 Mon Sep 17 00:00:00 2001 From: initrv Date: Fri, 16 Sep 2022 21:47:12 +0300 Subject: [PATCH 2/9] plot features as html instead of png --- freqtrade/freqai/utils.py | 62 ++++++++++++++++----------------------- requirements-plot.txt | 1 - 2 files changed, 25 insertions(+), 38 deletions(-) diff --git a/freqtrade/freqai/utils.py b/freqtrade/freqai/utils.py index 86d89d4b0..3f6b8b053 100644 --- a/freqtrade/freqai/utils.py +++ b/freqtrade/freqai/utils.py @@ -1,13 +1,9 @@ import logging from datetime import datetime, timezone -# for plot_feature_importance from pathlib import Path import numpy as np import pandas as pd -import plotly.graph_objects as go -import plotly.io as pio -from plotly.subplots import make_subplots from freqtrade.configuration import TimeRange from freqtrade.data.dataprovider import DataProvider @@ -142,64 +138,56 @@ def get_required_data_timerange( # ) -def plot_feature_importance(model, feature_names, pair, train_dir, count_max=25) -> None: +def plot_feature_importance(model, feature_names, pair, train_dir, count_max=50) -> None: """ Plot Best and Worst Features by importance for CatBoost model. Called once per sub-train. - - Required: pip install kaleido - Usage: plot_feature_importance( model=model, feature_names=dk.training_features_list, pair=pair, train_dir=dk.data_path) """ + try: + import plotly.graph_objects as go + from plotly.subplots import make_subplots + except ImportError: + logger.exception("Module plotly not found \n Please install using `pip3 install plotly`") + exit(1) + + from freqtrade.plot.plotting import store_plot_file # Gather feature importance from model if "catboost.core" in str(model.__class__): - fi = model.get_feature_importance() - + feature_importance = model.get_feature_importance() elif "lightgbm.sklearn" in str(model.__class__): - fi = model.feature_importances_ - + feature_importance = model.feature_importances_ else: raise NotImplementedError(f"Cannot extract feature importance for {model.__class__}") # Data preparation fi_df = pd.DataFrame({ "feature_names": np.array(feature_names), - "feature_importance": np.array(fi) + "feature_importance": np.array(feature_importance) }) fi_df_top = fi_df.nlargest(count_max, "feature_importance")[::-1] fi_df_worst = fi_df.nsmallest(count_max, "feature_importance")[::-1] # Plotting + def add_feature_trace(fig, fi_df, col): + return fig.add_trace( + go.Bar( + x=fi_df["feature_importance"], + y=fi_df["feature_names"], + orientation='h', showlegend=False + ), row=1, col=col + ) fig = make_subplots(rows=1, cols=2, horizontal_spacing=0.5) - fig.add_trace( - go.Bar( - x=fi_df_top["feature_importance"], - y=fi_df_top["feature_names"], - orientation='h', showlegend=False - ), row=1, col=1 - ) - fig.add_trace( - go.Bar( - x=fi_df_worst["feature_importance"], - y=fi_df_worst["feature_names"], - orientation='h', showlegend=False - ), row=1, col=2 - ) - fig.update_layout( - title_text=f"Best and Worst Features {pair}", - width=1000, height=600 - ) + fig = add_feature_trace(fig, fi_df_top, 1) + fig = add_feature_trace(fig, fi_df_worst, 2) + fig.update_layout(title_text=f"Best and Worst Features {pair}") - # Create directory and save image + # Store plot file model_dir, train_name = str(train_dir).rsplit("/", 1) fi_dir = Path(f"{model_dir}/feature_importance/{pair.split('/')[0]}") - fi_dir.mkdir(parents=True, exist_ok=True) - - pio.write_image(fig, f"{fi_dir}/{train_name}.png", format="png") - - logger.info(f"Freqai saving feature importance plot {fi_dir}/{train_name}.png") + store_plot_file(fig, f"{train_name}.html", fi_dir) diff --git a/requirements-plot.txt b/requirements-plot.txt index ef3cf9f24..80cd3f4f2 100644 --- a/requirements-plot.txt +++ b/requirements-plot.txt @@ -2,4 +2,3 @@ -r requirements.txt plotly==5.10.0 -kaleido==0.2.1 From 1c92734f39074eb7078f45dc296d18c338467959 Mon Sep 17 00:00:00 2001 From: initrv Date: Sat, 17 Sep 2022 18:53:43 +0300 Subject: [PATCH 3/9] simplify plot_feature_importance call --- freqtrade/freqai/freqai_interface.py | 11 +++----- freqtrade/freqai/utils.py | 38 +++++++++++++--------------- 2 files changed, 20 insertions(+), 29 deletions(-) diff --git a/freqtrade/freqai/freqai_interface.py b/freqtrade/freqai/freqai_interface.py index 0cc51fdab..3fa8a801b 100644 --- a/freqtrade/freqai/freqai_interface.py +++ b/freqtrade/freqai/freqai_interface.py @@ -556,14 +556,6 @@ class IFreqaiModel(ABC): model = self.train(unfiltered_dataframe, pair, dk) - if self.freqai_info["feature_parameters"].get("plot_feature_importance", False): - plot_feature_importance( - model=model, - feature_names=dk.training_features_list, - pair=pair, - train_dir=dk.data_path - ) - self.dd.pair_dict[pair]["trained_timestamp"] = new_trained_timerange.stopts dk.set_new_model_names(pair, new_trained_timerange) self.dd.pair_dict[pair]["first"] = False @@ -571,6 +563,9 @@ class IFreqaiModel(ABC): self.dd.pair_to_end_of_training_queue(pair) self.dd.save_data(model, pair, dk) + if self.freqai_info["feature_parameters"].get("plot_feature_importance", False): + plot_feature_importance(model, pair, dk) + if self.freqai_info.get("purge_old_models", False): self.dd.purge_old_models() diff --git a/freqtrade/freqai/utils.py b/freqtrade/freqai/utils.py index 3f6b8b053..34528acdd 100644 --- a/freqtrade/freqai/utils.py +++ b/freqtrade/freqai/utils.py @@ -1,6 +1,7 @@ import logging from datetime import datetime, timezone from pathlib import Path +from typing import Any import numpy as np import pandas as pd @@ -11,6 +12,7 @@ from freqtrade.data.history.history_utils import refresh_backtest_ohlcv_data from freqtrade.exceptions import OperationalException from freqtrade.exchange import timeframe_to_seconds from freqtrade.exchange.exchange import market_is_active +from freqtrade.freqai.data_kitchen import FreqaiDataKitchen from freqtrade.plugins.pairlist.pairlist_helpers import dynamic_expand_pairlist @@ -138,36 +140,30 @@ def get_required_data_timerange( # ) -def plot_feature_importance(model, feature_names, pair, train_dir, count_max=50) -> None: +def plot_feature_importance(model: Any, pair: str, dk: FreqaiDataKitchen, + count_max: int = 25) -> None: """ - Plot Best and Worst Features by importance for CatBoost model. - Called once per sub-train. - Usage: plot_feature_importance( - model=model, - feature_names=dk.training_features_list, - pair=pair, - train_dir=dk.data_path) + Plot Best and worst features by importance for a single sub-train. + :param model: Any = A model which was `fit` using a common library + such as catboost or lightgbm + :param pair: str = pair e.g. BTC/USD + :param dk: FreqaiDataKitchen = non-persistent data container for current coin/loop + :param count_max: int = the amount of features to be loaded per column """ - try: - import plotly.graph_objects as go - from plotly.subplots import make_subplots - except ImportError: - logger.exception("Module plotly not found \n Please install using `pip3 install plotly`") - exit(1) + from freqtrade.plot.plotting import go, make_subplots, store_plot_file - from freqtrade.plot.plotting import store_plot_file - - # Gather feature importance from model + # Extract feature importance from model if "catboost.core" in str(model.__class__): feature_importance = model.get_feature_importance() elif "lightgbm.sklearn" in str(model.__class__): feature_importance = model.feature_importances_ else: - raise NotImplementedError(f"Cannot extract feature importance for {model.__class__}") + # TODO: Add support for more libraries + raise NotImplementedError(f"Cannot extract feature importance from {model.__class__}") # Data preparation fi_df = pd.DataFrame({ - "feature_names": np.array(feature_names), + "feature_names": np.array(dk.training_features_list), "feature_importance": np.array(feature_importance) }) fi_df_top = fi_df.nlargest(count_max, "feature_importance")[::-1] @@ -185,9 +181,9 @@ def plot_feature_importance(model, feature_names, pair, train_dir, count_max=50) fig = make_subplots(rows=1, cols=2, horizontal_spacing=0.5) fig = add_feature_trace(fig, fi_df_top, 1) fig = add_feature_trace(fig, fi_df_worst, 2) - fig.update_layout(title_text=f"Best and Worst Features {pair}") + fig.update_layout(title_text=f"Best and worst features by importance {pair}") # Store plot file - model_dir, train_name = str(train_dir).rsplit("/", 1) + model_dir, train_name = str(dk.data_path).rsplit("/", 1) fi_dir = Path(f"{model_dir}/feature_importance/{pair.split('/')[0]}") store_plot_file(fig, f"{train_name}.html", fi_dir) From 2c23effbf27adefa9949fe21c462dc3ef5e36b8d Mon Sep 17 00:00:00 2001 From: robcaulk Date: Sat, 17 Sep 2022 19:17:44 +0200 Subject: [PATCH 4/9] allow plot to plot multitargets, add test --- freqtrade/freqai/freqai_interface.py | 2 +- freqtrade/freqai/utils.py | 74 ++++++++++++++------------- freqtrade/plot/plotting.py | 5 +- tests/freqai/test_freqai_interface.py | 35 +++++++++++++ 4 files changed, 78 insertions(+), 38 deletions(-) diff --git a/freqtrade/freqai/freqai_interface.py b/freqtrade/freqai/freqai_interface.py index 3fa8a801b..c6b45d61b 100644 --- a/freqtrade/freqai/freqai_interface.py +++ b/freqtrade/freqai/freqai_interface.py @@ -563,7 +563,7 @@ class IFreqaiModel(ABC): self.dd.pair_to_end_of_training_queue(pair) self.dd.save_data(model, pair, dk) - if self.freqai_info["feature_parameters"].get("plot_feature_importance", False): + if self.freqai_info["feature_parameters"].get("plot_feature_importance", True): plot_feature_importance(model, pair, dk) if self.freqai_info.get("purge_old_models", False): diff --git a/freqtrade/freqai/utils.py b/freqtrade/freqai/utils.py index 34528acdd..3f278d436 100644 --- a/freqtrade/freqai/utils.py +++ b/freqtrade/freqai/utils.py @@ -1,6 +1,5 @@ import logging from datetime import datetime, timezone -from pathlib import Path from typing import Any import numpy as np @@ -153,37 +152,42 @@ def plot_feature_importance(model: Any, pair: str, dk: FreqaiDataKitchen, from freqtrade.plot.plotting import go, make_subplots, store_plot_file # Extract feature importance from model - if "catboost.core" in str(model.__class__): - feature_importance = model.get_feature_importance() - elif "lightgbm.sklearn" in str(model.__class__): - feature_importance = model.feature_importances_ - else: - # TODO: Add support for more libraries - raise NotImplementedError(f"Cannot extract feature importance from {model.__class__}") - - # Data preparation - fi_df = pd.DataFrame({ - "feature_names": np.array(dk.training_features_list), - "feature_importance": np.array(feature_importance) - }) - fi_df_top = fi_df.nlargest(count_max, "feature_importance")[::-1] - fi_df_worst = fi_df.nsmallest(count_max, "feature_importance")[::-1] - - # Plotting - def add_feature_trace(fig, fi_df, col): - return fig.add_trace( - go.Bar( - x=fi_df["feature_importance"], - y=fi_df["feature_names"], - orientation='h', showlegend=False - ), row=1, col=col - ) - fig = make_subplots(rows=1, cols=2, horizontal_spacing=0.5) - fig = add_feature_trace(fig, fi_df_top, 1) - fig = add_feature_trace(fig, fi_df_worst, 2) - fig.update_layout(title_text=f"Best and worst features by importance {pair}") - - # Store plot file - model_dir, train_name = str(dk.data_path).rsplit("/", 1) - fi_dir = Path(f"{model_dir}/feature_importance/{pair.split('/')[0]}") - store_plot_file(fig, f"{train_name}.html", fi_dir) + models = {} + if 'FreqaiMultiOutputRegressor' in str(model.__class__): + for estimator, label in zip(model.estimators_, dk.label_list): + models[label] = estimator + + for label in models: + mdl = models[label] + if "catboost.core" in str(mdl.__class__): + feature_importance = mdl.get_feature_importance() + elif "lightgbm.sklearn" or "xgb" in str(mdl.__class__): + feature_importance = mdl.feature_importances_ + else: + # TODO: Add support for more libraries + raise NotImplementedError(f"Cannot extract feature importance from {mdl.__class__}") + + # Data preparation + fi_df = pd.DataFrame({ + "feature_names": np.array(dk.training_features_list), + "feature_importance": np.array(feature_importance) + }) + fi_df_top = fi_df.nlargest(count_max, "feature_importance")[::-1] + fi_df_worst = fi_df.nsmallest(count_max, "feature_importance")[::-1] + + # Plotting + def add_feature_trace(fig, fi_df, col): + return fig.add_trace( + go.Bar( + x=fi_df["feature_importance"], + y=fi_df["feature_names"], + orientation='h', showlegend=False + ), row=1, col=col + ) + fig = make_subplots(rows=1, cols=2, horizontal_spacing=0.5) + fig = add_feature_trace(fig, fi_df_top, 1) + fig = add_feature_trace(fig, fi_df_worst, 2) + fig.update_layout(title_text=f"Best and worst features by importance {pair}") + + store_plot_file(fig, f"{dk.model_filename}-{label}.html", dk.data_path, + include_plotlyjs="cdn") diff --git a/freqtrade/plot/plotting.py b/freqtrade/plot/plotting.py index f8e95300a..8a00c7899 100644 --- a/freqtrade/plot/plotting.py +++ b/freqtrade/plot/plotting.py @@ -601,7 +601,8 @@ def generate_plot_filename(pair: str, timeframe: str) -> str: return file_name -def store_plot_file(fig, filename: str, directory: Path, auto_open: bool = False) -> None: +def store_plot_file(fig, filename: str, directory: Path, + auto_open: bool = False, include_plotlyjs=True) -> None: """ Generate a plot html file from pre populated fig plotly object :param fig: Plotly Figure to plot @@ -614,7 +615,7 @@ def store_plot_file(fig, filename: str, directory: Path, auto_open: bool = False _filename = directory.joinpath(filename) plot(fig, filename=str(_filename), - auto_open=auto_open) + auto_open=auto_open, include_plotlyjs=include_plotlyjs) logger.info(f"Stored plot as {_filename}") diff --git a/tests/freqai/test_freqai_interface.py b/tests/freqai/test_freqai_interface.py index a66594d7f..b600cc535 100644 --- a/tests/freqai/test_freqai_interface.py +++ b/tests/freqai/test_freqai_interface.py @@ -315,3 +315,38 @@ def test_principal_component_analysis(mocker, freqai_conf): assert Path(freqai.dk.data_path / f"{freqai.dk.model_filename}_pca_object.pkl") shutil.rmtree(Path(freqai.dk.full_path)) + + +def test_plot_feature_importance(mocker, freqai_conf): + + from freqtrade.freqai.utils import plot_feature_importance + + freqai_conf.update({"timerange": "20180110-20180130"}) + freqai_conf.get("freqai", {}).get("feature_parameters", {}).update( + {"princpial_component_analysis": "true"}) + + strategy = get_patched_freqai_strategy(mocker, freqai_conf) + exchange = get_patched_exchange(mocker, freqai_conf) + strategy.dp = DataProvider(freqai_conf, exchange) + strategy.freqai_info = freqai_conf.get("freqai", {}) + freqai = strategy.freqai + freqai.live = True + freqai.dk = FreqaiDataKitchen(freqai_conf) + timerange = TimeRange.parse_timerange("20180110-20180130") + freqai.dd.load_all_pair_histories(timerange, freqai.dk) + + freqai.dd.pair_dict = MagicMock() + + data_load_timerange = TimeRange.parse_timerange("20180110-20180130") + new_timerange = TimeRange.parse_timerange("20180120-20180130") + + freqai.extract_data_and_train_model( + new_timerange, "ADA/BTC", strategy, freqai.dk, data_load_timerange) + + model = freqai.dd.load_data("ADA/BTC", freqai.dk) + + plot_feature_importance(model, "ADA/BTC", freqai.dk) + + assert Path(freqai.dk.data_path / f"{freqai.dk.model_filename}.html") + + shutil.rmtree(Path(freqai.dk.full_path)) From 68f7a315048703285e978dc58e023506153069f2 Mon Sep 17 00:00:00 2001 From: robcaulk Date: Sun, 18 Sep 2022 00:00:14 +0200 Subject: [PATCH 5/9] ensure continued operation despite not being able to plot --- freqtrade/freqai/utils.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/freqtrade/freqai/utils.py b/freqtrade/freqai/utils.py index 3f278d436..10afbaf52 100644 --- a/freqtrade/freqai/utils.py +++ b/freqtrade/freqai/utils.py @@ -156,6 +156,8 @@ def plot_feature_importance(model: Any, pair: str, dk: FreqaiDataKitchen, if 'FreqaiMultiOutputRegressor' in str(model.__class__): for estimator, label in zip(model.estimators_, dk.label_list): models[label] = estimator + else: + models[dk.label_list[0]] for label in models: mdl = models[label] @@ -164,8 +166,8 @@ def plot_feature_importance(model: Any, pair: str, dk: FreqaiDataKitchen, elif "lightgbm.sklearn" or "xgb" in str(mdl.__class__): feature_importance = mdl.feature_importances_ else: - # TODO: Add support for more libraries - raise NotImplementedError(f"Cannot extract feature importance from {mdl.__class__}") + logger.info('Model type not support for generating feature importances.') + return # Data preparation fi_df = pd.DataFrame({ From 1ef875901aec7fabd11f794669d62c1047c009dd Mon Sep 17 00:00:00 2001 From: robcaulk Date: Sun, 18 Sep 2022 00:01:42 +0200 Subject: [PATCH 6/9] maintian user privacy by keeping plotly offline --- freqtrade/freqai/utils.py | 3 +-- freqtrade/plot/plotting.py | 4 ++-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/freqtrade/freqai/utils.py b/freqtrade/freqai/utils.py index 10afbaf52..50303019a 100644 --- a/freqtrade/freqai/utils.py +++ b/freqtrade/freqai/utils.py @@ -191,5 +191,4 @@ def plot_feature_importance(model: Any, pair: str, dk: FreqaiDataKitchen, fig = add_feature_trace(fig, fi_df_worst, 2) fig.update_layout(title_text=f"Best and worst features by importance {pair}") - store_plot_file(fig, f"{dk.model_filename}-{label}.html", dk.data_path, - include_plotlyjs="cdn") + store_plot_file(fig, f"{dk.model_filename}-{label}.html", dk.data_path) diff --git a/freqtrade/plot/plotting.py b/freqtrade/plot/plotting.py index 8a00c7899..752a25d2d 100644 --- a/freqtrade/plot/plotting.py +++ b/freqtrade/plot/plotting.py @@ -602,7 +602,7 @@ def generate_plot_filename(pair: str, timeframe: str) -> str: def store_plot_file(fig, filename: str, directory: Path, - auto_open: bool = False, include_plotlyjs=True) -> None: + auto_open: bool = False) -> None: """ Generate a plot html file from pre populated fig plotly object :param fig: Plotly Figure to plot @@ -615,7 +615,7 @@ def store_plot_file(fig, filename: str, directory: Path, _filename = directory.joinpath(filename) plot(fig, filename=str(_filename), - auto_open=auto_open, include_plotlyjs=include_plotlyjs) + auto_open=auto_open) logger.info(f"Stored plot as {_filename}") From fa3d4b58ab283bd5d5c490994eceaeec0a747aa3 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 18 Sep 2022 08:30:59 +0200 Subject: [PATCH 7/9] Revert unnecessary formatting --- freqtrade/plot/plotting.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/freqtrade/plot/plotting.py b/freqtrade/plot/plotting.py index 752a25d2d..f8e95300a 100644 --- a/freqtrade/plot/plotting.py +++ b/freqtrade/plot/plotting.py @@ -601,8 +601,7 @@ def generate_plot_filename(pair: str, timeframe: str) -> str: return file_name -def store_plot_file(fig, filename: str, directory: Path, - auto_open: bool = False) -> None: +def store_plot_file(fig, filename: str, directory: Path, auto_open: bool = False) -> None: """ Generate a plot html file from pre populated fig plotly object :param fig: Plotly Figure to plot From 188f75d8ec312e6d2687fc2442ef2517abfbd62e Mon Sep 17 00:00:00 2001 From: robcaulk Date: Sun, 18 Sep 2022 12:49:08 +0200 Subject: [PATCH 8/9] set model in models dict --- freqtrade/freqai/utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/freqtrade/freqai/utils.py b/freqtrade/freqai/utils.py index 50303019a..57bc17cdf 100644 --- a/freqtrade/freqai/utils.py +++ b/freqtrade/freqai/utils.py @@ -157,7 +157,7 @@ def plot_feature_importance(model: Any, pair: str, dk: FreqaiDataKitchen, for estimator, label in zip(model.estimators_, dk.label_list): models[label] = estimator else: - models[dk.label_list[0]] + models[dk.label_list[0]] = model for label in models: mdl = models[label] From 95457d23cae87da5fe11c4f053bb0e1c2b399541 Mon Sep 17 00:00:00 2001 From: robcaulk Date: Sun, 18 Sep 2022 13:59:30 +0200 Subject: [PATCH 9/9] escape freqai-specific characters from file naming --- freqtrade/freqai/utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/freqtrade/freqai/utils.py b/freqtrade/freqai/utils.py index 57bc17cdf..19a3098cc 100644 --- a/freqtrade/freqai/utils.py +++ b/freqtrade/freqai/utils.py @@ -190,5 +190,5 @@ def plot_feature_importance(model: Any, pair: str, dk: FreqaiDataKitchen, fig = add_feature_trace(fig, fi_df_top, 1) fig = add_feature_trace(fig, fi_df_worst, 2) fig.update_layout(title_text=f"Best and worst features by importance {pair}") - + label = label.replace('&', '').replace('%', '') # escape two FreqAI specific characters store_plot_file(fig, f"{dk.model_filename}-{label}.html", dk.data_path)