Skip to content

4.3 绩效指标全景

概念详解

绩效指标是量化策略的"体检报告"。一个好的策略需要从收益、风险、风险调整后收益、稳定性等多个维度进行综合评估。单一指标(如年化收益率)很容易产生误导——高收益可能来自高杠杆或极端集中持仓。

绩效指标可以分为五大类:

  1. 收益类:累计收益率、年化收益率、超额收益(Alpha)
  2. 风险类:波动率、最大回撤、下行波动率、VaR
  3. 风险调整收益类:夏普比率、索提诺比率、信息比率、卡玛比率
  4. 稳定性类:胜率、盈亏比、连续亏损次数、最长回撤恢复时间
  5. 归因分析类:因子暴露、行业贡献、择时能力 vs 选股能力
名词解释:夏普比率

衡量每单位总风险所获得的超额回报,公式:(年化收益率 - 无风险利率) / 年化波动率。数值越高越好。一个夏普比率为1的策略意味着超额收益等于其承担的风险;夏普比率超过2的策略被认为是优秀的,超过3非常罕见,可能暗示过拟合。

名词解释:最大回撤

在选定周期内,净值从最高点到最低点的最大跌幅,衡量策略最糟糕的连续亏损情况。例如:"2020-2023年间最大回撤15%",意味着净值曾从峰值下跌了15%。最大回撤不仅影响心理承受力,还决定杠杆使用上限。

名词解释:卡玛比率

年化收益率除以最大回撤,反映单位回撤所获得的收益,越大表示策略在不利时期的恢复能力越强。卡玛比率 = 年化收益率 / |最大回撤|。卡玛比率大于1意味着即使遇到历史最大回撤,一年也能收复失地。

名词解释:索提诺比率

与夏普比率类似,但分母只使用下行波动率(低于目标收益率的波动),排除了上行波动对风险度量的干扰。索提诺比率 = (年化收益率 - 目标收益率) / 下行波动率。

名词解释:信息比率

衡量主动管理带来的超额收益相对于跟踪误差的比率。信息比率 = 年化超额收益 / 年化跟踪误差。用于评估相对基准的表现,信息比率大于1的基金经理被认为优秀。

数学原理

年化收益与年化波动率

假设有日收益率序列 {r1,r2,...,rT},年化(假设252个交易日):

μannual=(t=1T(1+rt))252/T1σannual=σdaily252

夏普比率

Sharpe=μannualrfσannual

最大回撤

MDD=max0t1<t2T(NAVt1NAVt2NAVt1)

索提诺比率

Sortino=μannualMAR1Tt=1Tmin(rtMAR,0)2252

其中 MAR 是最低可接受收益率(Minimum Acceptable Return),通常取0或无风险利率。

Python实战

📌 案例:完整的绩效指标计算

PYTHON78 行 · 2.7 KB
📄此处有展示代码78 行 · 2.7 KB展开 ▼
python
import numpy as np
import pandas as pd

def calculate_all_metrics(equity_curve, benchmark=None, rf_rate=0.03):
    """
    计算全套绩效指标

    Parameters:
        equity_curve: pd.Series, 净值曲线(index为日期)
        benchmark: pd.Series, 基准净值曲线
        rf_rate: 无风险利率(年化)
    """
    # 日收益率
    returns = equity_curve.pct_change().dropna()
    n_days = len(returns)
    years = n_days / 252

    # === 收益指标 ===
    total_return = equity_curve.iloc[-1] / equity_curve.iloc[0] - 1
    annual_return = (1 + total_return) ** (1 / years) - 1

    # === 风险指标 ===
    daily_vol = returns.std()
    annual_vol = daily_vol * np.sqrt(252)

    # 最大回撤
    rolling_max = equity_curve.expanding().max()
    drawdown = (equity_curve - rolling_max) / rolling_max
    max_drawdown = drawdown.min()

    # 下行波动率
    downside_returns = returns[returns < 0]
    downside_vol = downside_returns.std() * np.sqrt(252)

    # === 风险调整收益 ===
    sharpe = (annual_return - rf_rate) / annual_vol if annual_vol > 0 else 0
    sortino = (annual_return - rf_rate) / downside_vol if downside_vol > 0 else 0
    calmar = annual_return / abs(max_drawdown) if max_drawdown != 0 else 0

    # 信息比率(相对于基准)
    if benchmark is not None:
        excess = returns - benchmark.pct_change().dropna()
        tracking_error = excess.std() * np.sqrt(252)
        excess_return = annual_return - calculate_annual_return(benchmark)
        ir = excess_return / tracking_error if tracking_error > 0 else 0
    else:
        ir = np.nan

    # === 稳定性指标 ===
    win_rate = (returns > 0).mean()
    win_mean = returns[returns > 0].mean()
    lose_mean = returns[returns < 0].mean()
    profit_loss_ratio = abs(win_mean / lose_mean) if lose_mean != 0 else np.inf

    # 最长回撤恢复时间
    max_dd_end = drawdown.idxmin()
    max_dd_start = drawdown.loc[:max_dd_end].idxmax()

    # Calmar Ratios per rolling year
    rolling_1y = returns.rolling(252).mean() * 252  # rolling annual return
    rolling_vol = returns.rolling(252).std() * np.sqrt(252)

    metrics = {
        '累计收益率': f'{total_return:.2%}',
        '年化收益率': f'{annual_return:.2%}',
        '年化波动率': f'{annual_vol:.2%}',
        '最大回撤': f'{max_drawdown:.2%}',
        '下行波动率': f'{downside_vol:.2%}',
        '夏普比率': f'{sharpe:.2f}',
        '索提诺比率': f'{sortino:.2f}',
        '卡玛比率': f'{calmar:.2f}',
        '信息比率': f'{ir:.2f}',
        '胜率': f'{win_rate:.2%}',
        '盈亏比': f'{profit_loss_ratio:.2f}',
        '最大回撤发生时间': str(max_dd_end),
    }

    return pd.Series(metrics)
