fix: don't break list-strategies if one strategy has invalid parameters

This commit is contained in:
Matthias
2026-02-07 13:40:51 +01:00
parent 646531cbfc
commit 65a713a569
3 changed files with 16 additions and 9 deletions

View File

@@ -4,7 +4,7 @@ import sys
from typing import Any from typing import Any
from freqtrade.enums import RunMode from freqtrade.enums import RunMode
from freqtrade.exceptions import ConfigurationError, OperationalException from freqtrade.exceptions import ConfigurationError, DependencyException, OperationalException
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@@ -166,7 +166,14 @@ def start_list_strategies(args: dict[str, Any]) -> None:
strategy_objs = sorted(strategy_objs, key=lambda x: x["name"]) strategy_objs = sorted(strategy_objs, key=lambda x: x["name"])
for obj in strategy_objs: for obj in strategy_objs:
if obj["class"]: if obj["class"]:
obj["hyperoptable"] = detect_all_parameters(obj["class"]) try:
obj["hyperoptable"] = detect_all_parameters(obj["class"])
except DependencyException as e:
logger.warning(
f"Cannot detect hyperoptable parameters for strategy {obj['name']}. Reason: {e}"
)
obj["hyperoptable"] = {}
else: else:
obj["hyperoptable"] = {} obj["hyperoptable"] = {}

View File

@@ -9,7 +9,7 @@ from collections.abc import Iterator
from pathlib import Path from pathlib import Path
from freqtrade.constants import Config from freqtrade.constants import Config
from freqtrade.exceptions import OperationalException from freqtrade.exceptions import DependencyException, OperationalException
from freqtrade.misc import deep_merge_dicts from freqtrade.misc import deep_merge_dicts
from freqtrade.optimize.hyperopt_tools import HyperoptTools from freqtrade.optimize.hyperopt_tools import HyperoptTools
from freqtrade.strategy.parameters import BaseParameter from freqtrade.strategy.parameters import BaseParameter
@@ -179,10 +179,10 @@ def detect_all_parameters(
attr.space = space attr.space = space
break break
if attr.space is None: if attr.space is None:
raise OperationalException(f"Cannot determine parameter space for {attr_name}.") raise DependencyException(f"Cannot determine parameter space for {attr_name}.")
if attr.space in ("all", "default") or attr.space.isidentifier() is False: if attr.space in ("all", "default") or attr.space.isidentifier() is False:
raise OperationalException( raise DependencyException(
f"'{attr.space}' is not a valid space. Parameter: {attr_name}." f"'{attr.space}' is not a valid space. Parameter: {attr_name}."
) )
attr.name = attr_name attr.name = attr_name

View File

@@ -13,7 +13,7 @@ from freqtrade.constants import CUSTOM_TAG_MAX_LENGTH
from freqtrade.data.dataprovider import DataProvider from freqtrade.data.dataprovider import DataProvider
from freqtrade.data.history import load_data from freqtrade.data.history import load_data
from freqtrade.enums import ExitCheckTuple, ExitType, SignalDirection from freqtrade.enums import ExitCheckTuple, ExitType, SignalDirection
from freqtrade.exceptions import OperationalException, StrategyError from freqtrade.exceptions import DependencyException, OperationalException, StrategyError
from freqtrade.persistence import PairLocks, Trade from freqtrade.persistence import PairLocks, Trade
from freqtrade.resolvers import StrategyResolver from freqtrade.resolvers import StrategyResolver
from freqtrade.strategy.hyper import detect_all_parameters from freqtrade.strategy.hyper import detect_all_parameters
@@ -958,20 +958,20 @@ def test_auto_hyperopt_interface(default_conf):
strategy.__class__.exit22_rsi = IntParameter([0, 10], default=5) strategy.__class__.exit22_rsi = IntParameter([0, 10], default=5)
with pytest.raises( with pytest.raises(
OperationalException, match=r"Cannot determine parameter space for exit22_rsi\." DependencyException, match=r"Cannot determine parameter space for exit22_rsi\."
): ):
detect_all_parameters(strategy.__class__) detect_all_parameters(strategy.__class__)
# Invalid parameter space # Invalid parameter space
strategy.__class__.exit22_rsi = IntParameter([0, 10], default=5, space="all") strategy.__class__.exit22_rsi = IntParameter([0, 10], default=5, space="all")
with pytest.raises( with pytest.raises(
OperationalException, match=r"'all' is not a valid space\. Parameter: exit22_rsi\." DependencyException, match=r"'all' is not a valid space\. Parameter: exit22_rsi\."
): ):
detect_all_parameters(strategy.__class__) detect_all_parameters(strategy.__class__)
strategy.__class__.exit22_rsi = IntParameter([0, 10], default=5, space="hello:world:22") strategy.__class__.exit22_rsi = IntParameter([0, 10], default=5, space="hello:world:22")
with pytest.raises( with pytest.raises(
OperationalException, DependencyException,
match=r"'hello:world:22' is not a valid space\. Parameter: exit22_rsi\.", match=r"'hello:world:22' is not a valid space\. Parameter: exit22_rsi\.",
): ):
detect_all_parameters(strategy.__class__) detect_all_parameters(strategy.__class__)