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