Merge pull request #5644 from slyons/develop
Add ability to ignore unparameterized spaces
This commit is contained in:
		| @@ -51,6 +51,7 @@ usage: freqtrade hyperopt [-h] [-v] [--logfile FILE] [-V] [-c PATH] [-d PATH] | ||||
|                           [--print-all] [--no-color] [--print-json] [-j JOBS] | ||||
|                           [--random-state INT] [--min-trades INT] | ||||
|                           [--hyperopt-loss NAME] [--disable-param-export] | ||||
|                           [--ignore-missing-spaces] | ||||
|  | ||||
| optional arguments: | ||||
|   -h, --help            show this help message and exit | ||||
| @@ -118,6 +119,9 @@ optional arguments: | ||||
|                         MaxDrawDownHyperOptLoss | ||||
|   --disable-param-export | ||||
|                         Disable automatic hyperopt parameter export. | ||||
|   --ignore-missing-spaces, --ignore-unparameterized-spaces | ||||
|                         Suppress errors for any requested Hyperopt spaces that | ||||
|                         do not contain any parameters. | ||||
|  | ||||
| Common arguments: | ||||
|   -v, --verbose         Verbose mode (-vv for more, -vvv to get all messages). | ||||
|   | ||||
| @@ -31,7 +31,8 @@ ARGS_HYPEROPT = ARGS_COMMON_OPTIMIZE + ["hyperopt", "hyperopt_path", | ||||
|                                         "epochs", "spaces", "print_all", | ||||
|                                         "print_colorized", "print_json", "hyperopt_jobs", | ||||
|                                         "hyperopt_random_state", "hyperopt_min_trades", | ||||
|                                         "hyperopt_loss", "disableparamexport"] | ||||
|                                         "hyperopt_loss", "disableparamexport", | ||||
|                                         "hyperopt_ignore_missing_space"] | ||||
|  | ||||
| ARGS_EDGE = ARGS_COMMON_OPTIMIZE + ["stoploss_range"] | ||||
|  | ||||
|   | ||||
| @@ -558,4 +558,10 @@ AVAILABLE_CLI_OPTIONS = { | ||||
|         help='Do not print epoch details header.', | ||||
|         action='store_true', | ||||
|     ), | ||||
|     "hyperopt_ignore_missing_space": Arg( | ||||
|         "--ignore-missing-spaces", "--ignore-unparameterized-spaces", | ||||
|         help=("Suppress errors for any requested Hyperopt spaces " | ||||
|               "that do not contain any parameters."), | ||||
|         action="store_true", | ||||
|     ), | ||||
| } | ||||
|   | ||||
| @@ -369,6 +369,9 @@ class Configuration: | ||||
|         self._args_to_config(config, argname='hyperopt_show_no_header', | ||||
|                              logstring='Parameter --no-header detected: {}') | ||||
|  | ||||
|         self._args_to_config(config, argname="hyperopt_ignore_missing_space", | ||||
|                              logstring="Paramter --ignore-missing-space detected: {}") | ||||
|  | ||||
|     def _process_plot_options(self, config: Dict[str, Any]) -> None: | ||||
|  | ||||
|         self._args_to_config(config, argname='pairs', | ||||
|   | ||||
| @@ -258,6 +258,7 @@ class Hyperopt: | ||||
|         if HyperoptTools.has_space(self.config, 'trailing'): | ||||
|             logger.debug("Hyperopt has 'trailing' space") | ||||
|             self.trailing_space = self.custom_hyperopt.trailing_space() | ||||
|  | ||||
|         self.dimensions = (self.buy_space + self.sell_space + self.protection_space | ||||
|                            + self.roi_space + self.stoploss_space + self.trailing_space) | ||||
|  | ||||
|   | ||||
| @@ -3,6 +3,7 @@ HyperOptAuto class. | ||||
| This module implements a convenience auto-hyperopt class, which can be used together with strategies | ||||
|  that implement IHyperStrategy interface. | ||||
| """ | ||||
| import logging | ||||
| from contextlib import suppress | ||||
| from typing import Callable, Dict, List | ||||
|  | ||||
| @@ -15,12 +16,19 @@ with suppress(ImportError): | ||||
| from freqtrade.optimize.hyperopt_interface import EstimatorType, IHyperOpt | ||||
|  | ||||
|  | ||||
| def _format_exception_message(space: str) -> str: | ||||
|     raise OperationalException( | ||||
|         f"The '{space}' space is included into the hyperoptimization " | ||||
|         f"but no parameter for this space was not found in your Strategy. " | ||||
|         f"Please make sure to have parameters for this space enabled for optimization " | ||||
|         f"or remove the '{space}' space from hyperoptimization.") | ||||
| logger = logging.getLogger(__name__) | ||||
|  | ||||
|  | ||||
| def _format_exception_message(space: str, ignore_missing_space: bool) -> None: | ||||
|     msg = (f"The '{space}' space is included into the hyperoptimization " | ||||
|            f"but no parameter for this space was not found in your Strategy. " | ||||
|            ) | ||||
|     if ignore_missing_space: | ||||
|         logger.warning(msg + "This space will be ignored.") | ||||
|     else: | ||||
|         raise OperationalException( | ||||
|             msg + f"Please make sure to have parameters for this space enabled for optimization " | ||||
|             f"or remove the '{space}' space from hyperoptimization.") | ||||
|  | ||||
|  | ||||
| class HyperOptAuto(IHyperOpt): | ||||
| @@ -48,13 +56,16 @@ class HyperOptAuto(IHyperOpt): | ||||
|             if attr.optimize: | ||||
|                 yield attr.get_space(attr_name) | ||||
|  | ||||
|     def _get_indicator_space(self, category): | ||||
|     def _get_indicator_space(self, category) -> List: | ||||
|         # TODO: is this necessary, or can we call "generate_space" directly? | ||||
|         indicator_space = list(self._generate_indicator_space(category)) | ||||
|         if len(indicator_space) > 0: | ||||
|             return indicator_space | ||||
|         else: | ||||
|             _format_exception_message(category) | ||||
|             _format_exception_message( | ||||
|                 category, | ||||
|                 self.config.get("hyperopt_ignore_missing_space", False)) | ||||
|             return [] | ||||
|  | ||||
|     def buy_indicator_space(self) -> List['Dimension']: | ||||
|         return self._get_indicator_space('buy') | ||||
|   | ||||
| @@ -702,7 +702,7 @@ def test_simplified_interface_roi_stoploss(mocker, hyperopt_conf, capsys) -> Non | ||||
|     assert hasattr(hyperopt, "position_stacking") | ||||
|  | ||||
|  | ||||
| def test_simplified_interface_all_failed(mocker, hyperopt_conf) -> None: | ||||
| def test_simplified_interface_all_failed(mocker, hyperopt_conf, caplog) -> None: | ||||
|     mocker.patch('freqtrade.optimize.hyperopt.dump', MagicMock()) | ||||
|     mocker.patch('freqtrade.optimize.hyperopt.file_dump_json') | ||||
|     mocker.patch('freqtrade.optimize.backtesting.Backtesting.load_bt_data', | ||||
| @@ -724,7 +724,13 @@ def test_simplified_interface_all_failed(mocker, hyperopt_conf) -> None: | ||||
|     hyperopt.custom_hyperopt.generate_roi_table = MagicMock(return_value={}) | ||||
|  | ||||
|     with pytest.raises(OperationalException, match=r"The 'protection' space is included into *"): | ||||
|         hyperopt.start() | ||||
|         hyperopt.init_spaces() | ||||
|  | ||||
|     hyperopt.config['hyperopt_ignore_missing_space'] = True | ||||
|     caplog.clear() | ||||
|     hyperopt.init_spaces() | ||||
|     assert log_has_re(r"The 'protection' space is included into *", caplog) | ||||
|     assert hyperopt.protection_space == [] | ||||
|  | ||||
|  | ||||
| def test_simplified_interface_buy(mocker, hyperopt_conf, capsys) -> None: | ||||
|   | ||||
		Reference in New Issue
	
	Block a user