brighter-trading/markdown/backtesting.md

3.8 KiB


@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