Skip to main content

Metrics Reference

The framework computes metrics at two levels:

  1. Per-run metrics (BacktestMetrics): one set per individual backtest run / window. Includes everything specific to that run: the equity curve, drawdown series, monthly/yearly return tables, best/worst trade, exposure, etc.
  2. Summary metrics (BacktestSummaryMetrics): a single roll-up across all runs/windows in a backtest. Used for ranking and robustness analysis in the HTML report.

Both objects expose roughly the same headline stats (CAGR, Sharpe, max drawdown, win rate…), but the per-run object is richer (it has time-series like equity_curve and drawdown_series) while the summary adds multi-window measures (consistency_score, stability_score, number_of_profitable_windows).

Prefer the getters over direct attribute access — they handle missing runs / metrics safely and work the same way whether the backtest was just produced or loaded from an .iafbt bundle.

from investing_algorithm_framework import BacktestDateRange

backtest = app.run_backtest(...) # or app.run_vector_backtest(...)

# Cross-window roll-up
summary = backtest.get_backtest_summary()
print(f"CAGR: {summary.cagr:.2%}")
print(f"Max drawdown: {summary.max_drawdown:.2%}")

# Per-run details — one BacktestMetrics per run/window
for metrics in backtest.get_all_backtest_metrics():
print(
f"{metrics.backtest_date_range_name}: "
f"return={metrics.total_net_gain_percentage:.2%}, "
f"sharpe={metrics.sharpe_ratio:.2f}"
)

# Or fetch a specific window by date range
date_range = BacktestDateRange(
start_date="2022-01-01", end_date="2022-12-31", name="2022"
)
metrics = backtest.get_backtest_metrics(date_range)
run = backtest.get_backtest_run(date_range)

All metrics are persisted inside the .iafbt bundle, so reports loaded from disk have identical values without recomputation.

Conventions

  • Decimal vs percentage. Fields ending in _percentage are decimals (e.g. 0.42 means 42%). Fields without a _percentage suffix are in account currency, except for ratios (Sharpe, Sortino, Calmar, win/loss, profit factor) which are dimensionless.
  • Currency. All currency-denominated metrics are expressed in the portfolio's trading_symbol (typically EUR/USD/USDT).
  • Per-run vs per-trade. On BacktestMetrics, total_* is over the whole run, average_trade_* is over closed trades within that run. On BacktestSummaryMetrics, average_* (without trade_) is the time-weighted mean across windows.
  • Single window. If the backtest has only one window, summary total_* and average_* collapse to the corresponding per-run values by definition.
  • Annualization. Sharpe, Sortino, CAGR, and annual volatility are annualized using the backtest's bar frequency (252 trading days for daily, scaled accordingly for intraday).

Per-run metrics — BacktestMetrics

One BacktestMetrics instance is produced for every backtest run / window. Retrieve them via backtest.get_all_backtest_metrics() or a specific one via backtest.get_backtest_metrics(date_range).

Run identity

MetricTypeDescription
backtest_date_range_namestrHuman-readable name of the date range (e.g. "2022_bear").
backtest_start_datedatetimeFirst bar timestamp of the run.
backtest_end_datedatetimeLast bar timestamp of the run.
total_number_of_daysintCalendar days covered by the run.
trading_symbolstrQuote currency of the portfolio (e.g. "EUR").
initial_unallocatedcurrencyStarting cash for the run.
final_valuecurrencyPortfolio value at the last bar.
metadatadictFree-form metadata attached to the run.

Returns and growth (per-run)

MetricTypeDescription
total_net_gaincurrencyfinal_value − initial_unallocated.
total_net_gain_percentagedecimaltotal_net_gain / initial_unallocated.
total_growth / total_growth_percentagecurrency / decimalLegacy aliases of total_net_gain*.
total_losscurrencyGross loss magnitude (sum of abs(net_gain) over losing trades).
total_loss_percentagedecimaltotal_loss / initial_unallocated.
gross_profitcurrencySum of P&L of winning trades.
gross_losscurrencySum of P&L of losing trades (negative).
cumulative_returndecimalCumulative return over the run.
cagrdecimalCompound annual growth rate.
annual_volatilitydecimalAnnualized stdev of periodic returns.

Time series (per-run only)

These are lists of (value, datetime) tuples used to render the charts in the HTML dashboard.

