Allow backtesting to reuse data
Allow activating / deactivating protections dynamically
This commit is contained in:
parent
edb8c4f0e5
commit
f96d7dfe6d
@ -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):
|
||||||
|
@ -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",
|
||||||
|
@ -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] = {}
|
||||||
|
Loading…
Reference in New Issue
Block a user