全市场 ETF 动量分析脚本
最近在 AI 的帮助下,写了一个全市场 ETF 动量分析脚本。其实这个脚本很早就已经写好了,但最近比较忙,一直没时间整理发推文。
在 ETF 轮动策略中,常见的做法是使用固定的 ETF 候选池。但这种方式存在一个明显的问题:行情是不断变化的,固定的候选池很难覆盖不同时段的市场机会。
动态ETF候选池
如果从长周期来看,固定候选池确实可以抓住大趋势。但另一方面,我们能不能做一个“动态 ETF 候选池”? 从理论上讲,动态候选池应该更有机会捕捉阶段性行情。
手动分析全市场ETF来构建动态ETF候选池,几乎不太可能:
- 全市场 ETF 数量很多,手动筛选不太现实
- 只看涨幅,容易选到短期冲高、溢价过高、或者流动性差的品种
- 多只看起来都很强的 ETF,可能高度相关,最终组合并没有真正分散
所以,我们需要一个自动化工具,来帮助我们在某个交易日快速完成全市场 ETF 的分析和筛选。

构建动态候选池的思路
该自动化分析工具的大致思路是:从全市场 ETF 出发,做动量分析,并筛选出动量分散、相关性较低的一组 ETF。
以下是基于Tushare数据来实现这个思路的主要步骤:
1. 获取历史某日的全市场 ETF 列表
使用 Tushare 的 fund_basic() 接口获取 ETF 列表:
pro.fund_basic(market="E")
然后筛选出满足以下条件的基金:
list_date <= trading_date- 尚未退市(
delist_date为空或 ≥trading_date) - 名称中包含 ETF 或 LOF (如果不喜欢LOF,也可以把LOF去掉)
2. 获取 ETF 行情数据
使用 fund_daily() 接口获取行情数据,包括:open, high, low, close, pre_close, vol, amount 等字段。
虽然接口本身不支持复权,但返回的数据提供了 pre_close字段,因此我们可以自行实现前复权或后复权逻辑。
3. 动量打分计算
这里采用的是对数价格的线性回归方法来计算动量:
最终得分定义为:
score = annualized_returns × r_squared
核心代码如下:
y = np.log(prices)
x = np.arange(len(y), dtype=float)
# 等权线形回归
slope, intercept = np.polyfit(x, y, 1)
annualized_returns = math.pow(math.exp(slope), 250) - 1
r_squared = 1 - (sum((y - (slope * x + intercept))**2) / ((len(y) - 1) * np.var(y, ddof=1)))
score = annualized_returns * r_squared
这种方式可以同时考虑:
- 收益强度
- 趋势稳定性
相比单纯涨幅,更稳健。
当然也可以用其他的一些动量指标,比如非等权平均、动态回溯窗口进行回归等。
4. 相关性控制(核心步骤)
全市场 ETF 中,很多高动量标的其实属于同一类资产(例如同一行业或同一指数),如果不做处理,最终选出来的组合可能高度集中。
因此,我们可以通过相关性分析来进行筛选。筛选逻辑如下:
- 按动量得分从高到低排序
- 第一只 ETF 直接入选
- 后续 ETF 需满足:与已选 ETF 的相关性均低于阈值
- 若与任意已选 ETF 相关性过高,则跳过
- 直到选到特定数量的ETF
这本质上是在做一个“去相关”的动量组合构建。

5. 热力图功能
为了直观地感受最终筛选的ETF的动量变化,我新增了热力图功能,用于可视化最终入选 ETF 的历史动量得分变化。
这样,我们就可以很直观地看到:
- 哪些 ETF 是持续强势
- 哪些只是阶段性爆发

6. 相关性可视化
另外我单独写了一个相关性分析脚本,用于分析给定 ETF 列表中,两两之间的相关性。以帮助更细致地理解:
- 组合内部是否真正分散
- 是否存在“看起来不同,本质一样”的 ETF

7. 其他细节处理
在实际实现中,还做了一些比较重要的过滤和风控处理:
- 剔除低波动 ETF(如债券、货币、固收类)
- 剔除流动性较差的 ETF(基于近期成交额均值)
- 风控过滤:
- 剔除近期出现大跌的 ETF
- 对溢价过高的 ETF 进行惩罚
8. 后记
整体来看,这个脚本的核心目标是:
从“全市场”中,自动构建一个“高动量 + 低相关 + 可交易”的 ETF 组合候选池
相比传统固定池策略,更加灵活,也更贴近真实市场结构。
不过,其具体效果如何,还是得测试测试才知道,目前完全靠这个来实现整套ETF轮动策略的自动化还是不太安全,更多的是进行辅助分析,最终还是需要人来分析把关。
浙公网安备 33010602011771号