Skip to content

Sharpe Ratio

Annualized Sharpe ratio: (mean(return) − rf) / std(return) × sqrt(annualization_factor). Zero-volatility inputs are guarded via an np.ptp check (the BUG-GOLDEN-001 fix). Edge-first; wired to more than one Price Factor it fans out to per-ticker by_symbol results.

What (One-liner)

A Layer-1 transform: consume a returns series, emit the annualized risk-adjusted return. Constant (zero-volatility) returns clamp to 0.0, not NaN/inf.

Inputs

  • returns (array, required) — return series.
  • annualization_factor (number, optional) — default 252 (daily); 12 for monthly.
  • risk_free_rate (number, optional) — annualized risk-free rate, default 0.

Outputs

  • sharpe_ratio — annualized Sharpe.
  • by_symbol — per-ticker map when fed by multiple Price Factors.

How to use

  1. Provide a returns array.
  2. Set annualization_factor (252 for daily, 12 for monthly).
  3. Optionally set risk_free_rate (annualized).

Core formulas

per_period_rf = rf / annualization_factor
excess_t = r_t - per_period_rf
sharpe = mean(excess) / std(excess, ddof=0) × √annualization_factor

Special case: ptp(excess) == 0 (constant returns, no volatility) → returns 0.0 (not NaN / inf).

Assumptions & applicability

Assumptions: annualization_factor matches input frequency (252 daily / 12 monthly) + population std + linear per-period rf conversion + approximately normal returns.

Applicable: portfolio / strategy performance measurement, n ≥ 30.

Not applicable: intraday, fat-tailed assets, leveraged option portfolios, short series n<30.

Known limitations

  1. Penalizes upside and downside volatility symmetrically (see Sortino for downside-only).
  2. Sensitive to annualization_factor — daily vs monthly must match the input frequency.
  3. Normality assumption (large deviation for BTC/crypto).
  4. Zero volatility clamped to 0.0 (experience from BUG-GOLDEN-001).

References

Sharpe (1966) + Sharpe (1994) revisions. See frontmatter for details.

Golden Test

tests/golden/fixtures/tier1/sharpe_ratio/, 1e-12 tolerance, covering 3 scenarios: normal series / zero volatility / small sample. Passing as of 2026-05-25. Reference: independent numpy 2.2.6 reimplementation of the Sharpe 1966 definition.

Changelog

  • 1.1.0 (2026-05-25) — Promoted to Active as Layer-1 transform; merged rich governance fields from the superseded Layer-0 sharpe_ratio card.
  • 1.0.0 (2026-05-23) — Initial edge-first Layer-1 Draft card.

Verifiable intelligence for the decisions that demand scrutiny.