refactor backtesting to avoid recalculating indicators in hyperopt

This commit is contained in:
Janne Sinivirta 2017-11-15 20:06:37 +02:00
parent 1ccb266032
commit 1b6a60ecb2
2 changed files with 19 additions and 10 deletions

View File

@ -1,4 +1,5 @@
# pragma pylint: disable=missing-docstring
from typing import Dict
import logging
import os
@ -7,7 +8,8 @@ import arrow
from pandas import DataFrame
from freqtrade import exchange
from freqtrade.analyze import analyze_ticker
from freqtrade.analyze import parse_ticker_dataframe, populate_indicators, \
populate_buy_trend, populate_sell_trend
from freqtrade.exchange import Bittrex
from freqtrade.main import min_roi_reached
from freqtrade.persistence import Trade
@ -25,15 +27,21 @@ def print_pair_results(pair, results):
print(format_results(results[results.currency == pair]))
def backtest(backtest_conf, backdata, mocker):
def preprocess(backdata) -> Dict[str, DataFrame]:
processed = {}
for pair, pair_data in backdata.items():
processed[pair] = populate_indicators(parse_ticker_dataframe(pair_data))
return processed
def backtest(backtest_conf, processed, mocker):
trades = []
exchange._API = Bittrex({'key': '', 'secret': ''})
mocked_history = mocker.patch('freqtrade.analyze.get_ticker_history')
mocker.patch.dict('freqtrade.main._CONF', backtest_conf)
mocker.patch('arrow.utcnow', return_value=arrow.get('2017-08-20T14:50:00'))
for pair, pair_data in backdata.items():
mocked_history.return_value = pair_data
ticker = analyze_ticker(pair)[['close', 'date', 'buy', 'sell']].copy()
for pair, pair_data in processed.items():
ticker = populate_sell_trend(populate_buy_trend(pair_data))[['close', 'date', 'buy', 'sell']].copy()
# for each buy point
for row in ticker[ticker.buy == 1].itertuples(index=True):
trade = Trade(
@ -56,7 +64,7 @@ def backtest(backtest_conf, backdata, mocker):
@pytest.mark.skipif(not os.environ.get('BACKTEST', False), reason="BACKTEST not set")
def test_backtest(backtest_conf, backdata, mocker, report=True):
results = backtest(backtest_conf, backdata, mocker)
results = backtest(backtest_conf, preprocess(backdata), mocker)
print('====================== BACKTESTING REPORT ================================')
for pair in backdata:

View File

@ -9,7 +9,7 @@ import pytest
from hyperopt import fmin, tpe, hp, Trials, STATUS_OK
from pandas import DataFrame
from freqtrade.tests.test_backtesting import backtest, format_results
from freqtrade.tests.test_backtesting import backtest, format_results, preprocess
from freqtrade.vendor.qtpylib.indicators import crossed_above
logging.disable(logging.DEBUG) # disable debug logs that slow backtesting a lot
@ -67,12 +67,13 @@ def buy_strategy_generator(params):
@pytest.mark.skipif(not os.environ.get('BACKTEST', False), reason="BACKTEST not set")
def test_hyperopt(backtest_conf, backdata, mocker):
mocked_buy_trend = mocker.patch('freqtrade.analyze.populate_buy_trend')
mocked_buy_trend = mocker.patch('freqtrade.tests.test_backtesting.populate_buy_trend')
processed = preprocess(backdata)
def optimizer(params):
mocked_buy_trend.side_effect = buy_strategy_generator(params)
results = backtest(backtest_conf, backdata, mocker)
results = backtest(backtest_conf, processed, mocker)
result = format_results(results)