点击展开可浏览运行结果
年化收益率: 12.15%
年化波动率: 18.67%
夏普比率: 0.65
最大回撤: -16.78%
卡玛比率: 0.72

📌 案例:滚动指标分析

PYTHON33 行 · 1.0 KB
📄此处有展示代码33 行 · 1.0 KB展开 ▼
python
def rolling_metrics(returns, window=252):
    """
    计算滚动窗口的夏普比率和最大回撤,评估策略表现的稳定性
    """
    rolling_sharpe = returns.rolling(window).mean() / returns.rolling(window).std() * np.sqrt(252)
    rolling_dd = returns.rolling(window).apply(
        lambda x: (x.cumsum().cummax() - x.cumsum()).max()
    )

    return rolling_sharpe, rolling_dd

# 可视化滚动夏普
import matplotlib.pyplot as plt

fig, axes = plt.subplots(3, 1, figsize=(12, 10))
rolling_sharpe, rolling_dd = rolling_metrics(returns)

axes[0].plot(rolling_sharpe, label='Rolling Sharpe (1Y)')
axes[0].axhline(y=0, color='r', linestyle='--')
axes[0].axhline(y=1, color='g', linestyle='--')
axes[0].set_title('Rolling Sharpe Ratio')
axes[0].legend()

axes[1].fill_between(rolling_dd.index, 0, rolling_dd.values, color='red', alpha=0.3)
axes[1].set_title('Rolling Max Drawdown')
axes[1].invert_yaxis()

axes[2].plot((1 + returns).cumprod(), label='Cumulative Return')
axes[2].set_title('Cumulative Return')
axes[2].legend()

plt.tight_layout()
plt.show()
点击展开可浏览运行结果
运行结果图 1
📘 本段为代码片段(依赖上文变量或外部输入,如 df/data/参数等),无法独立运行

📊 实战模拟

📊 实战模拟

常见误区

  1. 只看夏普比率不看最大回撤:一个夏普3但回撤80%的策略,在实盘中几乎不可能坚持执行(你会被心理压力击垮,或者触发风控强制清仓)。

  2. 不考虑样本长度的影响:年化夏普比率的统计误差约为 1/T(T为年数)。一个3年样本的夏普比率,其95%置信区间约±1.15,意味着"夏普2"与"夏普0.85"在统计上可能没有区别。

  3. 用算术平均替代几何平均:年化收益应该用几何平均(CAGR),[(1+r1)(1+r2)...(1+rT)]1/n1,而不是简单算术平均 r¯×252

  4. 忽略尾部风险指标:夏普比率假设收益率服从正态分布,但股票收益率通常有肥尾。需要额外关注偏度、峰度和VaR/CVaR。

  5. 把"胜率"当作最重要的指标:很多优秀趋势跟踪策略的胜率只有30%-40%,但盈亏比很高。胜率低不代表策略不好。

实战练习

  1. 获取任意一只股票的日收益数据,分别计算其:

    • 全样本的年化收益、年化波动率和夏普比率
    • 分年度的年化收益、最大回撤(观察策略表现的年度差异性)
  2. 构造两个虚拟策略:策略A胜率60%、每次赚1%、亏1%;策略B胜率40%、每次赚3%、亏1%。分别计算它们的期望收益和夏普比率。哪个更好?为什么?

  3. 在你的回测框架中加入滚动指标分析模块:计算滚动252天的夏普比率、最大回撤和年化收益,绘制这三个序列的走势图。分析策略表现的稳定性。

延伸阅读

  • Sharpe, W. F. (1966). "Mutual Fund Performance." Journal of Business.
  • Sortino, F. A. & van der Meer, R. (1991). "Downside Risk."
  • Lo, A. W. (2002). "The Statistics of Sharpe Ratios." Financial Analysts Journal. 讨论夏普比率的统计推断问题。
  • Eling, M. & Schuhmacher, F. (2007). "Does the Choice of Performance Measure Influence the Evaluation of Hedge Funds?" 比较不同绩效指标的异同。

本章要点

  • 绩效评估需要从收益、风险、风险调整收益、稳定性四个维度全面分析。
  • 夏普比率是最常用的风险调整收益指标,但假设正态分布,不捕捉尾部风险。索提诺比率只惩罚下行波动,更符合投资者心理。
  • 最大回撤是一个路径依赖的指标,反映策略的历史最差表现,直接影响心理承受力和杠杆上限。
  • 卡玛比率衡量单位最大回撤的收益补偿,是实践中非常实用的参考指标。
  • 所有绩效指标都有统计误差,短期的高夏普比率可能只是运气。需要结合统计检验(见4.5章)判断显著性。
  • 没有哪个单一指标能完美评价策略——好的策略评估必然是多指标交叉验证