樣本內 vs 樣本外:怎麼切分、多少才夠
用歷史資料較早的一段(樣本內)調整策略,再原封不動地用較晚的一段(樣本外)來評判。樣本外要用完成的交易筆數來衡量,而不是用年數;判斷標準要在看結果之前先寫好,並另外留下最後一段完全不碰的資料,只做一次最終測試。
作者 Soren Huang · 發佈 · 更新於 · 編輯原則
目錄
什麼是樣本內與樣本外資料,為什麼一定要切分?
依日期切分你的歷史資料:用較早的一段(樣本內)調整規則與設定,再原封不動地用較晚的一段(樣本外)去跑。常見的切分比例是 70:30 到 80:20。樣本外夠不夠,要看完成的交易筆數,而不是年數;另外還要留下最後一段資料完全不碰,只做一次最終測試。
樣本內(IS)資料是你用來挑選策略規則與設定的那一段歷史價格。樣本外(OOS)資料則是你先擱在一旁、只用來原封不動地執行這些規則並讀取結果的那一段。拿學生來比喻:樣本內期間是讀書的教材,樣本外期間是考試。事先看過考題的學生分數會很漂亮,但這個分數看不出他到底學會了什麼。兩段要用同一把尺比較,可以各用免費的夏普比率計算器算一次。
之所以要切分,是因為幫忙挑出策略的資料,沒辦法公平地替這個策略打分數。當你在同一份資料上測試許多規則組合、再留下最好的那個,你留下的東西一部分是真實的規律,另一部分則是剛好和那段歷史湊在一起的雜訊。樣本內的結果分不出這兩者。只有搜尋過程從未碰過的資料才分得出來,所以策略生成中的過度最佳化只能在樣本外檢查,別無他法。
資料該怎麼切分?
依時間切分,樣本內期間在前、樣本外期間在後,比例大約是 70:30 到 80:20。依時間切分複製了你實際交易的方式:以過去為基礎,交易一段沒看過的未來。若把 K 棒隨機打散,例如每隔一週就丟進測試集,資訊就會跨過切分線外洩,因為相鄰幾天的市場狀況彼此高度相關。
- 在跑任何東西之前先決定切分日期。把它寫下來。看到壞結果之後再去移動日期,本身就是一種調整參數。
- 樣本內大約佔歷史資料的 70% 到 80%。它需要足夠的交易筆數讓最佳化程式運作。樣本外則需要足夠的交易筆數來評分,下一節會談到。
- 確認兩段資料都包含不只一種行情。在切分線的兩側,都要找得到趨勢段、盤整段、波動大的段落與波動小的段落。如果樣本外那幾年剛好是一路長多的多頭行情,一個單純做多的策略就會因為錯誤的理由而過關。
- 兩邊使用相同的交易成本、交易時段與成交設定。如果策略是用下一根 K 棒成交來調整,卻用同一根 K 棒成交來測試,那就等於根本沒有測試。
| 選擇 | 依時間切分(建議) | 隨機打散 K 棒 |
|---|---|---|
| 資料順序 | 樣本內在前,樣本外在後 | 整段歷史混在一起 |
| 資訊外洩 | 結構上不會發生 | 相鄰 K 棒共享相同的市場狀況 |
| 是否符合實單交易 | 符合:以過去為基礎,向前交易 | 不符合:你無法交易一段被打散的未來 |
| 行情型態 | 兩側都必須人工檢查 | 自動分散,但代價是資訊外洩 |
樣本外多少才夠:看交易筆數還是年數?
樣本外夠不夠,要用完成的交易筆數來衡量,而不是日曆上的年數。兩年的資料,對一個每月交易一次的波段策略來說大約只有 24 筆交易,對一個每天交易兩次的日內策略來說卻大約有一千筆。第一個樣本幾乎說明不了什麼,第二個卻能說明很多。日期相同,證據的分量卻天差地遠。
原因在於平均值的行為。由十幾筆交易算出的平均值,只要換掉其中兩三筆就可能大幅移動;由幾百筆交易算出的平均值則幾乎不動。值得記住的公式只有一個:
平均每筆損益的不確定性 = 單筆交易的離散程度 ÷ √N
這裡的單筆交易的離散程度指的是各筆交易結果通常偏離平均值多遠(標準差),N 是樣本外的交易筆數,√N 是它的平方根。由於平方根成長得很慢,你需要四倍的交易筆數,才能讓不確定性減半。
假設性範例
假設單筆交易結果通常與平均值相差約 $400,而樣本外扣除成本後的平均每筆損益是 $60。在 24 筆交易時,不確定性約為 $400 ÷ 4.9 ≈ $80,所以真正的平均值很可能低於零。在 1,000 筆交易時,約為 $400 ÷ 31.6 ≈ $13,所以 $60 的平均值就明顯高於零。這個波段策略需要更多年的資料,或是能產生更多樣本外交易的推進分析設計,結果才有意義。
許多系統化交易者採用的實用經驗法則是:在相信單筆交易的數字之前,至少要有幾百筆樣本外交易,而少於約 30 筆的情況只當作線索,不算結果。Bailey 等人(2014)指出了這件事的另一面:你試的策略變體越多,就需要越長的歷史資料,才能把其中最好的那個和運氣區分開來。在相信單筆交易的數字之前,可以從 AlphaPrime(Valynox) 績效報表的交易明細,數一數樣本外期間實際有幾筆完成的交易。
曲線擬合有哪些徵兆?
曲線擬合的表現是:樣本內權益曲線陡峭又平滑,而樣本外曲線在切分日期之後走平或下滑。曲線擬合,是把策略調整到極度貼合某一段歷史,使它描述的是那一段的雜訊,而不是可重複的規律。切分線上的形狀變化是最明顯的徵兆,但在跑樣本外之前,還有其他可以檢查的地方。
| 徵兆 | 你會看到什麼 | 合理的優勢看起來像什麼 |
|---|---|---|
| 切分處的形狀變化 | 樣本內陡峭平滑地上升;樣本外走平或下滑 | 樣本內上升較為崎嶇;樣本外斜率相近但略為平緩 |
| 只在單一數值有效的設定 | 20 根 K 棒的回看期間很好,18 和 22 卻很差 | 相鄰的一大片設定表現都差不多 |
| 參數多、交易筆數少 | 調了八個數字,樣本內只有 60 筆交易 | 參數很少,每個參數對應數百筆交易 |
| 獲利集中在少數幾筆交易 | 拿掉最大的五筆獲利交易,結果就變成持平 | 拿掉最大的幾筆交易後結果縮水,但仍為正 |
| 獲利集中在特定時間 | 全年的獲利都來自某一季;其他季度持平或為負 | 大多數季度都有貢獻;沒有單一期間獨大 |
第二列和第三列,在你動用樣本外資料之前就可以測試。把相鄰的設定都跑一遍,看參數曲面;推進分析的方法對此有詳細說明。這些徵兆背後的研究,以及為什麼大規模搜尋中最好的回測幾乎總是被高估,整理在回測的過度最佳化:為什麼最好的回測通常被高估。
樣本外變弱但沒有壞掉時該怎麼辦?
從樣本內到樣本外出現一些衰退是正常的,所以要用你在看結果之前就寫好的規則來判斷衰退幅度,並使用扣除成本後的每筆數字。樣本內的結果是許多次嘗試中最好的那一個,帶有選擇上的加成,而樣本外的執行沒有這份加成。單單是樣本外的斜率比較平緩,並不算失敗。正負號反轉,或是結果全靠某一個幸運的月份撐著,才算失敗。
可行的做法是衡量樣本內的平均每筆損益有多少比例在樣本外保留下來,並事先設定好區間:
- 計算兩邊扣除手續費與滑價後的平均每筆損益。使用相同的成本設定;回測中的交易成本說明了如何設定。把樣本外的數字除以樣本內的數字。
- 為負或接近零:淘汰。這個策略描述的是雜訊。
- 大約 30% 到 70%:變弱但沒有壞掉。執行下面的額外檢查,並根據檢查結果決定。
- 高於約 70%:進入下一道檢查。樣本內結果中只有很少部分是選擇上的加成。
針對中間區間的額外檢查,和揭露曲線擬合的檢查是同一批:計算樣本外有多少個月或季度為正、拿掉樣本外最大的五筆獲利交易看結果是否仍高於零、用兩倍滑價重跑一次,並確認相鄰的設定表現相近。四項中通過三項的策略,通常值得繼續往下走;有三項沒通過的,通常就不值得。在執行這些檢查之前,先寫下你要求的通過項數。
假設性範例
樣本內扣除成本後的平均每筆損益:$120。樣本外扣除成本後的平均每筆損益:$60,來自 400 筆交易。比例是 50%,落在中間區間。額外檢查顯示 9 個季度中有 7 個為正;拿掉最大的五筆獲利交易後,每筆損益為 $38;滑價加倍後,每筆損益為 $41;所選設定周圍的參數曲面平坦。在要求四項通過三項的規則下,這個策略通過,並且原封不動地進入下一階段。
你絕對不能做的是重新調整。因為樣本外曲線看起來疲弱,就去改停損、回看期間或濾網,會讓樣本外期間變成樣本內資料。下一節會說明,即使沒有明顯的重新調整,為什麼也會發生這種情形。
為什麼要留一段最後完全不碰的期間?
每看一次樣本外結果,那段資料就慢慢變成樣本內資料,所以要保留最後一段歷史,在策略通過其他所有檢查之前,什麼都不碰它,而且只測試一次。這種外洩是逐步發生的。你用樣本外測試了十個候選策略,留下表現最好的三個,樣本外期間就已經參與了策略的挑選。Bailey、Borwein、López de Prado 與 Zhu(2017)將此形式化:在同一份資料上比較的候選策略越多,看起來最好的策略是過度擬合的機率就越高。Harvey 與 Liu(2015)從不同角度得到相同的結論,並提議依背後的測試次數對結果打折。
解決方法是設立第三段資料,而且允許查看的次數不同:
實務上,這代表把歷史資料中最近的六到十二個月(或是依策略頻率足以容納足夠交易筆數的任何長度)保留起來,不要載入任何研究執行中。當某個策略通過了樣本內搜尋、樣本外評分與穩健度檢查之後,在保留的那一段上只跑一次,依照同一條事先寫好的規則讀取結果,然後接受或淘汰。如果淘汰,這段資料對該策略家族來說就用掉了;下一個想法只有在和前者真正無關時,才可以用它來評分。
這和推進分析有什麼關係?
推進分析沿著歷史資料重複做許多次樣本內與樣本外的切分,因此能從同一份資料產生更多樣本外交易。推進分析是一種測試:在一個視窗上調整設定,原封不動地用在緊接著的下一個視窗,然後往前移動,如此重複,直到接起來的樣本外片段構成一個完整的結果。對於前面那個單一兩年樣本外區塊只有 24 筆交易的波段策略,在十年上做滾動設計,可以產生數倍的樣本外交易,而且每一筆交易所用的設定,都是在那段資料出現之前就選好的。完整的方法、視窗大小,以及如何解讀接起來的曲線,請見推進分析:為什麼只做一次回測不夠。
有兩件事不會改變。每個視窗仍然遵守第一節的單向規則:設定從樣本內流向樣本外,絕不倒流。而且最後那段不碰的期間,仍然位於所有視窗之外。推進分析本身就是一項你可能用不同視窗長度跑好幾次的檢查,所以它接起來的樣本外曲線,用上一節的說法是「看過幾次」,而不是「只看一次」。AlphaPrime把推進分析當作策略檢驗的其中一個步驟,並在策略沒有通過前面的檢查時,停止後面的檢查,這讓能走到後段資料的候選策略數量維持在很少。
如果你使用 AlphaPrime,這代表:在搜尋開始之前,先在策略檢驗中設定好門檻,讓樣本內、樣本外與推進分析的決定,都由你事先寫好的規則來做,並且在每一次研究執行中,都把你自己的 K 棒資料中最近的一段保留起來,留給那一次最終測試。
常見問題
交易中的樣本外是什麼意思?
樣本外資料是你在挑選策略規則或設定時,先擱在一旁、沒有使用的那一段歷史價格。你把完成的策略原封不動地套用在這段資料上,然後讀取結果。因為策略在調整期間從未看過這段資料,所以樣本外的結果,比樣本內的結果更能公平地估計這些規則在新價格上的表現。
我可以用隨機切分取代依時間切分嗎?
對交易策略來說,請依日期切分,不要隨機切分。相鄰的幾天共享波動度、趨勢與消息面,所以隨機打散會讓測試期間的資訊外洩到調整期間。依時間切分,把樣本外期間放在樣本內期間之後,也符合你實際交易的方式:以過去為基礎,交易一段沒看過的未來。
我需要多少筆樣本外交易?
要夠多,使得幾筆交易改變時,平均每筆損益不會大幅移動。許多系統化交易者的目標是至少幾百筆樣本外交易,並把少於約 30 筆的情況當作線索而非結果。平均值的不確定性會隨交易筆數的平方根縮小,所以四倍的交易筆數可以讓不確定性減半。如果單一樣本外區塊的交易筆數太少,推進分析能用同一份歷史資料產生更多筆。
樣本外結果不好之後,可以重新最佳化嗎?
如果你希望樣本外結果保有它的意義,就不行。因為樣本外曲線看起來疲弱就更改某項設定,會讓那段資料變成調整的一部分。請用你在看結果之前寫好的規則來判斷疲弱的結果,執行額外檢查(獲利在時間上的分布、拿掉最大的幾筆交易、滑價加倍、相鄰設定),然後接受或淘汰。如果你決定修改策略,就把它當作新的候選策略,並用它沒看過的資料來評分。
參考文獻
- Bailey, D. H., Borwein, J., López de Prado, M., & Zhu, Q. J. (2014). Pseudo-Mathematics and Financial Charlatanism: The Effects of Backtest Overfitting on Out-of-Sample Performance. Notices of the American Mathematical Society, 61(5), 458–471.
- Bailey, D. H., Borwein, J., López de Prado, M., & Zhu, Q. J. (2017). The Probability of Backtest Overfitting. Journal of Computational Finance, 20(4), 39–69.
- Harvey, C. R., & Liu, Y. (2015). Backtesting. The Journal of Portfolio Management, 42(1), 13–28.

