refactor backtesting to avoid recalculating indicators in hyperopt
This commit is contained in:
parent
1ccb266032
commit
1b6a60ecb2
@ -1,4 +1,5 @@
|
|||||||
# pragma pylint: disable=missing-docstring
|
# pragma pylint: disable=missing-docstring
|
||||||
|
from typing import Dict
|
||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
|
|
||||||
@ -7,7 +8,8 @@ import arrow
|
|||||||
from pandas import DataFrame
|
from pandas import DataFrame
|
||||||
|
|
||||||
from freqtrade import exchange
|
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.exchange import Bittrex
|
||||||
from freqtrade.main import min_roi_reached
|
from freqtrade.main import min_roi_reached
|
||||||
from freqtrade.persistence import Trade
|
from freqtrade.persistence import Trade
|
||||||
@ -25,15 +27,21 @@ def print_pair_results(pair, results):
|
|||||||
print(format_results(results[results.currency == pair]))
|
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 = []
|
trades = []
|
||||||
exchange._API = Bittrex({'key': '', 'secret': ''})
|
exchange._API = Bittrex({'key': '', 'secret': ''})
|
||||||
mocked_history = mocker.patch('freqtrade.analyze.get_ticker_history')
|
|
||||||
mocker.patch.dict('freqtrade.main._CONF', backtest_conf)
|
mocker.patch.dict('freqtrade.main._CONF', backtest_conf)
|
||||||
mocker.patch('arrow.utcnow', return_value=arrow.get('2017-08-20T14:50:00'))
|
mocker.patch('arrow.utcnow', return_value=arrow.get('2017-08-20T14:50:00'))
|
||||||
for pair, pair_data in backdata.items():
|
for pair, pair_data in processed.items():
|
||||||
mocked_history.return_value = pair_data
|
ticker = populate_sell_trend(populate_buy_trend(pair_data))[['close', 'date', 'buy', 'sell']].copy()
|
||||||
ticker = analyze_ticker(pair)[['close', 'date', 'buy', 'sell']].copy()
|
|
||||||
# for each buy point
|
# for each buy point
|
||||||
for row in ticker[ticker.buy == 1].itertuples(index=True):
|
for row in ticker[ticker.buy == 1].itertuples(index=True):
|
||||||
trade = Trade(
|
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")
|
@pytest.mark.skipif(not os.environ.get('BACKTEST', False), reason="BACKTEST not set")
|
||||||
def test_backtest(backtest_conf, backdata, mocker, report=True):
|
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 ================================')
|
print('====================== BACKTESTING REPORT ================================')
|
||||||
for pair in backdata:
|
for pair in backdata:
|
||||||
|
@ -9,7 +9,7 @@ import pytest
|
|||||||
from hyperopt import fmin, tpe, hp, Trials, STATUS_OK
|
from hyperopt import fmin, tpe, hp, Trials, STATUS_OK
|
||||||
from pandas import DataFrame
|
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
|
from freqtrade.vendor.qtpylib.indicators import crossed_above
|
||||||
|
|
||||||
logging.disable(logging.DEBUG) # disable debug logs that slow backtesting a lot
|
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")
|
@pytest.mark.skipif(not os.environ.get('BACKTEST', False), reason="BACKTEST not set")
|
||||||
def test_hyperopt(backtest_conf, backdata, mocker):
|
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):
|
def optimizer(params):
|
||||||
mocked_buy_trend.side_effect = buy_strategy_generator(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)
|
result = format_results(results)
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user