diff --git a/freqtrade/configuration/config_validation.py b/freqtrade/configuration/config_validation.py index ee846e7e6..5f1f68554 100644 --- a/freqtrade/configuration/config_validation.py +++ b/freqtrade/configuration/config_validation.py @@ -85,6 +85,7 @@ def validate_config_consistency(conf: Dict[str, Any], preliminary: bool = False) _validate_unlimited_amount(conf) _validate_ask_orderbook(conf) validate_migrated_strategy_settings(conf) + _validate_freqai(conf) # validate configuration before returning logger.info('Validating configuration ...') @@ -163,6 +164,21 @@ def _validate_edge(conf: Dict[str, Any]) -> None: ) +def _validate_freqai(conf: Dict[str, Any]) -> None: + """ + Freqai param validator + """ + + if not conf.get('freqai', {}): + return + + for param in constants.SCHEMA_FREQAI_REQUIRED: + if param not in conf.get('freqai', {}): + raise OperationalException( + f'{param} not found in Freqai config' + ) + + def _validate_whitelist(conf: Dict[str, Any]) -> None: """ Dynamic whitelist does not require pair_whitelist to be set - however StaticWhitelist does. diff --git a/freqtrade/constants.py b/freqtrade/constants.py index 05581cc3a..eea657d84 100644 --- a/freqtrade/constants.py +++ b/freqtrade/constants.py @@ -515,6 +515,17 @@ SCHEMA_MINIMAL_REQUIRED = [ 'dataformat_trades', ] +SCHEMA_FREQAI_REQUIRED = [ + 'timeframes', + 'train_period', + 'backtest_period', + 'identifier', + 'corr_pairlist', + 'feature_parameters', + 'data_split_parameters', + 'model_training_parameters' +] + CANCEL_REASON = { "TIMEOUT": "cancelled due to timeout", "PARTIALLY_FILLED_KEEP_OPEN": "partially filled - keeping order open", diff --git a/freqtrade/enums/runmode.py b/freqtrade/enums/runmode.py index c280edf7c..6545aaec7 100644 --- a/freqtrade/enums/runmode.py +++ b/freqtrade/enums/runmode.py @@ -15,10 +15,9 @@ class RunMode(Enum): UTIL_NO_EXCHANGE = "util_no_exchange" PLOT = "plot" WEBSERVER = "webserver" - FREQAI = "freqai" OTHER = "other" TRADING_MODES = [RunMode.LIVE, RunMode.DRY_RUN] -OPTIMIZE_MODES = [RunMode.BACKTEST, RunMode.EDGE, RunMode.HYPEROPT, RunMode.FREQAI] +OPTIMIZE_MODES = [RunMode.BACKTEST, RunMode.EDGE, RunMode.HYPEROPT] NON_UTIL_MODES = TRADING_MODES + OPTIMIZE_MODES diff --git a/freqtrade/freqai/data_kitchen.py b/freqtrade/freqai/data_kitchen.py index b0eb8b40d..c5f57bf86 100644 --- a/freqtrade/freqai/data_kitchen.py +++ b/freqtrade/freqai/data_kitchen.py @@ -44,7 +44,6 @@ class FreqaiDataKitchen: self.data: Dict[Any, Any] = {} self.data_dictionary: Dict[Any, Any] = {} self.config = config - self.assert_config(self.config, live) self.freqai_config = config["freqai"] self.predictions: npt.ArrayLike = np.array([]) self.do_predict: npt.ArrayLike = np.array([]) @@ -72,28 +71,6 @@ class FreqaiDataKitchen: self.data_drawer = data_drawer - def assert_config(self, config: Dict[str, Any], live: bool) -> None: - if not config.get('freqai'): - logger.error('No Freqai parameters found in config file.') - - # assert config.get('freqai'), "No Freqai parameters found in config file." - # assert config.get('freqai', {}).get('train_period'), ("No Freqai train_period found in" - # "config file.") - # assert type(config.get('freqai', {}) - # .get('train_period')) is int, ('Can only train on full day period.' - # 'No fractional days permitted.') - # assert config.get('freqai', {}).get('backtest_period'), ("No Freqai backtest_period found" - # "in config file.") - # if not live: - # assert type(config.get('freqai', {}) - # .get('backtest_period')) is int, ('Can only backtest on full day' - # 'backtest_period. Only live/dry mode' - # 'allows fractions of days') - # assert config.get('freqai', {}).get('identifier'), ("No Freqai identifier found in config" - # "file.") - # assert config.get('freqai', {}).get('feature_parameters'), ("No Freqai feature_parameters" - # "found in config file.") - def set_paths(self, metadata: dict, trained_timestamp: int = None,) -> None: self.full_path = Path(self.config['user_data_dir'] / "models" / diff --git a/freqtrade/freqai/freqai_interface.py b/freqtrade/freqai/freqai_interface.py index 041343683..71807ad19 100644 --- a/freqtrade/freqai/freqai_interface.py +++ b/freqtrade/freqai/freqai_interface.py @@ -13,6 +13,7 @@ from pandas import DataFrame from freqtrade.configuration import TimeRange from freqtrade.enums import RunMode +from freqtrade.exceptions import OperationalException from freqtrade.freqai.data_drawer import FreqaiDataDrawer from freqtrade.freqai.data_kitchen import FreqaiDataKitchen from freqtrade.strategy.interface import IStrategy @@ -57,18 +58,11 @@ class IFreqaiModel(ABC): self.config['exchange']['pair_whitelist']) def assert_config(self, config: Dict[str, Any]) -> None: - if not config.get('freqai'): - logger.error('No Freqai parameters found in config file.') - # assert config.get('freqai'), "No Freqai parameters found in config file." - # assert config.get('freqai', {}).get('data_split_parameters'), ("No Freqai" - # "data_split_parameters" - # "in config file.") - # assert config.get('freqai', {}).get('model_training_parameters'), ("No Freqai" - # "modeltrainingparameters" - # "found in config file.") - # assert config.get('freqai', {}).get('feature_parameters'), ("No Freqai" - # "feature_parameters found in" - # "config file.") + + if not config.get('freqai', {}): + raise OperationalException( + "No freqai parameters found in configuration file." + ) def start(self, dataframe: DataFrame, metadata: dict, strategy: IStrategy) -> DataFrame: """