← 返回文章列表
July 2, 2026
5 分钟阅读

Deflated Sharpe Ratio:你回测里的'赢家',有多少能扛过多重检验?

Deflated Sharpe Ratio:你回测里的'赢家',有多少能扛过多重检验?
#算法交易
#回测
#过拟合
#统计学
#夏普比率
#多重检验
#验证
🎯
Part 6 of 7 · Collection
Backtesting Without Fooling Yourself

"回测无幻觉"系列文章。

📄 本文成长为了一篇研究论文。 以下每一个数字都来自同一个确定性脚本,它构建了受控的真实基准——纯噪声搜索、植入优势的搜索,以及一个真实的相关参数网格——然后对其运行 Deflated Sharpe Ratio、Harvey-Liu 多重检验折价法,以及 White's Reality Check / Hansen's SPA,直接测量每种方法的假发现率与检验功效。可在线阅读论文(交互版 + PDF):deflated-sharpe.marketmaker.cc,代码与数据见 github.com/suenot/deflated-sharpe-search

你跑了一次参数扫描。十六种快线长度,四十种慢线长度,一条移动平均线交叉策略的 640 种组合。网格跑完,有一个格子在发光:年化夏普比率 3.9,单次检验 p 值 6×10126\times10^{-12}。十二个零的显著性。你发现了点什么。

又或者,你什么都没发现,是搜索替你"发现"了它。

参数搜索不是一次检验。它是一台专门找出 N 次尝试中最幸运那一次的机器,你给它的尝试越多,它的赢家看起来就越幸运——无论底下是否真的有优势。best-of-N 的夏普比率因选择而被虚高,其原理就跟一千个随机路人里最高的那个人显得特别高一样:不是因为"高"是真的,而是因为你搜索过了。印在赢家旁边的单次检验统计量——它的 p 值、它的 t 统计量、它那个"这显著吗?"——本来是为一个预先注册好的假设设计的。把它们喂给一次搜索的幸存者,它们每次都会自信满满地撒谎。

本文精确测量它们撒谎撒得有多严重,然后测量三种能修正它的工具。整件事的核心在于受控的真实基准:我们生成一些我们已知答案的收益序列——有时是真实优势为零的纯噪声,有时是强度已知的植入优势——这样"这种方法判断对了吗"就是一个事实,而不是一个主观判断。先把结论摆在前面。在已知零假设的搜索上——诚实的答案永远是"没有发现"——每种检验各自"狼来了"的频率如下:

检验 已知零假设搜索上的假发现率 结论
朴素检验"最佳夏普比率显著吗?" 1.000 每一次都宣布发现
Deflated Sharpe Ratio(DSR ≥ 0.95) 0.001 得到控制
Harvey-Liu 折价法——Bonferroni 0.057 基本得到控制
Harvey-Liu 折价法——Holm 0.057 基本得到控制
Harvey-Liu 折价法——BHY 0.007 得到控制
White's Reality Check(自助法) 0.022 得到控制

每次搜索 1,000 个策略,每个策略 1,000 次观测,2,000 次独立的零假设搜索,处处真实夏普比率 = 0。合成的独立同分布正态收益,种子 0,α = 0.05,每年 252 个周期。朴素检验的假发现率不是"偏高"——而是正好等于一

把第一行盯着看,直到它刺痛你为止。一个本应在纯噪声上以 5% 的频率触发的检验,实际触发频率是 100%——因为你给它看的不是纯噪声,而是一千次纯噪声抽取里的最大值,而一千个抛硬币的人里最靠运气的那个,看起来永远像个天才。其余每一行都是懂得这一点并对此做出修正的方法。这就是本文的全部内容:为什么第一行是 1.000,为什么其他行不是,以及唯一一处(最后一节)连好的方法也需要第二次修正才能保持诚实。

第 1 幕——陷阱:搜索凭空制造出夏普比率

一台参数搜索被描绘成一台老虎机,把一千条随机策略曲线灌进一个漏斗,唯有最幸运的那一条曲线钻出来,标着一个诱人的夏普比率,其余被淘汰的曲线在它身后褪成噪声

从最干净的那种陷阱开始。生成 N=1000N = 1000 个策略,它们的收益是相互独立的标准正态噪声——没有漂移,没有技巧,全部真实夏普比率恰好为零。每个策略有 T=1000T = 1000 次观测。现在做每个参数搜索都会做的事:只留下最好的那个。

best-of-1000 的单期夏普比率平均为 0.1027,年化后为 1.63(推算:0.1027×2521.630.1027 \times \sqrt{252} \approx 1.63)。这可不是个不起眼的数字。年化夏普比率 1.63,是那种能让一个策略拿到资金、被写成报告、被实际配置资金的成绩。而它来自一台把漂移项调到零的随机数生成器。

现在把这个赢家交给朴素显著性检验——就是每个回测库都免费打印出来的那种。把它的夏普比率换算成 t 统计量(t=SR^Tt = \hat{SR}\sqrt{T}),取单侧 p 值,如果 p<0.05p < 0.05 就宣布为一次发现:

