From 2058b492eb2b668616f06d0d001e01ffca17e38f Mon Sep 17 00:00:00 2001 From: Fredrik Rydin Date: Tue, 18 Feb 2020 22:46:53 +0100 Subject: [PATCH 1/7] Added function to print hyperopt-list as table using tabulate --- docs/utils.md | 1 + freqtrade/commands/arguments.py | 3 +- freqtrade/commands/cli_options.py | 6 +++ freqtrade/commands/hyperopt_commands.py | 36 ++++++++++-------- freqtrade/configuration/configuration.py | 3 ++ freqtrade/optimize/hyperopt.py | 47 +++++++++++++++++++++++- tests/commands/test_commands.py | 16 ++++++++ 7 files changed, 95 insertions(+), 17 deletions(-) diff --git a/docs/utils.md b/docs/utils.md index abb7fd0db..6ca0b7920 100644 --- a/docs/utils.md +++ b/docs/utils.md @@ -440,6 +440,7 @@ optional arguments: --no-color Disable colorization of hyperopt results. May be useful if you are redirecting output to a file. --print-json Print best result detailization in JSON format. + --print-table Print results in table format. --no-details Do not print best epoch details. Common arguments: diff --git a/freqtrade/commands/arguments.py b/freqtrade/commands/arguments.py index fe6f49039..0f6478a60 100644 --- a/freqtrade/commands/arguments.py +++ b/freqtrade/commands/arguments.py @@ -66,7 +66,8 @@ ARGS_HYPEROPT_LIST = ["hyperopt_list_best", "hyperopt_list_profitable", "hyperopt_list_min_avg_time", "hyperopt_list_max_avg_time", "hyperopt_list_min_avg_profit", "hyperopt_list_max_avg_profit", "hyperopt_list_min_total_profit", "hyperopt_list_max_total_profit", - "print_colorized", "print_json", "hyperopt_list_no_details"] + "print_colorized", "print_json", "print_table", + "hyperopt_list_no_details"] ARGS_HYPEROPT_SHOW = ["hyperopt_list_best", "hyperopt_list_profitable", "hyperopt_show_index", "print_json", "hyperopt_show_no_header"] diff --git a/freqtrade/commands/cli_options.py b/freqtrade/commands/cli_options.py index 1776955b1..9efc1151a 100644 --- a/freqtrade/commands/cli_options.py +++ b/freqtrade/commands/cli_options.py @@ -220,6 +220,12 @@ AVAILABLE_CLI_OPTIONS = { action='store_true', default=False, ), + "print_table": Arg( + '--print-table', + help='Print results in table format.', + action='store_true', + default=False, + ), "hyperopt_jobs": Arg( '-j', '--job-workers', help='The number of concurrently running jobs for hyperoptimization ' diff --git a/freqtrade/commands/hyperopt_commands.py b/freqtrade/commands/hyperopt_commands.py index 8c1c80d98..88cd79468 100755 --- a/freqtrade/commands/hyperopt_commands.py +++ b/freqtrade/commands/hyperopt_commands.py @@ -21,6 +21,7 @@ def start_hyperopt_list(args: Dict[str, Any]) -> None: print_colorized = config.get('print_colorized', False) print_json = config.get('print_json', False) + print_table = config.get('print_table', False) no_details = config.get('hyperopt_list_no_details', False) no_header = False @@ -52,14 +53,20 @@ def start_hyperopt_list(args: Dict[str, Any]) -> None: if print_colorized: colorama_init(autoreset=True) - try: - # Human-friendly indexes used here (starting from 1) - for val in trials[epoch_start:epoch_stop]: - Hyperopt.print_results_explanation(val, total_epochs, - not filteroptions['only_best'], print_colorized) - - except KeyboardInterrupt: - print('User interrupted..') + if print_table: + try: + Hyperopt.print_result_table(config, trials, total_epochs, + not filteroptions['only_best'], print_colorized) + except KeyboardInterrupt: + print('User interrupted..') + else: + try: + # Human-friendly indexes used here (starting from 1) + for val in trials[epoch_start:epoch_stop]: + Hyperopt.print_results_explanation(val, total_epochs, + not filteroptions['only_best'], print_colorized) + except KeyboardInterrupt: + print('User interrupted..') if trials and not no_details: sorted_trials = sorted(trials, key=itemgetter('loss')) @@ -75,6 +82,12 @@ def start_hyperopt_show(args: Dict[str, Any]) -> None: config = setup_utils_configuration(args, RunMode.UTIL_NO_EXCHANGE) + print_json = config.get('print_json', False) + no_header = config.get('hyperopt_show_no_header', False) + trials_file = (config['user_data_dir'] / + 'hyperopt_results' / 'hyperopt_results.pickle') + n = config.get('hyperopt_show_index', -1) + filteroptions = { 'only_best': config.get('hyperopt_list_best', False), 'only_profitable': config.get('hyperopt_list_profitable', False), @@ -87,10 +100,6 @@ def start_hyperopt_show(args: Dict[str, Any]) -> None: 'filter_min_total_profit': config.get('hyperopt_list_min_total_profit', None), 'filter_max_total_profit': config.get('hyperopt_list_max_total_profit', None) } - no_header = config.get('hyperopt_show_no_header', False) - - trials_file = (config['user_data_dir'] / - 'hyperopt_results' / 'hyperopt_results.pickle') # Previous evaluations trials = Hyperopt.load_previous_results(trials_file) @@ -99,7 +108,6 @@ def start_hyperopt_show(args: Dict[str, Any]) -> None: trials = _hyperopt_filter_trials(trials, filteroptions) trials_epochs = len(trials) - n = config.get('hyperopt_show_index', -1) if n > trials_epochs: raise OperationalException( f"The index of the epoch to show should be less than {trials_epochs + 1}.") @@ -111,8 +119,6 @@ def start_hyperopt_show(args: Dict[str, Any]) -> None: if n > 0: n -= 1 - print_json = config.get('print_json', False) - if trials: val = trials[n] Hyperopt.print_epoch_details(val, total_epochs, print_json, no_header, diff --git a/freqtrade/configuration/configuration.py b/freqtrade/configuration/configuration.py index c2613ba99..0adfe03e7 100644 --- a/freqtrade/configuration/configuration.py +++ b/freqtrade/configuration/configuration.py @@ -286,6 +286,9 @@ class Configuration: self._args_to_config(config, argname='print_json', logstring='Parameter --print-json detected ...') + self._args_to_config(config, argname='print_table', + logstring='Parameter --print-table detected: {}') + self._args_to_config(config, argname='hyperopt_jobs', logstring='Parameter -j/--job-workers detected: {}') diff --git a/freqtrade/optimize/hyperopt.py b/freqtrade/optimize/hyperopt.py index ff6e7f3bc..72b3516c7 100644 --- a/freqtrade/optimize/hyperopt.py +++ b/freqtrade/optimize/hyperopt.py @@ -20,7 +20,8 @@ from colorama import Fore, Style from colorama import init as colorama_init from joblib import (Parallel, cpu_count, delayed, dump, load, wrap_non_picklable_objects) -from pandas import DataFrame +from pandas import DataFrame, json_normalize, isna +from tabulate import tabulate from freqtrade.data.history import get_timerange, trim_dataframe from freqtrade.exceptions import OperationalException @@ -295,6 +296,50 @@ class Hyperopt: f"{results['results_explanation']} " + f"Objective: {results['loss']:.5f}") + @staticmethod + def print_result_table(config: dict, results: list, total_epochs: int, highlight_best: bool, + print_colorized: bool) -> None: + """ + Log result table + """ + if not results: + return + + trials = json_normalize(results, max_level=1) + trials = trials[['is_best', 'current_epoch', + 'results_metrics.trade_count', 'results_metrics.avg_profit', + 'results_metrics.total_profit', 'results_metrics.profit', + 'results_metrics.duration', 'loss']] + trials.columns = ['Best', 'Epoch', 'Trades', 'Avg profit', 'Total profit', + 'Profit', 'Avg duration', 'Objective'] + + trials['Best'] = trials['Best'].apply(lambda x: '*' if x else '') + trials['Objective'] = trials['Objective'].astype(str) + + if print_colorized: + for i in range(len(trials)): + if trials.loc[i]['Total profit'] > 0: + trials.at[i, 'Best'] = Fore.GREEN + trials.loc[i]['Best'] + trials.at[i, 'Objective'] = "{}{}".format(trials.loc[i]['Objective'], + Fore.RESET) + if '*' in trials.loc[i]['Best'] and highlight_best: + trials.at[i, 'Best'] = Style.BRIGHT + trials.loc[i]['Best'] + trials.at[i, 'Objective'] = "{}{}".format(trials.loc[i]['Objective'], + Style.RESET_ALL) + + trials['Epoch'] = trials['Epoch'].apply( + lambda x: "{}/{}".format(x, total_epochs)) + trials['Avg profit'] = trials['Avg profit'].apply( + lambda x: '{:,.2f}%'.format(x) if not isna(x) else x) + trials['Profit'] = trials['Profit'].apply( + lambda x: '{:,.2f}%'.format(x) if not isna(x) else x) + trials['Total profit'] = trials['Total profit'].apply( + lambda x: '{: 11.8f} '.format(x) + config['stake_currency'] if not isna(x) else x) + trials['Avg duration'] = trials['Avg duration'].apply( + lambda x: '{:,.1f}m'.format(x) if not isna(x) else x) + + print(tabulate(trials.to_dict(orient='list'), headers='keys', tablefmt='psql')) + def has_space(self, space: str) -> bool: """ Tell if the space value is contained in the configuration diff --git a/tests/commands/test_commands.py b/tests/commands/test_commands.py index ee1db5db5..9ecd990ec 100644 --- a/tests/commands/test_commands.py +++ b/tests/commands/test_commands.py @@ -893,6 +893,22 @@ def test_hyperopt_list(mocker, capsys, hyperopt_results): assert all(x not in captured.out for x in [" 1/12", " 3/12", " 4/12", " 5/12", " 7/12", " 8/12" " 9/12", " 10/12", " 11/12", " 12/12"]) + args = [ + "hyperopt-list", + "--profitable", + "--no-details", + "--print-table", + "--max-trades", "20" + ] + pargs = get_args(args) + pargs['config'] = None + start_hyperopt_list(pargs) + captured = capsys.readouterr() + assert all(x in captured.out + for x in [" 2/12", " 10/12"]) + assert all(x not in captured.out + for x in [" 1/12", " 3/12", " 4/12", " 5/12", " 6/12", " 7/12", " 8/12", " 9/12", + " 11/12", " 12/12"]) def test_hyperopt_show(mocker, capsys, hyperopt_results): From 585545405dea4d34bc1ce6d8296ceb38861a7b85 Mon Sep 17 00:00:00 2001 From: Fredrik Rydin Date: Wed, 19 Feb 2020 00:51:44 +0100 Subject: [PATCH 2/7] Changed tests --- tests/commands/test_commands.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/commands/test_commands.py b/tests/commands/test_commands.py index 9ecd990ec..9c233019c 100644 --- a/tests/commands/test_commands.py +++ b/tests/commands/test_commands.py @@ -895,20 +895,20 @@ def test_hyperopt_list(mocker, capsys, hyperopt_results): " 9/12", " 10/12", " 11/12", " 12/12"]) args = [ "hyperopt-list", - "--profitable", "--no-details", "--print-table", - "--max-trades", "20" + "--min-trades", "100", + "--print-json" ] pargs = get_args(args) pargs['config'] = None start_hyperopt_list(pargs) captured = capsys.readouterr() assert all(x in captured.out - for x in [" 2/12", " 10/12"]) + for x in [" 3/12", " 7/12", " 9/12", " 11/12"]) assert all(x not in captured.out - for x in [" 1/12", " 3/12", " 4/12", " 5/12", " 6/12", " 7/12", " 8/12", " 9/12", - " 11/12", " 12/12"]) + for x in [" 1/12", " 2/12", " 4/12", " 5/12", " 6/12", " 8/12", " 10/12" + " 12/12"]) def test_hyperopt_show(mocker, capsys, hyperopt_results): From e7b12704dec4c8265e5adf51dfb3d7f36367adae Mon Sep 17 00:00:00 2001 From: Fredrik81 Date: Thu, 20 Feb 2020 19:12:55 +0100 Subject: [PATCH 3/7] Added test for details --- tests/commands/test_commands.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/tests/commands/test_commands.py b/tests/commands/test_commands.py index 9c233019c..dfaa936ed 100644 --- a/tests/commands/test_commands.py +++ b/tests/commands/test_commands.py @@ -778,6 +778,19 @@ def test_hyperopt_list(mocker, capsys, hyperopt_results): assert all(x not in captured.out for x in [" 1/12", " 3/12", " 4/12", " 5/12", " 6/12", " 7/12", " 8/12", " 9/12", " 11/12", " 12/12"]) + args = [ + "hyperopt-list", + "--profitable" + ] + pargs = get_args(args) + pargs['config'] = None + start_hyperopt_list(pargs) + captured = capsys.readouterr() + assert all(x in captured.out + for x in [" 2/12", " 10/12", "Best result:", "Buy hyperspace params", "Sell hyperspace params", "ROI table", "Stoploss"]) + assert all(x not in captured.out + for x in [" 1/12", " 3/12", " 4/12", " 5/12", " 6/12", " 7/12", " 8/12", " 9/12", + " 11/12", " 12/12"]) args = [ "hyperopt-list", "--no-details", From 09226fd5d5e378e9f7ee11382528ec6c06ac7571 Mon Sep 17 00:00:00 2001 From: Fredrik81 Date: Thu, 20 Feb 2020 19:18:42 +0100 Subject: [PATCH 4/7] PEP8 correction --- tests/commands/test_commands.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/commands/test_commands.py b/tests/commands/test_commands.py index dfaa936ed..ceae6f372 100644 --- a/tests/commands/test_commands.py +++ b/tests/commands/test_commands.py @@ -787,7 +787,8 @@ def test_hyperopt_list(mocker, capsys, hyperopt_results): start_hyperopt_list(pargs) captured = capsys.readouterr() assert all(x in captured.out - for x in [" 2/12", " 10/12", "Best result:", "Buy hyperspace params", "Sell hyperspace params", "ROI table", "Stoploss"]) + for x in [" 2/12", " 10/12", "Best result:", "Buy hyperspace params", + "Sell hyperspace params", "ROI table", "Stoploss"]) assert all(x not in captured.out for x in [" 1/12", " 3/12", " 4/12", " 5/12", " 6/12", " 7/12", " 8/12", " 9/12", " 11/12", " 12/12"]) From 7eb62ed32e7acc7004821a9213c7752fe31f1f9c Mon Sep 17 00:00:00 2001 From: Fredrik81 Date: Mon, 24 Feb 2020 00:33:01 +0100 Subject: [PATCH 5/7] Remove old print option for hyperopt-list and made table as default --- docs/utils.md | 1 - freqtrade/commands/arguments.py | 3 +-- freqtrade/commands/cli_options.py | 6 ------ freqtrade/commands/hyperopt_commands.py | 23 +++++------------------ freqtrade/configuration/configuration.py | 3 --- tests/commands/test_commands.py | 16 ---------------- 6 files changed, 6 insertions(+), 46 deletions(-) diff --git a/docs/utils.md b/docs/utils.md index 6ca0b7920..abb7fd0db 100644 --- a/docs/utils.md +++ b/docs/utils.md @@ -440,7 +440,6 @@ optional arguments: --no-color Disable colorization of hyperopt results. May be useful if you are redirecting output to a file. --print-json Print best result detailization in JSON format. - --print-table Print results in table format. --no-details Do not print best epoch details. Common arguments: diff --git a/freqtrade/commands/arguments.py b/freqtrade/commands/arguments.py index 0f6478a60..fe6f49039 100644 --- a/freqtrade/commands/arguments.py +++ b/freqtrade/commands/arguments.py @@ -66,8 +66,7 @@ ARGS_HYPEROPT_LIST = ["hyperopt_list_best", "hyperopt_list_profitable", "hyperopt_list_min_avg_time", "hyperopt_list_max_avg_time", "hyperopt_list_min_avg_profit", "hyperopt_list_max_avg_profit", "hyperopt_list_min_total_profit", "hyperopt_list_max_total_profit", - "print_colorized", "print_json", "print_table", - "hyperopt_list_no_details"] + "print_colorized", "print_json", "hyperopt_list_no_details"] ARGS_HYPEROPT_SHOW = ["hyperopt_list_best", "hyperopt_list_profitable", "hyperopt_show_index", "print_json", "hyperopt_show_no_header"] diff --git a/freqtrade/commands/cli_options.py b/freqtrade/commands/cli_options.py index 9efc1151a..1776955b1 100644 --- a/freqtrade/commands/cli_options.py +++ b/freqtrade/commands/cli_options.py @@ -220,12 +220,6 @@ AVAILABLE_CLI_OPTIONS = { action='store_true', default=False, ), - "print_table": Arg( - '--print-table', - help='Print results in table format.', - action='store_true', - default=False, - ), "hyperopt_jobs": Arg( '-j', '--job-workers', help='The number of concurrently running jobs for hyperoptimization ' diff --git a/freqtrade/commands/hyperopt_commands.py b/freqtrade/commands/hyperopt_commands.py index 88cd79468..ccaa59e54 100755 --- a/freqtrade/commands/hyperopt_commands.py +++ b/freqtrade/commands/hyperopt_commands.py @@ -21,7 +21,6 @@ def start_hyperopt_list(args: Dict[str, Any]) -> None: print_colorized = config.get('print_colorized', False) print_json = config.get('print_json', False) - print_table = config.get('print_table', False) no_details = config.get('hyperopt_list_no_details', False) no_header = False @@ -47,26 +46,14 @@ def start_hyperopt_list(args: Dict[str, Any]) -> None: trials = _hyperopt_filter_trials(trials, filteroptions) - # TODO: fetch the interval for epochs to print from the cli option - epoch_start, epoch_stop = 0, None - if print_colorized: colorama_init(autoreset=True) - if print_table: - try: - Hyperopt.print_result_table(config, trials, total_epochs, - not filteroptions['only_best'], print_colorized) - except KeyboardInterrupt: - print('User interrupted..') - else: - try: - # Human-friendly indexes used here (starting from 1) - for val in trials[epoch_start:epoch_stop]: - Hyperopt.print_results_explanation(val, total_epochs, - not filteroptions['only_best'], print_colorized) - except KeyboardInterrupt: - print('User interrupted..') + try: + Hyperopt.print_result_table(config, trials, total_epochs, + not filteroptions['only_best'], print_colorized) + except KeyboardInterrupt: + print('User interrupted..') if trials and not no_details: sorted_trials = sorted(trials, key=itemgetter('loss')) diff --git a/freqtrade/configuration/configuration.py b/freqtrade/configuration/configuration.py index 0adfe03e7..c2613ba99 100644 --- a/freqtrade/configuration/configuration.py +++ b/freqtrade/configuration/configuration.py @@ -286,9 +286,6 @@ class Configuration: self._args_to_config(config, argname='print_json', logstring='Parameter --print-json detected ...') - self._args_to_config(config, argname='print_table', - logstring='Parameter --print-table detected: {}') - self._args_to_config(config, argname='hyperopt_jobs', logstring='Parameter -j/--job-workers detected: {}') diff --git a/tests/commands/test_commands.py b/tests/commands/test_commands.py index ceae6f372..995b504c5 100644 --- a/tests/commands/test_commands.py +++ b/tests/commands/test_commands.py @@ -907,22 +907,6 @@ def test_hyperopt_list(mocker, capsys, hyperopt_results): assert all(x not in captured.out for x in [" 1/12", " 3/12", " 4/12", " 5/12", " 7/12", " 8/12" " 9/12", " 10/12", " 11/12", " 12/12"]) - args = [ - "hyperopt-list", - "--no-details", - "--print-table", - "--min-trades", "100", - "--print-json" - ] - pargs = get_args(args) - pargs['config'] = None - start_hyperopt_list(pargs) - captured = capsys.readouterr() - assert all(x in captured.out - for x in [" 3/12", " 7/12", " 9/12", " 11/12"]) - assert all(x not in captured.out - for x in [" 1/12", " 2/12", " 4/12", " 5/12", " 6/12", " 8/12", " 10/12" - " 12/12"]) def test_hyperopt_show(mocker, capsys, hyperopt_results): From 23bf135b8aeb704c64e775dba8a12b166a692a41 Mon Sep 17 00:00:00 2001 From: Fredrik81 Date: Mon, 24 Feb 2020 11:01:14 +0100 Subject: [PATCH 6/7] Alignment of table content, changed coloring, changed 'Best' column to show if it's initial_point or best --- freqtrade/optimize/hyperopt.py | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/freqtrade/optimize/hyperopt.py b/freqtrade/optimize/hyperopt.py index 72b3516c7..7ff5c3500 100644 --- a/freqtrade/optimize/hyperopt.py +++ b/freqtrade/optimize/hyperopt.py @@ -306,15 +306,18 @@ class Hyperopt: return trials = json_normalize(results, max_level=1) - trials = trials[['is_best', 'current_epoch', - 'results_metrics.trade_count', 'results_metrics.avg_profit', - 'results_metrics.total_profit', 'results_metrics.profit', - 'results_metrics.duration', 'loss']] + trials['Best'] = '' + trials = trials[['Best', 'current_epoch', 'results_metrics.trade_count', + 'results_metrics.avg_profit', 'results_metrics.total_profit', + 'results_metrics.profit', 'results_metrics.duration', + 'loss', 'is_initial_point', 'is_best']] trials.columns = ['Best', 'Epoch', 'Trades', 'Avg profit', 'Total profit', - 'Profit', 'Avg duration', 'Objective'] + 'Profit', 'Avg duration', 'Objective', 'is_initial_point', 'is_best'] - trials['Best'] = trials['Best'].apply(lambda x: '*' if x else '') + trials.loc[trials['is_initial_point'], 'Best'] = '*' + trials.loc[trials['is_best'], 'Best'] = 'Best' trials['Objective'] = trials['Objective'].astype(str) + trials = trials.drop(columns=['is_initial_point', 'is_best']) if print_colorized: for i in range(len(trials)): @@ -322,10 +325,10 @@ class Hyperopt: trials.at[i, 'Best'] = Fore.GREEN + trials.loc[i]['Best'] trials.at[i, 'Objective'] = "{}{}".format(trials.loc[i]['Objective'], Fore.RESET) - if '*' in trials.loc[i]['Best'] and highlight_best: - trials.at[i, 'Best'] = Style.BRIGHT + trials.loc[i]['Best'] - trials.at[i, 'Objective'] = "{}{}".format(trials.loc[i]['Objective'], - Style.RESET_ALL) + if 'Best' in trials.loc[i]['Best'] and highlight_best: + trials.at[i, 'Best'] = Style.BRIGHT + trials.loc[i]['Best'] + trials.at[i, 'Objective'] = "{}{}".format(trials.loc[i]['Objective'], + Style.RESET_ALL) trials['Epoch'] = trials['Epoch'].apply( lambda x: "{}/{}".format(x, total_epochs)) @@ -338,7 +341,8 @@ class Hyperopt: trials['Avg duration'] = trials['Avg duration'].apply( lambda x: '{:,.1f}m'.format(x) if not isna(x) else x) - print(tabulate(trials.to_dict(orient='list'), headers='keys', tablefmt='psql')) + print(tabulate(trials.to_dict(orient='list'), headers='keys', tablefmt='psql', + stralign="right")) def has_space(self, space: str) -> bool: """ From cd7efde6c0618c3a40d44432dece4592510e5c87 Mon Sep 17 00:00:00 2001 From: Fredrik81 Date: Mon, 24 Feb 2020 22:06:21 +0100 Subject: [PATCH 7/7] Fixed coloring so it's only targeting the values not the table borders --- freqtrade/optimize/hyperopt.py | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/freqtrade/optimize/hyperopt.py b/freqtrade/optimize/hyperopt.py index 7ff5c3500..9c18d6803 100644 --- a/freqtrade/optimize/hyperopt.py +++ b/freqtrade/optimize/hyperopt.py @@ -313,22 +313,12 @@ class Hyperopt: 'loss', 'is_initial_point', 'is_best']] trials.columns = ['Best', 'Epoch', 'Trades', 'Avg profit', 'Total profit', 'Profit', 'Avg duration', 'Objective', 'is_initial_point', 'is_best'] - + trials['is_profit'] = False trials.loc[trials['is_initial_point'], 'Best'] = '*' trials.loc[trials['is_best'], 'Best'] = 'Best' trials['Objective'] = trials['Objective'].astype(str) - trials = trials.drop(columns=['is_initial_point', 'is_best']) - - if print_colorized: - for i in range(len(trials)): - if trials.loc[i]['Total profit'] > 0: - trials.at[i, 'Best'] = Fore.GREEN + trials.loc[i]['Best'] - trials.at[i, 'Objective'] = "{}{}".format(trials.loc[i]['Objective'], - Fore.RESET) - if 'Best' in trials.loc[i]['Best'] and highlight_best: - trials.at[i, 'Best'] = Style.BRIGHT + trials.loc[i]['Best'] - trials.at[i, 'Objective'] = "{}{}".format(trials.loc[i]['Objective'], - Style.RESET_ALL) + trials.loc[trials['Total profit'] > 0, 'is_profit'] = True + trials['Trades'] = trials['Trades'].astype(str) trials['Epoch'] = trials['Epoch'].apply( lambda x: "{}/{}".format(x, total_epochs)) @@ -340,9 +330,21 @@ class Hyperopt: lambda x: '{: 11.8f} '.format(x) + config['stake_currency'] if not isna(x) else x) trials['Avg duration'] = trials['Avg duration'].apply( lambda x: '{:,.1f}m'.format(x) if not isna(x) else x) + if print_colorized: + for i in range(len(trials)): + if trials.loc[i]['is_profit']: + for z in range(len(trials.loc[i])-3): + trials.iat[i, z] = "{}{}{}".format(Fore.GREEN, + str(trials.loc[i][z]), Fore.RESET) + if trials.loc[i]['is_best'] and highlight_best: + for z in range(len(trials.loc[i])-3): + trials.iat[i, z] = "{}{}{}".format(Style.BRIGHT, + str(trials.loc[i][z]), Style.RESET_ALL) + + trials = trials.drop(columns=['is_initial_point', 'is_best', 'is_profit']) print(tabulate(trials.to_dict(orient='list'), headers='keys', tablefmt='psql', - stralign="right")) + stralign="right")) def has_space(self, space: str) -> bool: """