Reports
Performance metrics and HTML tearsheet generation.
Two entry points:
mktlib.reports.html()— generates an interactive HTML tearsheet (returns the string or writes to disk).mktlib.reports.metrics()— computes the same metric set without the rendering overhead, returns aMetricsResultdataclass.
Both accept a daily returns series; sub-daily input is automatically
collapsed to one geometrically-compounded value per date. The accepted
input types — pl.Series, pl.DataFrame with date and return
columns, or any pandas-like object with a DatetimeIndex — are
documented under mktlib.reports.html().
- mktlib.reports.html(returns, *, benchmark=None, trades=None, output=None, title='Strategy Tearsheet', rf=0.0, periods_per_year=252, compounded=True, extra_metrics=None, extra_charts=None, template=None, mc_config=None)[source]
Generate an interactive HTML tearsheet report.
- Parameters:
returns (
DataFrame|Series|PandasConvertible) – Daily returns aspl.Series,pl.DataFrame(with date and return columns), orpd.Serieswith aDatetimeIndex.benchmark (
DataFrame|Series|PandasConvertible|None) – Optional benchmark returns (same types as returns).trades (
DataFrame|None) – Optional per-trade DataFrame with columnsentry_date(Date),exit_date(Date),side(Int8),pnl(Float64), andbars_held(Int64). When provided, per-trade metrics are computed and the Win/Loss card values are overridden with trade-based figures. Two extra metric cards (Trade Stats, Trade Risk-Adjusted) and two extra charts (PnL distribution, PnL over time) are added.output (
str|None) – File path to write the HTML to. When None, returns the HTML string.title (
str) – Report title shown in the header.rf (
float|str) – Risk-free rate (annualised, e.g.0.05for 5 %). Pass"auto"to fetch the 3-month T-bill average for the returns date range.periods_per_year (
int) – Trading days per year (default 252).compounded (
bool) – Whether to compute compounded returns (default True).extra_metrics (
dict[str,list[tuple[str,str]]] |None) – Additional metric cards:{card_title: [(label, value), ...]}. Appended to the built-in metrics grid.extra_charts (
dict[str,Figure] |None) – Additional charts:{name: plotly.graph_objects.Figure}. Converted to HTML divs and rendered after the built-in charts.template (
str|Path|None) – Custom Jinja2 template.Pathloads from file,stris treated as inline Jinja2 source,Noneuses the built-in template.mc_config (MonteCarloConfig | None)
- Returns:
The HTML string when output is None, otherwise None.
- Return type:
- mktlib.reports.metrics(returns, *, benchmark=None, trades=None, rf=0.0, periods_per_year=252, compounded=True, mc_config=None)[source]
Compute performance metrics without generating an HTML report.
- Parameters:
rf (
float|str) – Risk-free rate (annualised). Pass"auto"to fetch the 3-month T-bill average for the returns date range.trades (
DataFrame|None) – Optional per-trade DataFrame (same schema ashtml()). When provided,MetricsResult.trade_metricsis populated.mc_config (
MonteCarloConfig|None) – OptionalMonteCarloConfig. Whenmc_config.enabled, populatesMetricsResult.mc_varandmc_cvarwith simulation- based forward-looking risk numbers; otherwise leaves themNone.returns (DataFrame | Series | PandasConvertible)
benchmark (DataFrame | Series | PandasConvertible | None)
periods_per_year (int)
compounded (bool)
- Return type:
Result and Configuration
- class mktlib.reports.MetricsResult(cumulative_return, cagr, mtd, ytd, one_year, sharpe, sortino, calmar, omega, romad, max_drawdown, max_drawdown_date, longest_drawdown_days, avg_drawdown, volatility, var_95, cvar_95, win_rate, payoff_ratio, profit_factor, kelly_criterion, alpha=None, beta=None, r_squared=None, information_ratio=None, trade_metrics=None, mc_var=None, mc_cvar=None)[source]
Complete metrics computation result (25 metrics).
- Parameters:
cumulative_return (float)
cagr (float)
mtd (float)
ytd (float)
one_year (float)
sharpe (float)
sortino (float)
calmar (float)
omega (float)
romad (float)
max_drawdown (float)
max_drawdown_date (str | None)
longest_drawdown_days (float)
avg_drawdown (float)
volatility (float)
var_95 (float)
cvar_95 (float)
win_rate (float)
payoff_ratio (float)
profit_factor (float)
kelly_criterion (float)
alpha (float | None)
beta (float | None)
r_squared (float | None)
information_ratio (float | None)
trade_metrics (TradeMetrics | None)
mc_var (float | None)
mc_cvar (float | None)
- trade_metrics: TradeMetrics | None
- class mktlib.reports.ReportConfig(rf=0.0, periods_per_year=252, compounded=True, title='Strategy Tearsheet')[source]
Configuration for report generation.
- class mktlib.reports.TradeMetrics(trade_win_rate, payoff_ratio, profit_factor, kelly_criterion, avg_trade_pnl, avg_bars_held, avg_duration_minutes, total_trades, avg_winner, avg_loser, largest_winner, largest_loser, max_consecutive_wins, max_consecutive_losses, trade_sharpe, trade_sortino, trades_per_year)[source]
Per-trade performance metrics computed from a trades DataFrame.
- Parameters:
trade_win_rate (float)
payoff_ratio (float)
profit_factor (float)
kelly_criterion (float)
avg_trade_pnl (float)
avg_bars_held (float)
avg_duration_minutes (float)
total_trades (int)
avg_winner (float)
avg_loser (float)
largest_winner (float)
largest_loser (float)
max_consecutive_wins (int)
max_consecutive_losses (int)
trade_sharpe (float)
trade_sortino (float)
trades_per_year (float)
Forward-Looking Risk (Monte Carlo)
The MonteCarloConfig dataclass enables an opt-in Monte Carlo
estimation path on top of the standard tearsheet. When enabled=True,
html() and metrics() populate two new
MetricsResult fields — mc_var and mc_cvar — using the
simulation-based estimator from Metrics, and (in html())
render a Monte Carlo Forward Paths chart showing the spaghetti subset,
α/2 / 1−α/2 percentile band, and median path anchored at the last
historical equity value over forward business days.
- class mktlib.reports.MonteCarloConfig(enabled=False, horizon=21, n_simulations=10000, innovations=None, df=None, seed=None, alpha=0.05, n_paths_displayed=100, exchange='XNYS')[source]
Configuration for opt-in Monte Carlo VaR / CVaR + path chart in reports.
Pass to
mktlib.reports.html()/mktlib.reports.metrics()via themc_config=kwarg. Defaultenabled=Falsepreserves backwards-compatible report output exactly.When
enabled=True, the report runs three MC GBM batches under a single shared seed (one for the chart’s full simulation frame, two for the VaR / CVaR estimators). Identical seeds produce identical sample paths, so all three artefacts are mutually consistent. WhenseedisNonethe driver mints one OS-derived seed up front and threads it through all three calls.The dataclass intentionally has no “method” knob (closed-form Gaussian vs simulation): when MC is enabled we always run paths because the spaghetti chart requires actual paths. Users who want closed-form numbers without paths should call
mktlib.metrics.var(method="gaussian")directly.- Parameters:
enabled (
bool) – Master switch;False(default) disables the entire MC code path and the report renders identically to v0.10.x.horizon (
int) – Forecast horizon in trading bars (default 21 ≈ 1 month at 252 ppy).n_simulations (
int) – Number of simulated paths (default 10 000). At default scales, Gaussian MC runs in ~10 ms / Student-t in ~15 ms.innovations (
Innovations|None) –mktlib.data.Innovationsmember orNone(Gaussian default).STUDENT_Trequiresdf;BOOTSTRAPresamples standardized empirical residuals from the input series.df (
float|None) – Degrees of freedom forInnovations.STUDENT_T(>2).seed (
int|None) – Reproducibility seed.Noneuses OS entropy.alpha (
float) – Tail probability for both the VaR / CVaR numbers and theα/2 / 1−α/2percentile band on the path chart.n_paths_displayed (
int) – Number of individual MC paths to render in the spaghetti plot. Hard-capped at 500 inside the chart helper to keep the Plotly DOM responsive — pass any larger value and it is silently clipped.exchange (
str) – ISO MIC for the calendar used to project forward dates on the path chart’s x-axis ("XNYS"/"XLON"/"XPAR"/"XCME"/"XNAS"/"XCBO"/"XTSE"/"XETR"/"XTKS").
- innovations: Innovations | None
Three MC runs per report, one shared seed. Internally html()
and metrics() run mktlib.metrics.monte_carlo_paths() for
the chart frame plus two mktlib.metrics.simulate_metric() calls
(VaR + CVaR), all threaded through one fixed seed so they produce
identical sample paths. When mc_config.seed is None the
driver mints one OS-derived seed up front and reuses it across all
three calls; otherwise the user-supplied seed is honoured. At the
perf-path defaults (~10–15 ms per MC batch) the triplet adds 30–45 ms
total — invisible inside the typical tearsheet render.
from mktlib.data import Innovations
from mktlib.reports import html, MonteCarloConfig
# Heavy-tailed Student-t innovations, 21-bar (≈1 month) horizon
html(
returns,
title="Forward-Looking Tearsheet",
output="tearsheet.html",
mc_config=MonteCarloConfig(
enabled=True,
horizon=21,
n_simulations=10_000,
innovations=Innovations.STUDENT_T,
df=5,
seed=42,
alpha=0.05,
n_paths_displayed=100,
exchange="XNYS",
),
)
The chart’s x-axis spans roughly 60 historical bars plus the forecast
horizon, with forward dates generated via
mktlib.scheduling.get_calendar(exchange).session_offset(...) so
weekends and holidays are skipped.
Displayed-subset sampling. When n_simulations > n_paths_displayed
the chart renders only a subset of paths. The subset is drawn via
uniform random sampling without replacement, seeded from the MC
run’s parent seed for reproducibility — this is preferred over taking
the prefix simulation < n_paths_displayed because the prefix
relies on the underlying RNG’s i.i.d. property over consecutive
samples (mostly fine for modern PRNGs but a known MC-literature
footgun re: warm-up bias). Distributional equivalence between the
displayed subset and the full population is regression-tested via
two-sample Kolmogorov–Smirnov.
Note
When enabled=False (the default), the mc_* fields stay
None and the tearsheet renders identically to v0.10.x. The
MonteCarloConfig import has zero runtime cost on
[reports]-only installs — the mktlib.data dependency is
loaded lazily inside the MC code path.