t=SR^T,p=1Z(t),"discovery" if p<αt = \hat{SR}\sqrt{T}, \qquad p = 1 - Z(t), \qquad \text{"discovery" if } p < \alpha

这些噪声赢家的单次检验 p 值中位数是 0.000686——一个毫无优势的策略,却拿到了三个零的"显著性"。而在 2,000 次独立的零假设搜索中,朴素检验在每一次都宣布了发现:假发现率 1.000。不是"偏高"。不是"有点高"。一个按构造在单一零假设上最多 5% 的时候会判对的检验,在一次搜索的赢家身上却 100% 判错。

这台机器一旦被点名,运作机制就不再神秘了。朴素检验问的是"在零假设下,这个夏普比率会不会纯粹出于偶然?"——如果你是在看数据之前就选中了这个策略,这是个公平的问题。但你选中它,恰恰是因为它是一千个里夏普比率最高的那个。你是在对最大值做条件,而最大值的抽样分布和单次抽取的抽样分布完全是两回事。这和我们的前视偏差分类法从另一端诊断出的其实是同一种病——那篇文章里,一根 K 线的泄漏就从噪声中凭空制造出 15 的夏普比率;这里,一次搜索完全没有任何泄漏,纯靠选择,就从噪声中制造出 1.63 的夏普比率。机制不同,症状一模一样:一个看起来很棒、却毫无意义的夏普比率。

1.63 这个数字很重要,记住它。它是这次搜索的噪声上限:1,000 个零优势策略中最幸运的那个,理应报出的夏普比率。任何对搜索赢家的诚实检验,都不该拿它去跟零比,而要拿它跟这个数字比——跟你看一千次之后,单靠运气就能拿到的东西比。

第 2 幕——工具箱:给搜索定价的三种方法

工作台上摆着三件测量仪器,全都对准同一个虚高的夏普比率数字:一个把基准线往下压的去膨胀仪表、一把带刻度的折价剪刀,以及一个不断甩出收益序列众多影子副本的自助法重采样轮

三条各自独立发展出来的研究路线,最终都得出同一个修正办法:不要再拿赢家去跟零比,而要拿它跟"这个规模的搜索单靠运气能产出什么"去比。它们的差异在于各自如何构建这个比较对象。

PSR 与 Deflated Sharpe Ratio(Bailey & López de Prado,2012 / 2014)

**Probabilistic Sharpe Ratio(概率夏普比率,PSR)**问的问题,比"夏普比率是不是正的?"要犀利得多。它问的是:给定样本长度和收益分布的形状(偏度、肥尾),真实夏普比率超过某个基准 SRSR^*概率是多少?

PSR(SR)=Z ⁣((SR^SR)n11γ^3SR^+γ^414SR^2)\text{PSR}(SR^*) = Z\!\left( \frac{(\hat{SR} - SR^*)\sqrt{n-1}}{\sqrt{\,1 - \hat\gamma_3\,\hat{SR} + \frac{\hat\gamma_4 - 1}{4}\,\hat{SR}^2\,}} \right)

这里 ZZ 是标准正态分布的 CDF,γ^3\hat\gamma_3 是偏度,γ^4\hat\gamma_4非超额约定下的峰度(正态分布 ⇒ γ^4=3\hat\gamma_4 = 3;如果这里直接代入超额峰度而不加 3,折损结果就会算错)。令 SR=0SR^* = 0,PSR 就只是一个有限样本显著性检验。真正的魔法在于把 SRSR^* 选好。

Deflated Sharpe Ratio(DSR)就是把 PSR 的基准从零换成整次搜索的期望最大夏普比率后算出来的结果:

SR0=Var[{SRn}]  ((1γ)Z1 ⁣(11N)  +  γZ1 ⁣(11Ne))SR_0 = \sqrt{\operatorname{Var}[\{SR_n\}]}\;\Big(\,(1-\gamma)\,Z^{-1}\!\big(1 - \tfrac{1}{N}\big) \;+\; \gamma\,Z^{-1}\!\big(1 - \tfrac{1}{N e}\big)\Big)

这里 Var[{SRn}]\operatorname{Var}[\{SR_n\}]全部 N 次试验夏普比率的方差(也就是搜索本身产生的离散程度),γ0.5772\gamma \approx 0.5772 是欧拉-马歇罗尼常数,两个逆正态项则是对 NN 次标准正态抽取的期望最大值的极值理论(Extreme-Value-Theory)近似。写成代码短得都不够拿出来炫耀:

def expected_max_sharpe(sr_variance, N, mean_sr=0.0):
    """E[max of N independent SR estimates ~ N(mean_sr, sr_variance)]
    (Bailey & LdP 2014)."""
    g = EULER_MASCHERONI                       # 0.5772156649
    a = norm.ppf(1.0 - 1.0 / N)                # Z^{-1}(1 - 1/N)
    b = norm.ppf(1.0 - 1.0 / (N * E))          # Z^{-1}(1 - 1/(N e))
    return float(mean_sr + np.sqrt(sr_variance) * ((1.0 - g) * a + g * b))

