项目

一般

简介

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 标准化,进一步抹平了微小的绝对值差异 |