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 知识体系总览

为了让你更直观地理解这三个指标的关系,我画了一张图:

回撤量化指标体系 回撤管理 最大回撤 最惨的那次下跌 回撤幅度 每次下跌的深度 回撤时间 多久才能回本 三者关系 • 最大回撤 = 所有回撤幅度中的最小值 • 回撤幅度分布 = 判断风险集中度 • 回撤时间 = 衡量策略的恢复能力 • 三者结合 = 完整的回撤风险画像

这张图把三个指标的关系说得很清楚了。你想想看,如果只看最大回撤,就像只看一个人的身高,但不知道他胖瘦、跑得快不快。三个指标一起看,才能给策略画一个完整的「风险画像」。

好了,这一章的内容就到这。记住一句话:回撤不是洪水猛兽,不了解回撤才是。把这三个指标算清楚,你离一个成熟的交易员就更近了一步。

专注资料整理