然后 DSR 就只是用这个折损后的基准算出的 PSR:

def deflated_sharpe(sr_max, sr_estimates, T, skew=0.0, kurt=3.0, N=None):
    """DSR = PSR(sr_max, SR0). Returns (dsr, sr0)."""
    v = float(np.asarray(sr_estimates).var(ddof=1))   # dispersion of the search
    m = float(np.asarray(sr_estimates).mean())
    if N is None:
        N = len(sr_estimates)
    sr0 = expected_max_sharpe(v, N, mean_sr=m)
    return psr(sr_max, sr0, T, skew, kurt), sr0

DSR 本身是一个概率。当 DSR1α=0.95\text{DSR} \geq 1 - \alpha = 0.95 时,我们宣布一次发现:赢家的真实夏普比率以 95% 的置信度超过了运气所能给出的最佳预期。注意 SR0SR_0 里埋着一个承重的假设:这 NN 次试验被当作相互独立。第 5 幕整节讲的就是当它们并不独立时会发生什么。

Harvey-Liu 折价法(2015)

Harvey 和 Liu 从多重检验 p 值修正的角度攻克同一个问题——这是那套经典机制的用武之地:"我跑了 M 次检验,别让我自己骗自己"。把 MM 个单次检验 p 值排序为 p(1)p(M)p_{(1)} \le \dots \le p_{(M)},然后把它们放大:

piBonf=min[Mp(i),1],piHolm=min ⁣[maxji{(Mj+1)p(j)},1]p_i^{\text{Bonf}} = \min[\,M\,p_{(i)},\,1\,], \qquad p_i^{\text{Holm}} = \min\!\Big[\max_{j\le i}\{(M-j+1)\,p_{(j)}\},\,1\Big]

Bonferroni 是那件笨重的工具(把每个 p 值都乘以 MM,控制任意假阳性的概率);Holm 是它那个功效一致更高的降阶版本。第三种,Benjamini-Yekutieli(BHY),控制的是假发现率——你的拒绝结果里预期有多大比例是错的——而且关键在于,它在检验之间存在任意依赖关系的情况下依然成立,靠的是分子里的调和归一化项:

c(M)=j=1M1j,c(1000)7.49c(M) = \sum_{j=1}^{M} \frac{1}{j}, \qquad c(1000) \approx 7.49

c(1000)=7.49c(1000) = 7.49 这个数,就是 BHY 为了不去假设你那 1,000 次试验相互独立所付出的代价——它把 FDR 阈值放大了一个按 lnM\ln M 增长的倍数。"折价"本身才是那个点睛的指标:把修正后的 p 值换算回夏普比率,报告出你不得不从原始夏普比率里削掉多少。折价 100% 意味着赢家完全可以用多重检验来解释;15% 意味着它基本上还站得住。

White's Reality Check 与 Hansen's SPA(2000 / 2005)

第三种工具完全不做任何分布假设。White 的 Reality Check 拿每条规则的真实收益,构造出规则间取最大值的统计量,然后直接对它的零假设分布做自助法:

RCT=maxk=1,,KTfˉkRC_T = \max_{k=1,\dots,K} \sqrt{T}\,\bar{f}_k

这里 fˉk\bar{f}_k 是规则 kk 相对基准的平均表现。它用平稳自助法(Politis-Romano——随机长度的分块,让序列相关性在重采样中得以保留)对收益重采样,把每次抽取重新居中,使其按构造满足零假设,在每次抽取上重新计算最大值,并把 p 值报告为超过观测最大值的自助法最大值所占的比例。Hansen 的 SPA 从两个方向锐化了 RC:学生化(把每条规则的均值除以它自己的标准误,这样一条方差异常大的规则就没法劫持最大值)以及对零假设做一次一致的、依赖样本的重新居中。我们的实现加上了学生化,但没有做完整的一致重新居中步骤——所以本文中出现的任何 SPA 式p 值,都应读作学生化的 Reality Check,而不是完整的 Hansen SPA。DSR 问的是"这个赢家在这次搜索内部是不是特别?",Reality Check 问的则是"在诚实地把我试过多少条规则算进去之后,最好的那条规则还能不能跑赢现金?"——而且它通过自助法天然地处理了规则之间的相关性,完全不需要去数试验次数。记住这个区别;最后一节就建立在它之上。

第 3 幕——校准就是全部的证明

一张校准图,一根柱子高耸在假发现率为一的位置,与另外五根被死死钉在百分之五 alpha 水平附近的矮柱子形成对比,一条水平参考线标出噪声上限夏普比率一点六三

一个什么都不宣布发现的方法,假发现率也会是零——但它毫无用处。所以,检验这些工具唯一有意义的方式是双面的:在已知零假设的数据上,它们必须把假发现率控制在 α\alpha 或以下;在已知优势的数据上(下一节),它们依然得能触发。本节讲的是前半部分。

跑 2,000 次独立搜索,每次都在 1,000 个零优势策略上进行,统计每种方法宣布发现的次数。这个次数除以 2,000,就是假发现率——而因为真相是没有优势,所以每一次"发现"都是假的:

