4. 核心指标(上):计算收益率、波动率、最大回撤、夏普比率

做量化交易,说白了就是跟数字打交道。但数字本身不会说话,得靠指标来解读。

这一章,我们来聊聊四个最基础、也最核心的指标:收益率、波动率、最大回撤、夏普比率。我个人习惯把它们叫做「四大金刚」——你只要做策略,就绕不开它们。

核心观点:这四个指标分别回答了四个问题——赚了多少?稳不稳?亏过多少?性价比如何?

核心指标知识体系 四大金刚 收益率 赚了多少? 波动率 稳不稳? 最大回撤 亏过多少? 夏普比率 性价比如何?

4.1 收益率:最直观的「成绩单」

收益率,谁都会算。但我要说的是,计算方式不同,结果可能差很多。

简单收益率 vs 对数收益率

简单收益率就是 (P_t - P_{t-1}) / P_{t-1}。这个好理解,你买100块的东西涨到110,收益率就是10%。

但我个人更推荐用对数收益率,也就是 ln(P_t / P_{t-1})。为什么?

  • 可加性:对数收益率可以直接相加得到总收益率,简单收益率不行
  • 正态性更好:对数收益率更接近正态分布,方便后续建模
  • 对称性:涨10%再跌10%,简单收益率算出来是亏的,对数收益率是0

我的习惯:做回测时用对数收益率计算,展示给客户时用简单收益率——因为客户更习惯「涨了10%」这种说法。

import numpy as np
import pandas as pd

# 假设我们有收盘价数据
prices = pd.Series([100, 102, 101, 105, 110])

# 简单收益率
simple_returns = prices.pct_change().dropna()

# 对数收益率
log_returns = np.log(prices / prices.shift(1)).dropna()

print("简单收益率:", simple_returns.values)
print("对数收益率:", log_returns.values)

4.2 波动率:风险的「体温计」

波动率衡量的是收益率的离散程度。说白了,就是看你的策略稳不稳。

年化波动率的计算

日波动率乘以根号下交易天数,就得到年化波动率。A股一般用252个交易日,港股用250,美股用252。

嗯,这里要注意:如果你用的是对数收益率,直接算标准差就行。如果是简单收益率,理论上应该用几何平均,但实践中大家也都用标准差——差别不大。

避坑指南:我曾经在计算波动率时忘记年化,结果夏普比率算出来是0.8,看起来还不错。后来发现是日波动率直接当成年波动率用了——实际只有0.05。那叫一个尴尬。

# 计算年化波动率
daily_vol = log_returns.std()
annual_vol = daily_vol * np.sqrt(252)

print(f"日波动率: {daily_vol:.4f}")
print(f"年化波动率: {annual_vol:.4f}")

4.3 最大回撤:最痛的「伤疤」

最大回撤,就是净值从最高点跌到最低点的最大幅度。这个指标我特别看重——因为它直接关系到你能不能拿住策略。

你想想看,一个策略年化收益30%,但最大回撤40%。你敢投吗?反正我不敢。回撤太大,心态先崩了。

计算逻辑

  1. 计算累计净值(从1开始)
  2. 计算历史最高点(滚动最大值)
  3. 回撤 = (当前净值 - 历史最高) / 历史最高
  4. 最大回撤 = 所有回撤中的最小值(负的最大)
# 计算最大回撤
cumulative = (1 + log_returns).cumprod()
running_max = cumulative.cummax()
drawdown = (cumulative - running_max) / running_max
max_drawdown = drawdown.min()

print(f"最大回撤: {max_drawdown:.2%}")

重要提醒:最大回撤是一个「事后指标」。它告诉你历史上最惨的时候亏了多少,但不代表未来不会更惨。所以,我一般会在最大回撤的基础上再加一个安全边际——比如策略最大回撤20%,我按30%来评估风险。

4.4 夏普比率:性价比之王

夏普比率 = (策略收益率 - 无风险利率) / 波动率

这个指标衡量的是「每承担一单位风险,能获得多少超额收益」。说白了,就是性价比。

无风险利率怎么选?

  • 国内常用:一年期国债收益率(目前约2%左右)
  • 或者用:SHIBOR 3个月利率
  • 也有人直接用0——我个人不太建议,因为这样会高估夏普比率

夏普比率多少算好?

夏普比率 评价
< 0.5 一般般,不如买理财
0.5 - 1.0 还不错,可以考虑
1.0 - 2.0 优秀,值得关注
> 2.0 小心!可能是过拟合

我的经验:实盘中夏普比率能稳定在1.0以上,就已经是顶级策略了。回测里动不动就3.0、5.0的,十有八九是过拟合。我曾经见过一个回测夏普8.0的策略,实盘直接亏了30%——嗯,从那以后我对高夏普特别警惕。

# 计算夏普比率
risk_free_rate = 0.02  # 假设无风险利率2%
excess_return = log_returns.mean() * 252 - risk_free_rate
sharpe_ratio = excess_return / annual_vol

print(f"年化超额收益: {excess_return:.2%}")
print(f"夏普比率: {sharpe_ratio:.2f}")

4.5 实战:一次性计算所有指标

来,我们把上面这些整合成一个函数。这样以后每次回测完,直接调用就行。

def calculate_metrics(prices, risk_free_rate=0.02, trading_days=252):
    """
    计算核心指标
    prices: 收盘价序列
    risk_free_rate: 无风险利率(年化)
    trading_days: 年交易天数
    """
    # 对数收益率
    log_returns = np.log(prices / prices.shift(1)).dropna()
    
    # 年化收益率
    annual_return = log_returns.mean() * trading_days
    
    # 年化波动率
    annual_vol = log_returns.std() * np.sqrt(trading_days)
    
    # 最大回撤
    cumulative = (1 + log_returns).cumprod()
    running_max = cumulative.cummax()
    drawdown = (cumulative - running_max) / running_max
    max_drawdown = drawdown.min()
    
    # 夏普比率
    excess_return = annual_return - risk_free_rate
    sharpe = excess_return / annual_vol if annual_vol != 0 else 0
    
    return {
        '年化收益率': f"{annual_return:.2%}",
        '年化波动率': f"{annual_vol:.2%}",
        '最大回撤': f"{max_drawdown:.2%}",
        '夏普比率': f"{sharpe:.2f}"
    }

# 使用示例
result = calculate_metrics(prices)
for k, v in result.items():
    print(f"{k}: {v}")

这四个指标,是量化分析的基石。你掌握了它们,就能对任何一个策略做出初步判断。下一章我们会继续讲其他核心指标,比如卡玛比率、索提诺比率等等——但说实话,这四个是最常用的,先把它们吃透。

总结一下:

  • 收益率:看赚了多少,推荐用对数收益率
  • 波动率:看稳不稳,记得年化
  • 最大回撤:看亏过多少,要留安全边际
  • 夏普比率:看性价比,太高要警惕过拟合
专注资料整理