From f200f52a163b67348a1e41c4cb5026e59c21d5d2 Mon Sep 17 00:00:00 2001 From: hroff-1902 Date: Sat, 3 Aug 2019 19:09:42 +0300 Subject: [PATCH 01/11] hyperopt print colorized results --- docs/hyperopt.md | 4 ++++ freqtrade/configuration/arguments.py | 3 ++- freqtrade/configuration/cli_options.py | 6 ++++++ freqtrade/configuration/configuration.py | 3 +++ freqtrade/misc.py | 12 ++++++++++++ freqtrade/optimize/hyperopt.py | 18 ++++++++++++++++-- 6 files changed, 43 insertions(+), 3 deletions(-) diff --git a/docs/hyperopt.md b/docs/hyperopt.md index 0b5d1a50e..2826dfc3b 100644 --- a/docs/hyperopt.md +++ b/docs/hyperopt.md @@ -343,6 +343,10 @@ def populate_buy_trend(self, dataframe: DataFrame) -> DataFrame: return dataframe ``` +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 the `--color/--print-colorized` command line option is used, the results are colorized -- bad results (with zero trades or limited by the `--min-trades` option) are red, currest bests -- in green, results with positive total profit are printed in bold. + ### Understand Hyperopt ROI results If you are optimizing ROI, you're result will look as follows and include a ROI table. diff --git a/freqtrade/configuration/arguments.py b/freqtrade/configuration/arguments.py index 4f0c3d31b..dd5a4290e 100644 --- a/freqtrade/configuration/arguments.py +++ b/freqtrade/configuration/arguments.py @@ -23,7 +23,8 @@ ARGS_BACKTEST = ARGS_COMMON_OPTIMIZE + ["position_stacking", "use_max_market_pos ARGS_HYPEROPT = ARGS_COMMON_OPTIMIZE + ["hyperopt", "hyperopt_path", "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_continue", "hyperopt_loss"] diff --git a/freqtrade/configuration/cli_options.py b/freqtrade/configuration/cli_options.py index 04fde2051..aab3c12b3 100644 --- a/freqtrade/configuration/cli_options.py +++ b/freqtrade/configuration/cli_options.py @@ -191,6 +191,12 @@ AVAILABLE_CLI_OPTIONS = { action='store_true', default=False, ), + "print_colorized": Arg( + '--color', '--print-colorized', + help='Print colorized hyperopt results.', + action='store_true', + default=False + ), "hyperopt_jobs": Arg( '-j', '--job-workers', help='The number of concurrently running jobs for hyperoptimization ' diff --git a/freqtrade/configuration/configuration.py b/freqtrade/configuration/configuration.py index 17ad37d6a..01732ca9e 100644 --- a/freqtrade/configuration/configuration.py +++ b/freqtrade/configuration/configuration.py @@ -254,6 +254,9 @@ class Configuration(object): self._args_to_config(config, argname='print_all', logstring='Parameter --print-all detected ...') + self._args_to_config(config, argname='print_colorized', + logstring='Parameter --color/--print-colorized detected ...') + self._args_to_config(config, argname='hyperopt_jobs', logstring='Parameter -j/--job-workers detected: {}') diff --git a/freqtrade/misc.py b/freqtrade/misc.py index 05946e008..eadfc7490 100644 --- a/freqtrade/misc.py +++ b/freqtrade/misc.py @@ -113,3 +113,15 @@ def deep_merge_dicts(source, destination): destination[key] = value return destination + + +def green(s): + return '\033[92m' + s + '\033[0m' + + +def red(s): + return '\033[91m' + s + '\033[0m' + + +def bold(s): + return '\033[1m' + s + '\033[0m' diff --git a/freqtrade/optimize/hyperopt.py b/freqtrade/optimize/hyperopt.py index 427b17cb8..e62cbe66b 100644 --- a/freqtrade/optimize/hyperopt.py +++ b/freqtrade/optimize/hyperopt.py @@ -20,6 +20,7 @@ from skopt.space import Dimension from freqtrade.configuration import Arguments from freqtrade.data.history import load_data, get_timeframe +from freqtrade.misc import green, red, bold from freqtrade.optimize.backtesting import Backtesting # Import IHyperOptLoss to allow users import from this file from freqtrade.optimize.hyperopt_loss_interface import IHyperOptLoss # noqa: F4 @@ -153,8 +154,19 @@ class Hyperopt(Backtesting): Log results if it is better than any previous evaluation """ 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) + # Colorize output + if self.config.get('print_colorized', False): + if results['total_profit'] > 0: + log_str = bold(log_str) + if results['loss'] >= MAX_LOSS: + log_str = red(log_str) + elif is_best_loss: + log_str = green(log_str) if print_all: print(log_str) else: @@ -169,7 +181,6 @@ class Hyperopt(Backtesting): total = self.total_epochs res = results['results_explanation'] loss = results['loss'] - self.current_best_loss = results['loss'] log_str = f'{current:5d}/{total}: {res} Objective: {loss:.5f}' log_str = f'*{log_str}' if results['is_initial_point'] else f' {log_str}' return log_str @@ -237,6 +248,7 @@ class Hyperopt(Backtesting): results_explanation = self.format_results(results) trade_count = len(results.index) + total_profit = results.profit_abs.sum() # If this evaluation contains too short amount of trades to be # interesting -- consider it as 'bad' (assigned max. loss value) @@ -247,6 +259,7 @@ class Hyperopt(Backtesting): 'loss': MAX_LOSS, 'params': params, 'results_explanation': results_explanation, + 'total_profit': total_profit, } loss = self.calculate_loss(results=results, trade_count=trade_count, @@ -256,6 +269,7 @@ class Hyperopt(Backtesting): 'loss': loss, 'params': params, 'results_explanation': results_explanation, + 'total_profit': total_profit, } def format_results(self, results: DataFrame) -> str: From fe796c46c329d51c36761ef74ec24a53fc4dbf3e Mon Sep 17 00:00:00 2001 From: hroff-1902 Date: Sat, 3 Aug 2019 19:13:18 +0300 Subject: [PATCH 02/11] test adjusted --- freqtrade/tests/optimize/test_hyperopt.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/freqtrade/tests/optimize/test_hyperopt.py b/freqtrade/tests/optimize/test_hyperopt.py index e3b049c06..4fb08181a 100644 --- a/freqtrade/tests/optimize/test_hyperopt.py +++ b/freqtrade/tests/optimize/test_hyperopt.py @@ -605,7 +605,8 @@ def test_generate_optimizer(mocker, default_conf) -> None: 'loss': 1.9840569076926293, 'results_explanation': ' 1 trades. Avg profit 2.31%. Total profit 0.00023300 BTC ' '( 2.31Σ%). Avg duration 100.0 mins.', - 'params': optimizer_param + 'params': optimizer_param, + 'total_profit': 0.00023300 } hyperopt = Hyperopt(default_conf) From 3dd6fe2703a4884eaa43443980e523465b381435 Mon Sep 17 00:00:00 2001 From: hroff-1902 Date: Sat, 3 Aug 2019 19:44:32 +0300 Subject: [PATCH 03/11] wording --- docs/hyperopt.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/hyperopt.md b/docs/hyperopt.md index 2826dfc3b..16e2212d5 100644 --- a/docs/hyperopt.md +++ b/docs/hyperopt.md @@ -345,7 +345,7 @@ def populate_buy_trend(self, dataframe: DataFrame) -> DataFrame: 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 the `--color/--print-colorized` command line option is used, the results are colorized -- bad results (with zero trades or limited by the `--min-trades` option) are red, currest bests -- in green, results with positive total profit are printed in bold. +When the `--color/--print-colorized` command line option is used, the results are colorized -- bad results (with zero trades or limited by the `--min-trades` option) are red, current bests -- in green, results with positive total profit are printed in bold. ### Understand Hyperopt ROI results From 9cbab35de01db7338563d4a029d4c62d7cbd9fe7 Mon Sep 17 00:00:00 2001 From: hroff-1902 Date: Sun, 4 Aug 2019 22:54:19 +0300 Subject: [PATCH 04/11] colorization by means of termcolor and colorama --- freqtrade/misc.py | 12 ------------ freqtrade/optimize/hyperopt.py | 12 ++++++++---- requirements-common.txt | 4 ++++ 3 files changed, 12 insertions(+), 16 deletions(-) diff --git a/freqtrade/misc.py b/freqtrade/misc.py index eadfc7490..05946e008 100644 --- a/freqtrade/misc.py +++ b/freqtrade/misc.py @@ -113,15 +113,3 @@ def deep_merge_dicts(source, destination): destination[key] = value return destination - - -def green(s): - return '\033[92m' + s + '\033[0m' - - -def red(s): - return '\033[91m' + s + '\033[0m' - - -def bold(s): - return '\033[1m' + s + '\033[0m' diff --git a/freqtrade/optimize/hyperopt.py b/freqtrade/optimize/hyperopt.py index e62cbe66b..fc0fb56b2 100644 --- a/freqtrade/optimize/hyperopt.py +++ b/freqtrade/optimize/hyperopt.py @@ -13,14 +13,15 @@ from pathlib import Path from pprint import pprint from typing import Any, Dict, List, Optional +from colorama import init as colorama_init from joblib import Parallel, delayed, dump, load, wrap_non_picklable_objects, cpu_count from pandas import DataFrame from skopt import Optimizer from skopt.space import Dimension +from termcolor import colored from freqtrade.configuration import Arguments from freqtrade.data.history import load_data, get_timeframe -from freqtrade.misc import green, red, bold from freqtrade.optimize.backtesting import Backtesting # Import IHyperOptLoss to allow users import from this file from freqtrade.optimize.hyperopt_loss_interface import IHyperOptLoss # noqa: F4 @@ -162,11 +163,11 @@ class Hyperopt(Backtesting): # Colorize output if self.config.get('print_colorized', False): if results['total_profit'] > 0: - log_str = bold(log_str) + log_str = colored(log_str, attrs=['bold']) if results['loss'] >= MAX_LOSS: - log_str = red(log_str) + log_str = colored(log_str, 'red') elif is_best_loss: - log_str = green(log_str) + log_str = colored(log_str, 'green') if print_all: print(log_str) else: @@ -353,6 +354,9 @@ class Hyperopt(Backtesting): logger.info(f'Number of parallel jobs set as: {config_jobs}') opt = self.get_optimizer(config_jobs) + + colorama_init() + try: with Parallel(n_jobs=config_jobs) as parallel: jobs = parallel._effective_n_jobs() diff --git a/requirements-common.txt b/requirements-common.txt index 2e52b84ad..b0c4c6729 100644 --- a/requirements-common.txt +++ b/requirements-common.txt @@ -30,3 +30,7 @@ sdnotify==0.3.2 # Api server flask==1.1.1 + +# Support for colorized terminal output +termcolor==1.1.0 +colorama==0.4.1 From ae39f6fba510bf1d285433e18a91b75ecd996dc2 Mon Sep 17 00:00:00 2001 From: hroff-1902 Date: Fri, 9 Aug 2019 14:48:57 +0300 Subject: [PATCH 05/11] use of termcolor eliminated --- freqtrade/optimize/hyperopt.py | 11 ++++++----- requirements-common.txt | 1 - 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/freqtrade/optimize/hyperopt.py b/freqtrade/optimize/hyperopt.py index fc0fb56b2..802c848f1 100644 --- a/freqtrade/optimize/hyperopt.py +++ b/freqtrade/optimize/hyperopt.py @@ -14,11 +14,11 @@ from pprint import pprint 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 pandas import DataFrame from skopt import Optimizer from skopt.space import Dimension -from termcolor import colored from freqtrade.configuration import Arguments from freqtrade.data.history import load_data, get_timeframe @@ -163,11 +163,11 @@ class Hyperopt(Backtesting): # Colorize output if self.config.get('print_colorized', False): if results['total_profit'] > 0: - log_str = colored(log_str, attrs=['bold']) + log_str = Style.BRIGHT + log_str if results['loss'] >= MAX_LOSS: - log_str = colored(log_str, 'red') + log_str = Fore.RED + log_str elif is_best_loss: - log_str = colored(log_str, 'green') + log_str = Fore.GREEN + log_str if print_all: print(log_str) else: @@ -355,7 +355,8 @@ class Hyperopt(Backtesting): opt = self.get_optimizer(config_jobs) - colorama_init() + if self.config.get('print_colorized', False): + colorama_init(autoreset=True) try: with Parallel(n_jobs=config_jobs) as parallel: diff --git a/requirements-common.txt b/requirements-common.txt index b0c4c6729..9b62cae5c 100644 --- a/requirements-common.txt +++ b/requirements-common.txt @@ -32,5 +32,4 @@ sdnotify==0.3.2 flask==1.1.1 # Support for colorized terminal output -termcolor==1.1.0 colorama==0.4.1 From 8f9291285238037d5483807e479741cde9f3de33 Mon Sep 17 00:00:00 2001 From: hroff-1902 Date: Sat, 10 Aug 2019 21:59:44 +0300 Subject: [PATCH 06/11] final colorization schema colorization schema-2: red, green, bright/dim colorization schema-3: red, green, bright only green bests colorization schema-4: no red, green for profit, bright for bests --- freqtrade/optimize/hyperopt.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/freqtrade/optimize/hyperopt.py b/freqtrade/optimize/hyperopt.py index 802c848f1..550f13e28 100644 --- a/freqtrade/optimize/hyperopt.py +++ b/freqtrade/optimize/hyperopt.py @@ -163,11 +163,9 @@ class Hyperopt(Backtesting): # Colorize output if self.config.get('print_colorized', False): if results['total_profit'] > 0: - log_str = Style.BRIGHT + log_str - if results['loss'] >= MAX_LOSS: - log_str = Fore.RED + log_str - elif is_best_loss: log_str = Fore.GREEN + log_str + if print_all and is_best_loss: + log_str = Style.BRIGHT + log_str if print_all: print(log_str) else: From 1a34b9b61ca481b5a7472723c8a780ce45c4a194 Mon Sep 17 00:00:00 2001 From: hroff-1902 Date: Mon, 12 Aug 2019 21:07:29 +0300 Subject: [PATCH 07/11] --no-color option introduced --- freqtrade/configuration/cli_options.py | 9 +++++---- freqtrade/configuration/configuration.py | 5 +++-- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/freqtrade/configuration/cli_options.py b/freqtrade/configuration/cli_options.py index aab3c12b3..a5784b0c1 100644 --- a/freqtrade/configuration/cli_options.py +++ b/freqtrade/configuration/cli_options.py @@ -192,10 +192,11 @@ AVAILABLE_CLI_OPTIONS = { default=False, ), "print_colorized": Arg( - '--color', '--print-colorized', - help='Print colorized hyperopt results.', - action='store_true', - default=False + '--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( '-j', '--job-workers', diff --git a/freqtrade/configuration/configuration.py b/freqtrade/configuration/configuration.py index 01732ca9e..4d85d5c28 100644 --- a/freqtrade/configuration/configuration.py +++ b/freqtrade/configuration/configuration.py @@ -254,8 +254,9 @@ class Configuration(object): self._args_to_config(config, argname='print_all', logstring='Parameter --print-all detected ...') - self._args_to_config(config, argname='print_colorized', - logstring='Parameter --color/--print-colorized detected ...') + if 'print_colorized' in self.args and not self.args.print_colorized: + logger.info('Parameter --no-color detected ...') + config.update({'print_colorized': getattr(self.args, 'print_colorized')}) self._args_to_config(config, argname='hyperopt_jobs', logstring='Parameter -j/--job-workers detected: {}') From 58d308fd05cef7339445fb91226ff6f052021ca0 Mon Sep 17 00:00:00 2001 From: hroff-1902 Date: Mon, 12 Aug 2019 23:13:04 +0300 Subject: [PATCH 08/11] fix handling --no-color for edge and backtesting --- freqtrade/configuration/configuration.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/freqtrade/configuration/configuration.py b/freqtrade/configuration/configuration.py index 4d85d5c28..a2e16d5d9 100644 --- a/freqtrade/configuration/configuration.py +++ b/freqtrade/configuration/configuration.py @@ -256,7 +256,9 @@ class Configuration(object): if 'print_colorized' in self.args and not self.args.print_colorized: logger.info('Parameter --no-color detected ...') - config.update({'print_colorized': getattr(self.args, 'print_colorized')}) + config.update({'print_colorized': False}) + else: + config.update({'print_colorized': True}) self._args_to_config(config, argname='hyperopt_jobs', logstring='Parameter -j/--job-workers detected: {}') From de802341651109b31884d3af3931123d16fe590b Mon Sep 17 00:00:00 2001 From: hroff-1902 Date: Tue, 13 Aug 2019 00:23:41 +0300 Subject: [PATCH 09/11] hyperopt options updated in bot-usage.md --- docs/bot-usage.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/docs/bot-usage.md b/docs/bot-usage.md index 8877ed010..e3db2ab33 100644 --- a/docs/bot-usage.md +++ b/docs/bot-usage.md @@ -207,7 +207,7 @@ usage: freqtrade hyperopt [-h] [-i TICKER_INTERVAL] [--timerange TIMERANGE] [--customhyperopt NAME] [--hyperopt-path PATH] [--eps] [-e INT] [-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] [--hyperopt-loss NAME] @@ -243,6 +243,8 @@ optional arguments: (same as setting `max_open_trades` to a very high number). --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 The number of concurrently running jobs for hyperoptimization (hyperopt worker processes). If -1 @@ -256,8 +258,7 @@ optional arguments: --continue Continue hyperopt from previous runs. By default, temporary files will be removed and hyperopt will start from scratch. - --hyperopt-loss NAME - Specify the class name of the hyperopt loss function + --hyperopt-loss NAME Specify the class name of the hyperopt loss function class (IHyperOptLoss). Different functions can generate completely different results, since the target for optimization is different. (default: From 94196c84e9f2354163d47b57009793c7ea39e730 Mon Sep 17 00:00:00 2001 From: hroff-1902 Date: Tue, 13 Aug 2019 14:25:56 +0300 Subject: [PATCH 10/11] docs: explanation for --no-color and colorization schema for results --- docs/hyperopt.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/hyperopt.md b/docs/hyperopt.md index 16e2212d5..db6dbb343 100644 --- a/docs/hyperopt.md +++ b/docs/hyperopt.md @@ -343,9 +343,9 @@ def populate_buy_trend(self, dataframe: DataFrame) -> DataFrame: return dataframe ``` -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. +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. -When the `--color/--print-colorized` command line option is used, the results are colorized -- bad results (with zero trades or limited by the `--min-trades` option) are red, current bests -- in green, results with positive total profit are printed in bold. +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 From 4c4ba08e854bd49b56fbc243f65534fa5ddc3dad Mon Sep 17 00:00:00 2001 From: hroff-1902 Date: Tue, 13 Aug 2019 19:47:38 +0300 Subject: [PATCH 11/11] colorama added to install_requires --- setup.py | 1 + 1 file changed, 1 insertion(+) diff --git a/setup.py b/setup.py index 202e3fd0d..572a32ccb 100644 --- a/setup.py +++ b/setup.py @@ -58,6 +58,7 @@ setup(name='freqtrade', 'py_find_1st', 'python-rapidjson', 'sdnotify', + 'colorama', # from requirements.txt 'numpy', 'pandas',