Skip to content

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 映射。

怎么用

  1. 提供 returns 数组。
  2. 可选设置 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。

已知局限

  1. 低于 target 的观测极少时未定义 / 不稳定。
  2. target_return 的取值会明显改变结果。
  3. 零 downside clamp 到 0.0(修复 BUG-GOLDEN-001 做法)。
  4. 与 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 卡片。

Verifiable intelligence for the decisions that demand scrutiny.