回測與驗證 intermediate 13 分鐘閱讀

MT5 回測報告怎麼看:23 份報告,以及每個代表數字漏掉的東西

MT5 回測報告是一項主張:關於某一組交易,在某一段價格歷史上。這句話的兩半都會左右數字。我們把本站已公開的 23 份報告全部讀過一遍——在兩段切片都有公開的那 20 次執行裡,有 14 次的代表獲利因子比 EA 當初被挑中的那段期間更好看;有一份報告只涵蓋自己 315 筆交易裡的 303 筆;而同一支 EA 換一個資料來源重跑,就從 1.35 通過變成 1.13 不通過。

發佈於 · 審閱於

MT5 回測報告是一項主張:關於某一組特定的交易,在某一段特定的價格歷史上被做出來。幾乎每一次誤讀,都來自把這句話丟掉一半。代表性的那個獲利因子被讀成了 EA 的性質。它其實是另外兩件事的性質:這份報告涵蓋的那組交易母體,以及餵給測試器的那些 tick。

這篇文章給你的,是一套會產出決定的閱讀順序。報告在印出任何東西之前先假設了什麼、哪一個指標回答哪一個問題、每一個數字會在哪裡騙你,以及每一次閱讀在告訴你該改什麼。產出一份報告是另一件工作——怎麼跑一次回測把那件事從頭到尾走了一遍。

