Allow backtesting to reuse data

Allow activating / deactivating protections dynamically
This commit is contained in:
Matthias 2021-01-06 15:05:54 +01:00
parent edb8c4f0e5
commit f96d7dfe6d
3 changed files with 50 additions and 14 deletions

View File

@ -321,6 +321,7 @@ class BacktestRequest(BaseModel):
timerange: Optional[str] timerange: Optional[str]
max_open_trades: Optional[int] max_open_trades: Optional[int]
stake_amount: Optional[int] stake_amount: Optional[int]
enable_protections: bool
class BacktestResponse(BaseModel): class BacktestResponse(BaseModel):

View File

@ -280,11 +280,40 @@ async def api_start_backtest(bt_settings: BacktestRequest, background_tasks: Bac
# Start backtesting # Start backtesting
# Initialize backtesting object # Initialize backtesting object
def run_backtest(): def run_backtest():
from freqtrade.optimize.backtesting import Backtesting from freqtrade.optimize.optimize_reports import generate_backtest_stats
from freqtrade.resolvers import StrategyResolver
asyncio.set_event_loop(asyncio.new_event_loop()) asyncio.set_event_loop(asyncio.new_event_loop())
try: try:
ApiServer._backtesting = Backtesting(btconfig) # Reload strategy
ApiServer._backtesting.start() strat = StrategyResolver.load_strategy(btconfig)
if (not ApiServer._bt
or ApiServer._lastbacktestconfig.get('timeframe') != strat.timeframe
or ApiServer._lastbacktestconfig.get('enable_protections') != btconfig.get('enable_protections')
or ApiServer._lastbacktestconfig.get('protections') != btconfig.get('protections', [])):
# TODO: Investigate if enabling protections can be dynamically ingested from here...
from freqtrade.optimize.backtesting import Backtesting
ApiServer._bt = Backtesting(btconfig)
# Reset data if backtesting is reloaded
# TODO: is this always necessary??
ApiServer._backtestdata = None
if (not ApiServer._backtestdata or not ApiServer._bt_timerange
or ApiServer._lastbacktestconfig.get('timerange') != btconfig['timerange']):
ApiServer._lastbacktestconfig['timerange'] = btconfig['timerange']
ApiServer._lastbacktestconfig['protections'] = btconfig.get('protections', [])
ApiServer._lastbacktestconfig['enable_protections'] = btconfig.get('enable_protections')
ApiServer._lastbacktestconfig['timeframe'] = strat.timeframe
ApiServer._backtestdata, ApiServer._bt_timerange = ApiServer._bt.load_bt_data()
min_date, max_date = ApiServer._bt.backtest_one_strategy(
strat, ApiServer._backtestdata,
ApiServer._bt_timerange)
ApiServer._bt.results = generate_backtest_stats(
ApiServer._backtestdata, ApiServer._bt.all_results,
min_date=min_date, max_date=max_date)
logger.info("Backtesting finished.")
finally: finally:
ApiServer._bgtask_running = False ApiServer._bgtask_running = False
@ -304,12 +333,6 @@ def api_get_backtest():
Get backtesting result. Get backtesting result.
Returns Result after backtesting has been ran. Returns Result after backtesting has been ran.
""" """
if not ApiServer._backtesting:
return {
"status": "not_started",
"running": False,
"status_msg": "Backtesting not yet executed"
}
if ApiServer._bgtask_running: if ApiServer._bgtask_running:
return { return {
"status": "running", "status": "running",
@ -317,11 +340,18 @@ def api_get_backtest():
"status_msg": "Backtest running", "status_msg": "Backtest running",
} }
if not ApiServer._bt:
return {
"status": "not_started",
"running": False,
"status_msg": "Backtesting not yet executed"
}
return { return {
"status": "ended", "status": "ended",
"running": False, "running": False,
"status_msg": "Backtest ended", "status_msg": "Backtest ended",
"backtest_result": ApiServer._backtesting.results, "backtest_result": ApiServer._bt.results,
} }
@ -334,9 +364,11 @@ def api_delete_backtest():
"running": True, "running": True,
"status_msg": "Backtest running", "status_msg": "Backtest running",
} }
if ApiServer._backtesting: if ApiServer._bt:
del ApiServer._backtesting del ApiServer._bt
ApiServer._backtesting = None ApiServer._bt = None
del ApiServer._backtestdata
ApiServer._backtestdata = None
logger.info("Backtesting reset") logger.info("Backtesting reset")
return { return {
"status": "reset", "status": "reset",

View File

@ -34,7 +34,10 @@ class ApiServer(RPCHandler):
_rpc: RPC _rpc: RPC
# Backtesting type: Backtesting # Backtesting type: Backtesting
_backtesting = None _bt = None
_backtestdata = None
_bt_timerange = None
_lastbacktestconfig: Dict[str, Any] = {}
_has_rpc: bool = False _has_rpc: bool = False
_bgtask_running: bool = False _bgtask_running: bool = False
_config: Dict[str, Any] = {} _config: Dict[str, Any] = {}