Merge pull request #2943 from Fredrik81/add-print-table
Added function to print hyperopt-list as table using tabulate
This commit is contained in:
		| @@ -46,18 +46,12 @@ 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) | ||||
|  | ||||
|     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) | ||||
|  | ||||
|         Hyperopt.print_result_table(config, trials, total_epochs, | ||||
|                                     not filteroptions['only_best'], print_colorized) | ||||
|     except KeyboardInterrupt: | ||||
|         print('User interrupted..') | ||||
|  | ||||
| @@ -75,6 +69,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 +87,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 +95,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 +106,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, | ||||
|   | ||||
| @@ -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.converter import trim_dataframe | ||||
| from freqtrade.data.history import get_timerange | ||||
| @@ -296,6 +297,56 @@ 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['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', '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.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)) | ||||
|         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) | ||||
|         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")) | ||||
|  | ||||
|     def has_space(self, space: str) -> bool: | ||||
|         """ | ||||
|         Tell if the space value is contained in the configuration | ||||
|   | ||||
| @@ -779,6 +779,20 @@ 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", | ||||
|   | ||||
		Reference in New Issue
	
	Block a user