检验 假发现率(α = 0.05)
朴素显著性检验 1.000
Deflated Sharpe Ratio 0.001
Harvey-Liu——Bonferroni 0.057
Harvey-Liu——Holm 0.057
Harvey-Liu——BHY 0.007
White's Reality Check 0.022

每种有理论依据的方法都落在 5% 这条线上或附近——两个 FWER 折价法略高一点,DSR/BHY/RC 略低一点——而朴素检验则停在 100。(Bonferroni 和 Holm 在这里打印出一样的 0.057,这不是巧合:对于单一的最佳策略而言,Holm 的第一步是 (M1+1)p(1)=Mp(1)(M-1+1)\,p_{(1)} = M\,p_{(1)},按构造就和 Bonferroni 完全相同,所以这是同一个确认,而不是两个独立确认。)但整项研究里最深刻的数字不在这张表里——而是产出 DSR 那一列的折损基准。在各次零假设搜索上取平均,SR0SR_0 算出的单期值是 0.1030,年化后为 1.63(推算:0.1030×2521.630.1030 \times \sqrt{252} \approx 1.63)——正是噪声赢家平均报出的那同一个 1.63(1.63)。这不是巧合;这正是整个想法在起作用:

折损后的基准线,恰好就落在噪声上限上。 DSR 并不要求搜索赢家去打败零。它要求赢家打败单靠运气、从这个规模的搜索里所能拿到的最好成绩——这里就是年化 1.63。一个刚好打平噪声上限的赢家,DSR 得分 ≈ 0.5(跟抛硬币一样),这就是为什么零假设下的平均 DSR 是 0.495,而不是一个很小的数。要成为一次真正的发现,赢家必须打穿 1.63 而且还要多出不少——多到足以把 PSR 推过 0.95。

这重新定义了整件事。朴素检验衡量的是离零有多远;任何一次搜索都能轻而易举地跨过这道坎,这就是它没用的原因。DSR 衡量的是离噪声上限有多远,而跨过这道坎才是真正困难的——本来就该如此。Harvey-Liu 折价法和 Reality Check 走的是不同的路,却达到了同样的控制水平(BHY 用 c(1000)=7.49c(1000)=7.49 的放大系数,RC 用自助法给出的最大值分布),最终都落在同一个区间里:0.001 到 0.057,处在 α\alpha 或其附近。Bonferroni/Holm 的 0.057 比 5% 这条线略高一点点,但也就一点点:在 2,000 次蒙特卡洛搜索的规模下,FDR 估计值在 0.05 附近的标准误约为 0.005,所以 0.057 大约高出 α\alpha 1.4 个标准误——这是蒙特卡洛噪声,不是保证失灵。而且"控制 FWER"本来就是一个渐近意义上的承诺,在 T=1000T = 1000 时并不是逐比特精确的。

第 4 幕——功效:它还留得住真实的优势吗?

一条 S 形的检验功效曲线,随着横轴上植入的真实夏普比率增大而从接近零升到一,一条垂直虚线标出噪声上限夏普比率一点六三,曲线在这条线右侧不远处就爬到了百分之五十的功效,而一条平坦的假阳性率曲线则被死死钉在地板上

控制假发现只是检验的一半——一个疑神疑鬼、什么都拒绝的方法能拿到满分 0.000,却毫无用处。另一半是:当真实优势确实存在时,DSR 找得到它吗?

植入一个优势试试。在 1,000 个策略组成的一片田地里,让其中 25 个带上强度已知的真实优势,其余留作噪声,然后跑搜索,看 DSR 会不会标出这个赢家。把植入的优势从弱到强扫一遍,检验功效画出一条干净的 S 形曲线(假阳性率全程维持在 ~0):

植入的真实夏普比率(年化) DSR 检验功效 DSR 假阳性率
0.79 0.005 0.000
1.27 0.090 0.000
1.90 0.651 0.000
2.54 0.998 0.000
3.17 1.000 0.000

看看曲线在哪里转折。低于噪声上限时——真实年化夏普比率 0.79,远低于 1.63——DSR 只有 0.5% 的时候会触发,正确地拒绝承认它:这么弱的优势,跟一次 1,000 次试验的搜索所产生的运气,真的分辨不出来,硬说能分辨出来,不是功效强,而是不诚实。刚过上限附近,曲线陡峭爬升(1.27 处 0.09,1.90 处 0.65)。到年化夏普比率 2.54 时,功效是 0.998;到 3.17 时是满分的 1.000。强优势基本每次都能被留住,假阳性率始终钉在零,而 50% 功效的交叉点落在年化夏普比率约 1.73 处(由 1.27 与 1.90 两行插值推算)——刚好高于 1.63 的噪声上限,正是一条诚实的基准线该落在的地方:优势开始跑赢一次 1,000 次试验的搜索所能凭空捏造出来的东西的那个点。

