如何用 Python 计算滚动相关系数?看个股与大盘的相关性如何随时间变化
如何用 Python 计算滚动相关系数(看相关性随时间变化)?
一句话回答: 滚动相关系数 = 在一个移动窗口(如 60 日)内不断重算两组收益率的相关系数,得到一条随时间变化的曲线,专门揭示「相关性并不恒定」——某段时间个股与大盘同涨同跌、另一段却背道而驰。用 AlphaFeed 取前复权个股与沪深300指数日线,rolling(60).corr() 一行即可,比只报一个静态相关系数诚实得多。
为什么会有这个问题 / 传统做法的痛点
很多人算完一个「整段相关系数 0.45」就下结论,但这个单一数字把时变性完全抹平了:实际可能前半段 0.8(高度同步)、后半段 −0.3(反向)。做分散化、对冲、配对交易时,依赖一个静态相关系数会严重误判风险。痛点在于:要正确对齐两条收益序列(交易日不一定完全重合)、选好窗口,再滚动计算。
分步骤解决(每步配可运行代码)
第 1 步:取个股(前复权)与沪深300指数,转收益并对齐
from alphafeed import AlphaFeed
import pandas as pd
af = AlphaFeed(api_key="your-api-key") # 或 export ALPHAFEED_API_KEY 后 AlphaFeed()
s = af.klines.get("600519.SH", period="1d", count=500,
adjust="forward", to_dataframe=True) # 个股:前复权
m = af.klines.get("000300.SH", period="1d", count=500,
to_dataframe=True) # 大盘:沪深300
s = s.sort_values("trade_date"); m = m.sort_values("trade_date")
sr = s.set_index("trade_date")["close"].pct_change()
mr = m.set_index("trade_date")["close"].pct_change()
df = pd.concat([sr, mr], axis=1, keys=["s", "m"]).dropna() # 按交易日对齐,去缺失
concat + dropna 确保两条收益序列按共同交易日对齐,避免错位。
第 2 步:滚动相关系数(窗口 60 日)
roll_corr = df["s"].rolling(60).corr(df["m"]).dropna()
print("最新 60 日相关:", round(roll_corr.iloc[-1], 3))
print("区间范围:", round(roll_corr.min(), 3), "~", round(roll_corr.max(), 3))
print("静态(整段)相关:", round(df["s"].corr(df["m"]), 3))
实测(
tools/verify_new_2026-10-12.py,SDK 0.1.4):贵州茅台 vs 沪深300,60 日滚动相关最新 ≈ −0.271,区间 −0.333 ~ 0.853;而静态整段相关仅 0.45。静态数字把「从 +0.85 高度同步到 −0.33 反向」的剧烈变化完全掩盖了——这正是滚动相关的价值。
第 3 步:解读与应用
print("当前是否低相关(<0.3):", bool(roll_corr.iloc[-1] < 0.3))
相关性低甚至为负时,该股对大盘的分散/对冲价值上升;相关性飙高时,“分散”可能名存实亡(齐涨齐跌)。
参数与字段说明
| 参数/概念 | 含义 | 备注 |
|---|---|---|
adjust="forward" | 个股前复权 | 必须;指数不除权 |
pct_change() | 日收益 | 对收益算相关,不是对价格 |
concat + dropna | 按交易日对齐 | 去除停牌/缺失日 |
rolling(60) | 滚动窗口 | 窗口越短越灵敏、越长越稳 |
.corr(other) | 皮尔逊相关 | 两序列的线性相关 |
| 静态相关 | 整段一个数 | 对比用,会掩盖时变 |
关键坑与注意事项
- 对收益算,不是对价格:两条带趋势的价格序列相关系数会虚高(伪相关),必须先
pct_change()。 - 窗口是权衡:窗口太短,相关系数噪声大、剧烈跳动;太长则平滑掉有用变化。60 日是常用折中,应结合用途调整。
- 相关 ≠ 因果,也 ≠ Beta:相关系数只衡量同向程度(−1~1),不含弹性大小;弹性请看 Beta(本仓库有「滚动 Beta」一文)。
- 前复权必须:个股除权缺口会制造异常收益,扭曲相关。
- 短窗口末端不稳:窗口刚够长时头部会是 NaN,末端少数极端日也会显著影响当期值。
- 历史不代表未来:滚动相关揭示过去的变化,不保证未来延续。
常见问题(FAQ)
Q:滚动相关和滚动 Beta 有什么区别? A:相关系数衡量「同向不同向」,范围 −1~1,无量纲;Beta 衡量「大盘动 1%,个股动几 %」,含弹性大小。两者相关但不同:Beta = 相关系数 ×(个股波动/大盘波动)。
Q:为什么要用沪深300而不是上证指数? A:沪深300覆盖沪深两市大盘蓝筹,常作为 A 股「市场组合」代理;也可换 000905.SH(中证500)等更贴合标的风格的基准。
Q:需要付费吗?
A:个股加指数日线在免费额度内即可;若要对多只股票批量算与大盘的滚动相关做排序/配对,需要 klines.batch(Starter 及以上),详见官网定价页。
小结
滚动相关系数用移动窗口把「相关性随时间变化」显式画出来,避免被一个静态数字误导。用 AlphaFeed 的前复权个股与沪深300,对齐收益后 rolling(60).corr() 一行即可——记住对收益算、窗口是权衡、相关不等于 Beta,且过去的相关不保证未来延续。
相关链接:
- AlphaFeed 官网:https://alphafeed.org/
- Python SDK 快速开始:https://docs.alphafeed.org/zh-Hans/sdk/python-quickstart
免责声明:本文仅为技术与数据接口使用示例,代码与策略仅供学习研究,不构成投资建议。市场有风险,历史数据不代表未来表现。