Merge pull request #2175 from hroff-1902/hyperopt-split-backtesting

Hyperopt redesign
This commit is contained in:
Matthias 2019-08-24 14:39:46 +02:00 committed by GitHub
commit 3820a38e79
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 24 additions and 22 deletions

View File

@ -37,7 +37,7 @@ INITIAL_POINTS = 30
MAX_LOSS = 100000 # just a big enough number to be bad result in loss optimization MAX_LOSS = 100000 # just a big enough number to be bad result in loss optimization
class Hyperopt(Backtesting): class Hyperopt:
""" """
Hyperopt class, this class contains all the logic to run a hyperopt simulation Hyperopt class, this class contains all the logic to run a hyperopt simulation
@ -46,7 +46,9 @@ class Hyperopt(Backtesting):
hyperopt.start() hyperopt.start()
""" """
def __init__(self, config: Dict[str, Any]) -> None: def __init__(self, config: Dict[str, Any]) -> None:
super().__init__(config) self.config = config
self.backtesting = Backtesting(self.config)
self.custom_hyperopt = HyperOptResolver(self.config).hyperopt self.custom_hyperopt = HyperOptResolver(self.config).hyperopt
self.custom_hyperoptloss = HyperOptLossResolver(self.config).hyperoptloss self.custom_hyperoptloss = HyperOptLossResolver(self.config).hyperoptloss
@ -70,10 +72,10 @@ class Hyperopt(Backtesting):
# Populate functions here (hasattr is slow so should not be run during "regular" operations) # Populate functions here (hasattr is slow so should not be run during "regular" operations)
if hasattr(self.custom_hyperopt, 'populate_buy_trend'): if hasattr(self.custom_hyperopt, 'populate_buy_trend'):
self.advise_buy = self.custom_hyperopt.populate_buy_trend # type: ignore self.backtesting.advise_buy = self.custom_hyperopt.populate_buy_trend # type: ignore
if hasattr(self.custom_hyperopt, 'populate_sell_trend'): if hasattr(self.custom_hyperopt, 'populate_sell_trend'):
self.advise_sell = self.custom_hyperopt.populate_sell_trend # type: ignore self.backtesting.advise_sell = self.custom_hyperopt.populate_sell_trend # type: ignore
# Use max_open_trades for hyperopt as well, except --disable-max-market-positions is set # Use max_open_trades for hyperopt as well, except --disable-max-market-positions is set
if self.config.get('use_max_market_positions', True): if self.config.get('use_max_market_positions', True):
@ -249,22 +251,22 @@ class Hyperopt(Backtesting):
""" """
params = self.get_args(_params) params = self.get_args(_params)
if self.has_space('roi'): if self.has_space('roi'):
self.strategy.minimal_roi = self.custom_hyperopt.generate_roi_table(params) self.backtesting.strategy.minimal_roi = self.custom_hyperopt.generate_roi_table(params)
if self.has_space('buy'): if self.has_space('buy'):
self.advise_buy = self.custom_hyperopt.buy_strategy_generator(params) self.backtesting.advise_buy = self.custom_hyperopt.buy_strategy_generator(params)
if self.has_space('sell'): if self.has_space('sell'):
self.advise_sell = self.custom_hyperopt.sell_strategy_generator(params) self.backtesting.advise_sell = self.custom_hyperopt.sell_strategy_generator(params)
if self.has_space('stoploss'): if self.has_space('stoploss'):
self.strategy.stoploss = params['stoploss'] self.backtesting.strategy.stoploss = params['stoploss']
processed = load(self.tickerdata_pickle) processed = load(self.tickerdata_pickle)
min_date, max_date = get_timeframe(processed) min_date, max_date = get_timeframe(processed)
results = self.backtest( results = self.backtesting.backtest(
{ {
'stake_amount': self.config['stake_amount'], 'stake_amount': self.config['stake_amount'],
'processed': processed, 'processed': processed,
@ -345,9 +347,9 @@ class Hyperopt(Backtesting):
data = load_data( data = load_data(
datadir=Path(self.config['datadir']) if self.config.get('datadir') else None, datadir=Path(self.config['datadir']) if self.config.get('datadir') else None,
pairs=self.config['exchange']['pair_whitelist'], pairs=self.config['exchange']['pair_whitelist'],
ticker_interval=self.ticker_interval, ticker_interval=self.backtesting.ticker_interval,
refresh_pairs=self.config.get('refresh_pairs', False), refresh_pairs=self.config.get('refresh_pairs', False),
exchange=self.exchange, exchange=self.backtesting.exchange,
timerange=timerange timerange=timerange
) )
@ -364,15 +366,15 @@ class Hyperopt(Backtesting):
(max_date - min_date).days (max_date - min_date).days
) )
self.strategy.advise_indicators = \ self.backtesting.strategy.advise_indicators = \
self.custom_hyperopt.populate_indicators # type: ignore self.custom_hyperopt.populate_indicators # type: ignore
preprocessed = self.strategy.tickerdata_to_dataframe(data) preprocessed = self.backtesting.strategy.tickerdata_to_dataframe(data)
dump(preprocessed, self.tickerdata_pickle) dump(preprocessed, self.tickerdata_pickle)
# We don't need exchange instance anymore while running hyperopt # We don't need exchange instance anymore while running hyperopt
self.exchange = None # type: ignore self.backtesting.exchange = None # type: ignore
self.load_previous_results() self.load_previous_results()

View File

@ -429,7 +429,7 @@ def test_start_calls_optimizer(mocker, default_conf, caplog, capsys) -> None:
'hyperopt_jobs': 1, }) 'hyperopt_jobs': 1, })
hyperopt = Hyperopt(default_conf) hyperopt = Hyperopt(default_conf)
hyperopt.strategy.tickerdata_to_dataframe = MagicMock() hyperopt.backtesting.strategy.tickerdata_to_dataframe = MagicMock()
hyperopt.custom_hyperopt.generate_roi_table = MagicMock(return_value={}) hyperopt.custom_hyperopt.generate_roi_table = MagicMock(return_value={})
hyperopt.start() hyperopt.start()
@ -441,8 +441,8 @@ def test_start_calls_optimizer(mocker, default_conf, caplog, capsys) -> None:
assert dumper.called assert dumper.called
# Should be called twice, once for tickerdata, once to save evaluations # Should be called twice, once for tickerdata, once to save evaluations
assert dumper.call_count == 2 assert dumper.call_count == 2
assert hasattr(hyperopt, "advise_sell") assert hasattr(hyperopt.backtesting, "advise_sell")
assert hasattr(hyperopt, "advise_buy") assert hasattr(hyperopt.backtesting, "advise_buy")
assert hasattr(hyperopt, "max_open_trades") assert hasattr(hyperopt, "max_open_trades")
assert hyperopt.max_open_trades == default_conf['max_open_trades'] assert hyperopt.max_open_trades == default_conf['max_open_trades']
assert hasattr(hyperopt, "position_stacking") assert hasattr(hyperopt, "position_stacking")
@ -488,7 +488,7 @@ def test_populate_indicators(hyperopt) -> None:
tick = load_tickerdata_file(None, 'UNITTEST/BTC', '1m') tick = load_tickerdata_file(None, 'UNITTEST/BTC', '1m')
tickerlist = {'UNITTEST/BTC': parse_ticker_dataframe(tick, '1m', pair="UNITTEST/BTC", tickerlist = {'UNITTEST/BTC': parse_ticker_dataframe(tick, '1m', pair="UNITTEST/BTC",
fill_missing=True)} fill_missing=True)}
dataframes = hyperopt.strategy.tickerdata_to_dataframe(tickerlist) dataframes = hyperopt.backtesting.strategy.tickerdata_to_dataframe(tickerlist)
dataframe = hyperopt.custom_hyperopt.populate_indicators(dataframes['UNITTEST/BTC'], dataframe = hyperopt.custom_hyperopt.populate_indicators(dataframes['UNITTEST/BTC'],
{'pair': 'UNITTEST/BTC'}) {'pair': 'UNITTEST/BTC'})
@ -502,7 +502,7 @@ def test_buy_strategy_generator(hyperopt) -> None:
tick = load_tickerdata_file(None, 'UNITTEST/BTC', '1m') tick = load_tickerdata_file(None, 'UNITTEST/BTC', '1m')
tickerlist = {'UNITTEST/BTC': parse_ticker_dataframe(tick, '1m', pair="UNITTEST/BTC", tickerlist = {'UNITTEST/BTC': parse_ticker_dataframe(tick, '1m', pair="UNITTEST/BTC",
fill_missing=True)} fill_missing=True)}
dataframes = hyperopt.strategy.tickerdata_to_dataframe(tickerlist) dataframes = hyperopt.backtesting.strategy.tickerdata_to_dataframe(tickerlist)
dataframe = hyperopt.custom_hyperopt.populate_indicators(dataframes['UNITTEST/BTC'], dataframe = hyperopt.custom_hyperopt.populate_indicators(dataframes['UNITTEST/BTC'],
{'pair': 'UNITTEST/BTC'}) {'pair': 'UNITTEST/BTC'})
@ -538,7 +538,7 @@ def test_generate_optimizer(mocker, default_conf) -> None:
backtest_result = pd.DataFrame.from_records(trades, columns=labels) backtest_result = pd.DataFrame.from_records(trades, columns=labels)
mocker.patch( mocker.patch(
'freqtrade.optimize.hyperopt.Hyperopt.backtest', 'freqtrade.optimize.hyperopt.Backtesting.backtest',
MagicMock(return_value=backtest_result) MagicMock(return_value=backtest_result)
) )
mocker.patch( mocker.patch(
@ -644,7 +644,7 @@ def test_print_json_spaces_all(mocker, default_conf, caplog, capsys) -> None:
}) })
hyperopt = Hyperopt(default_conf) hyperopt = Hyperopt(default_conf)
hyperopt.strategy.tickerdata_to_dataframe = MagicMock() hyperopt.backtesting.strategy.tickerdata_to_dataframe = MagicMock()
hyperopt.custom_hyperopt.generate_roi_table = MagicMock(return_value={}) hyperopt.custom_hyperopt.generate_roi_table = MagicMock(return_value={})
hyperopt.start() hyperopt.start()
@ -681,7 +681,7 @@ def test_print_json_spaces_roi_stoploss(mocker, default_conf, caplog, capsys) ->
}) })
hyperopt = Hyperopt(default_conf) hyperopt = Hyperopt(default_conf)
hyperopt.strategy.tickerdata_to_dataframe = MagicMock() hyperopt.backtesting.strategy.tickerdata_to_dataframe = MagicMock()
hyperopt.custom_hyperopt.generate_roi_table = MagicMock(return_value={}) hyperopt.custom_hyperopt.generate_roi_table = MagicMock(return_value={})
hyperopt.start() hyperopt.start()