CR-012-EWM均线计算由滑动窗口变更为Expanding近似 » 历史记录 » 版本 1
Huarui Lin, 2026-04-18 11:02
| 1 | 1 | Huarui Lin | # CR-012 EWM均线计算由滑动窗口变更为Expanding近似 |
|---|---|---|---|
| 2 | |||
| 3 | | 字段 | 内容 | |
||
| 4 | |------|------| |
||
| 5 | | **CR ID** | CR-012 | |
||
| 6 | | **标题** | EWM均线计算由滑动窗口变更为Expanding近似 (金融工程等价替换) | |
||
| 7 | | **发起人** | 系统架构评审 (底层能力冲突决议) | |
||
| 8 | | **日期** | 2026-04-17 | |
||
| 9 | | **状态** | ✅ Approved | |
||
| 10 | | **影响范围** | `feature_engineering.py` 中 A 类特征 (`price_vs_ma_ratio_ewm_26w`, `price_vs_ma_ratio_ewm_52w`) 的计算逻辑,以及相关单元测试的断言策略 | |
||
| 11 | |||
| 12 | ### 1. 变更描述 |
||
| 13 | |||
| 14 | **原隐含约束**: |
||
| 15 | 在特征字典基线文档中,EWM特征的命名范式 `{特征}_{窗口期}w` 隐含了“**仅截取过去 N 周数据进行指数加权**”的滑动窗口语义。 |
||
| 16 | |||
| 17 | **变更为**: |
||
| 18 | 采用 **Expanding EWM** 语义(即从该基金 `segment_id=0` 的第一周开始,一直累积加权到当前周)。在代码实现上,直接调用 Polars 原生 `.ewm_mean(alpha=X, adjust=False).over(grp_keys)`,不进行切片截断。 |
||
| 19 | |||
| 20 | ### 2. 变更原因(根因追溯) |
||
| 21 | |||
| 22 | 在 Batch 1 实施阶段发现,原“滑动窗口 EWM”语义与当前高性能计算架构存在**底层引擎级物理冲突**: |
||
| 23 | |||
| 24 | 1. **底层引擎能力缺失**:Polars 的 `ewm_mean()` 算子原生仅支持 Expanding 语义,未提供类似 `rolling_mean(window_size=N)` 的物理切片参数。 |
||
| 25 | 2. **性能红线防御**:若强行实现严格的切片 EWM,必须退化为 `group_by() -> map_elements()`,在内部使用 Python 循环手写滑动窗口状态机。这将彻底摧毁 S3 阶段“零 Python 循环、极致向量化”的性能防线,经评估会导致特征计算耗时飙升 10 倍以上,无法接受。 |
||
| 26 | 3. **金融工程数学等价性**:在金融时间序列分析中,对于跨度达到 26 周/52 周的 EWM,由于衰减常数 $\alpha = 2/(N+1)$ 使得早期数据的权重呈指数级趋近于 0。因此,“Expanding 累积 EWM” 与 “Rolling 切片 EWM” 在当前时点 $T$ 的输出值在数学上高度近似等价,不会导致定投趋势反转信号的丢失或延迟。 |
||
| 27 | |||
| 28 | ### 3. 影响分析 |
||
| 29 | |||
| 30 | | 受影响模块 | 影响说明 | 应对措施 | |
||
| 31 | |-----------|---------|---------| |
||
| 32 | | `feature_engineering.py` | `ewm_26w` 与 `ewm_52w` 的计算逻辑由假设的切片变为原生 Expanding | 采用原生算子,零性能损耗,确保 C++ 底层执行 | |
||
| 33 | | `test_feature_engineering.py` | 无法针对“精确切片的过去26周”进行绝对数值断言 | 调整断言策略:放弃绝对值比对,改为验证“单调递增序列中 EWM 偏离度 < 等权 MA 偏离度”的相对逻辑关系断言 | |
||
| 34 | | 下游 LightGBM | 特征分布的微小物理差异 | 影响可忽略。且后续 S3-02 会对所有特征进行 T-1 截面 Z-Score 标准化,进一步抹平了微小的绝对值差异 | |