I was staring at my MT4 chart, confused. The EA I'd just attached was running fine on EURUSD, but when I switched to GBPUSD, it stopped trading. No errors. No warnings. Just silence. I restarted MT4, reattached the EA, and it worked again. But the moment I changed the symbol, it went dead.
That's when I realized I didn't actually understand how MT4 loads and runs programs. I knew how to drag an EA onto a chart, but I had no clue what happened behind the scenes. So I dug into the MQL4 documentation and found some things that completely changed how I debug my EAs.
The Three Program Types – Different Behaviors
Before we get into the nitty-gritty, let's clarify what we're dealing with. MT4 has three types of executable MQL4 programs:
Each type has its own loading and unloading rules. And this is where most of the confusion comes from.
Step 1: How EAs Actually Load – More Than Just Drag-and-Drop
When you drag an EA onto a chart, here's what happens in sequence:
OnInit() event handler is called, if it exists.Here's the kicker: Every MQL4 program must have at least one event-handler function. If it doesn't, the loaded program simply won't execute. I've seen people spend hours debugging an EA that compiled fine but did nothing on the chart, only to realize they'd forgotten to implement
OnTick() or OnStart().EAs are also loaded in these scenarios:
When the terminal starts, if the EA was attached to a chart before shutdown.
When loading a template that includes the EA.
When changing a profile that includes the EA.
Hidden one: When reconnecting to an account—even if it's the same account number. If you disconnect and reconnect your account, the EA reloads.
Step 2: The Symbol/Timeframe Change – My Aha Moment
This is what tripped me up with EURUSD vs GBPUSD. According to the MQL4 documentation, when you change the symbol or timeframe of a chart that has an EA attached, the EA is not unloaded and reloaded.
Wait, what? I had to read that twice.
Here's the exact behavior from the official docs: When the symbol or timeframe changes, the client terminal calls
OnDeinit() on the old symbol/timeframe, and then OnInit() on the new symbol/timeframe. Global variables and static variables are not reset. Their values persist through the transition.My exclusive take on this: This is a feature, not a bug, but it's also a trap. I've seen EAs break because they assumed certain symbol-specific data (like point size or digits) wouldn't change mid-run. If your EA initializes something in
OnInit() that's symbol-dependent—like storing a fixed stop-loss distance in pips—that value gets stale when you switch from EURUSD to GBPUSD because the point value changes.The fix I use now: Always recalculate symbol-dependent values in
OnTick() or OnTimer(), not just in OnInit(). Or, better yet, store the symbol name in a global variable and check if it's changed each tick.Step 3: What Happens When an EA Unloads
EAs are unloaded in these situations:
When you detach them from a chart.
When you attach a new EA to the same chart (the old one is removed).
When you shut down the terminal.
When loading a template that overwrites the EA.
When closing the chart.
When changing the profile (if the EA was attached to one of the charts in the changed profile).
ExpertRemove() function from within the EA itself.When an EA is unloaded, the terminal does two things:
OnDeinit() with a reason code.Step 4: Indicator Loading – The Shared Thread Problem
Indicators have the same basic loading rules as EAs, but they're different in a critical way: all indicators share the graphic interface thread.
This means if you have an indicator that gets stuck in an infinite loop, it's not just that indicator that freezes—it's the entire MT4 terminal. I learned this the hard way when I accidentally wrote an indicator with a
while(1) loop in OnCalculate(). MT4 locked up completely. I had to kill the process through Task Manager.This is also why indicators run slower when you have many of them open. They're all competing for the same thread. If you're running 10 indicators on 10 charts, that's 10 programs sharing a single thread.
Reference: MQL4 Official Documentation, "Program Running".
Step 5: Scripts – The Simplest, But With a Catch
Scripts are the simplest MQL4 programs. They load immediately when you attach them, execute
OnStart(), and then unload automatically.The catch: Scripts run in their own separate thread, just like EAs. But unlike EAs, they're not saved between terminal sessions. If you restart MT4, your scripts aren't restarted automatically—the information about them isn't saved.
This means if you're using a script for something critical, you need to manually re-attach it after every restart.
Step 6: Recompilation and Input Parameters – A Hidden Behavior
Here's another thing that surprised me. If you recompile an EA that's already running on a chart, the old version is removed and the new compiled copy is loaded automatically.
But here's the important part: If the input parameters haven't changed in the source code, the previously specified parameter values are preserved. If you've changed the number, order, name, or type of parameters, the default values from the new code are used instead.
I've been burned by this before. I added a new input parameter to an EA, recompiled it on a running chart, and the new parameter defaulted to
false instead of the true I expected. The EA started trading differently, and I didn't notice until I checked the logs an hour later.My workflow now: Always restart the EA manually after making parameter changes, even if the docs say it reloads automatically.
Step 7: The Event Queue – Why Your EA Might Miss a Tick
Every MQL4 program has its own event queue. The terminal sends events to the chart, and the program processes them one after another.
Important: NewTick events are coalesced. If a NewTick event is already in the queue or being processed, new NewTick events are not enqueued. The same rule applies to Timer and ChartEvent events.
This means if your
OnTick() handler takes a long time to execute, you'll miss ticks. The terminal won't queue them up—it'll just discard them. I've seen this happen with EAs that do heavy calculations or call Sleep() inside OnTick(). The EA gets stuck, misses a few ticks, and then resumes.My take: Don't do heavy lifting in
OnTick(). Use OnTimer() for periodic calculations or offload work to separate functions that don't block the main thread.Reference: MQL4 Official Documentation, "Program Running – Event Queue".
Step 8: DLL Imports – A Recurring Pain Point
If your EA uses external DLLs, the loading behavior changes. The DLL must be present in the
terminal_dir\MQL4\Libraries folder. When the EA loads, it tries to import the DLL functions. If the DLL is missing or the function signature doesn't match, the EA will fail to initialize.A point I haven't seen documented clearly: Some DLLs depend on other system DLLs (like Visual C++ runtimes). If those are missing, the import fails silently—you'll see a "DLL call is not allowed" or "Error 126" in the Experts tab. This isn't an MT4 issue; it's a Windows dependency issue.
The official MQL4 documentation covers the import syntax, but the system-level dependencies are a Microsoft concern. Reference: Microsoft Official Documentation, "Visual C++ Redistributable" for the missing runtime fix.
Step 9: The AutoTrading Button – The Master Kill Switch
One more thing that confuses people: the "AutoTrading" button at the top of the MT4 window. This is a global toggle for all EAs.
Even if your EA is loaded and has
OnInit() running successfully, it won't place trades if AutoTrading is disabled. The EA can still analyze prices and run calculations, but OrderSend() and other trading functions won't work.Reference: MetaQuotes Official Help Center, "Autotrading Settings" section.
Final Thought: Know Your Program's Lifecycle
Here's what I've learned from all this. An EA isn't just a piece of code that runs mindlessly. It has a lifecycle—load, init, run, deinit, unload—and each phase has rules that affect how your EA behaves.
If your EA works on EURUSD but stops on GBPUSD, don't blame the code right away. Check what happens when you change the symbol. Understand that
OnInit() runs once, and symbol-specific values might become stale. And remember that the event queue drops ticks if your EA is too slow.Once I understood how MT4 actually manages programs, debugging got a lot easier. I stopped wasting hours on things that weren't actually bugs—they were just me not knowing how the platform works.
Reference:
本文首发于FXEAR.com,原创内容,未经授权禁止转载。