← 返回量化与 AI 投研概念库

回撤恢复期:亏完之后,你还要在水下待多久

最后更新 2026-08-18
R2 · 注意风险

有个问题,你可以现在就问自己一遍:如果你的账户从最高点掉下去 30%,你能忍多久?

大多数人回答这个问题的时候,脑子里想的是「30% 我扛得住」。这句话回答的其实是另一个问题——坑有多深。真正会把人熬走的不是深度,是你要在这个坑里待多长时间。掉下去可能只用三个月,爬回原来那个高点,可能要三年。这三年里,你每次打开账户,看到的都是一个比你最好那天低的数字。

坑深是一次性的疼,水下时间是每天都在的疼。前者你看报告的时候会记住,后者你要真的活过一遍才知道。

先说人话:这件事是三段,不是两段

想象你从游泳池边跳下去。整个过程有三个时刻:你离开水面的那一刻、你沉到最深处的那一刻、你重新浮出水面的那一刻。

多数人讲「回撤」——就是账户从历史最高点往下掉的那个幅度——只讲了前两个时刻之间的事:我下去了多深。但你憋不憋得住气,取决于从离开水面到重新浮出来,一共多久。而这段时间里,触底只是中点,不是终点。

放到账户上,同样三个时刻:

  • 峰值日:你的账户创下历史新高的那一天。这是水面。
  • 谷底日:你的账户跌到最低的那一天。这是最深处。
  • 回本日:你的账户重新超过当初那个峰值的那一天。这是你重新露头。

峰值日到谷底日,是下跌期;谷底日到回本日,是恢复期;从峰值日到回本日的整段,业内叫水下时间(underwater duration,字面意思就是「在水面以下待的时长」)。

关键在这儿:这三段的长短完全不成比例。跌下去往往很快——市场恐慌的时候,几周就能把你一年的成果抹掉。爬回来往往很慢,因为爬回来靠的不是恐慌,是一天一天的正常赚钱速度。下跌是事件驱动的,恢复是速度驱动的。 这两者压根不是一个量级的时间尺度。

投资层:为什么这个数才是你真正扛不住的那个

一个纯算术的例子(假设值,仅为演示)

坑深 30%,意味着你的钱只剩 0.7。要回到 1,需要涨 1÷0.7 − 1 ≈ 42.9%。这个「亏得越深、回本要求越离谱」的算术,亏损的不对称数学 那篇已经讲透了,这里不重复。

我们把它换成时间来看。假设某套方法长期的复利速度是每年 10%(这只是一个用来做算术的假设数字,不是任何预期收益),那么补上 42.9% 这个缺口需要多久?

log(1÷0.7) ÷ log(1.1) ≈ 3.74

接近四年。也就是说,一个「只有 30%」的回撤,在一套年化 10% 的方法上,理论最快也要将近四年才能回到原点——而且这还是假设你从谷底开始就一路顺风、中间不再有任何波折的理想情况。现实里中间还会再有小坑,实际时间只会更长。

这个换算值得你自己拿计算器再按一遍,因为它会改变你对回撤的感受方式。30% 听起来是个可以忍的数字,「四年不创新高」听起来就完全是另一回事了。懒得手按的话,回撤恢复期测算器填两个数就出年数,把回撤幅度往上挪几档,你会看到那条曲线抬头有多陡。

它伤的是你的耐心,不是你的本金

本金那部分是可逆的——只要方法还有效,钱总会回来。真正不可逆的是三样东西:

时间。 那四年的机会成本没有人赔给你。你的钱被卡在一个坑里,什么也没做成。

信心。 人对「一直不好转」的耐受度远低于对「亏一大笔」的耐受度。亏 30% 那天你会难受一周,然后咬牙坚持。可当第 18 个月还没回本、账户曲线躺平在半山腰不动的时候,「这套方法是不是已经失效了」这个念头会一天比一天大声。绝大多数人放弃一套方法,不是在最痛的那一天,而是在不痛不痒拖了很久的某个平常日子。

行为。 水下待得越久,你越容易做那件最糟糕的事——在接近谷底的位置改规则、加杠杆想快点回本、或者干脆换一套「看起来更好」的方法。而换方法这个动作本身,等于把你已经忍受完的那段痛苦一笔勾销,重新从水面下开始计时。

所以,如果只允许你看一个数字来判断「我这个人能不能配这套方法」,看恢复期比看最大回撤有用得多。深度考验的是你的账户,长度考验的是你这个人。

