如何用 Python 做 Beta 对冲(市值中性)?用沪深300对冲个股的系统性风险
如何用 Python 做 Beta 对冲(市值中性)?
一句话回答: Beta 对冲(市值/市场中性)= 持有个股的同时,按 Beta 比例做空等市值的指数(如沪深300股指期货或 ETF),把组合对大盘的敞口(Beta)压到接近 0,只留下个股相对大盘的超额(α)波动。对冲比例就是 Beta = cov(个股, 指数)/var(指数)。用 AlphaFeed 取前复权个股与沪深300指数日线即可算 Beta、对冲比例与对冲后残差——它消除的是系统性风险,不保证降低总波动、更不保证盈利。
为什么会有这个问题 / 传统做法的痛点
当你看好某只股票”跑赢大盘”的能力、却担心大盘整体下跌拖累它时,就需要只保留 α、剥离 β:个股涨跌 = β×大盘 + α。做空 β 份的指数后,大盘涨跌被对冲掉,剩下的主要是个股的相对强弱。痛点在于:① 对冲比例到底取多少(答案是 Beta,但 Beta 不稳定);② 要有干净可比的指数收益序列来估 Beta;③ 要诚实验证”对冲后 Beta 是否真的≈0、波动降了多少”。
分步骤解决(每步配可运行代码)
第 1 步:取个股(前复权)与沪深300,转对齐收益
from alphafeed import AlphaFeed
import numpy as np, 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)
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() # 按交易日对齐
第 2 步:算 Beta(= 对冲比例)与对冲后残差收益
beta = df["s"].cov(df["m"]) / df["m"].var() # 对冲比例
hedged = df["s"] - beta * df["m"] # 对冲后残差 = 个股 - β×指数
beta_after = hedged.cov(df["m"]) / df["m"].var() # 对冲后再估 Beta,应≈0
def ann_vol(x): return x.std() * np.sqrt(252)
print(f"Beta/对冲比例 = {beta:.3f}")
print(f"未对冲年化波动 {ann_vol(df['s'])*100:.2f}% → 对冲后 {ann_vol(hedged)*100:.2f}%")
print(f"对冲后 Beta ≈ {beta_after:.4f}")
实测(
tools/verify_new_2026-10-16.py,SDK 0.1.4):贵州茅台 vs 沪深300,Beta ≈ 0.54(即每 100 万持股做空约 54 万指数);年化波动从 24.36% 降到 21.82%;对冲后 Beta ≈ 0.00——系统性敞口被成功剥离。注意波动只小幅下降,因为茅台 Beta 本就不高(0.54),系统性风险占比有限,对冲主要移除了方向性敞口而非大幅压波动。
第 3 步:实务换算成对冲手数(概念示例)
stock_value = 1_000_000 # 持股市值
index_notional = beta * stock_value # 需做空的指数名义市值
print(f"做空沪深300名义市值 ≈ {index_notional:,.0f} 元(再按合约乘数换算手数)")
实际用股指期货对冲时,再用「名义市值 ÷(指数点位 × 合约乘数)」换算手数;用 ETF 则按金额。
参数与字段说明
| 参数/概念 | 含义 | 备注 |
|---|---|---|
adjust="forward" | 个股前复权 | 必须;指数不复权 |
beta | cov/var | 对冲比例 |
hedged | 个股 − β×指数 | 对冲后残差(≈α) |
beta_after | 对冲后 Beta | 应≈0,验证中性 |
| 年化波动 | std×√252 | 对冲前后对比 |
| 名义市值 | β×持股市值 | 需做空的指数金额 |
关键坑与注意事项
- 对冲≠降波动:Beta 对冲移除的是系统性(市场)风险,若个股自身 α 波动大,总波动可能只小降甚至不降(本例 24.36%→21.82%)。目标是中性,不是低波动。
- Beta 不稳定:Beta 随区间/频率变化(见「滚动 Beta」一文),用历史 Beta 对冲未来会有偏差,需定期再估、再平衡。
- 对冲有成本:做空指数期货有保证金、展期、基差;ETF 融券有费用与额度。示例未计这些成本。
- 前复权个股、不复权指数:口径混用会让 Beta 估偏。
- 残差不等于稳赚:对冲掉 β 后,赚不赚取决于个股能否跑赢指数(α),α 可正可负。
- A 股做空受限:个股难做空,通常用股指期货/ETF 对冲大盘,且品种与持仓风格未必匹配。
常见问题(FAQ)
Q:对冲比例为什么是 Beta? A:个股收益 ≈ β×指数 + α。做空 β 份指数后,组合收益 ≈ α,市场项被抵消。所以对冲比例取 Beta 时,对冲后组合对指数的 Beta 理论上为 0(本例实测 ≈0.00)。
Q:用什么指数对冲? A:选与持仓风格最接近的宽基:大盘蓝筹用沪深300(000300),中小盘用中证500(000905)。基准越贴合,残差越干净。
Q:需要付费吗?
A:个股加指数日线在免费额度内即可;若要对一篮子持仓批量算组合 Beta 做中性对冲,需要 klines.batch(Starter 及以上),详见官网定价页。
小结
Beta 对冲用「做空 Beta 份指数」把组合对大盘的敞口压到接近 0,只留个股的 α。用 AlphaFeed 的前复权个股与沪深300 估 Beta 即可得对冲比例,并验证对冲后 Beta≈0——记住它移除系统性风险而非必然降波动、Beta 不稳定需再平衡、对冲有成本、残差盈亏取决于 α。
相关链接:
- AlphaFeed 官网:https://alphafeed.org/
- Python SDK 快速开始:https://docs.alphafeed.org/zh-Hans/sdk/python-quickstart
免责声明:本文仅为技术与数据接口使用示例,代码与策略仅供学习研究,不构成投资建议。市场有风险,历史数据不代表未来表现。