Merge pull request #2089 from hroff-1902/hyperopt-print-colorized

Hyperopt print colorized results
This commit is contained in:
Matthias 2019-08-13 19:36:06 +02:00 committed by GitHub
commit c0784b7c33
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 47 additions and 5 deletions

View File

@ -207,7 +207,7 @@ usage: freqtrade hyperopt [-h] [-i TICKER_INTERVAL] [--timerange TIMERANGE]
[--customhyperopt NAME] [--hyperopt-path PATH] [--customhyperopt NAME] [--hyperopt-path PATH]
[--eps] [-e INT] [--eps] [-e INT]
[-s {all,buy,sell,roi,stoploss} [{all,buy,sell,roi,stoploss} ...]] [-s {all,buy,sell,roi,stoploss} [{all,buy,sell,roi,stoploss} ...]]
[--dmmp] [--print-all] [-j JOBS] [--dmmp] [--print-all] [--no-color] [-j JOBS]
[--random-state INT] [--min-trades INT] [--continue] [--random-state INT] [--min-trades INT] [--continue]
[--hyperopt-loss NAME] [--hyperopt-loss NAME]
@ -243,6 +243,8 @@ optional arguments:
(same as setting `max_open_trades` to a very high (same as setting `max_open_trades` to a very high
number). number).
--print-all Print all results, not only the best ones. --print-all Print all results, not only the best ones.
--no-color Disable colorization of hyperopt results. May be
useful if you are redirecting output to a file.
-j JOBS, --job-workers JOBS -j JOBS, --job-workers JOBS
The number of concurrently running jobs for The number of concurrently running jobs for
hyperoptimization (hyperopt worker processes). If -1 hyperoptimization (hyperopt worker processes). If -1

View File

@ -352,6 +352,10 @@ def populate_buy_trend(self, dataframe: DataFrame) -> DataFrame:
return dataframe return dataframe
``` ```
By default, hyperopt prints colorized results -- epochs with positive profit are printed in the green color. This highlighting helps you find epochs that can be interesting for later analysis. Epochs with zero total profit or with negative profits (losses) are printed in the normal color. If you do not need colorization of results (for instance, when you are redirecting hyperopt output to a file) you can switch colorization off by specifying the `--no-color` option in the command line.
You can use the `--print-all` command line option if you would like to see all results in the hyperopt output, not only the best ones. When `--print-all` is used, current best results are also colorized by default -- they are printed in bold (bright) style. This can also be switched off with the `--no-color` command line option.
### Understand Hyperopt ROI results ### Understand Hyperopt ROI results
If you are optimizing ROI (i.e. if optimization search-space contains 'all' or 'roi'), your result will look as follows and include a ROI table: If you are optimizing ROI (i.e. if optimization search-space contains 'all' or 'roi'), your result will look as follows and include a ROI table:

View File

