Risk Dimensions

Calculations We Use rd_metrics v0.1

One source of truth so every analyst, notebook, and agent computes the same metric the same way. Each row is a calculation in the rd_metrics library. Cite rd_metrics v0.1 on any deliverable. Risk V2 (downside-only) is reality; V1 (total-vol) is kept for comparison.
V2 — reality  V1 — comparison  relative / vs benchmark

House conventions

Total return. Performance uses adjusted close / a total-return index, never raw price.

Inputs. Functions take periodic returns (decimal, 0.012 = 1.2%) unless the row says "prices".

Annualization. ppy = periods per year: 252 daily · 52 weekly · 12 monthly · 4 quarterly · 1 annual.

Rates. Risk-free rf and MAR (minimum acceptable return) are annual decimals, default 0.

Stats. Sample standard deviation (ddof=1). NaNs dropped (pairwise for two-series metrics).

Core — return & growth

MetricWhat it meansFormula (essence)Function
Periodic returnsPer-period return from a price / TR seriesp_t / p_{t-1} − 1 (or log)to_returns(prices, kind)
Total returnCompounded return over the window∏(1+r) − 1total_return(r)
Annualized returnGeometric annual rate of the return stream(1+TR)^(ppy/n) − 1ann_return(r, ppy)
CAGRCompound annual growth from a price series(last/first)^(ppy/(n−1)) − 1cagr(prices, ppy)

Risk — V2 (the real measures)

MetricWhat it meansFormula (essence)Function
Downside deviationAnnualized dispersion of shortfalls vs MAR — only bad moves count√(mean(min(r−MAR,0)²)) · √ppydownside_deviation(r, mar, ppy)V2
Max drawdownWorst peak-to-trough of the equity curve (negative)min(equity/peak − 1)max_drawdown(r)V2
SortinoReturn per unit of bad volmean(excess) / downside_dev · √ppysortino(r, mar, rf, ppy)V2
CalmarReturn per unit of worst painann_return / |max_drawdown|calmar(r, ppy)V2

Risk — V1 (kept for comparison)

MetricWhat it meansFormula (essence)Function
VolatilityAnnualized total volatility — treats up and down the samestd(r, ddof=1) · √ppyann_vol(r, ppy)V1
SharpeReturn per unit of total volmean(excess)/std(excess) · √ppysharpe(r, rf, ppy)V1

Relative — vs a market or benchmark

MetricWhat it meansFormula (essence)Function
CorrelationPearson correlation of two return streamscorr(a, b)correlation(a, b)rel
BetaSensitivity to a market seriescov(asset, mkt) / var(mkt)beta(r, market)rel
AlphaAnnualized CAPM excess over what beta predictsann_ret − [rf + β(ann_ret_mkt − rf)]alpha(r, market, rf, ppy)rel
Tracking errorAnnualized std of active return (vs benchmark)std(r − bench) · √ppytracking_error(r, bench, ppy)rel
Information ratioActive return per unit of tracking errormean(active)/std(active) · √ppyinformation_ratio(r, bench, ppy)rel

Distribution shape

MetricWhat it meansFormula (essence)Function
SkewAsymmetry of returns (sample skewness)bias-correctedskew(r)
Excess kurtosisTail heaviness (normal = 0)Fisherkurtosis(r)
Tear-sheet bundleAll of the above as one dict — the standard summarysummary(r, rf, mar, ppy)

How to use it

Point Claude or any agent at rd_metrics.sortino() instead of letting it freelance a formula. One import, every calculation house-standard:

import rd_metrics as m

s = m.summary(returns, ppy=252)     # full tear sheet
m.sortino(returns, mar=0.0)         # one metric
m.cagr(prices, ppy=252)             # from a price series

Why this exists

Uniformity — everyone computes Sortino the same way. Auditable trail — versioned, tested calcs any deliverable can cite. Agent-ready — a named function beats a re-derived formula. The framing (Risk V1 vs V2, good vol vs bad vol) is in docs/first_principles.md.

Risk Dimensions · rd_metrics v0.1 · source lib/rd_metrics/ · tests test_rd_metrics.py (all pass) · glossary docs/rd_metrics_glossary.md