From e97de4643fe1f0389523cdacf252c57029879d64 Mon Sep 17 00:00:00 2001 From: Matthias Date: Mon, 14 Jun 2021 21:06:15 +0200 Subject: [PATCH] Move tests to hyperopttools test file --- tests/optimize/test_hyperopt.py | 137 ------------------------- tests/optimize/test_hyperopttools.py | 146 +++++++++++++++++++++++++++ 2 files changed, 146 insertions(+), 137 deletions(-) create mode 100644 tests/optimize/test_hyperopttools.py diff --git a/tests/optimize/test_hyperopt.py b/tests/optimize/test_hyperopt.py index c4cea638f..91d9f5496 100644 --- a/tests/optimize/test_hyperopt.py +++ b/tests/optimize/test_hyperopt.py @@ -1,9 +1,6 @@ # pragma pylint: disable=missing-docstring,W0212,C0103 -import logging -import re from datetime import datetime from pathlib import Path -from typing import Dict, List from unittest.mock import ANY, MagicMock import pandas as pd @@ -28,12 +25,6 @@ from tests.conftest import (get_args, log_has, log_has_re, patch_exchange, from .hyperopts.default_hyperopt import DefaultHyperOpt -# Functions for recurrent object patching -def create_results() -> List[Dict]: - - return [{'loss': 1, 'result': 'foo', 'params': {}, 'is_best': True}] - - def test_setup_hyperopt_configuration_without_arguments(mocker, default_conf, caplog) -> None: patched_configuration_load_config_file(mocker, default_conf) @@ -303,52 +294,6 @@ def test_no_log_if_loss_does_not_improve(hyperopt, caplog) -> None: assert caplog.record_tuples == [] -def test_save_results_saves_epochs(mocker, hyperopt, tmpdir, caplog) -> None: - # Test writing to temp dir and reading again - epochs = create_results() - hyperopt.results_file = Path(tmpdir / 'ut_results.fthypt') - - caplog.set_level(logging.DEBUG) - - for epoch in epochs: - hyperopt._save_result(epoch) - assert log_has(f"1 epoch saved to '{hyperopt.results_file}'.", caplog) - - 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) - assert len(hyperopt_epochs) == 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) - - -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) - - def test_roi_table_generation(hyperopt) -> None: params = { 'roi_t1': 5, @@ -467,40 +412,6 @@ def test_hyperopt_format_results(hyperopt): assert '0:50:00 min' in result -@pytest.mark.parametrize("spaces, expected_results", [ - (['buy'], - {'buy': True, 'sell': False, 'roi': False, 'stoploss': False, 'trailing': False}), - (['sell'], - {'buy': False, 'sell': True, 'roi': False, 'stoploss': False, 'trailing': False}), - (['roi'], - {'buy': False, 'sell': False, 'roi': True, 'stoploss': False, 'trailing': False}), - (['stoploss'], - {'buy': False, 'sell': False, 'roi': False, 'stoploss': True, 'trailing': False}), - (['trailing'], - {'buy': False, 'sell': False, 'roi': False, 'stoploss': False, 'trailing': True}), - (['buy', 'sell', 'roi', 'stoploss'], - {'buy': True, 'sell': True, 'roi': True, 'stoploss': True, 'trailing': False}), - (['buy', 'sell', 'roi', 'stoploss', 'trailing'], - {'buy': True, 'sell': True, 'roi': True, 'stoploss': True, 'trailing': True}), - (['buy', 'roi'], - {'buy': True, 'sell': False, 'roi': True, 'stoploss': False, 'trailing': False}), - (['all'], - {'buy': True, 'sell': True, 'roi': True, 'stoploss': True, 'trailing': True}), - (['default'], - {'buy': True, 'sell': True, 'roi': True, 'stoploss': True, 'trailing': False}), - (['default', 'trailing'], - {'buy': True, 'sell': True, 'roi': True, 'stoploss': True, 'trailing': True}), - (['all', 'buy'], - {'buy': True, 'sell': True, 'roi': True, 'stoploss': True, 'trailing': True}), - (['default', 'buy'], - {'buy': True, 'sell': True, 'roi': True, 'stoploss': True, 'trailing': False}), -]) -def test_has_space(hyperopt_conf, spaces, expected_results): - for s in ['buy', 'sell', 'roi', 'stoploss', 'trailing']: - hyperopt_conf.update({'spaces': spaces}) - assert HyperoptTools.has_space(hyperopt_conf, s) == expected_results[s] - - 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) @@ -1070,42 +981,6 @@ def test_simplified_interface_failed(mocker, hyperopt_conf, method, space) -> No hyperopt.start() -def test_show_epoch_details(capsys): - test_result = { - 'params_details': { - 'trailing': { - 'trailing_stop': True, - 'trailing_stop_positive': 0.02, - 'trailing_stop_positive_offset': 0.04, - 'trailing_only_offset_is_reached': True - }, - 'roi': { - 0: 0.18, - 90: 0.14, - 225: 0.05, - 430: 0}, - }, - 'results_explanation': 'foo result', - 'is_initial_point': False, - 'total_profit': 0, - 'current_epoch': 2, # This starts from 1 (in a human-friendly manner) - 'is_best': True - } - - HyperoptTools.show_epoch_details(test_result, 5, False, no_header=True) - captured = capsys.readouterr() - assert '# Trailing stop:' in captured.out - # re.match(r"Pairs for .*", captured.out) - assert re.search(r'^\s+trailing_stop = True$', captured.out, re.MULTILINE) - assert re.search(r'^\s+trailing_stop_positive = 0.02$', captured.out, re.MULTILINE) - assert re.search(r'^\s+trailing_stop_positive_offset = 0.04$', captured.out, re.MULTILINE) - assert re.search(r'^\s+trailing_only_offset_is_reached = True$', captured.out, re.MULTILINE) - - assert '# ROI table:' in captured.out - assert re.search(r'^\s+minimal_roi = \{$', captured.out, re.MULTILINE) - assert re.search(r'^\s+\"90\"\:\s0.14,\s*$', captured.out, re.MULTILINE) - - def test_in_strategy_auto_hyperopt(mocker, hyperopt_conf, tmpdir, fee) -> None: patch_exchange(mocker) mocker.patch('freqtrade.exchange.Exchange.get_fee', fee) @@ -1147,15 +1022,3 @@ def test_SKDecimal(): assert space.transform([1.5, 1.6]) == [150, 160] -def test___pprint(): - params = {'buy_std': 1.2, 'buy_rsi': 31, 'buy_enable': True, 'buy_what': 'asdf'} - non_params = {'buy_notoptimied': 55} - - x = HyperoptTools._pprint(params, non_params) - assert x == """{ - "buy_std": 1.2, - "buy_rsi": 31, - "buy_enable": True, - "buy_what": "asdf", - "buy_notoptimied": 55, # value loaded from strategy -}""" diff --git a/tests/optimize/test_hyperopttools.py b/tests/optimize/test_hyperopttools.py new file mode 100644 index 000000000..94216f2f7 --- /dev/null +++ b/tests/optimize/test_hyperopttools.py @@ -0,0 +1,146 @@ +import logging +import re +from pathlib import Path +from typing import Dict, List + +import pytest + +from freqtrade.exceptions import OperationalException +from freqtrade.optimize.hyperopt_tools import HyperoptTools +from tests.conftest import log_has, log_has_re + + +# Functions for recurrent object patching +def create_results() -> List[Dict]: + + return [{'loss': 1, 'result': 'foo', 'params': {}, 'is_best': True}] + + +def test_save_results_saves_epochs(hyperopt, tmpdir, caplog) -> None: + # Test writing to temp dir and reading again + epochs = create_results() + hyperopt.results_file = Path(tmpdir / 'ut_results.fthypt') + + caplog.set_level(logging.DEBUG) + + for epoch in epochs: + hyperopt._save_result(epoch) + assert log_has(f"1 epoch saved to '{hyperopt.results_file}'.", caplog) + + 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) + assert len(hyperopt_epochs) == 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) + + +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) + + +@pytest.mark.parametrize("spaces, expected_results", [ + (['buy'], + {'buy': True, 'sell': False, 'roi': False, 'stoploss': False, 'trailing': False}), + (['sell'], + {'buy': False, 'sell': True, 'roi': False, 'stoploss': False, 'trailing': False}), + (['roi'], + {'buy': False, 'sell': False, 'roi': True, 'stoploss': False, 'trailing': False}), + (['stoploss'], + {'buy': False, 'sell': False, 'roi': False, 'stoploss': True, 'trailing': False}), + (['trailing'], + {'buy': False, 'sell': False, 'roi': False, 'stoploss': False, 'trailing': True}), + (['buy', 'sell', 'roi', 'stoploss'], + {'buy': True, 'sell': True, 'roi': True, 'stoploss': True, 'trailing': False}), + (['buy', 'sell', 'roi', 'stoploss', 'trailing'], + {'buy': True, 'sell': True, 'roi': True, 'stoploss': True, 'trailing': True}), + (['buy', 'roi'], + {'buy': True, 'sell': False, 'roi': True, 'stoploss': False, 'trailing': False}), + (['all'], + {'buy': True, 'sell': True, 'roi': True, 'stoploss': True, 'trailing': True}), + (['default'], + {'buy': True, 'sell': True, 'roi': True, 'stoploss': True, 'trailing': False}), + (['default', 'trailing'], + {'buy': True, 'sell': True, 'roi': True, 'stoploss': True, 'trailing': True}), + (['all', 'buy'], + {'buy': True, 'sell': True, 'roi': True, 'stoploss': True, 'trailing': True}), + (['default', 'buy'], + {'buy': True, 'sell': True, 'roi': True, 'stoploss': True, 'trailing': False}), +]) +def test_has_space(hyperopt_conf, spaces, expected_results): + for s in ['buy', 'sell', 'roi', 'stoploss', 'trailing']: + hyperopt_conf.update({'spaces': spaces}) + assert HyperoptTools.has_space(hyperopt_conf, s) == expected_results[s] + + +def test_show_epoch_details(capsys): + test_result = { + 'params_details': { + 'trailing': { + 'trailing_stop': True, + 'trailing_stop_positive': 0.02, + 'trailing_stop_positive_offset': 0.04, + 'trailing_only_offset_is_reached': True + }, + 'roi': { + 0: 0.18, + 90: 0.14, + 225: 0.05, + 430: 0}, + }, + 'results_explanation': 'foo result', + 'is_initial_point': False, + 'total_profit': 0, + 'current_epoch': 2, # This starts from 1 (in a human-friendly manner) + 'is_best': True + } + + HyperoptTools.show_epoch_details(test_result, 5, False, no_header=True) + captured = capsys.readouterr() + assert '# Trailing stop:' in captured.out + # re.match(r"Pairs for .*", captured.out) + assert re.search(r'^\s+trailing_stop = True$', captured.out, re.MULTILINE) + assert re.search(r'^\s+trailing_stop_positive = 0.02$', captured.out, re.MULTILINE) + assert re.search(r'^\s+trailing_stop_positive_offset = 0.04$', captured.out, re.MULTILINE) + assert re.search(r'^\s+trailing_only_offset_is_reached = True$', captured.out, re.MULTILINE) + + assert '# ROI table:' in captured.out + assert re.search(r'^\s+minimal_roi = \{$', captured.out, re.MULTILINE) + assert re.search(r'^\s+\"90\"\:\s0.14,\s*$', captured.out, re.MULTILINE) + + +def test___pprint(): + params = {'buy_std': 1.2, 'buy_rsi': 31, 'buy_enable': True, 'buy_what': 'asdf'} + non_params = {'buy_notoptimied': 55} + + x = HyperoptTools._pprint(params, non_params) + assert x == """{ + "buy_std": 1.2, + "buy_rsi": 31, + "buy_enable": True, + "buy_what": "asdf", + "buy_notoptimied": 55, # value loaded from strategy +}"""