diff --git a/docs/utils.md b/docs/utils.md index b0559f9cc..71039f174 100644 --- a/docs/utils.md +++ b/docs/utils.md @@ -135,15 +135,27 @@ Common arguments: ``` ``` freqtrade list-hyperopts --help -usage: freqtrade list-hyperopts [-h] [-v] [--logfile FILE] [-V] [-c PATH] - [-d PATH] [--userdir PATH] - [--hyperopt-path PATH] [-1] +usage: freqtrade hyperopt-list [-h] [-v] [--logfile FILE] [-V] [-c PATH] + [-d PATH] [--userdir PATH] [--best] + [--profitable] [--min-avg-time INT] + [--max-avg-time INT] [--min-avg-profit FLOAT] + [--min-total-profit FLOAT] [--no-color] + [--print-json] [--no-details] optional arguments: -h, --help show this help message and exit - --hyperopt-path PATH Specify additional lookup path for Hyperopt and - Hyperopt Loss functions. - -1, --one-column Print output in one column. + --best Select only best epochs. + --profitable Select only profitable epochs. + --min-avg-time INT Select epochs on above average time. + --max-avg-time INT Select epochs on under average time. + --min-avg-profit FLOAT + Select epochs on above average profit. + --min-total-profit FLOAT + Select epochs on above total profit. + --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. + --no-details Do not print best epoch details. Common arguments: -v, --verbose Verbose mode (-vv for more, -vvv to get all messages). diff --git a/freqtrade/commands/arguments.py b/freqtrade/commands/arguments.py index 1931a51be..2d02058f1 100644 --- a/freqtrade/commands/arguments.py +++ b/freqtrade/commands/arguments.py @@ -59,7 +59,8 @@ ARGS_PLOT_DATAFRAME = ["pairs", "indicators1", "indicators2", "plot_limit", ARGS_PLOT_PROFIT = ["pairs", "timerange", "export", "exportfilename", "db_url", "trade_source", "ticker_interval"] -ARGS_HYPEROPT_LIST = ["hyperopt_list_best", "hyperopt_list_profitable", "print_colorized", +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_min_total_profit", "print_colorized", "print_json", "hyperopt_list_no_details"] ARGS_HYPEROPT_SHOW = ["hyperopt_list_best", "hyperopt_list_profitable", "hyperopt_show_index", diff --git a/freqtrade/commands/cli_options.py b/freqtrade/commands/cli_options.py index 6d8d13129..0c6d64691 100644 --- a/freqtrade/commands/cli_options.py +++ b/freqtrade/commands/cli_options.py @@ -398,6 +398,30 @@ AVAILABLE_CLI_OPTIONS = { help='Select only best epochs.', action='store_true', ), + "hyperopt_list_min_avg_time": Arg( + '--min-avg-time', + help='Select epochs on above average time.', + type=check_int_nonzero, + metavar='INT', + ), + "hyperopt_list_max_avg_time": Arg( + '--max-avg-time', + help='Select epochs on under average time.', + type=check_int_nonzero, + metavar='INT', + ), + "hyperopt_list_min_avg_profit": Arg( + '--min-avg-profit', + help='Select epochs on above average profit.', + type=float, + metavar='FLOAT', + ), + "hyperopt_list_min_total_profit": Arg( + '--min-total-profit', + help='Select epochs on above total profit.', + type=float, + metavar='FLOAT', + ), "hyperopt_list_no_details": Arg( '--no-details', help='Do not print best epoch details.', diff --git a/freqtrade/commands/hyperopt_commands.py b/freqtrade/commands/hyperopt_commands.py index 5c6f25848..8472fcfe1 100644 --- a/freqtrade/commands/hyperopt_commands.py +++ b/freqtrade/commands/hyperopt_commands.py @@ -19,13 +19,20 @@ def start_hyperopt_list(args: Dict[str, Any]) -> None: config = setup_utils_configuration(args, RunMode.UTIL_NO_EXCHANGE) - only_best = config.get('hyperopt_list_best', False) - only_profitable = config.get('hyperopt_list_profitable', False) print_colorized = config.get('print_colorized', False) print_json = config.get('print_json', False) no_details = config.get('hyperopt_list_no_details', False) no_header = False + filteroptions = { + 'only_best': config.get('hyperopt_list_best', False), + 'only_profitable': config.get('hyperopt_list_profitable', False), + 'filter_min_avg_time': config.get('hyperopt_list_min_avg_time', 0), + 'filter_max_avg_time': config.get('hyperopt_list_max_avg_time', 0), + 'filter_min_avg_profit': config.get('hyperopt_list_min_avg_profit', 0.0), + 'filter_min_total_profit': config.get('hyperopt_list_min_total_profit', 0.0) + } + trials_file = (config['user_data_dir'] / 'hyperopt_results' / 'hyperopt_results.pickle') @@ -33,7 +40,7 @@ def start_hyperopt_list(args: Dict[str, Any]) -> None: trials = Hyperopt.load_previous_results(trials_file) total_epochs = len(trials) - trials = _hyperopt_filter_trials(trials, only_best, only_profitable) + trials = _hyperopt_filter_trials(trials, filteroptions) # TODO: fetch the interval for epochs to print from the cli option epoch_start, epoch_stop = 0, None @@ -44,7 +51,7 @@ def start_hyperopt_list(args: Dict[str, Any]) -> None: 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 only_best, print_colorized) + Hyperopt.print_results_explanation(val, total_epochs, not filteroptions['only_best'], print_colorized) except KeyboardInterrupt: print('User interrupted..') @@ -63,8 +70,14 @@ def start_hyperopt_show(args: Dict[str, Any]) -> None: config = setup_utils_configuration(args, RunMode.UTIL_NO_EXCHANGE) - only_best = config.get('hyperopt_list_best', False) - only_profitable = config.get('hyperopt_list_profitable', False) + filteroptions = { + 'only_best': config.get('hyperopt_list_best', False), + 'only_profitable': config.get('hyperopt_list_profitable', False), + 'filter_min_avg_time': config.get('hyperopt_list_min_avg_time', 0), + 'filter_max_avg_time': config.get('hyperopt_list_max_avg_time', 0), + 'filter_min_avg_profit': config.get('hyperopt_list_min_avg_profit', 0), + 'filter_min_total_profit': config.get('hyperopt_list_min_total_profit', 0) + } no_header = config.get('hyperopt_show_no_header', False) trials_file = (config['user_data_dir'] / @@ -74,7 +87,7 @@ def start_hyperopt_show(args: Dict[str, Any]) -> None: trials = Hyperopt.load_previous_results(trials_file) total_epochs = len(trials) - trials = _hyperopt_filter_trials(trials, only_best, only_profitable) + trials = _hyperopt_filter_trials(trials, filteroptions) trials_epochs = len(trials) n = config.get('hyperopt_show_index', -1) @@ -97,18 +110,28 @@ def start_hyperopt_show(args: Dict[str, Any]) -> None: header_str="Epoch details") -def _hyperopt_filter_trials(trials: List, only_best: bool, only_profitable: bool) -> List: +def _hyperopt_filter_trials(trials: List, filteroptions: dict) -> List: """ Filter our items from the list of hyperopt results """ - if only_best: + if filteroptions['only_best']: trials = [x for x in trials if x['is_best']] - if only_profitable: + if filteroptions['only_profitable']: trials = [x for x in trials if x['results_metrics']['profit'] > 0] + if not filteroptions['only_best']: + if filteroptions['filter_min_avg_time'] > 0: + trials = [x for x in trials if x['results_metrics']['duration'] > filteroptions['filter_min_avg_time']] + if filteroptions['filter_max_avg_time'] > 0: + trials = [x for x in trials if x['results_metrics']['duration'] < filteroptions['filter_max_avg_time']] + if filteroptions['filter_min_avg_profit'] > 0: + trials = [x for x in trials if x['results_metrics']['avg_profit'] > filteroptions['filter_min_avg_profit']] + if filteroptions['filter_min_total_profit'] > 0: + trials = [x for x in trials if x['results_metrics']['profit'] > filteroptions['filter_min_total_profit']] + logger.info(f"{len(trials)} " + - ("best " if only_best else "") + - ("profitable " if only_profitable else "") + + ("best " if filteroptions['only_best'] else "") + + ("profitable " if filteroptions['only_profitable'] else "") + "epochs found.") return trials diff --git a/freqtrade/configuration/configuration.py b/freqtrade/configuration/configuration.py index a8b7638c8..f7e87f3a1 100644 --- a/freqtrade/configuration/configuration.py +++ b/freqtrade/configuration/configuration.py @@ -310,6 +310,18 @@ class Configuration: self._args_to_config(config, argname='hyperopt_list_profitable', logstring='Parameter --profitable detected: {}') + self._args_to_config(config, argname='hyperopt_list_min_avg_time', + logstring='Parameter --min-avg-time detected: {}') + + self._args_to_config(config, argname='hyperopt_list_max_avg_time', + logstring='Parameter --max-avg-time detected: {}') + + self._args_to_config(config, argname='hyperopt_list_min_avg_profit', + logstring='Parameter --min-avg-profit detected: {}') + + self._args_to_config(config, argname='hyperopt_list_min_total_profit', + logstring='Parameter --min-total-profit detected: {}') + self._args_to_config(config, argname='hyperopt_list_no_details', logstring='Parameter --no-details detected: {}')