Migrate MT4 EAs to MT5: Complete Code Conversion Guide

Step-by-step guide to convert your MT4 Expert Advisors and indicators to MT5. Learn MQL4 vs MQL5 syntax differences, platform features, and common pitfalls.

migrate-mt4-eas-to-mt5-complete-code-conversion

Introduction

If you’ve built or purchased Expert Advisors (EAs) and indicators for MetaTrader 4, you know the platform is reliable but limited. MetaTrader 5 offers superior backtesting (multi-threaded, tick-level), 21 timeframes, more order types (market, limit, stop), and a built-in economic calendar. The catch: MQL4 code does not run on MT5. This guide walks you through the MT4 to MT5 conversion process, covering syntax changes, order functions, and indicator handling. By the end, you’ll be able to migrate your own EA migration projects with confidence.

Prerequisites

Before starting, ensure you have:

  • MetaTrader 5 installed (free from your broker or the MetaQuotes website).
  • MetaEditor 5 (comes with MT5).
  • The original MQL4 source code (.mq4 files) for your EAs and indicators. Compiled .ex4 files cannot be converted.
  • A demo account with an MT5 broker (to test the converted code).
  • Basic familiarity with the MetaEditor interface and MQL language concepts.

Step-by-Step Instructions

Step 1: Create a New MQL5 Project

Open MetaEditor 5 (press F4 in MT5 or launch from the Start menu). Go to File > New > Expert Advisor (or Indicator). Give it the same name as your MT4 file. This creates a skeleton file with the correct MQL5 structure.

Step 2: Copy Code Structure

Open your original .mq4 file alongside the new .mq5 file. Copy the #property directives, global variables, and input parameters. Note that MQL5 uses slightly different property names:

  • #property indicator_chart_window (same)
  • #property indicator_buffers (same)
  • #property indicator_plots (MQL5 only, replaces indicator_separate_window in some cases)
  • For EAs, #property version is optional in MQL5 but recommended.

Step 3: Convert Order Functions (The Biggest Change)

This is where most of the work lies. MQL4 uses a single set of order functions (OrderSend, OrderSelect, etc.) while MQL5 uses a position-based model with separate trade classes. Here’s a conversion table:

MQL4 Function MQL5 Replacement Notes
OrderSend() CTrade::PositionOpen() or OrderSend() (deprecated) Use the CTrade class; avoid the legacy OrderSend() function.
OrderSelect() PositionSelect() or HistorySelect() Positions and orders are separate in MQL5.
OrderModify() CTrade::PositionModify() or OrderModify() (for pending orders) Modify stop loss/take profit on positions; modify price on pending orders.
OrderClose() CTrade::PositionClose() Specify the position ticket.
OrdersTotal() PositionsTotal() Returns number of open positions.
OrderTicket() PositionGetTicket() Use with a loop to iterate positions.

Example conversion: In MQL4, you might have:

int ticket = OrderSend(Symbol(), OP_BUY, 0.1, Ask, 3, 0, 0, "My EA", 0, 0, Green);

In MQL5, use the CTrade class:

#include <Trade\Trade.mqh>
CTrade trade;
double price = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
if(trade.Buy(0.1, _Symbol, price, 0, 0, "My EA"))
   Print("Buy order placed, ticket: ", trade.ResultOrder());

Step 4: Convert Indicator Buffers and Plots

MQL5 requires explicit buffer arrays and plot indices. In MQL4, you declare buffer arrays and use SetIndexBuffer(). In MQL5, the same function exists but you must also set PlotIndexSetInteger() for colors and styles. Example:

MQL4:

double Buffer1[];
SetIndexBuffer(0, Buffer1);
SetIndexStyle(0, DRAW_LINE);

MQL5:

double Buffer1[];
SetIndexBuffer(0, Buffer1, INDICATOR_DATA);
PlotIndexSetInteger(0, PLOT_DRAW_TYPE, DRAW_LINE);

Also, MQL5 uses #property indicator_plots to define the number of plot lines (distinct visual series), separate from buffer count.

Step 5: Handle Time and Bar Indexing

MQL5 uses CopyRates() and CopyClose() instead of iClose() series functions. For example:

  • iClose(Symbol(), PERIOD_H1, 1) becomes CopyClose(Symbol(), PERIOD_H1, 1, 1, buffer) then read buffer[0].
  • iTime() becomes CopyTime().
  • iHigh() becomes CopyHigh().

