Sortino 比率
下行偏差调整版夏普。仅惩罚负收益(低于 target_return 的收益),采用与 Sharpe 相同的零波动守卫。Edge-first;连到多个 Price Factor 时按标的 fan out 为 by_symbol。
做什么(One-liner)
Layer-1 变换:消费收益率序列,输出只惩罚下行(低于 target)波动的风险调整收益 —— Sharpe 的非对称修正。零 downside clamp 到 0.0,不是 inf。
输入
returns(array,必填)—— 收益率序列。target_return(number,可选)—— 最低可接受收益,默认 0。annualization_factor(number,可选)—— 默认 252。
输出
sortino_ratio—— 年化 Sortino。by_symbol—— 连多个 Price Factor 时的 per-ticker 映射。
怎么用
- 提供
returns数组。 - 可选设置
target_return(默认 0)与annualization_factor。
核心公式
excess = returns - rf
downside = [min(x - target, 0) for x in excess]
sortino = mean(excess) / std(downside, ddof=0) × √年化因子零 downside → 0.0。
假设与适用场景
假设:年化因子与输入频率匹配(日频 252)+ MAR = target_return(默认 0)+ downside std 右截断 + 零 downside → 0.0。
适用:厚尾 / 偏斜 / hedge fund-style 策略,n ≥ 30。
不适用:intraday、全正收益序列、短序列 n<30。
已知局限
- 低于 target 的观测极少时未定义 / 不稳定。
target_return的取值会明显改变结果。- 零 downside clamp 到 0.0(修复 BUG-GOLDEN-001 做法)。
- 与 Sharpe 共享年化假设。
参考文献
Sortino & Price (1994) + Rollinger-Hoffman (2013) 计算陷阱指南。
Golden Test
tests/golden/fixtures/tier1/sortino_ratio/,1e-12 tolerance,2026-05-25 passing。参考:numpy 2.2.6 独立重实现 Sortino-Price (1994)。
Changelog
- 1.1.0 (2026-05-25) —— 提升为 Active 的 Layer-1 变换;并入已弃用 Layer-0
sortino_ratio卡片的完整治理字段。 - 1.0.0 (2026-05-23) —— 初始 edge-first Layer-1 Draft 卡片。

