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

下行风险:只惩罚往下的波动,可「往下」到底从哪算起

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

有个说法你大概听过:用波动率衡量风险不公平,因为涨得猛也算波动大,而没人会因为账户涨太快去投诉。于是有了「下行风险」——只统计往下掉的那部分。

听起来天经地义,问题也就到此为止了。可你真去看几套系统给同一段净值算出来的下行风险,会发现数字对不上,有时还差着好几倍。不是谁算错了,是「往下」这两个字里,藏着三个必须有人替你拍板的问题:多低才算往下?谁被算进去?除以几个数? 每个问题都有不止一个合理答案,而不同的答案会给出不同的结论——甚至会把两套方法的优劣排名整个调过来。

这篇不重复讲索提诺比率是什么(那部分在 夏普比率与索提诺比率 里已经说清了),只盯着分母:下行波动这个数,到底是怎么被造出来的。

先说人话:它想修的是哪种不公平

想象一个班级要评「最稳的学生」。老师的第一版办法是看每次考试成绩围绕平均分的起伏——起伏越小越稳。结果有个孩子平时都是八十来分,有一次超常发挥考了满分,起伏一下变大,稳定性评分反而掉下来了。

全班都觉得离谱:考得特别好,怎么成了减分项?

于是老师改规则:只看低于及格线的那些次,考得高不扣分。 这就是下行风险的全部动机——把「让你高兴的意外」从风险里摘出去,只留下「让你难受的意外」。

到这儿都没毛病。可老师接下来立刻会被问住:及格线定六十还是定平时的平均分?一学期考了二十次、只有三次低于线,算平均的时候是除以三,还是除以二十?那三次分别是五十九、五十八、五十七(低得很整齐)和五十九、五十八、二十(有一次崩了),要不要区别对待?

这三个问题,就是下行波动在工程里全部的争议来源。你会发现它们没有一个是数学问题,全是口径问题——而口径是人定的。

投资层:三个口径分别决定你会误判什么

第一个口径:门槛线画在哪

「往下」总得相对某条线。行业里管这条线叫最低可接受回报(常写作 MAR,minimum acceptable return,意思就是「低于这个数我就不满意了」)。常见的选法有三种:

  • 画在零上:只有真金白银亏了才算下行。最符合直觉,也最常见。
  • 画在无风险利率上:钱存起来什么都不干也有一点利息,赚得比这还少,就算你没干好。
  • 画在你的目标上:比如你需要年化八个点才够用,那么赚了三个点也是「没达标」,照样计入下行。

这不是学术分歧,它会实实在在改变结论。同一段净值,门槛画在零上,那些不赚不亏的月份统统不算风险;门槛抬到你的目标线上,这些月份全部变成下行样本,下行波动立刻变大。更要命的是排名会翻转:一套「常年小赚、极少亏」的方法,在零门槛下几乎没有下行样本,看起来无懈可击;一旦把门槛提到你的实际目标,它的「小赚」大部分都在门槛之下,风险数字瞬间难看。而另一套「涨跌都大但均值高」的方法,评价则往相反方向走。

所以看到任何一个下行风险数字,第一句要问的不是「这个数大不大」,而是**「这是相对哪条线算的」**。没人告诉你线在哪,这个数就没法解读。

第二个口径:分母除以几个数

假设一年二百多个交易日,其中三十天在跌。算「平均跌得有多厉害」的时候,把那三十天的平方和除以三十,和除以二百多,是完全不同的两件事。

  • 除以下跌的天数:你量的是「一旦跌,会跌多狠」。跌的频率被消掉了。
  • 除以全部天数:你量的是「跌这件事整体给你造成了多大压力」。跌得少,本身就是一种优点,会被记进分数里。

教科书里的下行离差走的是后者——把所有低于门槛的缺口平方加起来,除以全部期数再开方。理由很朴素:一年只跌三天,和一年跌一百天但每次幅度一样,这俩显然不是同一种体验,风险指标应该分得出来。

