Add trailing stoploss hyperspace

This commit is contained in:
hroff-1902
2019-11-08 01:55:14 +03:00
parent ad2289c34c
commit f90676cfc5
4 changed files with 110 additions and 34 deletions

View File

@@ -149,7 +149,7 @@ class Hyperopt:
self.trials_file.unlink()
return trials
def log_trials_result(self) -> None:
def log_trials_result(self) -> None: # noqa: C901
"""
Display Best hyperopt result
"""
@@ -161,14 +161,16 @@ class Hyperopt:
if self.config.get('print_json'):
result_dict: Dict = {}
if self.has_space('buy') or self.has_space('sell'):
result_dict['params'] = {}
if self.has_space('buy'):
result_dict['params'].update({p.name: params.get(p.name)
for p in self.hyperopt_space('buy')})
result_dict['params'].update(self.space_params(params, 'buy'))
if self.has_space('sell'):
result_dict['params'].update({p.name: params.get(p.name)
for p in self.hyperopt_space('sell')})
result_dict['params'].update(self.space_params(params, 'sell'))
if self.has_space('roi'):
# Convert keys in min_roi dict to strings because
# rapidjson cannot dump dicts with integer keys...
@@ -177,25 +179,35 @@ class Hyperopt:
result_dict['minimal_roi'] = OrderedDict(
(str(k), v) for k, v in self.custom_hyperopt.generate_roi_table(params).items()
)
if self.has_space('stoploss'):
result_dict['stoploss'] = params.get('stoploss')
result_dict.update(self.space_params(params, 'stoploss'))
if self.has_space('trailing'):
result_dict.update(self.space_params(params, 'trailing'))
print(rapidjson.dumps(result_dict, default=str, number_mode=rapidjson.NM_NATIVE))
else:
if self.has_space('buy'):
print('Buy hyperspace params:')
pprint({p.name: params.get(p.name) for p in self.hyperopt_space('buy')},
indent=4)
pprint(self.space_params(params, 'buy', 5), indent=4)
if self.has_space('sell'):
print('Sell hyperspace params:')
pprint({p.name: params.get(p.name) for p in self.hyperopt_space('sell')},
indent=4)
pprint(self.space_params(params, 'sell', 5), indent=4)
if self.has_space('roi'):
print("ROI table:")
# Round printed values to 5 digits after the decimal point
pprint(round_dict(self.custom_hyperopt.generate_roi_table(params), 5), indent=4)
if self.has_space('stoploss'):
# Also round to 5 digits after the decimal point
print(f"Stoploss: {round(params.get('stoploss'), 5)}")
print(f"Stoploss:")
pprint(self.space_params(params, 'stoploss', 5), indent=4)
if self.has_space('trailing'):
print('Trailing stop:')
pprint(self.space_params(params, 'trailing', 5), indent=4)
def log_results(self, results) -> None:
"""
@@ -233,9 +245,13 @@ class Hyperopt:
def has_space(self, space: str) -> bool:
"""
Tell if a space value is contained in the configuration
Tell if the space value is contained in the configuration
"""
return any(s in self.config['spaces'] for s in [space, 'all'])
# The 'trailing' space is not included in the 'default' set of spaces
if space == 'trailing':
return any(s in self.config['spaces'] for s in [space, 'all'])
else:
return any(s in self.config['spaces'] for s in [space, 'all', 'default'])
def hyperopt_space(self, space: Optional[str] = None) -> List[Dimension]:
"""
@@ -245,20 +261,34 @@ class Hyperopt:
for all hyperspaces used.
"""
spaces: List[Dimension] = []
if space == 'buy' or (space is None and self.has_space('buy')):
logger.debug("Hyperopt has 'buy' space")
spaces += self.custom_hyperopt.indicator_space()
if space == 'sell' or (space is None and self.has_space('sell')):
logger.debug("Hyperopt has 'sell' space")
spaces += self.custom_hyperopt.sell_indicator_space()
if space == 'roi' or (space is None and self.has_space('roi')):
logger.debug("Hyperopt has 'roi' space")
spaces += self.custom_hyperopt.roi_space()
if space == 'stoploss' or (space is None and self.has_space('stoploss')):
logger.debug("Hyperopt has 'stoploss' space")
spaces += self.custom_hyperopt.stoploss_space()
if space == 'trailing' or (space is None and self.has_space('trailing')):
logger.debug("Hyperopt has 'trailing' space")
spaces += self.custom_hyperopt.trailing_space()
return spaces
def space_params(self, params, space: str, r: int = None) -> Dict:
d = {p.name: params.get(p.name) for p in self.hyperopt_space(space)}
# Round floats to `r` digits after the decimal point if requested
return round_dict(d, r) if r else d
def generate_optimizer(self, _params: Dict, iteration=None) -> Dict:
"""
Used Optimize function. Called once per epoch to optimize whatever is configured.
@@ -281,6 +311,15 @@ class Hyperopt:
if self.has_space('stoploss'):
self.backtesting.strategy.stoploss = params['stoploss']
if self.has_space('trailing'):
self.backtesting.strategy.trailing_stop = params['trailing_stop']
self.backtesting.strategy.trailing_stop_positive = \
params['trailing_stop_positive']
self.backtesting.strategy.trailing_stop_positive_offset = \
params['trailing_stop_positive_offset']
self.backtesting.strategy.trailing_only_offset_is_reached = \
params['trailing_only_offset_is_reached']
processed = load(self.tickerdata_pickle)
min_date, max_date = get_timeframe(processed)