Merge pull request #2905 from Fredrik81/hyperopt-more-filters

Adding --min-trades, --max-trades, --max-avg-profit, --max-total-profit for hyperopt-list
This commit is contained in:
hroff-1902 2020-02-11 23:46:48 +03:00 committed by GitHub
commit e73dac8d91
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 140 additions and 5 deletions

View File

@ -413,21 +413,30 @@ You can list the hyperoptimization epochs the Hyperopt module evaluated previous
``` ```
usage: freqtrade hyperopt-list [-h] [-v] [--logfile FILE] [-V] [-c PATH] usage: freqtrade hyperopt-list [-h] [-v] [--logfile FILE] [-V] [-c PATH]
[-d PATH] [--userdir PATH] [--best] [-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] [--max-avg-time FLOAT] [--min-avg-profit FLOAT]
[--min-total-profit FLOAT] [--no-color] [--max-avg-profit FLOAT]
[--min-total-profit FLOAT]
[--max-total-profit FLOAT] [--no-color]
[--print-json] [--no-details] [--print-json] [--no-details]
optional arguments: optional arguments:
-h, --help show this help message and exit -h, --help show this help message and exit
--best Select only best epochs. --best Select only best epochs.
--profitable Select only profitable 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. --min-avg-time FLOAT Select epochs on above average time.
--max-avg-time FLOAT Select epochs on under average time. --max-avg-time FLOAT Select epochs on under average time.
--min-avg-profit FLOAT --min-avg-profit FLOAT
Select epochs on above average profit. Select epochs on above average profit.
--max-avg-profit FLOAT
Select epochs on below average profit.
--min-total-profit FLOAT --min-total-profit FLOAT
Select epochs on above total profit. Select epochs on above total profit.
--max-total-profit FLOAT
Select epochs on below total profit.
--no-color Disable colorization of hyperopt results. May be --no-color Disable colorization of hyperopt results. May be
useful if you are redirecting output to a file. useful if you are redirecting output to a file.
--print-json Print best result detailization in JSON format. --print-json Print best result detailization in JSON format.

View File