但真去读代码你会发现,前一种做法在工程里更常见,因为它写起来只有一行。这不是谁偷懒,是「先筛出负的、再求个标准差」这个写法太自然了,自然到没人觉得需要停下来想一想。

第三个口径:量「离门槛多远」还是量「彼此有多散」

这是最隐蔽、也最值得你花三分钟想明白的一处。

标准差衡量的是一组数彼此之间有多分散——它先算这组数的平均,再看每个数离这个平均有多远。而下行风险想问的是另一件事:这些坏结果离门槛有多远。

平时这俩差不多,但在一种情形下会彻底分道扬镳:当亏损非常整齐的时候。

设想一套方法每个下跌日都稳定跌 1%,一次不多一次不少。它们彼此完全不分散,标准差是零。如果你的下行风险用「亏损的标准差」来算,分母就是零;把它放进任何一个「收益 ÷ 下行风险」的比率里,结果会冲到天上去——一套天天稳定失血的方法,被打成了满分。

而如果你用「离门槛的缺口」来算,同样这段序列给出的下行风险是实打实的 1% 量级,比率老老实实地难看。

同一段数据,同一个名字,两种算法,一个说完美,一个说糟糕。这不是极端假设——「每天固定亏一点」正是很多带固定成本的高频方法、以及被手续费慢慢磨死的策略的真实形状。

系统层:同一个词,四个仓库四种做法

把几套开源系统摆在一起读,上面三个口径的分歧全部现形。这一段的价值不在于代码,而在于让你看到:这个词在真实系统里根本没有统一含义。

系统 做法 一句话
freqtrade(按天的超参搜索目标) 缺口平方和 ÷ 全部天数,再开方 教科书写法:门槛可换、跌得少算优点
freqtrade(按笔交易统计) 只取亏损的那些笔,求标准差 量的是「亏损彼此有多散」
freqtrade(按账户余额快照) 只取下跌的日收益,求标准差 同上,但换成按日
Vibe-Trading 只取下跌的日收益,求标准差 同上;样本太少时用极小数兜底
qlib 没有这个指标 只给对称波动率 + 最大回撤

一个一个说。

写法一 · 缺口平方和:教科书的那一版

freqtrade 里有一个专门用来做超参数搜索(就是让程序自动试很多组参数、挑一组最好的)的目标函数,它算下行波动的方式是标准做法:

total_profit = sum_daily["profit_ratio_after_slippage"] - minimum_acceptable_return
sum_daily["downside_returns"] = 0.0
sum_daily.loc[total_profit < 0, "downside_returns"] = total_profit
total_downside = sum_daily["downside_returns"]
down_stdev = math.sqrt((total_downside**2).sum() / len(total_downside))

四行里三个口径全齐了。第一行减掉了 minimum_acceptable_return,这就是门槛——它是一个明确写出来的变量,说明作者知道这条线是可以挪的(该实现里把它设成了零,属于当前实现的取值,换个版本或换个人写就可能不同)。第二、三行把所有非负的那些天填成零,保留在序列里,而不是删掉。最后一行除的是 len(total_downside),也就是全部天数——因为上一步没删,所以这个长度是整段区间。

所以「跌得少」在这里确实是加分项:不跌的日子作为零留在分母里,把整体拉低。

还有个细节值得看:这段计算之前,先从每笔收益里扣掉了一个固定的滑点比例(源码里写死,具体数值属实现细节,可能随版本变)。下行风险从来不是在原始收益上算的,是在扣完成本之后算的——成本口径变了,下行风险跟着变,这也是同一套净值在不同系统里数字对不上的原因之一。想深究成本这一层,可以看 交易成本假设

写法二 · 只取亏损求标准差:更常见,也更容易骗人

同一个仓库里,展示在回测报告上的那个索提诺比率,算法完全是另一套:

down_stdev = np.std(trades.loc[trades["profit_abs"] < 0, "profit_abs"] / starting_balance)

