# ETF跟踪误差计算方法 **文档版本**: v1.0 **创建日期**: 2026-06-19 **适用范围**: 轮动策略标的池ETF跟踪准确率评估 --- ## 一、定义 **跟踪误差(Tracking Error, TE)**:衡量ETF净值收益率与标的指数收益率之间偏离程度的指标,反映基金经理的追踪能力。 **核心公式**: ``` 跟踪误差(TE) = STDEV(每日跟踪偏离度) × √252 ``` --- ## 二、计算步骤 ### 2.1 数据准备 | 数据类型 | 字段 | 来源 | 说明 | |---------|------|------|------| | ETF单位净值 | `unit_nav` | Tushare `fund_nav` | 必须用单位净值,不能用累计净值 | | 基准收盘价 | `close` | Tushare `index_daily` / `fut_daily` / Flask API | 根据标的类型选择数据源 | ### 2.2 计算流程 ``` 步骤1: 获取ETF单位净值序列 NAV[t], NAV[t-1], NAV[t-2], ... 步骤2: 获取基准收盘价序列 Index[t], Index[t-1], Index[t-2], ... 步骤3: 计算ETF日收益率 ETF_ret[t] = (NAV[t] - NAV[t-1]) / NAV[t-1] 步骤4: 计算基准日收益率 Index_ret[t] = (Index[t] - Index[t-1]) / Index[t-1] 步骤5: 计算每日跟踪偏离度 Deviation[t] = ETF_ret[t] - Index_ret[t] 步骤6: 计算偏离度标准差 Std = STDEV(Deviation序列) 步骤7: 年化处理 TE = Std × √252 ``` ### 2.3 Python代码示例 ```python import numpy as np import pandas as pd def calculate_tracking_error(etf_nav: pd.Series, benchmark_close: pd.Series) -> dict: """ 计算ETF跟踪误差 Args: etf_nav: ETF单位净值序列(index=date, value=unit_nav) benchmark_close: 基准收盘价序列(index=date, value=close) Returns: dict: 包含跟踪误差、R²、相关系数等指标 """ # 计算收益率 etf_ret = etf_nav.pct_change().dropna() bench_ret = benchmark_close.pct_change().dropna() # 对齐日期 common = etf_ret.index.intersection(bench_ret.index) if len(common) < 20: return None e = etf_ret.loc[common] b = bench_ret.loc[common] # 每日偏离度 daily_deviation = e - b # 跟踪误差 = 标准差 × √252 tracking_error = daily_deviation.std() * np.sqrt(252) # 其他指标 correlation = e.corr(b) r_squared = correlation ** 2 # 累计收益 etf_cum = (1 + e).prod() - 1 bench_cum = (1 + b).prod() - 1 excess = etf_cum - bench_cum return { 'annual_tracking_error': round(tracking_error * 100, 4), # % 'correlation': round(correlation, 6), 'r_squared': round(r_squared, 6), 'etf_cum_return': round(etf_cum * 100, 2), # % 'benchmark_cum_return': round(bench_cum * 100, 2), # % 'excess_return': round(excess * 100, 2), # % 'common_days': len(common), } ``` --- ## 三、基准数据来源 ### 3.1 数据源选择 | 标的类型 | 示例 | 基准来源 | Tushare接口 | 数据可用性 | |---------|------|---------|------------|-----------| | A股指数 | 创业板指、红利低波 | 指数收盘价 | `index_daily` | ✅ 完整 | | 商品期货 | 黄金、有色金属 | 期货主力合约 | `fut_daily` | ✅ 完整 | | 海外指数 | 纳指、恒生、日经、DAX | 指数收盘价 | Flask API (yfinance) | ✅ 完整 | ### 3.2 接口调用示例 ```python # A股指数 index_data = pro.index_daily( ts_code='399006.SZ', start_date='20250601', end_date='20260619' ) # 商品期货 futures_data = pro.fut_daily( ts_code='AU.SHF', start_date='20250601', end_date='20260619' ) # 海外指数(通过Flask API) from datasource.flask_api_source import FlaskAPIDataSource flask_source = FlaskAPIDataSource() index_data = flask_source.fetch('^NDX', '2025-06-01', '2026-06-19') ``` --- ## 四、关键注意事项 ### 4.1 必须使用单位净值(unit_nav) | 净值类型 | 含义 | 是否可用 | |---------|------|---------| | **单位净值** (unit_nav) | 当前每份基金的实际价值 | ✅ **必须用这个** | | 累计净值 (accum_nav) | 单位净值 + 历史分红 | ❌ 会虚高规模 | **原因**:累计净值包含了历史分红再投资,会导致规模计算偏大。 ### 4.2 必须使用标的指数做基准 | 基准类型 | 计算结果 | 说明 | |---------|---------|------| | **标的指数** | 真实跟踪误差 | ✅ 反映基金经理追踪能力 | | 另一只ETF价格 | 价格一致性 | ❌ 包含溢价率波动噪声 | ### 4.3 年化因子 - 使用 **√252**(假设一年252个交易日) - 如果使用月度数据,则用 **√12** - 如果使用周度数据,则用 **√52** --- ## 五、校验结果 ### 5.1 与天天基金数据对比 我们用 Tushare 计算的创业板指 ETF 跟踪误差 vs 天天基金官方数据: | ETF代码 | Tushare TE | 天天基金 TE | 差异 | |--------|-----------|------------|------| | 159948.SZ | 0.3302% | 0.32% | +0.0102% | | 159952.SZ | 0.3559% | 0.35% | +0.0059% | | 159205.SZ | 0.3698% | 0.36% | +0.0098% | | 159977.SZ | 0.3727% | 0.36% | +0.0127% | **平均差异:+0.0091%** → 高度一致 ### 5.2 结论 - Tushare 数据计算的跟踪误差与天天基金官方数据**高度一致** - 验证了计算方法的正确性 - 可用于日常跟踪误差监控 --- ## 六、完整计算脚本 参考文件:`rotation/tracking_error_full.py` ### 6.1 主要功能 - 覆盖轮动策略标的池全部10个标的 - 自动选择合适的数据源(Tushare指数/期货/Flask API) - 批量获取ETF净值数据 - 计算跟踪误差并排序 - 与天天基金数据对比校验 ### 6.2 运行方式 ```bash cd /Users/aszer/code/etf python3 rotation/tracking_error_full.py ``` ### 6.3 输出结果 - JSON文件:`rotation/results/tracking_error_full.json` - 包含每个标的下所有ETF的跟踪误差、R²、超额收益等指标 --- ## 七、相关文档 - [ETF竞品分析报告](./etf_competitor_analysis_report.md) - [跟踪误差校验报告](./tracking_error_validation_report.md) - [ETF数据源说明](../datasource/README.md) --- ## 八、更新日志 | 版本 | 日期 | 变更内容 | |------|------|---------| | v1.0 | 2026-06-19 | 初始版本,包含完整计算方法和校验结果 |