feat(backtest): 消除前视偏差,实现动态ETF池重建
消除回测前视偏差(Look-Ahead Bias): - 新增 ETFDataCache 本地缓存系统,预下载全量ETF(含已退市)基础信息和日线数据 - 改造 ETFUniverseBuilder 支持纯历史模式,每个时间点只使用当时可获得的数据 - 动量.py 新增 dynamic 模式,回测中每60交易日动态重建ETF候选池 - momentum_experiment.py 同步支持动态重建 - 新增 ETF筛选引擎文档和动态池方案文档 无前视偏差实验结果(6组对比,2015-2026): A: 全仓1只 CAGR=3.32%, MaxDD=-63.19%, Sharpe=0.26 B: 等权3只 CAGR=3.40%, MaxDD=-49.72%, Sharpe=0.30 ← 最优 C: 反波动率3只 CAGR=1.73%, MaxDD=-38.59%, Sharpe=0.21 D: 等权5只 CAGR=2.77%, MaxDD=-42.39%, Sharpe=0.29 E: 反波动率5只 CAGR=-0.37%, MaxDD=-19.56%, Sharpe=-0.03 F: 动量>0全选等权 CAGR=2.02%, MaxDD=-43.27%, Sharpe=0.24 最优方案: B(等权3只)夏普、Calmar、CAGR三项均最高
This commit is contained in:
300
docs/etf_rotation_framework.md
Normal file
300
docs/etf_rotation_framework.md
Normal file
@@ -0,0 +1,300 @@
|
||||
# ETF 动量轮动策略:筛选框架与多持仓实验分析
|
||||
|
||||
## 1. 系统概览
|
||||
|
||||
本系统从全市场 ETF 中,通过 **5 层漏斗** 筛选出低相关、高流动性、覆盖多资产类别的候选池,再以动量因子选出 Top-N 等权持仓。
|
||||
|
||||
```
|
||||
全市场 ETF (~900+)
|
||||
│ Layer 0: 拉取全量基础信息
|
||||
▼
|
||||
│ Layer 1: 上市≥1年 + 排除货币/杠杆 + 日均额≥5000万
|
||||
▼ (~200+)
|
||||
│ Layer 2: 同一跟踪指数去重 (保留流动性最优)
|
||||
▼ (~220)
|
||||
│ Layer 3: 三级分类链 → 10 大类资产标签
|
||||
▼
|
||||
│ Layer 4: 类内等比分配预筛 (ENB × 3 预算)
|
||||
▼ (~36)
|
||||
│ Layer 5: 相关性矩阵 + ENB → 贪心最大分散选择
|
||||
▼ (9 只, ENB 驱动)
|
||||
候选池 → 动量打分 → Top-3 等权持仓
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 2. 五层漏斗详解
|
||||
|
||||
### 2.1 Layer 0 — 全量拉取
|
||||
|
||||
通过 Tushare `fund_basic` 获取全量上市 ETF,字段包括:
|
||||
|
||||
| 字段 | 用途 |
|
||||
|------|------|
|
||||
| `ts_code`, `name` | 标识 |
|
||||
| `fund_type` | 一级分类 (股票型/债券型/商品型/REITs/货币市场型) |
|
||||
| `invest_type` | 二级分类 (黄金现货合约/白银期货型/被动指数型…) |
|
||||
| `benchmark` | 跟踪指数名称 (用于地域+行业判断) |
|
||||
| `list_date` | 上市日期 |
|
||||
|
||||
### 2.2 Layer 1 — 基础过滤
|
||||
|
||||
| 条件 | 阈值 | 目的 |
|
||||
|------|------|------|
|
||||
| 上市时间 | ≥ 365 天 | 排除新基金,确保有足够历史数据 |
|
||||
| 基金类型 | 排除货币型 | 不参与轮动 |
|
||||
| 名称过滤 | 排除杠杆/反向/分级 | 避免衍生品风险 |
|
||||
| 日均成交额 | ≥ 5000 万元 (60 日均值) | 保证流动性 |
|
||||
|
||||
### 2.3 Layer 2 — 同指数去重
|
||||
|
||||
从 ETF 名称提取核心指数名(去除基金公司前缀和 ETF/LOF/联接等后缀),同一指数只保留日均成交额最大的一只。
|
||||
|
||||
### 2.4 Layer 3 — 三级分类链
|
||||
|
||||
**核心创新**:不依赖纯关键词匹配,而是利用官方字段构建优先级分类链,覆盖率 100%。
|
||||
|
||||
```
|
||||
classify(row):
|
||||
┌─ 第1级: fund_type 硬判断
|
||||
│ REITs → REITs
|
||||
│ 货币市场型 → 货币/现金
|
||||
│ 商品型 → 商品
|
||||
│
|
||||
├─ 第2级: invest_type 细分
|
||||
│ 黄金现货合约 / 白银期货型 / 有色金属期货型
|
||||
│ 能源化工期货型 / 豆粕期货型 / 原油主题基金 → 商品
|
||||
│ (fund_type=债券型) → 债券
|
||||
│
|
||||
├─ 第3级: 商品名称优先 (防止 QDII 油气被误分到美股)
|
||||
│ name/benchmark 含 油气/原油/石油/能源行业 → 商品
|
||||
│
|
||||
├─ 第4级: 地域判断 (benchmark + name)
|
||||
│ 恒生/港股/H股 → 港股
|
||||
│ 纳斯达克/标普500/道琼斯 → 美股
|
||||
│ 日经/德国/越南/印度/全球 → 全球/其他
|
||||
│
|
||||
├─ 第5级: A股内部细分
|
||||
│ 沪深300/中证500/创业板… → A股宽基
|
||||
│ 红利/央企/ESG/AI… → A股主题
|
||||
│ 其余股票型/混合型 → A股行业
|
||||
│
|
||||
└─ 兜底: 货币/债券关键词 → 对应类别
|
||||
其他 → 未分类
|
||||
```
|
||||
|
||||
**最终 10 大类**:A股宽基、A股行业、A股主题、港股、美股、全球/其他、商品、债券、REITs、货币/现金
|
||||
|
||||
### 2.5 Layer 4 — 类内等比分配
|
||||
|
||||
不使用固定的 `INTRA_CLASS_LIMITS`,改为数据驱动的等比分配:
|
||||
|
||||
$$
|
||||
\text{budget} = \text{ENB}_{\text{fallback}} \times \text{candidate\_multiplier}
|
||||
$$
|
||||
|
||||
$$
|
||||
\text{limit}_i = \min\bigl(n_i,\; \max(\text{min\_per\_class},\; \lfloor r_i \times \text{budget} \rceil)\bigr)
|
||||
$$
|
||||
|
||||
其中 $r_i = n_i / \sum n_j$ 为第 $i$ 类在筛选后样本中的占比,$n_i$ 为该类可选 ETF 数量。
|
||||
|
||||
默认参数:`ENB_fallback=12, candidate_multiplier=3.0, min_per_class=2`,总预算约 36 只。
|
||||
|
||||
每类选取日均成交额最高的 `limit_i` 只。
|
||||
|
||||
### 2.6 Layer 5 — ENB 驱动 + 贪心选择
|
||||
|
||||
1. **计算相关性矩阵**:使用 120 个交易日收益率
|
||||
2. **确定目标池大小**:
|
||||
|
||||
$$
|
||||
\text{ENB} = \exp\!\Bigl(-\sum_{i=1}^{d} p_i \ln p_i\Bigr), \quad p_i = \frac{\lambda_i}{\sum_j \lambda_j}
|
||||
$$
|
||||
|
||||
其中 $\lambda_i$ 为相关性矩阵的特征值 (Meucci 2009)。ENB 衡量的是候选池中**独立风险因子**的有效数量。
|
||||
|
||||
3. **贪心选择**:
|
||||
- Step A:每个大类先选入流动性最好的 1 只(确保覆盖)
|
||||
- Step B:从剩余候选中贪心选取与已选集合最大相关系数最小的 ETF
|
||||
- 约束:最大相关系数 ≤ 0.85;A股行业占比 ≤ 50%
|
||||
|
||||
---
|
||||
|
||||
## 3. 多持仓对比实验
|
||||
|
||||
### 3.1 实验设计
|
||||
|
||||
从 Layer 5 输出的 9 只候选池(ENB 驱动版本)出发,使用动量策略打分,比较不同持仓数量和权重方案。
|
||||
|
||||
**动量打分**:自适应回看窗口 + 加权动量得分 + 崩溃过滤器 + 溢价率惩罚。得分在 (0, 6) 区间内视为有效正动量。
|
||||
|
||||
**6 组实验**:
|
||||
|
||||
| 编号 | 持仓数 | 权重方案 | 说明 |
|
||||
|------|--------|---------|------|
|
||||
| A | 1 | — | 全仓 1 只(基准) |
|
||||
| B | 3 | 等权 (1/N) | 每只 33.3% |
|
||||
| C | 3 | 反波动率 | 权重 ∝ 1/σ |
|
||||
| D | 5 | 等权 | 每只 20% |
|
||||
| E | 5 | 反波动率 | 权重 ∝ 1/σ |
|
||||
| F | 全部正动量 | 等权 | 所有得分>0 的 ETF 等权 |
|
||||
|
||||
**反波动率权重公式**:
|
||||
|
||||
$$
|
||||
w_i = \frac{1/\sigma_i}{\sum_{j=1}^{N} 1/\sigma_j}
|
||||
$$
|
||||
|
||||
$\sigma_i$ 为过去 20 个交易日的日收益率标准差。
|
||||
|
||||
### 3.2 实验结果
|
||||
|
||||
| 实验 | CAGR | 夏普比率 | 最大回撤 | Calmar | 盈利年 |
|
||||
|------|------|---------|---------|--------|-------|
|
||||
| A: 全仓1只 | 20.41% | 1.01 | -29.65% | 0.69 | 8/12 |
|
||||
| **B: 等权3只** | **15.11%** | **1.23** | **-17.96%** | **0.84** | **10/12** |
|
||||
| C: 反波动率3只 | 10.03% | 1.09 | -12.37% | 0.81 | 9/12 |
|
||||
| D: 等权5只 | 11.41% | 1.14 | -19.66% | 0.58 | 10/12 |
|
||||
| E: 反波动率5只 | 2.68% | 0.53 | -8.68% | 0.31 | 8/12 |
|
||||
| F: 动量>0全选等权 | 10.73% | 1.13 | -18.19% | 0.59 | 10/12 |
|
||||
|
||||
### 3.3 关键发现
|
||||
|
||||
1. **等权 3 只 (B) 综合最优**:夏普 1.23(最高)、Calmar 0.84(最高)、盈利年 10/12(并列最高)
|
||||
2. **全仓 1 只 (A) 收益最高但波动最大**:CAGR 20.41%,但最大回撤 -29.65%
|
||||
3. **5 只持仓边际收益递减**:D 和 E 相比 B 和 C,CAGR 大幅下降但回撤未明显改善
|
||||
4. **全选正动量 (F) ≈ 等权 5 只 (D)**:说明选优比全选更重要,动量 alpha 被稀释
|
||||
5. **反波动率权重降低收益**:低波动资产权重更高,倾向持有债券/货币等低收益品种
|
||||
|
||||
---
|
||||
|
||||
## 4. 等权选 3 只的理论基础
|
||||
|
||||
### 4.1 从信息论角度:√N 经验法则
|
||||
|
||||
当从 $N$ 个候选中选取子集构建组合时,一个经典的经验法则是:
|
||||
|
||||
$$
|
||||
k^* = \lfloor \sqrt{N} \rceil
|
||||
$$
|
||||
|
||||
对于 $N = 9$ 的候选池:
|
||||
|
||||
$$
|
||||
k^* = \sqrt{9} = 3
|
||||
$$
|
||||
|
||||
**直觉**:$\sqrt{N}$ 是分散化收益与集中度损失之间的平衡点。少于 $\sqrt{N}$ 时分散不足,多于 $\sqrt{N}$ 时每增加一只带来的边际方差下降不抵 alpha 稀释。
|
||||
|
||||
### 4.2 从动量文献角度:Top Decile / Top Tercile
|
||||
|
||||
Jegadeesh & Titman (1993, 2001) 的经典动量策略将资产按动量排序后分为 3~10 组,持有**最强的一组**:
|
||||
|
||||
$$
|
||||
\text{Top Group Size} = \frac{N}{D}
|
||||
$$
|
||||
|
||||
其中 $D$ 为分组数。当 $D = 3$(三分位法)时:
|
||||
|
||||
$$
|
||||
k = \frac{N}{3} = \frac{9}{3} = 3
|
||||
$$
|
||||
|
||||
Top Tercile (前 1/3) 是动量文献中最常用的分组方式之一,在回测中稳健地跑赢其他分位。
|
||||
|
||||
### 4.3 从等权理论角度:DeMiguel (2009)
|
||||
|
||||
DeMiguel, Garlappi & Uppal (2009) 在 "Optimal Versus Naive Diversification: How Inefficient is the 1/N Portfolio?" 中证明:
|
||||
|
||||
> 在估计误差存在的情况下,简单的 $1/N$ 等权组合在样本外表现优于大多数均值-方差优化模型,除非样本量 $T$ 满足:
|
||||
>
|
||||
> $$T > \frac{N(N+1)}{2} \cdot c$$
|
||||
>
|
||||
> 其中 $c$ 依赖于资产的夏普比率差异。
|
||||
|
||||
对于 $N = 3$:$T > 6c$(很容易满足);对于 $N = 9$:$T > 45c$(需要更长数据)。
|
||||
|
||||
**结论**:在小池子(N=9 候选、k=3 持仓)的场景下,等权是理论最优的权重方案。
|
||||
|
||||
### 4.4 从方差分解角度:边际分散效应递减
|
||||
|
||||
等权组合的方差为:
|
||||
|
||||
$$
|
||||
\sigma_p^2 = \frac{1}{k}\bar{\sigma}^2 + \frac{k-1}{k}\overline{\text{Cov}}
|
||||
$$
|
||||
|
||||
其中 $\bar{\sigma}^2$ 为平均方差,$\overline{\text{Cov}}$ 为平均协方差。
|
||||
|
||||
对 $k$ 求导:
|
||||
|
||||
$$
|
||||
\frac{\partial \sigma_p^2}{\partial k} = -\frac{1}{k^2}(\bar{\sigma}^2 - \overline{\text{Cov}})
|
||||
$$
|
||||
|
||||
边际方差下降 $\propto 1/k^2$,呈二次递减:
|
||||
|
||||
| k | 边际方差下降 (相对于 k=1) |
|
||||
|---|--------------------------|
|
||||
| 1 → 2 | $-25.0\%$ |
|
||||
| 2 → 3 | $-11.1\%$ |
|
||||
| 3 → 4 | $-6.3\%$ |
|
||||
| 4 → 5 | $-4.0\%$ |
|
||||
|
||||
从 k=1 到 k=3,方差下降约 $\frac{2}{3}(\bar{\sigma}^2 - \overline{\text{Cov}})$,覆盖了可分散风险的大部分;k>3 后边际效益显著递减。
|
||||
|
||||
### 4.5 综合公式
|
||||
|
||||
给定候选池大小 $N$ 和目标风险调整收益最大化,推荐持仓数:
|
||||
|
||||
$$
|
||||
\boxed{k^* = \max\!\Big(2,\; \min\!\big(\lfloor\sqrt{N}\rceil,\; \lfloor N/3 \rfloor\big)\Big)}
|
||||
$$
|
||||
|
||||
| 候选池 N | √N | N/3 | k* |
|
||||
|----------|-----|------|-----|
|
||||
| 6 | 2.4 → 2 | 2 | 2 |
|
||||
| 9 | 3.0 → 3 | 3 | **3** |
|
||||
| 12 | 3.5 → 4 | 4 | 4 |
|
||||
| 16 | 4.0 → 4 | 5 | 4 |
|
||||
| 20 | 4.5 → 5 | 6 | 5 |
|
||||
|
||||
---
|
||||
|
||||
## 5. 完整策略流程总结
|
||||
|
||||
```
|
||||
┌────────────────────────────────────────┐
|
||||
│ Layer 0-5: 五层漏斗筛选 (~月频重建) │
|
||||
│ 输出: N 只低相关候选池 (当前 N=9) │
|
||||
└──────────────┬─────────────────────────┘
|
||||
▼
|
||||
┌────────────────────────────────────────┐
|
||||
│ 动量打分 (日频/周频) │
|
||||
│ 自适应回看 + 加权动量 + 崩溃过滤 │
|
||||
│ 输出: 各 ETF 动量得分 │
|
||||
└──────────────┬─────────────────────────┘
|
||||
▼
|
||||
┌────────────────────────────────────────┐
|
||||
│ 选出 Top-k 持仓 │
|
||||
│ k = min(√N, N/3) = 3 │
|
||||
│ 仅选得分 > 0 的 ETF │
|
||||
└──────────────┬─────────────────────────┘
|
||||
▼
|
||||
┌────────────────────────────────────────┐
|
||||
│ 等权配置 (1/k) │
|
||||
│ 每只 33.3%,换仓时计算换手成本 │
|
||||
└────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 6. 参考文献
|
||||
|
||||
- **Meucci, A.** (2009). "Managing Diversification." *Risk*, 22(5). — ENB (Effective Number of Bets) 公式来源
|
||||
- **Jegadeesh, N. & Titman, S.** (1993, 2001). "Returns to Buying Winners and Selling Losers." — 动量策略与 Top Tercile 方法
|
||||
- **DeMiguel, V., Garlappi, L. & Uppal, R.** (2009). "Optimal Versus Naive Diversification." *Review of Financial Studies*. — 1/N 等权优于均值-方差优化
|
||||
- **Faber, M.** (2007). "A Quantitative Approach to Tactical Asset Allocation." *SSRN:962461*. — GTAA 风险因子覆盖设计
|
||||
- **Antonacci, G.** (2014). "Dual Momentum Investing." *SSRN:2042750*. — 跨资产动量分散化
|
||||
- **López de Prado, M.** (2016). "Building Diversified Portfolios that Outperform." *SSRN:2708678*. — HRP 层次聚类相关性优化
|
||||
247
docs/动态ETF池筛选引擎-调研与方案.md
Normal file
247
docs/动态ETF池筛选引擎-调研与方案.md
Normal file
@@ -0,0 +1,247 @@
|
||||
# 动态ETF池自动化筛选引擎 — 调研与方案
|
||||
|
||||
## 1. 问题背景
|
||||
|
||||
当前ETF轮动策略的标的池是人工预选的,存在严重的**幸存者偏差**。回测对比实验显示:
|
||||
|
||||
| 标的池 | 累计收益 | CAGR | 最大回撤 |
|
||||
|--------|---------|------|---------|
|
||||
| 9只精选ETF (全仓1只, 2015-2026) | 2733.60% | 34.38% | -32.79% |
|
||||
| 20只行业ETF (全仓1只, 2015-2026) | 208.16% | 10.46% | -67.16% |
|
||||
| 20只轮动ETF (等权5只, 2020-2026) | 171.36% | 17.48% | -30.85% |
|
||||
|
||||
**结论**: 标的池选择是策略最大的 alpha 来源,需要构建**系统化、无偏差**的动态筛选能力。
|
||||
|
||||
---
|
||||
|
||||
## 2. 学术论文与权威机构调研
|
||||
|
||||
### 2.1 TrendFolios (UCLA, 2024)
|
||||
|
||||
- **论文**: Lu et al. "TrendFolios: A Portfolio Construction Framework for Utilizing Momentum and Trend-Following In a Multi-Asset Portfolio"
|
||||
- **来源**: arxiv:2506.09330
|
||||
- **核心方法**:
|
||||
- 按资产类别的风险因子对ETF进行分类
|
||||
- Universe 随时间自然扩展 — 新ETF上市后才纳入,杜绝前视偏差
|
||||
- 结合趋势跟踪信号与动量因子构建多资产组合
|
||||
- **对本方案的启发**: Layer 3 资产标签化设计 + 滚动重建机制中的无前视偏差原则
|
||||
|
||||
### 2.2 AEGIS (2024)
|
||||
|
||||
- **论文**: Chakraborty & Singh. "Taming the Black Swan: A Momentum-Gated Hierarchical Optimisation Framework"
|
||||
- **来源**: arxiv:2604.09060
|
||||
- **核心方法**:
|
||||
- 流动性硬门槛: FALR (Fraction of Available Liquidity Ratio) >= 0.75
|
||||
- 每年根据动量领先者重建 universe
|
||||
- 分层优化框架: 先筛选 universe → 动量门控 → 层次化权重优化
|
||||
- **对本方案的启发**: Layer 1 流动性过滤的硬门槛设计 + 定期重建机制
|
||||
|
||||
### 2.3 HRP — Hierarchical Risk Parity (Lopez de Prado, 2016)
|
||||
|
||||
- **论文**: Lopez de Prado. "Building Diversified Portfolios that Outperform Out-of-Sample"
|
||||
- **来源**: SSRN:2708678
|
||||
- **核心方法**:
|
||||
- 基于收益率相关性矩阵进行层次聚类(Hierarchical Clustering)
|
||||
- 将资产分为互不相关的簇,同簇内取代表性资产
|
||||
- 相比传统均值-方差优化,HRP 在样本外表现更稳健,不依赖协方差矩阵求逆
|
||||
- **对本方案的启发**: Layer 5 相关性优化选择算法的理论基础
|
||||
|
||||
### 2.4 Faber GTAA — Global Tactical Asset Allocation (2006)
|
||||
|
||||
- **论文**: Faber. "A Quantitative Approach to Tactical Asset Allocation"
|
||||
- **来源**: SSRN:962461
|
||||
- **核心方法**:
|
||||
- 选择 5-13 个大类资产ETF,每个代表一个独立的经济驱动因子
|
||||
- 用 10 个月移动平均线作为趋势信号(价格 > MA10 则持有,否则转现金)
|
||||
- 关键洞察: **资产类别的覆盖度比选择数量更重要**
|
||||
- **对本方案的启发**: Universe 设计原则 — 确保风险因子全覆盖(股票、债券、商品、REITs、外汇)
|
||||
|
||||
### 2.5 Antonacci Dual Momentum (2012)
|
||||
|
||||
- **论文**: Antonacci. "Risk Premia Harvesting Through Dual Momentum"
|
||||
- **来源**: SSRN:2042750
|
||||
- **核心方法**:
|
||||
- **绝对动量** (时间序列动量): 资产自身是否处于上升趋势
|
||||
- **相对动量** (横截面动量): 资产间的相对强弱排序
|
||||
- 资产对(pairs)作为构建模块,每对代表一个风险溢价
|
||||
- 当绝对动量为负时,转入债券避险
|
||||
- **对本方案的启发**: 跨资产分散化设计理念 — 每个资产类别用"对"来覆盖
|
||||
|
||||
### 2.6 Jegadeesh & Titman (1993) — 动量效应经典文献
|
||||
|
||||
- **论文**: "Returns to Buying Winners and Selling Losers: Implications for Stock Market Efficiency"
|
||||
- **来源**: Journal of Finance, 48(1), 65-91
|
||||
- **核心发现**:
|
||||
- 买入过去 3-12 个月的赢家、卖出输家,可获得显著超额收益
|
||||
- 动量效应在不同市场、不同时期持续存在
|
||||
- 这是所有动量策略的学术基石
|
||||
|
||||
### 2.7 华宝基金动量优选基金 (业界实践)
|
||||
|
||||
- **来源**: 华宝基金动量优选混合型基金招募说明书
|
||||
- **实践方法**:
|
||||
- 年度 ETF 池调整(非固定池)
|
||||
- 行业、风格、主题多维度覆盖
|
||||
- 定量筛选 + 基金经理主观判断结合
|
||||
- **对本方案的启发**: 实业级重建周期参考(年度/季度)
|
||||
|
||||
---
|
||||
|
||||
## 3. 方案设计:多层漏斗筛选
|
||||
|
||||
### 3.1 架构概览
|
||||
|
||||
```
|
||||
全量ETF (~1000只)
|
||||
|
|
||||
v [Layer 1] 基础过滤 (流动性/类型/上市时间)
|
||||
约300只
|
||||
|
|
||||
v [Layer 2] 同指数去重 (每个指数只留1只最优ETF)
|
||||
约200只
|
||||
|
|
||||
v [Layer 3] 大类资产标签化 (自动分类)
|
||||
约200只 (含标签)
|
||||
|
|
||||
v [Layer 4] 类内预筛选 (每类留Top-N)
|
||||
约30-50只
|
||||
|
|
||||
v [Layer 5] 相关性优化选择 (贪心/HRP聚类)
|
||||
10-15只 最终池
|
||||
```
|
||||
|
||||
### 3.2 Layer 1 — 基础过滤(硬性门槛)
|
||||
|
||||
| 过滤条件 | 原因 |
|
||||
|---------|------|
|
||||
| 上市满1年 | 新基金数据不足,无法计算有效因子 |
|
||||
| 日均成交额 > 5000万 | 流动性不足会导致冲击成本过大 (参考AEGIS的FALR门槛) |
|
||||
| 非货币/非债券增强类 | 货币基金无轮动意义 |
|
||||
| 非杠杆/非反向ETF | 杠杆ETF不适合持有 |
|
||||
| 有明确跟踪指数 | 需要指数数据计算因子 |
|
||||
|
||||
### 3.3 Layer 2 — 同指数去重
|
||||
|
||||
一个指数可能有 20+ 只 ETF 跟踪(如沪深300有30+只),按 `index_code` 分组,每组选1只:
|
||||
|
||||
1. 优先选**日均成交额最大**的(流动性最好)
|
||||
2. 同等条件下选**管理费最低**的
|
||||
3. 同等条件下选**上市时间最早**的(历史数据最长)
|
||||
|
||||
### 3.4 Layer 3 — 大类资产标签化
|
||||
|
||||
根据指数名称和类别,自动打上资产大类标签(参考 Faber GTAA 的风险因子覆盖思想):
|
||||
|
||||
```python
|
||||
ASSET_CLASS_RULES = {
|
||||
'A股宽基': ['沪深300', '中证500', '中证1000', '创业板', '上证50', '科创50'],
|
||||
'A股行业': ['银行', '证券', '医疗', '白酒', '军工', '新能源', '芯片', '煤炭', ...],
|
||||
'A股主题': ['红利', '消费', '科技', '央企', '国企', ...],
|
||||
'港股': ['恒生', '港股', 'H股'],
|
||||
'美股': ['纳斯达克', '纳指', '标普', '美股'],
|
||||
'全球/其他': ['日经', '德国', '法国', '越南', '印度', 'MSCI'],
|
||||
'商品': ['黄金', '白银', '原油', '有色', '豆粕'],
|
||||
'债券': ['国债', '利率债', '信用债', '可转债'],
|
||||
}
|
||||
```
|
||||
|
||||
### 3.5 Layer 4 — 类内预筛选
|
||||
|
||||
每个大类保留最具代表性的 Top-N 只,避免单一类别占满池子:
|
||||
|
||||
| 大类 | 保留数量 | 选择依据 |
|
||||
|------|---------|---------|
|
||||
| A股宽基 | 3-5 | 按规模/流动性排序 |
|
||||
| A股行业 | 8-12 | 按行业分散度,每个细分行业最多1只 |
|
||||
| A股主题 | 3-5 | 按流动性 |
|
||||
| 港股 | 2-3 | 按流动性 |
|
||||
| 美股 | 2-3 | 按流动性 |
|
||||
| 全球/其他 | 2-3 | 按流动性 |
|
||||
| 商品 | 2-3 | 按流动性 |
|
||||
| 债券 | 2-3 | 按流动性 |
|
||||
|
||||
### 3.6 Layer 5 — 相关性优化选择(核心算法)
|
||||
|
||||
基于 HRP (Lopez de Prado) 的层次聚类思想,用贪心最大分散化算法从30-50只候选中选出最终10-15只:
|
||||
|
||||
```python
|
||||
def greedy_max_diversification(candidates, n_select, lookback_days=120):
|
||||
"""
|
||||
1. 计算所有候选的 lookback_days 日收益率相关系数矩阵
|
||||
2. 先选入每个大类中流动性最好的1只(确保类别覆盖)
|
||||
3. 剩余名额贪心填充:
|
||||
- 对每个未选候选,计算其与已选集合的最大相关系数
|
||||
- 选入 max_corr 最小的(即与已有持仓最不相关的)
|
||||
4. 重复直到选满 n_select 只
|
||||
"""
|
||||
```
|
||||
|
||||
**约束条件**:
|
||||
- 每个大类至少1只(确保资产类别覆盖)
|
||||
- 任意两只的相关系数不超过 0.85(强制分散)
|
||||
- A股行业类别不超过总数的 50%(避免A股过度集中)
|
||||
|
||||
---
|
||||
|
||||
## 4. 定期重建机制
|
||||
|
||||
- **重建周期**: 每季度(90个交易日)重建一次
|
||||
- **平滑切换**: 新旧池差异超过 30% 时才执行切换,避免频繁调整
|
||||
- **反前视偏差** (TrendFolios/AEGIS 强调): 重建时只用截止到重建日的历史数据,Universe 随时间自然扩展
|
||||
- **退市ETF处理**: 回测中需包含已退市ETF的历史数据,避免幸存者偏差
|
||||
|
||||
---
|
||||
|
||||
## 5. 实现规划
|
||||
|
||||
### 5.1 独立脚本 `scripts/build_etf_universe.py`
|
||||
|
||||
```python
|
||||
class ETFUniverseBuilder:
|
||||
def __init__(self, config):
|
||||
self.min_trading_days = 250 # 上市满1年
|
||||
self.min_daily_amount = 5000 # 日均成交额万元
|
||||
self.n_select = 12 # 最终池大小
|
||||
self.max_corr = 0.85 # 最大相关系数
|
||||
self.lookback_days = 120 # 相关性计算窗口
|
||||
|
||||
def run(self):
|
||||
raw = self.fetch_etf_universe() # Layer 0: 获取全量
|
||||
filtered = self.basic_filter(raw) # Layer 1: 基础过滤
|
||||
deduped = self.dedup_by_index(filtered) # Layer 2: 同指数去重
|
||||
labeled = self.label_asset_class(deduped) # Layer 3: 标签化
|
||||
shortlist = self.intra_class_select(labeled) # Layer 4: 类内筛选
|
||||
final = self.correlation_optimize(shortlist) # Layer 5: 相关性优化
|
||||
self.save_results(final)
|
||||
return final
|
||||
```
|
||||
|
||||
### 5.2 输出文件
|
||||
|
||||
- `data/etf_universe/universe_{date}.csv`: 最终筛选结果
|
||||
- `data/etf_universe/pipeline_log_{date}.txt`: 每层过滤日志
|
||||
- `data/etf_universe/corr_matrix_{date}.csv`: 相关性矩阵
|
||||
|
||||
### 5.3 集成到动量策略
|
||||
|
||||
修改 `动量.py`,支持从动态池加载:
|
||||
|
||||
```python
|
||||
CONFIG = {
|
||||
'etf_pool': 'auto', # 'auto' 表示使用动态池
|
||||
'rebuild_interval': 90, # 每90个交易日重建
|
||||
}
|
||||
```
|
||||
|
||||
回测时每隔90天调用一次 `ETFUniverseBuilder`,用截止到当前回测日期的数据重建池子,确保不使用未来数据。
|
||||
|
||||
---
|
||||
|
||||
## 6. 参考文献
|
||||
|
||||
1. Lu et al. (2024). "TrendFolios: A Portfolio Construction Framework for Utilizing Momentum and Trend-Following In a Multi-Asset Portfolio". *arxiv:2506.09330*
|
||||
2. Chakraborty & Singh (2024). "Taming the Black Swan: A Momentum-Gated Hierarchical Optimisation Framework". *arxiv:2604.09060*
|
||||
3. Lopez de Prado (2016). "Building Diversified Portfolios that Outperform Out-of-Sample" (HRP). *SSRN:2708678*
|
||||
4. Faber (2006). "A Quantitative Approach to Tactical Asset Allocation". *SSRN:962461*
|
||||
5. Antonacci (2012). "Risk Premia Harvesting Through Dual Momentum". *SSRN:2042750*
|
||||
6. Jegadeesh & Titman (1993). "Returns to Buying Winners and Selling Losers". *Journal of Finance, 48(1), 65-91*
|
||||
Reference in New Issue
Block a user