Merge branch 'develop' into pr/Axel-CH/5347
This commit is contained in:
@@ -938,247 +938,261 @@ def test_start_test_pairlist(mocker, caplog, tickers, default_conf, capsys):
|
||||
pytest.fail(f'Expected well formed JSON, but failed to parse: {captured.out}')
|
||||
|
||||
|
||||
def test_hyperopt_list(mocker, capsys, caplog, saved_hyperopt_results,
|
||||
saved_hyperopt_results_legacy, tmpdir):
|
||||
def test_hyperopt_list(mocker, capsys, caplog, saved_hyperopt_results, tmpdir):
|
||||
csv_file = Path(tmpdir) / "test.csv"
|
||||
for res in (saved_hyperopt_results, saved_hyperopt_results_legacy):
|
||||
mocker.patch(
|
||||
'freqtrade.optimize.hyperopt_tools.HyperoptTools.load_previous_results',
|
||||
MagicMock(return_value=res)
|
||||
mocker.patch(
|
||||
'freqtrade.optimize.hyperopt_tools.HyperoptTools._test_hyperopt_results_exist',
|
||||
return_value=True
|
||||
)
|
||||
|
||||
args = [
|
||||
"hyperopt-list",
|
||||
"--no-details",
|
||||
"--no-color",
|
||||
]
|
||||
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", " 4/12", " 5/12",
|
||||
" 6/12", " 7/12", " 8/12", " 9/12", " 10/12",
|
||||
" 11/12", " 12/12"])
|
||||
args = [
|
||||
"hyperopt-list",
|
||||
"--best",
|
||||
"--no-details",
|
||||
"--no-color",
|
||||
]
|
||||
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", " 5/12", " 10/12"])
|
||||
assert all(x not in captured.out
|
||||
for x in [" 2/12", " 3/12", " 4/12", " 6/12", " 7/12", " 8/12", " 9/12",
|
||||
" 11/12", " 12/12"])
|
||||
args = [
|
||||
"hyperopt-list",
|
||||
"--profitable",
|
||||
"--no-details",
|
||||
"--no-color",
|
||||
]
|
||||
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"])
|
||||
args = [
|
||||
"hyperopt-list",
|
||||
"--profitable",
|
||||
"--no-color",
|
||||
]
|
||||
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",
|
||||
"--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",
|
||||
"--no-color",
|
||||
"--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"])
|
||||
args = [
|
||||
"hyperopt-list",
|
||||
"--profitable",
|
||||
"--no-details",
|
||||
"--no-color",
|
||||
"--min-avg-profit", "0.11",
|
||||
]
|
||||
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"])
|
||||
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",
|
||||
" 10/12", " 11/12", " 12/12"])
|
||||
args = [
|
||||
"hyperopt-list",
|
||||
"--no-details",
|
||||
"--no-color",
|
||||
"--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 = [
|
||||
"hyperopt-list",
|
||||
"--no-details",
|
||||
"--no-color",
|
||||
"--min-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 [" 10/12"])
|
||||
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",
|
||||
" 9/12", " 11/12", " 12/12"])
|
||||
args = [
|
||||
"hyperopt-list",
|
||||
"--no-details",
|
||||
"--no-color",
|
||||
"--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 = [
|
||||
"hyperopt-list",
|
||||
"--no-details",
|
||||
"--no-color",
|
||||
"--min-objective", "0.1",
|
||||
]
|
||||
pargs = get_args(args)
|
||||
pargs['config'] = None
|
||||
start_hyperopt_list(pargs)
|
||||
captured = capsys.readouterr()
|
||||
assert all(x in captured.out
|
||||
for x in [" 10/12"])
|
||||
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",
|
||||
" 9/12", " 11/12", " 12/12"])
|
||||
args = [
|
||||
"hyperopt-list",
|
||||
"--no-details",
|
||||
"--max-objective", "0.1",
|
||||
]
|
||||
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 = [
|
||||
"hyperopt-list",
|
||||
"--profitable",
|
||||
"--no-details",
|
||||
"--no-color",
|
||||
"--min-avg-time", "2000",
|
||||
]
|
||||
pargs = get_args(args)
|
||||
pargs['config'] = None
|
||||
start_hyperopt_list(pargs)
|
||||
captured = capsys.readouterr()
|
||||
assert all(x in captured.out
|
||||
for x in [" 10/12"])
|
||||
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", " 9/12", " 11/12", " 12/12"])
|
||||
args = [
|
||||
"hyperopt-list",
|
||||
"--no-details",
|
||||
"--no-color",
|
||||
"--max-avg-time", "1500",
|
||||
]
|
||||
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", " 6/12"])
|
||||
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",
|
||||
"--no-color",
|
||||
"--export-csv",
|
||||
str(csv_file),
|
||||
]
|
||||
pargs = get_args(args)
|
||||
pargs['config'] = None
|
||||
start_hyperopt_list(pargs)
|
||||
captured = capsys.readouterr()
|
||||
log_has("CSV file created: test_file.csv", caplog)
|
||||
assert csv_file.is_file()
|
||||
line = csv_file.read_text()
|
||||
assert ('Best,1,2,-1.25%,-1.2222,-0.00125625,,-2.51,"3,930.0 m",0.43662' in line
|
||||
or "Best,1,2,-1.25%,-1.2222,-0.00125625,,-2.51,2 days 17:30:00,0.43662" in line)
|
||||
csv_file.unlink()
|
||||
def fake_iterator(*args, **kwargs):
|
||||
yield from [saved_hyperopt_results]
|
||||
|
||||
mocker.patch(
|
||||
'freqtrade.optimize.hyperopt_tools.HyperoptTools._read_results',
|
||||
side_effect=fake_iterator
|
||||
)
|
||||
|
||||
args = [
|
||||
"hyperopt-list",
|
||||
"--no-details",
|
||||
"--no-color",
|
||||
]
|
||||
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", " 4/12", " 5/12",
|
||||
" 6/12", " 7/12", " 8/12", " 9/12", " 10/12",
|
||||
" 11/12", " 12/12"])
|
||||
args = [
|
||||
"hyperopt-list",
|
||||
"--best",
|
||||
"--no-details",
|
||||
"--no-color",
|
||||
]
|
||||
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", " 5/12", " 10/12"])
|
||||
assert all(x not in captured.out
|
||||
for x in [" 2/12", " 3/12", " 4/12", " 6/12", " 7/12", " 8/12", " 9/12",
|
||||
" 11/12", " 12/12"])
|
||||
args = [
|
||||
"hyperopt-list",
|
||||
"--profitable",
|
||||
"--no-details",
|
||||
"--no-color",
|
||||
]
|
||||
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"])
|
||||
args = [
|
||||
"hyperopt-list",
|
||||
"--profitable",
|
||||
"--no-color",
|
||||
]
|
||||
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",
|
||||
"--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",
|
||||
"--no-color",
|
||||
"--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"])
|
||||
args = [
|
||||
"hyperopt-list",
|
||||
"--profitable",
|
||||
"--no-details",
|
||||
"--no-color",
|
||||
"--min-avg-profit", "0.11",
|
||||
]
|
||||
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"])
|
||||
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",
|
||||
" 10/12", " 11/12", " 12/12"])
|
||||
args = [
|
||||
"hyperopt-list",
|
||||
"--no-details",
|
||||
"--no-color",
|
||||
"--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 = [
|
||||
"hyperopt-list",
|
||||
"--no-details",
|
||||
"--no-color",
|
||||
"--min-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 [" 10/12"])
|
||||
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",
|
||||
" 9/12", " 11/12", " 12/12"])
|
||||
args = [
|
||||
"hyperopt-list",
|
||||
"--no-details",
|
||||
"--no-color",
|
||||
"--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 = [
|
||||
"hyperopt-list",
|
||||
"--no-details",
|
||||
"--no-color",
|
||||
"--min-objective", "0.1",
|
||||
]
|
||||
pargs = get_args(args)
|
||||
pargs['config'] = None
|
||||
start_hyperopt_list(pargs)
|
||||
captured = capsys.readouterr()
|
||||
assert all(x in captured.out
|
||||
for x in [" 10/12"])
|
||||
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",
|
||||
" 9/12", " 11/12", " 12/12"])
|
||||
args = [
|
||||
"hyperopt-list",
|
||||
"--no-details",
|
||||
"--max-objective", "0.1",
|
||||
]
|
||||
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 = [
|
||||
"hyperopt-list",
|
||||
"--profitable",
|
||||
"--no-details",
|
||||
"--no-color",
|
||||
"--min-avg-time", "2000",
|
||||
]
|
||||
pargs = get_args(args)
|
||||
pargs['config'] = None
|
||||
start_hyperopt_list(pargs)
|
||||
captured = capsys.readouterr()
|
||||
assert all(x in captured.out
|
||||
for x in [" 10/12"])
|
||||
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", " 9/12", " 11/12", " 12/12"])
|
||||
args = [
|
||||
"hyperopt-list",
|
||||
"--no-details",
|
||||
"--no-color",
|
||||
"--max-avg-time", "1500",
|
||||
]
|
||||
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", " 6/12"])
|
||||
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",
|
||||
"--no-color",
|
||||
"--export-csv",
|
||||
str(csv_file),
|
||||
]
|
||||
pargs = get_args(args)
|
||||
pargs['config'] = None
|
||||
start_hyperopt_list(pargs)
|
||||
captured = capsys.readouterr()
|
||||
log_has("CSV file created: test_file.csv", caplog)
|
||||
assert csv_file.is_file()
|
||||
line = csv_file.read_text()
|
||||
assert ('Best,1,2,-1.25%,-1.2222,-0.00125625,,-2.51,"3,930.0 m",0.43662' in line
|
||||
or "Best,1,2,-1.25%,-1.2222,-0.00125625,,-2.51,2 days 17:30:00,0.43662" in line)
|
||||
csv_file.unlink()
|
||||
|
||||
|
||||
def test_hyperopt_show(mocker, capsys, saved_hyperopt_results):
|
||||
mocker.patch(
|
||||
'freqtrade.optimize.hyperopt_tools.HyperoptTools.load_previous_results',
|
||||
MagicMock(return_value=saved_hyperopt_results)
|
||||
'freqtrade.optimize.hyperopt_tools.HyperoptTools._test_hyperopt_results_exist',
|
||||
return_value=True
|
||||
)
|
||||
|
||||
def fake_iterator(*args, **kwargs):
|
||||
yield from [saved_hyperopt_results]
|
||||
|
||||
mocker.patch(
|
||||
'freqtrade.optimize.hyperopt_tools.HyperoptTools._read_results',
|
||||
side_effect=fake_iterator
|
||||
)
|
||||
mocker.patch('freqtrade.commands.hyperopt_commands.show_backtest_result')
|
||||
|
||||
|
@@ -6,8 +6,8 @@
|
||||
*/
|
||||
"stake_currency": "BTC",
|
||||
"stake_amount": 0.05,
|
||||
"fiat_display_currency": "USD", // C++-style comment
|
||||
"amount_reserve_percent" : 0.05, // And more, tabs before this comment
|
||||
"fiat_display_currency": "USD", // C++-style comment
|
||||
"amount_reserve_percent": 0.05, // And more, tabs before this comment
|
||||
"dry_run": false,
|
||||
"timeframe": "5m",
|
||||
"trailing_stop": false,
|
||||
@@ -15,15 +15,15 @@
|
||||
"trailing_stop_positive_offset": 0.0051,
|
||||
"trailing_only_offset_is_reached": false,
|
||||
"minimal_roi": {
|
||||
"40": 0.0,
|
||||
"30": 0.01,
|
||||
"20": 0.02,
|
||||
"0": 0.04
|
||||
"40": 0.0,
|
||||
"30": 0.01,
|
||||
"20": 0.02,
|
||||
"0": 0.04
|
||||
},
|
||||
"stoploss": -0.10,
|
||||
"unfilledtimeout": {
|
||||
"buy": 10,
|
||||
"sell": 30, // Trailing comma should also be accepted now
|
||||
"sell": 30, // Trailing comma should also be accepted now
|
||||
},
|
||||
"bid_strategy": {
|
||||
"use_order_book": false,
|
||||
@@ -34,7 +34,7 @@
|
||||
"bids_to_ask_delta": 1
|
||||
}
|
||||
},
|
||||
"ask_strategy":{
|
||||
"ask_strategy": {
|
||||
"use_order_book": false,
|
||||
"order_book_min": 1,
|
||||
"order_book_max": 9
|
||||
@@ -64,7 +64,9 @@
|
||||
"key": "your_exchange_key",
|
||||
"secret": "your_exchange_secret",
|
||||
"password": "",
|
||||
"ccxt_config": {"enableRateLimit": true},
|
||||
"ccxt_config": {
|
||||
"enableRateLimit": true
|
||||
},
|
||||
"ccxt_async_config": {
|
||||
"enableRateLimit": false,
|
||||
"rateLimit": 500,
|
||||
@@ -103,8 +105,8 @@
|
||||
"remove_pumps": false
|
||||
},
|
||||
"telegram": {
|
||||
// We can now comment out some settings
|
||||
// "enabled": true,
|
||||
// We can now comment out some settings
|
||||
// "enabled": true,
|
||||
"enabled": false,
|
||||
"token": "your_telegram_token",
|
||||
"chat_id": "your_telegram_chat_id"
|
||||
@@ -124,4 +126,4 @@
|
||||
},
|
||||
"strategy": "DefaultStrategy",
|
||||
"strategy_path": "user_data/strategies/"
|
||||
}
|
||||
}
|
@@ -1814,138 +1814,6 @@ def open_trade():
|
||||
)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def saved_hyperopt_results_legacy():
|
||||
return [
|
||||
{
|
||||
'loss': 0.4366182531161519,
|
||||
'params_dict': {
|
||||
'mfi-value': 15, 'fastd-value': 20, 'adx-value': 25, 'rsi-value': 28, 'mfi-enabled': False, 'fastd-enabled': True, 'adx-enabled': True, 'rsi-enabled': True, 'trigger': 'macd_cross_signal', 'sell-mfi-value': 88, 'sell-fastd-value': 97, 'sell-adx-value': 51, 'sell-rsi-value': 67, 'sell-mfi-enabled': False, 'sell-fastd-enabled': False, 'sell-adx-enabled': True, 'sell-rsi-enabled': True, 'sell-trigger': 'sell-bb_upper', 'roi_t1': 1190, 'roi_t2': 541, 'roi_t3': 408, 'roi_p1': 0.026035863879169705, 'roi_p2': 0.12508730043628782, 'roi_p3': 0.27766427921605896, 'stoploss': -0.2562930402099556}, # noqa: E501
|
||||
'params_details': {'buy': {'mfi-value': 15, 'fastd-value': 20, 'adx-value': 25, 'rsi-value': 28, 'mfi-enabled': False, 'fastd-enabled': True, 'adx-enabled': True, 'rsi-enabled': True, 'trigger': 'macd_cross_signal'}, 'sell': {'sell-mfi-value': 88, 'sell-fastd-value': 97, 'sell-adx-value': 51, 'sell-rsi-value': 67, 'sell-mfi-enabled': False, 'sell-fastd-enabled': False, 'sell-adx-enabled': True, 'sell-rsi-enabled': True, 'sell-trigger': 'sell-bb_upper'}, 'roi': {0: 0.4287874435315165, 408: 0.15112316431545753, 949: 0.026035863879169705, 2139: 0}, 'stoploss': {'stoploss': -0.2562930402099556}}, # noqa: E501
|
||||
'results_metrics': {'trade_count': 2, 'avg_profit': -1.254995, 'median_profit': -1.2222, 'total_profit': -0.00125625, 'profit': -2.50999, 'duration': 3930.0}, # noqa: E501
|
||||
'results_explanation': ' 2 trades. Avg profit -1.25%. Total profit -0.00125625 BTC ( -2.51Σ%). Avg duration 3930.0 min.', # noqa: E501
|
||||
'total_profit': -0.00125625,
|
||||
'current_epoch': 1,
|
||||
'is_initial_point': True,
|
||||
'is_best': True
|
||||
}, {
|
||||
'loss': 20.0,
|
||||
'params_dict': {
|
||||
'mfi-value': 17, 'fastd-value': 38, 'adx-value': 48, 'rsi-value': 22, 'mfi-enabled': True, 'fastd-enabled': False, 'adx-enabled': True, 'rsi-enabled': True, 'trigger': 'macd_cross_signal', 'sell-mfi-value': 96, 'sell-fastd-value': 68, 'sell-adx-value': 63, 'sell-rsi-value': 81, 'sell-mfi-enabled': False, 'sell-fastd-enabled': True, 'sell-adx-enabled': True, 'sell-rsi-enabled': True, 'sell-trigger': 'sell-sar_reversal', 'roi_t1': 334, 'roi_t2': 683, 'roi_t3': 140, 'roi_p1': 0.06403981740598495, 'roi_p2': 0.055519840060645045, 'roi_p3': 0.3253712811342459, 'stoploss': -0.338070047333259}, # noqa: E501
|
||||
'params_details': {
|
||||
'buy': {'mfi-value': 17, 'fastd-value': 38, 'adx-value': 48, 'rsi-value': 22, 'mfi-enabled': True, 'fastd-enabled': False, 'adx-enabled': True, 'rsi-enabled': True, 'trigger': 'macd_cross_signal'}, # noqa: E501
|
||||
'sell': {'sell-mfi-value': 96, 'sell-fastd-value': 68, 'sell-adx-value': 63, 'sell-rsi-value': 81, 'sell-mfi-enabled': False, 'sell-fastd-enabled': True, 'sell-adx-enabled': True, 'sell-rsi-enabled': True, 'sell-trigger': 'sell-sar_reversal'}, # noqa: E501
|
||||
'roi': {0: 0.4449309386008759, 140: 0.11955965746663, 823: 0.06403981740598495, 1157: 0}, # noqa: E501
|
||||
'stoploss': {'stoploss': -0.338070047333259}},
|
||||
'results_metrics': {'trade_count': 1, 'avg_profit': 0.12357, 'median_profit': -1.2222, 'total_profit': 6.185e-05, 'profit': 0.12357, 'duration': 1200.0}, # noqa: E501
|
||||
'results_explanation': ' 1 trades. Avg profit 0.12%. Total profit 0.00006185 BTC ( 0.12Σ%). Avg duration 1200.0 min.', # noqa: E501
|
||||
'total_profit': 6.185e-05,
|
||||
'current_epoch': 2,
|
||||
'is_initial_point': True,
|
||||
'is_best': False
|
||||
}, {
|
||||
'loss': 14.241196856510731,
|
||||
'params_dict': {'mfi-value': 25, 'fastd-value': 16, 'adx-value': 29, 'rsi-value': 20, 'mfi-enabled': False, 'fastd-enabled': False, 'adx-enabled': False, 'rsi-enabled': False, 'trigger': 'macd_cross_signal', 'sell-mfi-value': 98, 'sell-fastd-value': 72, 'sell-adx-value': 51, 'sell-rsi-value': 82, 'sell-mfi-enabled': True, 'sell-fastd-enabled': True, 'sell-adx-enabled': True, 'sell-rsi-enabled': True, 'sell-trigger': 'sell-macd_cross_signal', 'roi_t1': 889, 'roi_t2': 533, 'roi_t3': 263, 'roi_p1': 0.04759065393663096, 'roi_p2': 0.1488819964638463, 'roi_p3': 0.4102801822104605, 'stoploss': -0.05394588767607611}, # noqa: E501
|
||||
'params_details': {'buy': {'mfi-value': 25, 'fastd-value': 16, 'adx-value': 29, 'rsi-value': 20, 'mfi-enabled': False, 'fastd-enabled': False, 'adx-enabled': False, 'rsi-enabled': False, 'trigger': 'macd_cross_signal'}, 'sell': {'sell-mfi-value': 98, 'sell-fastd-value': 72, 'sell-adx-value': 51, 'sell-rsi-value': 82, 'sell-mfi-enabled': True, 'sell-fastd-enabled': True, 'sell-adx-enabled': True, 'sell-rsi-enabled': True, 'sell-trigger': 'sell-macd_cross_signal'}, 'roi': {0: 0.6067528326109377, 263: 0.19647265040047726, 796: 0.04759065393663096, 1685: 0}, 'stoploss': {'stoploss': -0.05394588767607611}}, # noqa: E501
|
||||
'results_metrics': {'trade_count': 621, 'avg_profit': -0.43883302093397747, 'median_profit': -1.2222, 'total_profit': -0.13639474, 'profit': -272.515306, 'duration': 1691.207729468599}, # noqa: E501
|
||||
'results_explanation': ' 621 trades. Avg profit -0.44%. Total profit -0.13639474 BTC (-272.52Σ%). Avg duration 1691.2 min.', # noqa: E501
|
||||
'total_profit': -0.13639474,
|
||||
'current_epoch': 3,
|
||||
'is_initial_point': True,
|
||||
'is_best': False
|
||||
}, {
|
||||
'loss': 100000,
|
||||
'params_dict': {'mfi-value': 13, 'fastd-value': 35, 'adx-value': 39, 'rsi-value': 29, 'mfi-enabled': True, 'fastd-enabled': False, 'adx-enabled': False, 'rsi-enabled': True, 'trigger': 'macd_cross_signal', 'sell-mfi-value': 87, 'sell-fastd-value': 54, 'sell-adx-value': 63, 'sell-rsi-value': 93, 'sell-mfi-enabled': False, 'sell-fastd-enabled': True, 'sell-adx-enabled': True, 'sell-rsi-enabled': True, 'sell-trigger': 'sell-bb_upper', 'roi_t1': 1402, 'roi_t2': 676, 'roi_t3': 215, 'roi_p1': 0.06264755784937427, 'roi_p2': 0.14258587851894644, 'roi_p3': 0.20671291201040828, 'stoploss': -0.11818343570194478}, # noqa: E501
|
||||
'params_details': {'buy': {'mfi-value': 13, 'fastd-value': 35, 'adx-value': 39, 'rsi-value': 29, 'mfi-enabled': True, 'fastd-enabled': False, 'adx-enabled': False, 'rsi-enabled': True, 'trigger': 'macd_cross_signal'}, 'sell': {'sell-mfi-value': 87, 'sell-fastd-value': 54, 'sell-adx-value': 63, 'sell-rsi-value': 93, 'sell-mfi-enabled': False, 'sell-fastd-enabled': True, 'sell-adx-enabled': True, 'sell-rsi-enabled': True, 'sell-trigger': 'sell-bb_upper'}, 'roi': {0: 0.411946348378729, 215: 0.2052334363683207, 891: 0.06264755784937427, 2293: 0}, 'stoploss': {'stoploss': -0.11818343570194478}}, # noqa: E501
|
||||
'results_metrics': {'trade_count': 0, 'avg_profit': None, 'median_profit': None, 'total_profit': 0, 'profit': 0.0, 'duration': None}, # noqa: E501
|
||||
'results_explanation': ' 0 trades. Avg profit nan%. Total profit 0.00000000 BTC ( 0.00Σ%). Avg duration nan min.', # noqa: E501
|
||||
'total_profit': 0, 'current_epoch': 4, 'is_initial_point': True, 'is_best': False
|
||||
}, {
|
||||
'loss': 0.22195522184191518,
|
||||
'params_dict': {'mfi-value': 17, 'fastd-value': 21, 'adx-value': 38, 'rsi-value': 33, 'mfi-enabled': True, 'fastd-enabled': False, 'adx-enabled': True, 'rsi-enabled': False, 'trigger': 'macd_cross_signal', 'sell-mfi-value': 87, 'sell-fastd-value': 82, 'sell-adx-value': 78, 'sell-rsi-value': 69, 'sell-mfi-enabled': True, 'sell-fastd-enabled': False, 'sell-adx-enabled': True, 'sell-rsi-enabled': False, 'sell-trigger': 'sell-macd_cross_signal', 'roi_t1': 1269, 'roi_t2': 601, 'roi_t3': 444, 'roi_p1': 0.07280999507931168, 'roi_p2': 0.08946698095898986, 'roi_p3': 0.1454876733325284, 'stoploss': -0.18181041180901014}, # noqa: E501
|
||||
'params_details': {'buy': {'mfi-value': 17, 'fastd-value': 21, 'adx-value': 38, 'rsi-value': 33, 'mfi-enabled': True, 'fastd-enabled': False, 'adx-enabled': True, 'rsi-enabled': False, 'trigger': 'macd_cross_signal'}, 'sell': {'sell-mfi-value': 87, 'sell-fastd-value': 82, 'sell-adx-value': 78, 'sell-rsi-value': 69, 'sell-mfi-enabled': True, 'sell-fastd-enabled': False, 'sell-adx-enabled': True, 'sell-rsi-enabled': False, 'sell-trigger': 'sell-macd_cross_signal'}, 'roi': {0: 0.3077646493708299, 444: 0.16227697603830155, 1045: 0.07280999507931168, 2314: 0}, 'stoploss': {'stoploss': -0.18181041180901014}}, # noqa: E501
|
||||
'results_metrics': {'trade_count': 14, 'avg_profit': -0.3539515, 'median_profit': -1.2222, 'total_profit': -0.002480140000000001, 'profit': -4.955321, 'duration': 3402.8571428571427}, # noqa: E501
|
||||
'results_explanation': ' 14 trades. Avg profit -0.35%. Total profit -0.00248014 BTC ( -4.96Σ%). Avg duration 3402.9 min.', # noqa: E501
|
||||
'total_profit': -0.002480140000000001,
|
||||
'current_epoch': 5,
|
||||
'is_initial_point': True,
|
||||
'is_best': True
|
||||
}, {
|
||||
'loss': 0.545315889154162,
|
||||
'params_dict': {'mfi-value': 22, 'fastd-value': 43, 'adx-value': 46, 'rsi-value': 20, 'mfi-enabled': False, 'fastd-enabled': False, 'adx-enabled': True, 'rsi-enabled': True, 'trigger': 'bb_lower', 'sell-mfi-value': 87, 'sell-fastd-value': 65, 'sell-adx-value': 94, 'sell-rsi-value': 63, 'sell-mfi-enabled': False, 'sell-fastd-enabled': True, 'sell-adx-enabled': True, 'sell-rsi-enabled': True, 'sell-trigger': 'sell-macd_cross_signal', 'roi_t1': 319, 'roi_t2': 556, 'roi_t3': 216, 'roi_p1': 0.06251955472249589, 'roi_p2': 0.11659519602202795, 'roi_p3': 0.0953744132197762, 'stoploss': -0.024551752215582423}, # noqa: E501
|
||||
'params_details': {'buy': {'mfi-value': 22, 'fastd-value': 43, 'adx-value': 46, 'rsi-value': 20, 'mfi-enabled': False, 'fastd-enabled': False, 'adx-enabled': True, 'rsi-enabled': True, 'trigger': 'bb_lower'}, 'sell': {'sell-mfi-value': 87, 'sell-fastd-value': 65, 'sell-adx-value': 94, 'sell-rsi-value': 63, 'sell-mfi-enabled': False, 'sell-fastd-enabled': True, 'sell-adx-enabled': True, 'sell-rsi-enabled': True, 'sell-trigger': 'sell-macd_cross_signal'}, 'roi': {0: 0.2744891639643, 216: 0.17911475074452382, 772: 0.06251955472249589, 1091: 0}, 'stoploss': {'stoploss': -0.024551752215582423}}, # noqa: E501
|
||||
'results_metrics': {'trade_count': 39, 'avg_profit': -0.21400679487179478, 'median_profit': -1.2222, 'total_profit': -0.0041773, 'profit': -8.346264999999997, 'duration': 636.9230769230769}, # noqa: E501
|
||||
'results_explanation': ' 39 trades. Avg profit -0.21%. Total profit -0.00417730 BTC ( -8.35Σ%). Avg duration 636.9 min.', # noqa: E501
|
||||
'total_profit': -0.0041773,
|
||||
'current_epoch': 6,
|
||||
'is_initial_point': True,
|
||||
'is_best': False
|
||||
}, {
|
||||
'loss': 4.713497421432944,
|
||||
'params_dict': {'mfi-value': 13, 'fastd-value': 41, 'adx-value': 21, 'rsi-value': 29, 'mfi-enabled': False, 'fastd-enabled': True, 'adx-enabled': False, 'rsi-enabled': False, 'trigger': 'bb_lower', 'sell-mfi-value': 99, 'sell-fastd-value': 60, 'sell-adx-value': 81, 'sell-rsi-value': 69, 'sell-mfi-enabled': True, 'sell-fastd-enabled': True, 'sell-adx-enabled': True, 'sell-rsi-enabled': False, 'sell-trigger': 'sell-macd_cross_signal', 'roi_t1': 771, 'roi_t2': 620, 'roi_t3': 145, 'roi_p1': 0.0586919200378493, 'roi_p2': 0.04984118697312542, 'roi_p3': 0.37521058680247044, 'stoploss': -0.14613268022709905}, # noqa: E501
|
||||
'params_details': {
|
||||
'buy': {'mfi-value': 13, 'fastd-value': 41, 'adx-value': 21, 'rsi-value': 29, 'mfi-enabled': False, 'fastd-enabled': True, 'adx-enabled': False, 'rsi-enabled': False, 'trigger': 'bb_lower'}, 'sell': {'sell-mfi-value': 99, 'sell-fastd-value': 60, 'sell-adx-value': 81, 'sell-rsi-value': 69, 'sell-mfi-enabled': True, 'sell-fastd-enabled': True, 'sell-adx-enabled': True, 'sell-rsi-enabled': False, 'sell-trigger': 'sell-macd_cross_signal'}, 'roi': {0: 0.4837436938134452, 145: 0.10853310701097472, 765: 0.0586919200378493, 1536: 0}, # noqa: E501
|
||||
'stoploss': {'stoploss': -0.14613268022709905}}, # noqa: E501
|
||||
'results_metrics': {'trade_count': 318, 'avg_profit': -0.39833954716981146, 'median_profit': -1.2222, 'total_profit': -0.06339929, 'profit': -126.67197600000004, 'duration': 3140.377358490566}, # noqa: E501
|
||||
'results_explanation': ' 318 trades. Avg profit -0.40%. Total profit -0.06339929 BTC (-126.67Σ%). Avg duration 3140.4 min.', # noqa: E501
|
||||
'total_profit': -0.06339929,
|
||||
'current_epoch': 7,
|
||||
'is_initial_point': True,
|
||||
'is_best': False
|
||||
}, {
|
||||
'loss': 20.0, # noqa: E501
|
||||
'params_dict': {'mfi-value': 24, 'fastd-value': 43, 'adx-value': 33, 'rsi-value': 20, 'mfi-enabled': False, 'fastd-enabled': True, 'adx-enabled': True, 'rsi-enabled': True, 'trigger': 'sar_reversal', 'sell-mfi-value': 89, 'sell-fastd-value': 74, 'sell-adx-value': 70, 'sell-rsi-value': 70, 'sell-mfi-enabled': False, 'sell-fastd-enabled': False, 'sell-adx-enabled': False, 'sell-rsi-enabled': True, 'sell-trigger': 'sell-sar_reversal', 'roi_t1': 1149, 'roi_t2': 375, 'roi_t3': 289, 'roi_p1': 0.05571820757172588, 'roi_p2': 0.0606240398618907, 'roi_p3': 0.1729012220156157, 'stoploss': -0.1588514289110401}, # noqa: E501
|
||||
'params_details': {'buy': {'mfi-value': 24, 'fastd-value': 43, 'adx-value': 33, 'rsi-value': 20, 'mfi-enabled': False, 'fastd-enabled': True, 'adx-enabled': True, 'rsi-enabled': True, 'trigger': 'sar_reversal'}, 'sell': {'sell-mfi-value': 89, 'sell-fastd-value': 74, 'sell-adx-value': 70, 'sell-rsi-value': 70, 'sell-mfi-enabled': False, 'sell-fastd-enabled': False, 'sell-adx-enabled': False, 'sell-rsi-enabled': True, 'sell-trigger': 'sell-sar_reversal'}, 'roi': {0: 0.2892434694492323, 289: 0.11634224743361658, 664: 0.05571820757172588, 1813: 0}, 'stoploss': {'stoploss': -0.1588514289110401}}, # noqa: E501
|
||||
'results_metrics': {'trade_count': 1, 'avg_profit': 0.0, 'median_profit': 0.0, 'total_profit': 0.0, 'profit': 0.0, 'duration': 5340.0}, # noqa: E501
|
||||
'results_explanation': ' 1 trades. Avg profit 0.00%. Total profit 0.00000000 BTC ( 0.00Σ%). Avg duration 5340.0 min.', # noqa: E501
|
||||
'total_profit': 0.0,
|
||||
'current_epoch': 8,
|
||||
'is_initial_point': True,
|
||||
'is_best': False
|
||||
}, {
|
||||
'loss': 2.4731817780991223,
|
||||
'params_dict': {'mfi-value': 22, 'fastd-value': 20, 'adx-value': 29, 'rsi-value': 40, 'mfi-enabled': False, 'fastd-enabled': False, 'adx-enabled': False, 'rsi-enabled': False, 'trigger': 'sar_reversal', 'sell-mfi-value': 97, 'sell-fastd-value': 65, 'sell-adx-value': 81, 'sell-rsi-value': 64, 'sell-mfi-enabled': True, 'sell-fastd-enabled': True, 'sell-adx-enabled': True, 'sell-rsi-enabled': True, 'sell-trigger': 'sell-bb_upper', 'roi_t1': 1012, 'roi_t2': 584, 'roi_t3': 422, 'roi_p1': 0.036764323603472565, 'roi_p2': 0.10335480573205287, 'roi_p3': 0.10322347377503042, 'stoploss': -0.2780610808108503}, # noqa: E501
|
||||
'params_details': {'buy': {'mfi-value': 22, 'fastd-value': 20, 'adx-value': 29, 'rsi-value': 40, 'mfi-enabled': False, 'fastd-enabled': False, 'adx-enabled': False, 'rsi-enabled': False, 'trigger': 'sar_reversal'}, 'sell': {'sell-mfi-value': 97, 'sell-fastd-value': 65, 'sell-adx-value': 81, 'sell-rsi-value': 64, 'sell-mfi-enabled': True, 'sell-fastd-enabled': True, 'sell-adx-enabled': True, 'sell-rsi-enabled': True, 'sell-trigger': 'sell-bb_upper'}, 'roi': {0: 0.2433426031105559, 422: 0.14011912933552545, 1006: 0.036764323603472565, 2018: 0}, 'stoploss': {'stoploss': -0.2780610808108503}}, # noqa: E501
|
||||
'results_metrics': {'trade_count': 229, 'avg_profit': -0.38433433624454144, 'median_profit': -1.2222, 'total_profit': -0.044050070000000004, 'profit': -88.01256299999999, 'duration': 6505.676855895196}, # noqa: E501
|
||||
'results_explanation': ' 229 trades. Avg profit -0.38%. Total profit -0.04405007 BTC ( -88.01Σ%). Avg duration 6505.7 min.', # noqa: E501
|
||||
'total_profit': -0.044050070000000004, # noqa: E501
|
||||
'current_epoch': 9,
|
||||
'is_initial_point': True,
|
||||
'is_best': False
|
||||
}, {
|
||||
'loss': -0.2604606005845212, # noqa: E501
|
||||
'params_dict': {'mfi-value': 23, 'fastd-value': 24, 'adx-value': 22, 'rsi-value': 24, 'mfi-enabled': False, 'fastd-enabled': False, 'adx-enabled': False, 'rsi-enabled': True, 'trigger': 'macd_cross_signal', 'sell-mfi-value': 97, 'sell-fastd-value': 70, 'sell-adx-value': 64, 'sell-rsi-value': 80, 'sell-mfi-enabled': False, 'sell-fastd-enabled': True, 'sell-adx-enabled': True, 'sell-rsi-enabled': True, 'sell-trigger': 'sell-sar_reversal', 'roi_t1': 792, 'roi_t2': 464, 'roi_t3': 215, 'roi_p1': 0.04594053535385903, 'roi_p2': 0.09623192684243963, 'roi_p3': 0.04428219070850663, 'stoploss': -0.16992287161634415}, # noqa: E501
|
||||
'params_details': {'buy': {'mfi-value': 23, 'fastd-value': 24, 'adx-value': 22, 'rsi-value': 24, 'mfi-enabled': False, 'fastd-enabled': False, 'adx-enabled': False, 'rsi-enabled': True, 'trigger': 'macd_cross_signal'}, 'sell': {'sell-mfi-value': 97, 'sell-fastd-value': 70, 'sell-adx-value': 64, 'sell-rsi-value': 80, 'sell-mfi-enabled': False, 'sell-fastd-enabled': True, 'sell-adx-enabled': True, 'sell-rsi-enabled': True, 'sell-trigger': 'sell-sar_reversal'}, 'roi': {0: 0.18645465290480528, 215: 0.14217246219629864, 679: 0.04594053535385903, 1471: 0}, 'stoploss': {'stoploss': -0.16992287161634415}}, # noqa: E501
|
||||
'results_metrics': {'trade_count': 4, 'avg_profit': 0.1080385, 'median_profit': -1.2222, 'total_profit': 0.00021629, 'profit': 0.432154, 'duration': 2850.0}, # noqa: E501
|
||||
'results_explanation': ' 4 trades. Avg profit 0.11%. Total profit 0.00021629 BTC ( 0.43Σ%). Avg duration 2850.0 min.', # noqa: E501
|
||||
'total_profit': 0.00021629,
|
||||
'current_epoch': 10,
|
||||
'is_initial_point': True,
|
||||
'is_best': True
|
||||
}, {
|
||||
'loss': 4.876465945994304, # noqa: E501
|
||||
'params_dict': {'mfi-value': 20, 'fastd-value': 32, 'adx-value': 49, 'rsi-value': 23, 'mfi-enabled': True, 'fastd-enabled': True, 'adx-enabled': False, 'rsi-enabled': False, 'trigger': 'bb_lower', 'sell-mfi-value': 75, 'sell-fastd-value': 56, 'sell-adx-value': 61, 'sell-rsi-value': 62, 'sell-mfi-enabled': False, 'sell-fastd-enabled': False, 'sell-adx-enabled': True, 'sell-rsi-enabled': True, 'sell-trigger': 'sell-macd_cross_signal', 'roi_t1': 579, 'roi_t2': 614, 'roi_t3': 273, 'roi_p1': 0.05307643172744114, 'roi_p2': 0.1352282078262871, 'roi_p3': 0.1913307406325751, 'stoploss': -0.25728526022513887}, # noqa: E501
|
||||
'params_details': {'buy': {'mfi-value': 20, 'fastd-value': 32, 'adx-value': 49, 'rsi-value': 23, 'mfi-enabled': True, 'fastd-enabled': True, 'adx-enabled': False, 'rsi-enabled': False, 'trigger': 'bb_lower'}, 'sell': {'sell-mfi-value': 75, 'sell-fastd-value': 56, 'sell-adx-value': 61, 'sell-rsi-value': 62, 'sell-mfi-enabled': False, 'sell-fastd-enabled': False, 'sell-adx-enabled': True, 'sell-rsi-enabled': True, 'sell-trigger': 'sell-macd_cross_signal'}, 'roi': {0: 0.3796353801863034, 273: 0.18830463955372825, 887: 0.05307643172744114, 1466: 0}, 'stoploss': {'stoploss': -0.25728526022513887}}, # noqa: E501
|
||||
'results_metrics': {'trade_count': 117, 'avg_profit': -1.2698609145299145, 'median_profit': -1.2222, 'total_profit': -0.07436117, 'profit': -148.573727, 'duration': 4282.5641025641025}, # noqa: E501
|
||||
'results_explanation': ' 117 trades. Avg profit -1.27%. Total profit -0.07436117 BTC (-148.57Σ%). Avg duration 4282.6 min.', # noqa: E501
|
||||
'total_profit': -0.07436117,
|
||||
'current_epoch': 11,
|
||||
'is_initial_point': True,
|
||||
'is_best': False
|
||||
}, {
|
||||
'loss': 100000,
|
||||
'params_dict': {'mfi-value': 10, 'fastd-value': 36, 'adx-value': 31, 'rsi-value': 22, 'mfi-enabled': True, 'fastd-enabled': True, 'adx-enabled': True, 'rsi-enabled': False, 'trigger': 'sar_reversal', 'sell-mfi-value': 80, 'sell-fastd-value': 71, 'sell-adx-value': 60, 'sell-rsi-value': 85, 'sell-mfi-enabled': False, 'sell-fastd-enabled': False, 'sell-adx-enabled': True, 'sell-rsi-enabled': True, 'sell-trigger': 'sell-bb_upper', 'roi_t1': 1156, 'roi_t2': 581, 'roi_t3': 408, 'roi_p1': 0.06860454019988212, 'roi_p2': 0.12473718444931989, 'roi_p3': 0.2896360635226823, 'stoploss': -0.30889015124682806}, # noqa: E501
|
||||
'params_details': {'buy': {'mfi-value': 10, 'fastd-value': 36, 'adx-value': 31, 'rsi-value': 22, 'mfi-enabled': True, 'fastd-enabled': True, 'adx-enabled': True, 'rsi-enabled': False, 'trigger': 'sar_reversal'}, 'sell': {'sell-mfi-value': 80, 'sell-fastd-value': 71, 'sell-adx-value': 60, 'sell-rsi-value': 85, 'sell-mfi-enabled': False, 'sell-fastd-enabled': False, 'sell-adx-enabled': True, 'sell-rsi-enabled': True, 'sell-trigger': 'sell-bb_upper'}, 'roi': {0: 0.4829777881718843, 408: 0.19334172464920202, 989: 0.06860454019988212, 2145: 0}, 'stoploss': {'stoploss': -0.30889015124682806}}, # noqa: E501
|
||||
'results_metrics': {'trade_count': 0, 'avg_profit': None, 'median_profit': None, 'total_profit': 0, 'profit': 0.0, 'duration': None}, # noqa: E501
|
||||
'results_explanation': ' 0 trades. Avg profit nan%. Total profit 0.00000000 BTC ( 0.00Σ%). Avg duration nan min.', # noqa: E501
|
||||
'total_profit': 0,
|
||||
'current_epoch': 12,
|
||||
'is_initial_point': True,
|
||||
'is_best': False
|
||||
}
|
||||
]
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def saved_hyperopt_results():
|
||||
hyperopt_res = [
|
||||
|
@@ -381,7 +381,7 @@ def test_get_timerange(default_conf, mocker, testdatadir) -> None:
|
||||
default_conf.update({'strategy': 'DefaultStrategy'})
|
||||
strategy = StrategyResolver.load_strategy(default_conf)
|
||||
|
||||
data = strategy.ohlcvdata_to_dataframe(
|
||||
data = strategy.advise_all_indicators(
|
||||
load_data(
|
||||
datadir=testdatadir,
|
||||
timeframe='1m',
|
||||
@@ -399,7 +399,7 @@ def test_validate_backtest_data_warn(default_conf, mocker, caplog, testdatadir)
|
||||
default_conf.update({'strategy': 'DefaultStrategy'})
|
||||
strategy = StrategyResolver.load_strategy(default_conf)
|
||||
|
||||
data = strategy.ohlcvdata_to_dataframe(
|
||||
data = strategy.advise_all_indicators(
|
||||
load_data(
|
||||
datadir=testdatadir,
|
||||
timeframe='1m',
|
||||
@@ -424,7 +424,7 @@ def test_validate_backtest_data(default_conf, mocker, caplog, testdatadir) -> No
|
||||
strategy = StrategyResolver.load_strategy(default_conf)
|
||||
|
||||
timerange = TimeRange('index', 'index', 200, 250)
|
||||
data = strategy.ohlcvdata_to_dataframe(
|
||||
data = strategy.advise_all_indicators(
|
||||
load_data(
|
||||
datadir=testdatadir,
|
||||
timeframe='5m',
|
||||
|
@@ -984,16 +984,21 @@ def test_create_dry_run_order_limit_fill(default_conf, mocker, side, startprice,
|
||||
assert order['fee']
|
||||
|
||||
|
||||
@pytest.mark.parametrize("side,amount,endprice", [
|
||||
("buy", 1, 25.566),
|
||||
("buy", 100, 25.5672), # Requires interpolation
|
||||
("buy", 1000, 25.575), # More than orderbook return
|
||||
("sell", 1, 25.563),
|
||||
("sell", 100, 25.5625), # Requires interpolation
|
||||
("sell", 1000, 25.5555), # More than orderbook return
|
||||
@pytest.mark.parametrize("side,rate,amount,endprice", [
|
||||
# spread is 25.263-25.266
|
||||
("buy", 25.564, 1, 25.566),
|
||||
("buy", 25.564, 100, 25.5672), # Requires interpolation
|
||||
("buy", 25.590, 100, 25.5672), # Price above spread ... average is lower
|
||||
("buy", 25.564, 1000, 25.575), # More than orderbook return
|
||||
("buy", 24.000, 100000, 25.200), # Run into max_slippage of 5%
|
||||
("sell", 25.564, 1, 25.563),
|
||||
("sell", 25.564, 100, 25.5625), # Requires interpolation
|
||||
("sell", 25.510, 100, 25.5625), # price below spread - average is higher
|
||||
("sell", 25.564, 1000, 25.5555), # More than orderbook return
|
||||
("sell", 27, 10000, 25.65), # max-slippage 5%
|
||||
])
|
||||
@pytest.mark.parametrize("exchange_name", EXCHANGES)
|
||||
def test_create_dry_run_order_market_fill(default_conf, mocker, side, amount, endprice,
|
||||
def test_create_dry_run_order_market_fill(default_conf, mocker, side, rate, amount, endprice,
|
||||
exchange_name, order_book_l2_usd):
|
||||
default_conf['dry_run'] = True
|
||||
exchange = get_patched_exchange(mocker, default_conf, id=exchange_name)
|
||||
@@ -1003,7 +1008,7 @@ def test_create_dry_run_order_market_fill(default_conf, mocker, side, amount, en
|
||||
)
|
||||
|
||||
order = exchange.create_dry_run_order(
|
||||
pair='LTC/USDT', ordertype='market', side=side, amount=amount, rate=25.5)
|
||||
pair='LTC/USDT', ordertype='market', side=side, amount=amount, rate=rate)
|
||||
assert 'id' in order
|
||||
assert f'dry_run_{side}_' in order["id"]
|
||||
assert order["side"] == side
|
||||
|
@@ -52,4 +52,6 @@ def _build_backtest_dataframe(data):
|
||||
# Ensure floats are in place
|
||||
for column in ['open', 'high', 'low', 'close', 'volume']:
|
||||
frame[column] = frame[column].astype('float64')
|
||||
if 'buy_tag' not in columns:
|
||||
frame['buy_tag'] = None
|
||||
return frame
|
||||
|
@@ -1,6 +1,7 @@
|
||||
# pragma pylint: disable=missing-docstring, W0212, line-too-long, C0103, unused-argument
|
||||
|
||||
import random
|
||||
from datetime import timedelta
|
||||
from pathlib import Path
|
||||
from unittest.mock import MagicMock, PropertyMock
|
||||
|
||||
@@ -85,7 +86,7 @@ def simple_backtest(config, contour, mocker, testdatadir) -> None:
|
||||
backtesting._set_strategy(backtesting.strategylist[0])
|
||||
|
||||
data = load_data_test(contour, testdatadir)
|
||||
processed = backtesting.strategy.ohlcvdata_to_dataframe(data)
|
||||
processed = backtesting.strategy.advise_all_indicators(data)
|
||||
min_date, max_date = get_timerange(processed)
|
||||
assert isinstance(processed, dict)
|
||||
results = backtesting.backtest(
|
||||
@@ -107,7 +108,7 @@ def _make_backtest_conf(mocker, datadir, conf=None, pair='UNITTEST/BTC'):
|
||||
patch_exchange(mocker)
|
||||
backtesting = Backtesting(conf)
|
||||
backtesting._set_strategy(backtesting.strategylist[0])
|
||||
processed = backtesting.strategy.ohlcvdata_to_dataframe(data)
|
||||
processed = backtesting.strategy.advise_all_indicators(data)
|
||||
min_date, max_date = get_timerange(processed)
|
||||
return {
|
||||
'processed': processed,
|
||||
@@ -289,7 +290,7 @@ def test_backtesting_init(mocker, default_conf, order_types) -> None:
|
||||
backtesting._set_strategy(backtesting.strategylist[0])
|
||||
assert backtesting.config == default_conf
|
||||
assert backtesting.timeframe == '5m'
|
||||
assert callable(backtesting.strategy.ohlcvdata_to_dataframe)
|
||||
assert callable(backtesting.strategy.advise_all_indicators)
|
||||
assert callable(backtesting.strategy.advise_buy)
|
||||
assert callable(backtesting.strategy.advise_sell)
|
||||
assert isinstance(backtesting.strategy.dp, DataProvider)
|
||||
@@ -335,14 +336,14 @@ def test_data_to_dataframe_bt(default_conf, mocker, testdatadir) -> None:
|
||||
fill_up_missing=True)
|
||||
backtesting = Backtesting(default_conf)
|
||||
backtesting._set_strategy(backtesting.strategylist[0])
|
||||
processed = backtesting.strategy.ohlcvdata_to_dataframe(data)
|
||||
processed = backtesting.strategy.advise_all_indicators(data)
|
||||
assert len(processed['UNITTEST/BTC']) == 102
|
||||
|
||||
# Load strategy to compare the result between Backtesting function and strategy are the same
|
||||
default_conf.update({'strategy': 'DefaultStrategy'})
|
||||
strategy = StrategyResolver.load_strategy(default_conf)
|
||||
|
||||
processed2 = strategy.ohlcvdata_to_dataframe(data)
|
||||
processed2 = strategy.advise_all_indicators(data)
|
||||
assert processed['UNITTEST/BTC'].equals(processed2['UNITTEST/BTC'])
|
||||
|
||||
|
||||
@@ -535,6 +536,8 @@ def test_backtest__enter_trade(default_conf, fee, mocker) -> None:
|
||||
trade = backtesting._enter_trade(pair, row=row)
|
||||
assert trade is None
|
||||
|
||||
backtesting.cleanup()
|
||||
|
||||
|
||||
def test_backtest_one(default_conf, fee, mocker, testdatadir) -> None:
|
||||
default_conf['use_sell_signal'] = False
|
||||
@@ -547,7 +550,7 @@ def test_backtest_one(default_conf, fee, mocker, testdatadir) -> None:
|
||||
timerange = TimeRange('date', None, 1517227800, 0)
|
||||
data = history.load_data(datadir=testdatadir, timeframe='5m', pairs=['UNITTEST/BTC'],
|
||||
timerange=timerange)
|
||||
processed = backtesting.strategy.ohlcvdata_to_dataframe(data)
|
||||
processed = backtesting.strategy.advise_all_indicators(data)
|
||||
min_date, max_date = get_timerange(processed)
|
||||
result = backtesting.backtest(
|
||||
processed=processed,
|
||||
@@ -581,7 +584,7 @@ def test_backtest_one(default_conf, fee, mocker, testdatadir) -> None:
|
||||
'initial_stop_loss_ratio': [-0.1, -0.1],
|
||||
'stop_loss_abs': [0.0940005, 0.09272236],
|
||||
'stop_loss_ratio': [-0.1, -0.1],
|
||||
'min_rate': [0.1038, 0.10302485],
|
||||
'min_rate': [0.10370188, 0.10300000000000001],
|
||||
'max_rate': [0.10501, 0.1038888],
|
||||
'is_open': [False, False],
|
||||
'buy_tag': [None, None],
|
||||
@@ -612,7 +615,7 @@ def test_backtest_1min_timeframe(default_conf, fee, mocker, testdatadir) -> None
|
||||
timerange = TimeRange.parse_timerange('1510688220-1510700340')
|
||||
data = history.load_data(datadir=testdatadir, timeframe='1m', pairs=['UNITTEST/BTC'],
|
||||
timerange=timerange)
|
||||
processed = backtesting.strategy.ohlcvdata_to_dataframe(data)
|
||||
processed = backtesting.strategy.advise_all_indicators(data)
|
||||
min_date, max_date = get_timerange(processed)
|
||||
results = backtesting.backtest(
|
||||
processed=processed,
|
||||
@@ -631,7 +634,7 @@ def test_processed(default_conf, mocker, testdatadir) -> None:
|
||||
backtesting._set_strategy(backtesting.strategylist[0])
|
||||
|
||||
dict_of_tickerrows = load_data_test('raise', testdatadir)
|
||||
dataframes = backtesting.strategy.ohlcvdata_to_dataframe(dict_of_tickerrows)
|
||||
dataframes = backtesting.strategy.advise_all_indicators(dict_of_tickerrows)
|
||||
dataframe = dataframes['UNITTEST/BTC']
|
||||
cols = dataframe.columns
|
||||
# assert the dataframe got some of the indicator columns
|
||||
@@ -739,8 +742,13 @@ def test_backtest_alternate_buy_sell(default_conf, fee, mocker, testdatadir):
|
||||
# 100 buys signals
|
||||
results = result['results']
|
||||
assert len(results) == 100
|
||||
# Cached data should be 200 (no change since required_startup is 0)
|
||||
assert len(backtesting.dataprovider.get_analyzed_dataframe('UNITTEST/BTC', '1m')[0]) == 200
|
||||
# Cached data should be 200
|
||||
analyzed_df = backtesting.dataprovider.get_analyzed_dataframe('UNITTEST/BTC', '1m')[0]
|
||||
assert len(analyzed_df) == 200
|
||||
# Expect last candle to be 1 below end date (as the last candle is assumed as "incomplete"
|
||||
# during backtesting)
|
||||
expected_last_candle_date = backtest_conf['end_date'] - timedelta(minutes=1)
|
||||
assert analyzed_df.iloc[-1]['date'].to_pydatetime() == expected_last_candle_date
|
||||
|
||||
# One trade was force-closed at the end
|
||||
assert len(results.loc[results['is_open']]) == 0
|
||||
@@ -772,7 +780,8 @@ def test_backtest_multi_pair(default_conf, fee, mocker, tres, pair, testdatadir)
|
||||
data = trim_dictlist(data, -500)
|
||||
|
||||
# Remove data for one pair from the beginning of the data
|
||||
data[pair] = data[pair][tres:].reset_index()
|
||||
if tres > 0:
|
||||
data[pair] = data[pair][tres:].reset_index()
|
||||
default_conf['timeframe'] = '5m'
|
||||
|
||||
backtesting = Backtesting(default_conf)
|
||||
@@ -780,7 +789,7 @@ def test_backtest_multi_pair(default_conf, fee, mocker, tres, pair, testdatadir)
|
||||
backtesting.strategy.advise_buy = _trend_alternate_hold # Override
|
||||
backtesting.strategy.advise_sell = _trend_alternate_hold # Override
|
||||
|
||||
processed = backtesting.strategy.ohlcvdata_to_dataframe(data)
|
||||
processed = backtesting.strategy.advise_all_indicators(data)
|
||||
min_date, max_date = get_timerange(processed)
|
||||
backtest_conf = {
|
||||
'processed': processed,
|
||||
@@ -798,8 +807,11 @@ def test_backtest_multi_pair(default_conf, fee, mocker, tres, pair, testdatadir)
|
||||
assert len(evaluate_result_multi(results['results'], '5m', 3)) == 0
|
||||
|
||||
# Cached data correctly removed amounts
|
||||
removed_candles = len(data[pair]) - 1 - backtesting.strategy.startup_candle_count
|
||||
offset = 1 if tres == 0 else 0
|
||||
removed_candles = len(data[pair]) - offset - backtesting.strategy.startup_candle_count
|
||||
assert len(backtesting.dataprovider.get_analyzed_dataframe(pair, '5m')[0]) == removed_candles
|
||||
assert len(backtesting.dataprovider.get_analyzed_dataframe(
|
||||
'NXT/BTC', '5m')[0]) == len(data['NXT/BTC']) - 1 - backtesting.strategy.startup_candle_count
|
||||
|
||||
backtest_conf = {
|
||||
'processed': processed,
|
||||
|
@@ -351,7 +351,7 @@ def test_start_calls_optimizer(mocker, hyperopt_conf, capsys) -> None:
|
||||
del hyperopt_conf['timeframe']
|
||||
|
||||
hyperopt = Hyperopt(hyperopt_conf)
|
||||
hyperopt.backtesting.strategy.ohlcvdata_to_dataframe = MagicMock()
|
||||
hyperopt.backtesting.strategy.advise_all_indicators = MagicMock()
|
||||
hyperopt.custom_hyperopt.generate_roi_table = MagicMock(return_value={})
|
||||
|
||||
hyperopt.start()
|
||||
@@ -399,7 +399,7 @@ def test_hyperopt_format_results(hyperopt):
|
||||
'rejected_signals': 2,
|
||||
'backtest_start_time': 1619718665,
|
||||
'backtest_end_time': 1619718665,
|
||||
}
|
||||
}
|
||||
results_metrics = generate_strategy_stats({'XRP/BTC': None}, '', bt_result,
|
||||
Arrow(2017, 11, 14, 19, 32, 00),
|
||||
Arrow(2017, 12, 14, 19, 32, 00), market_change=0)
|
||||
@@ -426,7 +426,7 @@ def test_hyperopt_format_results(hyperopt):
|
||||
|
||||
def test_populate_indicators(hyperopt, testdatadir) -> None:
|
||||
data = load_data(testdatadir, '1m', ['UNITTEST/BTC'], fill_up_missing=True)
|
||||
dataframes = hyperopt.backtesting.strategy.ohlcvdata_to_dataframe(data)
|
||||
dataframes = hyperopt.backtesting.strategy.advise_all_indicators(data)
|
||||
dataframe = hyperopt.custom_hyperopt.populate_indicators(dataframes['UNITTEST/BTC'],
|
||||
{'pair': 'UNITTEST/BTC'})
|
||||
|
||||
@@ -438,7 +438,7 @@ def test_populate_indicators(hyperopt, testdatadir) -> None:
|
||||
|
||||
def test_buy_strategy_generator(hyperopt, testdatadir) -> None:
|
||||
data = load_data(testdatadir, '1m', ['UNITTEST/BTC'], fill_up_missing=True)
|
||||
dataframes = hyperopt.backtesting.strategy.ohlcvdata_to_dataframe(data)
|
||||
dataframes = hyperopt.backtesting.strategy.advise_all_indicators(data)
|
||||
dataframe = hyperopt.custom_hyperopt.populate_indicators(dataframes['UNITTEST/BTC'],
|
||||
{'pair': 'UNITTEST/BTC'})
|
||||
|
||||
@@ -463,7 +463,7 @@ def test_buy_strategy_generator(hyperopt, testdatadir) -> None:
|
||||
|
||||
def test_sell_strategy_generator(hyperopt, testdatadir) -> None:
|
||||
data = load_data(testdatadir, '1m', ['UNITTEST/BTC'], fill_up_missing=True)
|
||||
dataframes = hyperopt.backtesting.strategy.ohlcvdata_to_dataframe(data)
|
||||
dataframes = hyperopt.backtesting.strategy.advise_all_indicators(data)
|
||||
dataframe = hyperopt.custom_hyperopt.populate_indicators(dataframes['UNITTEST/BTC'],
|
||||
{'pair': 'UNITTEST/BTC'})
|
||||
|
||||
@@ -577,6 +577,7 @@ def test_generate_optimizer(mocker, hyperopt_conf) -> None:
|
||||
"20.0": 0.02,
|
||||
"50.0": 0.01,
|
||||
"110.0": 0},
|
||||
'protection': {},
|
||||
'sell': {'sell-adx-enabled': False,
|
||||
'sell-adx-value': 0,
|
||||
'sell-fastd-enabled': True,
|
||||
@@ -592,7 +593,7 @@ def test_generate_optimizer(mocker, hyperopt_conf) -> None:
|
||||
'trailing_stop_positive': 0.02,
|
||||
'trailing_stop_positive_offset': 0.07}},
|
||||
'params_dict': optimizer_param,
|
||||
'params_not_optimized': {'buy': {}, 'sell': {}},
|
||||
'params_not_optimized': {'buy': {}, 'protection': {}, 'sell': {}},
|
||||
'results_metrics': ANY,
|
||||
'total_profit': 3.1e-08
|
||||
}
|
||||
@@ -659,7 +660,7 @@ def test_print_json_spaces_all(mocker, hyperopt_conf, capsys) -> None:
|
||||
})
|
||||
|
||||
hyperopt = Hyperopt(hyperopt_conf)
|
||||
hyperopt.backtesting.strategy.ohlcvdata_to_dataframe = MagicMock()
|
||||
hyperopt.backtesting.strategy.advise_all_indicators = MagicMock()
|
||||
hyperopt.custom_hyperopt.generate_roi_table = MagicMock(return_value={})
|
||||
|
||||
hyperopt.start()
|
||||
@@ -712,7 +713,7 @@ def test_print_json_spaces_default(mocker, hyperopt_conf, capsys) -> None:
|
||||
hyperopt_conf.update({'print_json': True})
|
||||
|
||||
hyperopt = Hyperopt(hyperopt_conf)
|
||||
hyperopt.backtesting.strategy.ohlcvdata_to_dataframe = MagicMock()
|
||||
hyperopt.backtesting.strategy.advise_all_indicators = MagicMock()
|
||||
hyperopt.custom_hyperopt.generate_roi_table = MagicMock(return_value={})
|
||||
|
||||
hyperopt.start()
|
||||
@@ -760,7 +761,7 @@ def test_print_json_spaces_roi_stoploss(mocker, hyperopt_conf, capsys) -> None:
|
||||
})
|
||||
|
||||
hyperopt = Hyperopt(hyperopt_conf)
|
||||
hyperopt.backtesting.strategy.ohlcvdata_to_dataframe = MagicMock()
|
||||
hyperopt.backtesting.strategy.advise_all_indicators = MagicMock()
|
||||
hyperopt.custom_hyperopt.generate_roi_table = MagicMock(return_value={})
|
||||
|
||||
hyperopt.start()
|
||||
@@ -804,7 +805,7 @@ def test_simplified_interface_roi_stoploss(mocker, hyperopt_conf, capsys) -> Non
|
||||
hyperopt_conf.update({'spaces': 'roi stoploss'})
|
||||
|
||||
hyperopt = Hyperopt(hyperopt_conf)
|
||||
hyperopt.backtesting.strategy.ohlcvdata_to_dataframe = MagicMock()
|
||||
hyperopt.backtesting.strategy.advise_all_indicators = MagicMock()
|
||||
hyperopt.custom_hyperopt.generate_roi_table = MagicMock(return_value={})
|
||||
|
||||
del hyperopt.custom_hyperopt.__class__.buy_strategy_generator
|
||||
@@ -843,7 +844,7 @@ def test_simplified_interface_all_failed(mocker, hyperopt_conf) -> None:
|
||||
hyperopt_conf.update({'spaces': 'all', })
|
||||
|
||||
hyperopt = Hyperopt(hyperopt_conf)
|
||||
hyperopt.backtesting.strategy.ohlcvdata_to_dataframe = MagicMock()
|
||||
hyperopt.backtesting.strategy.advise_all_indicators = MagicMock()
|
||||
hyperopt.custom_hyperopt.generate_roi_table = MagicMock(return_value={})
|
||||
|
||||
del hyperopt.custom_hyperopt.__class__.buy_strategy_generator
|
||||
@@ -885,7 +886,7 @@ def test_simplified_interface_buy(mocker, hyperopt_conf, capsys) -> None:
|
||||
hyperopt_conf.update({'spaces': 'buy'})
|
||||
|
||||
hyperopt = Hyperopt(hyperopt_conf)
|
||||
hyperopt.backtesting.strategy.ohlcvdata_to_dataframe = MagicMock()
|
||||
hyperopt.backtesting.strategy.advise_all_indicators = MagicMock()
|
||||
hyperopt.custom_hyperopt.generate_roi_table = MagicMock(return_value={})
|
||||
|
||||
# TODO: sell_strategy_generator() is actually not called because
|
||||
@@ -939,7 +940,7 @@ def test_simplified_interface_sell(mocker, hyperopt_conf, capsys) -> None:
|
||||
hyperopt_conf.update({'spaces': 'sell', })
|
||||
|
||||
hyperopt = Hyperopt(hyperopt_conf)
|
||||
hyperopt.backtesting.strategy.ohlcvdata_to_dataframe = MagicMock()
|
||||
hyperopt.backtesting.strategy.advise_all_indicators = MagicMock()
|
||||
hyperopt.custom_hyperopt.generate_roi_table = MagicMock(return_value={})
|
||||
|
||||
# TODO: buy_strategy_generator() is actually not called because
|
||||
@@ -984,7 +985,7 @@ def test_simplified_interface_failed(mocker, hyperopt_conf, method, space) -> No
|
||||
hyperopt_conf.update({'spaces': space})
|
||||
|
||||
hyperopt = Hyperopt(hyperopt_conf)
|
||||
hyperopt.backtesting.strategy.ohlcvdata_to_dataframe = MagicMock()
|
||||
hyperopt.backtesting.strategy.advise_all_indicators = MagicMock()
|
||||
hyperopt.custom_hyperopt.generate_roi_table = MagicMock(return_value={})
|
||||
|
||||
delattr(hyperopt.custom_hyperopt.__class__, method)
|
||||
@@ -1002,6 +1003,8 @@ def test_in_strategy_auto_hyperopt(mocker, hyperopt_conf, tmpdir, fee) -> None:
|
||||
hyperopt_conf.update({
|
||||
'strategy': 'HyperoptableStrategy',
|
||||
'user_data_dir': Path(tmpdir),
|
||||
'hyperopt_random_state': 42,
|
||||
'spaces': ['all']
|
||||
})
|
||||
hyperopt = Hyperopt(hyperopt_conf)
|
||||
assert isinstance(hyperopt.custom_hyperopt, HyperOptAuto)
|
||||
@@ -1009,12 +1012,18 @@ def test_in_strategy_auto_hyperopt(mocker, hyperopt_conf, tmpdir, fee) -> None:
|
||||
|
||||
assert hyperopt.backtesting.strategy.buy_rsi.in_space is True
|
||||
assert hyperopt.backtesting.strategy.buy_rsi.value == 35
|
||||
assert hyperopt.backtesting.strategy.sell_rsi.value == 74
|
||||
assert hyperopt.backtesting.strategy.protection_cooldown_lookback.value == 30
|
||||
buy_rsi_range = hyperopt.backtesting.strategy.buy_rsi.range
|
||||
assert isinstance(buy_rsi_range, range)
|
||||
# Range from 0 - 50 (inclusive)
|
||||
assert len(list(buy_rsi_range)) == 51
|
||||
|
||||
hyperopt.start()
|
||||
# All values should've changed.
|
||||
assert hyperopt.backtesting.strategy.protection_cooldown_lookback.value != 30
|
||||
assert hyperopt.backtesting.strategy.buy_rsi.value != 35
|
||||
assert hyperopt.backtesting.strategy.sell_rsi.value != 74
|
||||
|
||||
|
||||
def test_SKDecimal():
|
||||
|
@@ -10,7 +10,7 @@ import rapidjson
|
||||
from freqtrade.constants import FTHYPT_FILEVERSION
|
||||
from freqtrade.exceptions import OperationalException
|
||||
from freqtrade.optimize.hyperopt_tools import HyperoptTools, hyperopt_serializer
|
||||
from tests.conftest import log_has, log_has_re
|
||||
from tests.conftest import log_has
|
||||
|
||||
|
||||
# Functions for recurrent object patching
|
||||
@@ -20,9 +20,14 @@ def create_results() -> List[Dict]:
|
||||
|
||||
|
||||
def test_save_results_saves_epochs(hyperopt, tmpdir, caplog) -> None:
|
||||
|
||||
hyperopt.results_file = Path(tmpdir / 'ut_results.fthypt')
|
||||
|
||||
hyperopt_epochs = HyperoptTools.load_filtered_results(hyperopt.results_file, {})
|
||||
assert hyperopt_epochs == ([], 0)
|
||||
|
||||
# Test writing to temp dir and reading again
|
||||
epochs = create_results()
|
||||
hyperopt.results_file = Path(tmpdir / 'ut_results.fthypt')
|
||||
|
||||
caplog.set_level(logging.DEBUG)
|
||||
|
||||
@@ -33,36 +38,28 @@ def test_save_results_saves_epochs(hyperopt, tmpdir, caplog) -> None:
|
||||
hyperopt._save_result(epochs[0])
|
||||
assert log_has(f"2 epochs saved to '{hyperopt.results_file}'.", caplog)
|
||||
|
||||
hyperopt_epochs = HyperoptTools.load_previous_results(hyperopt.results_file)
|
||||
hyperopt_epochs = HyperoptTools.load_filtered_results(hyperopt.results_file, {})
|
||||
assert len(hyperopt_epochs) == 2
|
||||
assert hyperopt_epochs[1] == 2
|
||||
assert len(hyperopt_epochs[0]) == 2
|
||||
|
||||
|
||||
def test_load_previous_results(testdatadir, caplog) -> None:
|
||||
|
||||
results_file = testdatadir / 'hyperopt_results_SampleStrategy.pickle'
|
||||
|
||||
hyperopt_epochs = HyperoptTools.load_previous_results(results_file)
|
||||
|
||||
assert len(hyperopt_epochs) == 5
|
||||
assert log_has_re(r"Reading pickled epochs from .*", caplog)
|
||||
|
||||
caplog.clear()
|
||||
|
||||
# Modern version
|
||||
results_file = testdatadir / 'strategy_SampleStrategy.fthypt'
|
||||
|
||||
hyperopt_epochs = HyperoptTools.load_previous_results(results_file)
|
||||
|
||||
assert len(hyperopt_epochs) == 5
|
||||
assert log_has_re(r"Reading epochs from .*", caplog)
|
||||
result_gen = HyperoptTools._read_results(hyperopt.results_file, 1)
|
||||
epoch = next(result_gen)
|
||||
assert len(epoch) == 1
|
||||
assert epoch[0] == epochs[0]
|
||||
epoch = next(result_gen)
|
||||
assert len(epoch) == 1
|
||||
epoch = next(result_gen)
|
||||
assert len(epoch) == 0
|
||||
with pytest.raises(StopIteration):
|
||||
next(result_gen)
|
||||
|
||||
|
||||
def test_load_previous_results2(mocker, testdatadir, caplog) -> None:
|
||||
mocker.patch('freqtrade.optimize.hyperopt_tools.HyperoptTools._read_results_pickle',
|
||||
return_value=[{'asdf': '222'}])
|
||||
results_file = testdatadir / 'hyperopt_results_SampleStrategy.pickle'
|
||||
with pytest.raises(OperationalException, match=r"The file .* incompatible.*"):
|
||||
HyperoptTools.load_previous_results(results_file)
|
||||
with pytest.raises(OperationalException,
|
||||
match=r"Legacy hyperopt results are no longer supported.*"):
|
||||
HyperoptTools.load_filtered_results(results_file, {})
|
||||
|
||||
|
||||
@pytest.mark.parametrize("spaces, expected_results", [
|
||||
|
@@ -93,7 +93,7 @@ def test_stoploss_guard(mocker, default_conf, fee, caplog):
|
||||
Trade.query.session.add(generate_mock_trade(
|
||||
'XRP/BTC', fee.return_value, False, sell_reason=SellType.STOP_LOSS.value,
|
||||
min_ago_open=200, min_ago_close=30,
|
||||
))
|
||||
))
|
||||
|
||||
assert not freqtrade.protections.global_stop()
|
||||
assert not log_has_re(message, caplog)
|
||||
@@ -150,7 +150,7 @@ def test_stoploss_guard_perpair(mocker, default_conf, fee, caplog, only_per_pair
|
||||
Trade.query.session.add(generate_mock_trade(
|
||||
pair, fee.return_value, False, sell_reason=SellType.STOP_LOSS.value,
|
||||
min_ago_open=200, min_ago_close=30, profit_rate=0.9,
|
||||
))
|
||||
))
|
||||
|
||||
assert not freqtrade.protections.stop_per_pair(pair)
|
||||
assert not freqtrade.protections.global_stop()
|
||||
|
@@ -139,9 +139,9 @@ def test_fiat_too_many_requests_response(mocker, caplog):
|
||||
assert length_cryptomap == 0
|
||||
assert fiat_convert._backoff > datetime.datetime.now().timestamp()
|
||||
assert log_has(
|
||||
'Too many requests for Coingecko API, backing off and trying again later.',
|
||||
caplog
|
||||
)
|
||||
'Too many requests for Coingecko API, backing off and trying again later.',
|
||||
caplog
|
||||
)
|
||||
|
||||
|
||||
def test_fiat_invalid_response(mocker, caplog):
|
||||
|
@@ -942,7 +942,7 @@ def test_api_whitelist(botclient):
|
||||
"whitelist": ['ETH/BTC', 'LTC/BTC', 'XRP/BTC', 'NEO/BTC'],
|
||||
"length": 4,
|
||||
"method": ["StaticPairList"]
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
def test_api_forcebuy(botclient, mocker, fee):
|
||||
@@ -1033,7 +1033,7 @@ def test_api_forcebuy(botclient, mocker, fee):
|
||||
'buy_tag': None,
|
||||
'timeframe': 5,
|
||||
'exchange': 'binance',
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
def test_api_forcesell(botclient, mocker, ticker, fee, markets):
|
||||
@@ -1215,7 +1215,7 @@ def test_api_strategies(botclient):
|
||||
'DefaultStrategy',
|
||||
'HyperoptableStrategy',
|
||||
'TestStrategyLegacy'
|
||||
]}
|
||||
]}
|
||||
|
||||
|
||||
def test_api_strategy(botclient):
|
||||
|
@@ -4,7 +4,8 @@ import talib.abstract as ta
|
||||
from pandas import DataFrame
|
||||
|
||||
import freqtrade.vendor.qtpylib.indicators as qtpylib
|
||||
from freqtrade.strategy import DecimalParameter, IntParameter, IStrategy, RealParameter
|
||||
from freqtrade.strategy import (BooleanParameter, DecimalParameter, IntParameter, IStrategy,
|
||||
RealParameter)
|
||||
|
||||
|
||||
class HyperoptableStrategy(IStrategy):
|
||||
@@ -64,6 +65,18 @@ class HyperoptableStrategy(IStrategy):
|
||||
sell_rsi = IntParameter(low=50, high=100, default=70, space='sell')
|
||||
sell_minusdi = DecimalParameter(low=0, high=1, default=0.5001, decimals=3, space='sell',
|
||||
load=False)
|
||||
protection_enabled = BooleanParameter(default=True)
|
||||
protection_cooldown_lookback = IntParameter([0, 50], default=30)
|
||||
|
||||
@property
|
||||
def protections(self):
|
||||
prot = []
|
||||
if self.protection_enabled.value:
|
||||
prot.append({
|
||||
"method": "CooldownPeriod",
|
||||
"stop_duration_candles": self.protection_cooldown_lookback.value
|
||||
})
|
||||
return prot
|
||||
|
||||
def informative_pairs(self):
|
||||
"""
|
||||
|
@@ -16,8 +16,8 @@ from freqtrade.exceptions import OperationalException, StrategyError
|
||||
from freqtrade.optimize.space import SKDecimal
|
||||
from freqtrade.persistence import PairLocks, Trade
|
||||
from freqtrade.resolvers import StrategyResolver
|
||||
from freqtrade.strategy.hyper import (BaseParameter, CategoricalParameter, DecimalParameter,
|
||||
IntParameter, RealParameter)
|
||||
from freqtrade.strategy.hyper import (BaseParameter, BooleanParameter, CategoricalParameter,
|
||||
DecimalParameter, IntParameter, RealParameter)
|
||||
from freqtrade.strategy.interface import SellCheckTuple
|
||||
from freqtrade.strategy.strategy_wrapper import strategy_safe_wrapper
|
||||
from tests.conftest import log_has, log_has_re
|
||||
@@ -228,25 +228,25 @@ def test_assert_df(ohlcv_history, caplog):
|
||||
_STRATEGY.disable_dataframe_checks = False
|
||||
|
||||
|
||||
def test_ohlcvdata_to_dataframe(default_conf, testdatadir) -> None:
|
||||
def test_advise_all_indicators(default_conf, testdatadir) -> None:
|
||||
default_conf.update({'strategy': 'DefaultStrategy'})
|
||||
strategy = StrategyResolver.load_strategy(default_conf)
|
||||
|
||||
timerange = TimeRange.parse_timerange('1510694220-1510700340')
|
||||
data = load_data(testdatadir, '1m', ['UNITTEST/BTC'], timerange=timerange,
|
||||
fill_up_missing=True)
|
||||
processed = strategy.ohlcvdata_to_dataframe(data)
|
||||
processed = strategy.advise_all_indicators(data)
|
||||
assert len(processed['UNITTEST/BTC']) == 102 # partial candle was removed
|
||||
|
||||
|
||||
def test_ohlcvdata_to_dataframe_copy(mocker, default_conf, testdatadir) -> None:
|
||||
def test_advise_all_indicators_copy(mocker, default_conf, testdatadir) -> None:
|
||||
default_conf.update({'strategy': 'DefaultStrategy'})
|
||||
strategy = StrategyResolver.load_strategy(default_conf)
|
||||
aimock = mocker.patch('freqtrade.strategy.interface.IStrategy.advise_indicators')
|
||||
timerange = TimeRange.parse_timerange('1510694220-1510700340')
|
||||
data = load_data(testdatadir, '1m', ['UNITTEST/BTC'], timerange=timerange,
|
||||
fill_up_missing=True)
|
||||
strategy.ohlcvdata_to_dataframe(data)
|
||||
strategy.advise_all_indicators(data)
|
||||
assert aimock.call_count == 1
|
||||
# Ensure that a copy of the dataframe is passed to advice_indicators
|
||||
assert aimock.call_args_list[0][0][0] is not data
|
||||
@@ -398,7 +398,7 @@ def test_stop_loss_reached(default_conf, fee, profit, adjusted, expected, traili
|
||||
exchange='binance',
|
||||
open_rate=1,
|
||||
)
|
||||
trade.adjust_min_max_rates(trade.open_rate)
|
||||
trade.adjust_min_max_rates(trade.open_rate, trade.open_rate)
|
||||
strategy.trailing_stop = trailing
|
||||
strategy.trailing_stop_positive = -0.05
|
||||
strategy.use_custom_stoploss = custom
|
||||
@@ -552,6 +552,7 @@ def test__analyze_ticker_internal_skip_analyze(ohlcv_history, mocker, caplog) ->
|
||||
def test_is_pair_locked(default_conf):
|
||||
default_conf.update({'strategy': 'DefaultStrategy'})
|
||||
PairLocks.timeframe = default_conf['timeframe']
|
||||
PairLocks.use_db = True
|
||||
strategy = StrategyResolver.load_strategy(default_conf)
|
||||
# No lock should be present
|
||||
assert len(PairLocks.get_pair_locks(None)) == 0
|
||||
@@ -717,6 +718,17 @@ def test_hyperopt_parameters():
|
||||
assert len(list(catpar.range)) == 3
|
||||
assert list(catpar.range) == ['buy_rsi', 'buy_macd', 'buy_none']
|
||||
|
||||
boolpar = BooleanParameter(default=True, space='buy')
|
||||
assert boolpar.value is True
|
||||
assert isinstance(boolpar.get_space(''), Categorical)
|
||||
assert isinstance(boolpar.range, list)
|
||||
assert len(list(boolpar.range)) == 1
|
||||
|
||||
boolpar.in_space = True
|
||||
assert len(list(boolpar.range)) == 2
|
||||
|
||||
assert list(boolpar.range) == [True, False]
|
||||
|
||||
|
||||
def test_auto_hyperopt_interface(default_conf):
|
||||
default_conf.update({'strategy': 'HyperoptableStrategy'})
|
||||
@@ -734,7 +746,8 @@ def test_auto_hyperopt_interface(default_conf):
|
||||
assert isinstance(all_params, dict)
|
||||
assert len(all_params['buy']) == 2
|
||||
assert len(all_params['sell']) == 2
|
||||
assert all_params['count'] == 4
|
||||
# Number of Hyperoptable parameters
|
||||
assert all_params['count'] == 6
|
||||
|
||||
strategy.__class__.sell_rsi = IntParameter([0, 10], default=5, space='buy')
|
||||
|
||||
|
@@ -125,7 +125,7 @@ def test_parse_args_backtesting_custom() -> None:
|
||||
'--strategy-list',
|
||||
'DefaultStrategy',
|
||||
'SampleStrategy'
|
||||
]
|
||||
]
|
||||
call_args = Arguments(args).get_parsed_arg()
|
||||
assert call_args['config'] == ['test_conf.json']
|
||||
assert call_args['verbosity'] == 0
|
||||
|
@@ -1130,17 +1130,17 @@ def test_pairlist_resolving_fallback(mocker):
|
||||
|
||||
|
||||
@pytest.mark.parametrize("setting", [
|
||||
("ask_strategy", "use_sell_signal", True,
|
||||
None, "use_sell_signal", False),
|
||||
("ask_strategy", "sell_profit_only", True,
|
||||
None, "sell_profit_only", False),
|
||||
("ask_strategy", "sell_profit_offset", 0.1,
|
||||
None, "sell_profit_offset", 0.01),
|
||||
("ask_strategy", "ignore_roi_if_buy_signal", True,
|
||||
None, "ignore_roi_if_buy_signal", False),
|
||||
("ask_strategy", "ignore_buying_expired_candle_after", 5,
|
||||
None, "ignore_buying_expired_candle_after", 6),
|
||||
])
|
||||
("ask_strategy", "use_sell_signal", True,
|
||||
None, "use_sell_signal", False),
|
||||
("ask_strategy", "sell_profit_only", True,
|
||||
None, "sell_profit_only", False),
|
||||
("ask_strategy", "sell_profit_offset", 0.1,
|
||||
None, "sell_profit_offset", 0.01),
|
||||
("ask_strategy", "ignore_roi_if_buy_signal", True,
|
||||
None, "ignore_roi_if_buy_signal", False),
|
||||
("ask_strategy", "ignore_buying_expired_candle_after", 5,
|
||||
None, "ignore_buying_expired_candle_after", 6),
|
||||
])
|
||||
def test_process_temporary_deprecated_settings(mocker, default_conf, setting, caplog):
|
||||
patched_configuration_load_config_file(mocker, default_conf)
|
||||
|
||||
@@ -1180,10 +1180,10 @@ def test_process_temporary_deprecated_settings(mocker, default_conf, setting, ca
|
||||
|
||||
|
||||
@pytest.mark.parametrize("setting", [
|
||||
("experimental", "use_sell_signal", False),
|
||||
("experimental", "sell_profit_only", True),
|
||||
("experimental", "ignore_roi_if_buy_signal", True),
|
||||
])
|
||||
("experimental", "use_sell_signal", False),
|
||||
("experimental", "sell_profit_only", True),
|
||||
("experimental", "ignore_roi_if_buy_signal", True),
|
||||
])
|
||||
def test_process_removed_settings(mocker, default_conf, setting):
|
||||
patched_configuration_load_config_file(mocker, default_conf)
|
||||
|
||||
@@ -1330,7 +1330,7 @@ def test_process_removed_setting(mocker, default_conf, caplog):
|
||||
'sectionB', 'somesetting')
|
||||
|
||||
|
||||
def test_process_deprecated_ticker_interval(mocker, default_conf, caplog):
|
||||
def test_process_deprecated_ticker_interval(default_conf, caplog):
|
||||
message = "DEPRECATED: Please use 'timeframe' instead of 'ticker_interval."
|
||||
config = deepcopy(default_conf)
|
||||
process_temporary_deprecated_settings(config)
|
||||
@@ -1352,6 +1352,17 @@ def test_process_deprecated_ticker_interval(mocker, default_conf, caplog):
|
||||
process_temporary_deprecated_settings(config)
|
||||
|
||||
|
||||
def test_process_deprecated_protections(default_conf, caplog):
|
||||
message = "DEPRECATED: Setting 'protections' in the configuration is deprecated."
|
||||
config = deepcopy(default_conf)
|
||||
process_temporary_deprecated_settings(config)
|
||||
assert not log_has(message, caplog)
|
||||
|
||||
config['protections'] = []
|
||||
process_temporary_deprecated_settings(config)
|
||||
assert log_has(message, caplog)
|
||||
|
||||
|
||||
def test_flat_vars_to_nested_dict(caplog):
|
||||
|
||||
test_args = {
|
||||
|
@@ -799,25 +799,30 @@ def test_adjust_min_max_rates(fee):
|
||||
open_rate=1,
|
||||
)
|
||||
|
||||
trade.adjust_min_max_rates(trade.open_rate)
|
||||
trade.adjust_min_max_rates(trade.open_rate, trade.open_rate)
|
||||
assert trade.max_rate == 1
|
||||
assert trade.min_rate == 1
|
||||
|
||||
# check min adjusted, max remained
|
||||
trade.adjust_min_max_rates(0.96)
|
||||
trade.adjust_min_max_rates(0.96, 0.96)
|
||||
assert trade.max_rate == 1
|
||||
assert trade.min_rate == 0.96
|
||||
|
||||
# check max adjusted, min remains
|
||||
trade.adjust_min_max_rates(1.05)
|
||||
trade.adjust_min_max_rates(1.05, 1.05)
|
||||
assert trade.max_rate == 1.05
|
||||
assert trade.min_rate == 0.96
|
||||
|
||||
# current rate "in the middle" - no adjustment
|
||||
trade.adjust_min_max_rates(1.03)
|
||||
trade.adjust_min_max_rates(1.03, 1.03)
|
||||
assert trade.max_rate == 1.05
|
||||
assert trade.min_rate == 0.96
|
||||
|
||||
# current rate "in the middle" - no adjustment
|
||||
trade.adjust_min_max_rates(1.10, 0.91)
|
||||
assert trade.max_rate == 1.10
|
||||
assert trade.min_rate == 0.91
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("init_persistence")
|
||||
@pytest.mark.parametrize('use_db', [True, False])
|
||||
@@ -1219,6 +1224,11 @@ def test_update_order_from_ccxt(caplog):
|
||||
assert o.ft_is_open
|
||||
assert o.order_filled_date is None
|
||||
|
||||
# Order is unfilled, "filled" not set
|
||||
# https://github.com/freqtrade/freqtrade/issues/5404
|
||||
ccxt_order.update({'filled': None, 'remaining': 20.0, 'status': 'canceled'})
|
||||
o.update_from_ccxt_object(ccxt_order)
|
||||
|
||||
# Order has been closed
|
||||
ccxt_order.update({'filled': 20.0, 'remaining': 0.0, 'status': 'closed'})
|
||||
o.update_from_ccxt_object(ccxt_order)
|
||||
|
Reference in New Issue
Block a user