Note that MQL5 bar indexing starts at 0 (current forming bar) just like MQL4, but CopyRates() returns data from newest to oldest by default.

Step 6: Test in Strategy Tester

After converting, compile the code (F7 in MetaEditor). Fix any errors. Then open the MT5 Strategy Tester (Ctrl+R), select your EA, choose a symbol and timeframe, and run a single backtest. Check the Journal tab for errors and the Results tab for trade history. Compare with your MT4 results to verify consistency.

Tips and Best Practices from Experience

  • Start with a simple EA first. If you have multiple EAs, convert the simplest one to learn the patterns.
  • Use the same variable names where possible to minimize confusion. MQL5 is case-sensitive; MQL4 is not.
  • Leverage the Trade class. The CTrade class handles slippage, magic number, and comment automatically. It’s more reliable than raw OrderSend() in MQL5.
  • Check the MQL5 Reference in MetaEditor (F1) for function prototypes. The built-in help is excellent.
  • Convert indicators first if your EA uses custom indicators. Custom indicator calls change from iCustom() (MQL4) to CopyBuffer() (MQL5).
  • Use #include for libraries. MQL5 supports include files; move common functions (like money management) to a separate .mqh file.

Common Mistakes and Troubleshooting

Mistake 1: Forgetting to Include the Trade Library

If you get “‘trade’ – undeclared identifier”, you forgot #include <Trade\Trade.mqh> at the top of your EA.

Mistake 2: Using MQL4 Order Functions Directly

MQL5 still has OrderSend() but it’s deprecated. It may work for simple cases but fails with multiple positions. Always use the CTrade class.

Mistake 3: Incorrect Bar Indexing in Indicators

In MQL5, the OnCalculate() function receives rates_total and prev_calculated. The first call has prev_calculated = 0. Make sure you handle the initial calculation correctly. A common fix:

int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
{
   if(prev_calculated == 0)
   {
      // Initial calculation
      ArrayInitialize(Buffer1, EMPTY_VALUE);
   }
   // ... rest of calculation
}

Mistake 4: Not Updating SymbolInfo Calls

MQL4 uses MarketInfo(); MQL5 uses SymbolInfoDouble() and SymbolInfoInteger(). Convert all MarketInfo(Symbol(), MODE_SPREAD) to SymbolInfoInteger(_Symbol, SYMBOL_SPREAD).

Mistake 5: Ignoring Time Conversions

In MQL5, TimeCurrent() returns server time; TimeTradeServer() is also available. For bar times, use CopyTime() rather than assuming iTime() works.

Summary and Next Steps

You’ve learned the core differences between MQL4 and MQL5, converted order functions, adapted indicator buffers, and tested your migrated code. The key takeaway: MT4 to MT5 conversion is systematic, not magical. Focus on the order model (position vs. order), the trade class, and the new time/series functions.

Next steps:

  • Convert a second, more complex EA to solidify your skills.
  • Explore MT5-specific features like multi-threaded backtesting and hedging mode.
  • Join the MQL5 community forum for additional support.
  • Consider using the built-in MT4 to MT5 Converter tool in MetaEditor (Tools > Convert MQL4 to MQL5) as a starting point, but always review the output manually.

With practice, you’ll be able to migrate any MQL4 to MQL5 project in a few hours.

Frequently Asked Questions

Can I run MT4 EAs directly on MT5 without conversion?

No. MT5 uses a completely different executable format (.ex5 vs .ex4) and a different API. You must convert the source code (.mq4 to .mq5) and recompile.

Is there an automatic tool to convert MQL4 code to MQL5?

MetaEditor includes a “Convert MQL4 to MQL5” tool under Tools menu. It handles basic syntax (like function renames) but fails on complex order logic, custom indicators, and file operations. Always review and test the output.

Will my converted EA produce identical results on MT5?

Not always. Differences in order execution (instant vs. request), tick generation, and bar indexing can cause slight variations. Always compare backtest statistics and trade logs between platforms.

Do I need to convert my indicators separately from my EAs?

Yes. If your EA calls custom indicators via iCustom() in MQL4, you must convert those indicators to MQL5 and use CopyBuffer() to access their values

Community

Clap for the article and open comments only when you want to read them.

0 claps0 comments

Related articles