You build a MACD Expert Advisor in MT5 without coding by placing a Start node, two MACD blocks — one reading the main line, one reading the signal line — a Cross condition between them, and an order block. The server generates and compiles the MQL5 and hands you a real .ex5. Fifteen minutes, no syntax.
Then comes the part that decides whether the file is worth anything. This recipe has a measured record, and its most flattering number is the one you should trust least.
What you’ll build
A single-position EA on one pair that buys when the MACD line crosses above its signal line and sells when it crosses below, with a fixed stop and target, compiled to a real .ex5. Eight blocks.
Two blocks of that count exist for one reason: the MACD indicator block returns one line at a time.
Before you start: what MACD reports, and which line you are reading
You need a free account with a verified email address (designing is free and needs no sign-in; compiling to .ex5 does), about fifteen minutes, and a MetaTrader 5 terminal.
MACD subtracts a slow moving average from a fast one, then averages that difference again. So the main line measures how far apart two averages have drifted, and the signal line is that measurement smoothed. Everything a MACD rule can say is a statement about the distance between two averages — which means it is a trend tool wearing an oscillator’s clothes, and it inherits the lag of both averages that built it.
The Builder’s MACD block exposes these settings:
| Block setting | Default | What it controls |
|---|---|---|
fast_ema | 12 | The quicker average. Range 1–999 |
slow_ema | 26 | The slower one. The gap between the two is the whole signal |
signal_period | 9 | How much the difference is smoothed before you compare it |
line | MODE_MAIN | Which line this block outputs — MODE_MAIN or MODE_SIGNAL |
applied_price | PRICE_CLOSE | Which price feeds the calculation |
shift | 0 | 0 is the forming bar; 1 is the last closed one |
timeframe | current chart | Any of M1 through MN1, read independently of the chart |
line is the row that changes the shape of your flow. It is a two-value select, so one block gives you one line. A signal-line cross therefore needs two MACD blocks; a zero-line cross needs one, plus a comparison against a constant.
Step-by-step: build the MACD EA in the Builder
- Open the EA Builder and load the
macd_signaltemplate from the gallery, or start from a blank canvas to wire it yourself. - Place a Start node from the Utility palette. Without one, validation stops the build with
EAB-E202. - Add a MACD block and leave
lineatMODE_MAIN. Leave 12/26/9 alone for the first build so your result stays comparable to the baseline below. - Add a second MACD block with identical periods and set
linetoMODE_SIGNAL. Same indicator, same settings, different output — this is the step people skip, and skipping it is why their flow compares a line to itself. - Wire both into a Cross condition. Cross takes two inputs and asks whether one crossed the other on this bar; its
cross_typeiscrossoverorcrossunder, so the buy and sell sides are two separate conditions, not one reversed. - Wire each condition into its own Open Buy / Open Sell block. Wiring an indicator straight into an order is rejected with
EAB-E205— a raw value is not a decision. - Set risk in the Settings tab. The shared defaults are a 50-pip stop, a 100-pip target and a fixed
0.01lot; a flow with no valid stop raises aCRITICALpreflight diagnosis before it will build. - Press Measure and read the result against the bar the panel prints: profit factor at least 1.2, at least 60 trades, drawdown no worse than 20%.
- Press Compile .ex5, move the file into
MQL5/Expertsvia File > Open Data Folder, refresh the Navigator, and test it in the Strategy Tester before it touches an account.
- Start node
- MACD block, line = MODE_MAIN
- MACD block, line = MODE_SIGNAL
- Cross — crossover for buy, crossunder for sell
- Open Buy and Open Sell
- Stop-loss and take-profit
- Compile to .ex5
If you want the zero-line version instead, delete the second MACD block and replace Cross with Compare, whose operators are > < >= <= == != and whose offset defaults to 0. “MACD main above zero” is a statement that the fast average is above the slow one at all — a much rarer and much later event than the two lines touching. The palette also ships OsMA, which outputs the main-minus-signal difference directly as one value, so a histogram rule needs one block rather than two.
MACD entry, exit and parameter settings
| Setting | Template value | What moving it does |
|---|---|---|
fast_ema | 12 | Lower reacts sooner and crosses far more often; the trade count moves before the win rate does |
slow_ema | 26 | Raising it widens the gap the fast line must travel, so signals arrive later and rarer |
signal_period | 9 | The smoothing on the comparison line. Shorter means more crosses, most of them noise |
line | MODE_MAIN | Not a tuning knob — it decides which rule you built |
shift | 0 | Set to 1 to decide on closed bars only |
| Stop-loss | 50 pips (shared default) | The searched range was 30–80 |
| Take-profit | 100 pips (shared default) | The searched range was 60–250 |
On lag, which is the honest complaint about this indicator. Every value here is the output of two averages stacked on a third. A cross is therefore a report that a move already happened — the question is only how late. Shortening fast_ema buys earliness and pays for it in false crosses; lengthening slow_ema buys reliability and pays for it in entries that arrive after the move. The template’s own record suggests where it landed: 698 trades in a year, the second-highest count of the thirteen trend and momentum templates measured under identical conditions. That is a design firing constantly, and firing constantly is what a short lag costs.
What the search did and did not touch. The recorded parameter search moved the stop and the target only — SL30-80 × TP60-250, 12 combinations across three windows on H1. It never varied fast_ema, slow_ema or signal_period. So nothing on this page supports a claim that 12/26/9 is right, wrong, or improvable. It supports a much narrower and more useful claim: no stop-and-target combination rescued the design.
Backtest the MACD EA
This is the Builder’s own measured record, not a re-run, and every template in the comparison shares the single conditions block below. How we test states the standard those records are held to.
macd_signal baseline | Value |
|---|---|
| Profit factor | 0.93 |
| Trades | 698 |
| Max drawdown | -1.05% |
| Net | -93.93 |
| Rank in its neighbourhood by profit factor | 8th of 13 |
| Rank in its neighbourhood by trade count | 2nd of 13 |
| Clears the Measure panel’s own pass bar | no |
| Test conditions | |
|---|---|
| Experiment ID | EXP-MACD-RECIPE-BASELINE-001 |
| Parent experiment | EXP-BUILDER-TEMPLATE-BASELINE-001 |
| Symbol / timeframe | USDJPYm M5 |
| Period | 2025-06-01 – 2026-06-09 |
| Model | M1 OHLC (Model=1) |
| Deposit | 10,000 |
| Environment | Exness MT5 |
| Baseline measured | 2026-06-18 |
| Last verified | 2026-08-25 |
The search result deserves more than a line. Eight templates in the gallery carry a recorded parameter search, and all eight ended at no_robust_edge. But they failed in two different ways, and the difference matters more than the shared verdict. Two of them never produced a winning setting at all, even on the period the search was fitted to. macd_signal is the only one that produced a setting which cleared 1.0 out of sample — 1.14 to 1.15 at the widest target — and then scored 0.74 to 0.77 on the window before it. The manifest’s own word for this is regime-dependent.
Read what that implies about testing. If you had split your data once, fitted on the first half and checked on the second, this template would have handed you a passing result. The only thing that caught it was checking a third period the search never saw. That is the argument for walk-forward analysis in one concrete case, and it is worth more than any general warning about overfitting.
Where MACD sits among its neighbours, all measured under the one conditions block above:
| Template | Blocks | Profit factor | Drawdown | Trades |
|---|---|---|---|---|
ma_perfect_order_trend | 10 | 1.07 | -0.36% | 305 |
mtf_osc_filter | 27 | 1.04 | -0.64% | 187 |
consecutive_bars_momentum | 7 | 1.03 | -0.36% | 377 |
ao_ama_trend | 14 | 0.97 | -0.95% | 239 |
adx_trend | 12 | 0.96 | -0.76% | 534 |
multi_tf_trend | 15 | 0.96 | -0.51% | 247 |
ma_crossover | 9 | 0.95 | -0.84% | 420 |
macd_signal | 8 | 0.93 | -1.05% | 698 |
ma_slope_trend | 7 | 0.92 | -1.00% | 478 |
mtf_adx_filter | 14 | 0.92 | -0.84% | 343 |
elder_ray | 9 | 0.90 | -1.34% | 529 |
pitch_trail_trend | 9 | 0.77 | -1.61% | 467 |
dynamic_sl_trend | 9 | 0.68 | -1.62% | 708 |
Split those thirteen at their own median trade count of 420, and the halves separate cleanly. The six that traded less averaged a profit factor of 1.00 on 283 trades with a -0.61% drawdown. The six that traded more averaged 0.86 on 569 trades with -1.23% — worse results and twice the depth. All three designs above 1.0 sit in the quieter half. MACD sits in the busier one.
That is a description of thirteen designs under one setup, not a law: entry logic, node count and exits differ too, so frequency is not established as the cause. But it is the pattern in front of you, and the shipped MACD template is on the wrong side of it.
Common mistakes to avoid
Believing an out-of-sample pass. This is the mistake this template exists to demonstrate. One held-back period is a single sample, and a momentum rule can win a single sample because the market trended during it. Test a third window the search never saw before you believe a number.
Comparing a line to itself. If both MACD blocks are left on MODE_MAIN, the Cross condition compares identical values and never fires — or fires on rounding. Check the line setting on both blocks before you wonder why the trade count is zero.
Reading a cross as a prediction. MACD is two averages of an average. A cross reports that a move has already been under way for some bars. The design choice is how much lateness you accept, not whether to accept any.
Fitting the stop and target until the equity curve looks right. The recorded search already did that systematically across 12 combinations and three windows, and reported no_robust_edge. If your manual tuning beats a systematic search, suspect the tuning.
Stacking momentum filters. The composition above is the measured version of that instinct: 3.76 times the drawdown for a slightly worse profit factor.
Running it beside another EA without separating them. Each EA on one account needs its own magic number, or one EA’s exits close the other’s positions.
Next steps and variations
When not to use MACD. In a range, two averages cross repeatedly and every cross is noise — and a fast-firing default is exactly what a range punishes. If you cannot state a condition that stops the rule during flat periods, either add one or use an idea that does not depend on the two averages separating.
The variations worth trying, in order of evidence. Try the zero-line version first: it is one block simpler and it fires far less often, and the quieter half of the neighbourhood is where every result above 1.0 sits. Then try the same rule on a higher timeframe inside the MACD block, which slows the signal without touching the chart. Only then move the periods — and change one at a time.
Then test it properly. The Measure panel is bar-level and approximate; it is a filter, not a verdict. How to run a backtest in MT5 walks a real run end to end, including which of the report’s two drawdown numbers to believe. How to build an RSI EA is the sibling recipe with the opposite failure mode — its search never won anything, which makes it easier to reject and less instructive than this one. How to create an MT5 EA without coding covers the wider block vocabulary, and the backtesting guides go deeper into the walk-forward step this page argues for.
And to calibrate what a documented record looks like, the published EAs each carry a complete closed-trade list and a run manifest. Compare one against the table above before trusting any strategy, including one you built yourself.