Superseded (2026-05-25) — this operator is a Layer-1 transform, not a Layer-0 atomic input. Merged into
sortino_ratio_v1. Kept for history.
What (One-liner)
Sortino ratio — risk-adjusted return that only penalizes downside volatility. Asymmetric correction of Sharpe. Library-level primitive, candidate Canvas node.
How to use
python
from services.algo.time_series import sortino_ratio
sortino = sortino_ratio(returns, risk_free_rate=0.02)Core formulas
excess = returns - rf/252
downside = [x for x in excess if x < 0]
sortino = mean(excess) / std(downside, ddof=0) × √252Zero downside → 0.0.
Assumptions & applicability
Assumptions: Daily frequency + 252 annualization + MAR=0 (not custom target).
Applicability: Fat-tailed / skewed / hedge fund-style strategies.
Out of scope: Intraday, all-positive return sequences, n<30.
Known limitations
- MAR hardcoded 0 (custom target return not supported)
- Zero downside clamp 0 (BUG-GOLDEN-001 fix approach)
- Shares annualization factor assumptions with Sharpe
References
Sortino & Price (1994) + Rollinger-Hoffman (2013) calculation pitfalls guide.
Golden Test
tests/golden/fixtures/tier1/sortino_ratio/, 1e-12 tolerance, 2026-04-20 passing.
Changelog
- 1.0.0 (2026-04-20) — First Active, BUG-GOLDEN-001 fix