最深的坑,往往不是最久的坑

这是很多人没意识到的一点:最大回撤和最长水下时间常常不是同一段

一次剧烈的暴跌,可能跌 35%,但因为跌得急、市场反弹也急,八个月就回本了。而另一段温吞的阴跌,只跌了 18%,却是三年半的慢慢磨——磨到你都忘了自己还在水下。

如果你的报告只写了「最大回撤 35%」,那次让你真正熬不住的 18% 慢性回撤,在报告里根本不会露面。这就是下面要说的系统层问题的根源。

系统层:在真实系统里它长什么样(以及它其实没被算出来)

先把回撤序列这件事讲清楚。几乎所有系统的算法都是同一个骨架——当前净值 ÷ 历史最高净值 − 1(「净值」就是你这笔钱现在值多少,通常从 1 起算)。历史最高净值就是那个「只涨不跌的水位线」,专业点叫累计最大值(cummax)。

Vibe-Trading 的风险 X 光模块里,这三行就是全部:

equity = (1.0 + port).cumprod()
peak = equity.cummax()
dd = equity / peak - 1.0

第一行把每天的收益率滚成净值曲线,第二行记住「到今天为止的最高水位」,第三行相减——得到的 dd 就是一条永远小于等于 0 的曲线:等于 0 的日子表示你在水面上(正在创新高),小于 0 的日子表示你在水下,数值就是当天的水深。

把这条曲线画出来,就是「水下图」(underwater plot)。freqtrade 的绘图模块专门给它留了一整行子图,画的正是这条一直吊在零线以下的曲线。这张图为什么值得看?因为它把「深度」和「长度」同时摆在你眼前:坑的深浅看纵轴,坑的宽窄看横轴。而你只看一个「最大回撤 35%」的数字时,横轴那一维被彻底压扁了。

关键发现:三个系统都只算到谷底为止

这才是本篇最想让你知道的事。

freqtrade 的回测报告里有一项叫「Drawdown duration」(回撤持续时间),听名字像是「你在水下待了多久」。但它的计算就一行:

drawdown_duration = drawdown.low_date - drawdown.high_date

high_date 是峰值日,low_date 是谷底日。这个减法算出来的是峰值到谷底——只有下跌那半程。恢复期那半程,压根不在这个数里。

Vibe-Trading 的风险 X 光同样只吐三个字段:最大回撤值、回撤开始日、谷底日。没有回本日。

qlib 更简洁,它的风险分析函数只返回一个标量:

max_drawdown = (cumulative_curve / cumulative_curve.cummax() - 1).min()

一个 .min(),取整条曲线上最深的那一点。连日期都没有,更不用说时长。

结论很清楚:你在主流回测报告上看到的所有回撤数字,默认都不包含「爬回来要多久」这件事。 不是这些工具做得不好,而是「回本日」在工程上是个麻烦的东西——它可能根本不存在(回测结束时你还在水下),也可能一段回撤里套着好几个小反弹,「算不算回本」需要定义。工具选择了回避,把这个判断留给了看图的人。

代价是:如果你只读数字不读图,你会系统性地低估这套方法的痛苦程度。想系统地学怎么读这条曲线,可以看 怎么看一条收益曲线;想知道最大回撤这个数本身的口径问题,看 最大回撤:从数字到体感

同一条曲线,两种口径两个数

qlib 的风险分析函数里还有个细节值得一提:它支持两种累计方式。「加总」模式下,回撤算的是收益率累加值减去累加值的历史最高;「连乘」模式下,才是上面那个净值除以峰值。

# 加总模式
max_drawdown = (r.cumsum() - r.cumsum().cummax()).min()
# 连乘模式
max_drawdown = (cumulative_curve / cumulative_curve.cummax() - 1).min()

同一条收益序列,这两个式子给出的数不一样,量纲也不一样——前者是收益率的累加差值,后者是百分比。拿两份用不同口径出的报告直接比大小,比的是口径不是策略。这是回测偏差总览里那类「数字对但意义错」的典型。

系统会不会替你「熬不住」

有意思的是,回撤在系统里除了被统计,还会被当成刹车。freqtrade 有个保护插件:在一个回看窗口内,如果回撤超过设定的阈值,就全局停止开新仓,锁定到一个计算出来的时间点为止。

