VALYNOXSTRATEGY RESEARCH TECHNOLOGY
AlphaPrimeAlphaPrime
策略學院 / 平台與匯出

MT4 策略轉換 MT5:要改什麼、為什麼

MT5 不載入 MQL4 檔案,所以轉換 MT4 策略,就是以 MQL5 重寫。規則不變,但委託變成委託、成交與部位,帳戶類型決定重複進場的行為,指標讀取改用控制代碼與緩衝區,移植後必須對照參考交易明細重新回測,才能用於實單交易。

作者 · 發佈 · 更新於 · 編輯原則

目錄
  1. MT4 的 EA 能直接在 MT5 執行嗎?
  2. MQL4 的委託模型與 MQL5 的部位模型有何不同?
  3. 淨額(Netting)或對沖(Hedging):轉換後的策略需要哪種帳戶類型?
  4. 指標與事件處理常式有哪些要重寫?
  5. MT5 回測結果為什麼與 MT4 不同?如何重新回測?
  6. 可依序照做的轉換檢查表
  7. 常見問題
  8. References

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 時有哪些改變一文,用另一組語言呈現同樣的模式。

項目MT4MT5
策略語言MQL4MQL5
檔案類型.mq4 原始碼、.ex4 編譯檔.mq5 原始碼、.ex5 編譯檔
交易模型委託委託、成交與部位
帳戶類型僅對沖模式淨額或對沖,由券商帳戶決定
策略測試器每次回測一個商品每次可測多個商品,多種逐筆報價模式
MT5 不載入 MT4 檔案:MT4 使用 MQL4,檔案為 .mq4 與 .ex4;MT5 使用 MQL5,檔案為 .mq5 與 .ex5;不經改寫,沒有任何東西能在兩者之間通用 MT5 不載入MT4 檔案 兩個平台,兩種語言 MT4 MQL4 .mq4 .ex4 MT5 MQL5 .mq5 .ex5 無法直接載入 是兩種語言,不是兩個版本。 所以:以 MQL5 重寫,再重新回測。
MT4 與 MT5 是兩個平台、兩種語言,不是同一個檔案的兩個版本。不經改寫,沒有任何東西能跨過檔案類型那一列。

最省手工翻譯的做法,是把規則存成不綁定任何一種語言的形式,再由它產生兩種版本。AlphaPrime(Valynox)以規則與參數保存策略,並由同一份定義產生 MQL4 與 MQL5 原始碼,因此存在其中的策略,透過平台匯出即可進入 MT5,無需逐行移植。手寫的 EA,則依本文其餘部分處理。

MQL4 的委託模型與 MQL5 的部位模型有何不同?

MQL4 把每筆持有中的交易視為一張委託,以單號平倉;MQL5 則把一筆交易拆成委託、成交與部位三種物件,因此策略中每一個開倉、修改與平倉步驟都得重新對應。移植後的 EA 多半壞在這裡,而且壞得很安靜:程式碼能編譯、能執行,只是修改了錯的物件。

在 MQL4,委託就是持有中的交易本身。送出後會取得單號(ticket),單號上記載手數、停損、停利與浮動損益。要調整停損,就選取該單號後修改;要出場,就平掉該單號。一個物件、一個單號,從進場到出場。

MQL5 的三種物件各司其職。委託是送往伺服器的買賣請求,帶有請求的手數、價格與停損價位,並有狀態,例如已掛出、已成交或已取消。成交是委託被執行的部分;一張委託分批成交時會產生多筆成交,每筆成交記錄實際成交的手數與價格。部位是成交之後持有的結果,帶有目前手數、停損、停利與浮動損益。已實現損益記在平掉部位的那筆成交上。

MQL4 中一張委託包含整筆交易;MQL5 中一筆交易由委託(請求)經成交(執行)到部位(持有),停損掛在部位上 一筆交易,三個物件 移植後停損掛在哪裡 MQL4 MQL5 委託 包辦整筆交易 委託 成交 部位 請求 成交 停損掛此 MQL5 將一筆交易拆成三份。 所以:停損要指向部位。
MQL5 中,一筆交易依序經過請求、成交與持有。停損與浮動損益在部位上;已實現損益在平倉的那筆成交上。

