Update backtesting and hyperopt tests to use default_config and mock validate_pairs

Use default_config from conftest.py instead of user supplied config in user_data/hyperopt_conf
Mock validate pairs so tests don't fail if pairs don't exist/are removed from exchanges
This commit is contained in:
enenn 2018-04-08 11:11:14 +02:00
parent 4ac2afacfa
commit a86104d0fe
1 changed files with 43 additions and 23 deletions

View File

@ -3,18 +3,31 @@ import json
import os import os
from copy import deepcopy from copy import deepcopy
from unittest.mock import MagicMock from unittest.mock import MagicMock
import pytest
import pandas as pd import pandas as pd
from freqtrade.optimize.__init__ import load_tickerdata_file from freqtrade.optimize.__init__ import load_tickerdata_file
from freqtrade.optimize.hyperopt import Hyperopt, start from freqtrade.optimize.hyperopt import Hyperopt, start
from freqtrade.strategy.strategy import Strategy from freqtrade.strategy.strategy import Strategy
from freqtrade.tests.conftest import default_conf, log_has from freqtrade.tests.conftest import log_has
from freqtrade.tests.optimize.test_backtesting import get_args from freqtrade.tests.optimize.test_backtesting import get_args
# Avoid to reinit the same object again and again # Avoid to reinit the same object again and again
_HYPEROPT = Hyperopt(default_conf()) _HYPEROPT_INITIALIZED = False
_HYPEROPT = None
@pytest.fixture(scope='function')
def init_hyperopt(default_conf, mocker):
global _HYPEROPT_INITIALIZED, _HYPEROPT
if not _HYPEROPT_INITIALIZED:
mocker.patch('freqtrade.exchange.validate_pairs', MagicMock(return_value=True))
mocker.patch('freqtrade.optimize.hyperopt.hyperopt_optimize_conf', MagicMock(return_value=default_conf))
mocker.patch('freqtrade.exchange.validate_pairs', MagicMock())
_HYPEROPT = Hyperopt(default_conf)
_HYPEROPT_INITIALIZED = True
# Functions for recurrent object patching # Functions for recurrent object patching
@ -52,9 +65,9 @@ def test_start(mocker, default_conf, caplog) -> None:
start_mock = MagicMock() start_mock = MagicMock()
mocker.patch('freqtrade.logger.Logger.set_format', MagicMock()) mocker.patch('freqtrade.logger.Logger.set_format', MagicMock())
mocker.patch('freqtrade.optimize.hyperopt.Hyperopt.start', start_mock) mocker.patch('freqtrade.optimize.hyperopt.Hyperopt.start', start_mock)
mocker.patch('freqtrade.configuration.open', mocker.mock_open( mocker.patch('freqtrade.optimize.hyperopt.hyperopt_optimize_conf', MagicMock(return_value=default_conf))
read_data=json.dumps(default_conf) mocker.patch('freqtrade.freqtradebot.exchange.validate_pairs', MagicMock())
))
args = [ args = [
'--config', 'config.json', '--config', 'config.json',
'--strategy', 'default_strategy', '--strategy', 'default_strategy',
@ -75,7 +88,7 @@ def test_start(mocker, default_conf, caplog) -> None:
assert start_mock.call_count == 1 assert start_mock.call_count == 1
def test_loss_calculation_prefer_correct_trade_count() -> None: def test_loss_calculation_prefer_correct_trade_count(init_hyperopt) -> None:
""" """
Test Hyperopt.calculate_loss() Test Hyperopt.calculate_loss()
""" """
@ -89,7 +102,7 @@ def test_loss_calculation_prefer_correct_trade_count() -> None:
assert under > correct assert under > correct
def test_loss_calculation_prefer_shorter_trades() -> None: def test_loss_calculation_prefer_shorter_trades(init_hyperopt) -> None:
""" """
Test Hyperopt.calculate_loss() Test Hyperopt.calculate_loss()
""" """
@ -100,7 +113,7 @@ def test_loss_calculation_prefer_shorter_trades() -> None:
assert shorter < longer assert shorter < longer
def test_loss_calculation_has_limited_profit() -> None: def test_loss_calculation_has_limited_profit(init_hyperopt) -> None:
hyperopt = _HYPEROPT hyperopt = _HYPEROPT
correct = hyperopt.calculate_loss(hyperopt.expected_max_profit, hyperopt.target_trades, 20) correct = hyperopt.calculate_loss(hyperopt.expected_max_profit, hyperopt.target_trades, 20)
@ -110,7 +123,7 @@ def test_loss_calculation_has_limited_profit() -> None:
assert under > correct assert under > correct
def test_log_results_if_loss_improves(caplog) -> None: def test_log_results_if_loss_improves(init_hyperopt, caplog) -> None:
hyperopt = _HYPEROPT hyperopt = _HYPEROPT
hyperopt.current_best_loss = 2 hyperopt.current_best_loss = 2
hyperopt.log_results( hyperopt.log_results(
@ -124,7 +137,7 @@ def test_log_results_if_loss_improves(caplog) -> None:
assert log_has(' 1/2: foo. Loss 1.00000', caplog.record_tuples) assert log_has(' 1/2: foo. Loss 1.00000', caplog.record_tuples)
def test_no_log_if_loss_does_not_improve(caplog) -> None: def test_no_log_if_loss_does_not_improve(init_hyperopt, caplog) -> None:
hyperopt = _HYPEROPT hyperopt = _HYPEROPT
hyperopt.current_best_loss = 2 hyperopt.current_best_loss = 2
hyperopt.log_results( hyperopt.log_results(
@ -135,7 +148,7 @@ def test_no_log_if_loss_does_not_improve(caplog) -> None:
assert caplog.record_tuples == [] assert caplog.record_tuples == []
def test_fmin_best_results(mocker, default_conf, caplog) -> None: def test_fmin_best_results(mocker, init_hyperopt, default_conf, caplog) -> None:
fmin_result = { fmin_result = {
"macd_below_zero": 0, "macd_below_zero": 0,
"adx": 1, "adx": 1,
@ -170,6 +183,7 @@ def test_fmin_best_results(mocker, default_conf, caplog) -> None:
mocker.patch('freqtrade.optimize.hyperopt.fmin', return_value=fmin_result) mocker.patch('freqtrade.optimize.hyperopt.fmin', return_value=fmin_result)
mocker.patch('freqtrade.optimize.hyperopt.hyperopt_optimize_conf', return_value=conf) mocker.patch('freqtrade.optimize.hyperopt.hyperopt_optimize_conf', return_value=conf)
mocker.patch('freqtrade.logger.Logger.set_format', MagicMock()) mocker.patch('freqtrade.logger.Logger.set_format', MagicMock())
mocker.patch('freqtrade.freqtradebot.exchange.validate_pairs', MagicMock())
Strategy({'strategy': 'default_strategy'}) Strategy({'strategy': 'default_strategy'})
hyperopt = Hyperopt(conf) hyperopt = Hyperopt(conf)
@ -204,7 +218,7 @@ def test_fmin_best_results(mocker, default_conf, caplog) -> None:
assert line in caplog.text assert line in caplog.text
def test_fmin_throw_value_error(mocker, default_conf, caplog) -> None: def test_fmin_throw_value_error(mocker, init_hyperopt, default_conf, caplog) -> None:
mocker.patch('freqtrade.optimize.hyperopt.load_data', MagicMock()) mocker.patch('freqtrade.optimize.hyperopt.load_data', MagicMock())
mocker.patch('freqtrade.optimize.hyperopt.fmin', side_effect=ValueError()) mocker.patch('freqtrade.optimize.hyperopt.fmin', side_effect=ValueError())
@ -215,6 +229,8 @@ def test_fmin_throw_value_error(mocker, default_conf, caplog) -> None:
conf.update({'spaces': 'all'}) conf.update({'spaces': 'all'})
mocker.patch('freqtrade.optimize.hyperopt.hyperopt_optimize_conf', return_value=conf) mocker.patch('freqtrade.optimize.hyperopt.hyperopt_optimize_conf', return_value=conf)
mocker.patch('freqtrade.logger.Logger.set_format', MagicMock()) mocker.patch('freqtrade.logger.Logger.set_format', MagicMock())
mocker.patch('freqtrade.freqtradebot.exchange.validate_pairs', MagicMock())
Strategy({'strategy': 'default_strategy'}) Strategy({'strategy': 'default_strategy'})
hyperopt = Hyperopt(conf) hyperopt = Hyperopt(conf)
hyperopt.trials = create_trials(mocker) hyperopt.trials = create_trials(mocker)
@ -232,7 +248,7 @@ def test_fmin_throw_value_error(mocker, default_conf, caplog) -> None:
assert line in caplog.text assert line in caplog.text
def test_resuming_previous_hyperopt_results_succeeds(mocker, default_conf) -> None: def test_resuming_previous_hyperopt_results_succeeds(mocker, init_hyperopt, default_conf) -> None:
trials = create_trials(mocker) trials = create_trials(mocker)
conf = deepcopy(default_conf) conf = deepcopy(default_conf)
@ -257,6 +273,7 @@ def test_resuming_previous_hyperopt_results_succeeds(mocker, default_conf) -> No
mocker.patch('freqtrade.optimize.hyperopt.fmin', return_value={}) mocker.patch('freqtrade.optimize.hyperopt.fmin', return_value={})
mocker.patch('freqtrade.optimize.hyperopt.hyperopt_optimize_conf', return_value=conf) mocker.patch('freqtrade.optimize.hyperopt.hyperopt_optimize_conf', return_value=conf)
mocker.patch('freqtrade.logger.Logger.set_format', MagicMock()) mocker.patch('freqtrade.logger.Logger.set_format', MagicMock())
mocker.patch('freqtrade.exchange.validate_pairs', MagicMock())
Strategy({'strategy': 'default_strategy'}) Strategy({'strategy': 'default_strategy'})
hyperopt = Hyperopt(conf) hyperopt = Hyperopt(conf)
@ -275,7 +292,7 @@ def test_resuming_previous_hyperopt_results_succeeds(mocker, default_conf) -> No
assert total_tries == (current_tries + len(trials.results)) assert total_tries == (current_tries + len(trials.results))
def test_save_trials_saves_trials(mocker, caplog) -> None: def test_save_trials_saves_trials(mocker, init_hyperopt, caplog) -> None:
create_trials(mocker) create_trials(mocker)
mock_dump = mocker.patch('freqtrade.optimize.hyperopt.pickle.dump', return_value=None) mock_dump = mocker.patch('freqtrade.optimize.hyperopt.pickle.dump', return_value=None)
@ -292,7 +309,7 @@ def test_save_trials_saves_trials(mocker, caplog) -> None:
mock_dump.assert_called_once() mock_dump.assert_called_once()
def test_read_trials_returns_trials_file(mocker, caplog) -> None: def test_read_trials_returns_trials_file(mocker, init_hyperopt, caplog) -> None:
trials = create_trials(mocker) trials = create_trials(mocker)
mock_load = mocker.patch('freqtrade.optimize.hyperopt.pickle.load', return_value=trials) mock_load = mocker.patch('freqtrade.optimize.hyperopt.pickle.load', return_value=trials)
mock_open = mocker.patch('freqtrade.optimize.hyperopt.open', return_value=mock_load) mock_open = mocker.patch('freqtrade.optimize.hyperopt.open', return_value=mock_load)
@ -309,7 +326,7 @@ def test_read_trials_returns_trials_file(mocker, caplog) -> None:
mock_load.assert_called_once() mock_load.assert_called_once()
def test_roi_table_generation() -> None: def test_roi_table_generation(init_hyperopt) -> None:
params = { params = {
'roi_t1': 5, 'roi_t1': 5,
'roi_t2': 10, 'roi_t2': 10,
@ -323,10 +340,11 @@ def test_roi_table_generation() -> None:
assert hyperopt.generate_roi_table(params) == {0: 6, 15: 3, 25: 1, 30: 0} assert hyperopt.generate_roi_table(params) == {0: 6, 15: 3, 25: 1, 30: 0}
def test_start_calls_fmin(mocker, default_conf) -> None: def test_start_calls_fmin(mocker, init_hyperopt, default_conf) -> None:
trials = create_trials(mocker) trials = create_trials(mocker)
mocker.patch('freqtrade.optimize.hyperopt.sorted', return_value=trials.results) mocker.patch('freqtrade.optimize.hyperopt.sorted', return_value=trials.results)
mocker.patch('freqtrade.optimize.hyperopt.load_data', MagicMock()) mocker.patch('freqtrade.optimize.hyperopt.load_data', MagicMock())
mocker.patch('freqtrade.exchange.validate_pairs', MagicMock())
mock_fmin = mocker.patch('freqtrade.optimize.hyperopt.fmin', return_value={}) mock_fmin = mocker.patch('freqtrade.optimize.hyperopt.fmin', return_value={})
conf = deepcopy(default_conf) conf = deepcopy(default_conf)
@ -344,7 +362,7 @@ def test_start_calls_fmin(mocker, default_conf) -> None:
mock_fmin.assert_called_once() mock_fmin.assert_called_once()
def test_start_uses_mongotrials(mocker, default_conf) -> None: def test_start_uses_mongotrials(mocker, init_hyperopt, default_conf) -> None:
mocker.patch('freqtrade.optimize.hyperopt.load_data', MagicMock()) mocker.patch('freqtrade.optimize.hyperopt.load_data', MagicMock())
mock_fmin = mocker.patch('freqtrade.optimize.hyperopt.fmin', return_value={}) mock_fmin = mocker.patch('freqtrade.optimize.hyperopt.fmin', return_value={})
mock_mongotrials = mocker.patch( mock_mongotrials = mocker.patch(
@ -359,6 +377,7 @@ def test_start_uses_mongotrials(mocker, default_conf) -> None:
conf.update({'timerange': None}) conf.update({'timerange': None})
conf.update({'spaces': 'all'}) conf.update({'spaces': 'all'})
mocker.patch('freqtrade.optimize.hyperopt.hyperopt_optimize_conf', return_value=conf) mocker.patch('freqtrade.optimize.hyperopt.hyperopt_optimize_conf', return_value=conf)
mocker.patch('freqtrade.freqtradebot.exchange.validate_pairs', MagicMock())
hyperopt = Hyperopt(conf) hyperopt = Hyperopt(conf)
hyperopt.tickerdata_to_dataframe = MagicMock() hyperopt.tickerdata_to_dataframe = MagicMock()
@ -387,7 +406,7 @@ def test_format_results():
assert x.find(' 66.67%') assert x.find(' 66.67%')
def test_signal_handler(mocker): def test_signal_handler(mocker, init_hyperopt):
""" """
Test Hyperopt.signal_handler() Test Hyperopt.signal_handler()
""" """
@ -401,7 +420,7 @@ def test_signal_handler(mocker):
assert m.call_count == 3 assert m.call_count == 3
def test_has_space(): def test_has_space(init_hyperopt):
""" """
Test Hyperopt.has_space() method Test Hyperopt.has_space() method
""" """
@ -414,7 +433,7 @@ def test_has_space():
assert _HYPEROPT.has_space('buy') assert _HYPEROPT.has_space('buy')
def test_populate_indicators() -> None: def test_populate_indicators(init_hyperopt) -> None:
""" """
Test Hyperopt.populate_indicators() Test Hyperopt.populate_indicators()
""" """
@ -429,7 +448,7 @@ def test_populate_indicators() -> None:
assert 'cci' in dataframe assert 'cci' in dataframe
def test_buy_strategy_generator() -> None: def test_buy_strategy_generator(init_hyperopt) -> None:
""" """
Test Hyperopt.buy_strategy_generator() Test Hyperopt.buy_strategy_generator()
""" """
@ -486,7 +505,7 @@ def test_buy_strategy_generator() -> None:
assert 1 in result['buy'] assert 1 in result['buy']
def test_generate_optimizer(mocker, default_conf) -> None: def test_generate_optimizer(mocker, init_hyperopt, default_conf) -> None:
""" """
Test Hyperopt.generate_optimizer() function Test Hyperopt.generate_optimizer() function
""" """
@ -505,6 +524,7 @@ def test_generate_optimizer(mocker, default_conf) -> None:
'freqtrade.optimize.hyperopt.Hyperopt.backtest', 'freqtrade.optimize.hyperopt.Hyperopt.backtest',
MagicMock(return_value=backtest_result) MagicMock(return_value=backtest_result)
) )
mocker.patch('freqtrade.exchange.validate_pairs', MagicMock())
optimizer_param = { optimizer_param = {
'adx': {'enabled': False}, 'adx': {'enabled': False},