Skip to content

Trading & Fintech

Building MT4/MT5 Expert Advisors in MQL5, Step by Step

How to specify, structure, test and hand over a MetaTrader Expert Advisor in MQL5 without treating a backtest as a promise of profit.

Prakash Tank

Prakash Tank

October 28, 2026 · 11 min read

MetaTrader 4 and MetaTrader 5 still run a large share of retail FX and CFD automation. If you are a founder or CTO hiring an agency to build an Expert Advisor, the useful question is not “can you code MQL5?” It is whether they can design an EA that fails closed, logs enough to debug a Sunday gap, and never confuses a backtest with a live account.

This is a step-by-step build sequence for MT4/MT5 Expert Advisors in MQL5 (with notes where MT4/MQL4 still differs). DayDecoder is a founder-led software company in Ahmedabad; we treat EAs as software products, not magic money machines. See our trading and investing work and custom software development if you want this built into a maintainable codebase.

Risk disclaimer. Trading foreign exchange, CFDs and other leveraged products can result in the loss of some or all of your capital. Leverage multiplies losses as well as gains. Backtests, strategy tester reports, demos and hypothetical results are not live trading and do not predict the future. This article is about software architecture. It is not investment, trading or financial advice, and DayDecoder does not promise profits or a particular strategy outcome. Only risk money you can afford to lose. If you need advice, speak to a regulated adviser in your country.

Key takeaways

  • Write the trading rules as a specification before a single OnTick. Ambiguous rules become hidden martingales.
  • Separate signal, risk, execution and logging. Mixing them in one file is how EAs become untestable.
  • MQL5 is the default for new work. Support MT4 only when a broker or existing book forces it.
  • A first production EA is a cautious, well-logged automation of a rule you already understand, not an optimiser chasing a pretty equity curve.
  • You own the source, the version, and the VPS. The broker owns fills, swaps and disconnects.

MT4 vs MT5, in practice

MT4 / MQL4 MT5 / MQL5
Order model Mostly trade-based (open/close orders) Position + deal + order (netting or hedging, broker-dependent)
Testers Older tester, fewer symbols at once Multi-currency tester, more modelling modes
Language C-like, smaller standard library Closer to C++, classes, events, better IDE
When we still use it A broker or an existing MT4 book you cannot move New EAs, anything that needs clean architecture

If you are starting now and the broker offers both, build in MQL5. Porting later is possible; designing for both from day one usually means two bugs for every feature.

Step 1: specify the rule, not the “bot”

Write a one-page spec a sceptical engineer can implement without calling you:

  • Markets and timeframes. Session filter (London, New York, overlap) in the broker’s server time, not in “GMT unless DST” folklore.
  • Entry: exact indicator or price condition, including whether the bar must close.
  • Exit: take profit, stop, time stop, opposite signal, or a human. “We’ll see” is not an exit.
  • Position sizing: fixed lots, percent of equity, or volatility-based. What happens after a loss. (If the answer is “double the lot”, stop and read the risk article in this series.)
  • Max positions, max daily loss, max spread, news blackout if you use one.
  • What the EA must not do: hedge against itself, average down without a cap, trade when the VPS clock is wrong.

If the spec cannot be coded as booleans and numbers, it is not ready. Agencies that skip this step will still invoice you; they will just invoice you twice.

Step 2: project layout in MetaEditor

Create an Expert Advisor project. Keep indicators as separate files if they are reused. We typically split:

  • Signal.mqh — pure functions: given bars, return long / short / flat.
  • Risk.mqh — lot size, stop distance, daily loss, spread gate.
  • Trade.mqh — wrap CTrade (MT5) or OrderSend (MT4). No strategy here.
  • Log.mqh — file or PrintFormat with ticket, reason, spread, ping.
  • The EA file — lifecycle only: OnInit, OnDeinit, OnTick or OnTimer, inputs.

