feat: 新增 standardized_slope (t-statistic) 因子并实验验证

- simple_rotation.py: 新增 standardized_slope_score 函数 (slope/SE)
- config_loader.py: FactorType 枚举新增 STANDARDIZED_SLOPE
- 对比实验结果: standardized_slope 年化 13.73% vs slope_r2 19.84%
- 结论: t-statistic 过度惩罚高波动资产的有效趋势信号,不适合本场景
- 文档更新: 动量因子对比调研报告新增 3.3 节详细分析
This commit is contained in:
2026-06-06 16:40:01 +08:00
parent aff04318b1
commit 921f84cb6a
5 changed files with 224 additions and 2 deletions

View File

@@ -86,9 +86,12 @@ $$\text{Score} = \frac{\text{prices}[-1]}{\text{prices}[0]} - 1$$
| 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% |
| standardized_slope | 13.73% | 1.01 | -13.52% | 1.02 | 335 | 54.5% |
**结论**`slope_r2` 全面胜出,年化 +1.48%,夏普 +0.12,回撤改善 +1.01%。
> **注**`standardized_slope`t-statistic回撤更小但收益大幅落后年化 -6.11%),说明统计显著性过滤在高波动资产上过度惩罚趋势信号,不适合本场景(详见 3.3)。
### 3.2 数值尺度分析2024-06-03 截面)
| 因子 | 最大值 | 最小正值 | max/min 比值 |
@@ -100,6 +103,31 @@ $$\text{Score} = \frac{\text{prices}[-1]}{\text{prices}[0]} - 1$$
`slope_r2` 的跨资产数值差距仅 31 倍,远小于其他因子的 2000~3000 倍,这是其跨市场可比的根本原因。
### 3.3 standardized_slopet-statistic实验
**公式**
$$\text{Score} = \frac{\hat{\beta}}{\text{SE}(\hat{\beta})}, \quad \text{SE}(\hat{\beta}) = \sqrt{\frac{\text{MSE}}{S_{xx}}}$$
**学术动机**t-statistic 同时考虑了斜率大小和估计的统计显著性,理论上比 `slope × R²` 更严格。
**实验结果**
| 指标 | slope_r2 | standardized_slope | Δ |
|------|---------|-------------------|---|
| 年化收益 | 19.84% | 13.73% | **-6.11%** |
| 夏普比率 | 1.14 | 1.01 | **-0.12** |
| 最大回撤 | -15.35% | -13.52% | +1.83% |
| Calmar | 1.29 | 1.02 | -0.27 |
| 调仓次数 | 394 | 335 | -59 |
**失败原因分析**
- **绝对度量 vs 相对度量**`SE(β)` 是绝对度量(量纲同斜率),而 `R²` 是相对度量无量纲。在跨资产比较中SE 对高波动资产(如 CL=F、HSTECH惩罚过重即使趋势方向正确score 也会被压低。
- **过度过滤**:调仓次数减少 59 次,说明 t-statistic 把大量"方向对但波动大"的有效信号过滤掉了,反而错失趋势行情。
- **数学等价性**`slope / SE(slope) = slope × √(Sxx / MSE)`,而 `slope × R² = slope × (1 - SS_res/SS_tot)`。前者惩罚的是残差方差绝对值,后者惩罚的是偏离趋势线的比例——后者更适合作为趋势质量因子。
**结论**t-statistic 不适合本场景,保持 `slope_r2` 为默认因子。
---
## 4. slope_r2 胜出的原因分析
@@ -245,18 +273,22 @@ factor:
| 负价格排除 | 窗口内出现非正价格时返回 None | 低(实际影响极小) |
| 多窗口融合 | 结合 5/25/60 天信号 | 中 |
| 截面 rank | 动量值转截面百分位排名 | 低slope_r2 已天然可比) |
| ~~标准化斜率~~ | slope/SE(slope),已验证不适合(详见 3.3 | **已排除** |
---
## 附录:实验代码
对比实验脚本:`rotation/experiments/factor_comparison.py`
对比实验脚本:`rotation/experiments/factor_comparison.py``rotation/experiments/std_slope_test.py`
运行方式:
```bash
cd /Users/aszer/code/etf
set -a && source .env && set +a
python rotation/experiments/factor_comparison.py
python rotation/experiments/std_slope_test.py
```
结果输出:`rotation/experiments/output/factor_comparison_results.json`
结果输出:
- `rotation/experiments/output/factor_comparison_results.json`
- `rotation/experiments/output/std_slope_test_results.json`