Merge pull request #5046 from freqtrade/list_strategy_hyperopt
allow list-strategies to show if params are hyperoptable
This commit is contained in:
commit
e17e35f0ef
@ -54,15 +54,21 @@ def _print_objs_tabular(objs: List, print_colorized: bool) -> None:
|
|||||||
reset = ''
|
reset = ''
|
||||||
|
|
||||||
names = [s['name'] for s in objs]
|
names = [s['name'] for s in objs]
|
||||||
objss_to_print = [{
|
objs_to_print = [{
|
||||||
'name': s['name'] if s['name'] else "--",
|
'name': s['name'] if s['name'] else "--",
|
||||||
'location': s['location'].name,
|
'location': s['location'].name,
|
||||||
'status': (red + "LOAD FAILED" + reset if s['class'] is None
|
'status': (red + "LOAD FAILED" + reset if s['class'] is None
|
||||||
else "OK" if names.count(s['name']) == 1
|
else "OK" if names.count(s['name']) == 1
|
||||||
else yellow + "DUPLICATE NAME" + reset)
|
else yellow + "DUPLICATE NAME" + reset)
|
||||||
} for s in objs]
|
} for s in objs]
|
||||||
|
for idx, s in enumerate(objs):
|
||||||
print(tabulate(objss_to_print, headers='keys', tablefmt='psql', stralign='right'))
|
if 'hyperoptable' in s:
|
||||||
|
objs_to_print[idx].update({
|
||||||
|
'hyperoptable': "Yes" if s['hyperoptable']['count'] > 0 else "No",
|
||||||
|
'buy-Params': len(s['hyperoptable'].get('buy', [])),
|
||||||
|
'sell-Params': len(s['hyperoptable'].get('sell', [])),
|
||||||
|
})
|
||||||
|
print(tabulate(objs_to_print, headers='keys', tablefmt='psql', stralign='right'))
|
||||||
|
|
||||||
|
|
||||||
def start_list_strategies(args: Dict[str, Any]) -> None:
|
def start_list_strategies(args: Dict[str, Any]) -> None:
|
||||||
@ -75,6 +81,11 @@ def start_list_strategies(args: Dict[str, Any]) -> None:
|
|||||||
strategy_objs = StrategyResolver.search_all_objects(directory, not args['print_one_column'])
|
strategy_objs = StrategyResolver.search_all_objects(directory, not args['print_one_column'])
|
||||||
# Sort alphabetically
|
# Sort alphabetically
|
||||||
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:
|
||||||
|
if obj['class']:
|
||||||
|
obj['hyperoptable'] = obj['class'].detect_all_parameters()
|
||||||
|
else:
|
||||||
|
obj['hyperoptable'] = {'count': 0}
|
||||||
|
|
||||||
if args['print_one_column']:
|
if args['print_one_column']:
|
||||||
print('\n'.join([s['name'] for s in strategy_objs]))
|
print('\n'.join([s['name'] for s in strategy_objs]))
|
||||||
|
@ -273,11 +273,12 @@ class HyperStrategyMixin(object):
|
|||||||
for par in params:
|
for par in params:
|
||||||
yield par.name, par
|
yield par.name, par
|
||||||
|
|
||||||
def _detect_parameters(self, category: str) -> Iterator[Tuple[str, BaseParameter]]:
|
@classmethod
|
||||||
|
def detect_parameters(cls, category: str) -> Iterator[Tuple[str, BaseParameter]]:
|
||||||
""" Detect all parameters for 'category' """
|
""" Detect all parameters for 'category' """
|
||||||
for attr_name in dir(self):
|
for attr_name in dir(cls):
|
||||||
if not attr_name.startswith('__'): # Ignore internals, not strictly necessary.
|
if not attr_name.startswith('__'): # Ignore internals, not strictly necessary.
|
||||||
attr = getattr(self, attr_name)
|
attr = getattr(cls, attr_name)
|
||||||
if issubclass(attr.__class__, BaseParameter):
|
if issubclass(attr.__class__, BaseParameter):
|
||||||
if (attr_name.startswith(category + '_')
|
if (attr_name.startswith(category + '_')
|
||||||
and attr.category is not None and attr.category != category):
|
and attr.category is not None and attr.category != category):
|
||||||
@ -287,6 +288,19 @@ class HyperStrategyMixin(object):
|
|||||||
(attr_name.startswith(category + '_') and attr.category is None)):
|
(attr_name.startswith(category + '_') and attr.category is None)):
|
||||||
yield attr_name, attr
|
yield attr_name, attr
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def detect_all_parameters(cls) -> Dict:
|
||||||
|
""" Detect all parameters and return them as a list"""
|
||||||
|
params: Dict = {
|
||||||
|
'buy': list(cls.detect_parameters('buy')),
|
||||||
|
'sell': list(cls.detect_parameters('sell')),
|
||||||
|
}
|
||||||
|
params.update({
|
||||||
|
'count': len(params['buy'] + params['sell'])
|
||||||
|
})
|
||||||
|
|
||||||
|
return params
|
||||||
|
|
||||||
def _load_hyper_params(self, hyperopt: bool = False) -> None:
|
def _load_hyper_params(self, hyperopt: bool = False) -> None:
|
||||||
"""
|
"""
|
||||||
Load Hyperoptable parameters
|
Load Hyperoptable parameters
|
||||||
@ -303,7 +317,7 @@ class HyperStrategyMixin(object):
|
|||||||
logger.info(f"No params for {space} found, using default values.")
|
logger.info(f"No params for {space} found, using default values.")
|
||||||
param_container: List[BaseParameter] = getattr(self, f"ft_{space}_params")
|
param_container: List[BaseParameter] = getattr(self, f"ft_{space}_params")
|
||||||
|
|
||||||
for attr_name, attr in self._detect_parameters(space):
|
for attr_name, attr in self.detect_parameters(space):
|
||||||
attr.name = attr_name
|
attr.name = attr_name
|
||||||
attr.in_space = hyperopt and HyperoptTools.has_space(self.config, space)
|
attr.in_space = hyperopt and HyperoptTools.has_space(self.config, space)
|
||||||
if not attr.category:
|
if not attr.category:
|
||||||
|
@ -667,8 +667,13 @@ def test_auto_hyperopt_interface(default_conf):
|
|||||||
|
|
||||||
# Parameter is disabled - so value from sell_param dict will NOT be used.
|
# Parameter is disabled - so value from sell_param dict will NOT be used.
|
||||||
assert strategy.sell_minusdi.value == 0.5
|
assert strategy.sell_minusdi.value == 0.5
|
||||||
|
all_params = strategy.detect_all_parameters()
|
||||||
|
assert isinstance(all_params, dict)
|
||||||
|
assert len(all_params['buy']) == 2
|
||||||
|
assert len(all_params['sell']) == 2
|
||||||
|
assert all_params['count'] == 4
|
||||||
|
|
||||||
strategy.sell_rsi = IntParameter([0, 10], default=5, space='buy')
|
strategy.__class__.sell_rsi = IntParameter([0, 10], default=5, space='buy')
|
||||||
|
|
||||||
with pytest.raises(OperationalException, match=r"Inconclusive parameter.*"):
|
with pytest.raises(OperationalException, match=r"Inconclusive parameter.*"):
|
||||||
[x for x in strategy._detect_parameters('sell')]
|
[x for x in strategy.detect_parameters('sell')]
|
||||||
|
Loading…
Reference in New Issue
Block a user