这才是你真正想要的性质,用 S 曲线来表述就是:噪声上限以下的优势被正确地判定为运气;舒舒服服高于上限的优势则以逼近一的功效被留住。 相比之下,朴素检验即便在真实夏普比率只有 0.79 时也能"检测"到 67% 的植入优势——但这个数字毫无意义,因为我们已经看到它对一个根本不存在的优势也能 100% 地"检测"到。一个什么都触发的检验没有功效可言;它没有任何区分能力。DSR 用一点点对边缘优势(0.79 和 1.27 那两行)的敏感度,换来了真正重要的东西:它给出的发现是真的。

第 5 幕——从业者的陷阱:相关网格

一张移动平均线交叉结果的参数网格热力图,相邻格子之间闪耀着强烈的两两相关性,旁边是一条横轴,列出五种不同的有效试验数估计,跨度从约两个到接近四百个,一条阴影稳健性带显示真实优势在几乎整个区间内都跨过了折损基准,只有最右侧那个过度计数的估计让它跌到基准之下

目前为止用的都是相互独立的策略——这是最干净的设定,也是 DSR 的独立性假设完全成立的那种设定。真实的参数网格可不是这样,而这正是一个工具一旦被天真地使用,就会变成一种新的犯错方式的地方。

拿一次诚实的移动平均线交叉搜索来说:16 种快线长度 ×\times 40 种慢线长度 =640= 640 次试验,每次 755 次观测。这样一个网格浸透了相关性——fast=45/slow=120 和 fast=45/slow=125 几乎是同一个策略,它们的收益序列会一起动。实测 640 次试验间的平均两两相关性:约 0.61。这可不是 640 次独立的赌注。差得远了。

案例 A——随机游走(无优势):每种方法都正确地否决了它

在纯随机游走上跑这个网格。赢家看起来很诱人:参数 fast=45/slow=120,最佳年化夏普比率 0.81,单次检验 p 值 0.081。每种方法都识破了它:

方法 结果 结论
DSR(原始 K = 640) 0.431 否决(< 0.95)
Reality Check p 0.570 否决
SPA 式 p(学生化 RC) 0.569 否决
Harvey-Liu 折价法 100% 否决

先看这个根本不需要任何折损就露出破绽的信号:即便是这个赢家未经修正的有限样本显著性,也就是 PSR\text{PSR} 相对零的检验,也只有 0.918——在我们对 640 次试验中的哪怕一次做修正之前,就已经够不上 0.95 了。折损之后,它就彻底被埋了:基准是单期 SR0=0.057SR_0 = 0.057,年化约 0.91(推算:0.057×2520.057 \times \sqrt{252})——高于赢家的 0.81。这个最佳策略连噪声上限都够不着,DSR ≈ 0.43(比抛硬币还差),而 Reality Check、SPA 式检验和 100% 的折价率全都一致:这里什么都没有。完美。这是简单的那个案例,而它奏效了——正如我们接下来会看到的,无论我们尝试哪个有效试验数,它都始终被否决。

案例 B——一个真实的状态优势:原始 DSR 判

现在在一个带有真实、可利用优势的状态切换序列上跑同一个网格。赢家的信号非常强烈:参数 fast=3/slow=55,最佳年化夏普比率 3.92——这是样本内、经过挑选的夏普比率,本身就被搜索的选择效应抬高了(不是一个真实或样本外的优势),但底层的状态效应是真实的——单次检验 p 值为 6×10126\times10^{-12},未折损的显著性 PSR\text{PSR} 相对零基本为 1.000。这里确实有一个真实的优势,赢家也找到了它。看看原始 DSR 还是照样否决了它:

方法 结果 结论
DSR(原始 K = 640) 0.748 否决(< 0.95)✗ 过度折损
Reality Check p 0.0024 确认 ✓
SPA 式 p(学生化 RC) 0.0038 确认 ✓
Harvey-Liu 折价法 15% 确认 ✓

原始 DSR 的 0.748 是对一个真实优势的假否决。原因就是独立性假设,这里被狠狠违反了:DSR 在构建折损基准时,把 640 次相关试验当成了 640 次独立抽取,这把期望最大值 SR0SR_0 抬高到了单期 0.221——年化约 3.51(推算:0.221×2520.221 \times \sqrt{252})。相对于 3.51 这道基准,赢家的 3.92 只是勉强越过,DSR 落在 0.748——够不上 0.95。有两个因素在把基准往上推:一是原始试验数(640 次"看",而不是少数几次有效的),而且试验之间还存在真实的技巧离散——有些参数组合在状态序列上确实表现更好,这拓宽了 Var[{SRn}]\operatorname{Var}[\{SR_n\}],把 SR0SR_0 抬到了纯粹靠运气所能达到的水平之上。两个因素朝同一个方向发力,基准最终被推得太高,因为这次搜索从来就不是真正的 640 次独立"看";它其实是少数几个独立的赌注,被重复采样了 640 次。

该给 DSR 喂的是有效试验数。上面用到的这个一行代码,是从平均两两相关性得出的一个粗略估计:

def effective_n_trials(returns_matrix):
    """N_eff = N / (1 + (N-1) * rho_bar), clipped to [1, N].
    Correlated trials -> fewer independent bets."""
    C = np.corrcoef(returns_matrix, rowvar=False)
    rho_bar = max(np.nanmean(C[np.triu_indices(C.shape[0], k=1)]), 0.0)
    N = returns_matrix.shape[1]
    neff = N / (1.0 + (N - 1) * rho_bar)
    return float(min(max(neff, 1.0), N))