測試條件
實驗編號EXP-REPORT-READING-001
母實驗EXP-BACKTEST-RUNBOOK-001
來源data/run-manifests/*.jsonresults, ledger_recomputed, shadow_runs
母體all 23 runs published on mt5depot at the time of derivation
MT5 build 版本6090 and 6140
模型Every tick generated from M1 bars (Model 0) and Every tick based on real ticks (Model 4)
帳戶10,000 USD deposit on all 23 runs
最後驗證2026-08-26

底下每一個數字都是回測,而這 23 次執行全部帶著 PASS 判定——它們是通過了上架門檻的那些執行。這使得它是一組倖存者樣本,所以這裡沒有任何內容能告訴你一次回測有多常通過。它告訴你的是,一份通過的報告從內部看起來長什麼樣子。

設定:報告在印出任何數字之前就已經假設的事

MT5 報告最上面的 Settings 區塊不是前言。它是底下每一個數字都會繼承的假設清單,而其中有六項決定了剩下的部分值不值得讀。經紀商名稱與 build 版本就在報告自己的標題那一行——我們的寫著 Exness-MT5Trial5 (Build 6090)

Settings 欄位它實際上釘死了什麼我們的紀錄寫著什麼
Symbol: / Period:這個結果所取樣的那些市場狀態22 次執行從 2019 年 1 月開始;cairn 從 2021 年 6 月開始
模型(tick 產生方式)每根 K 棒內部的 tick 是怎麼被做出來的12 次用 Model 0(從 M1 K 棒產生),11 次用 Model 4(真實 tick)
Initial Deposit:這一頁上每一個百分比的分母23 次全部是 10,000 USD
點差每一筆成交被扣掉的成本23 次裡剛好只有 1 次量過——其餘的都繼承了價格歷史自己帶著的值
手續費你有設定,測試器才會套用的成本23 次全部是 0
Inputs:產出這份報告的那整組設定,完整版每一次執行都拿報告核對驗證過

Inputs: 這一列是大家會跳過的那一列,而它正是讓一份報告根本可以被重現的那一列:它是你要把同一頁拿回來,就必須重新輸入一遍的完整值集合。

其中兩列值得停一下。手續費那一行是零,並不代表手續費被忽略了。它代表在被測試的那個商品上沒有被收這筆費用。這是兩句不同的話,而只有執行紀錄能告訴你適用的是哪一句。另外,沒有被量測的點差,不是零點差:我們 23 次執行裡有 22 次那個欄位是空的,因為沒有任何紀錄器跟著測試一起跑。每一筆成交就只是拿到 M1 歷史帶著的那個點差。只有 tidewell-slack 講得出自己的平均值,19.14 點。

這裡有一個命名陷阱。舊一點的指南叫做建模品質的那個欄位,MT5 印出來的名字是 History Quality:,位置在 Results 區塊裡 Bars:Ticks:Symbols: 的旁邊。在一份 Build 6090 的報告裡搜尋 modelling quality,什麼也找不到。在我們自己的紀錄裡,這個數字只出現在 23 份 manifest 裡的 2 份上,因為它是在原始報告有寫出來的時候才被留下來的——這是這些紀錄的性質,不是在量 MetaTrader 多常印出它。實務上的意思是,你沒辦法拿它來過濾不是你自己產生的報告。它底下真正的問題是 tick 資料的來源,而那個問題永遠答得出來:問這次執行用的是哪一份歷史。

讀報告:一個指標一個指標讀

照這個順序讀這一頁。它刻意不是 MetaTrader 印出來的順序,因為那兩個最便宜的淘汰條件坐在報告的最下面。

  1. 先讀 Settings。模型、Initial Deposit:、點差與手續費。底下每一個百分比都繼承它們,而一次點差沒有被量測的執行,並不是一次沒有點差的執行。
  2. 在讀任何比率之前,先讀 Total Trades:。一個比率和它的樣本數是一件事實,不是兩件。把筆數寫在比率旁邊。
  3. 問這個代表數字涵蓋了哪些交易。如果旁邊有公開的交易帳本,請確認它的總數對得上 Total Trades:。我們自己 23 份報告裡有一份對不上。
  4. Equity Drawdown Maximal:,不要讀餘額那一行,並且記下你取的是 Maximal 還是 Relative 那個數字——它們是分開的兩列。
  5. 找出價格歷史。哪一家經紀商、哪一個來源、哪一段期間。在我們的紀錄裡,移動了判定的就是這個欄位;tick 模型沒有。

以下是把整套讀法放進一張表,用的是報告實際印出來的欄位名稱。「在我們這一組裡」這一欄,是每一個指標在 23 次已公開執行上實際的樣子。這比教科書給的區間更有用,因為它是在和你手上拿著的同一種報告上量出來的。

報告欄位它回答的問題在我們這一組裡警訊
Total Trades:證據有多少每次執行 108 到 4,725 筆低於大約 100;20 筆交易上的比率是傳聞
Profit Factor:總毛利除以總毛損(獲利因子23 次全部落在 1.22 到 1.59在很短的區間上高於大約 2.0;先確認 Total Trades:
Profit Trades (% of total):勝率——分布的形狀,不是它的正負號30.80% 到 82.27%,全部獲利單獨被引用,旁邊沒有放獲利因子
Total Net Profit:在有脈絡之前,賺到的金額在同樣 10,000 USD 的初始資金上,386.05 到 28,687.43 USD引用時沒有帶上 Initial Deposit: 與年數
Balance Drawdown Maximal:已平倉交易上最糟的一段下跌(最大回撤0.67% 到 18.24%同一頁上就有權益那一行,卻引用這一個
Equity Drawdown Maximal:把未平倉部位算進去之後最糟的一段下跌23 次裡有 23 次比餘額更深被忽略——你的保證金活在這個數字上
Expected Payoff:每筆交易的平均結果,以金額計我們的 manifest 沒有帶被讀成預測,而不是平均
Recovery Factor: / Sharpe Ratio:每單位痛苦換到的報酬,兩種算法我們的 manifest 沒有帶拿交易筆數不同的報告互相比較
History Quality:tick 序列解析不解析得出你的停損23 次裡有 2 次寫了空白,而且資料來源不明

那個區塊裡有兩個慣例,在任何解讀開始之前就先把人絆倒。

Total Trades:Total Deals: 是兩個不同的計數。在 MetaTrader 5 裡,一次來回是兩筆 deal——進場一筆、出場一筆——所以一份寫著 Total Trades: 50 的報告,旁邊會寫著 Total Deals: 100,而分批平倉會在不增加 trade 的情況下增加 deal。比率要拿去對 trade 讀,絕對不要對 deal。

回撤那幾行有六條,不是一條。報告會替餘額與權益各印出 AbsoluteMaximalRelative。更糟的是,其中兩條的金額與百分比會互換位置:Balance Drawdown Maximal: 36.84 (0.37%) 把金額放前面,Balance Drawdown Relative: 0.37% (36.84) 把百分比放前面。兩份報告從相鄰的兩行分別引用「0.37%」與「36.84」,可能講的是同一個事件——也可能是不同的事件。

Results 區塊剩下的部分——Z-Score:AHPR:GHPR:LR Correlation:LR Standard Error:Margin Level: 以及 MFE/MAE 相關性——描述的是資金曲線的形狀,而不是它的大小。它們沒有一個救得了一份交易筆數太少的報告,也沒有一個在價格歷史被換掉的時候比獲利因子更耐得住。請在上面那五個步驟之後再讀它,或者乾脆不要讀。

那些指標列裡有兩列在實務上造成最多損害,所以要把它們放在一起讀,而不是照順序讀。

淨利需要它的分母,也需要它的日曆。我們 23 次執行全部從同樣的 10,000 USD 出發,這讓它們異常地可比。它們依然橫跨每年 0.51% 到 57.38%。低的那一端很有教育意義。orrery 的獲利因子是 1.46,最大回撤 0.67%——目錄裡最好看的一對數字。它在 7.58 年裡賺了 386.05 USD。那份報告沒有任何不誠實的地方。它只是在回答一個問題,而那個問題和大多數讀者以為自己在問的並不一樣。

勝率與獲利因子在這裡接近互相獨立。在 23 次已公開的執行上,兩者的相關性是 0.37。所以決定一支 EA 賺不賺錢的東西,大部分都是勝率那一行看不見的。nautical 的勝率是 30.80%,獲利因子 1.22;gyre 贏 82.27%,獲利因子 1.59。兩支都獲利,而勝率差了 51 個百分點。

你的報告沒有秀給你看的那個獲利因子

這是沒有任何報告會秀給你看的部分,也正是我們能夠用自己的資料寫出這篇文章的原因。每一次已公開的執行都留著它完整的平倉交易帳本,所以每一份報告都會裂成兩半。有一段是這支 EA 被挑中的依據——上架時被拿去過門檻的那段開發區間。然後是它上線之後才發生的那些交易,那些交易沒有被任何東西挑過。我們 23 次執行裡有 20 次兩段切片都有公開;另外三次根本沒有上架後的那一段。

EA開發切片上架後切片代表數字
orrery1.28(195 筆)6.43(15 筆)1.46(210 筆)
windrose1.31(101 筆)3.58(7 筆)1.38(108 筆)
cairn1.48(4,583 筆)1.64(142 筆)1.48(4,725 筆)
gyre1.55(136 筆)—(5 筆,沒有虧損交易)1.59(141 筆)
tessera1.28(624 筆)0.88(21 筆)1.27(645 筆)
zerqon1.53(232 筆)0.72(21 筆)1.43(253 筆)

把 orrery 那一列的第一欄與最後一欄放在一起讀。代表數字說是 1.46;這支 EA 實際上被挑中的那段期間說是 1.28;差別是15 筆交易——佔整份紀錄的 7%——跑出了 6.43 的獲利因子。用同樣的方式讀 zerqon 那一列,方向剛好相反:開發切片 1.53,上架至今的 21 筆是 0.72,而 1.43 這個代表數字把兩邊都藏了起來。

在兩段切片都有公開的那 20 次執行上,代表數字比開發切片好看的有 14 次,比較差的有 6 次。另外三次是刻意被排除在外的:它們只有一段切片,代表數字與開發數字涵蓋的是完全相同的那些交易,所以兩者之間的差別根本不是母體效應——那是報告自己四捨五入到小數點後兩位,和重算過的帳本之間的落差。almanac 印出來的是 1.52,帳本重算出來的是 1.5153。把同樣這道四捨五入的門檻套到那 20 次上,還是有 13 次的落差不是四捨五入能解釋的,其中 8 次是往好看的方向。

這個不對稱不是醜聞。一個橫跨兩段期間的代表數字,會被拉向其中運氣比較好的那一段。但它確實代表:當你要拿一個數字去對照關於未來行為的主張時,代表數字永遠不是那一個。

陷阱:這些數字如何誤導人

這五條底下的失敗模式是同一個:一份報告是對一個母體的量測,而這一頁上每一個指標,都默默繼承了測試器當初被指向的那個母體。

改進:每一次閱讀在告訴你該改什麼

一次改一件事,而且每一次都重讀同樣那三個數字:交易筆數、獲利因子與權益回撤。底下的順序是照成本排的——便宜的檢查排前面,因為其中有兩個經常直接結束整場調查。

  1. 如果交易筆數很小,就把期間拉長——不要動參數。一個建立在大約 100 筆交易以下的獲利因子,從一段更長的區間上得到的移動,會比你動任何設定得到的都大。我們最小的一次已公開執行有 108 筆交易,而它也正是我們引用比率時最小心的那一次。
  2. 如果代表數字和開發切片不一致,就只在開發切片上重讀一次。那才是當初挑設定所對照的那個數字,也是你該拿去和其他候選比較的那一個。
  3. 如果權益回撤明顯高過餘額回撤,就照權益那個數字算部位大小。這個差距告訴你這支 EA 會抱著幾個部位一起走進同一段走勢。chrysalis 那次執行講得很直接:最多同時七個。
  4. 如果報告是從別人的資料來的,就在做別的事之前先換第二個來源重跑一次。在我們整組資料裡,這項檢查量到的效果最大,而它也是大家最後才做的那一項。

真正移動了數字的東西:資料來源,不是 tick 模型

我們有一支 EA 是被刻意重跑來把這兩個變數分開的,而執行紀錄替每一個 shadow 標了它隔離的是什麼。

tidewell-slack 執行改了什麼交易筆數獲利因子最大回撤歷史品質判定
已公開Exness M1 歷史,Model 03031.359.92%99%PASS
Shadow — 隔離資料來源Dukascopy 歷史,Model 03511.1318.18%99%FAIL
Shadow — 隔離真實 tickDukascopy 歷史,Model 43451.1118.20%100%FAIL

把它讀成兩個各自獨立的實驗。只改價格歷史——第一列到第二列,tick 模型相同——讓獲利因子從 1.35 掉到 1.13,回撤幾乎翻倍,判定也從通過翻成不通過。在那份新歷史上只改 tick 模型——第二列到第三列——讓獲利因子動了 0.02,回撤動了 0.02 個百分點。而失敗的那兩次執行,歷史品質分別讀作 99% 與 100%,所以大多數人拿來篩選的那個欄位,從頭到尾都很優秀。

另一支 EA 從不同的角度指向同一件事。kestrel-hover 公開的版本跑在 Dukascopy 真實 tick 上,獲利因子 1.33、回撤 7.11%,而它在 Exness M1 歷史、Model 0 上的 shadow 執行讀作 1.30 與 6.76%——來源與模型同時都換了,結果卻幾乎沒有動。跨資料來源的穩定性是有可能的。它只是不是單獨一份報告能證明的東西。

實務上的規則是:一份報告能當成可攜證據的程度,就是它那份價格歷史能被攜帶的程度。換第二個來源重跑一次要花一個晚上。在我們的紀錄裡,這是這篇文章裡唯一一項改變過決定的檢查。

接下來的步驟:從一份報告到一個決定

把報告讀好是四個步驟裡的第二步。順序是回測 → 讀報告 → 前推分析 → 模擬帳戶,而每一步排除的是一種不同的出錯方式。四步都撐過來的報告,賺到了一個小部位;只撐過前兩步的,賺到的是再做一次測試。

  • 拿紀錄完整的東西來練習。已發布的 EA每一則都附上完整的平倉交易清單與執行清單,所以你可以自己把代表數字重算一遍,看清楚到底是哪些交易做出了它。這是唯一一項能讓這套讀法真正留在身上的練習。
  • 如果某個數字把你送回策略本身、而不是送回測試,那麼 Builder 才是規則本身被改動的地方。在設定上做搜尋又是另一件工作,寫在參數最佳化
  • 在你拿剛讀到的回撤數字去決定部位大小之前,EA 交易者的風險管理會把它換算成一筆入金與一個手數。
  • 我們如何產出、評分並記錄這一切,寫在我們的測試方法

測試器裡的過去結果不是預測,上面沒有任何一次執行是對接下來 12 個月的承諾。把一份報告讀對,它的意義比一個預測更小,但也更有用。它告訴你的是:什麼已經被展示出來了,而什麼只是被印出來而已。

常見問題

MT5 回測報告裡的獲利因子要多少才算好?
在你評斷這個數字之前,先問它涵蓋了哪些交易。本站公開的 23 份報告,每一份都落在 1.22 到 1.59 之間,而單獨一份報告內部的落差,比整個目錄的落差還大:orrery 在它被挑中的那 195 筆交易上是 1.28,把後來的 15 筆算進去之後變成 1.46。一個獲利因子要能講出它是幾筆交易做出來的、以及那些交易有沒有被拿來挑設定,它才開始有意義。低於大約 25 筆交易,它幾乎不帶任何資訊——我們 20 段上架後切片裡有 16 段就是這麼小,而它們的獲利因子從 0.72 到 6.43 都有。
為什麼我的 MT5 報告會出現兩個不一樣的回撤數字?
因為 MetaTrader 是分開量餘額曲線與權益曲線的,而權益把未平倉部位也算了進去。在我們 23 份報告裡,權益回撤每一次都是比較深的那一條;差距最大的是 cairn,餘額 14.52% 對權益 25.62%,也就是只引用餘額會藏起來的 11 個百分點。這個差距是這支 EA 怎麼抱部位的性質——chrysalis 那次執行的紀錄講得很白:它最多會抱著七個部位一起走進同一段走勢。還有第二個軸:MetaTrader 會同時印出 Maximal 與 Relative 兩種定義,而我們 16 次執行記錄的是 Maximal 那一組,5 次記錄的是 Relative 那一組。請引用權益那一行,並且把它是哪一個定義一起講出來。
勝率高就代表這支 EA 好嗎?
不代表,而我們自己這一組就是反例。在 23 份已公開的報告上,勝率與獲利因子的相關性是 0.37,也就是大部分的變異都沒有被解釋掉。nautical 的勝率是 30.80%,獲利因子仍然有 1.22;zerqon 贏了 78.26% 的交易,讀數是 1.43。最清楚的案例是 zerqon 後來發生的事:上架之後的 21 筆交易裡,它照樣贏了 76.19% 的時候,獲利因子卻是 0.72,虧了 61.47 USD。勝率告訴你的是交易分布的形狀,不是它的正負號。
別人用他自己的資料跑出來的回測報告可以相信嗎?
把它當成一項關於他們那份價格歷史的主張,而不是關於這支 EA 的主張。我們手上有一支 EA 在 tick 模型固定的情況下被兩邊都量過:tidewell-slack 在 Exness M1 歷史上公開的是 303 筆交易、獲利因子 1.35、回撤 9.92%,而同一支 EA 在同一段期間換成 Dukascopy 歷史,跑出的是 351 筆交易、1.13、回撤 18.18%——在同一道門檻底下不通過。接著把那次 Dukascopy 執行從產生的 tick 換成真實 tick,只移動了 0.02,到 1.11。移動判定的是資料來源,不是 tick 模型。在你問任何其他問題之前,先問這份報告是從哪一份價格歷史來的。