3、风险指标:最大回撤、波动率、下行风险的定义与计算

做量化交易,我最怕听到的一句话就是:「策略回测曲线真漂亮,年化50%!」

嗯,漂亮归漂亮,但你要是只看收益不看风险,迟早要栽跟头。我见过太多人,拿着一个回撤30%的策略冲进实盘,结果三个月就扛不住了。

今天咱们就聊聊三个最核心的风险指标:最大回撤波动率下行风险。说白了,它们就是帮你回答三个问题:

  • 这策略最惨的时候能亏多少?
  • 它平时上蹿下跳有多厉害?
  • 它亏钱的时候到底有多痛?

核心观点:风险指标不是用来吓唬人的,而是用来帮你做仓位管理和策略筛选的。不懂风险,你赚的钱迟早要还回去。

3.1 最大回撤:你的策略能扛住多大的坑?

最大回撤,英文叫 Maximum Drawdown,简称 MDD。定义很简单:在某个时间段内,从净值最高点跌到最低点的最大幅度。

公式长这样:

MDD = max( (Peak - Trough) / Peak )

其中 Peak 是历史最高净值,Trough 是之后的最低净值。

举个例子:

  • 策略净值从 1.0 涨到 1.5,然后跌到 1.2,再涨到 1.8,又跌到 1.3。
  • 第一个回撤:(1.5 - 1.2) / 1.5 = 20%
  • 第二个回撤:(1.8 - 1.3) / 1.8 = 27.8%
  • 最大回撤就是 27.8%

我个人习惯把最大回撤分成两类:

  • 历史最大回撤:整个回测期内的最大值。这是最严格的指标。
  • 滚动最大回撤:按固定窗口(比如60天)滚动计算。能看出不同阶段的风险变化。

避坑指南:我曾经犯过一个错误——只看历史最大回撤,忽略了回撤的持续时间。一个策略回撤30%但只持续了5天,和回撤30%持续了半年,完全是两码事。所以建议你同时关注「回撤恢复天数」。

3.2 波动率:你的策略有多「颠簸」?

波动率,说白了就是收益率的「标准差」。它衡量的是策略净值的波动幅度。

公式:

σ = sqrt( (1/(n-1)) * Σ(Ri - R̄)² )

其中 Ri 是每日收益率,R̄ 是平均收益率,n 是样本数。

实际计算时,我们通常用年化波动率:

年化波动率 = 日波动率 * sqrt(252)

为什么是252?因为一年大约有252个交易日。

举个例子:

  • 策略A:日波动率 0.5%,年化波动率 ≈ 7.9%
  • 策略B:日波动率 1.5%,年化波动率 ≈ 23.8%

策略B的波动是策略A的3倍,意味着你坐过山车的体验也差了3倍。

我的经验:波动率不是越低越好。低波动策略往往收益也低。关键是看「收益风险比」,也就是夏普比率。我一般要求年化波动率控制在15%-25%之间,太低了没意思,太高了拿不住。

3.3 下行风险:只关心亏钱的时候

波动率有个问题——它把上涨和下跌都算进去了。但说实话,上涨的波动谁不喜欢?

所以就有了下行风险(Downside Risk),它只关注收益率低于某个目标值(通常是0)的部分。

公式:

下行风险 = sqrt( (1/n) * Σ min(Ri - R_target, 0)² )

其中 R_target 是目标收益率,通常设为0。

说白了:

  • 如果某天赚了2%,下行风险贡献为0
  • 如果某天亏了3%,下行风险贡献为 (-3%)² = 0.09%

这样算出来的风险,才真正反映了「亏钱时的痛苦程度」。

实用技巧:我建议你把下行风险和最大回撤结合起来看。如果下行风险很低但最大回撤很高,说明策略虽然偶尔大亏,但平时亏钱的日子不多。反之,如果下行风险很高,说明策略天天都在「小刀割肉」,这种策略更难拿住。

3.4 代码实现:用Python算一遍

光说不练假把式。咱们用Python把这三个指标算一遍。

import numpy as np
import pandas as pd

def calculate_risk_metrics(returns):
    """
    计算风险指标
    returns: 每日收益率序列(pandas Series)
    """
    # 1. 最大回撤
    cumulative = (1 + returns).cumprod()
    running_max = cumulative.cummax()
    drawdown = (cumulative - running_max) / running_max
    max_drawdown = drawdown.min()
    
    # 2. 年化波动率
    daily_vol = returns.std()
    annual_vol = daily_vol * np.sqrt(252)
    
    # 3. 下行风险
    target = 0
    downside_returns = returns[returns < target]
    downside_risk = np.sqrt((downside_returns ** 2).mean()) * np.sqrt(252)
    
    return {
        'max_drawdown': max_drawdown,
        'annual_volatility': annual_vol,
        'downside_risk': downside_risk
    }

# 示例
np.random.seed(42)
daily_returns = pd.Series(np.random.normal(0.001, 0.02, 1000))
metrics = calculate_risk_metrics(daily_returns)

print(f"最大回撤: {metrics['max_drawdown']:.2%}")
print(f"年化波动率: {metrics['annual_volatility']:.2%}")
print(f"下行风险: {metrics['downside_risk']:.2%}")

注意:代码中的下行风险我做了年化处理,但有些教材里用的是非年化版本。使用时请确认你的计算口径。我个人习惯统一年化,这样比较起来更方便。

3.5 三个指标的关系与使用场景

这三个指标不是孤立的,它们从不同角度描述风险:

指标 衡量什么 适合场景
最大回撤 最坏情况下的亏损幅度 风控阈值设定、仓位管理
波动率 整体波动幅度(涨跌都算) 策略稳定性评估、杠杆计算
下行风险 亏损时的平均亏损程度 投资者心理承受力评估

举个例子你就明白了:

  • 策略A:最大回撤20%,波动率15%,下行风险8%
  • 策略B:最大回撤20%,波动率25%,下行风险18%

两个策略最大回撤一样,但策略B的下行风险高出一倍多。说明策略B亏钱的日子更多、亏得更狠。你选哪个?

我的建议:做策略筛选时,先看最大回撤能不能接受,再看下行风险高不高。波动率可以作为辅助参考。记住,一个让你夜不能寐的策略,再高的收益也没意义。

3.6 知识体系总览

下面这张图帮你理清三个指标的关系:

风险指标知识体系 风险指标 最大回撤 波动率 下行风险 历史最大回撤 滚动最大回撤 日波动率 年化波动率 只关注亏损时的波动 三者结合使用,全面评估策略风险特征

嗯,这三个指标讲完了。你可能会问:「知道了这些,然后呢?」

然后就是实战了。下次你看到一个策略,别光盯着收益率。先算算最大回撤你能不能接受,再看看下行风险高不高。如果这两个指标都过关,再谈收益也不迟。

最后一句:风险指标不是用来限制你的,而是用来保护你的。我见过太多人因为不懂风险,把辛辛苦苦赚的钱又还给了市场。希望你不是其中之一。


公众号:蓝海资料掘金营,微信deep3321