按余额快照算的那一版结构一样,只是把「亏损的交易」换成「下跌的日收益」。Vibe-Trading 的做法也在同一族:

downside = port_ret[port_ret < 0]
downside_std = float(downside.std()) if len(downside) > 1 else 1e-10

这几行都干了同一件事:先把非负的样本扔掉,再对剩下的求标准差。 两个后果同时发生——分母变成了「下跌的次数」(跌得少不再是优点),量的东西变成了「亏损之间有多分散」(不是「离门槛多远」)。前面说的「稳定失血反而满分」,就是从这里来的。

不是说这个写法错。它回答的是一个合理的问题:「这套方法亏的时候,亏得稳不稳?」只是这个问题和「它有多让人难受」不是同一个问题,而两者共用了同一个名字。

顺带一个更细的分歧:求标准差时分母减不减一(代码里的 ddof)。样本多的时候差别可以忽略,样本只有十来个的时候,这一下就能让数字挪动百分之几。同一个仓库里不同文件的选择都未必一致——这不是 bug,是没人觉得需要统一。

写法三 · 样本不够时的兜底:两套系统给出相反的答案

这是最有意思的一处。如果这段区间里根本没有下跌的日子呢?

分母是零,除不下去,每套系统都得处理。而它们的处理方式截然相反:

  • freqtrade 那个按天的目标函数,遇到下行波动为零,直接把这次的分数判成一个很大的负数,并在注释里说明「这样才清楚地表明这不是最优解」——把「查不出风险」当成可疑,不当成优秀。
  • Vibe-Trading 那一版,遇到有效样本不足,用一个极小的数当分母兜底。极小的数做分母,结果是天文数字——同一种情况,被显示成了一个惊人漂亮的比率。

(两处的具体数值都是实现细节,会随版本变化,重点是方向相反。)

同一段「区间内没跌过」的净值,一个系统说「这数据不可信」,另一个系统说「这策略无敌」。你要是只看报告上那个数,永远不会知道自己看到的是哪一种。而「区间内没跌过」这件事,在短样本、牛市片段、或者刚上线两周的实盘里,一点都不罕见。

写法四 · qlib 的选择:干脆不提供

qlib 的收益分析函数给的是均值、标准差、年化收益、信息比率、最大回撤——没有下行波动,也没有索提诺。 整个仓库里搜不到这个概念。

这不是遗漏,更像是一种立场:要表达「往下有多疼」,最大回撤比下行波动直白得多。 下行波动是把所有坏日子打散、平均、开方之后得到的一个统计量,读者对它没有体感;而最大回撤是「最惨的时候,从高点掉下来多少」,任何人都能立刻换算成「我账户少了多少钱」。这一层展开在 最大回撤:从数字到体感

还有一个技术性理由:下行波动和最大回撤看的根本不是一回事。下行波动只统计每一天有多差,完全不管这些坏日子的先后顺序。十次 −2% 均匀撒在两年里,和十次 −2% 连着发生,下行波动一模一样,可后者会打出一个大得多的坑。顺序对人的杀伤力,下行波动看不见。

为什么它更符合直觉,却更容易骗人

它把一半样本扔了。 用对称波动率,你有全部数据;只算下行,样本立刻少一大半。样本少,估计就抖——今年算出来的下行风险和去年差一截,可能只是那一年跌的天数少了几天,跟方法本身没关系。「更贴近直觉」的代价是「更不稳」,这笔账很少有人明说。

它对「还没发生的那类亏损」完全失明。 有一类收益形状是「天天赚一点小钱,偶尔捅一个大篓子」——卖保险式的策略、杠杆套利、赌波动不会放大的做法,都长这样。在篓子捅出来之前,这类方法的下行样本极少且都很小,下行风险算出来低得离谱,各种「风险调整后收益」全是满分。而那个还没到来的尾巴,不在样本里。这是 尾部风险 那一篇要处理的问题,下行波动本身给不了任何提示。

