AlphaFeed Blog

如何用 Python 计算滚动夏普比率?(看风险调整收益随时间的变化)

分析与指标 · 代码验证于 2026-10-03

如何用 Python 计算滚动夏普比率?

一句话回答: 全样本只给一个夏普值,掩盖了「近期是不是变差了」。滚动夏普用滚动窗口内的「平均收益 ÷ 收益标准差 × √252」算出随时间变化的夏普序列,能看出风险调整后收益何时走强、何时恶化。用 AlphaFeed 取回前复权日线算日收益,几行 pandas 的 rolling 就能得到。

为什么会有这个问题 / 传统做法的痛点

一只票/一个策略整段算出夏普=1.2,但它可能前两年很好、近半年很差——静态值把这掩盖了。做风控、决定是否继续持有/运行策略,你需要知道当前阶段的风险调整收益。滚动夏普正好把它画成时间序列。坑在于:用前复权收益、统一年化口径(日频 ×√252)、窗口别太短(否则噪音大)。

分步骤解决(每步配可运行代码)

第 1 步:取前复权日线算日收益

from alphafeed import AlphaFeed
import numpy as np
import pandas as pd

af = AlphaFeed()  # 读取 ALPHAFEED_API_KEY

df = af.klines.get("600519.SH", period="1d", count=750,
                   adjust="forward", to_dataframe=True)
df = df.sort_values("trade_date").reset_index(drop=True)
ret = df["close"].pct_change()
ret.index = pd.to_datetime(df["trade_date"])

第 2 步:计算滚动夏普

TRADING_DAYS = 252
RF_DAILY = 0.0   # 简化:无风险利率按 0

def rolling_sharpe(ret, window=120, rf=0.0):
    excess = ret - rf
    mean = excess.rolling(window).mean()
    std = excess.rolling(window).std(ddof=1)
    return np.sqrt(TRADING_DAYS) * mean / std

df_rs = pd.DataFrame({
    "sharpe_60": rolling_sharpe(ret, 60),
    "sharpe_120": rolling_sharpe(ret, 120),
})
print(df_rs.tail(5).to_string())

参数与含义:

参数/字段含义常用值
window滚动窗口(交易日)60(约3月)/120(约半年)
rf无风险日利率简化为 0
√252日频年化因子A 股约 252 交易日/年
滚动夏普 ↑风险调整收益转好—

第 3 步:对比滚动夏普与静态夏普

cur = df_rs["sharpe_120"].dropna()
static = np.sqrt(TRADING_DAYS) * ret.mean() / ret.std(ddof=1)
print(f"当前滚动夏普(120)={cur.iloc[-1]:.2f}")
print(f"区间[min={cur.min():.2f}, max={cur.max():.2f}, 均值={cur.mean():.2f}]")
print(f"静态全样本夏普={static:.2f}(滚动揭示了它掩盖的时变)")

第 4 步:批量算多只的当前滚动夏普

codes = ["600519.SH", "000001.SZ", "601318.SH", "000858.SZ"]
data = af.klines.batch(codes, period="1d", count=400,
                       adjust="forward", to_dataframe=True)
rows = []
for s, k in data.items():
    r = k.sort_values("trade_date")["close"].pct_change()
    rs = rolling_sharpe(r, 120)
    rows.append({"symbol": s, "sharpe_120_now": round(float(rs.dropna().iloc[-1]), 2)})
print(pd.DataFrame(rows).to_string(index=False))

关键坑与注意事项

常见问题(FAQ)

Q:滚动夏普和静态夏普差别大吗? A:常常很大。静态值是整段平均,滚动值能暴露「近期恶化」或「某段特别好」,对风控和是否继续持有更有参考意义。

Q:窗口用 60 还是 120? A:短线/预警用 60,稳健评估用 120/250。建议至少看两个窗口,别只信一个。

Q:为什么要 √252? A:把日频夏普年化。日收益的均值和标准差都按 √T 规则年化,A 股一年约 252 个交易日。

Q:需要付费吗? A:单只历史日线有免费额度;批量算多只滚动夏普(klines.batch)需 Starter 及以上。详见定价页。

小结

滚动夏普把「一个静态夏普数字」变成「随时间变化的风险调整收益曲线」,能看清近期是变好还是变差。用 AlphaFeed 取前复权日收益,rolling().mean()/rolling().std()*√252 几行即可。关键是前复权、统一年化口径、合理选窗口,并结合索提诺等指标综合判断。

相关链接:


免责声明:本文仅为技术与数据接口使用示例,代码与策略仅供学习研究,不构成投资建议。市场有风险,历史数据不代表未来表现。