MetricTypeDescription
equity_curvelist[(float, datetime)]Portfolio value over time.
cumulative_return_serieslist[(float, datetime)]Cumulative return over time.
rolling_sharpe_ratiolist[(float, datetime)]Rolling Sharpe ratio over a fixed lookback.
drawdown_serieslist[(float, datetime)]Drawdown from running peak over time.
monthly_returnslist[(float, datetime)]Monthly return per month. Powers the heatmap.
yearly_returnslist[(float, date)]Yearly return per year.

Risk-adjusted performance (per-run)

MetricTypeDescription
sharpe_ratioratioAnnualized excess return / annualized volatility.
sortino_ratioratioAnnualized excess return / downside deviation.
calmar_ratioratiocagr / max_drawdown.
profit_factorratiogross_profit / abs(gross_loss).

Drawdown and tail risk (per-run)

MetricTypeDescription
max_drawdowndecimalLargest peak-to-trough drop, as a fraction of peak.
max_drawdown_absolutecurrencySame drop in account currency.
max_daily_drawdowndecimalLargest single-day equity drop.
max_drawdown_durationint (days)Days from drawdown peak to recovery.
var_95decimalValue at Risk at 95% confidence.
cvar_95decimalConditional VaR — average loss in the worst 5% of cases.

Trade statistics (per-run)

MetricTypeDescription
number_of_tradesintAll trades touched during the run.
number_of_trades_openedintTrades opened during the run.
number_of_trades_closedintTrades closed during the run.
number_of_trades_open_at_endintTrades still open at last bar.
number_of_positive_tradesintProfitable closed trades.
number_of_negative_tradesintLosing closed trades.
percentage_positive_tradesdecimaln_positive / n_closed.
percentage_negative_tradesdecimaln_negative / n_closed.
average_trade_sizecurrencyMean notional per trade.
average_trade_return / _percentagecurrency / decimalMean P&L of all closed trades.
median_trade_return / _percentagecurrency / decimalMedian P&L.
average_trade_gain / _percentagecurrency / decimalMean P&L of winning trades.
average_trade_loss / _percentagecurrency / decimalMean loss of losing trades.
average_trade_durationhoursMean time a trade is open.
average_win_durationhoursMean duration of winning trades.
average_loss_durationhoursMean duration of losing trades.
best_tradeTradeHighest-P&L trade in the run.
worst_tradeTradeLowest-P&L trade in the run.
current_average_trade_*variousSame as above but rolling over the most recent trades.

Win/loss (per-run)

MetricTypeDescription
win_ratedecimaln_positive / n_closed.
current_win_ratedecimalRolling win rate over recent trades.
win_loss_ratioratioaverage_trade_gain / average_trade_loss.
current_win_loss_ratioratioRolling version.
max_consecutive_winsintLongest winning streak.
max_consecutive_lossesintLongest losing streak.

Calendar performance (per-run)

MetricTypeDescription
percentage_winning_monthsdecimalMonths with positive return / total months.
percentage_winning_yearsdecimalYears with positive return / total years.
average_monthly_returndecimalMean monthly return.
average_monthly_return_winning_monthsdecimalMean return over positive months.
average_monthly_return_losing_monthsdecimalMean return over negative months.
best_month(float, datetime)Best monthly return.
worst_month(float, datetime)Worst monthly return.
best_year(float, date)Best yearly return.
worst_year(float, date)Worst yearly return.

Exposure and activity (per-run)

MetricTypeDescription
cumulative_exposurecurrency × timeIntegral of capital deployed.
exposure_ratiodecimalFraction of time with at least one open position.
trades_per_yearfloatAnnualized trade frequency.
trades_per_monthfloatMonthly trade frequency.
trades_per_weekfloatWeekly trade frequency.
trade_per_dayfloatDaily trade frequency.

Summary metrics — BacktestSummaryMetrics

A single roll-up across all runs/windows in a backtest. Available via backtest.get_backtest_summary(). Used by BacktestReport for ranking, filtering, and KPI cards.

For single-window backtests these collapse to the per-run values; for multi-window backtests (e.g. walk-forward, permutation tests, see Vector Backtesting) they aggregate across windows and add robustness measures.

Returns and growth (aggregate)

