MT4 策略轉換 MT5:要改什麼、為什麼
MT5 不載入 MQL4 檔案,所以轉換 MT4 策略,就是以 MQL5 重寫。規則不變,但委託變成委託、成交與部位,帳戶類型決定重複進場的行為,指標讀取改用控制代碼與緩衝區,移植後必須對照參考交易明細重新回測,才能用於實單交易。
作者 Soren Huang · 發佈 · 更新於 · 編輯原則
目錄
MT4 的 EA 能直接在 MT5 執行嗎?
要把 MT4 策略轉換到 MT5,就得以 MQL5 重寫:MT5 不載入 MQL4 檔案。規則不變,但交易模型、指標呼叫與事件處理常式都會改變,結果也必須重新回測,因為即使移植正確,MT5 測試器報出的數字也不同。
自動交易程式(Expert Advisor,EA)是在 MetaTrader 內執行、依規則下單的程式。在 MT4 以 MQL4 撰寫,編譯成 .ex4 檔;在 MT5 以 MQL5 撰寫,編譯成 .ex5 檔。MT5 既不開啟 .mq4,也不開啟 .ex4。兩種語言外觀都像 C 語系,迴圈與 if 敘述兩邊寫法相同,所以移植乍看工程不大。其實不小,因為與券商和圖表相關的部分,建構方式不同。
可用一個比喻來看:策略是家具,平台是公寓。從 MT4 搬到 MT5,不是把箱子從這個架子搬到另一個架子,而是把同樣的家具搬進格局不同的大樓。每件家具仍然放得進去,但每一件都要重新擺放,住進去之前也要確認房間能用。策略在其他平台之間搬移時也一樣;把策略從 EasyLanguage 移到 PowerLanguage 時有哪些改變一文,用另一組語言呈現同樣的模式。
| 項目 | MT4 | MT5 |
|---|---|---|
| 策略語言 | MQL4 | MQL5 |
| 檔案類型 | .mq4 原始碼、.ex4 編譯檔 | .mq5 原始碼、.ex5 編譯檔 |
| 交易模型 | 委託 | 委託、成交與部位 |
| 帳戶類型 | 僅對沖模式 | 淨額或對沖,由券商帳戶決定 |
| 策略測試器 | 每次回測一個商品 | 每次可測多個商品,多種逐筆報價模式 |
最省手工翻譯的做法,是把規則存成不綁定任何一種語言的形式,再由它產生兩種版本。AlphaPrime(Valynox)以規則與參數保存策略,並由同一份定義產生 MQL4 與 MQL5 原始碼,因此存在其中的策略,透過平台匯出即可進入 MT5,無需逐行移植。手寫的 EA,則依本文其餘部分處理。
MQL4 的委託模型與 MQL5 的部位模型有何不同?
MQL4 把每筆持有中的交易視為一張委託,以單號平倉;MQL5 則把一筆交易拆成委託、成交與部位三種物件,因此策略中每一個開倉、修改與平倉步驟都得重新對應。移植後的 EA 多半壞在這裡,而且壞得很安靜:程式碼能編譯、能執行,只是修改了錯的物件。
在 MQL4,委託就是持有中的交易本身。送出後會取得單號(ticket),單號上記載手數、停損、停利與浮動損益。要調整停損,就選取該單號後修改;要出場,就平掉該單號。一個物件、一個單號,從進場到出場。
MQL5 的三種物件各司其職。委託是送往伺服器的買賣請求,帶有請求的手數、價格與停損價位,並有狀態,例如已掛出、已成交或已取消。成交是委託被執行的部分;一張委託分批成交時會產生多筆成交,每筆成交記錄實際成交的手數與價格。部位是成交之後持有的結果,帶有目前手數、停損、停利與浮動損益。已實現損益記在平掉部位的那筆成交上。
逐步對應如下:
- 開倉。MQL4:送出委託並保存其單號。MQL5:送出委託請求,等成交,再讀取由此產生的部位,保存的是部位單號,而不是委託單號。
- 讀取。MQL4:以迴圈走訪所有委託,逐一以單號選取。MQL5:以迴圈走訪該商品的部位;尚未成交的掛單放在另一份清單,還不算持有。
- 修改停損。MQL4:修改委託。MQL5:修改部位。仍以開倉委託為對象的常式,不會產生任何作用。
- 平倉。MQL4:平掉該單號。MQL5:送出一張參照該部位的反向委託;成交的那筆交易會平掉或減少部位。
淨額(Netting)或對沖(Hedging):轉換後的策略需要哪種帳戶類型?
淨額帳戶中,一個商品只有一個部位,再買一次是加碼,賣出則是減碼;對沖帳戶則像 MT4 一樣,各自保留獨立部位。因此做金字塔加碼,或同時持有多單與空單的策略,除非帳戶類型與策略邏輯相符,否則行為會不同。帳戶類型不由 EA 決定,而由券商帳戶決定;EA 可讀取帳戶的保證金模式,得知自己跑在哪一種帳戶上。
淨額帳戶,是同一商品的所有成交合併成單一部位、只有一個均價與一個總手數的帳戶。對沖帳戶,則是每一筆開倉成交都形成各自的部位,有各自的單號、停損與損益,所以同一商品可以同時存在兩筆多單,或一筆多單加一筆空單。MT4 只有後一種行為。MT5 兩種都支援,而且差別不只是外觀:它會改變報表出現哪些交易,以及每一筆顯示多少損益。
假設性範例
某策略在 100.00 買進 1 手,在 102.00 加碼 1 手,再於 103.00 賣出 1 手。在淨額帳戶,部位由 1 手變成 2 手,均價 101.00,賣出後減為 1 手,已平倉部分實現損益 2.00 點。在對沖帳戶,兩筆買進是兩個部位;若程式碼平掉第一個單號,已實現損益為 3.00 點,102.00 開的 1 手部位仍留著;若程式碼只是送出賣單,則會新開一筆 1 手空單,三個部位全部留在帳上。同一套規則,三種不同的交易明細。
| 策略行為 | 淨額帳戶 | 對沖帳戶 |
|---|---|---|
| 一次只有一個部位,交易之間空手 | 與 MT4 相同 | 與 MT4 相同 |
| 金字塔加碼(獲利時加碼) | 加碼合成一個部位,只有一個均價與一個停損 | 每次加碼各自保有停損與損益 |
| 部分出場 | 減少合併後的部位 | 程式碼必須指明平哪個單號 |
| 同時持有多單與空單 | 不可能;兩者互相抵銷 | 可以,與 MT4 相同 |
寫下第一行 MQL5 之前,先決定帳戶類型,因為它決定上一節的平倉與修改步驟怎麼寫。若策略在交易之間空手,兩種類型得到相同的交易明細。若策略有加碼或同時持有兩個方向,要嘛選對沖帳戶以保留 MT4 的行為,要嘛為淨額帳戶重寫部位大小與出場邏輯,並接受不同的交易明細。各平台如何處理部位與帳戶類型,是各自動交易平台有何差異一文涵蓋的重點之一。
指標與事件處理常式有哪些要重寫?
MQL4 每次詢問,都以一次呼叫回傳一個指標值;MQL5 則先建立一次指標控制代碼(handle),再從緩衝區複製數值。init、start、deinit 等進入點也改成 OnInit、OnTick 與 OnDeinit,因此每一處指標讀取與每一個時序假設,都要在每根 K 棒上檢查。規則本身不變。變的是程式碼取得規則所用數字的方式。
指標控制代碼,是指向終端機替你計算之指標的參照;通常在 OnInit 中建立一次,之後依需要從它的緩衝區複製任意數量的數值到陣列。在 MQL4,移動平均線的呼叫要指明商品、K 棒週期、期數與第幾根 K 棒,回傳一個數字。在 MQL5,同一條移動平均線只建立一次控制代碼,每筆報價再複製例如最近三個值到陣列,並從陣列讀取。複製的數值少於規則所需,或在緩衝區尚未備妥時就讀取,會得到看似合理的錯誤數字。
K 棒索引是第二個陷阱。MQL4 的內建價格陣列與指標呼叫由後往前數:索引 0 是目前這根 K 棒,索引 1 是最近一根已收盤的 K 棒。MQL5 複製出來的陣列預設由最舊排到最新,除非你把它設為時間序列。移植時若沿用 MQL4 的索引習慣、卻沒設定方向,讀到的就是錯的那根 K 棒,常是尚未走完的目前這根,而不是最近一根已收盤的;這與前視偏誤與單根 K 棒檢查所述是同一種洩漏。請對移植版執行該檢查。
| 部分 | MQL4 | MQL5 |
|---|---|---|
| 進入點 | init、start、deinit(較新的程式碼可能已使用 On 開頭的名稱) | OnInit、OnTick、OnDeinit |
| 指標讀取 | 每次呼叫回傳一個值 | 控制代碼只建立一次,數值從緩衝區複製 |
| K 棒索引 | 預設為時間序列順序,0 是目前這根 K 棒 | 明確設定陣列方向 |
| 目前價格 | 內建的 Bid、Ask 與價格陣列 | 透過商品與價格資料函式讀取 |
| 交易事件 | 在 start 中輪詢 | 可用 OnTrade 與 OnTradeTransaction |
事件處理常式一對一對應,兩個平台的 OnTick 都仍在每筆報價時執行。要在每根 K 棒只動作一次的策略,兩種語言都需要新 K 棒檢查,這段邏輯原樣帶過去即可。交易事件則不同:MQL4 程式碼要在下一筆報價輪詢委託清單,才知道停損已觸發;MQL5 還可以透過 OnTrade 或 OnTradeTransaction 得到通知。直接移植時,可以繼續用部位函式輪詢;改用事件屬於設計變更,而設計變更該放在交易明細對齊之後,不是移植期間。
MT5 回測結果為什麼與 MT4 不同?如何重新回測?
即使移植正確,報表也會不同,因為兩個測試器建構報價、價差、保證金與成交的方式不一樣。因此應把 MT5 的結果當成一次新的回測,用相同成本與參考回測的交易明細比對,而不是等舊數字回來。MT4 測試器以一分鐘 K 棒合成報價,只用一個價差值;MT5 測試器提供多種報價模式,可重播記錄下來的價差,保證金與隔夜利息(swap)取自商品設定,也能分批成交。同一條進場規則,進出時遇到的價格就不同。
要回答的問題不是「淨損益是否相同」,而是「移植版是否在相同的 K 棒、朝相同方向觸發」。同一根 K 棒上成交價不同,來自測試器,屬預期之內。一筆交易只出現在其中一份明細,或提早一根 K 棒出場,則來自移植,必須修正。把差異分成這兩組,就是整個重新回測的工作。
有一份參考回測,分類會容易得多。參考回測,是在兩個終端機之外,以相同規則、相同 K 棒、固定手續費與滑價、下一根 K 棒成交所產生的回測,這樣 MT4 與 MT5 的報表都不是裁判。下面這次回測就是這類參考的樣子。它測試 NQ 日 K 棒,期間為 2019-01-02 至 2025-06-30,多空皆做,一口,每筆交易手續費 $20、滑價 $10。進出場只用 Trend Cycle Oscillator 一條規則,沒有停損、停利或濾網,作為待移植策略的替身,並非本文的主題。它是搜尋嘗試約一千個後留下的唯一候選策略,留下它是因為報酬相對於回撤的表現;事後挑出留下的那一個,會高估它的表現,Bailey、Borwein、López de Prado 與 Zhu(2014)指出這種挑選加成可以有多大。這裡的任何內容都不表示這條規則賺到了那些錢,也不表示讀者可以期待同樣結果。
來源:AlphaPrime 產品引擎(CPU),2026-10-31 執行。NQ 日線,2019-01-02 至 2025-06-30,多空都做,1 口,每筆手續費 $20、滑價 $10。
| 項目 | 結果 |
|---|---|
| 淨損益(已平倉交易) | $251,455 |
| 最大回撤 | $114,205 |
| 交易筆數 | 60 |
| 勝率 | 63.33% |
| 獲利因子 | 1.864 |
| 平均每筆損益 | $4,190.92 |
| 部位持有時間占比 | 85.7% |

