```plantuml @startuml !define RECTANGLE class actor User as U participant "User Interface" as UI participant "Backtester Class" as Backtester participant "DataCache_v3" as DataCache participant "Strategies" as Strategies participant "Indicators" as Indicators participant "StrategyInstance" as StrategyInstance participant "Backtrader (Cerebro)" as Cerebro participant "Custom Analyzers" as Analyzers participant "EquityCurveAnalyzer" as EquityAnalyzer participant "TradeAnalyzer" as TradeAnalyzer participant "Pandas DataFeed" as DataFeed participant "Logging" as Logging participant "SocketIO" as SocketIO == Backtest Submission == U -> UI: Submit Backtest Request\n(strategy details, parameters) UI -> Backtester: initiate_backtest(strategy_details, parameters) activate Backtester == Caching Backtest == Backtester -> DataCache: cache_backtest(user_name, backtest_name, backtest_data, strategy_instance_id) activate DataCache DataCache --> Backtester: Confirmation deactivate DataCache == Preparing Strategy Instance == Backtester -> Strategies: retrieve_strategy(strategy_id) activate Strategies Strategies --> Backtester: strategy_class deactivate Strategies Backtester -> Indicators: get_precomputed_indicators(strategy_id) activate Indicators Indicators --> Backtester: precomputed_indicators deactivate Indicators Backtester -> Backtester: map_user_strategy(user_strategy, precomputed_indicators, mode) Backtester -> StrategyInstance: __init__(strategy_instance_id, strategy_id, strategy_name, user_id, generated_code, data_cache, indicators, trades) activate StrategyInstance StrategyInstance --> Backtester: Initialized deactivate StrategyInstance == Preparing Data Feed == Backtester -> DataCache: prepare_data_feed(data_parameters) activate DataCache DataCache --> Backtester: data_feed deactivate DataCache Backtester -> Backtester: add_custom_handlers() Backtester -> Backtester: precompute_indicators(precomputed_indicators) Backtester -> Backtester: setup_strategy_instance(strategy_instance) == Running Backtest == Backtester -> Cerebro: setup_cerebro(data_feed, strategy_class, parameters) activate Cerebro Cerebro -> Cerebro: addstrategy(strategy_class, **kwargs) Cerebro -> Cerebro: adddata(data_feed) Cerebro -> Cerebro: setcash(initial_capital) Cerebro -> Cerebro: setcommission(commission) Cerebro -> Analyzers: add_analyzer(EquityCurveAnalyzer, _name='equity_curve') Cerebro -> Analyzers: add_analyzer(TradeAnalyzer, _name='trade_analyzer') Cerebro -> Logging: configure_logging() Cerebro -> Cerebro: run() activate Cerebro Cerebro -> EquityAnalyzer: initialize() activate EquityAnalyzer Cerebro -> TradeAnalyzer: initialize() activate TradeAnalyzer Cerebro -> StrategyInstance: attach_backtrader_strategy(strategy) Cerebro -> StrategyInstance: execute() activate StrategyInstance StrategyInstance -> Cerebro: next() StrategyInstance -> Logging: log("Strategy execution step") StrategyInstance --> Cerebro: Step completed Cerebro -> EquityAnalyzer: record_equity_curve() Cerebro -> TradeAnalyzer: analyze_trades() Cerebro --> Backtester: backtest_results deactivate Cerebro deactivate Analyzers == Processing Results == Backtester -> Backtester: calculate_returns(equity_curve) Backtester -> Backtester: analyze_trades(trades) Backtester -> Backtester: compute_statistics(total_return, sharpe_ratio, max_drawdown, win_loss_ratio) Backtester -> Backtester: update_stats(strategy_id, stats) Backtester -> DataCache: store_backtest_results(user_name, backtest_name, results) activate DataCache DataCache --> Backtester: Confirmation deactivate DataCache == Emitting Results == Backtester -> SocketIO: emit('backtest_results', data, room=socket_conn_id) activate SocketIO SocketIO --> U: Receive Backtest Results deactivate SocketIO deactivate Backtester @enduml