首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >如何用 Python 计算股票的收益率、波动率和最大回撤?

如何用 Python 计算股票的收益率、波动率和最大回撤?

原创
作者头像
用户7083614
修改2026-09-05 18:28:41
修改2026-09-05 18:28:41
300
举报

一句话回答: 拿到一段前复权日 K 线的收盘价序列后,用 pandas 就能算出日收益率,进而得到年化收益率、年化波动率、夏普比率和最大回撤这四个最核心的风险收益指标。下面给出可直接运行的完整代码。

准备数据

风险指标依赖复权后的收盘价(否则分红送股会污染收益率),所以取数时用默认的前复权:

代码语言:python
复制
from alphafeed import AlphaFeed

af = AlphaFeed(api_key="your-api-key")

# 取近 250 个交易日(约 1 年)的前复权日 K 线
df = af.klines.get("600519.SH", period="1d", count=250, adjust="forward", to_dataframe=True)
df = df.sort_values("trade_date").reset_index(drop=True)

1. 日收益率与累计收益

代码语言:python
复制
df["ret"] = df["close"].pct_change()

total_return = df["close"].iloc[-1] / df["close"].iloc[0] - 1
print(f"区间累计收益: {total_return:.2%}")

2. 年化收益率

A 股一年约 250 个交易日。用几何年化:

代码语言:python
复制
n = len(df) - 1                     # 收益率个数
ann_return = (1 + total_return) ** (250 / n) - 1
print(f"年化收益率: {ann_return:.2%}")

3. 年化波动率

日收益率标准差 × √250:

代码语言:python
复制
import numpy as np

daily_vol = df["ret"].std()
ann_vol = daily_vol * np.sqrt(250)
print(f"年化波动率: {ann_vol:.2%}")

4. 夏普比率

(年化收益 − 无风险利率) / 年化波动率,无风险利率取 2%:

代码语言:python
复制
risk_free = 0.02
sharpe = (ann_return - risk_free) / ann_vol
print(f"夏普比率: {sharpe:.2f}")

夏普比率衡量"每承担一单位波动,能换来多少超额收益",越高越好。一般 >1 算不错,>2 很优秀(但要警惕样本太短带来的偶然性)。

5. 最大回撤

最大回撤是"从历史最高点跌到后续最低点的最大跌幅",是衡量策略痛苦程度的核心指标:

代码语言:python
复制
cum = (1 + df["ret"].fillna(0)).cumprod()   # 净值曲线
running_max = cum.cummax()                   # 历史最高
drawdown = cum / running_max - 1             # 每一刻的回撤
max_dd = drawdown.min()

# 回撤最深的那天
trough_idx = drawdown.idxmin()
peak_idx = cum[:trough_idx].idxmax()
print(f"最大回撤: {max_dd:.2%}")
print(f"从 {df['trade_date'][peak_idx]} 跌到 {df['trade_date'][trough_idx]}")

封装成一个函数

代码语言:python
复制
import numpy as np
import pandas as pd
from alphafeed import AlphaFeed

def risk_metrics(symbol, count=250, risk_free=0.02):
    af = AlphaFeed(api_key="your-api-key")
    df = af.klines.get(symbol, period="1d", count=count, adjust="forward", to_dataframe=True)
    df = df.sort_values("trade_date").reset_index(drop=True)

    df["ret"] = df["close"].pct_change()
    total = df["close"].iloc[-1] / df["close"].iloc[0] - 1
    n = len(df) - 1
    ann_ret = (1 + total) ** (250 / n) - 1
    ann_vol = df["ret"].std() * np.sqrt(250)
    sharpe = (ann_ret - risk_free) / ann_vol if ann_vol else np.nan

    cum = (1 + df["ret"].fillna(0)).cumprod()
    max_dd = (cum / cum.cummax() - 1).min()

    return {
        "symbol": symbol,
        "total_return": round(total, 4),
        "ann_return": round(ann_ret, 4),
        "ann_vol": round(ann_vol, 4),
        "sharpe": round(sharpe, 2),
        "max_drawdown": round(max_dd, 4),
    }

print(risk_metrics("600519.SH"))

批量对比多只股票

代码语言:python
复制
import pandas as pd

symbols = ["600519.SH", "000001.SZ", "601318.SH", "300750.SZ"]
rows = [risk_metrics(s) for s in symbols]
table = pd.DataFrame(rows)
print(table.to_string(index=False))

或者更高效地用一次批量请求拿全部 K 线,再逐个计算:

代码语言:python
复制
dfs = af.klines.batch(symbols, period="1d", count=250, adjust="forward",
                      to_dataframe=True, show_progress=True)

指标速查表

指标

含义

越大越好?

年化收益率

一年赚多少

年化波动率

波动/风险大小

否(越小越稳)

夏普比率

单位风险的超额收益

最大回撤

最惨时亏多少

否(越小越好)

常见问题(FAQ)

Q:为什么必须用复权价?

A:不复权价格在除权日会跳空,pct_change() 会算出一个假的暴跌,污染所有指标。用 adjust="forward""backward"

Q:一年到底按多少个交易日?

A:A 股常用 250(有时用 252)。保持全项目一致即可。

Q:能算组合的指标吗?

A:能。把各标的收益率按权重加权成组合收益率序列,再套同样的公式即可。

小结

收益率、波动率、夏普、最大回撤是评价任何股票或策略的四大基础指标。只要有一段干净的复权收盘价,pandas 十几行就能全部算出来。数据侧用 AlphaFeed 的 af.klines.get 保证复权正确、可复现,是这类分析可靠的前提。

参考

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

目录
  • 准备数据
  • 1. 日收益率与累计收益
  • 2. 年化收益率
  • 3. 年化波动率
  • 4. 夏普比率
  • 5. 最大回撤
  • 封装成一个函数
  • 批量对比多只股票
  • 指标速查表
  • 常见问题(FAQ)
  • 小结
  • 参考
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档