如何避免策略過度擬合

為什麼漂亮的回測可能什麼都不代表——以及如何分辨真正的優勢和曲線擬合的幻覺。

最後更新 2026-09
重點整理
  • 過度擬合是策略把歷史的雜訊記下來,不是學到規則:回測看起來卓越,實盤卻和隨機沒有差別。
  • 掃 100 組參數,就算策略完全沒有優勢,在 5% 的顯著水準下純靠機率也會有大約 5 組跑出正的 Sharpe。
  • 不要挑峰值,要挑高原:Blave Agent 的 find_plateau 取 3×3 鄰域平均 Sharpe 最高的格子,不是單點最大值。
  • 掃描範圍從指標自己的分佈長出來:取 p5 與 p95 當兩端、算術中點當分界,進場門檻掃上半段、出場門檻掃下半段。
  • 五個過度擬合訊號:孤立峰值、樣本外大幅下滑、交易筆數不到 30–50 筆、績效只來自單一市場環境、為了「修掉」虧損期而加參數。

你掃完參數,挑了 Sharpe 最高的那一組,回測曲線漂亮得不像話。真的跑起來之後,它的表現跟隨機沒有差別。中間發生的事有個名字。

什麼是過度擬合

當一個策略的參數被精確調整到能夠完美符合歷史資料時,它實際上是在記憶過去,而不是學習可以泛化的規則。回測看起來卓越,實盤卻表現很差——甚至和隨機沒有差別。

過度擬合通常不是有意為之的。每當你做了以下事情,它就自然發生:

  • 掃描大量參數組合,然後挑 Sharpe 最高的那個
  • 看到回測結果後修改策略,再用同一段資料重新測試
  • 針對圖表上看到的虧損區間,特別加入條件來「避開」它
  • 回測期間過短,某個參數組合純粹靠運氣超越其他組合
核心問題: 每一段回測資料都同時包含真實的規律和雜訊。一個足夠複雜的策略永遠能夠擬合雜訊。但雜訊不會在未來重演。

參數掃描的陷阱

假設你掃描了 100 個參數組合。就算你的策略完全沒有優勢,在 5% 的顯著水準下,單純靠機率就有大約 5 個組合會產生正的 Sharpe。如果你挑出最好的那個並回報為策略績效,你是在把雜訊當訊號。

這個問題隨著參數數量增加而惡化。兩個參數做 20×20 的格子有 400 個組合;四個參數做 10×10×10×10 有 10,000 個。每增加一個維度,撞上幸運峰值的機率就倍增。

經驗法則: 策略每多一個自由參數,回測需要的交易筆數就要多大約 10 倍,結果才具有統計意義。兩個參數已經需要相當多的交易。四個參數所需的回測長度通常難以達到。

峰值 vs 高原

避免過度擬合最重要的實務技巧是:不要挑峰值。

看一張參數掃描的 Sharpe 熱力圖。絕對最佳的格子可能顯示 Sharpe 1.8。往左移一格:0.4。往上移一格:0.3。這個峰值很脆弱——它之所以存在,是因為那個特定的參數組合剛好符合了訓練資料裡幾個特定的市場事件。

正確的做法是找高原(Plateau):在許多鄰近參數組合上 Sharpe 都持續偏高的區域。如果一個 3×3 鄰域的 Sharpe 平均都在 1.2 左右,這才是穩健的訊號——優勢存在於一個參數範圍之內,不只在單一的精確值。

# Blave Agent 的 find_plateau:
# 選的是鄰域(3×3 窗口)平均 Sharpe 最高的格子,
# 而不是單點最大值。
best_idx = argmax(neighborhood_average_sharpe)

這就是為什麼參數掃描腳本——每支策略自己資料夾裡的 scan.py——用 find_plateau 而不是直接取最佳 Sharpe。位於平滑高原上的參數組合,遠比位於孤立峰值的組合更可能泛化到未來。

樣本內 vs 樣本外