Inputs should be named like a product: InpMaxSpreadPoints, InpMagic, InpRiskPercent, not x1. Magic numbers must be unique per chart and account so later tools can tell your EA’s positions from a human’s.

Step 3: lifecycle and fail-closed behaviour

OnInit should validate inputs (risk percent in range, magic non-zero, symbol exists), detect netting vs hedging, and refuse to start if the chart symbol does not match the spec. Returning INIT_FAILED is cheaper than a surprise live trade.

On each tick (or timer, if you trade bar close only), the sequence is:

  1. Is trading allowed? Terminal connected, AutoTrading on, expert allowed, spread under cap, session window open, no pause flag.
  2. Refresh rates and positions for this magic and symbol.
  3. Compute signal from completed bars, not from a forming spike unless the spec says so.
  4. If flat and signal fires, size the lot, place the order with stops in the same call where the broker allows it.
  5. If in a trade, manage exits only as specified. Do not invent a trailing stop in code review.
  6. Log. Always.

When anything is uncertain (requote, invalid stops, no ticks), do nothing. An EA that “tries again harder” during a disconnect is how you wake up to a book you did not want.

Step 4: money and stops are part of the software

Stops must respect SYMBOL_TRADE_STOPS_LEVEL and freeze level. Lot size must sit on SYMBOL_VOLUME_STEP between min and max. Margin check before send. These are not polish. Brokers reject or silently modify orders that ignore them, and your backtest will not look like your live account.

Use the account currency and contract size from the symbol, not a hardcoded “standard lot is 100,000 of something”. Gold, indices and crypto CFDs will punish that assumption.

Checklist before the first tester run

  • Magic number set and documented.
  • Stops and lots normalised to the symbol.
  • No unbounded loops inside OnTick.
  • No FileOpen without a close path; no DLL unless you have a reason and a signed build story.
  • Comments on orders include version and reason codes you can grep.

Step 5: test like software, then like a market

Unit-test the signal functions with saved bar snippets where you can (MQL5 unit patterns, or extract rules to a language you can test). Then the Strategy Tester: every tick or 1-minute OHLC only if you understand the error that introduces. Walk-forward and out-of-sample belong in testing, backtesting and deploying MT5 EAs on a VPS. Do not optimise twenty inputs against two years of one pair and call it research.

A demo account with the same broker, same leverage, same product is the next gate. Paper fills are still not live fills. Live, if you ever go there, starts at a size that is boring.

Step 6: version, VPS, and handover

Keep MQL in git even if MetaEditor is the IDE. Tag releases. The compiled .ex5 on the VPS must match a tag. When something trades wrong, you need to know which binary.

Handover to you (or your ops person): source, inputs used in production, magic numbers, VPS access, broker account role (the EA should not run as the only person who can disable AutoTrading from a beach). We describe the operating rhythm we use with overseas clients in working with an offshore software development company.

If the EA must talk to Python, a risk service, or a Telegram alert bus, that is a different slice: MetaTrader bot integration with external APIs and a Python bridge. Do not bolt sockets into OnTick as an afterthought.

What we will not build

We will not encode a “guaranteed” martingale, a recovery factor as a sales claim, or an EA whose only edge is fitting yesterday. We will not hide lot multipliers in an input called Aggressive. If a strategy requires that, it is a trading decision you own, written explicitly in the spec, with caps, not a surprise in MQL.

DayDecoder has 10+ years building software for 103 customers. Trading automation is still software: requirements, tests, logs, and a human who can turn it off. Email contact@daydecoder.com with the spec if you want a 30-minute call on whether it is buildable as written.

Inputs, presets and the temptation to hide risk

Every input is a product decision. A risk percent, a max spread, a magic number and a session window are honest. A “secret multiplier”, an undocumented recovery mode, or a preset called “Aggressive++” that removes the daily loss cap is how EAs become unsupportable. If a client insists on a recovery mode, it goes in the spec in a sentence a non-trader can read, with a hard ceiling on lots and a log line every time it fires. We would rather lose the work than hide it.

