@@ -45,10 +45,11 @@ report.show()
4545```
4646
4747This generates a multi-strategy comparison dashboard with:
48- - Strategy ranking table (sortable by CAGR, Sharpe, Max DD, etc.)
48+ - Strategy ranking tables (Key Metrics, Trading Activity)
49+ - Return Scenarios projections (Good/Average/Bad/Very Bad Year)
4950- Normalized equity curves overlay
5051- Per-strategy detail pages with Summary, Runs, and Performance tabs
51- - Compare mode for selected strategies
52+ - Compare mode with monthly return distribution (Rows/Heatmap × Returns/Growth toggles)
5253
5354### From Saved Backtests on Disk
5455
@@ -59,7 +60,7 @@ report = BacktestReport.open(directory_path="./my_backtests")
5960report.show()
6061```
6162
62- The ` open() ` method recursively finds all valid backtest directories (containing ` results .json` and ` metrics.json ` ) and loads them into a single report.
63+ The ` open() ` method recursively finds all valid backtest directories (containing ` algorithm_id .json` and a ` runs/ ` folder ) and loads them into a single report.
6364
6465You can also combine disk and in-memory backtests:
6566
@@ -71,6 +72,49 @@ report = BacktestReport.open(
7172report.show()
7273```
7374
75+ ## Recalculating Metrics
76+
77+ When metric calculations are updated in a newer framework version, previously saved backtests may have stale metrics. Use ` recalculate_backtests ` to recompute all per-run and summary metrics from the raw portfolio snapshots and trades:
78+
79+ ``` python
80+ from investing_algorithm_framework import BacktestReport, recalculate_backtests
81+
82+ report = BacktestReport.open(directory_path = " ./my_backtests" )
83+
84+ # Recalculate all metrics for all backtests
85+ recalculate_backtests(report.backtests)
86+
87+ report.show()
88+ ```
89+
90+ You can specify a custom risk-free rate (otherwise each backtest's stored rate is used):
91+
92+ ``` python
93+ recalculate_backtests(report.backtests, risk_free_rate = 0.04 )
94+ ```
95+
96+ Or limit which metrics are recomputed:
97+
98+ ``` python
99+ recalculate_backtests(
100+ report.backtests,
101+ metrics = [" cagr" , " sharpe_ratio" , " max_drawdown" , " win_rate" ]
102+ )
103+ ```
104+
105+ ` recalculate_backtests ` works on any list of ` Backtest ` objects, not just those loaded from disk:
106+
107+ ``` python
108+ from investing_algorithm_framework import recalculate_backtests
109+
110+ backtests = [backtest_a, backtest_b, backtest_c]
111+ recalculate_backtests(backtests, risk_free_rate = 0.027 )
112+ ```
113+
114+ For each backtest, the function:
115+ 1 . Recomputes per-run ` BacktestMetrics ` from raw ` portfolio_snapshots ` and ` trades `
116+ 2 . Regenerates ` BacktestSummaryMetrics ` by aggregating the updated per-run metrics
117+
74118## Saving Reports
75119
76120Save the report as a standalone HTML file you can share or open later:
@@ -96,27 +140,38 @@ report.show(browser=True) # Also opens in the browser
96140## Dashboard Features
97141
98142### Overview Page
99- - ** KPI cards** : Strategies count, backtest windows, best CAGR, best Sharpe, lowest max drawdown
100- - ** Backtest windows table** : Date ranges, duration, number of strategies per window
101- - ** Strategy ranking table** : Sortable by any metric, with best-in-class highlighting
102- - ** Equity curves** : Normalized percentage growth overlay for all strategies
143+ - ** KPI cards** : Best CAGR, best Sharpe, lowest max drawdown (with dual values when a window is selected)
144+ - ** Window Coverage** : Strategy × window matrix showing data coverage
145+ - ** Key Metrics table** : Sortable ranking with CAGR, Sharpe, Sortino, Calmar, Max DD, Volatility, Recovery Factor, Net Gain %
146+ - ** Trading Activity table** : Profit Factor, Win Rate, Trades/yr, Trades/mo, Trades/wk, # Trades, Avg Return, Avg Duration
147+ - ** Return Scenarios** : Good/Average/Bad/Very Bad Year projections based on CAGR ± volatility
148+ - ** Equity curves** : Normalized percentage growth overlay
149+ - ** Collapsible cards** : All chart sections can be collapsed/expanded
103150
104151### Strategy Pages
105152Each strategy gets a dedicated page with three tabs:
106153
107154| Tab | Contents |
108155| -----| ----------|
109- | ** Summary** | Full KPI grid (CAGR, Sharpe, Sortino, Calmar, Max DD, Profit Factor, Win Rate, Volatility, etc.) |
156+ | ** Summary** | Full KPI grid (CAGR, Sharpe, Sortino, Calmar, Max DD, Profit Factor, Win Rate, Volatility, Recovery Factor, etc.) |
110157| ** Runs** | Backtest run comparison table, equity overlay across runs |
111- | ** Performance** | Monthly returns heatmap, yearly returns bar chart |
158+ | ** Performance** | Monthly returns heatmap, yearly returns bar chart, return distribution |
112159
113160Use the run selector pills to switch between summary view and individual backtest runs.
114161
115162### Compare Mode (Multi-Strategy)
116- Select strategies via checkboxes in the ranking table, then click ** Compare Selected** to see:
117- - Side-by-side equity curves
118- - Metric bar charts (CAGR, Sharpe, Max DD, Win Rate)
119- - Monthly and yearly return comparisons
163+ Open the strategy selection modal to pick strategies for comparison. You can set a challenger strategy for highlighting. The compare page includes:
164+ - ** Key Metrics** and ** Trading Activity** ranking tables
165+ - ** Return Scenarios** projections
166+ - ** Monthly Returns** with four view modes (Returns/Growth × Rows/Heatmap), plus a year filter
167+ - Side-by-side equity curves and drawdown overlays
168+ - Metric bar charts (CAGR, Sharpe, Sortino, Calmar, Max DD, Win Rate, Profit Factor)
169+ - Return distribution histograms and correlation matrix
170+ - Rolling Sharpe ratio chart
171+ - Yearly returns bar charts
172+
173+ ### Sticky Navigation
174+ The page title bar with the window selector stays visible as you scroll.
120175
121176### Dark / Light Theme
122177Toggle between dark and light mode using the sun icon in the top-right corner.
@@ -126,7 +181,7 @@ Toggle between dark and light mode using the sun icon in the top-right corner.
126181``` python
127182from datetime import datetime, timezone
128183from investing_algorithm_framework import (
129- create_app, BacktestDateRange, BacktestReport
184+ create_app, BacktestDateRange, BacktestReport, recalculate_backtests
130185)
131186
132187app = create_app()
@@ -153,6 +208,9 @@ backtests = app.run_vector_backtests(
153208 backtest_storage_directory = " ./backtests"
154209)
155210
211+ # Optional: recalculate metrics with updated calculations
212+ recalculate_backtests(backtests, risk_free_rate = 0.04 )
213+
156214# Generate and save the comparison report
157215report = BacktestReport(backtests = backtests)
158216report.save(" comparison_report.html" )
@@ -170,3 +228,15 @@ report.show(browser=True)
170228| ` BacktestReport.open(directory_path=..., backtests=[...]) ` | Load backtests from disk and/or combine with in-memory backtests |
171229| ` report.show(browser=False) ` | Display the report. In Jupyter: renders inline. Otherwise: opens browser. Set ` browser=True ` to force browser. |
172230| ` report.save(path) ` | Save the report as a self-contained HTML file |
231+
232+ ### ` recalculate_backtests `
233+
234+ | Parameter | Type | Description |
235+ | -----------| ------| -------------|
236+ | ` backtests ` | ` List[Backtest] ` | The backtests to recalculate (mutated in place and returned) |
237+ | ` risk_free_rate ` | ` float ` , optional | Override risk-free rate. If ` None ` , uses each backtest's stored rate (falls back to ` 0.0 ` ) |
238+ | ` metrics ` | ` List[str] ` , optional | Specific metrics to compute. If ` None ` , computes all default metrics |
239+
240+ ** Returns:** ` List[Backtest] ` — the same backtest objects with updated metrics.
241+
242+ Recalculates all per-run ` BacktestMetrics ` from raw portfolio snapshots and trades, then regenerates ` BacktestSummaryMetrics ` for each backtest.
0 commit comments