衡量策略真實績效的唯一有效方式,是在它從未「見過」的資料上測試。如果你用 2020–2023 的資料優化參數,然後在 2024 的資料上評估,2024 的績效就是真正的樣本外估計。

如果你用 2020–2024 的資料優化,再回報 2020–2024 的績效:那是樣本內。即使你並沒有刻意過度擬合,優化過程本身已經隱性地使用了 2020–2024 的結果來選擇參數。回報的 Sharpe 包含了事後之明的好處。

方法有效?說明
用全部歷史資料優化,回報全部歷史績效✗樣本內——必然過度擬合
用前 70% 優化,回報後 30% 績效✓簡單訓練/測試分割——有效但有限
走步向前:用滾動窗口優化,回報下一段✓✓最真實——和實盤的方式相同

從指標分佈決定掃描範圍

另一個常見的過度擬合陷阱是把掃描範圍設得太廣,包含在歷史上幾乎從未出現過的極端參數值,讓某個異常市場期的偶然事件拉高那個參數的 Sharpe。

Blave Agent 對門檻型策略採用不同的做法:從指標本身的分佈來決定掃描範圍。先取指標歷史分佈的 p5 與 p95 當兩端,再用兩者的算術中點(不是中位數)當分界;進場門檻的候選值落在上半段(中點到 p95),出場門檻的候選值落在下半段(p5 到中點)。這讓兩個門檻都落在有足夠歷史資料的範圍內,不會把歷史上只出現過兩次的極端值當作候選。

你的策略可能過度擬合的五個訊號

1

Sharpe 熱力圖上的孤立峰值。 最佳參數組合的鄰近格子 Sharpe 大幅下跌。往任何方向移動一格就掉 0.5 以上。優勢不穩健,只是局部的。

2

回測 Sharpe 在樣本外大幅下滑。 訓練期 Sharpe 2.0,測試期 Sharpe 0.2。落差越大,策略越過度擬合。

3

交易筆數太少。 三年回測只有 12 筆交易,幾乎沒有統計效力。幾筆幸運的交易就能純靠機率製造 Sharpe 2.0。需要至少 30–50 筆完整交易,回測數字才有意義。

4

績效完全集中在單一市場環境。 如果回測績效完全來自某一段牛市或熊市,其他時期都是平盤或虧損,策略可能只是學會了那個特定的市場環境,而不是一個普遍的規則。

5

為了「修掉」虧損期而加入參數。 在圖表上看到某段回撤後,特意加入一個條件來避開它,然後在同樣的資料上重測——這是最典型的過度擬合操作,因為未來不會再有一模一樣的虧損期等你去避開。

幾個參數算太多

沒有通用的上限,但有一個實用原則:每一個額外的自由參數都應該有先驗的理由存在於策略邏輯中。不是因為加了它能讓資料擬合得更好,而是因為它代表了你所利用的市場機制的一個真實維度。

一個有兩個參數、代表有意義概念的策略(例如快速訊號窗口和慢速確認窗口),比一個有六個參數、其中幾個是為了「修掉」圖表上特定虧損期而加入的策略,更有說服力。

這些做法救不了什麼

  • 高原選擇法處理的是「你挑到的那一格是不是運氣」,它不處理「這個策略到底有沒有優勢」。用分佈決定掃描範圍也一樣——它只是不讓你去測歷史上幾乎沒發生過的極端值,不會讓一條沒有優勢的規則變成有優勢。
  • 上面那張樣本內/樣本外的表是概念層的判斷。產品層要補一句:Blave 上沒有「留 30% 當測試集」這個設定,唯一的樣本外工具是工作頁第五分頁的 rolling walk-forward,兩個輸入框填的是天數。它驗的東西跟簡單切分不一樣,見〈樣本外驗證怎麼做:為什麼這裡沒有「留 30% 當測試集」〉。
  • 還有一個問題這篇沒有回答:就算樣本外也過了,這個成績是不是運氣?那是顯著性檢定的工作,見〈回測賺的是實力還是運氣:MCPT p 值怎麼看〉。樣本外和顯著性問的不是同一件事,兩個工具也不保證會給你一樣的答案。