3. 最大回撤控制:定义、计算与心理影响,如何设定硬性回撤止损线

做量化交易,你最先要学会面对的不是盈利,而是亏损。我见过太多策略,回测曲线漂亮得像教科书,一上实盘就崩了。为什么?说白了,就是没管住回撤。

今天咱们就聊聊最大回撤。这东西,既是数学指标,也是心理防线。

3.1 最大回撤的定义

最大回撤,英文叫 Maximum Drawdown,简称 MDD。它衡量的是:从某个高点跌到后续最低点,这个跌幅有多大。

公式很简单:

最大回撤 = (峰值 - 谷值) / 峰值 × 100%

举个例子:你的账户从 100 万涨到 150 万,然后跌到 90 万,接着又涨到 120 万。那么最大回撤就是 (150 - 90) / 150 = 40%。

注意,这个 40% 是历史最高点到最低点的跌幅。哪怕后来涨到 200 万,这个 40% 的记录依然存在。

核心要点:最大回撤只看「从山顶到谷底」这一段,中间的小波动不算。

3.2 怎么计算?我常用的两种方式

计算最大回撤,我一般用两种方法:

方法一:滚动计算法

把净值序列从头扫到尾,每到一个新高点,就记录一下,然后看后面跌了多少。代码实现很简单:

def max_drawdown(net_values):
    peak = net_values[0]
    max_dd = 0.0
    
    for value in net_values:
        if value > peak:
            peak = value
        dd = (peak - value) / peak
        if dd > max_dd:
            max_dd = dd
    
    return max_dd

这段代码我用了好多年,简单可靠。你想想看,它其实就是不断更新「历史最高点」,然后算当前跌了多少。

方法二:向量化计算(适合大数据)

如果你用 Pandas,可以一行搞定:

import pandas as pd

def max_drawdown_vectorized(net_series):
    rolling_max = net_series.cummax()
    drawdown = (net_series - rolling_max) / rolling_max
    return drawdown.min()

我个人习惯用第二种,速度快,尤其回测几千次的时候,差距很明显。

3.3 回撤的心理影响——这才是最要命的

我做过一个统计:当回撤超过 20% 时,超过 60% 的交易者会手动干预策略。说白了,就是慌了。

为什么会这样?因为亏损带来的痛苦,大约是同等盈利带来快乐的两倍。这是行为金融学里的「损失厌恶」理论。

我在项目中遇到过一位客户,策略回测最大回撤只有 15%,他信誓旦旦说能扛住。结果实盘回撤到 12% 时,他半夜打电话给我,说「要不要先平仓出来看看?」。嗯,这就是人性。

回撤的心理影响分三个阶段:

  • 5% 以内:大多数人还能理性看待,觉得是正常波动。
  • 5%-15%:开始焦虑,频繁查看账户,怀疑策略是否失效。
  • 15% 以上:恐慌情绪蔓延,容易做出非理性决策,比如提前止损、修改参数。

警告:回撤本身不可怕,可怕的是你在回撤中做出的错误决策。我曾经见过一个策略,回撤 18% 时被手动关闭,结果后面三个月涨了 60%。

3.4 如何设定硬性回撤止损线?

硬性回撤止损线,就是一条不能碰的红线。碰了,无条件清仓。没有商量余地。

怎么设定?我建议分三步走:

第一步:分析策略的历史回撤特征

拿出你的回测报告,看看最大回撤是多少。注意,不要只看平均值,要看极端情况。比如:

指标 数值
平均回撤 8.2%
最大回撤 22.5%
90%分位回撤 15.3%

我个人习惯把止损线设在「最大回撤 × 1.2」的位置。比如上面这个策略,就是 22.5% × 1.2 = 27%。

第二步:考虑资金承受能力

回撤止损线不能只看策略,还要看你的资金量。如果你只有 10 万本金,回撤 30% 就是 3 万,你能接受吗?

我建议用这个公式:

硬性止损线 = min(策略最大回撤 × 1.2, 资金心理承受上限)

资金心理承受上限怎么算?很简单:你晚上能睡着的最大亏损比例。

第三步:写进代码,自动化执行

手动止损?不存在的。等你犹豫半天,行情早变了。必须写进代码:

class RiskManager:
    def __init__(self, max_drawdown_limit=0.25):
        self.peak = None
        self.max_drawdown_limit = max_drawdown_limit
    
    def check_drawdown(self, current_value):
        if self.peak is None or current_value > self.peak:
            self.peak = current_value
        
        current_dd = (self.peak - current_value) / self.peak
        
        if current_dd > self.max_drawdown_limit:
            return "STOP"  # 触发硬性止损
        return "OK"

小技巧:硬性止损触发后,不要马上重新入场。我一般会设置一个「冷却期」,比如 5 个交易日。等市场冷静下来,再重新评估是否要重启策略。

3.5 知识体系总览

下面这张图,是我自己整理的最大回撤控制框架。你可以把它当成一个检查清单:

最大回撤控制知识体系 定义与计算 • 峰值到谷值跌幅 • 滚动计算法 • 向量化计算 • 历史高点追踪 • 回撤持续时间 心理影响 • 损失厌恶效应 • 5%以内:理性期 • 5%-15%:焦虑期 • 15%以上:恐慌期 • 手动干预风险 硬性止损设定 • 历史回撤分析 • 资金承受能力 • 自动化执行 • 冷却期机制 • 动态调整策略 三者缺一不可,构成完整风控闭环

你看,定义计算是基础,心理影响是软肋,硬性止损是最后一道防线。三者缺一不可。

我的经验:设定硬性止损线时,一定要在回测阶段就想好。别等实盘亏钱了再拍脑袋。我曾经吃过这个亏,后来学乖了,每次上线新策略前,先把止损线写死,然后锁起来。嗯,物理上锁,钥匙交给合伙人。

最后说一句:最大回撤控制不是限制你的盈利,而是保护你的本金。只要本金在,机会永远有。


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