← 返回文章列表
June 29, 2026
5 分鐘閱讀

Deflated Sharpe Ratio:你回測裡的'贏家',有多少能扛過多重檢驗?

#演算法交易
#回測
#過擬合
#統計學
#夏普比率
#多重檢驗
#驗證
🎯
Part 7 of 9 · 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 交易見解、市場分析和平台更新。

我們尊重您的隱私。您可以隨時退訂。