MetricTypeDescription
total_net_gaincurrencySum of per-window net gains.
total_net_gain_percentagedecimaltotal_net_gain / total initial capital.
total_growth / total_growth_percentagecurrency / decimalLegacy aliases of total_net_gain*.
cagrdecimalCompound annual growth rate of the combined equity curve.
annual_volatilitydecimalAnnualized return volatility across windows.
average_net_gain / _percentagecurrency / decimalTime-weighted mean per-window net gain.
average_growth / _percentagecurrency / decimalLegacy aliases.

Risk-adjusted performance (aggregate)

MetricTypeDescription
sharpe_ratioratioAnnualized excess return / annualized volatility.
sortino_ratioratioDownside-risk adjusted return.
calmar_ratioratiocagr / max_drawdown.
profit_factorratioGross profit / gross loss across all closed trades.

Drawdown and tail risk (aggregate)

MetricTypeDescription
max_drawdowndecimalWorst peak-to-trough drop seen across all windows.
max_drawdown_durationint (bars)Bars between the worst drawdown peak and recovery.
var_95decimalValue at Risk at 95% confidence across all returns.
cvar_95decimalConditional VaR.

Loss metrics (aggregate)

MetricTypeDescription
total_losscurrencySum of per-window gross losses (non-negative magnitude).
total_loss_percentagedecimaltotal_loss / total initial capital.
average_loss / _percentagecurrency / decimalTime-weighted mean loss across windows.

Per-trade metrics (aggregate)

MetricTypeDescription
number_of_tradesintTrades opened across all windows.
number_of_trades_closedintTrades closed across all windows.
average_trade_return / _percentagecurrency / decimalMean P&L per closed trade.
average_trade_gain / _percentagecurrency / decimalMean P&L of winners.
average_trade_loss / _percentagecurrency / decimalMean loss of losers.
average_trade_durationsecondsMean trade open time.
average_win_durationsecondsMean winning trade duration.
average_loss_durationsecondsMean losing trade duration.

Win/loss statistics (aggregate)

MetricTypeDescription
win_ratedecimalProfitable trades / closed trades across all windows.
current_win_ratedecimalRolling win rate over recent trades.
win_loss_ratioratioaverage_trade_gain / average_trade_loss.
current_win_loss_ratioratioRolling version.
max_consecutive_winsintLongest winning streak across all windows.
max_consecutive_lossesintLongest losing streak across all windows.

Exposure and activity (aggregate)

MetricTypeDescription
cumulative_exposurecurrency × timeTotal capital deployed across all windows.
exposure_ratiodecimalFraction of time with at least one open position.
trades_per_year / trades_per_month / trades_per_weekfloatAnnualized / monthly / weekly trade frequency.

Multi-window robustness (summary-only)

These metrics only exist on BacktestSummaryMetrics — they describe how performance varies across windows and have no per-run analog.

MetricTypeDescription
number_of_windowsintTotal backtest windows executed.
number_of_windows_with_tradesintWindows in which at least one trade closed.
number_of_profitable_windowsintWindows with positive net gain.
return_consistencydecimalCoefficient of variation of per-window returns (lower = more consistent).
win_rate_consistencydecimalCoefficient of variation of per-window win rates.
sharpe_consistencydecimalCoefficient of variation of per-window Sharpe ratios.
consistency_scoredecimalComposite of the three *_consistency measures, scaled to [0, 1] (higher = better).
return_stabilitydecimalPer-window return autocorrelation — how stable returns are over time.
win_rate_stabilitydecimalSame, for win rate.
sharpe_stabilitydecimalSame, for Sharpe ratio.
stability_scoredecimalComposite stability score, scaled to [0, 1] (higher = better).

Using metrics in code

Every summary metric is also available as a ranking key in BacktestReport:

from investing_algorithm_framework import BacktestReport

report = BacktestReport.open(directory_path="backtest_results/")

# Top 10 strategies by Sharpe ratio
top_sharpe = report.rank(by="sharpe_ratio", ascending=False, limit=10)

# Filter to robust strategies only
robust = report.filter(
lambda b: b.backtest_summary.consistency_score > 0.7
and b.backtest_summary.max_drawdown < 0.2
)

# Drill into per-run detail for a specific backtest
for metrics in robust[0].get_all_backtest_metrics():
print(f"{metrics.backtest_date_range_name}: {metrics.total_net_gain_percentage:.2%}")

For multi-strategy comparison and visualization, see Backtest Reports.