逐步對應如下:

  1. 開倉。MQL4:送出委託並保存其單號。MQL5:送出委託請求,等成交,再讀取由此產生的部位,保存的是部位單號,而不是委託單號。
  2. 讀取。MQL4:以迴圈走訪所有委託,逐一以單號選取。MQL5:以迴圈走訪該商品的部位;尚未成交的掛單放在另一份清單,還不算持有。
  3. 修改停損。MQL4:修改委託。MQL5:修改部位。仍以開倉委託為對象的常式,不會產生任何作用。
  4. 平倉。MQL4:平掉該單號。MQL5:送出一張參照該部位的反向委託;成交的那筆交易會平掉或減少部位。

淨額(Netting)或對沖(Hedging):轉換後的策略需要哪種帳戶類型?

淨額帳戶中,一個商品只有一個部位,再買一次是加碼,賣出則是減碼;對沖帳戶則像 MT4 一樣,各自保留獨立部位。因此做金字塔加碼,或同時持有多單與空單的策略,除非帳戶類型與策略邏輯相符,否則行為會不同。帳戶類型不由 EA 決定,而由券商帳戶決定;EA 可讀取帳戶的保證金模式,得知自己跑在哪一種帳戶上。

淨額帳戶,是同一商品的所有成交合併成單一部位、只有一個均價與一個總手數的帳戶。對沖帳戶,則是每一筆開倉成交都形成各自的部位,有各自的單號、停損與損益,所以同一商品可以同時存在兩筆多單,或一筆多單加一筆空單。MT4 只有後一種行為。MT5 兩種都支援,而且差別不只是外觀:它會改變報表出現哪些交易,以及每一筆顯示多少損益。

買 1 手、再買 1 手、賣 1 手之後,淨額帳戶只有一個多單部位,對沖帳戶則有兩個多單與一個空單 一套規則,兩種結果 買 1、買 1、賣 1 手之後 淨額帳戶 1 個部位 多單 對沖帳戶 3 個部位 多單 多單 空單 淨額合併,對沖全留。 所以:先選帳戶類型。
同樣三個訊號,在淨額帳戶得到一個合併後的部位,在對沖帳戶則得到兩個或三個獨立部位。程式碼必須寫明要的是哪一種結果。

假設性範例

某策略在 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 棒檢查所述是同一種洩漏。請對移植版執行該檢查。

部分MQL4MQL5
進入點init、start、deinit(較新的程式碼可能已使用 On 開頭的名稱)OnInit、OnTick、OnDeinit
指標讀取每次呼叫回傳一個值控制代碼只建立一次,數值從緩衝區複製
K 棒索引預設為時間序列順序,0 是目前這根 K 棒明確設定陣列方向
目前價格內建的 Bid、Ask 與價格陣列透過商品與價格資料函式讀取
交易事件在 start 中輪詢可用 OnTrade 與 OnTradeTransaction
規則不變,底層改寫:進入點由 start 移到 OnTick,指標讀取由一次呼叫改為控制代碼加複製的緩衝區,K 棒順序由最新在前改為自行設定的方向,交易事件由輪詢改為 OnTrade;每個 MQL5 儲存格都需要在每根 K 棒上檢查 規則不變,底層全新 MQL4 程式碼在 MQL5 的改動處 MQL4 MQL5 進入點 start() OnTick() 指標 一次呼叫 控制代碼+複製 K 棒 新到舊 設定方向 事件 輪詢 OnTrade() 讀錯 K 棒,數字看似合理。 所以:做單根 K 棒檢查。
同一個指標、同一條規則,底層不同。每個 MQL5 儲存格,都是單根 K 棒的位移可能悄悄混入的地方。

事件處理常式一對一對應,兩個平台的 OnTick 都仍在每筆報價時執行。要在每根 K 棒只動作一次的策略,兩種語言都需要新 K 棒檢查,這段邏輯原樣帶過去即可。交易事件則不同:MQL4 程式碼要在下一筆報價輪詢委託清單,才知道停損已觸發;MQL5 還可以透過 OnTrade 或 OnTradeTransaction 得到通知。直接移植時,可以繼續用部位函式輪詢;改用事件屬於設計變更,而設計變更該放在交易明細對齊之後,不是移植期間。

MT5 回測結果為什麼與 MT4 不同?如何重新回測?

