Skip to main content
On this page

Convert MQL4 to MQL5: Events, Indicators and Trade Semantics

· 7 min read
Pineify Team
Pine Script and AI trading workflow research team

Converting MQL4 to MQL5 means preserving a program's intended behavior on MetaTrader 5, not merely renaming functions until it compiles. The main migration risks are data timing, indicator access and the relationship between orders, deals and positions.

Start with a concrete reason to migrate, such as a broker or platform requirement. This guide does not establish a universal MT4 shutdown deadline or a fixed speed advantage for converted programs.

Convert MQL4 to MQL5: The Complete Trader's Guide for Migration

Establish what the existing program does​

Collect the source, include files, custom indicators, external dependencies and input settings. Record the terminal build, broker symbol, timeframe and account assumptions. A compiled executable without its corresponding source is not an equivalent migration input.

For each trading decision, specify which bar or tick supplies the information. Identify whether the EA acts on every tick, once per bar, at a session boundary or after a trade event. Preserve these choices before changing implementation details.

MetaQuotes' migration reference is a starting point for language and API differences. Avoid outdated shorthand: modern MQL4 already supports object-oriented programming and named event handlers. It is not limited to procedural, single-symbol or single-timeframe logic.

Map events by program type​

Older MQL4 source may use legacy initialization and start functions; newer source may already use OnInit, OnTick or OnCalculate. Inspect the code rather than applying a global name replacement.

Program responsibilityMQL5 event to inspect
Initialize an EA or indicatorOnInit
Process a new chart-symbol tick in an EAOnTick
Calculate an indicatorOnCalculate
Run a one-off scriptOnStart
Release resources during deinitializationOnDeinit

The handler's return type and parameters must match the event contract. An indicator's calculation loop and an EA's tick handler are different workloads. Also preserve any timer, chart-event or trade-event behavior used by the original program.

Replace value-returning indicator calls with managed handles​

Many MQL4 indicator calls return a value for a selected shift. In MQL5, the corresponding function generally creates an indicator handle; data is then read from its buffers. Verify the exact function's documentation rather than assuming one mechanical signature conversion.

A useful review sequence is:

  1. Create and validate the handle during initialization where appropriate.
  2. Confirm that enough data has been calculated before using it.
  3. Request the intended buffer and bar range.
  4. Check the number of copied values and handle unavailable data explicitly.
  5. Release resources when appropriate.

MetaQuotes' CopyBuffer documentation defines starting position zero as the current bar. It also states that copied data is placed with the oldest copied element first in physical memory, regardless of the receiving array's series flag. Therefore, requesting two values does not by itself establish which logical index your later code should read.

Skipping a failed or incomplete copy is different from trading with a stale or default value. Make that failure behavior explicit.

Verify indexing with timestamps​

For series-style indexing, logical index zero refers to the newest bar. Describing that as "oldest to newest" is contradictory. Ordinary arrays and indicator buffers require explicit attention to their indexing convention.

ArraySetAsSeries changes the indexing flag for supported arrays; it does not make every array eligible. Static and multidimensional arrays cannot receive that flag. Check buffer-binding behavior and set the intended convention at the appropriate point.

Before evaluating a trading condition, log the timestamp beside each price and indicator value. Compare the same completed bar on both platforms. This catches a one-bar shift more directly than comparing two final profit totals.

Separate orders, deals and positions​

An order is an instruction; a deal records an execution; a position represents exposure. MQL5 exposes these through different APIs. Decide which object the original MQL4 loop actually intended to examine before replacing it.

Account mode is central. MetaQuotes documents netting and hedging accounts: netting permits one position per symbol, while hedging can permit multiple positions, including opposing directions. Inspect the account's margin mode; do not assume hedging can be enabled with a local EA setting.

The standard-library CTrade class can simplify request construction, but it is optional. Direct trade requests are another approach. Crucially, CTrade Buy returning true does not prove a trade was executed. Inspect the server result code and relevant deal information, then reconcile the resulting account state.

For a hedging account, closing or modifying by symbol can differ from targeting a particular ticket. Preserve the intended symbol, strategy identifier and position-selection rule. Avoid changing another strategy's exposure during migration tests.

Recheck broker constraints and units​

Use the target symbol's documented properties for volume minimum/maximum/step, tick size, contract specification, stops and permitted filling modes. A pip, point and tick are not automatically the same unit.

A request that compiled can still be rejected because its volume, price or stop is invalid for that symbol. Include the request, result and observed position in diagnostics rather than treating any failure as a language-conversion error.

Validate in layers​

First compile in MetaEditor and review errors and warnings. Then compare deterministic values and signal timestamps before attempting to reproduce trades. Finally compare orders, fills, position changes and costs under aligned test conditions.

When results diverge, locate the first different decision. Possible causes include different price feeds, spread assumptions, session cutoffs, available ticks, bar indexing or account semantics. A difference is not automatically an improvement merely because the target is MT5.

Retain a migration record with source hashes, inputs, terminal builds and test dates. After historical checks, a demo forward run can reveal operational issues such as restarts, unavailable data or rejected requests. It remains a simulation and does not establish future profitability.

Using AI assistance​

Pineify's MQL5 Coding Agent can help draft and revise MQL5 source. Its workflow includes MQL5 reference context and syntax-check tooling when enabled; that is different from evidence that a model was trained exclusively on MQL5.

Provide the original dependencies, program type, account mode and timing specification. Ask for a change explanation and inspect the final diagnostics. No verified 30-second conversion time or universal compilability rate is supplied here.

Compatibility headers and other converters also need version-specific evaluation. Without a named implementation and test set, a "65% success rate" is not meaningful evidence for choosing a migration tool.

Pineify Website

Frequently asked questions​

Is MQL4 procedural only?

No. Modern MQL4 supports classes and other object-oriented features, as well as named event handlers. Migration work depends on the actual source version and APIs used.

Must I use CTrade in MQL5?

No. It is a standard-library convenience layer. Direct trade requests are also possible, and either approach needs result-code and account-state checks.

Can I assume MT5 is a hedging account?

No. Read the account mode and design the program for its netting or hedging semantics. It is not a universal local toggle.

Does a successful compile mean the migration is complete?

No. Validate data access, signal timing, request handling and position behavior. Compare the first divergence under aligned conditions before interpreting return differences.