diff --git a/docs/utils.md b/docs/utils.md index 5bb3a0e53..91dd6eae0 100644 --- a/docs/utils.md +++ b/docs/utils.md @@ -413,7 +413,8 @@ You can list the hyperoptimization epochs the Hyperopt module evaluated previous ``` usage: freqtrade hyperopt-list [-h] [-v] [--logfile FILE] [-V] [-c PATH] [-d PATH] [--userdir PATH] [--best] - [--profitable] [--min-avg-time FLOAT] + [--profitable] [--min-trades INT] + [--max-trades INT] [--min-avg-time FLOAT] [--max-avg-time FLOAT] [--min-avg-profit FLOAT] [--min-total-profit FLOAT] [--no-color] [--print-json] [--no-details] @@ -422,6 +423,8 @@ optional arguments: -h, --help show this help message and exit --best Select only best epochs. --profitable Select only profitable epochs. + --min-trades INT Select epochs with more than INT trades. + --max-trades INT Select epochs with less than INT trades. --min-avg-time FLOAT Select epochs on above average time. --max-avg-time FLOAT Select epochs on under average time. --min-avg-profit FLOAT diff --git a/freqtrade/commands/arguments.py b/freqtrade/commands/arguments.py index e5a68389b..1b2c4482e 100644 --- a/freqtrade/commands/arguments.py +++ b/freqtrade/commands/arguments.py @@ -62,6 +62,7 @@ ARGS_PLOT_PROFIT = ["pairs", "timerange", "export", "exportfilename", "db_url", "trade_source", "ticker_interval"] ARGS_HYPEROPT_LIST = ["hyperopt_list_best", "hyperopt_list_profitable", + "hyperopt_list_min_trades", "hyperopt_list_max_trades", "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"] diff --git a/freqtrade/commands/cli_options.py b/freqtrade/commands/cli_options.py index 154404821..f9351c207 100644 --- a/freqtrade/commands/cli_options.py +++ b/freqtrade/commands/cli_options.py @@ -398,6 +398,18 @@ AVAILABLE_CLI_OPTIONS = { help='Select only best epochs.', action='store_true', ), + "hyperopt_list_min_trades": Arg( + '--min-trades', + help='Select epochs with more than INT trades.', + type=check_int_nonzero, + metavar='INT', + ), + "hyperopt_list_max_trades": Arg( + '--max-trades', + help='Select epochs with less than INT trades.', + type=check_int_nonzero, + metavar='INT', + ), "hyperopt_list_min_avg_time": Arg( '--min-avg-time', help='Select epochs on above average time.', diff --git a/freqtrade/commands/hyperopt_commands.py b/freqtrade/commands/hyperopt_commands.py old mode 100644 new mode 100755 index ed0728bf6..c3baf2406 --- a/freqtrade/commands/hyperopt_commands.py +++ b/freqtrade/commands/hyperopt_commands.py @@ -27,6 +27,8 @@ def start_hyperopt_list(args: Dict[str, Any]) -> None: filteroptions = { 'only_best': config.get('hyperopt_list_best', False), 'only_profitable': config.get('hyperopt_list_profitable', False), + 'filter_min_trades': config.get('hyperopt_list_min_trades', 0), + 'filter_max_trades': config.get('hyperopt_list_max_trades', 0), 'filter_min_avg_time': config.get('hyperopt_list_min_avg_time', None), 'filter_max_avg_time': config.get('hyperopt_list_max_avg_time', None), 'filter_min_avg_profit': config.get('hyperopt_list_min_avg_profit', None), @@ -74,6 +76,8 @@ def start_hyperopt_show(args: Dict[str, Any]) -> None: filteroptions = { 'only_best': config.get('hyperopt_list_best', False), 'only_profitable': config.get('hyperopt_list_profitable', False), + 'filter_min_trades': config.get('hyperopt_list_min_trades', 0), + 'filter_max_trades': config.get('hyperopt_list_max_trades', 0), 'filter_min_avg_time': config.get('hyperopt_list_min_avg_time', None), 'filter_max_avg_time': config.get('hyperopt_list_max_avg_time', None), 'filter_min_avg_profit': config.get('hyperopt_list_min_avg_profit', None), @@ -119,6 +123,16 @@ def _hyperopt_filter_trials(trials: List, filteroptions: dict) -> List: trials = [x for x in trials if x['is_best']] if filteroptions['only_profitable']: trials = [x for x in trials if x['results_metrics']['profit'] > 0] + if filteroptions['filter_min_trades'] > 0: + trials = [ + x for x in trials + if x['results_metrics']['trade_count'] > filteroptions['filter_min_trades'] + ] + if filteroptions['filter_max_trades'] > 0: + trials = [ + x for x in trials + if x['results_metrics']['trade_count'] < filteroptions['filter_max_trades'] + ] if filteroptions['filter_min_avg_time'] is not None: trials = [x for x in trials if x['results_metrics']['trade_count'] > 0] trials = [ diff --git a/freqtrade/configuration/configuration.py b/freqtrade/configuration/configuration.py index f7e87f3a1..41f24e55c 100644 --- a/freqtrade/configuration/configuration.py +++ b/freqtrade/configuration/configuration.py @@ -310,6 +310,12 @@ class Configuration: self._args_to_config(config, argname='hyperopt_list_profitable', logstring='Parameter --profitable detected: {}') + self._args_to_config(config, argname='hyperopt_list_min_trades', + logstring='Parameter --min-trades detected: {}') + + self._args_to_config(config, argname='hyperopt_list_max_trades', + logstring='Parameter --max-trades detected: {}') + self._args_to_config(config, argname='hyperopt_list_min_avg_time', logstring='Parameter --min-avg-time detected: {}') diff --git a/tests/commands/test_commands.py b/tests/commands/test_commands.py index db8a9289a..e02a721a4 100644 --- a/tests/commands/test_commands.py +++ b/tests/commands/test_commands.py @@ -773,6 +773,35 @@ def test_hyperopt_list(mocker, capsys, hyperopt_results): 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"]) + args = [ + "hyperopt-list", + "--no-details", + "--no-color", + "--min-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 [" 3/12", " 6/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", " 8/12", " 10/12", " 12/12"]) + args = [ + "hyperopt-list", + "--profitable", + "--no-details", + "--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