diff --git a/freqtrade/optimize/hyperopt_auto.py b/freqtrade/optimize/hyperopt_auto.py index fb8adfe6b..31a11e303 100644 --- a/freqtrade/optimize/hyperopt_auto.py +++ b/freqtrade/optimize/hyperopt_auto.py @@ -51,7 +51,8 @@ class HyperOptAuto(IHyperOpt): def _generate_indicator_space(self, category): for attr_name, attr in self.strategy.enumerate_parameters(category): - yield attr.get_space(attr_name) + if attr.enabled: + yield attr.get_space(attr_name) def _get_indicator_space(self, category, fallback_method_name): indicator_space = list(self._generate_indicator_space(category)) diff --git a/freqtrade/strategy/hyper.py b/freqtrade/strategy/hyper.py index 0b3021af2..e6f63f5a5 100644 --- a/freqtrade/strategy/hyper.py +++ b/freqtrade/strategy/hyper.py @@ -2,6 +2,7 @@ IHyperStrategy interface, hyperoptable Parameter class. This module defines a base class for auto-hyperoptable strategies. """ +import logging from contextlib import suppress from typing import Iterator, Tuple, Any, Optional, Sequence, Union @@ -11,6 +12,9 @@ with suppress(ImportError): from freqtrade.exceptions import OperationalException +logger = logging.getLogger(__name__) + + class BaseParameter(object): """ Defines a parameter that can be optimized by hyperopt. @@ -21,7 +25,7 @@ class BaseParameter(object): opt_range: Sequence[Any] def __init__(self, *, opt_range: Sequence[Any], default: Any, space: Optional[str] = None, - **kwargs): + enabled: bool = True, **kwargs): """ Initialize hyperopt-optimizable parameter. :param space: A parameter category. Can be 'buy' or 'sell'. This parameter is optional if @@ -36,6 +40,7 @@ class BaseParameter(object): self._space_params = kwargs self.value = default self.opt_range = opt_range + self.enabled = enabled def __repr__(self): return f'{self.__class__.__name__}({self.value})' @@ -50,7 +55,7 @@ class IntParameter(BaseParameter): opt_range: Sequence[int] def __init__(self, low: Union[int, Sequence[int]], high: Optional[int] = None, *, default: int, - space: Optional[str] = None, **kwargs): + space: Optional[str] = None, enabled: bool = True, **kwargs): """ Initialize hyperopt-optimizable parameter. :param low: lower end of optimization space or [low, high]. @@ -67,7 +72,8 @@ class IntParameter(BaseParameter): opt_range = low else: opt_range = [low, high] - super().__init__(opt_range=opt_range, default=default, space=space, **kwargs) + super().__init__(opt_range=opt_range, default=default, space=space, enabled=enabled, + **kwargs) def get_space(self, name: str) -> 'Integer': """ @@ -83,7 +89,7 @@ class FloatParameter(BaseParameter): opt_range: Sequence[float] def __init__(self, low: Union[float, Sequence[float]], high: Optional[int] = None, *, - default: float, space: Optional[str] = None, **kwargs): + default: float, space: Optional[str] = None, enabled: bool = True, **kwargs): """ Initialize hyperopt-optimizable parameter. :param low: lower end of optimization space or [low, high]. @@ -100,7 +106,8 @@ class FloatParameter(BaseParameter): opt_range = low else: opt_range = [low, high] - super().__init__(opt_range=opt_range, default=default, space=space, **kwargs) + super().__init__(opt_range=opt_range, default=default, space=space, enabled=enabled, + **kwargs) def get_space(self, name: str) -> 'Real': """ @@ -116,7 +123,7 @@ class CategoricalParameter(BaseParameter): opt_range: Sequence[Any] def __init__(self, categories: Sequence[Any], *, default: Optional[Any] = None, - space: Optional[str] = None, **kwargs): + space: Optional[str] = None, enabled: bool = True, **kwargs): """ Initialize hyperopt-optimizable parameter. :param categories: Optimization space, [a, b, ...]. @@ -130,7 +137,8 @@ class CategoricalParameter(BaseParameter): if len(categories) < 2: raise OperationalException( 'IntParameter space must be [a, b, ...] (at least two parameters)') - super().__init__(opt_range=categories, default=default, space=space, **kwargs) + super().__init__(opt_range=categories, default=default, space=space, enabled=enabled, + **kwargs) def get_space(self, name: str) -> 'Categorical': """ @@ -167,7 +175,8 @@ class HyperStrategyMixin(object): if issubclass(attr.__class__, BaseParameter): if category is None or category == attr.category or \ attr_name.startswith(category + '_'): - yield attr_name, attr + if attr.enabled: + yield attr_name, attr def _load_params(self, params: dict) -> None: """ @@ -178,4 +187,9 @@ class HyperStrategyMixin(object): return for attr_name, attr in self.enumerate_parameters(): if attr_name in params: - attr.value = params[attr_name] + if attr.enabled: + attr.value = params[attr_name] + logger.info(f'attr_name = {attr.value}') + else: + logger.warning(f'Parameter "{attr_name}" exists, but is disabled. ' + f'Default value "{attr.value}" used.')