ρˉ0.62\bar\rho \approx 0.62N=640N = 640 代入,网格就坍缩成了有效 Neff1.6N_{\text{eff}} \approx 1.6 次试验(推算:640/(1+639×0.62)640 / (1 + 639 \times 0.62)),DSR 随之跳到 1.000。但先别急着为这个数字欢呼,因为它是本节全部证据里最弱的一个。在 Neff1.6N_{\text{eff}} \approx 1.6 时,折损基准会坍缩成年化 SR00.25SR_0 \approx 0.25——基本上就是试验均值,基本上等于零。这里的折损其实是被关掉了Neff1.6N_{\text{eff}} \approx 1.6 处的 DSR,不过是在重新报告赢家未经折损的有限样本显著性(PSR\text{PSR} 相对零 =1.000= 1.000)而已。这个结论是从原始显著性继承来的,而不是由多重检验修正产生的。随机游走那边也有一个对称的警示:它在 Neff1.6N_{\text{eff}} \approx 1.6 处被否决,仅仅是因为那个赢家一开始独立来看就已经很勉强了(PSR\text{PSR} 相对零 =0.918<0.95= 0.918 < 0.95)。如果把整个论证都押在 1.6 这个数字上,一个怀疑者完全有理由耸耸肩:你只是把修正关掉了,然后报告了底下原本就有的东西。

所以不要把论证押在单一一种估计方法上。诚实的做法——也是更有说服力的做法——是用五种不同的标准方式计算 NeffN_{\text{eff}},然后通读整条区间上的结论。下面是把五种估计方法应用到同一个 640 次试验的信号网格上,各自对应的折损基准和产出的 DSR:

有效试验数估计法 NeffN_{\text{eff}} 折损基准 SR0SR_0(年化) DSR 结论
平均相关性 1.6 0.25 1.000 保留
参与率 2.4 0.43 1.000 保留
PCA(95% 方差) 16 1.85 1.000 保留
Kaiser 准则(特征值 > 1) 21 2.00 0.999 保留
Cheverud-Nyholt 370 3.31 0.845 否决
原始网格计数(不修正) 640 3.51 0.748 否决

估计方法说明:平均相关性就是上面那个 N/(1+(N1)ρˉ)N/(1+(N-1)\bar\rho) 的一行公式;参与率 (λi)2/λi2(\sum\lambda_i)^2/\sum\lambda_i^2 以及 PCA-95%/Kaiser 计数,都是从相关矩阵的特征值中读出有效维度;Cheverud-Nyholt 是来自遗传学文献的一种特征值方差估计法,已知在接近等相关时会过度计数。

现在重点才真正落地,而这个重点并不是"随便什么修正都能救你"。看看那个站得住脚的中段——PCA-95%(Neff=16N_{\text{eff}} = 16)和 Kaiser(Neff=21N_{\text{eff}} = 21)。这两个不属于折损被关掉的那种情形;它们施加的是一道真实的年化 SR0SR_0 基准,1.85 到 2.00——一次实实在在的折价,远高于噪声,是对 16-21 次有效"看"的真正多重检验惩罚。而 3.92 这个优势依然跨了过去(DSR 1.000 和 0.999)。只要 NeffN_{\text{eff}} 低于 144.8(从交叉点推算),这个信号在任何估计下都能扛过 DSR;只有在 Cheverud-Nyholt 给出的 Neff=370N_{\text{eff}} = 370 下才会失败——而这个估计法在试验接近等相关时被证明会过度计数——即便是那个原始、未经修正的 640 计数,也只是把 DSR 压到 0.748,而不是压到零。把随机游走的赢家放进同样这五种估计法里跑一遍,它在每一种估计下都被否决(找不到任何一个高于 1 的 NeffN_{\text{eff}} 能让它活下来)。这才是真正的结果:不是靠一个幸运的数字,而是一个在整条标准有效试验数估计区间上都稳定的结论——这比只相信其中任何一个数字都要强得多。

关于那个最粗糙的估计法,还有一个技术性的警示,它解释了为什么这个估计法处在软弱的那一端:N/(1+(N1)ρˉ)N/(1+(N-1)\bar\rho) 本质上是相关变量均值的方差缩减因子(在相关性 ρˉ\bar\rho 下,取平均究竟能给你带来多少好处)。而 DSR 的基准是一个极值量——试验的期望最大值——所以拿一个均值方差收缩量当作试验数,在功能上是不匹配的:方向是对的(相关性越强 ⇒ 有效试验数越少),但它并不是最大值分布实际依赖的那个量。这正是为什么区间中段那些基于特征值的估计法读数更值得信赖,也正是为什么真正应该交付的是这整条区间,而不是某一个点。

教训:两种工具都要用,还要喂给 DSR 正确的 N