@ -62,8 +62,10 @@ ARGS_PLOT_PROFIT = ["pairs", "timerange", "export", "exportfilename", "db_url",
"trade_source", "ticker_interval"] "trade_source", "ticker_interval"]
ARGS_HYPEROPT_LIST = ["hyperopt_list_best", "hyperopt_list_profitable", 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_time", "hyperopt_list_max_avg_time",
"hyperopt_list_min_avg_profit", "hyperopt_list_min_total_profit", "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", "hyperopt_list_no_details"]
ARGS_HYPEROPT_SHOW = ["hyperopt_list_best", "hyperopt_list_profitable", "hyperopt_show_index", ARGS_HYPEROPT_SHOW = ["hyperopt_list_best", "hyperopt_list_profitable", "hyperopt_show_index",

View File

@ -398,6 +398,18 @@ AVAILABLE_CLI_OPTIONS = {
help='Select only best epochs.', help='Select only best epochs.',
action='store_true', action='store_true',
), ),
"hyperopt_list_min_trades": Arg(
'--min-trades',
help='Select epochs with more than INT trades.',
type=check_int_positive,
metavar='INT',
),
"hyperopt_list_max_trades": Arg(
'--max-trades',
help='Select epochs with less than INT trades.',
type=check_int_positive,
metavar='INT',
),
"hyperopt_list_min_avg_time": Arg( "hyperopt_list_min_avg_time": Arg(
'--min-avg-time', '--min-avg-time',
help='Select epochs on above average time.', help='Select epochs on above average time.',
@ -416,12 +428,24 @@ AVAILABLE_CLI_OPTIONS = {
type=float, type=float,
metavar='FLOAT', metavar='FLOAT',
), ),
"hyperopt_list_max_avg_profit": Arg(
'--max-avg-profit',
help='Select epochs on below average profit.',
type=float,
metavar='FLOAT',
),
"hyperopt_list_min_total_profit": Arg( "hyperopt_list_min_total_profit": Arg(
'--min-total-profit', '--min-total-profit',
help='Select epochs on above total profit.', help='Select epochs on above total profit.',
type=float, type=float,
metavar='FLOAT', metavar='FLOAT',
), ),
"hyperopt_list_max_total_profit": Arg(
'--max-total-profit',
help='Select epochs on below total profit.',
type=float,
metavar='FLOAT',
),
"hyperopt_list_no_details": Arg( "hyperopt_list_no_details": Arg(
'--no-details', '--no-details',
help='Do not print best epoch details.', help='Do not print best epoch details.',

35
freqtrade/commands/hyperopt_commands.py Normal file → Executable file
View File

@ -27,10 +27,14 @@ def start_hyperopt_list(args: Dict[str, Any]) -> None:
filteroptions = { filteroptions = {
'only_best': config.get('hyperopt_list_best', False), 'only_best': config.get('hyperopt_list_best', False),
'only_profitable': config.get('hyperopt_list_profitable', 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_min_avg_time': config.get('hyperopt_list_min_avg_time', None),
'filter_max_avg_time': config.get('hyperopt_list_max_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), 'filter_min_avg_profit': config.get('hyperopt_list_min_avg_profit', None),
'filter_min_total_profit': config.get('hyperopt_list_min_total_profit', None) 'filter_max_avg_profit': config.get('hyperopt_list_max_avg_profit', 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)
} }
trials_file = (config['user_data_dir'] / trials_file = (config['user_data_dir'] /
@ -74,10 +78,14 @@ def start_hyperopt_show(args: Dict[str, Any]) -> None:
filteroptions = { filteroptions = {
'only_best': config.get('hyperopt_list_best', False), 'only_best': config.get('hyperopt_list_best', False),
'only_profitable': config.get('hyperopt_list_profitable', 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_min_avg_time': config.get('hyperopt_list_min_avg_time', None),
'filter_max_avg_time': config.get('hyperopt_list_max_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), 'filter_min_avg_profit': config.get('hyperopt_list_min_avg_profit', None),
'filter_min_total_profit': config.get('hyperopt_list_min_total_profit', None) 'filter_max_avg_profit': config.get('hyperopt_list_max_avg_profit', 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) no_header = config.get('hyperopt_show_no_header', False)
@ -119,6 +127,16 @@ def _hyperopt_filter_trials(trials: List, filteroptions: dict) -> List:
trials = [x for x in trials if x['is_best']] trials = [x for x in trials if x['is_best']]
if filteroptions['only_profitable']: if filteroptions['only_profitable']:
trials = [x for x in trials if x['results_metrics']['profit'] > 0] 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: if filteroptions['filter_min_avg_time'] is not None:
trials = [x for x in trials if x['results_metrics']['trade_count'] > 0] trials = [x for x in trials if x['results_metrics']['trade_count'] > 0]
trials = [ trials = [
@ -138,12 +156,25 @@ def _hyperopt_filter_trials(trials: List, filteroptions: dict) -> List:
if x['results_metrics']['avg_profit'] if x['results_metrics']['avg_profit']
> filteroptions['filter_min_avg_profit'] > filteroptions['filter_min_avg_profit']
] ]
if filteroptions['filter_max_avg_profit'] is not None:
trials = [x for x in trials if x['results_metrics']['trade_count'] > 0]
trials = [
x for x in trials
if x['results_metrics']['avg_profit']
< filteroptions['filter_max_avg_profit']
]
if filteroptions['filter_min_total_profit'] is not None: if filteroptions['filter_min_total_profit'] is not None:
trials = [x for x in trials if x['results_metrics']['trade_count'] > 0] trials = [x for x in trials if x['results_metrics']['trade_count'] > 0]
trials = [ trials = [
x for x in trials x for x in trials
if x['results_metrics']['profit'] > filteroptions['filter_min_total_profit'] if x['results_metrics']['profit'] > filteroptions['filter_min_total_profit']
] ]
if filteroptions['filter_max_total_profit'] is not None:
trials = [x for x in trials if x['results_metrics']['trade_count'] > 0]
trials = [
x for x in trials
if x['results_metrics']['profit'] < filteroptions['filter_max_total_profit']
]
logger.info(f"{len(trials)} " + logger.info(f"{len(trials)} " +
("best " if filteroptions['only_best'] else "") + ("best " if filteroptions['only_best'] else "") +

View File

@ -310,6 +310,12 @@ class Configuration:
self._args_to_config(config, argname='hyperopt_list_profitable', self._args_to_config(config, argname='hyperopt_list_profitable',
logstring='Parameter --profitable detected: {}') 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', self._args_to_config(config, argname='hyperopt_list_min_avg_time',
logstring='Parameter --min-avg-time detected: {}') logstring='Parameter --min-avg-time detected: {}')
@ -319,9 +325,15 @@ class Configuration:
self._args_to_config(config, argname='hyperopt_list_min_avg_profit', self._args_to_config(config, argname='hyperopt_list_min_avg_profit',
logstring='Parameter --min-avg-profit detected: {}') logstring='Parameter --min-avg-profit detected: {}')
self._args_to_config(config, argname='hyperopt_list_max_avg_profit',
logstring='Parameter --max-avg-profit detected: {}')
self._args_to_config(config, argname='hyperopt_list_min_total_profit', self._args_to_config(config, argname='hyperopt_list_min_total_profit',
logstring='Parameter --min-total-profit detected: {}') logstring='Parameter --min-total-profit detected: {}')
self._args_to_config(config, argname='hyperopt_list_max_total_profit',
logstring='Parameter --max-total-profit detected: {}')
self._args_to_config(config, argname='hyperopt_list_no_details', self._args_to_config(config, argname='hyperopt_list_no_details',
logstring='Parameter --no-details detected: {}') logstring='Parameter --no-details detected: {}')

View File

@ -773,6 +773,35 @@ def test_hyperopt_list(mocker, capsys, hyperopt_results):
pargs['config'] = None pargs['config'] = None
start_hyperopt_list(pargs) start_hyperopt_list(pargs)
captured = capsys.readouterr() 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 assert all(x in captured.out
for x in [" 2/12", " 10/12"]) for x in [" 2/12", " 10/12"])
assert all(x not in captured.out assert all(x not in captured.out
@ -793,6 +822,20 @@ def test_hyperopt_list(mocker, capsys, hyperopt_results):
assert all(x not in captured.out 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", for x in [" 1/12", " 3/12", " 4/12", " 5/12", " 6/12", " 7/12", " 8/12", " 9/12",
" 10/12", " 11/12", " 12/12"]) " 10/12", " 11/12", " 12/12"])
args = [
"hyperopt-list",
"--no-details",
"--max-avg-profit", "0.10"
]
pargs = get_args(args)
pargs['config'] = None
start_hyperopt_list(pargs)
captured = capsys.readouterr()
assert all(x in captured.out
for x in [" 1/12", " 3/12", " 5/12", " 6/12", " 7/12", " 8/12", " 9/12",
" 11/12"])
assert all(x not in captured.out
for x in [" 2/12", " 4/12", " 10/12", " 12/12"])
args = [ args = [
"hyperopt-list", "hyperopt-list",
"--no-details", "--no-details",
@ -807,6 +850,20 @@ def test_hyperopt_list(mocker, capsys, hyperopt_results):
assert all(x not in captured.out assert all(x not in captured.out
for x in [" 1/12", " 2/12", " 3/12", " 4/12", " 5/12", " 6/12", " 7/12", " 8/12", for x in [" 1/12", " 2/12", " 3/12", " 4/12", " 5/12", " 6/12", " 7/12", " 8/12",
" 9/12", " 11/12", " 12/12"]) " 9/12", " 11/12", " 12/12"])
args = [
"hyperopt-list",
"--no-details",
"--max-total-profit", "0.4"
]
pargs = get_args(args)
pargs['config'] = None
start_hyperopt_list(pargs)
captured = capsys.readouterr()
assert all(x in captured.out
for x in [" 1/12", " 2/12", " 3/12", " 5/12", " 6/12", " 7/12", " 8/12",
" 9/12", " 11/12"])
assert all(x not in captured.out
for x in [" 4/12", " 10/12", " 12/12"])
args = [ args = [
"hyperopt-list", "hyperopt-list",
"--profitable", "--profitable",