In January 2025 I cancelled a $79/month commercial EA subscription. Not because it was bad — it made money — but because I was tired of running a black box I could not inspect. If it blew up, I would never know why. So I made a slightly unhinged New Year's resolution: learn MQL5 and code my own. I had not written a line of code since a Python course in 2019.
Three weekends later I had a working expert advisor: a moving-average cross with an ATR volatility filter, 84 lines of MQL5. I backtested it on 2022–2024 data and got +22% a year with a 14% max drawdown. I put it live on a $2,000 account in March. First month: +$340. I walked around like I had invented fire. Then in April I noticed something in the trade history that made my stomach drop — the EA had opened the same signal three times within two seconds on a fast GBPUSD tick. My "84 lines of genius" had a bug that could have stacked infinite positions into a spike.
That bug taught me the real curriculum of mt5 expert advisor programming basics. Writing an EA that backtests well takes a weekend. Writing one you can trust with rent money takes understanding how MT5 actually executes your code — tick by tick, with all the sharp edges. The DarkWolf MT5 Signal Calculator became my bridge between the two worlds: I prototype the risk math there, then encode exactly those numbers as EA inputs. Here is the whole path, mistakes included.
Turning my calculator settings into an actual EA
The smartest thing I did as a beginner was refusing to invent risk logic in code. Every risk parameter in my EA is a direct translation of a calculator input I had already validated by hand. When the EA sizes a position, it is running the same math I ran on the website — no drift between my plan and the program.
| Input Field | What it means | Sample value |
|---|---|---|
| Account balance | Maps to the EA's starting-equity reference for risk math | $2,000 |
| Risk % | Becomes the EA's RiskPercent input, used in every lot calculation | 1.0 |
| Stop loss (pips) | Becomes the StopLossPips input the EA applies to every order | 30 |
| Take profit (pips) | Becomes the TakeProfitPips input | 60 |
| Max spread filter | Becomes MaxSpreadPoints — EA skips entries above this | 25 points |
| Magic number | EA's ID tag so it only manages its own trades | 20250301 |
This mapping habit paid off in April when I found the duplicate-trade bug. Because the risk inputs were clean and separate from the entry logic, I could fix the entry bug without touching position sizing — and verify the fix by comparing the EA's computed lots against the calculator's output for the same inputs. They matched to the cent. If you are installing rather than coding, the DarkWolf EA installation walkthrough covers getting any EA onto your terminal before you start customizing inputs.
The programming mistakes that cost me 11 blown backtests
Eleven. I counted. Here are the ones that actually taught me something. Mistake one, the duplicate-trade bug: my OnTick ran the entry check on every tick with no new-bar guard, so a signal that stayed valid across 40 ticks opened 40 positions in backtests and 3 live before I caught it. One boolean — "already traded this bar" — fixed it. Every beginner EA needs this. No exceptions.
Mistake two: hardcoding pip math for 4-digit brokers. My stop distance used Point directly, which on a 5-digit broker made my 30-pip stop a 3-pip stop. The backtest showed a 90% win rate and I briefly thought I was a genius. I was not. Always compute with _Digits awareness: a pip is 10 points on 5/3-digit symbols. Mistake three: using Bid price for buy-stop calculations. Buy orders fill at Ask. My pending-order logic placed buys a full spread off from intended — invisible in backtests with fixed spread, very visible live.
Mistake four: never checking the order-send return code. My EA assumed every trade request succeeded. During a rollover spread spike, the broker rejected three entries and the EA kept trading as if it were positioned — its internal state and reality diverged for two days. Now every trade function verifies the retcode and logs failures. Mistake five: backtesting on "1 Minute OHLC" mode while the EA made tick-level decisions. The results were fiction. Real tick data or nothing — the backtesting best-practices guide is the checklist I wish I had read before blowing those eleven tests.
How an expert advisor really thinks, tick by tick
The mental model that finally clicked for me: an EA is not a program that runs. It is a program that reacts. MT5 calls your code when events happen — a new tick arrives, a timer fires, a trade executes. Between events, your EA is asleep. This event-driven design is the single most important concept in mt5 expert advisor programming basics, because every beginner bug I have seen comes from fighting it: trying to loop, trying to "wait," trying to poll.
| Event handler | When MT5 calls it | What your code should do there |
|---|---|---|
| OnInit | Once, when the EA is attached | Validate inputs, check account mode, create indicator handles |
| OnTick | On every new price tick | Update state, check entry/exit conditions, manage open trades |
| OnTimer | On your set interval, even with no ticks | Heartbeat checks, session filters, weekend position flattening |
| OnTradeTransaction | When anything trade-related happens | Reconcile internal state with actual positions — the anti-divergence guard |
| OnDeinit | When the EA is removed or inputs change | Release handles, write a shutdown log line |
The practical consequence: your OnTick must be fast and stateless-ish. No Sleep() calls — they freeze the terminal's processing. No heavy loops over years of bars on every tick — compute indicators once per new bar and cache. My first EA recalculated a 200-period MA over full history on every tick; the strategy tester took 40 minutes for one run. Caching dropped it to 90 seconds. When I got stuck on the event model, the official MQL5 documentation's event-handling section was the reference that finally made it click — worth bookmarking before you write line one.
Writing EA code you can trust with a live account
Backtest-profitable and live-trustworthy are different certifications. My trust checklist, earned the hard way. First: the EA identifies its own trades by magic number and never touches anything else — manual trades, other EAs' positions, all invisible to it. Second: a max-spread filter on every entry. My live spread monitor is the spread monitor indicator, but the EA enforces its own limit in code because indicators do not stop orders.
Third: fail-closed error handling. Every trade request checks its return code; three consecutive failures pause the EA for an hour and push an alert. Fourth: a daily loss limit in code, not just in my head — if closed P&L for the day breaches −3% of balance, the EA finishes managing open trades and takes no new entries until the next server day. Fifth: no trading during the rollover minute or around high-impact news unless the strategy is explicitly designed for it. Sixth: comprehensive logging. Every decision — entry skipped due to spread, exit triggered, error retried — goes to the Experts log with a timestamp. When something looks wrong at 2 a.m., logs are the difference between a five-minute diagnosis and a panic.
The deeper lesson: code the risk manager before the entry signal. Beginners (me included) write the sexy entry logic first and bolt on risk later. Professionals write position sizing, loss limits, and failure modes first, then add entries. An EA with perfect risk management and a mediocre signal survives. The reverse does not.
The position-size math every EA needs in its guts
This is the formula I prototyped in the signal calculator and then encoded verbatim. If your EA cannot compute this correctly — including the 5-digit adjustment — nothing else in it matters.
| Variable | Meaning | Example value |
|---|---|---|
| Balance | Current account balance (or equity, if you prefer conservative) | $2,000 |
| Risk % | Fraction of balance risked if the stop is hit | 0.01 (1%) |
| Stop Distance | Stop-loss in real pips — 10 points per pip on 5-digit quotes | 30 pips |
| Pip Value per Lot | Dollar value of one pip for one standard lot of this symbol | $10 (EURUSD) |
Worked: ($2,000 × 0.01) ÷ (30 × $10) = $20 ÷ $300 = 0.067 lots, rounded down to 0.06. In MQL5 I pull pip value from OrderCalcProfit rather than hardcoding $10, because cross pairs and gold break the assumption. Then I clamp the result between the broker's minimum and maximum volume — another beginner trap, since some brokers reject 0.06 lots on certain symbols. MetaQuotes documents all of this on metaquotes.net, but honestly the fastest teacher was watching my own EA get a "invalid volume" rejection in the tester and tracing it back.
EA builds I ran through the strategy tester before going live
Four builds, each tested on 2022–2024 tick data before it earned the right to touch the $2,000 account. The progression shows what actually moves the needle — spoiler: it was never the entry signal.
| Build | What changed | Tester result | Lesson |
|---|---|---|---|
| v0.1 | Raw MA cross, fixed 0.1 lots, no filters | +31%/yr, DD 29% | Exciting and untradeable — drawdown would end me |
| v0.2 | Added formula-based sizing at 1% risk | +22%/yr, DD 14% | Position sizing did more than any signal tweak |
| v0.3 | New-bar guard + max-spread filter + ATR regime filter | +19%/yr, DD 9% | Slightly less return, dramatically more survivable |
| v0.4 | Daily loss limit + news blackout + error handling | +17%/yr, DD 7% | The version I trust live — boring is the goal |
Notice the pattern: every build got slightly less profitable and significantly harder to kill. Beginners optimize for the return number. The v0.4 I actually trade makes less on paper than v0.1 and has never once scared me. That trade — return for survivability — is the entire game of EA development. Optimize for the equity curve you can stomach, not the one you can screenshot.
Beginner EA programming questions, answered without jargon
How long does it take to learn MQL5 as a beginner?
Expect two to three weekends to build your first working EA if you have any programming background, double that if you are starting from zero like I was. The language itself is C-like and the documentation is thorough. The slow part is not syntax — it is learning MT5's event model and the fifty small execution gotchas. Budget a month before you trust anything with real money.
Should I code my EA from scratch or modify an existing one?
Modify first, scratch second. Take a simple open-source MA-cross EA, change one thing at a time, and watch the tester. You will learn the event handlers, order functions, and input system ten times faster than from a blank file. I built mine from scratch out of stubbornness and it cost me eleven blown backtests. Start from a working skeleton and make it yours incrementally.
What is the biggest beginner bug in MT5 EAs?
Trading on every tick instead of once per bar — my infamous duplicate-trade bug. OnTick fires dozens of times per minute; without a new-bar guard, any entry condition that stays true opens position after position. The fix is one stored timestamp compared against the current bar's time. If your backtest shows hundreds of simultaneous positions, this is almost certainly your bug.
How do I know my backtest is trustworthy?
Three checks: real tick data (not 1-minute OHLC) for any tick-sensitive logic, the same GMT offset as your live broker, and a spread setting that matches or exceeds your broker's typical spread. Then forward-test on demo for at least a month. My v0.3 backtested at +19%/yr and demo-traded within 2% of that over six weeks — that agreement is what earned it live capital.
Can a beginner EA actually make money live?
Yes, with calibrated expectations. My first EA made $340 in its first live month on a $2,000 account — then needed a bug fix that would have cost far more if I had sized up blindly. Simple strategies with correct risk math beat complex strategies with sloppy execution. Start small, log everything, fix the bugs your live account reveals, and scale only after three boring months. Boring is profitable.