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:
@@ -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_slope(t-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`
|
||||
|
||||
Reference in New Issue
Block a user