两件互补的仪器从不同角度对准同一个搜索赢家:一件标着问题"这个赢家在这次搜索内部是不是特别",需要一个有效试验数旋钮;另一件标着"数据窥探之后最好的那个还能不能跑赢现金",由一个直接从数据里读出相关性的自助法驱动

案例 B 得出两条结论,两条都承重:

  1. 只要试验之间存在相关性,原始网格规模对 DSR 来说就是错误的 N——而单独任何一个有效 N 也都不是正确答案。 把 640 代入一个假设独立性的公式会过度折损:它捏造出一个远高于搜索实际达到的噪声上限,把真实优势埋在了它底下。DSR 需要的是有效试验数——但修正的办法不是去相信某一个估计法(尤其不是那个最粗糙的、在 Neff=2N_{\text{eff}} = 2 附近就把修正关掉了的那个)。而是要通读整条标准估计法组成的区间(这里是 1.6 到 370),看看结论是否稳定。对这个优势而言,结论是稳定的:在折损真正起作用的每一处都被保留下来(在 Neff=16N_{\text{eff}} = 16-2121 处有一道真实的年化 1.85-2.00 基准),只在一种会过度计数的估计法下才失败。一个在整条区间上都稳定的结论,比任何单一数字都要有说服力得多。
  2. 把 DSR 和 Reality Check 配对使用。 注意到 Reality Check 及其 SPA 式(学生化)表亲,完全没有对试验数动任何手术,就在案例 B 上判对了(p = 0.0024 和 0.0038)——它们通过平稳自助法天然地处理了依赖关系,因为它们重采样的是真实的、相关的收益序列,而不是去数假想中的独立赌注数量。这就是整个有效 N 乱局的裁决者:RC 根本不需要 NN。DSR 和 RC 回答的是不同的问题:DSR 问的是"这个赢家在这次搜索内部是不是特别?"(需要知道这次搜索到底进行了多少次有效的"看");RC/SPA 式问的是"数据窥探之后,最好的那条规则还能不能跑赢现金?"(并直接从数据本身读出依赖关系)。这两个你都需要。当它们意见不一致时——就像这里原始计数的 DSR 和 RC 那样——这种分歧本身就是诊断信号:它通常意味着你的 NN 错了。

这和我们的速度阶梯IPC 税两项研究从工程一侧不断撞上的,是同一个结构性警示——一次跑了巨大相关网格的快速搜索,并不能给你买来数量巨大的独立赌注,把网格规模当成试验数会同时骗过你的优化器和你的显著性检验。即将发布的姊妹篇回测过拟合概率从重采样一侧(CSCV)攻击的是同一种选择偏差,也和这里的一切自然配对:DSR 给赢家定价,PBO 给流程定价。

诚实说明

三条直白说出来的警示,因为一项受控研究的全部意义,就在于不要把它过度包装。

  • 这些收益是合成的。 校准和功效实验用的是独立同分布正态分布,真实优势案例用的是状态切换过程——这么选是为了受控的真实基准,不是为了贴近真实市场。真实收益是肥尾的、自相关的、非平稳的,而 PSR 的偏度/峰度项,存在的目的正是为了处理这三者中的第一个。这里交付的是经过校准的方法,而不是一个策略:我们只能通过在一份已知什么都没有可发现的数据上运行一个检验,来证明它确实控制了假发现。而这就需要人为构造出真实基准。
  • 没有哪种有效 N 估计法是权威标准——这正是我们报告了五种的原因。 平均相关性那个一行公式 Neff=N/(1+(N1)ρˉ)N_{\text{eff}} = N/(1 + (N-1)\bar\rho) 便于审阅者理解,方向也是对的(相关性越强 ⇒ 有效试验数越少),但它是均值的方差缩减因子——在功能上与 DSR 的最大值基准不匹配——而且在 Neff<2N_{\text{eff}} < 2 附近会把折损完全关掉。基于特征值的估计法(参与率、PCA-95%、Kaiser)匹配得更好,但依然是启发式的,而 Cheverud-Nyholt 在等相关下会过度计数。更完整、更有理论依据的做法是试验聚类(Bailey & López de Prado 的 DSR 附录 3):按相关结构对试验分组,数聚类数而不是把一切都坍缩成一个标量。我们报告整条区间,正是因为这个选择本身还没有定论——一个在全部五种估计法下都稳定的结论才是诚实的主张;一个依赖于挑选某一种估计法的结论则不是。
  • 这里的自助法是学生化的 Reality Check,不是完整的 Hansen SPA,而且不同实验的重采样次数不一样。 本文中出现的"SPA 式",指的都是带有逐规则学生化的 White's Reality Check;Hansen 那套完整的一致、依赖样本的重新居中并没有实现。校准实验的假发现率,用的是 400 次搜索、每次搜索 500 次平稳自助法重采样;两个案例研究里的 RC/SPA 式 p 值,各自用了 5,000 次重采样。平均分块长度全程为 20(Politis-Romano),α=0.05\alpha = 0.05,年化按每年 252 个周期计算。改变这些设置,小数点第三位的数字会变;但故事本身——朴素检验的 1.000 对上有理论依据方法的 0.001-0.057、一条恰好在噪声上限之上就达到 50% 功效的 S 曲线,以及一个相关网格陷阱,其结论必须通读整条有效 N 区间——不会变。