這次回測適合當參考,靠的是規模與設定,不是獲利。六年半六十筆交易,一個下午就能逐筆核對。部位持有時間占比 85.7%,表示這條規則幾乎隨時都有部位,所以上一節的淨額與對沖問題對它很重要:它是由多翻空,而不是空手;移植版在淨額帳戶必須一步反轉部位,在對沖帳戶則要平掉一筆、再開另一筆。請在相同的日 K 棒上,以 $20 手續費與 $10 滑價執行 MT4 原版與 MT5 移植版,作法見回測中的手續費、滑價與平均每筆損益,再把三份交易明細並排。同樣的比對方法,針對另一個平台寫成的是如何把策略匯入 MultiCharts 並對齊回測。Pardo(2008)描述,策略的實作一有改動就重新評估,屬於正常評估週期的一部分,不是額外的工作。
可依序照做的轉換檢查表
依序進行:固定規則、選定帳戶類型、將委託對應到部位、重建指標控制代碼、移植事件處理常式、以相同 K 棒與相同成本重新回測,並在任何實單交易之前比對交易明細。順序很重要,因為每一步都固定下一步所依賴的決定;先對應委託、再選帳戶類型,就得對應兩次。
- 固定規則與設定。寫下 MT4 版本的每個參數、交易時段濾網、停損與出場。若策略是以規則形式存在於策略生成軟體,而非手寫程式碼,此時可由規則產生 MT5 的 EA,而不是翻譯 MQL4 程式碼,再從步驟 6 接續。
- 選擇淨額或對沖。依帳戶類型一節的表格決定。測試前先開立該類型的 MT5 帳戶,因為測試器採用帳戶的保證金模式。
- 把委託對應到部位與成交。以部位為對象,重寫開倉、讀取、修改與平倉。保存部位單號。每一次停損變更都指向部位。
- 重建指標控制代碼。在 OnInit 中各建立一次控制代碼,在 OnTick 中複製足夠數量的數值,設定陣列方向,並以單根 K 棒檢查確認規則讀的是最近一根已收盤的 K 棒。
- 移植 OnInit、OnTick 與 OnDeinit。新 K 棒邏輯原樣帶過去。這一輪仍以輪詢取得交易狀態;事件處理常式可以之後再做。
- 以相同 K 棒、相同成本重新回測。MT4 測試器、MT5 測試器與參考回測,使用相同商品、相同 K 棒週期、相同日期範圍、相同手續費與滑價。
- 比對交易明細。以進場 K 棒與方向逐筆配對。成交價差異屬於測試器。缺少、多出或位移的交易,要回到步驟 3。
今天就從步驟 6 的 MT4 一側開始:在固定日期範圍、固定成本下執行原版 EA,匯出交易明細,數出交易筆數。這份明細是之後每次 MT5 回測的衡量基準;移植開始前就備好,才能把「數字看起來不一樣」變成一份要檢查的具體 K 棒清單。
常見問題
MT4 的 EA 能在 MT5 執行嗎?
不能。MT5 不載入 .mq4 原始碼檔或 .ex4 編譯檔,MT4 也不載入 .mq5 或 .ex5 檔。MT4 的 EA 必須以 MQL5 重寫,並在 MT5 編輯器中編譯。規則可以不變,但兩種語言的交易函式、指標呼叫與進入點並不相同。
MQL4 轉 MQL5 時,哪些必須改?
有四個面向要改。交易處理由單一委託改為委託、成交與部位,所以開倉、修改與平倉都要針對部位重寫。指標讀取由每次呼叫回傳一個值,改為只建立一次控制代碼、再從緩衝區複製數值。進入點改為 OnInit、OnTick 與 OnDeinit。陣列索引方向必須明確設定,因為複製出來的陣列預設不是時間序列順序。
MT5 的淨額帳戶與對沖帳戶有何差異?
淨額帳戶中,同一商品的所有成交合併為一個部位、只有一個均價,所以再買一次是加碼,賣出是減碼。對沖帳戶中,每筆開倉成交都形成各自的部位,有各自的停損與損益,所以可同時持有兩筆多單,或一多一空,MT4 正是這樣運作。帳戶類型由券商帳戶決定,會加碼或同時持有兩個方向的策略,必須選擇與其邏輯相符的類型。
同一策略在 MT5 的回測結果為什麼和 MT4 不同?
兩個策略測試器對市場的建模方式不同。MT4 以一分鐘 K 棒合成報價,只用一個價差值;MT5 提供多種報價模式,可重播記錄下來的價差,保證金與隔夜利息取自商品設定,也能分批成交。因此,正確的移植版會以略有差異的價格成交,並回報不同的權益曲線。請依進場 K 棒與方向比對交易明細,以區分這些測試器差異與真正的移植錯誤。
References
- 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.
- Pardo, R. (2008). The Evaluation and Optimization of Trading Strategies (2nd ed.). John Wiley & Sons.

