Update some tests to remove explicit hyperopt interface
This commit is contained in:
parent
dad4a49e81
commit
fd6bf591f8
@ -79,10 +79,9 @@ class Hyperopt:
|
|||||||
|
|
||||||
if not self.config.get('hyperopt'):
|
if not self.config.get('hyperopt'):
|
||||||
self.custom_hyperopt = HyperOptAuto(self.config)
|
self.custom_hyperopt = HyperOptAuto(self.config)
|
||||||
self.auto_hyperopt = True
|
|
||||||
else:
|
else:
|
||||||
raise OperationalException(
|
raise OperationalException(
|
||||||
"Using seperate Hyperopt files has been removed in 2021.9. Please convert "
|
"Using separate Hyperopt files has been removed in 2021.9. Please convert "
|
||||||
"your existing Hyperopt file to the new Hyperoptable strategy interface")
|
"your existing Hyperopt file to the new Hyperoptable strategy interface")
|
||||||
|
|
||||||
self.backtesting._set_strategy(self.backtesting.strategylist[0])
|
self.backtesting._set_strategy(self.backtesting.strategylist[0])
|
||||||
|
@ -4,9 +4,9 @@ This module implements a convenience auto-hyperopt class, which can be used toge
|
|||||||
that implement IHyperStrategy interface.
|
that implement IHyperStrategy interface.
|
||||||
"""
|
"""
|
||||||
from contextlib import suppress
|
from contextlib import suppress
|
||||||
from typing import Any, Callable, Dict, List
|
from typing import Callable, Dict, List
|
||||||
|
|
||||||
from pandas import DataFrame
|
from freqtrade.exceptions import OperationalException
|
||||||
|
|
||||||
|
|
||||||
with suppress(ImportError):
|
with suppress(ImportError):
|
||||||
@ -15,6 +15,14 @@ with suppress(ImportError):
|
|||||||
from freqtrade.optimize.hyperopt_interface import IHyperOpt
|
from freqtrade.optimize.hyperopt_interface import IHyperOpt
|
||||||
|
|
||||||
|
|
||||||
|
def _format_exception_message(space: str) -> str:
|
||||||
|
raise OperationalException(
|
||||||
|
f"The '{space}' space is included into the hyperoptimization "
|
||||||
|
f"but no parameter for this space was not found in your Strategy. "
|
||||||
|
f"Please make sure to have parameters for this space enabled for optimization "
|
||||||
|
f"or remove the '{space}' space from hyperoptimization.")
|
||||||
|
|
||||||
|
|
||||||
class HyperOptAuto(IHyperOpt):
|
class HyperOptAuto(IHyperOpt):
|
||||||
"""
|
"""
|
||||||
This class delegates functionality to Strategy(IHyperStrategy) and Strategy.HyperOpt classes.
|
This class delegates functionality to Strategy(IHyperStrategy) and Strategy.HyperOpt classes.
|
||||||
@ -40,22 +48,22 @@ class HyperOptAuto(IHyperOpt):
|
|||||||
if attr.optimize:
|
if attr.optimize:
|
||||||
yield attr.get_space(attr_name)
|
yield attr.get_space(attr_name)
|
||||||
|
|
||||||
def _get_indicator_space(self, category, fallback_method_name):
|
def _get_indicator_space(self, category):
|
||||||
# TODO: is this necessary, or can we call "generate_space" directly?
|
# TODO: is this necessary, or can we call "generate_space" directly?
|
||||||
indicator_space = list(self._generate_indicator_space(category))
|
indicator_space = list(self._generate_indicator_space(category))
|
||||||
if len(indicator_space) > 0:
|
if len(indicator_space) > 0:
|
||||||
return indicator_space
|
return indicator_space
|
||||||
else:
|
else:
|
||||||
return self._get_func(fallback_method_name)()
|
_format_exception_message(category)
|
||||||
|
|
||||||
def indicator_space(self) -> List['Dimension']:
|
def indicator_space(self) -> List['Dimension']:
|
||||||
return self._get_indicator_space('buy', 'indicator_space')
|
return self._get_indicator_space('buy')
|
||||||
|
|
||||||
def sell_indicator_space(self) -> List['Dimension']:
|
def sell_indicator_space(self) -> List['Dimension']:
|
||||||
return self._get_indicator_space('sell', 'sell_indicator_space')
|
return self._get_indicator_space('sell')
|
||||||
|
|
||||||
def protection_space(self) -> List['Dimension']:
|
def protection_space(self) -> List['Dimension']:
|
||||||
return self._get_indicator_space('protection', 'protection_space')
|
return self._get_indicator_space('protection')
|
||||||
|
|
||||||
def generate_roi_table(self, params: Dict) -> Dict[int, float]:
|
def generate_roi_table(self, params: Dict) -> Dict[int, float]:
|
||||||
return self._get_func('generate_roi_table')(params)
|
return self._get_func('generate_roi_table')(params)
|
||||||
|
@ -9,7 +9,6 @@ from typing import Dict, List
|
|||||||
|
|
||||||
from skopt.space import Categorical, Dimension, Integer
|
from skopt.space import Categorical, Dimension, Integer
|
||||||
|
|
||||||
from freqtrade.exceptions import OperationalException
|
|
||||||
from freqtrade.exchange import timeframe_to_minutes
|
from freqtrade.exchange import timeframe_to_minutes
|
||||||
from freqtrade.misc import round_dict
|
from freqtrade.misc import round_dict
|
||||||
from freqtrade.optimize.space import SKDecimal
|
from freqtrade.optimize.space import SKDecimal
|
||||||
@ -19,13 +18,6 @@ from freqtrade.strategy import IStrategy
|
|||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
def _format_exception_message(method: str, space: str) -> str:
|
|
||||||
return (f"The '{space}' space is included into the hyperoptimization "
|
|
||||||
f"but {method}() method is not found in your "
|
|
||||||
f"custom Hyperopt class. You should either implement this "
|
|
||||||
f"method or remove the '{space}' space from hyperoptimization.")
|
|
||||||
|
|
||||||
|
|
||||||
class IHyperOpt(ABC):
|
class IHyperOpt(ABC):
|
||||||
"""
|
"""
|
||||||
Interface for freqtrade hyperopt
|
Interface for freqtrade hyperopt
|
||||||
@ -45,25 +37,6 @@ class IHyperOpt(ABC):
|
|||||||
IHyperOpt.ticker_interval = str(config['timeframe']) # DEPRECATED
|
IHyperOpt.ticker_interval = str(config['timeframe']) # DEPRECATED
|
||||||
IHyperOpt.timeframe = str(config['timeframe'])
|
IHyperOpt.timeframe = str(config['timeframe'])
|
||||||
|
|
||||||
def protection_space(self) -> List[Dimension]:
|
|
||||||
"""
|
|
||||||
Create a protection space.
|
|
||||||
Only supported by the Parameter interface.
|
|
||||||
"""
|
|
||||||
raise OperationalException(_format_exception_message('indicator_space', 'protection'))
|
|
||||||
|
|
||||||
def indicator_space(self) -> List[Dimension]:
|
|
||||||
"""
|
|
||||||
Create an indicator space.
|
|
||||||
"""
|
|
||||||
raise OperationalException(_format_exception_message('indicator_space', 'buy'))
|
|
||||||
|
|
||||||
def sell_indicator_space(self) -> List[Dimension]:
|
|
||||||
"""
|
|
||||||
Create a sell indicator space.
|
|
||||||
"""
|
|
||||||
raise OperationalException(_format_exception_message('sell_indicator_space', 'sell'))
|
|
||||||
|
|
||||||
def generate_roi_table(self, params: Dict) -> Dict[int, float]:
|
def generate_roi_table(self, params: Dict) -> Dict[int, float]:
|
||||||
"""
|
"""
|
||||||
Create a ROI table.
|
Create a ROI table.
|
||||||
|
@ -10,10 +10,10 @@ import pytest
|
|||||||
|
|
||||||
from freqtrade.commands import (start_convert_data, start_create_userdir, start_download_data,
|
from freqtrade.commands import (start_convert_data, start_create_userdir, start_download_data,
|
||||||
start_hyperopt_list, start_hyperopt_show, start_install_ui,
|
start_hyperopt_list, start_hyperopt_show, start_install_ui,
|
||||||
start_list_data, start_list_exchanges, start_list_hyperopts,
|
start_list_data, start_list_exchanges, start_list_markets,
|
||||||
start_list_markets, start_list_strategies, start_list_timeframes,
|
start_list_strategies, start_list_timeframes, start_new_strategy,
|
||||||
start_new_strategy, start_show_trades,
|
start_show_trades, start_test_pairlist, start_trading,
|
||||||
start_test_pairlist, start_trading, start_webserver)
|
start_webserver)
|
||||||
from freqtrade.commands.deploy_commands import (clean_ui_subdir, download_and_install_ui,
|
from freqtrade.commands.deploy_commands import (clean_ui_subdir, download_and_install_ui,
|
||||||
get_ui_download_url, read_ui_version)
|
get_ui_download_url, read_ui_version)
|
||||||
from freqtrade.configuration import setup_utils_configuration
|
from freqtrade.configuration import setup_utils_configuration
|
||||||
@ -793,37 +793,20 @@ def test_start_list_strategies(mocker, caplog, capsys):
|
|||||||
assert "legacy_strategy_v1.py" in captured.out
|
assert "legacy_strategy_v1.py" in captured.out
|
||||||
assert "StrategyTestV2" in captured.out
|
assert "StrategyTestV2" in captured.out
|
||||||
|
|
||||||
|
# Test color output
|
||||||
def test_start_list_hyperopts(mocker, caplog, capsys):
|
|
||||||
|
|
||||||
args = [
|
args = [
|
||||||
"list-hyperopts",
|
"list-strategies",
|
||||||
"--hyperopt-path",
|
"--strategy-path",
|
||||||
str(Path(__file__).parent.parent / "optimize" / "hyperopts"),
|
str(Path(__file__).parent.parent / "strategy" / "strats"),
|
||||||
"-1"
|
|
||||||
]
|
]
|
||||||
pargs = get_args(args)
|
pargs = get_args(args)
|
||||||
# pargs['config'] = None
|
# pargs['config'] = None
|
||||||
start_list_hyperopts(pargs)
|
start_list_strategies(pargs)
|
||||||
captured = capsys.readouterr()
|
captured = capsys.readouterr()
|
||||||
assert "TestHyperoptLegacy" not in captured.out
|
assert "TestStrategyLegacyV1" in captured.out
|
||||||
assert "legacy_hyperopt.py" not in captured.out
|
assert "legacy_strategy_v1.py" in captured.out
|
||||||
assert "HyperoptTestSepFile" in captured.out
|
assert "StrategyTestV2" in captured.out
|
||||||
assert "test_hyperopt.py" not in captured.out
|
assert "LOAD FAILED" in captured.out
|
||||||
|
|
||||||
# Test regular output
|
|
||||||
args = [
|
|
||||||
"list-hyperopts",
|
|
||||||
"--hyperopt-path",
|
|
||||||
str(Path(__file__).parent.parent / "optimize" / "hyperopts"),
|
|
||||||
]
|
|
||||||
pargs = get_args(args)
|
|
||||||
# pargs['config'] = None
|
|
||||||
start_list_hyperopts(pargs)
|
|
||||||
captured = capsys.readouterr()
|
|
||||||
assert "TestHyperoptLegacy" not in captured.out
|
|
||||||
assert "legacy_hyperopt.py" not in captured.out
|
|
||||||
assert "HyperoptTestSepFile" in captured.out
|
|
||||||
|
|
||||||
|
|
||||||
def test_start_test_pairlist(mocker, caplog, tickers, default_conf, capsys):
|
def test_start_test_pairlist(mocker, caplog, tickers, default_conf, capsys):
|
||||||
|
@ -16,7 +16,7 @@ def hyperopt_conf(default_conf):
|
|||||||
hyperconf.update({
|
hyperconf.update({
|
||||||
'datadir': Path(default_conf['datadir']),
|
'datadir': Path(default_conf['datadir']),
|
||||||
'runmode': RunMode.HYPEROPT,
|
'runmode': RunMode.HYPEROPT,
|
||||||
'hyperopt': 'HyperoptTestSepFile',
|
'strategy': 'HyperoptableStrategy',
|
||||||
'hyperopt_loss': 'ShortTradeDurHyperOptLoss',
|
'hyperopt_loss': 'ShortTradeDurHyperOptLoss',
|
||||||
'hyperopt_path': str(Path(__file__).parent / 'hyperopts'),
|
'hyperopt_path': str(Path(__file__).parent / 'hyperopts'),
|
||||||
'epochs': 1,
|
'epochs': 1,
|
||||||
|
@ -17,7 +17,6 @@ from freqtrade.optimize.hyperopt_auto import HyperOptAuto
|
|||||||
from freqtrade.optimize.hyperopt_tools import HyperoptTools
|
from freqtrade.optimize.hyperopt_tools import HyperoptTools
|
||||||
from freqtrade.optimize.optimize_reports import generate_strategy_stats
|
from freqtrade.optimize.optimize_reports import generate_strategy_stats
|
||||||
from freqtrade.optimize.space import SKDecimal
|
from freqtrade.optimize.space import SKDecimal
|
||||||
from freqtrade.resolvers.hyperopt_resolver import HyperOptResolver
|
|
||||||
from freqtrade.strategy.hyper import IntParameter
|
from freqtrade.strategy.hyper import IntParameter
|
||||||
from tests.conftest import (get_args, log_has, log_has_re, patch_exchange,
|
from tests.conftest import (get_args, log_has, log_has_re, patch_exchange,
|
||||||
patched_configuration_load_config_file)
|
patched_configuration_load_config_file)
|
||||||
@ -133,47 +132,6 @@ def test_setup_hyperopt_configuration_stake_amount(mocker, default_conf) -> None
|
|||||||
setup_optimize_configuration(get_args(args), RunMode.HYPEROPT)
|
setup_optimize_configuration(get_args(args), RunMode.HYPEROPT)
|
||||||
|
|
||||||
|
|
||||||
def test_hyperoptresolver(mocker, default_conf, caplog) -> None:
|
|
||||||
patched_configuration_load_config_file(mocker, default_conf)
|
|
||||||
|
|
||||||
hyperopt = HyperoptTestSepFile
|
|
||||||
delattr(hyperopt, 'populate_indicators')
|
|
||||||
delattr(hyperopt, 'populate_buy_trend')
|
|
||||||
delattr(hyperopt, 'populate_sell_trend')
|
|
||||||
mocker.patch(
|
|
||||||
'freqtrade.resolvers.hyperopt_resolver.HyperOptResolver.load_object',
|
|
||||||
MagicMock(return_value=hyperopt(default_conf))
|
|
||||||
)
|
|
||||||
default_conf.update({'hyperopt': 'HyperoptTestSepFile'})
|
|
||||||
x = HyperOptResolver.load_hyperopt(default_conf)
|
|
||||||
assert not hasattr(x, 'populate_indicators')
|
|
||||||
assert not hasattr(x, 'populate_buy_trend')
|
|
||||||
assert not hasattr(x, 'populate_sell_trend')
|
|
||||||
assert log_has("Hyperopt class does not provide populate_indicators() method. "
|
|
||||||
"Using populate_indicators from the strategy.", caplog)
|
|
||||||
assert log_has("Hyperopt class does not provide populate_sell_trend() method. "
|
|
||||||
"Using populate_sell_trend from the strategy.", caplog)
|
|
||||||
assert log_has("Hyperopt class does not provide populate_buy_trend() method. "
|
|
||||||
"Using populate_buy_trend from the strategy.", caplog)
|
|
||||||
assert hasattr(x, "ticker_interval") # DEPRECATED
|
|
||||||
assert hasattr(x, "timeframe")
|
|
||||||
|
|
||||||
|
|
||||||
def test_hyperoptresolver_wrongname(default_conf) -> None:
|
|
||||||
default_conf.update({'hyperopt': "NonExistingHyperoptClass"})
|
|
||||||
|
|
||||||
with pytest.raises(OperationalException, match=r'Impossible to load Hyperopt.*'):
|
|
||||||
HyperOptResolver.load_hyperopt(default_conf)
|
|
||||||
|
|
||||||
|
|
||||||
def test_hyperoptresolver_noname(default_conf):
|
|
||||||
default_conf['hyperopt'] = ''
|
|
||||||
with pytest.raises(OperationalException,
|
|
||||||
match="No Hyperopt set. Please use `--hyperopt` to specify "
|
|
||||||
"the Hyperopt class to use."):
|
|
||||||
HyperOptResolver.load_hyperopt(default_conf)
|
|
||||||
|
|
||||||
|
|
||||||
def test_start_not_installed(mocker, default_conf, import_fails) -> None:
|
def test_start_not_installed(mocker, default_conf, import_fails) -> None:
|
||||||
start_mock = MagicMock()
|
start_mock = MagicMock()
|
||||||
patched_configuration_load_config_file(mocker, default_conf)
|
patched_configuration_load_config_file(mocker, default_conf)
|
||||||
@ -196,7 +154,7 @@ def test_start_not_installed(mocker, default_conf, import_fails) -> None:
|
|||||||
start_hyperopt(pargs)
|
start_hyperopt(pargs)
|
||||||
|
|
||||||
|
|
||||||
def test_start(mocker, hyperopt_conf, caplog) -> None:
|
def test_start_no_hyperopt_allowed(mocker, hyperopt_conf, caplog) -> None:
|
||||||
start_mock = MagicMock()
|
start_mock = MagicMock()
|
||||||
patched_configuration_load_config_file(mocker, hyperopt_conf)
|
patched_configuration_load_config_file(mocker, hyperopt_conf)
|
||||||
mocker.patch('freqtrade.optimize.hyperopt.Hyperopt.start', start_mock)
|
mocker.patch('freqtrade.optimize.hyperopt.Hyperopt.start', start_mock)
|
||||||
@ -210,11 +168,9 @@ def test_start(mocker, hyperopt_conf, caplog) -> None:
|
|||||||
'--epochs', '5'
|
'--epochs', '5'
|
||||||
]
|
]
|
||||||
pargs = get_args(args)
|
pargs = get_args(args)
|
||||||
|
with pytest.raises(OperationalException, match=r"Using separate Hyperopt files has been.*"):
|
||||||
start_hyperopt(pargs)
|
start_hyperopt(pargs)
|
||||||
|
|
||||||
assert log_has('Starting freqtrade in Hyperopt mode', caplog)
|
|
||||||
assert start_mock.call_count == 1
|
|
||||||
|
|
||||||
|
|
||||||
def test_start_no_data(mocker, hyperopt_conf) -> None:
|
def test_start_no_data(mocker, hyperopt_conf) -> None:
|
||||||
patched_configuration_load_config_file(mocker, hyperopt_conf)
|
patched_configuration_load_config_file(mocker, hyperopt_conf)
|
||||||
@ -225,11 +181,11 @@ def test_start_no_data(mocker, hyperopt_conf) -> None:
|
|||||||
)
|
)
|
||||||
|
|
||||||
patch_exchange(mocker)
|
patch_exchange(mocker)
|
||||||
|
# TODO: migrate to strategy-based hyperopt
|
||||||
args = [
|
args = [
|
||||||
'hyperopt',
|
'hyperopt',
|
||||||
'--config', 'config.json',
|
'--config', 'config.json',
|
||||||
'--hyperopt', 'HyperoptTestSepFile',
|
'--strategy', 'HyperoptableStrategy',
|
||||||
'--hyperopt-loss', 'SharpeHyperOptLossDaily',
|
'--hyperopt-loss', 'SharpeHyperOptLossDaily',
|
||||||
'--epochs', '5'
|
'--epochs', '5'
|
||||||
]
|
]
|
||||||
@ -427,66 +383,14 @@ def test_hyperopt_format_results(hyperopt):
|
|||||||
def test_populate_indicators(hyperopt, testdatadir) -> None:
|
def test_populate_indicators(hyperopt, testdatadir) -> None:
|
||||||
data = load_data(testdatadir, '1m', ['UNITTEST/BTC'], fill_up_missing=True)
|
data = load_data(testdatadir, '1m', ['UNITTEST/BTC'], fill_up_missing=True)
|
||||||
dataframes = hyperopt.backtesting.strategy.advise_all_indicators(data)
|
dataframes = hyperopt.backtesting.strategy.advise_all_indicators(data)
|
||||||
dataframe = hyperopt.custom_hyperopt.populate_indicators(dataframes['UNITTEST/BTC'],
|
dataframe = dataframes['UNITTEST/BTC']
|
||||||
{'pair': 'UNITTEST/BTC'})
|
|
||||||
|
|
||||||
# Check if some indicators are generated. We will not test all of them
|
# Check if some indicators are generated. We will not test all of them
|
||||||
assert 'adx' in dataframe
|
assert 'adx' in dataframe
|
||||||
assert 'mfi' in dataframe
|
assert 'macd' in dataframe
|
||||||
assert 'rsi' in dataframe
|
assert 'rsi' in dataframe
|
||||||
|
|
||||||
|
|
||||||
def test_buy_strategy_generator(hyperopt, testdatadir) -> None:
|
|
||||||
data = load_data(testdatadir, '1m', ['UNITTEST/BTC'], fill_up_missing=True)
|
|
||||||
dataframes = hyperopt.backtesting.strategy.advise_all_indicators(data)
|
|
||||||
dataframe = hyperopt.custom_hyperopt.populate_indicators(dataframes['UNITTEST/BTC'],
|
|
||||||
{'pair': 'UNITTEST/BTC'})
|
|
||||||
|
|
||||||
populate_buy_trend = hyperopt.custom_hyperopt.buy_strategy_generator(
|
|
||||||
{
|
|
||||||
'adx-value': 20,
|
|
||||||
'fastd-value': 20,
|
|
||||||
'mfi-value': 20,
|
|
||||||
'rsi-value': 20,
|
|
||||||
'adx-enabled': True,
|
|
||||||
'fastd-enabled': True,
|
|
||||||
'mfi-enabled': True,
|
|
||||||
'rsi-enabled': True,
|
|
||||||
'trigger': 'bb_lower'
|
|
||||||
}
|
|
||||||
)
|
|
||||||
result = populate_buy_trend(dataframe, {'pair': 'UNITTEST/BTC'})
|
|
||||||
# Check if some indicators are generated. We will not test all of them
|
|
||||||
assert 'buy' in result
|
|
||||||
assert 1 in result['buy']
|
|
||||||
|
|
||||||
|
|
||||||
def test_sell_strategy_generator(hyperopt, testdatadir) -> None:
|
|
||||||
data = load_data(testdatadir, '1m', ['UNITTEST/BTC'], fill_up_missing=True)
|
|
||||||
dataframes = hyperopt.backtesting.strategy.advise_all_indicators(data)
|
|
||||||
dataframe = hyperopt.custom_hyperopt.populate_indicators(dataframes['UNITTEST/BTC'],
|
|
||||||
{'pair': 'UNITTEST/BTC'})
|
|
||||||
|
|
||||||
populate_sell_trend = hyperopt.custom_hyperopt.sell_strategy_generator(
|
|
||||||
{
|
|
||||||
'sell-adx-value': 20,
|
|
||||||
'sell-fastd-value': 75,
|
|
||||||
'sell-mfi-value': 80,
|
|
||||||
'sell-rsi-value': 20,
|
|
||||||
'sell-adx-enabled': True,
|
|
||||||
'sell-fastd-enabled': True,
|
|
||||||
'sell-mfi-enabled': True,
|
|
||||||
'sell-rsi-enabled': True,
|
|
||||||
'sell-trigger': 'sell-bb_upper'
|
|
||||||
}
|
|
||||||
)
|
|
||||||
result = populate_sell_trend(dataframe, {'pair': 'UNITTEST/BTC'})
|
|
||||||
# Check if some indicators are generated. We will not test all of them
|
|
||||||
print(result)
|
|
||||||
assert 'sell' in result
|
|
||||||
assert 1 in result['sell']
|
|
||||||
|
|
||||||
|
|
||||||
def test_generate_optimizer(mocker, hyperopt_conf) -> None:
|
def test_generate_optimizer(mocker, hyperopt_conf) -> None:
|
||||||
hyperopt_conf.update({'spaces': 'all',
|
hyperopt_conf.update({'spaces': 'all',
|
||||||
'hyperopt_min_trades': 1,
|
'hyperopt_min_trades': 1,
|
||||||
@ -527,24 +431,12 @@ def test_generate_optimizer(mocker, hyperopt_conf) -> None:
|
|||||||
mocker.patch('freqtrade.optimize.hyperopt.load', return_value={'XRP/BTC': None})
|
mocker.patch('freqtrade.optimize.hyperopt.load', return_value={'XRP/BTC': None})
|
||||||
|
|
||||||
optimizer_param = {
|
optimizer_param = {
|
||||||
'adx-value': 0,
|
'buy_plusdi': 0.02,
|
||||||
'fastd-value': 35,
|
'buy_rsi': 35,
|
||||||
'mfi-value': 0,
|
'sell_minusdi': 0.02,
|
||||||
'rsi-value': 0,
|
'sell_rsi': 75,
|
||||||
'adx-enabled': False,
|
'protection_cooldown_lookback': 20,
|
||||||
'fastd-enabled': True,
|
'protection_enabled': True,
|
||||||
'mfi-enabled': False,
|
|
||||||
'rsi-enabled': False,
|
|
||||||
'trigger': 'macd_cross_signal',
|
|
||||||
'sell-adx-value': 0,
|
|
||||||
'sell-fastd-value': 75,
|
|
||||||
'sell-mfi-value': 0,
|
|
||||||
'sell-rsi-value': 0,
|
|
||||||
'sell-adx-enabled': False,
|
|
||||||
'sell-fastd-enabled': True,
|
|
||||||
'sell-mfi-enabled': False,
|
|
||||||
'sell-rsi-enabled': False,
|
|
||||||
'sell-trigger': 'macd_cross_signal',
|
|
||||||
'roi_t1': 60.0,
|
'roi_t1': 60.0,
|
||||||
'roi_t2': 30.0,
|
'roi_t2': 30.0,
|
||||||
'roi_t3': 20.0,
|
'roi_t3': 20.0,
|
||||||
@ -564,29 +456,19 @@ def test_generate_optimizer(mocker, hyperopt_conf) -> None:
|
|||||||
'0.00003100 BTC ( 0.00%). '
|
'0.00003100 BTC ( 0.00%). '
|
||||||
'Avg duration 0:50:00 min.'
|
'Avg duration 0:50:00 min.'
|
||||||
),
|
),
|
||||||
'params_details': {'buy': {'adx-enabled': False,
|
'params_details': {'buy': {'buy_plusdi': 0.02,
|
||||||
'adx-value': 0,
|
'buy_rsi': 35,
|
||||||
'fastd-enabled': True,
|
},
|
||||||
'fastd-value': 35,
|
|
||||||
'mfi-enabled': False,
|
|
||||||
'mfi-value': 0,
|
|
||||||
'rsi-enabled': False,
|
|
||||||
'rsi-value': 0,
|
|
||||||
'trigger': 'macd_cross_signal'},
|
|
||||||
'roi': {"0": 0.12000000000000001,
|
'roi': {"0": 0.12000000000000001,
|
||||||
"20.0": 0.02,
|
"20.0": 0.02,
|
||||||
"50.0": 0.01,
|
"50.0": 0.01,
|
||||||
"110.0": 0},
|
"110.0": 0},
|
||||||
'protection': {},
|
'protection': {'protection_cooldown_lookback': 20,
|
||||||
'sell': {'sell-adx-enabled': False,
|
'protection_enabled': True,
|
||||||
'sell-adx-value': 0,
|
},
|
||||||
'sell-fastd-enabled': True,
|
'sell': {'sell_minusdi': 0.02,
|
||||||
'sell-fastd-value': 75,
|
'sell_rsi': 75,
|
||||||
'sell-mfi-enabled': False,
|
},
|
||||||
'sell-mfi-value': 0,
|
|
||||||
'sell-rsi-enabled': False,
|
|
||||||
'sell-rsi-value': 0,
|
|
||||||
'sell-trigger': 'macd_cross_signal'},
|
|
||||||
'stoploss': {'stoploss': -0.4},
|
'stoploss': {'stoploss': -0.4},
|
||||||
'trailing': {'trailing_only_offset_is_reached': False,
|
'trailing': {'trailing_only_offset_is_reached': False,
|
||||||
'trailing_stop': True,
|
'trailing_stop': True,
|
||||||
@ -808,11 +690,6 @@ def test_simplified_interface_roi_stoploss(mocker, hyperopt_conf, capsys) -> Non
|
|||||||
hyperopt.backtesting.strategy.advise_all_indicators = MagicMock()
|
hyperopt.backtesting.strategy.advise_all_indicators = MagicMock()
|
||||||
hyperopt.custom_hyperopt.generate_roi_table = MagicMock(return_value={})
|
hyperopt.custom_hyperopt.generate_roi_table = MagicMock(return_value={})
|
||||||
|
|
||||||
del hyperopt.custom_hyperopt.__class__.buy_strategy_generator
|
|
||||||
del hyperopt.custom_hyperopt.__class__.sell_strategy_generator
|
|
||||||
del hyperopt.custom_hyperopt.__class__.indicator_space
|
|
||||||
del hyperopt.custom_hyperopt.__class__.sell_indicator_space
|
|
||||||
|
|
||||||
hyperopt.start()
|
hyperopt.start()
|
||||||
|
|
||||||
parallel.assert_called_once()
|
parallel.assert_called_once()
|
||||||
@ -843,16 +720,14 @@ def test_simplified_interface_all_failed(mocker, hyperopt_conf) -> None:
|
|||||||
|
|
||||||
hyperopt_conf.update({'spaces': 'all', })
|
hyperopt_conf.update({'spaces': 'all', })
|
||||||
|
|
||||||
|
mocker.patch('freqtrade.optimize.hyperopt_auto.HyperOptAuto._generate_indicator_space',
|
||||||
|
return_value=[])
|
||||||
|
|
||||||
hyperopt = Hyperopt(hyperopt_conf)
|
hyperopt = Hyperopt(hyperopt_conf)
|
||||||
hyperopt.backtesting.strategy.advise_all_indicators = MagicMock()
|
hyperopt.backtesting.strategy.advise_all_indicators = MagicMock()
|
||||||
hyperopt.custom_hyperopt.generate_roi_table = MagicMock(return_value={})
|
hyperopt.custom_hyperopt.generate_roi_table = MagicMock(return_value={})
|
||||||
|
|
||||||
del hyperopt.custom_hyperopt.__class__.buy_strategy_generator
|
with pytest.raises(OperationalException, match=r"The 'protection' space is included into *"):
|
||||||
del hyperopt.custom_hyperopt.__class__.sell_strategy_generator
|
|
||||||
del hyperopt.custom_hyperopt.__class__.indicator_space
|
|
||||||
del hyperopt.custom_hyperopt.__class__.sell_indicator_space
|
|
||||||
|
|
||||||
with pytest.raises(OperationalException, match=r"The 'buy' space is included into *"):
|
|
||||||
hyperopt.start()
|
hyperopt.start()
|
||||||
|
|
||||||
|
|
||||||
@ -889,11 +764,6 @@ def test_simplified_interface_buy(mocker, hyperopt_conf, capsys) -> None:
|
|||||||
hyperopt.backtesting.strategy.advise_all_indicators = MagicMock()
|
hyperopt.backtesting.strategy.advise_all_indicators = MagicMock()
|
||||||
hyperopt.custom_hyperopt.generate_roi_table = MagicMock(return_value={})
|
hyperopt.custom_hyperopt.generate_roi_table = MagicMock(return_value={})
|
||||||
|
|
||||||
# TODO: sell_strategy_generator() is actually not called because
|
|
||||||
# run_optimizer_parallel() is mocked
|
|
||||||
del hyperopt.custom_hyperopt.__class__.sell_strategy_generator
|
|
||||||
del hyperopt.custom_hyperopt.__class__.sell_indicator_space
|
|
||||||
|
|
||||||
hyperopt.start()
|
hyperopt.start()
|
||||||
|
|
||||||
parallel.assert_called_once()
|
parallel.assert_called_once()
|
||||||
@ -943,11 +813,6 @@ def test_simplified_interface_sell(mocker, hyperopt_conf, capsys) -> None:
|
|||||||
hyperopt.backtesting.strategy.advise_all_indicators = MagicMock()
|
hyperopt.backtesting.strategy.advise_all_indicators = MagicMock()
|
||||||
hyperopt.custom_hyperopt.generate_roi_table = MagicMock(return_value={})
|
hyperopt.custom_hyperopt.generate_roi_table = MagicMock(return_value={})
|
||||||
|
|
||||||
# TODO: buy_strategy_generator() is actually not called because
|
|
||||||
# run_optimizer_parallel() is mocked
|
|
||||||
del hyperopt.custom_hyperopt.__class__.buy_strategy_generator
|
|
||||||
del hyperopt.custom_hyperopt.__class__.indicator_space
|
|
||||||
|
|
||||||
hyperopt.start()
|
hyperopt.start()
|
||||||
|
|
||||||
parallel.assert_called_once()
|
parallel.assert_called_once()
|
||||||
@ -964,13 +829,12 @@ def test_simplified_interface_sell(mocker, hyperopt_conf, capsys) -> None:
|
|||||||
assert hasattr(hyperopt, "position_stacking")
|
assert hasattr(hyperopt, "position_stacking")
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize("method,space", [
|
@pytest.mark.parametrize("space", [
|
||||||
('buy_strategy_generator', 'buy'),
|
('buy'),
|
||||||
('indicator_space', 'buy'),
|
('sell'),
|
||||||
('sell_strategy_generator', 'sell'),
|
('protection'),
|
||||||
('sell_indicator_space', 'sell'),
|
|
||||||
])
|
])
|
||||||
def test_simplified_interface_failed(mocker, hyperopt_conf, method, space) -> None:
|
def test_simplified_interface_failed(mocker, hyperopt_conf, space) -> None:
|
||||||
mocker.patch('freqtrade.optimize.hyperopt.dump', MagicMock())
|
mocker.patch('freqtrade.optimize.hyperopt.dump', MagicMock())
|
||||||
mocker.patch('freqtrade.optimize.hyperopt.file_dump_json')
|
mocker.patch('freqtrade.optimize.hyperopt.file_dump_json')
|
||||||
mocker.patch('freqtrade.optimize.backtesting.Backtesting.load_bt_data',
|
mocker.patch('freqtrade.optimize.backtesting.Backtesting.load_bt_data',
|
||||||
@ -979,6 +843,8 @@ def test_simplified_interface_failed(mocker, hyperopt_conf, method, space) -> No
|
|||||||
'freqtrade.optimize.hyperopt.get_timerange',
|
'freqtrade.optimize.hyperopt.get_timerange',
|
||||||
MagicMock(return_value=(datetime(2017, 12, 10), datetime(2017, 12, 13)))
|
MagicMock(return_value=(datetime(2017, 12, 10), datetime(2017, 12, 13)))
|
||||||
)
|
)
|
||||||
|
mocker.patch('freqtrade.optimize.hyperopt_auto.HyperOptAuto._generate_indicator_space',
|
||||||
|
return_value=[])
|
||||||
|
|
||||||
patch_exchange(mocker)
|
patch_exchange(mocker)
|
||||||
|
|
||||||
@ -988,8 +854,6 @@ def test_simplified_interface_failed(mocker, hyperopt_conf, method, space) -> No
|
|||||||
hyperopt.backtesting.strategy.advise_all_indicators = MagicMock()
|
hyperopt.backtesting.strategy.advise_all_indicators = MagicMock()
|
||||||
hyperopt.custom_hyperopt.generate_roi_table = MagicMock(return_value={})
|
hyperopt.custom_hyperopt.generate_roi_table = MagicMock(return_value={})
|
||||||
|
|
||||||
delattr(hyperopt.custom_hyperopt.__class__, method)
|
|
||||||
|
|
||||||
with pytest.raises(OperationalException, match=f"The '{space}' space is included into *"):
|
with pytest.raises(OperationalException, match=f"The '{space}' space is included into *"):
|
||||||
hyperopt.start()
|
hyperopt.start()
|
||||||
|
|
||||||
@ -999,7 +863,6 @@ def test_in_strategy_auto_hyperopt(mocker, hyperopt_conf, tmpdir, fee) -> None:
|
|||||||
mocker.patch('freqtrade.exchange.Exchange.get_fee', fee)
|
mocker.patch('freqtrade.exchange.Exchange.get_fee', fee)
|
||||||
(Path(tmpdir) / 'hyperopt_results').mkdir(parents=True)
|
(Path(tmpdir) / 'hyperopt_results').mkdir(parents=True)
|
||||||
# No hyperopt needed
|
# No hyperopt needed
|
||||||
del hyperopt_conf['hyperopt']
|
|
||||||
hyperopt_conf.update({
|
hyperopt_conf.update({
|
||||||
'strategy': 'HyperoptableStrategy',
|
'strategy': 'HyperoptableStrategy',
|
||||||
'user_data_dir': Path(tmpdir),
|
'user_data_dir': Path(tmpdir),
|
||||||
|
Loading…
Reference in New Issue
Block a user