这是机器版的「先歇一歇」。但它有个结构性的盲区值得你留意:判断只在那个回看窗口内做。一段比窗口更长的慢性阴跌,每一个窗口切片看起来都很温和,于是它一次也不会触发。 而前面说过,恰恰是这种慢性回撤最能把人熬走。窗口长度、阈值这些都是可配置项,具体默认值以你手上那个版本的文档为准——但机制上的这个盲区,改参数是改不掉的。

系统还有一件事做得比人好:它同时记录「历史最大回撤」和「当前回撤」。freqtrade 的回撤结果对象里专门有一组 current_ 开头的字段,回答的是「此时此刻我在不在水下、水深多少」。对实盘来说这才是最要紧的那个数——历史最大回撤是一个已经翻篇的故事,当前水深是你现在正站的地方。

失效边界与常见误用

样本量是 1。 一段十年的历史里,「最长恢复期」这个数只有一个观测值。它不是一个统计意义上稳定的估计,而是一次具体经历。换一段历史,这个数可能翻倍。用一个样本量为 1 的数字去规划自己未来的忍耐力,是很危险的。 想看它的分布长什么样,得靠 蒙特卡洛检验 这类办法把它模拟成一个范围,而不是记住一个点。

截尾问题。 如果回测结束的那天你还在水下,这段回撤的恢复期是「未完成」的——真实值只会比报告里的更长,不会更短。很多报告会安静地把这段当成已经结束来算,或者干脆不算。看到回测末尾那条曲线正吊在半空的时候,要额外警惕。

时间轴不一定是日历。 freqtrade 的回撤序列是建在每一笔交易的平仓时刻上的,不是每一个自然日。如果某段时间一笔交易都没成交,这段序列上就没有点。序列上的「一步」和现实里的「一天」不是一回事——而你熬的是自然日,不是交易笔数。

把恢复期当承诺。 「历史上最长熬了三年就回本了」这句话,隐含了一个不成立的前提:坑总会被爬出来。历史数据里的每一次回撤都回本了,只是因为没回本的那些方法已经不在你的样本里了——这是幸存者偏差在时间维度上的版本。一套正在失效的方法,它的水下时间可以是无穷。

只看最大值,忽略占比。 除了「最长那一次」,还有个更能说明常态的数:整段历史里你有多大比例的日子是在水面以下的。有些方法最长恢复期不吓人,但常年七八成时间在水下——曲线一直在半山腰蹭,只是每次都不深。这种方法的持有体验,比一次深坑但大部分时间在创新高的方法糟糕得多。

用它反推该不该割。 恢复期是一个描述性的统计量,它告诉你历史上发生过什么,不告诉你现在这一次会不会一样。拿它当止损或加仓的依据,是把统计描述当成了预测。

🚧 避坑

「最大回撤 30%」和「三年不创新高」是同一件事的两种说法,但对你的心理是两种完全不同的东西。 报告只会告诉你前一种。评估一套方法之前,把它的水下图调出来看一眼横轴——最长的那一段有多宽。如果那个宽度你想想都觉得难熬,那这套方法就不适合你,跟它的年化数字多好看没有关系。

小结

  • 一次回撤是三个时刻两段路:峰值日 → 谷底日(下跌期)、谷底日 → 回本日(恢复期);两段加起来才是水下时间
  • 下跌是事件驱动的,往往很快;恢复是速度驱动的,往往很慢。所以恢复期通常远长于下跌期。
  • 主流系统默认不算恢复期:freqtrade 报告里的「回撤持续时间」是峰值到谷底、Vibe-Trading 只给到谷底日、qlib 只给一个标量最深值。回本日要你自己从水下图上读。
  • 最深的坑不一定是最久的坑。让人放弃的经常是那段「只跌了一点点却拖了很久」的慢性回撤,而它在「最大回撤」这个数里根本不出现。
  • 这个数的样本量通常只有 1,还可能被回测末尾截断;把它当经历参考可以,当规划依据不行。

一句话记住这篇:看一套方法,别只问它最惨的时候亏了多少,要问它最惨的时候,你要难受多久。

本文所引源码均来自上述快照版本,是阅读代码得出的机制说明,不是运行结果;具体行为请以你手上那个版本为准。文中所有百分比与年数均为演示算术用的假设值,不代表任何预期收益。回 量化与 AI 投研概念库 看其它概念各自在说什么;本站内容为投资教育,不构成任何投资建议,边界见 免责声明

内容有错、看不懂、或想看下一篇?告诉我们 →

本文为投资教育整理,不构成任何投资建议;不荐个股/基金、不预测点位、不承诺收益。关键数据与结论请结合权威来源自行验证,并见风险免责声明