项目

一般

简介

行为

CR-013 下行波动率与Sortino分母公式修正为严格半方差

字段 内容
CR ID CR-013
标题 下行波动率与Sortino分母计算由“截断序列标准差”修正为“严格半方差开方”
发起人 架构顾问 (数学公式严密性审查)
日期 2026-04-17
状态 ✅ Approved
影响范围 0001-特征字典基线文档.txt B/E类公式定义、feature_engineering.py 底层算子实现、test_feature_engineering.py 期望值断言

1. 变更描述

原基线公式约束:

  • downside_vol_26w: rolling_std(min(weekly_return, 0), 26)
  • rolling_sortino_26w 分母: rolling_std(min(weekly_ret, 0), 26)

变更为:

  • downside_vol_26w: $\sqrt{Mean(\min(weekly_return, 0)^2)}$ (即负收益平方的均方根 RMS)
  • rolling_sortino_26w 分母: $\sqrt{Mean(\min(weekly_ret - rf, 0)^2)}$ (即超额收益为负部分的半方差开方,目标收益率切换为无风险利率)

2. 变更原因(根因追溯)

在代码实施前的数学推演审查中发现,原基线公式存在严重的数学定义谬误:

  1. 零值污染导致方差缩水:原公式 rolling_std(min(ret, 0)) 实际计算的是“包含大量人为零值的截断序列的标准差”。将正收益强行置为 0 后,这些 0 会拉低序列均值 $\bar{X}$,导致原本真正的负收益偏离度 $(X - \bar{X})^2$ 被严重缩小,算出的值远小于真实下行风险。
  2. 违背“半方差”本意:业界标准的下行波动率(半方差开方)衡量的是“低于目标收益率部分的偏离度的平方根”,数学上是直接对偏离值求平方平均再开方(不减去均值,因为目标就是 0)。原公式错用了一般标准差的计算逻辑。
  3. 破坏树模型分裂点:对于 LightGBM,原公式会在原本没有 0 值的连续负收益分布中,强行注入大量绝对 0 值,制造出虚假的“数据密集区”,直接干扰决策树寻找最优信息增益分裂点。

3. 影响分析

受影响模块 影响说明 应对措施
0001-特征字典基线文档.txt B类与E类的公式描述必须重写,彻底消除 rolling_std(min(...)) 字眼 发起基线文档修订,锁定严格半方差公式
feature_engineering.py 底层算子无法直接复用 Polars 的 .rolling_std(),需改为 (pl.col("down_ret")**2).rolling(N).mean().sqrt() 重构波动矩阵计算逻辑,确保向量化且无零值污染
test_feature_engineering.py 针对 downside_vol 和 sortino 的手工计算期望值需按新公式重新推导 更新单测中的 pytest.approx 期望值

由 Huarui Lin 更新于 6 个月 之前 · 1 修订