Presets belong in set files next to the git tag, not in a screenshot on a phone. When you change a stop on Friday and the VPS still has Thursday’s set, you do not have “an EA”. You have two. Write the active set name in the chart comment so a remote session can see it without opening the inputs dialog in a panic.

Indicators, custom buffers and looking ahead

If you call a built-in indicator, pin the parameters in inputs and document whether you use the completed bar. If you write a custom indicator, it is a second program with its own bugs: buffer indexing, empty starts of history, and the classic off-by-one that looks like a crystal ball in visual mode. We test indicators with saved .set and a known bar where the value is hand-calculated. If you cannot do that, you cannot blame the broker when live differs from tester.

Multi-timeframe EAs need a rule for “the H1 bar is not closed on the M5 chart”. That rule is code, not a comment. Trading the forming H1 close is look-ahead dressed as confirmation.

News, calendars and things EAs should not scrape

Many specs say “no trades around NFP”. That requires a calendar you trust, a timezone you documented, and a behaviour when the calendar feed is stale (usually: do not trade, or trade only the session filter). Scraping a website from MQL on a timer is fragile and may violate the site’s terms. A local file dropped by a supervised process, or a paid calendar API through the Python bridge, is more adult. If the spec cannot name the source, it is not a news filter. It is a wish.

Comments, screenshots and support

Order comments should carry version, reason code and, if useful, the signal id. Screenshots of the tester are not a handover. A zip with source, compiled binary checksum, inputs, broker build, and a one-page runbook is a handover. If your previous developer vanished with a machine that had the only MQ5, that is a procurement lesson, not a MetaEditor feature. We work in your git from week one so that lesson stays in the past.

Support after go-live is mostly: symbol suffix changes, contract size changes, VPS disk full of logs, and “we changed an input and did not tell you”. Budget a small monthly or a pack of hours. “Lifetime EA support” as a slogan is how both sides get angry.

Have an EA spec, or a messy MQ4 file you need rewritten? Send the rule, the broker, and whether you need MT5 only. See custom software development or contact DayDecoder.

FAQ

Can you convert an MT4 EA to MT5?

Often, if the trading rule is clear. The order model, tester, and some indicator calls differ. A mechanical line-by-line port without tests is how you get a bot that compiles and trades the wrong volume. Budget time for a spec, then a port, then demo.

Will this EA make money?

We do not know, and nobody honest will promise that. Software can implement your rule faithfully and you can still lose money. This page is not a performance claim.

Do we need a VPS in the broker’s city?

Lower latency helps some styles and does nothing for others. Reliability (uptime, backups, who restarts the terminal) matters more than a few milliseconds for many EAs. See the VPS article in this series.

Who owns the MQL source?

Custom code should be yours when it is paid for, in your git remote. We work that way by default. Confirm it in the proposal.

Can the EA trade several symbols?

Yes, but start with one chart, one symbol, one magic. Multi-symbol EAs need a design for holidays, different sessions, and correlated risk. That is a second slice, not a checkbox.

Prakash Tank

Written by

Prakash Tank

Founder & Full-Stack Architect, DayDecoder

Prakash started as a certified Laravel developer and grew into a full-stack architect who owns a project end to end: requirements, architecture, development, deployment, and support. He designs event-driven systems with...

More about Prakash

Keep reading

Related articles

Let's talk

Turn this into a plan for your project.

Share what you are building. We will reply within one business day with honest advice and next steps.

  1. 1

    We reply within 24 hours

    A real person reads your message and replies on the next business day at the latest.

  2. 2

    Free 30-minute call

    We talk through your goals, users, and budget, and answer every question.

  3. 3

    Proposal & fixed quote

    You get a written scope, timeline, and price. No obligation.

contact@daydecoder.com Ahmedabad, India

Get a free consultation

Takes under a minute. No spam, no obligation.

What do you need help with?

Your details stay private. NDA on request.