Merge remote-tracking branch 'upstream/develop' into hyperopt-trailing-space
This commit is contained in:
@@ -13,7 +13,8 @@ from pandas import DataFrame
|
||||
from tabulate import tabulate
|
||||
|
||||
from freqtrade import OperationalException
|
||||
from freqtrade.configuration import TimeRange, remove_credentials
|
||||
from freqtrade.configuration import (TimeRange, remove_credentials,
|
||||
validate_config_consistency)
|
||||
from freqtrade.data import history
|
||||
from freqtrade.data.dataprovider import DataProvider
|
||||
from freqtrade.exchange import timeframe_to_minutes, timeframe_to_seconds
|
||||
@@ -75,10 +76,12 @@ class Backtesting:
|
||||
stratconf = deepcopy(self.config)
|
||||
stratconf['strategy'] = strat
|
||||
self.strategylist.append(StrategyResolver(stratconf).strategy)
|
||||
validate_config_consistency(stratconf)
|
||||
|
||||
else:
|
||||
# No strategy list specified, only one strategy
|
||||
self.strategylist.append(StrategyResolver(self.config).strategy)
|
||||
validate_config_consistency(self.config)
|
||||
|
||||
if "ticker_interval" not in self.config:
|
||||
raise OperationalException("Ticker-interval needs to be set in either configuration "
|
||||
|
@@ -9,7 +9,8 @@ from typing import Any, Dict
|
||||
from tabulate import tabulate
|
||||
|
||||
from freqtrade import constants
|
||||
from freqtrade.configuration import TimeRange, remove_credentials
|
||||
from freqtrade.configuration import (TimeRange, remove_credentials,
|
||||
validate_config_consistency)
|
||||
from freqtrade.edge import Edge
|
||||
from freqtrade.exchange import Exchange
|
||||
from freqtrade.resolvers import StrategyResolver
|
||||
@@ -35,6 +36,8 @@ class EdgeCli:
|
||||
self.exchange = Exchange(self.config)
|
||||
self.strategy = StrategyResolver(self.config).strategy
|
||||
|
||||
validate_config_consistency(self.config)
|
||||
|
||||
self.edge = Edge(config, self.exchange, self.strategy)
|
||||
# Set refresh_pairs to false for edge-cli (it must be true for edge)
|
||||
self.edge._refresh_pairs = False
|
||||
|
@@ -23,7 +23,7 @@ from skopt import Optimizer
|
||||
from skopt.space import Dimension
|
||||
|
||||
from freqtrade.data.history import get_timeframe, trim_dataframe
|
||||
from freqtrade.misc import round_dict
|
||||
from freqtrade.misc import plural, round_dict
|
||||
from freqtrade.optimize.backtesting import Backtesting
|
||||
# Import IHyperOpt and IHyperOptLoss to allow unpickling classes from these modules
|
||||
from freqtrade.optimize.hyperopt_interface import IHyperOpt # noqa: F4
|
||||
@@ -77,6 +77,8 @@ class Hyperopt:
|
||||
# Previous evaluations
|
||||
self.trials: List = []
|
||||
|
||||
self.num_trials_saved = 0
|
||||
|
||||
# Populate functions here (hasattr is slow so should not be run during "regular" operations)
|
||||
if hasattr(self.custom_hyperopt, 'populate_indicators'):
|
||||
self.backtesting.strategy.advise_indicators = \
|
||||
@@ -132,13 +134,18 @@ class Hyperopt:
|
||||
arg_dict = {dim.name: value for dim, value in zip(dimensions, params)}
|
||||
return arg_dict
|
||||
|
||||
def save_trials(self) -> None:
|
||||
def save_trials(self, final: bool = False) -> None:
|
||||
"""
|
||||
Save hyperopt trials to file
|
||||
"""
|
||||
if self.trials:
|
||||
logger.info("Saving %d evaluations to '%s'", len(self.trials), self.trials_file)
|
||||
num_trials = len(self.trials)
|
||||
if num_trials > self.num_trials_saved:
|
||||
logger.info(f"Saving {num_trials} {plural(num_trials, 'epoch')}.")
|
||||
dump(self.trials, self.trials_file)
|
||||
self.num_trials_saved = num_trials
|
||||
if final:
|
||||
logger.info(f"{num_trials} {plural(num_trials, 'epoch')} "
|
||||
f"saved to '{self.trials_file}'.")
|
||||
|
||||
def read_trials(self) -> List:
|
||||
"""
|
||||
@@ -153,6 +160,12 @@ class Hyperopt:
|
||||
"""
|
||||
Display Best hyperopt result
|
||||
"""
|
||||
# This is printed when Ctrl+C is pressed quickly, before first epochs have
|
||||
# a chance to be evaluated.
|
||||
if not self.trials:
|
||||
print("No epochs evaluated yet, no best result.")
|
||||
return
|
||||
|
||||
results = sorted(self.trials, key=itemgetter('loss'))
|
||||
best_result = results[0]
|
||||
params = best_result['params']
|
||||
@@ -209,12 +222,20 @@ class Hyperopt:
|
||||
print('Trailing stop:')
|
||||
pprint(self.space_params(params, 'trailing', 5), indent=4)
|
||||
|
||||
def is_best(self, results) -> bool:
|
||||
return results['loss'] < self.current_best_loss
|
||||
|
||||
def log_results(self, results) -> None:
|
||||
"""
|
||||
Log results if it is better than any previous evaluation
|
||||
"""
|
||||
print_all = self.config.get('print_all', False)
|
||||
is_best_loss = results['loss'] < self.current_best_loss
|
||||
is_best_loss = self.is_best(results)
|
||||
|
||||
if not print_all:
|
||||
print('.', end='' if results['current_epoch'] % 100 != 0 else None) # type: ignore
|
||||
sys.stdout.flush()
|
||||
|
||||
if print_all or is_best_loss:
|
||||
if is_best_loss:
|
||||
self.current_best_loss = results['loss']
|
||||
@@ -229,13 +250,9 @@ class Hyperopt:
|
||||
print(log_str)
|
||||
else:
|
||||
print(f'\n{log_str}')
|
||||
else:
|
||||
print('.', end='')
|
||||
sys.stdout.flush()
|
||||
|
||||
def format_results_logstring(self, results) -> str:
|
||||
# Output human-friendly index here (starting from 1)
|
||||
current = results['current_epoch'] + 1
|
||||
current = results['current_epoch']
|
||||
total = self.total_epochs
|
||||
res = results['results_explanation']
|
||||
loss = results['loss']
|
||||
@@ -460,15 +477,19 @@ class Hyperopt:
|
||||
self.opt.tell(asked, [v['loss'] for v in f_val])
|
||||
self.fix_optimizer_models_list()
|
||||
for j in range(jobs):
|
||||
current = i * jobs + j
|
||||
# Use human-friendly index here (starting from 1)
|
||||
current = i * jobs + j + 1
|
||||
val = f_val[j]
|
||||
val['current_epoch'] = current
|
||||
val['is_initial_point'] = current < INITIAL_POINTS
|
||||
val['is_initial_point'] = current <= INITIAL_POINTS
|
||||
logger.debug(f"Optimizer epoch evaluated: {val}")
|
||||
is_best = self.is_best(val)
|
||||
self.log_results(val)
|
||||
self.trials.append(val)
|
||||
logger.debug(f"Optimizer epoch evaluated: {val}")
|
||||
if is_best or current % 100 == 0:
|
||||
self.save_trials()
|
||||
except KeyboardInterrupt:
|
||||
print('User interrupted..')
|
||||
|
||||
self.save_trials()
|
||||
self.save_trials(final=True)
|
||||
self.log_trials_result()
|
||||
|
Reference in New Issue
Block a user