From 40853745c6d6fc5c05b8701f0878b03bad5c3863 Mon Sep 17 00:00:00 2001 From: aszerW Date: Sat, 6 Jun 2026 16:16:42 +0800 Subject: [PATCH] =?UTF-8?q?docs:=20=E6=B7=BB=E5=8A=A0=E5=8A=A8=E9=87=8F?= =?UTF-8?q?=E5=9B=A0=E5=AD=90=E5=AF=B9=E6=AF=94=E8=B0=83=E7=A0=94=E6=8A=A5?= =?UTF-8?q?=E5=91=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 包含4种因子公式对比、回测结果、slope_r2胜出原因分析、 业界学界方法调研(TSMOM/Baltas&Kosowski/AQR)、 负价格处理机制分析及改进建议 --- reports/动量因子对比调研报告.md | 262 ++++++++++++++++++++++++++++++++ 1 file changed, 262 insertions(+) create mode 100644 reports/动量因子对比调研报告.md diff --git a/reports/动量因子对比调研报告.md b/reports/动量因子对比调研报告.md new file mode 100644 index 0000000..1a0f7cd --- /dev/null +++ b/reports/动量因子对比调研报告.md @@ -0,0 +1,262 @@ +# 动量因子对比调研报告 + +> 调研日期:2026-06-06 +> 回测区间:2020-01-10 ~ 2026-06-05 +> 当前结论:`slope_r2` 作为默认因子(年化 19.84%,夏普 1.14) + +--- + +## 1. 问题背景 + +原始策略使用 `weighted_momentum` 因子,通过加权线性回归计算动量得分。诊断分析发现三个信号质量瓶颈: + +1. **跨市场动量不可比**:同组换仓 alpha=+0.47%,跨组换仓仅 +0.03% +2. **IC 极低**:IC=0.07,ICIR=0.17 +3. **T+1 执行噪声**:跨市场约 50% 翻转率 + +核心问题是:不同资产的动量得分量纲差异巨大(如 CL=F 原油极端值可达 375,527,068),导致跨资产比较失真。 + +--- + +## 2. 四种因子公式对比 + +### 2.1 weighted_momentum(加权线性回归动量) + +$$\text{Score} = (e^{\beta \times 250} - 1) \times R^2$$ + +**计算逻辑**: +- 价格变换:$y = \ln(\text{prices})$,取对数 +- 回归权重:$w = \text{linspace}(1, 2, n)$,近期权重线性递增 +- 加权线性回归:$y = \beta x + \alpha$ +- 年化收益:$e^{\beta \times 250} - 1$ +- $R^2$:加权决定系数 + +**特点**:近期加权强调趋势延续性,对数收益使跨资产量纲部分可比。 + +--- + +### 2.2 vol_adjusted_momentum(波动率调整动量) + +$$\text{Score} = \frac{\text{年化收益}}{\text{年化波动率}} \times R^2$$ + +**计算逻辑**: +- 回归逻辑与 weighted_momentum 完全相同 +- 额外除以已实现波动率:$\sigma = \text{std}(\text{daily\_returns}) \times \sqrt{250}$ +- 最小波动率保护:$\sigma \geq 0.01$ + +**学术来源**:Moskowitz, Ooi & Pedersen (2012) *Time Series Momentum*,类夏普比率构造。 + +**特点**:理论上使跨资产更可比,但实践中波动率计算对极端值敏感。 + +--- + +### 2.3 slope_r2(斜率×R²,归一化价格) + +$$\text{Score} = 10000 \times \text{slope} \times R^2$$ + +**计算逻辑**: +- 价格变换:$y = \text{prices} / \text{prices}[0]$,**归一化而非取对数** +- **无权重**,普通最小二乘回归:$y = \text{slope} \cdot x + \text{intercept}$ +- $R^2$:无权重决定系数 +- 乘以 10000 使数值范围便于阅读 + +**特点**:归一化天然消除量纲差异,所有资产起点为 1.0,斜率在同尺度上可比。 + +--- + +### 2.4 momentum(简单收益率) + +$$\text{Score} = \frac{\text{prices}[-1]}{\text{prices}[0]} - 1$$ + +**计算逻辑**: +- 最朴素:期末价格 / 期初价格 - 1 +- 不考虑趋势质量(无 $R^2$)、不考虑波动率 + +**特点**:简单但缺乏趋势质量过滤,对短期噪声敏感。 + +--- + +## 3. 回测对比结果 + +### 3.1 核心指标 + +| 因子类型 | 年化收益 | 夏普比率 | 最大回撤 | Calmar | 调仓次数 | 胜率 | +|---------|---------|---------|---------|--------|---------|------| +| weighted_momentum | 18.36% | 1.02 | -16.36% | 1.12 | 405 | 54.0% | +| vol_adjusted_momentum | 13.16% | 0.85 | -18.61% | 0.71 | 393 | 55.9% | +| **slope_r2(当前默认)** | **19.84%** | **1.14** | **-15.35%** | **1.29** | 394 | 54.1% | +| momentum | 9.27% | 0.57 | -17.42% | 0.53 | 729 | 53.3% | + +**结论**:`slope_r2` 全面胜出,年化 +1.48%,夏普 +0.12,回撤改善 +1.01%。 + +### 3.2 数值尺度分析(2024-06-03 截面) + +| 因子 | 最大值 | 最小正值 | max/min 比值 | +|------|-------|---------|-------------| +| weighted_momentum | 0.633 | 0.0003 | **2179x** | +| vol_adjusted_momentum | 4.812 | 0.0014 | **3378x** | +| **slope_r2** | **23.18** | **0.745** | **31x** | +| momentum | 0.046 | 0.0005 | 90x | + +`slope_r2` 的跨资产数值差距仅 31 倍,远小于其他因子的 2000~3000 倍,这是其跨市场可比的根本原因。 + +--- + +## 4. slope_r2 胜出的原因分析 + +### 4.1 跨市场可比性:归一化消除量纲 + +| 设计选择 | weighted 的做法 | slope_r2 的做法 | 为什么 slope_r2 更好 | +|---------|---------------|----------------|-------------------| +| 价格变换 | $\ln(p)$ | $p/p_0$ | 归一化后所有资产同尺度 | +| 回归权重 | 近期加权(1→2) | 无权重 | 25 天窗口已短,等权更抗噪 | +| $R^2$ 质量因子 | ✓ | ✓ | 都保留了趋势质量过滤 | + +### 4.2 不加权 > 加权:降噪效应 + +25 天窗口本身就不长,加权(权重 1→2)相当于把有效窗口缩到约 17 天,增加了随机性。等权回归对 25 天趋势的估计更稳健。 + +### 4.3 负价格免疫力 + +WTI 原油 2020-04-21 出现 -37.63 美元/桶的负价格。各因子处理方式: + +| 因子 | 处理方式 | 问题 | +|------|---------|------| +| weighted | $\ln(\text{clip}(0.01)) = -4.6$ | 虚假平台拉偏回归 | +| vol_adjusted | 对数收益率跳跃 | vol 被放大,score 压低 | +| **slope_r2** | $0.01/60 \approx 0.000167$ | 跌幅压缩但不爆炸 | +| momentum | $25/0.01 - 1 = 2499$ | 荒谬收益率,严重误判 | + +--- + +## 5. 业界学界方法调研 + +### 5.1 Moskowitz, Ooi & Pedersen (2012) — TSMOM + +**核心公式**: +``` +Signal = sign(r_{t-12, t}) // 仅取过去12月超额收益的符号 +Position = (1/σ_t) × Signal // 仓位反比于波动率 +``` + +**关键设计**: +- 使用**期货超额收益**(简单收益),不用对数收益 +- 只用 sign(正负号)决定方向,不用收益率幅度 +- 仓位大小由波动率倒数控制 + +**对负价格的态度**:简单收益天然兼容负价格,$(−5−60)/60 = −108\%$ 合法。 + +### 5.2 Baltas & Kosowski (2012) — 线性趋势拟合 + +> "Momentum trading signals generated by **fitting a linear trend on the asset price path** maximise the out-of-sample performance while minimizing the portfolio turnover." + +这正是 `slope_r2` 的思路——直接拟合价格路径而非计算收益率。 + +**结论**:线性趋势拟合 > 简单收益率 > 加权收益率。 + +### 5.3 Dudler, Gmuer, Malamud (2014) — Risk-Adjusted Momentum + +$$\text{RAMOM} = \text{mean}\left(\frac{r_1}{\sigma_1}, \frac{r_2}{\sigma_2}, \ldots, \frac{r_n}{\sigma_n}\right)$$ + +每天先算风险调整收益 $r_t/\sigma_t$,再取均值作为信号。比 TSMOM 整体更优。 + +### 5.4 AQR / Man Group / Winton — 实盘 CTA 做法 + +| 方法 | 做法 | 代表机构 | +|------|------|---------| +| **简单收益替代对数** | $r = (P_t - P_{t-1}) / P_{t-1}$ | AQR, Man AHL | +| **排除/跳过** | 窗口内出现非正价格时信号设为 0 | 多数 CTA | +| **连续合约** | 使用 roll-adjusted futures 价格 | 所有正规 CTA | +| **波动率缩放** | 只用 sign + vol 倒数,不用幅度 | Moskowitz 方案 | + +--- + +## 6. 负价格处理机制分析 + +### 6.1 当前实现的问题 + +四个因子均使用 `np.clip(prices, 0.01, None)` 处理负价格: + +```python +prices = np.clip(prices, 0.01, None) # 负值 → 0.01 +``` + +**问题**:这是粗暴的掩盖而非正确处理。 + +| 因子 | clip 后的核心问题 | 严重程度 | +|------|------------------|---------| +| weighted | $\log(0.01) = -4.6$ 形成假平台,拉偏回归 | 中 | +| vol_adjusted | 对数收益率剧烈跳跃,vol 被放大 | **高** | +| slope_r2 | 跌幅被压缩,但不产生数值爆炸 | **低** | +| momentum | 首尾任一被 clip 就产生荒谬比值 | **极高** | + +### 6.2 推荐改进方案 + +**方案 A:排除法(推荐)** + +窗口内出现非正价格 → 返回 `None`,该资产不参与排名。 + +```python +def _compute_momentum(self, signal_code: str, date: pd.Timestamp) -> Optional[float]: + # ... 获取 prices ... + if np.any(prices <= 0): + return None # 负价格期间不参与交易 + # ... 计算 score ... +``` + +**优点**: +- 负油价在历史上只出现几天,排除影响极小 +- 避免所有 clip 导致的信号扭曲 +- 实现成本极低 + +**方案 B:简单收益替代对数** + +把 `weighted_momentum` 和 `vol_adjusted` 的 `log(prices)` 改为简单收益率。但 `slope_r2` 已在价格空间操作,无需修改。 + +**方案 C:保持现状** + +`slope_r2` 已是当前最优(年化 19.84%),且对负价格抵抗力最强。clip 只在极端情况触发,实际影响有限。 + +--- + +## 7. 结论与建议 + +### 7.1 当前决策 + +**采用 `slope_r2` 作为默认因子**,配置已切换至 `config_simple.yaml`: + +```yaml +factor: + type: slope_r2 + n_days: 25 +``` + +### 7.2 理论依据 + +1. **跨市场可比**:归一化价格天然消除量纲差异 +2. **趋势质量**:$R^2$ 过滤噪声趋势 +3. **抗极端值**:不使用对数,对负价格免疫力最强 +4. **学术支持**:Baltas & Kosowski (2012) 证实线性趋势拟合优于简单收益率 + +### 7.3 后续优化方向 + +| 方向 | 描述 | 优先级 | +|------|------|-------| +| 负价格排除 | 窗口内出现非正价格时返回 None | 低(实际影响极小) | +| 多窗口融合 | 结合 5/25/60 天信号 | 中 | +| 截面 rank | 动量值转截面百分位排名 | 低(slope_r2 已天然可比) | + +--- + +## 附录:实验代码 + +对比实验脚本:`rotation/experiments/factor_comparison.py` + +运行方式: +```bash +cd /Users/aszer/code/etf +set -a && source .env && set +a +python rotation/experiments/factor_comparison.py +``` + +结果输出:`rotation/experiments/output/factor_comparison_results.json`