diff --git a/freqtrade/rpc/api_server/api_backtest.py b/freqtrade/rpc/api_server/api_backtest.py index 4055845e1..a06d65dcc 100644 --- a/freqtrade/rpc/api_server/api_backtest.py +++ b/freqtrade/rpc/api_server/api_backtest.py @@ -30,9 +30,9 @@ router = APIRouter() async def api_start_backtest( # noqa: C901 bt_settings: BacktestRequest, background_tasks: BackgroundTasks, config=Depends(get_config), ws_mode=Depends(is_webserver_mode)): - ApiBG._bt['bt_error'] = None + ApiBG.bt['bt_error'] = None """Start backtesting if not done so already""" - if ApiBG._bgtask_running: + if ApiBG.bgtask_running: raise RPCException('Bot Background task already running') if ':' in bt_settings.strategy: @@ -63,30 +63,30 @@ async def api_start_backtest( # noqa: C901 asyncio.set_event_loop(asyncio.new_event_loop()) try: # Reload strategy - lastconfig = ApiBG._bt['last_config'] + lastconfig = ApiBG.bt['last_config'] strat = StrategyResolver.load_strategy(btconfig) validate_config_consistency(btconfig) if ( - not ApiBG._bt['bt'] + not ApiBG.bt['bt'] or lastconfig.get('timeframe') != strat.timeframe or lastconfig.get('timeframe_detail') != btconfig.get('timeframe_detail') or lastconfig.get('timerange') != btconfig['timerange'] ): from freqtrade.optimize.backtesting import Backtesting - ApiBG._bt['bt'] = Backtesting(btconfig) - ApiBG._bt['bt'].load_bt_data_detail() + ApiBG.bt['bt'] = Backtesting(btconfig) + ApiBG.bt['bt'].load_bt_data_detail() else: - ApiBG._bt['bt'].config = btconfig - ApiBG._bt['bt'].init_backtest() + ApiBG.bt['bt'].config = btconfig + ApiBG.bt['bt'].init_backtest() # Only reload data if timeframe changed. if ( - not ApiBG._bt['data'] - or not ApiBG._bt['timerange'] + not ApiBG.bt['data'] + or not ApiBG.bt['timerange'] or lastconfig.get('timeframe') != strat.timeframe or lastconfig.get('timerange') != btconfig['timerange'] ): - ApiBG._bt['data'], ApiBG._bt['timerange'] = ApiBG._bt[ + ApiBG.bt['data'], ApiBG.bt['timerange'] = ApiBG.bt[ 'bt'].load_bt_data() lastconfig['timerange'] = btconfig['timerange'] @@ -95,27 +95,27 @@ async def api_start_backtest( # noqa: C901 lastconfig['enable_protections'] = btconfig.get('enable_protections') lastconfig['dry_run_wallet'] = btconfig.get('dry_run_wallet') - ApiBG._bt['bt'].enable_protections = btconfig.get('enable_protections', False) - ApiBG._bt['bt'].strategylist = [strat] - ApiBG._bt['bt'].results = {} - ApiBG._bt['bt'].load_prior_backtest() + ApiBG.bt['bt'].enable_protections = btconfig.get('enable_protections', False) + ApiBG.bt['bt'].strategylist = [strat] + ApiBG.bt['bt'].results = {} + ApiBG.bt['bt'].load_prior_backtest() - ApiBG._bt['bt'].abort = False - if (ApiBG._bt['bt'].results and - strat.get_strategy_name() in ApiBG._bt['bt'].results['strategy']): + ApiBG.bt['bt'].abort = False + if (ApiBG.bt['bt'].results and + strat.get_strategy_name() in ApiBG.bt['bt'].results['strategy']): # When previous result hash matches - reuse that result and skip backtesting. logger.info(f'Reusing result of previous backtest for {strat.get_strategy_name()}') else: - min_date, max_date = ApiBG._bt['bt'].backtest_one_strategy( - strat, ApiBG._bt['data'], ApiBG._bt['timerange']) + min_date, max_date = ApiBG.bt['bt'].backtest_one_strategy( + strat, ApiBG.bt['data'], ApiBG.bt['timerange']) - ApiBG._bt['bt'].results = generate_backtest_stats( - ApiBG._bt['data'], ApiBG._bt['bt'].all_results, + ApiBG.bt['bt'].results = generate_backtest_stats( + ApiBG.bt['data'], ApiBG.bt['bt'].all_results, min_date=min_date, max_date=max_date) if btconfig.get('export', 'none') == 'trades': store_backtest_stats( - btconfig['exportfilename'], ApiBG._bt['bt'].results, + btconfig['exportfilename'], ApiBG.bt['bt'].results, datetime.now().strftime("%Y-%m-%d_%H-%M-%S") ) @@ -123,13 +123,13 @@ async def api_start_backtest( # noqa: C901 except (Exception, OperationalException, DependencyException) as e: logger.exception(f"Backtesting caused an error: {e}") - ApiBG._bt['bt_error'] = str(e) + ApiBG.bt['bt_error'] = str(e) pass finally: - ApiBG._bgtask_running = False + ApiBG.bgtask_running = False background_tasks.add_task(run_backtest) - ApiBG._bgtask_running = True + ApiBG.bgtask_running = True return { "status": "running", @@ -147,18 +147,18 @@ def api_get_backtest(ws_mode=Depends(is_webserver_mode)): Returns Result after backtesting has been ran. """ from freqtrade.persistence import LocalTrade - if ApiBG._bgtask_running: + if ApiBG.bgtask_running: return { "status": "running", "running": True, - "step": (ApiBG._bt['bt'].progress.action if ApiBG._bt['bt'] + "step": (ApiBG.bt['bt'].progress.action if ApiBG.bt['bt'] else str(BacktestState.STARTUP)), - "progress": ApiBG._bt['bt'].progress.progress if ApiBG._bt['bt'] else 0, + "progress": ApiBG.bt['bt'].progress.progress if ApiBG.bt['bt'] else 0, "trade_count": len(LocalTrade.trades), "status_msg": "Backtest running", } - if not ApiBG._bt['bt']: + if not ApiBG.bt['bt']: return { "status": "not_started", "running": False, @@ -166,13 +166,13 @@ def api_get_backtest(ws_mode=Depends(is_webserver_mode)): "progress": 0, "status_msg": "Backtest not yet executed" } - if ApiBG._bt['bt_error']: + if ApiBG.bt['bt_error']: return { "status": "error", "running": False, "step": "", "progress": 0, - "status_msg": f"Backtest failed with {ApiBG._bt['bt_error']}" + "status_msg": f"Backtest failed with {ApiBG.bt['bt_error']}" } return { @@ -181,14 +181,14 @@ def api_get_backtest(ws_mode=Depends(is_webserver_mode)): "status_msg": "Backtest ended", "step": "finished", "progress": 1, - "backtest_result": ApiBG._bt['bt'].results, + "backtest_result": ApiBG.bt['bt'].results, } @router.delete('/backtest', response_model=BacktestResponse, tags=['webserver', 'backtest']) def api_delete_backtest(ws_mode=Depends(is_webserver_mode)): """Reset backtesting""" - if ApiBG._bgtask_running: + if ApiBG.bgtask_running: return { "status": "running", "running": True, @@ -196,12 +196,12 @@ def api_delete_backtest(ws_mode=Depends(is_webserver_mode)): "progress": 0, "status_msg": "Backtest running", } - if ApiBG._bt['bt']: - ApiBG._bt['bt'].cleanup() - del ApiBG._bt['bt'] - ApiBG._bt['bt'] = None - del ApiBG._bt['data'] - ApiBG._bt['data'] = None + if ApiBG.bt['bt']: + ApiBG.bt['bt'].cleanup() + del ApiBG.bt['bt'] + ApiBG.bt['bt'] = None + del ApiBG.bt['data'] + ApiBG.bt['data'] = None logger.info("Backtesting reset") return { "status": "reset", @@ -214,7 +214,7 @@ def api_delete_backtest(ws_mode=Depends(is_webserver_mode)): @router.get('/backtest/abort', response_model=BacktestResponse, tags=['webserver', 'backtest']) def api_backtest_abort(ws_mode=Depends(is_webserver_mode)): - if not ApiBG._bgtask_running: + if not ApiBG.bgtask_running: return { "status": "not_running", "running": False, @@ -222,7 +222,7 @@ def api_backtest_abort(ws_mode=Depends(is_webserver_mode)): "progress": 0, "status_msg": "Backtest ended", } - ApiBG._bt['bt'].abort = True + ApiBG.bt['bt'].abort = True return { "status": "stopping", "running": False, diff --git a/freqtrade/rpc/api_server/deps.py b/freqtrade/rpc/api_server/deps.py index b46ac88cd..8fd105d3e 100644 --- a/freqtrade/rpc/api_server/deps.py +++ b/freqtrade/rpc/api_server/deps.py @@ -44,11 +44,11 @@ def get_api_config() -> Dict[str, Any]: def get_exchange(config=Depends(get_config)): - if not ApiBG._exchange: + if not ApiBG.exchange: from freqtrade.resolvers import ExchangeResolver - ApiBG._exchange = ExchangeResolver.load_exchange( + ApiBG.exchange = ExchangeResolver.load_exchange( config, load_leverage_tiers=False) - return ApiBG._exchange + return ApiBG.exchange def get_message_stream(): diff --git a/freqtrade/rpc/api_server/webserver_bgwork.py b/freqtrade/rpc/api_server/webserver_bgwork.py index cdb1bd031..925f34de3 100644 --- a/freqtrade/rpc/api_server/webserver_bgwork.py +++ b/freqtrade/rpc/api_server/webserver_bgwork.py @@ -4,13 +4,13 @@ from typing import Any, Dict class ApiBG(): # Backtesting type: Backtesting - _bt: Dict[str, Any] = { + bt: Dict[str, Any] = { 'bt': None, 'data': None, 'timerange': None, 'last_config': {}, 'bt_error': None, } - _bgtask_running: bool = False + bgtask_running: bool = False # Exchange - only available in webserver mode. - _exchange = None + exchange = None diff --git a/tests/rpc/test_rpc_apiserver.py b/tests/rpc/test_rpc_apiserver.py index aad4bedb6..3b1a2616f 100644 --- a/tests/rpc/test_rpc_apiserver.py +++ b/tests/rpc/test_rpc_apiserver.py @@ -1734,7 +1734,7 @@ def test_api_backtesting(botclient, mocker, fee, caplog, tmpdir): assert result['status_msg'] == 'Backtest ended' # Simulate running backtest - ApiBG._bgtask_running = True + ApiBG.bgtask_running = True rc = client_get(client, f"{BASE_URI}/backtest/abort") assert_response(rc) result = rc.json() @@ -1763,7 +1763,7 @@ def test_api_backtesting(botclient, mocker, fee, caplog, tmpdir): result = rc.json() assert 'Bot Background task already running' in result['error'] - ApiBG._bgtask_running = False + ApiBG.bgtask_running = False # Rerun backtest (should get previous result) rc = client_post(client, f"{BASE_URI}/backtest", data=data)