要点总结

  1. 参数搜索是一台多重检验机器,而朴素显著性检验对此视而不见。 在 1,000 个零优势策略上,最佳年化夏普比率平均为 1.63,单次检验 p 值中位数为 0.000686——而"这显著吗?"这个检验100% 的时候都会宣布发现(假发现率 1.000)。一个凭空而来的漂亮夏普比率,被一个从一开始就问错了问题的检验,认证为"显著"。
  2. Deflated Sharpe Ratio 把球门从零挪到了噪声上限。 DSR 拿赢家去比的不是零,而是 SR0SR_0——这个规模的搜索靠运气所能拿到的最佳预期——在零假设情形下年化落在 1.63,正好就是噪声赢家平均所在的位置(推算:0.1030×2520.1030 \times \sqrt{252})。它在零假设下的假发现率是 0.001;Harvey-Liu 折价法(Bonferroni/Holm 0.057,BHY 0.007)和 White's Reality Check(0.022)走的是另外的路,却达到了同样的控制水平。
  3. 它留得住真实的优势。 DSR 的检验功效画出一条 S 曲线,在年化夏普比率约 1.73 处达到 50% 功效——刚好高于 1.63 的噪声上限:真实年化夏普比率 0.79 处为 0.005,1.90 处为 0.651,2.54 处为 0.998,3.17 处为 1.000,假阳性率全程 ~0。上限以下的优势被正确地判定为和运气无法区分;上限以上的优势则以逼近一的功效被留住。
  4. 相关网格会打垮原始 DSR——救它的不是某一个有效 N,而是整条区间。 在一个 640 格的移动平均线交叉网格上(平均两两相关性约 0.61),原始计数的 DSR 假否决了一个真实的(样本内挑选出来的、年化 3.92)优势(0.748 < 0.95),原因是 640 次相关试验并不是 640 次独立赌注。但修正的办法不是找出一个神奇的 NeffN_{\text{eff}}——在最粗糙的估计下(Neff1.6N_{\text{eff}} \approx 1.6),折损基本被关掉了(基准约年化 0.25),DSR 只是在附和原始显著性。真正的证据在于,这个优势在整条标准估计法的区间上都被保留——在 Neff=N_{\text{eff}} = 1.6/2.4/16/21 处 DSR 分别为 1.000/1.000/1.000/0.999,其中包括在站得住脚的 PCA-95%/Kaiser 中段处一道真实的年化 1.85-2.00 基准——只要 Neff<145N_{\text{eff}} < 145 就能存活,只在 Cheverud-Nyholt 那个过度计数的 370 下才失败。随机游走则在每一种估计法下都被否决。要读整条区间,而不是某一个点。
  5. 把 DSR 和 Reality Check 配对使用,因为它们回答的是不同的问题。 Reality Check 及其 SPA 式(学生化)表亲,没有对试验数动任何手术,就确认了这个真实优势(p = 0.0024 和 0.0038)——它们通过平稳自助法天然地处理了依赖关系,而这恰恰是当有效 N 存在争议时的裁决者。DSR 问的是"这个赢家在这次搜索内部是不是特别?";RC/SPA 式问的是"数据窥探之后,最好的那个还能不能跑赢现金?"两者之间的分歧,就是你的 NN 错了的信号。两个都要跑。

搜索的赢家在被证明清白之前,都是有罪的。朴素 p 值并不能证明清白——它是搜索自己那份被虚高了的证词,它会以十二个零的信心,为纯噪声担保。把基准折损到运气所能给出的水平,诚实地数出你的有效试验数,再用自助法对最大值求一个第二意见。能同时跨过这三道坎的,也许才是真的。只跨过朴素那一道坎的,不过是一千个抛硬币的人里最高的那一个。

完整的实验——零假设校准框架、植入优势的功效扫描、相关网格搜索,以及本文中每一个都能从同一个确定性脚本重新生成的数字——都收录在配套论文中,见 deflated-sharpe.marketmaker.cc,代码与数据见 github.com/suenot/deflated-sharpe-search

免责声明:本文提供的信息仅用于教育和参考目的,不构成财务、投资或交易建议。加密货币交易涉及重大损失风险。

Authors

Eugen Soloviov
Eugen Soloviov

Trading-systems engineer

Trading-systems engineer building bots since 2017: cross-exchange arbitrage (connected up to 30 venues), cointegration-based pairs arbitrage across spot and futures, scalping, news and sentiment-driven strategies, trend algorithms, and portfolio management and balancing algorithms. Also builds sub-millisecond order execution, big-data warehouses, backtesting engines, AI agents, and trading interfaces (incl. open-source profitmaker.cc). Stack: JS/TS, Python, Rust/Zig/Go, DevOps, backend, frontend, architecture.

Newsletter

紧跟市场步伐

订阅我们的时事通讯,获取独家 AI 交易见解、市场分析和平台更新。

我们尊重您的隐私。您可以随时退订。