2、回撤的数学定义:最大回撤、回撤幅度与回撤时间的量化计算
聊回撤管理,咱们得先把「回撤」这玩意儿量化了。不能光凭感觉说「跌了好多」,得用数字说话。
我刚开始做量化那会儿,就吃过这个亏。有次策略回测看着年化收益挺漂亮,结果实盘一跑,净值曲线跟过山车似的。后来一算最大回撤,好家伙,直接干到35%以上。嗯,从那以后,我养成了一个习惯:看任何策略,先看回撤,再看收益。
2.1 什么是回撤?
说白了,回撤就是你的账户净值从某个高点,跌到后面某个低点的幅度。注意,这里有个关键点——从高点算起。
举个例子:
- 你账户净值昨天是100万,今天跌到95万,回撤就是5%。
- 但如果你净值从100万涨到120万,然后又跌到110万,回撤是多少?
很多人会算成 (120-110)/120 ≈ 8.33%。没错,这才是正确的算法。因为回撤永远是从「最近的高点」开始算的。
核心概念:回撤 = (当前净值 - 阶段最高净值) / 阶段最高净值
注意,这个值通常是负数,但大家习惯说「回撤了5%」,所以一般取绝对值。
2.2 最大回撤(Max Drawdown)
最大回撤,就是整个回测周期或实盘周期里,最惨的那一次。它衡量的是策略在最坏情况下的抗风险能力。
我见过不少新手,看到策略年化收益30%,两眼放光。但一问最大回撤,40%。这什么概念?就是你投100万,最惨的时候只剩60万。你扛得住吗?
最大回撤的计算公式:
MDD = max( (D₁ - P₁) / P₁, (D₂ - P₂) / P₂, ..., (Dₙ - Pₙ) / Pₙ )
其中:
- Dₙ 是第n个交易日的净值
- Pₙ 是到第n个交易日为止的历史最高净值
说白了,就是每天算一次回撤,然后取最小值(因为回撤是负的,最小值就是跌得最狠的那个)。
我的经验:我个人习惯把最大回撤控制在15%以内。超过20%的策略,除非收益特别高(年化50%以上),否则我基本不考虑。为什么?因为回撤大了,你拿不住。
2.3 回撤幅度与回撤时间
光看最大回撤还不够。你想想看,同样是回撤20%,一种情况是3天就跌完,然后慢慢涨回来;另一种是慢慢跌了半年才跌20%。这两种情况,对心理的冲击完全不一样。
所以,我们还需要两个指标:
2.3.1 回撤幅度
回撤幅度就是每次回撤的深度。它和最大回撤的区别在于:最大回撤只取最深的那个,而回撤幅度记录每一次回撤的深度。
举个例子:
| 时间 | 净值 | 历史高点 | 回撤幅度 |
|---|---|---|---|
| 第1天 | 100 | 100 | 0% |
| 第2天 | 105 | 105 | 0% |
| 第3天 | 102 | 105 | -2.86% |
| 第4天 | 98 | 105 | -6.67% |
| 第5天 | 103 | 105 | -1.90% |
你看,第4天的回撤幅度是-6.67%,这就是一次完整的回撤事件。如果后面净值创了新高(比如涨到106),那这次回撤事件就结束了。
2.3.2 回撤时间
回撤时间,就是从净值创出新高,到再次创出新高所经历的时间。这个指标特别重要,因为它直接关系到你的持仓耐心。
我曾经做过一个ETF轮动策略,最大回撤只有12%,但回撤时间长达8个月。什么意思?就是你亏了12%之后,要等8个月才能回本。这8个月里,你看着别的策略赚钱,自己账户还是绿的,那种煎熬...嗯,懂的都懂。
避坑指南:我曾经犯过一个错误——只看最大回撤,不看回撤时间。结果选了一个回撤时间很长的策略,实盘时心态崩了,在回撤底部割肉离场。后来我给自己定了个规矩:回撤时间超过6个月的策略,一律不碰。
2.4 三个指标的关系
最大回撤、回撤幅度、回撤时间,这三个指标是互相补充的。我一般这样用:
- 最大回撤:看策略的「底线」在哪,能不能接受
- 回撤幅度分布:看回撤是集中在浅层(5%以内),还是经常出现深度回撤(15%以上)
- 回撤时间:看策略的「恢复能力」,回撤时间越短越好
举个实际案例:
我去年优化一个沪深300增强策略,原始版本的最大回撤是18%,回撤时间平均4个月。后来我加了波动率过滤和止损条件,最大回撤降到了12%,回撤时间缩短到2个月。虽然年化收益从22%降到了19%,但持有体验好了很多。你想想看,少赚3个点,但不用提心吊胆,值不值?
2.5 量化计算的代码实现
说了这么多理论,咱们来点实际的。下面是我常用的回撤计算代码,用Python写的:
import numpy as np
import pandas as pd
def calculate_drawdown(equity_curve):
"""
计算回撤相关指标
equity_curve: 净值序列,pandas Series
"""
# 计算历史最高点
rolling_max = equity_curve.cummax()
# 计算每日回撤
drawdown = (equity_curve - rolling_max) / rolling_max
# 最大回撤
max_drawdown = drawdown.min()
# 回撤持续时间
# 找到每次回撤的起始和结束位置
is_drawdown = drawdown < 0
drawdown_periods = []
start_idx = None
for i, val in enumerate(is_drawdown):
if val and start_idx is None:
start_idx = i
elif not val and start_idx is not None:
drawdown_periods.append(i - start_idx)
start_idx = None
# 平均回撤时间(交易日)
avg_drawdown_days = np.mean(drawdown_periods) if drawdown_periods else 0
return {
'max_drawdown': max_drawdown,
'avg_drawdown_days': avg_drawdown_days,
'drawdown_series': drawdown
}
# 使用示例
# equity = pd.Series([...]) # 你的净值数据
# result = calculate_drawdown(equity)
# print(f"最大回撤: {result['max_drawdown']:.2%}")
# print(f"平均回撤时间: {result['avg_drawdown_days']:.0f} 天")
小技巧:我习惯在回测报告里同时展示「最大回撤」和「回撤恢复时间」这两个指标。如果发现某个策略的回撤恢复时间特别长,我会进一步分析——是市场整体不好,还是策略本身有问题?
2.6 知识体系总览
为了让你更直观地理解这三个指标的关系,我画了一张图:
这张图把三个指标的关系说得很清楚了。你想想看,如果只看最大回撤,就像只看一个人的身高,但不知道他胖瘦、跑得快不快。三个指标一起看,才能给策略画一个完整的「风险画像」。
好了,这一章的内容就到这。记住一句话:回撤不是洪水猛兽,不了解回撤才是。把这三个指标算清楚,你离一个成熟的交易员就更近了一步。