如何用 Python 计算上行/下行捕获率?看一只股票是「涨跟得上、跌扛得住」还是反过来
如何用 Python 计算上行/下行捕获率?
一句话回答: 上行捕获率 = 大盘上涨的日子里「个股平均收益 ÷ 大盘平均收益」,下行捕获率 = 大盘下跌的日子里「个股平均收益 ÷ 大盘平均收益」。理想标的是上行捕获率高(涨跟得上)、下行捕获率低(跌扛得住)。用 AlphaFeed 取个股与沪深300(000300.SH)的前复权日线,按涨跌把交易日分两组各算一次比值即可——这是比单一 Beta 更细、能分辨「攻」与「守」的攻防性指标。
为什么会有这个问题 / 传统做法的痛点
Beta 只给一个数(整体对大盘的敏感度),分不清「涨的时候跟得紧、跌的时候更抗跌」还是相反。但对选股来说,这个区别至关重要:
- 进攻型:上行捕获 > 100%、下行捕获也高——牛市猛,熊市也猛跌。
- 防守型:上行捕获低、下行捕获更低——涨得慢但跌得更少。
- 最差:上行捕获低、下行捕获高——涨跟不上、跌还更惨。
捕获率把 Beta 拆成「涨时弹性」和「跌时弹性」两半,一眼看清攻防属性。
分步骤解决(每步配可运行代码)
第 1 步:取个股与基准,对齐交易日算日收益
from alphafeed import AlphaFeed
import pandas as pd
af = AlphaFeed(api_key="your-api-key") # 或 export ALPHAFEED_API_KEY 后 AlphaFeed()
stock = af.klines.get("600519.SH", period="1d", count=500,
adjust="forward", to_dataframe=True)
bench = af.klines.get("000300.SH", period="1d", count=500, to_dataframe=True)
s = stock.sort_values("trade_date").set_index("trade_date")["close"].pct_change()
b = bench.sort_values("trade_date").set_index("trade_date")["close"].pct_change()
pair = pd.concat([s, b], axis=1, keys=["s", "b"]).dropna() # 按交易日对齐
个股前复权,指数不除权;dropna() 剔除停牌错位。
第 2 步:按大盘涨/跌分组,各算捕获率
up = pair[pair["b"] > 0] # 大盘上涨日
down = pair[pair["b"] < 0] # 大盘下跌日
up_cap = up["s"].mean() / up["b"].mean() # 上行捕获率
down_cap = down["s"].mean() / down["b"].mean() # 下行捕获率
print("上行捕获率 =", round(up_cap, 3))
print("下行捕获率 =", round(down_cap, 3))
实测(
tools/verify_new_2026-10-06.py,SDK 0.1.4):贵州茅台 vs 沪深300、近 499 个交易日(上涨 268 日、下跌 231 日):上行捕获率 = 0.374、下行捕获率 = 0.425。两者都 < 1 说明茅台这段波动小于沪深300;但下行捕获(0.425) > 上行捕获(0.374),意味着「大盘跌时它跟跌的比例,反而比大盘涨时跟涨的比例更高」——这段时间偏弱(攻不足、守也不占优)。
第 3 步:用「捕获价差」一眼判好坏
spread = up_cap - down_cap # >0 攻守俱佳;<0 涨跟不上/跌更惨
print("捕获价差(上-下) =", round(spread, 3))
实测茅台捕获价差 = −0.051(略负),印证上面的判断。正值越大越理想。
参数与字段说明
| 参数/概念 | 含义 | 备注 |
|---|---|---|
adjust="forward" | 个股前复权 | 必须;指数无需复权 |
| 基准 | 000300.SH | 可换中证500/上证指数 |
| 上行捕获率 | 大盘涨日 个股/大盘平均收益 | 越高越能跟涨 |
| 下行捕获率 | 大盘跌日 个股/大盘平均收益 | 越低越抗跌 |
| 捕获价差 | 上行−下行 | >0 攻守俱佳 |
关键坑与注意事项
- 必须对齐交易日:个股停牌、指数照常,不对齐捕获率全错。本文用
concat(...).dropna()。 - 基准要选对:大盘股比沪深300、中小盘比中证500/1000,否则捕获率无意义。
- 本文用算术平均简化:严格的晨星口径用「几何年化收益比」。算术平均口径趋势一致、更直观,但数值与晨星不完全一致,比较时统一口径即可。
- 样本区间敏感:牛熊混合区间更有代表性,单边行情会失真。
- 前复权:务必
adjust="forward"。 - 历史不代表未来:攻防属性会随基本面与风格切换改变。
常见问题(FAQ)
Q:捕获率和 Beta 什么关系? A:Beta 是「整体」敏感度(一个数),捕获率把它拆成「涨时」和「跌时」两个数,能分辨攻守。两者互补。
Q:上行捕获率一定要 > 100% 吗? A:不一定。防守型标的上行 < 100% 但下行更低,照样是好的「守」。关键看捕获价差(上−下)和你的攻守需求。
Q:需要付费吗?
A:个股 + 指数日线在免费额度内即可;若要对一篮子股票批量算捕获率做攻守排名,需要 klines.batch + universes(Starter 及以上),详见官网定价页。
小结
上行/下行捕获率把 Beta 拆成「涨时弹性」和「跌时弹性」,用捕获价差(上−下)一眼判断攻守属性。有了 AlphaFeed 的个股前复权 + 沪深300 数据,对齐交易日后分两组各算一次比值即可——记住对齐停牌日、选对基准、统一口径。
相关链接:
- AlphaFeed 官网:https://alphafeed.org/
- Python SDK 快速开始:https://docs.alphafeed.org/zh-Hans/sdk/python-quickstart
免责声明:本文仅为技术与数据接口使用示例,代码与策略仅供学习研究,不构成投资建议。市场有风险,历史数据不代表未来表现。