@ -23,7 +23,8 @@ ARGS_BACKTEST = ARGS_COMMON_OPTIMIZE + ["position_stacking", "use_max_market_pos
ARGS_HYPEROPT = ARGS_COMMON_OPTIMIZE + ["hyperopt", "hyperopt_path", ARGS_HYPEROPT = ARGS_COMMON_OPTIMIZE + ["hyperopt", "hyperopt_path",
"position_stacking", "epochs", "spaces", "position_stacking", "epochs", "spaces",
"use_max_market_positions", "print_all", "hyperopt_jobs", "use_max_market_positions", "print_all",
"print_colorized", "hyperopt_jobs",
"hyperopt_random_state", "hyperopt_min_trades", "hyperopt_random_state", "hyperopt_min_trades",
"hyperopt_continue", "hyperopt_loss"] "hyperopt_continue", "hyperopt_loss"]

View File

@ -191,6 +191,13 @@ AVAILABLE_CLI_OPTIONS = {
action='store_true', action='store_true',
default=False, default=False,
), ),
"print_colorized": Arg(
'--no-color',
help='Disable colorization of hyperopt results. May be useful if you are '
'redirecting output to a file.',
action='store_false',
default=True,
),
"hyperopt_jobs": Arg( "hyperopt_jobs": Arg(
'-j', '--job-workers', '-j', '--job-workers',
help='The number of concurrently running jobs for hyperoptimization ' help='The number of concurrently running jobs for hyperoptimization '

View File

@ -236,6 +236,12 @@ class Configuration(object):
self._args_to_config(config, argname='print_all', self._args_to_config(config, argname='print_all',
logstring='Parameter --print-all detected ...') logstring='Parameter --print-all detected ...')
if 'print_colorized' in self.args and not self.args.print_colorized:
logger.info('Parameter --no-color detected ...')
config.update({'print_colorized': False})
else:
config.update({'print_colorized': True})
self._args_to_config(config, argname='hyperopt_jobs', self._args_to_config(config, argname='hyperopt_jobs',
logstring='Parameter -j/--job-workers detected: {}') logstring='Parameter -j/--job-workers detected: {}')

View File

@ -13,6 +13,8 @@ from pathlib import Path
from pprint import pprint from pprint import pprint
from typing import Any, Dict, List, Optional from typing import Any, Dict, List, Optional
from colorama import init as colorama_init
from colorama import Fore, Style
from joblib import Parallel, delayed, dump, load, wrap_non_picklable_objects, cpu_count from joblib import Parallel, delayed, dump, load, wrap_non_picklable_objects, cpu_count
from pandas import DataFrame from pandas import DataFrame
from skopt import Optimizer from skopt import Optimizer
@ -153,8 +155,17 @@ class Hyperopt(Backtesting):
Log results if it is better than any previous evaluation Log results if it is better than any previous evaluation
""" """
print_all = self.config.get('print_all', False) print_all = self.config.get('print_all', False)
if print_all or results['loss'] < self.current_best_loss: is_best_loss = results['loss'] < self.current_best_loss
if print_all or is_best_loss:
if is_best_loss:
self.current_best_loss = results['loss']
log_str = self.format_results_logstring(results) log_str = self.format_results_logstring(results)
# Colorize output
if self.config.get('print_colorized', False):
if results['total_profit'] > 0:
log_str = Fore.GREEN + log_str
if print_all and is_best_loss:
log_str = Style.BRIGHT + log_str
if print_all: if print_all:
print(log_str) print(log_str)
else: else:
@ -169,7 +180,6 @@ class Hyperopt(Backtesting):
total = self.total_epochs total = self.total_epochs
res = results['results_explanation'] res = results['results_explanation']
loss = results['loss'] loss = results['loss']
self.current_best_loss = results['loss']
log_str = f'{current:5d}/{total}: {res} Objective: {loss:.5f}' log_str = f'{current:5d}/{total}: {res} Objective: {loss:.5f}'
log_str = f'*{log_str}' if results['is_initial_point'] else f' {log_str}' log_str = f'*{log_str}' if results['is_initial_point'] else f' {log_str}'
return log_str return log_str
@ -237,6 +247,7 @@ class Hyperopt(Backtesting):
results_explanation = self.format_results(results) results_explanation = self.format_results(results)
trade_count = len(results.index) trade_count = len(results.index)
total_profit = results.profit_abs.sum()
# If this evaluation contains too short amount of trades to be # If this evaluation contains too short amount of trades to be
# interesting -- consider it as 'bad' (assigned max. loss value) # interesting -- consider it as 'bad' (assigned max. loss value)
@ -247,6 +258,7 @@ class Hyperopt(Backtesting):
'loss': MAX_LOSS, 'loss': MAX_LOSS,
'params': params, 'params': params,
'results_explanation': results_explanation, 'results_explanation': results_explanation,
'total_profit': total_profit,
} }
loss = self.calculate_loss(results=results, trade_count=trade_count, loss = self.calculate_loss(results=results, trade_count=trade_count,
@ -256,6 +268,7 @@ class Hyperopt(Backtesting):
'loss': loss, 'loss': loss,
'params': params, 'params': params,
'results_explanation': results_explanation, 'results_explanation': results_explanation,
'total_profit': total_profit,
} }
def format_results(self, results: DataFrame) -> str: def format_results(self, results: DataFrame) -> str:
@ -339,6 +352,10 @@ class Hyperopt(Backtesting):
logger.info(f'Number of parallel jobs set as: {config_jobs}') logger.info(f'Number of parallel jobs set as: {config_jobs}')
opt = self.get_optimizer(config_jobs) opt = self.get_optimizer(config_jobs)
if self.config.get('print_colorized', False):
colorama_init(autoreset=True)
try: try:
with Parallel(n_jobs=config_jobs) as parallel: with Parallel(n_jobs=config_jobs) as parallel:
jobs = parallel._effective_n_jobs() jobs = parallel._effective_n_jobs()

View File

@ -578,7 +578,8 @@ def test_generate_optimizer(mocker, default_conf) -> None:
'loss': 1.9840569076926293, 'loss': 1.9840569076926293,
'results_explanation': ' 1 trades. Avg profit 2.31%. Total profit 0.00023300 BTC ' 'results_explanation': ' 1 trades. Avg profit 2.31%. Total profit 0.00023300 BTC '
'( 2.31Σ%). Avg duration 100.0 mins.', '( 2.31Σ%). Avg duration 100.0 mins.',
'params': optimizer_param 'params': optimizer_param,
'total_profit': 0.00023300
} }
hyperopt = Hyperopt(default_conf) hyperopt = Hyperopt(default_conf)

View File

@ -30,3 +30,6 @@ sdnotify==0.3.2
# Api server # Api server
flask==1.1.1 flask==1.1.1
# Support for colorized terminal output
colorama==0.4.1

View File

@ -64,6 +64,7 @@ setup(name='freqtrade',
'py_find_1st', 'py_find_1st',
'python-rapidjson', 'python-rapidjson',
'sdnotify', 'sdnotify',
'colorama',
# from requirements.txt # from requirements.txt
'numpy', 'numpy',
'pandas', 'pandas',