From ea4b5d675df701d9cb0d6b36ada7cd9023408c97 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 10 Apr 2021 07:12:31 +0200 Subject: [PATCH] Don't explode low/high, but use explicit parameters --- freqtrade/strategy/hyper.py | 48 ++++++++++++++++++++++--------------- 1 file changed, 29 insertions(+), 19 deletions(-) diff --git a/freqtrade/strategy/hyper.py b/freqtrade/strategy/hyper.py index 9a7fc4ba4..c72beba55 100644 --- a/freqtrade/strategy/hyper.py +++ b/freqtrade/strategy/hyper.py @@ -25,9 +25,8 @@ class BaseParameter(ABC): category: Optional[str] default: Any value: Any - opt_range: Sequence[Any] - def __init__(self, *, opt_range: Sequence[Any], default: Any, space: Optional[str] = None, + def __init__(self, *, default: Any, space: Optional[str] = None, optimize: bool = True, load: bool = True, **kwargs): """ Initialize hyperopt-optimizable parameter. @@ -44,7 +43,6 @@ class BaseParameter(ABC): self.category = space self._space_params = kwargs self.value = default - self.opt_range = opt_range self.optimize = optimize self.load = load @@ -69,7 +67,6 @@ class BaseParameter(ABC): class IntParameter(BaseParameter): default: int value: int - opt_range: Sequence[int] def __init__(self, low: Union[int, Sequence[int]], high: Optional[int] = None, *, default: int, space: Optional[str] = None, optimize: bool = True, load: bool = True, **kwargs): @@ -90,10 +87,12 @@ class IntParameter(BaseParameter): if high is None or isinstance(low, Sequence): if not isinstance(low, Sequence) or len(low) != 2: raise OperationalException('IntParameter space must be [low, high]') - opt_range = low + self.low, self.high = low else: - opt_range = [low, high] - super().__init__(opt_range=opt_range, default=default, space=space, optimize=optimize, + self.low = low + self.high = high + + super().__init__(default=default, space=space, optimize=optimize, load=load, **kwargs) def get_space(self, name: str) -> 'Integer': @@ -101,13 +100,12 @@ class IntParameter(BaseParameter): Create skopt optimization space. :param name: A name of parameter field. """ - return Integer(*self.opt_range, name=name, **self._space_params) + return Integer(low=self.low, high=self.high, name=name, **self._space_params) class RealParameter(BaseParameter): default: float value: float - opt_range: Sequence[float] def __init__(self, low: Union[float, Sequence[float]], high: Optional[float] = None, *, default: float, space: Optional[str] = None, optimize: bool = True, @@ -129,10 +127,11 @@ class RealParameter(BaseParameter): if high is None or isinstance(low, Sequence): if not isinstance(low, Sequence) or len(low) != 2: raise OperationalException(f'{self.__class__.__name__} space must be [low, high]') - opt_range = low + self.low, self.high = low else: - opt_range = [low, high] - super().__init__(opt_range=opt_range, default=default, space=space, optimize=optimize, + self.low = low + self.high = high + super().__init__(default=default, space=space, optimize=optimize, load=load, **kwargs) def get_space(self, name: str) -> 'Real': @@ -140,13 +139,12 @@ class RealParameter(BaseParameter): Create skopt optimization space. :param name: A name of parameter field. """ - return Real(*self.opt_range, name=name, **self._space_params) + return Real(low=self.low, high=self.high, name=name, **self._space_params) -class DecimalParameter(RealParameter): +class DecimalParameter(BaseParameter): default: float value: float - opt_range: Sequence[float] def __init__(self, low: Union[float, Sequence[float]], high: Optional[float] = None, *, default: float, decimals: int = 3, space: Optional[str] = None, @@ -162,11 +160,22 @@ class DecimalParameter(RealParameter): parameter fieldname is prefixed with 'buy_' or 'sell_'. :param optimize: Include parameter in hyperopt optimizations. :param load: Load parameter value from {space}_params. - :param kwargs: Extra parameters to skopt.space.Real. + :param kwargs: Extra parameters to skopt.space.Integer. """ self._decimals = decimals default = round(default, self._decimals) - super().__init__(low=low, high=high, default=default, space=space, optimize=optimize, + + if high is not None and isinstance(low, Sequence): + raise OperationalException(f'{self.__class__.__name__} space invalid.') + if high is None or isinstance(low, Sequence): + if not isinstance(low, Sequence) or len(low) != 2: + raise OperationalException(f'{self.__class__.__name__} space must be [low, high]') + self.low, self.high = low + else: + self.low = low + self.high = high + + super().__init__(default=default, space=space, optimize=optimize, load=load, **kwargs) def get_space(self, name: str) -> 'SKDecimal': @@ -174,7 +183,7 @@ class DecimalParameter(RealParameter): Create skopt optimization space. :param name: A name of parameter field. """ - return SKDecimal(*self.opt_range, decimals=self._decimals, name=name, + return SKDecimal(low=self.low, high=self.high, decimals=self._decimals, name=name, **self._space_params) @@ -200,7 +209,8 @@ class CategoricalParameter(BaseParameter): if len(categories) < 2: raise OperationalException( 'CategoricalParameter space must be [a, b, ...] (at least two parameters)') - super().__init__(opt_range=categories, default=default, space=space, optimize=optimize, + self.opt_range = categories + super().__init__(default=default, space=space, optimize=optimize, load=load, **kwargs) def get_space(self, name: str) -> 'Categorical':