即使移植正確,報表也會不同,因為兩個測試器建構報價、價差、保證金與成交的方式不一樣。因此應把 MT5 的結果當成一次新的回測,用相同成本與參考回測的交易明細比對,而不是等舊數字回來。MT4 測試器以一分鐘 K 棒合成報價,只用一個價差值;MT5 測試器提供多種報價模式,可重播記錄下來的價差,保證金與隔夜利息(swap)取自商品設定,也能分批成交。同一條進場規則,進出時遇到的價格就不同。

要回答的問題不是「淨損益是否相同」,而是「移植版是否在相同的 K 棒、朝相同方向觸發」。同一根 K 棒上成交價不同,來自測試器,屬預期之內。一筆交易只出現在其中一份明細,或提早一根 K 棒出場,則來自移植,必須修正。把差異分成這兩組,就是整個重新回測的工作。

移植後的兩類差異:部位對應錯誤、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%
參考用的權益曲線與回撤。與移植後策略的回測比較時,看形狀與交易日期,不看最終數字。
參考用的權益曲線與回撤。與移植後策略的回測比較時,看形狀與交易日期,不看最終數字。 NQ · 日 K 棒 · 2019-01-02 至 2025-06-30 · CPU 引擎回測

這次回測適合當參考,靠的是規模與設定,不是獲利。六年半六十筆交易,一個下午就能逐筆核對。部位持有時間占比 85.7%,表示這條規則幾乎隨時都有部位,所以上一節的淨額與對沖問題對它很重要:它是由多翻空,而不是空手;移植版在淨額帳戶必須一步反轉部位,在對沖帳戶則要平掉一筆、再開另一筆。請在相同的日 K 棒上,以 $20 手續費與 $10 滑價執行 MT4 原版與 MT5 移植版,作法見回測中的手續費、滑價與平均每筆損益,再把三份交易明細並排。同樣的比對方法,針對另一個平台寫成的是如何把策略匯入 MultiCharts 並對齊回測。Pardo(2008)描述,策略的實作一有改動就重新評估,屬於正常評估週期的一部分,不是額外的工作。

可依序照做的轉換檢查表

依序進行:固定規則、選定帳戶類型、將委託對應到部位、重建指標控制代碼、移植事件處理常式、以相同 K 棒與相同成本重新回測,並在任何實單交易之前比對交易明細。順序很重要,因為每一步都固定下一步所依賴的決定;先對應委託、再選帳戶類型,就得對應兩次。

  1. 固定規則與設定。寫下 MT4 版本的每個參數、交易時段濾網、停損與出場。若策略是以規則形式存在於策略生成軟體,而非手寫程式碼,此時可由規則產生 MT5 的 EA,而不是翻譯 MQL4 程式碼,再從步驟 6 接續。
  2. 選擇淨額或對沖。依帳戶類型一節的表格決定。測試前先開立該類型的 MT5 帳戶,因為測試器採用帳戶的保證金模式。
  3. 把委託對應到部位與成交。以部位為對象,重寫開倉、讀取、修改與平倉。保存部位單號。每一次停損變更都指向部位。
  4. 重建指標控制代碼。在 OnInit 中各建立一次控制代碼,在 OnTick 中複製足夠數量的數值,設定陣列方向,並以單根 K 棒檢查確認規則讀的是最近一根已收盤的 K 棒。
  5. 移植 OnInit、OnTick 與 OnDeinit。新 K 棒邏輯原樣帶過去。這一輪仍以輪詢取得交易狀態;事件處理常式可以之後再做。
  6. 以相同 K 棒、相同成本重新回測。MT4 測試器、MT5 測試器與參考回測,使用相同商品、相同 K 棒週期、相同日期範圍、相同手續費與滑價。
  7. 比對交易明細。以進場 K 棒與方向逐筆配對。成交價差異屬於測試器。缺少、多出或位移的交易,要回到步驟 3。
七步轉換流程:固定規則、選擇帳戶類型、對應部位、重建指標、移植事件處理常式、重新回測並比對交易明細;不一致時,實單交易前先回到步驟 3 七步驟,一道關卡 實單前交易明細必須一致 12 34 56 7 固定 部位 事件 比對 帳戶 指標 重新回測 實單 不一致:回步驟 3 不一致代表對應有誤。 所以:修步驟 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.