MetaTrader 5 裡的參數最佳化是一次搜尋:你替每一個輸入參數宣告一段範圍,策略測試器把每一種組合都跑過一遍,然後把一張依照你選定的指標排序好的表格交到你手上。難的不是把它跑起來。難的是那張表永遠會有第一列,而第一列幾乎永遠是錯的。
這篇文章給你的,是一套會產出決定而不是產出一個數字的流程:一次你守得住的搜尋、一種撐得過第二段期間的通過表讀法,以及一條停止規則。
| 測試條件 | |
|---|---|
| 實驗編號 | EXP-PARAM-SEARCH-OUTCOMES-001 |
| 母實驗 | EXP-BUILDER-TEMPLATE-BASELINE-001 |
| 來源 | ea-templates-manifest.js → bt.explored |
| 母體 | 8 recorded searches of the 53 measured templates |
| 商品/時間週期 | USDJPYm, M5 and H1 |
| 模型 | M1 OHLC (Model=1), Exness MT5, measured 2026-06-18 |
| 變動的參數 | stop loss and take profit only |
| 最後驗證 | 2026-08-25 |
設定:網格、切分與資料
有三項設定決定了這次搜尋到底值不值得跑。設錯了,那張通過表就是一台非常昂貴的亂數產生器。
| 欄位 | 位置 | 要設成什麼 | 為什麼 |
|---|---|---|---|
| Optimisation(最佳化) | Settings 分頁 | 小網格就選 Slow complete algorithm | 遺傳模式是對這個空間取樣;12–32 種組合的規模,你負擔得起把全部看完 |
| Start / Step / Stop | Inputs 分頁,每個輸入參數各一組 | 兩個參數,粗一點的步長 | 你每勾一個輸入參數,網格就乘一次。我們只動兩個 |
| Forward(前推切分) | Settings 分頁 | 1/2、1/3 或 1/4 | 把區間切開,讓測試器把後半段另外評分——你跑這場搜尋,為的就是這一項檢查 |
| Optimisation criterion(最佳化準則) | Settings 分頁 | 在你看到網格之前就先決定 | 它是測試器用來替各輪排序的指標,所以是它決定了哪一列才是第一列 |
| Modelling(建模模式) | Settings 分頁 | 用粗模式掃,再把活下來的那組拿真實 tick 重跑 | 掃描用的模式是拿來替候選排名的,絕對不能拿來當公開的數字 |
| Period(期間) | Settings 分頁 | 長到足以裝下不只一種市場狀態 | 在單一趨勢裡做的搜尋,找到的是騎在那段趨勢上的那組設定 |
這個準則值得你做一個決定,而不是接受一個預設值。用淨利排序,獎勵的是冒最多風險的那一輪;用以回撤為基礎的指標排序,獎勵的是交易最少的那一輪——報酬回撤比之所以存在,正是因為這兩個答案互相打架。我們自己的搜尋根本沒有用測試器的排序來判定:每一組活下來的設定,都被拿到三段各自獨立的區間上量獲利因子,而任何單一區間內部的排名,從來沒有決定過任何事。
資料品質排在最前面:在爛 tick 上做搜尋,最佳化到的是那些缺口。簡短版是:建模品質低於 90% 會讓日內的通過表變得不能用,而用插值 tick 資料建出來的執行,解析不出一個落在 K 棒內部的止損。
- 先用預設值跑一次單獨的回測,並且把報告留下來。沒有基準,通過表就沒有東西可以打敗——怎麼跑一次回測把那一輪從頭到尾走了一遍。
- 在 Settings 分頁把 Optimisation 設成小網格的完整輪次,並把 Forward 設成
1/3,讓測試器把區間的最後三分之一留起來不看。 - 在 Inputs 分頁只勾你真的要測的那些參數,並且各給一組 Start、Step 與 Stop。兩個輸入參數配粗步長,勝過四個配細步長。
- 按 Start,讓它跑完。把 Optimisation Results 分頁當成一張表來讀,把 Optimisation Graph 當成一個形狀來讀——單獨一根尖峰是警訊,一片高原才是發現。
- 把活下來的那幾組——不是冠軍那一組——每一組都拿到最佳化區間之前的一段期間上,當成單獨一次回測重跑。這一步產出了我們這一組裡每一則否定的結論,而它也正是大家會跳過的那一步。
讀結果:三段期間,不是一段
以下是我們記錄下來的整組結果,依照每一次搜尋達到的最佳樣本內獲利因子排序。IS 是那組設定被配適的期間,OOS 是留出來的那一段,prior 則是搜尋從來沒看過的一段更早的區間。
| 範本 | 搜尋的網格 | 最佳 IS | OOS | Prior | Verdict |
|---|---|---|---|---|---|
ichimoku | 12 種組合 × 3 段區間 | 1.37 | 0.89 | 0.80 | no_robust_edge |
ma_crossover | 20 + 12 種組合,兩個時間週期 | 1.23 | 0.89–0.94 | 0.78 | no_robust_edge |
cci_level | 12 種組合 × 3 段區間 | 1.07 | 1.05 | 0.92 | no_robust_edge |
adx_trend | 12 種組合 × 3 段區間 | 1.04 | 0.91 | 0.80 | no_robust_edge |
breakout | 12 種組合 × 3 段區間 | 1.04 | 0.79–0.89 | 0.64–0.84 | no_robust_edge |
macd_signal | 12 種組合 × 3 段區間 | — | 1.14–1.15 | 0.74–0.77 | no_robust_edge |
rsi_reversal | 12 種組合 × 3 段區間 | 0.91 | — | — | no_robust_edge |
bb_bounce | 12 種組合 × 3 段區間 | 0.91 | — | — | no_robust_edge |
先往下讀第一個數字欄位,再往右讀。這一組裡樣本內最大的那個結果,垮得也最厲害:ichimoku 的 1.37 跌到 0.89,然後是 0.80。這個順序不是巧合——最貼合某一段區間的那組設定,按其構造就是吸收了那段區間最多雜訊的那一組。
現在來看真正最接近可用的那一組設定。它不在上面那張表裡,因為它從來就不是任何一張表的第一列:在同一張 ichimoku 網格上,SL50/TP150 的成績是樣本內 1.18、樣本外 0.99、前一段區間 1.00。三段期間,全都大致打平。它被記錄為最接近的候選,而且依然沒有被採用,因為三段區間都只是打平並不是優勢——那是優勢的缺席,只不過量得很仔細。
拿來對照的話,這些搜尋想要打敗的基準線落在 0.92 到 1.03 之間。沒有任何一次搜尋動得了一個已經出貨的預設值。
該避開的陷阱
這五條底下的失敗模式是同一個。過度配適不是你在一場搜尋結束時犯下的錯誤——它是跑一場搜尋的預設結果,而三段期間這套紀律之所以存在,就是要讓它在你採取行動之前先現形。
改進與迭代:該改什麼,以及什麼時候停
改一件事,重跑,拿去和你留下來的基準比。最不浪費時間的順序是:
- 先加寬期間,再加寬網格。更多市場狀態勝過更多組合。一場只涵蓋一段趨勢的搜尋,不管解析度多細,找到的都會是騎在那段趨勢上的設定。
- 接著把步長放粗,而不是去微調它。如果一個結果只在
SL47上存在,那它就不存在。 - 然後,也只有到這時候,才加一個參數。我們自己從來沒走到這一步,因為兩個參數就已經沒過三段期間那道門檻。
以下任何一條成立時就停下來,並且把是哪一條寫下來:
- 有一組活下來的設定三段期間全過。就出貨,並且把你搜過的整張網格記下來——不是只記你留下的那一輪。
- 樣本內最好的結果低於 1.0。你拿到了一個真正的答案:我們八次搜尋裡有兩次停在這裡,而在 36 次評估之後停在這裡是很便宜的。
- 活下來的設定一直是過了一段區間、又倒在另一段。這條規則依賴市場狀態。搜尋得更多,只會產出更多依賴市場狀態的設定。
- 你開始替前一段區間「不算數」找理由了。那一刻起,這場搜尋就不再是一次測試。
一場搜尋誠實的紀錄,是你涵蓋的範圍加上結論,兩者一起。我們那八次每一次都是這樣存下來的,這也正是這篇文章能夠從它們寫出來的原因——只存一個贏家,什麼也證明不了。
接下來的步驟:先做前向測試,再做決定
最佳化是四個步驟裡的第二步。順序是回測 → 最佳化 → 前推 → 模擬帳戶,而每一步排除的是一種不同的出錯方式。
- 拿一個你自己掌控的東西來練這個循環:在 Builder 裡做一支策略,然後自己搜尋它的止損與目標,因為一張你自己宣告的網格,要誠實地讀它,比讀一張你繼承來的網格容易太多。
- 三段期間這項檢查的正式版本是前推分析,它會把切分點往前滾動,而不是固定在一個地方。
- 不管這場搜尋交回來的是什麼,交回來時裝著它的那份報告還是得有人讀:讀懂一份 MT5 回測報告講的是每一個代表數字究竟是在對哪一個母體做主張。
- 想看看數字真的活下來的時候,一份做完的紀錄長什麼樣子,已發布的 EA每一則都附上完整的平倉交易清單與執行清單。
- 我們如何測試、評分並記錄這一切,寫在我們的測試方法。