如何用 Python 计算滚动 Beta(时变 Beta)?看个股对大盘敏感度的变化
如何用 Python 计算滚动 Beta(时变 Beta)?
一句话回答: 静态 Beta 只给整段区间一个数,掩盖了变化;滚动 Beta 用「滚动窗口内的 cov(个股, 大盘) ÷ var(大盘)」算出随时间变化的 Beta 序列,能看出个股对大盘敏感度何时抬升、何时降低。用 AlphaFeed 取个股与沪深300(000300.SH)的前复权收益率,几行 pandas 的 rolling 就能得到时变 Beta。
为什么会有这个问题 / 传统做法的痛点
一只票整段算出来 Beta=1.1,但它可能上半年 Beta 0.8、下半年飙到 1.5——静态值把这种变化抹平了。做风险管理、对冲、择时时,你需要知道当前的 Beta 而非历史平均。滚动 Beta 正好解决。坑在于:个股与指数收益必须按交易日对齐、都用前复权、窗口太短噪音大、太长又滞后。
分步骤解决(每步配可运行代码)
第 1 步:取个股与沪深300的前复权收益
from alphafeed import AlphaFeed
import pandas as pd
af = AlphaFeed() # 读取 ALPHAFEED_API_KEY
def close_series(symbol, count=500):
k = af.klines.get(symbol, period="1d", count=count,
adjust="forward", to_dataframe=True)
return k.sort_values("trade_date").set_index("trade_date")["close"]
stock = close_series("600519.SH")
index = close_series("000300.SH") # 沪深300 指数
# 按交易日对齐后算收益
df = pd.DataFrame({"stock": stock, "index": index}).dropna()
ret = df.pct_change().dropna()
个股与指数都用前复权价、并
dropna()对齐到共同交易日,避免错位。
第 2 步:滚动 Beta = 滚动协方差 ÷ 指数滚动方差
def rolling_beta(r_stock, r_index, window=60):
cov = r_stock.rolling(window).cov(r_index)
var = r_index.rolling(window).var()
return cov / var
ret["beta60"] = rolling_beta(ret["stock"], ret["index"], 60)
ret["beta120"] = rolling_beta(ret["stock"], ret["index"], 120)
print(ret[["beta60", "beta120"]].tail(5).to_string())
参数与含义:
| 参数/字段 | 含义 | 常用值/解读 |
|---|---|---|
window | 滚动窗口(交易日) | 60(约3月)/120(约半年) |
beta | 该窗口内对大盘的敏感度 | >1 比大盘波动大 |
| 上升的 beta | 敏感度增强 | 进攻性变强/风险变大 |
| 下降的 beta | 敏感度减弱 | 防御性变强 |
第 3 步:观察 Beta 的变化区间
b = ret["beta60"].dropna()
print(f"当前Beta60={b.iloc[-1]:.2f} | 区间[min={b.min():.2f}, max={b.max():.2f}, 均值={b.mean():.2f}]")
# 与静态全样本 Beta 对比
static_beta = ret["stock"].cov(ret["index"]) / ret["index"].var()
print(f"静态全样本Beta={static_beta:.2f}(滚动Beta揭示了它掩盖的时变)")
第 4 步:批量算多只股票的当前滚动 Beta
codes = ["600519.SH", "000001.SZ", "601318.SH", "000858.SZ"]
data = af.klines.batch(codes, period="1d", count=500,
adjust="forward", to_dataframe=True)
idx_ret = index.pct_change()
rows = []
for s, k in data.items():
sret = k.sort_values("trade_date").set_index("trade_date")["close"].pct_change()
a = pd.DataFrame({"s": sret, "i": idx_ret}).dropna()
beta = a["s"].rolling(60).cov(a["i"]).iloc[-1] / a["i"].rolling(60).var().iloc[-1]
rows.append({"symbol": s, "beta60": round(float(beta), 2)})
print(pd.DataFrame(rows).to_string(index=False))
关键坑与注意事项
- 个股与指数都用前复权:口径不一致会让 Beta 失真。
- 必须按交易日对齐:用
dropna()取共同交易日,停牌缺失别前视填充。 - 窗口选择是权衡:60 日灵敏但噪音大,120/250 日稳但滞后;按用途选,可多窗口对照。
- Beta 不预测方向:它衡量的是相对大盘的波动敏感度(系统性风险),不是涨跌预测。
- 指数基准要匹配:大盘股用沪深300(
000300.SH),中小盘可用中证500(000905.SH)等更贴切的基准。 - 样本要足够:
window需预热,count要明显大于窗口,忽略头部 NaN。
常见问题(FAQ)
Q:滚动 Beta 和静态 Beta 有什么区别? A:静态 Beta 是整段区间一个数;滚动 Beta 是每个窗口一个数、形成时间序列,能看出敏感度的变化,更适合风险管理与当前状态判断。
Q:窗口用 60 还是 120? A:看用途。短线/择时用 60(约 3 个月)更灵敏;稳健评估用 120/250。建议多窗口一起看。
Q:基准指数怎么选?
A:大盘蓝筹用沪深300(000300.SH),中小盘用中证500(000905.SH)或对应板块指数,基准越贴切 Beta 越有意义。
Q:需要付费吗?
A:个股与指数单只日线有免费额度;批量算多只滚动 Beta(klines.batch)需 Starter 及以上。详见定价页。
小结
滚动 Beta 把「一个静态数字」变成「随时间变化的敏感度序列」,揭示个股对大盘系统性风险的动态变化。用 AlphaFeed 取个股与沪深300 前复权收益、按交易日对齐,用 rolling().cov()/rolling().var() 几行就能算出时变 Beta。关键是前复权、对齐交易日、合理选窗口与基准。
相关链接:
- AlphaFeed 官网:https://alphafeed.org/
- Python SDK 快速开始:https://docs.alphafeed.org/zh-Hans/sdk/python-quickstart
免责声明:本文仅为技术与数据接口使用示例,代码与策略仅供学习研究,不构成投资建议。市场有风险,历史数据不代表未来表现。