同一支年化 Sharpe 1.8 的策略,校正之後可能剩 1.2,可能剩 0.5,也可能直接歸零。差別不在那支策略身上,在你之前丟掉了幾支,以及那批被丟掉的東西彼此有多像。
知道回測要校正的人不少,知道該用哪一件工具的人不多。回測校正工具不是一個方法,是一個分成兩族、至少七件的工具箱:一族在 p 值空間運作,一族直接在 Sharpe 空間運作,各自需要不同的輸入,回答不同的問題。多數人只認識其中一兩件,然後拿它去解它管不到的問題。
這篇拆五件事:七件工具的分工全表、它們共用的那個輸入(有效試驗次數)該怎麼估、p 值空間裡被忽略的第三條路、Sharpe 空間的兩種表達法,以及一條把工具串起來的研究流程。每一段都給可以自己重算的數字。
機制層的東西這裡不重複。多重測試為什麼在數學上必然生出假訊號,選擇偏誤與多重測試那篇拆過;Bonferroni、Holm、BH、SPA 的逐步算法,多重檢定校正怎麼做那篇算過。本文處理的是選型與串接。
回測校正工具分成兩族:一族在 p 值空間,一族在 Sharpe 空間
工具會挑錯,多半是因為沒有意識到它們活在兩個不同的空間裡。
p 值空間的工具吃的是各支策略的 p 值或報酬序列,吐出來的是校正後的 p 值與拒絕名單。Sharpe 空間的工具吃的是 Sharpe、樣本長度、報酬分布的形狀與試驗次數,吐出來的是折算後的 Sharpe 或一個機率。兩族處理的是同一個問題,但輸出的語言不同,能對接的決策也不同。
| 工具 | 空間 | 控制什麼 | 必要輸入 | 輸出的那句話 |
|---|---|---|---|---|
| Holm | p 值 | FWER | 各支 p 值、N | 這批入選者連一個假陽性都沒有的信心 |
| Benjamini-Hochberg | p 值 | FDR | 各支 p 值、N | 入選批次裡假陽性的期望比例 |
| Romano-Wolf StepM | p 值(bootstrap) | FWER | 全部策略的報酬序列 | 哪幾支真的贏過基準 |
| Hansen SPA | p 值(bootstrap) | 複合虛無 | 全部策略的報酬序列 | 冠軍是不是運氣 |
| Deflated Sharpe Ratio | Sharpe | 選擇偏誤+非常態 | SR、樣本長度、偏度峰度、N、試驗離散度 | 折算搜尋成本後真實 Sharpe 大於零的機率 |
| Haircut Sharpe | Sharpe | 多重檢定 | SR、樣本長度、N | 這個 Sharpe 該打幾折 |
| MinBTL | 樣本長度 | 事前的試驗預算 | 目標 SR、N 或可用樣本長度 | 這麼多次試驗至少需要多長的樣本 |
有一件常被歸進來但不屬於這裡的東西:PBO。回測過擬合機率不輸出校正後的顯著性,它輸出的是「樣本內冠軍在樣本外落到後段班的機率」。那是診斷工具,用來描述你的研究流程有多脆弱,不能拿來替一支策略背書。診斷跟校正混用,是這個領域裡很常見的一種張冠李戴。
所有工具共用同一個輸入:有效試驗次數,而這個數字多數人報錯
看那張表的「必要輸入」欄,七件工具有六件需要 N。這是整個工具箱最脆弱的地方:N 低報一個數量級,任何校正的輸出都只是裝飾。
實務上估 N 有三條路,建議三條都跑,因為它們錯的方向不一樣。
前置計數器:唯一誠實但無法查核的方法
從研究第一天開一個計數器,每碰一組參數、一個特徵定義、一個標的宇宙就加一,包含看一眼就丟的。研究結束後這個數字無法重建,人對自己丟掉的東西記憶系統性偏低。這一條的完整計數規則在選擇偏誤的六個入口那篇有清單。
它的弱點是沒有外部驗證性。除非搭配版本控制與事前登記,否則沒有人能查核你報的 N。自己交易時這是誠實問題,對外募資時是揭露問題。
折算相關結構:把 N 換成有效獨立數
計數器給的是原始次數,但 200 支高度相關的變體,在統計上遠遠不等於 200 次獨立試驗。把 200 支的報酬序列算相關矩陣、做特徵值分解,用參與比例估有效自由度:
N_eff =(Σλᵢ)² ÷ Σλᵢ²
拿一組典型的參數掃描結果跑。200 支變體的相關矩陣,特徵值總和固定等於 200,前四個吃掉 85、25、12、8,剩下 196 個平均只有 0.36。代進去算出來的 N_eff 是 5.0。你以為自己試了 200 次,統計上只試了大約 5 次。
這個差距的實際效果很大。Bonferroni 用 N=200 給的單支門檻是 0.00025,Šidák 用 N_eff=5.0 給的是 0.0103,寬了 41 倍。低報 N 會讓你把雜訊當訊號,用原始 N 取代 N_eff 則會反過來把真訊號一起殺掉。兩個方向都是錯,只是代價不同。
N_eff 的估計本身有誤差。相關矩陣是用歷史報酬估的,樣本一短,特徵值分解就不穩,算出來只能當量級參考。加密市場在這裡吃兩次虧:樣本本來就短,而且大部分幣種的報酬被同一個 beta 主導,相關矩陣的第一特徵值會吃掉絕大部分變異,讓 N_eff 看起來小得不合理。跨標的的策略宇宙,建議先把市場 beta 迴歸掉再算 N_eff。
反推法:把期望最大值公式倒過來用
第三條路不估 N,它問一個更直接的問題:要多少次獨立試驗,才能讓純雜訊平均生出我這支冠軍的成績?
Bailey 與 López de Prado 給的期望最大 Sharpe 近似式是這樣的:
E[max SR] ≈ σ_SR ×[(1 − γ)·Z⁻¹(1 − 1/N) + γ·Z⁻¹(1 − 1/(N·e))]
γ 是 Euler-Mascheroni 常數 0.5772,σ_SR 是你那批試驗的 Sharpe 橫斷面標準差,前提是試驗獨立、報酬 IID 常態、真實 Sharpe 的期望值為零。
假設你的冠軍是年化 Sharpe 2.1。把公式倒過來解:
| 試驗之間的 Sharpe 離散度 σ_SR | 讓雜訊平均生出 2.1 所需的 N |
|---|---|
| 0.5 | 約 42,000 |
| 0.75 | 約 220 |
| 1.0 | 約 32 |
同一支冠軍,離散度 0.5 時要四萬次試驗才會被雜訊解釋掉,離散度 1.0 時只要三十幾次。真正決定校正力道的變數是離散度,不是次數,而多數人從來沒算過自己那批回測的 Sharpe 標準差。
這條路有一個實用的副產品:它給你一個一致性檢查。如果反推出來的 N 遠大於你實際跑的次數,你的冠軍至少沒有被「雜訊的期望值」解釋掉;如果反推出來是 30 而你明明試了 300,後面的校正不用算了,先回去改研究設計。
p 值空間:Holm 與 SPA 之間漏掉的那件工具
p 值空間裡最常見的配置是 Holm 管小批、BH 管初篩、SPA 管冠軍。這個配置有一個洞:當你要選出的不是一支,而是一批,而且策略之間高度相關的時候,三件工具沒有一件對得上。
Holm 不需要任何相關性假設,代價是在高相關的宇宙裡系統性過罰。SPA 用 bootstrap 把相關結構帶進推論,但它只回答冠軍那一支算不算數,不告訴你第二名到第五名該不該留。
Romano 與 Wolf 的 StepM補的就是這一格。它同時做到三件事:控制 FWER、用 bootstrap 內建策略之間的聯合相依結構、逐步輸出一份名單而不只是一個是非題。
程序是這樣跑的:
- 對全部 N 支策略算相對基準的績效統計量。
- 用區塊 bootstrap 重抽整個報酬矩陣,得到「最大統計量」的虛無分布,取分位數當臨界值。
- 所有超過臨界值的策略一次全部拒絕,然後把它們從宇宙裡移除。
- 對剩下的策略重算最大統計量的臨界值,再拒絕一批。重複到某一輪沒有新的拒絕為止。
關鍵在第三步跟第四步。每移除一批已經確認的贏家,剩下宇宙的最大值分布就往下移,臨界值跟著鬆,下一輪就有機會撈出被冠軍遮住的真訊號。這是它比 Holm 有力、比 SPA 資訊量大的原因,而 FWER 的保證一路都在。
選型規則可以收成一句:要一支就用 SPA,要一批就用 StepM,兩者都要用區塊 bootstrap 而不是逐點重抽,因為報酬序列有自相關與波動聚集。區塊長度要做敏感度檢查,結論如果隨區塊長度翻面,那就不是結論。
Sharpe 空間:DSR 給機率,haircut 給折扣率
Sharpe 空間的兩件工具處理同一件事,輸出的語言不同。
DSR 輸出一個機率:折算搜尋成本、樣本長度與報酬分布的非常態之後,這支策略真實 Sharpe 大於零的信心是多少。公式與實算在把試過幾次算進顯著性那篇拆過。
Harvey 與 Liu 的 haircut Sharpe 輸出的是折扣率。它的五個步驟都可以手算:
- 把年化 Sharpe 換成 t 值,t = SR × √T(T 是年數,假設報酬 IID)。
- 把 t 值換成單尾 p 值。
- 對 p 值做多重檢定校正,得到校正後的 p。
- 把校正後的 p 換回 t 值。
- 除以 √T,得到折算後的 Sharpe。折扣率就是兩者的差距比例。
拿 3 年日資料、200 次試驗、用 Bonferroni 做第三步(最保守也最好複製的那個版本)跑一輪:
| 回測年化 Sharpe | 校正後 p | 折算後 Sharpe | 折扣率 |
|---|---|---|---|
| 1.2 | 1.00 | 0 | 100% |
| 1.5 | 0.94 | 0 | 100% |
| 1.8 | 0.18 | 0.52 | 71% |
| 2.2 | 0.014 | 1.27 | 42% |
| 2.6 | 0.0007 | 1.85 | 29% |
| 3.0 | 0.00003 | 2.37 | 21% |
這張表的形狀比任何一格的數字重要。折扣率是高度非線性的:Sharpe 3.0 只折掉五分之一,Sharpe 1.8 折掉七成,Sharpe 1.5 以下直接歸零。多重檢定校正對「勉強及格」的策略特別致命,而那正是實務上最多策略所在的區間。你看到的漂亮回測,多數死在這張表的上半段。
另外兩個維度值得單獨看。同樣 Sharpe 1.8、N=200,樣本從 3 年拉到 5 年,折扣率從 71% 掉到 37%;樣本不變、N 從 200 降到 20,折扣率從 71% 掉到 33%。加長樣本跟縮小搜尋空間,對校正結果的槓桿差不多大,而後者是你今天就能決定的事。
開頭那三個數字就是這樣來的。同一支年化 Sharpe 1.8 的策略,N=20 剩 1.2,N=200 剩 0.5,N=2000 剩 0。策略沒有變過,變的只有你在它之前丟掉了幾支。
實務上有兩件事要記得。第三步如果改用 Holm 或 BHY,折扣率會比上表溫和一些,Bonferroni 給的是上界。另外 p 值大於 0.5 時反推出來的 Sharpe 會是負的,習慣上把折扣率封頂在 100%,讀成「這個 Sharpe 在這個搜尋規模下沒有任何資訊」。
MinBTL:唯一能在動手之前用的回測校正工具
前面六件工具都是事後的。你跑完了、選完了,才拿它們來折算。第七件反過來:最短回測長度(MinBTL)在你碰資料之前就限制你能試幾次。
Bailey、Borwein、López de Prado 與 Zhu 給的最短回測長度近似式是:
MinBTL ≈ 2·ln(N) ÷ E[max SR]²
單位是年。倒過來寫更好用:給定樣本長度 T 與你期待的樣本內 Sharpe,試驗次數的上限是 N_max = e^(T·SR²/2)。
| 可用樣本 | 目標樣本內年化 SR | 試驗次數上限 |
|---|---|---|
| 2 年 | 1.0 | 3 |
| 3 年 | 1.0 | 4 |
| 3 年 | 1.5 | 29 |
| 5 年 | 1.5 | 277 |
| 11 年 | 1.0 | 245 |
表中數字建立在三個很強的假設上:試驗獨立、報酬 IID 常態、真實 Sharpe 為零。
這張表對加密市場的意思很直接。一個上線三年的標的,你想找出樣本內 Sharpe 1.5 的策略,試驗預算是 29 次。多數人一個下午就燒完了,而且是在還沒開始認真掃參數之前。
這些假設比其他六件工具都強,所以 MinBTL 給的是量級,不是證書。但它是唯一能寫進研究計畫的那一件,因為它的輸出是一個預算數字,而預算是可以事前分配的。用它決定要不要開這個題目,比事後用 DSR 判死刑便宜太多。
兩族的結論打架時,怎麼讀
兩個空間之間有一座橋:t = SR × √T。有了它,同一批策略可以同時走 p 值路線跟 Sharpe 路線,用同一個 N 交叉檢查。實務上這兩條路線經常給出不一樣的答案,而不一致本身就是資訊。
haircut 把 Sharpe 折光,DSR 卻給出高機率。 兩者的差別在離散度。haircut 走的是獨立試驗假設,DSR 用的是你那批試驗實測的 σ_SR。σ_SR 小的時候 DSR 的門檻會被壓低,機率自然漂亮。這時候要回頭問一個問題:離散度低,是因為你的變體真的穩定,還是因為那 200 支根本是同一支策略的 200 種寫法?後者的情況下 DSR 的輸出是被自己餵出來的。
SPA 判定冠軍不是運氣,PBO 卻很高。 這兩件事不矛盾。SPA 說的是這一支策略的績效超出雜訊,PBO 說的是你的挑選程序不穩定。可以交易這一支,但不能用同一套流程持續產策略,因為下一支冠軍多半不會複製這個結果。
StepM 選出五支,逐支跑 DSR 卻只有一支過。 FWER 名單保證的是「這批裡沒有假陽性」的整體機率,它不保證每一支的個別強度都一樣。名單裡的邊際成員該進組合,但要降權,不該跟第一名拿同樣的部位。
三種情況的共同處理原則是一樣的:不一致的時候取比較保守的那一邊,並且把不一致的原因寫進研究紀錄。挑一個比較好看的結論來報,等於是在做工具購物,只是換了個形式。
串接順序:一條研究流程上的四個關卡
工具不是選一件,是排一條線。每個階段的候選數量不同,能承受的錯誤類型也不同。
| 階段 | 候選規模 | 工具 | 過不了的處置 |
|---|---|---|---|
| 動手前 | 尚未開始 | MinBTL 定預算、開計數器、寫下經濟假設 | 預算低於 10 次就換題目,不要開 |
| 初篩 | 數百到數千 | Benjamini-Hochberg,q 設 0.1 | 候選池空的就停,不要放寬 q |
| 選一批或選冠軍 | 20 到 50 | 要一批用 StepM,要冠軍用 SPA,都配區塊 bootstrap | 回到初篩,不要換工具重試 |
| 投產前 | 1 到 5 | DSR 算機率、haircut 表達折扣、PBO 當診斷 | 縮小初始規模,不是取消校正 |
兩條紀律讓這條線不至於自我瓦解。
工具必須事前選定並寫下理由。Holm 沒過改跑 BH、BH 沒過改跑 SPA,這個行為本身就是一層沒有被校正的多重檢定,而且是最難自我察覺的那一層。
餵進去的宇宙必須是完整的。掃了 2000 組、憑肉眼刪到 20 組再送檢定,檢定看到的搜尋空間是 20,實際是 2000,輸出的數字從根上就是假的。宇宙包含你碰過的全部,包括看一眼就丟的。
還有一件反直覺的事要先有心理準備。加密市場歷史短、有效樣本少,檢定力天生偏低,嚴格校正之下「什麼都不顯著」是常態而不是故障。正確的回應是縮小搜尋空間:先寫下經濟假設再碰資料,讓事前理由替你付掉一部分懲罰。搜尋空間從 1000 縮到 20,Holm 的門檻就從 0.00005 鬆回 0.0025。這比任何統計技巧都有效。
七件工具一起管不到的四件事
N 是自己報的。 六件工具吃 N,沒有一件能查核 N。整個工具箱的可信度上限,等於你計數紀律的可信度,不會更高。
統計顯著不等於淨值為正。 校正處理的是「這個績效是不是運氣」,它不碰交易成本、滑價、容量上限。一支通過 DSR 的高頻訊號,可能在算進手續費之後就沒有了。
結構斷裂不在檢定的射程內。 這些工具全部假設未來的資料生成過程跟樣本期間同一個。造市商退場、保證金規則改版、主要參與者換人,這些問題在市場結構性風險那篇拆過,校正工具一件都測不到。
髒資料會被一起認證通過。 校正工具不檢查你的資料。前視偏誤製造出來的假 alpha,經過 StepM 跟 DSR 之後會變成一個有統計背書的假 alpha,而且更難被質疑。資料層的問題要在資料層解決,不能靠統計層補救。
結論
收攏成五句話:
- 校正工具分兩族。p 值空間輸出拒絕名單,Sharpe 空間輸出機率或折扣率,先確定你要的是哪一種語言,再選工具。
- 六件工具共用 N 這個輸入,而 N 該用三條路交叉估:前置計數器給原始次數,特徵值折算給有效獨立數,期望最大值公式倒推給一致性檢查。
- 決定校正力道的是試驗之間的離散度,不是試驗次數。σ_SR 從 1.0 降到 0.5,同一支冠軍需要的解釋次數從三十幾跳到四萬。
- 要選一批而不是一支的時候,Holm 太鈍、SPA 答非所問,該用的是 Romano-Wolf StepM。
- MinBTL 是唯一能在動手之前用的工具。三年樣本、目標 Sharpe 1.5,你的試驗預算是 29 次,這個數字決定了這個題目值不值得開。
這套工具箱真正的功能不是把 Sharpe 折小,是把「我試了幾次、怎麼選的」從記憶搬進數學。一支策略在付清全部搜尋成本之後還站得住,才輪得到討論部位規模。
我每週會把這類驗證框架與實際市場數據的交叉檢驗寫進電子報,包括流動性條件、衍生品結構與鏈上籌碼的例行審視。想讓自己的研究流程多一層濾網的,可以訂閱追蹤。