它可以被当成优化目标,然后被反向利用。 前面提到 freqtrade 把索提诺做成了超参搜索的目标函数——也就是说,程序会主动寻找「让这个数最大」的参数组合。一旦某个指标变成搜索目标,它就不再只是尺子,而是选择压力:你等于在告诉程序「上涨的波动我不在乎」,那么它当然会更青睐那些「上涨随便冲、下跌看着小」的参数——包括那些只是恰好在这段历史里下跌样本少的参数。指标的盲区,会被搜索过程精准地找出来并放大。这条路怎么滑向自欺,参数高原 那篇讲得更细。

它没有绝对好坏,只能同口径横比。 门槛线、分母、样本频率(按天还是按笔)、年化时乘的那个系数(加密市场按全年无休折算,A 股按一年二百多个交易日折算,具体数字各仓库自己定),任何一项不同,两个数字就没有可比性。跨平台抄一个「索提诺 3.2」过来和自己的比大小,是纯粹的自我安慰。

🚧 避坑

看到一个漂亮的下行风险数字,先确认它的下行样本有几个。 只有三五个下跌日算出来的下行波动,统计上几乎没有意义,却经常是报告里最亮眼的那一行;而「区间内一次没跌」还可能因为兜底逻辑被显示成天文数字般的高分。样本量应该和指标一起被报出来——不报样本量的风险指标,等于不报分母的百分比。

失效边界与常见误用

把「下行」等同于「亏钱」。 只有门槛画在零上时这句才成立。门槛一旦挪到无风险利率或你的目标收益上,「赚得不够多」也是下行。看指标先确认线在哪。

以为它比夏普「更正确」。 它只是更符合你的感受。感受和真相是两件事:对称波动率把上涨也当风险确实反直觉,但它至少用满了样本,估计更稳。合理的做法是两个一起看,而不是用一个替掉另一个:一个用满样本但对涨跌不分,一个贴近感受但样本减半,各补各的死角。

用它替代最大回撤。 前面说过,它对顺序失明。真正决定你会不会在半路割肉离场的,是连续下跌堆出来的那个坑的深度和长度,不是坏日子的平均程度。

在几个月的样本上算它。 下行样本本来就是全样本的一小部分,几个月的数据里可能只有十几个下跌日,得出的数字随便一个极端日就能翻倍。至少要覆盖一次像样的下跌,这个指标才开始有话语权。

忘了它是在扣完成本之后算的。 手续费、滑点这些成本,会把一堆「小赚」推到门槛线以下,凭空制造出下行样本。成本口径松一点,下行风险就小一点——这条通道比大多数人想的更宽。

小结

  • 下行风险的动机没毛病:上涨的意外不该扣分。 但「往下」不是一个自明的概念,它由三个人为口径拼出来——门槛画在哪、除以几个数、量的是离门槛多远还是彼此有多散。
  • 工程里最常见的写法是「筛出负的、求个标准差」,它悄悄换掉了后两个口径:跌得少不再算优点,量的变成了亏损之间的分散度。后果是一套稳定失血的方法可能被打成满分
  • 教科书写法把不跌的日子当零保留在分母里,所以「跌得少」是加分项;两种写法算同一段净值,数字可以差出好几倍,名字却一样。
  • 边界情况上,不同系统的兜底方向甚至相反:一边把「查不出下行」判为可疑,一边把它显示成天文数字般的高分。样本量必须和指标一起看。
  • 有的系统(qlib)干脆不提供这个指标,用最大回撤表达「往下有多疼」——因为下行波动对坏日子的先后顺序完全失明,而顺序恰恰是人扛不住的那部分。

一句话记住这篇:「只算跌的那部分」听着公平,可「从哪算起、除以几个数」是人定的,换个定法,同一段账户能从满分变及格。

本文所引源码均来自上述快照版本,是阅读代码得出的机制说明,不是运行结果;具体行为请以你手上那个版本为准。回 量化与 AI 投研概念库 看其它概念各自在说什么;本站内容为投资教育,不构成任何投资建议,边界见 免责声明

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

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