Introduction: Why Global Variables Matter in MetaTrader
Every experienced MetaTrader developer eventually hits a wall: you have two Expert Advisors running on different charts, or an EA that needs to remember a value after it stops running, or a script that must communicate with an indicator. Standard MQL variables disappear when the program unloads, and file-based storage is slow and messy. MetaTrader Global Variables (GV) solve this cleanly. They are persistent, cross-program, and stored in the terminal's memory alongside your account profile.
In this guide, you will learn exactly what Global Variables are, how to create, read, modify, and delete them from MQL4 and MQL5, how to use them for inter-EA communication, and how to avoid the common pitfalls that cause crashes or data corruption. By the end, you will be able to build EAs that coordinate across multiple charts, share state, and survive terminal restarts.
Prerequisites
- Platform: MetaTrader 4 Build 1400+ or MetaTrader 5 Build 4000+ (GV behavior is identical across both, but the MQL5 function names differ slightly).
- Account: Any live or demo account. Global Variables are account-specific — each account number has its own GV namespace.
- Tools: MetaEditor (F4 from MT4/MT5), basic familiarity with writing and compiling MQL4/MQL5 scripts or EAs.
- Optional: The built-in MetaTrader Global Variables Viewer (Tools → Global Variables or Ctrl+G in MT4; Tools → Options → Expert Advisors → Global Variables in MT5).
Step-by-Step Instructions: Working with Global Variables
1. Understanding the GV Namespace and Persistence
Each Global Variable is a name-value pair stored in the terminal's memory. The name is a case-sensitive string up to 256 characters (MQL4) or 512 characters (MQL5). The value is always a double. When you create a GV, it persists until:
- You explicitly delete it with
GlobalVariableDel(). - You close the terminal (MT4/5) — but note: GVs are not saved to disk automatically; they survive only while the terminal runs. If you need permanent storage, combine GVs with file writes or use
GlobalVariableSetOnCondition()for atomic updates. - You switch accounts or profiles — GVs are tied to the account number.
This account-specific binding means that if you run the same EA on a demo account and a live account on the same terminal, they will have completely separate GV namespaces. This prevents accidental interference between test and production environments.
2. Creating and Setting a Global Variable
In both MQL4 and MQL5, use GlobalVariableSet() to create or update a variable. The function returns true on success.
// MQL4 / MQL5 — identical syntax
if(GlobalVariableSet("MyEA_LastTradeTime", TimeCurrent())) {
Print("GV set successfully.");
} else {
Print("Failed to set GV. Error: ", GetLastError());
}
Important: Always check GetLastError() (MQL4) or GetLastError() (MQL5). Common error 4108 means the variable name is too long; 4200 means the terminal's GV limit (1024 per account) is reached. If you hit the limit, you must delete unused GVs or consolidate multiple values into a single GV using string packing.
3. Reading a Global Variable
Use GlobalVariableGet(). If the variable does not exist, it returns 0 and sets a last error (4058 in MQL4, 5401 in MQL5). Always verify existence first.
// MQL4 / MQL5
if(GlobalVariableCheck("MyEA_LastTradeTime")) {
double lastTime = GlobalVariableGet("MyEA_LastTradeTime");
Print("Last trade time: ", TimeToString((datetime)lastTime));
} else {
Print("GV does not exist yet.");
}
Note that GlobalVariableGet() returns a double, so for integer or boolean values you must cast appropriately. For example, to store a boolean flag (0 or 1), use int flag = (int)GlobalVariableGet("MyFlag");.
4. Modifying with Atomic Operations
For counters or accumulators, use GlobalVariableSetOnCondition() to avoid race conditions. This function only updates the value if the current value matches an expected one — perfect when two EAs might write to the same GV.
// MQL4 / MQL5 — atomic increment
double currentVal = GlobalVariableGet("MyEA_TradeCounter");
double newVal = currentVal + 1.0;
if(GlobalVariableSetOnCondition("MyEA_TradeCounter", newVal, currentVal)) {
Print("Counter incremented atomically to ", newVal);
} else {
Print("Race condition detected! Retrying...");
// Re-read and retry in a loop
}
This pattern is essential in high-frequency trading scenarios where multiple EAs might update the same counter within milliseconds. Without atomic operations, you risk losing increments when two EAs read the same value simultaneously and both write back the same incremented result.
5. Deleting a Global Variable
Use GlobalVariableDel(). For cleanup, especially after an EA finishes, delete only your own GVs to avoid interfering with other programs.
// MQL4 / MQL5
if(GlobalVariableDel("MyEA_LastTradeTime")) {
Print("GV deleted.");
}
You can also delete all GVs for your EA by iterating through all variables and matching names against your prefix. This is useful in deinit() when your EA is removed from a chart.
6. Listing All Global Variables (for debugging)
Use GlobalVariablesTotal() to get the count, then iterate with GlobalVariableName() and GlobalVariableGet().
// MQL4 / MQL5
int total = GlobalVariablesTotal();
for(int i = 0; i < total; i++) {
string name = GlobalVariableName(i);
double value = GlobalVariableGet(name);
Print("GV[", i, "]: ", name, " = ", value);
}
In MT4, you can also view all GVs via Tools → Global Variables (Ctrl+G). In MT5, go to Tools → Options → Expert Advisors → Global Variables. The viewer allows you to manually delete or modify variables, which is useful during development but dangerous in production.
7. Advanced: Using GVs for Inter-EA Communication
Here is a practical example: EA1 sets a flag when a trade opens, and EA2 checks that flag before opening a new trade to avoid conflicting positions.
// EA1 - Trade opener
void OnTrade() {
if(OrderSelect(0, SELECT_BY_POS, MODE_TRADES)) {
GlobalVariableSet("TradeActive", 1.0);
} else {
GlobalVariableSet("TradeActive", 0.0);
}
}
// EA2 - Trade checker
bool CanOpenTrade() {
if(GlobalVariableCheck("TradeActive") && GlobalVariableGet("TradeActive") == 1.0) {
Print("Trade already active. Skipping.");
return false;
}
return true;
}
This pattern can be extended to share complex data like current stop-loss levels, magic numbers, or even computed indicator values. For example, you might have one EA that calculates a moving average and stores it in a GV, while another EA reads that value for trade decisions.
Tips and Best Practices from Experience
- Use a naming convention. Prefix all your GVs with your EA or indicator name, e.g.,
"MyScalper_LastBarTime". This prevents collisions with other EAs and makes debugging easier. Avoid generic names like"counter"or"flag". - Always check existence before reading.
GlobalVariableGet()returns 0 for missing variables, which can be a valid value. Always pair it withGlobalVariableCheck(). - Limit GV count. Each account can have up to 1024 GVs. If you need many, consider using a single GV with a packed string (e.g., CSV) and parse it when needed. But this adds complexity — use it only when necessary.
- Clean up after yourself. In your EA's
deinit()function, delete all GVs your EA created. This prevents stale data from accumulating. - Avoid frequent writes. Writing to a GV on every tick can slow down the terminal. Write only when the value actually changes, or batch updates in
OnTimer(). - Use
GlobalVariableSetOnCondition()for counters. When two EAs increment a shared counter, without atomic operations you may lose increments. This function is your safety net. - Test on demo first. GVs behave identically on demo and live accounts, but always test your inter-program logic in a controlled environment.
Common Mistakes and Troubleshooting
| Symptom | Likely Cause | Fix |
|---|---|---|
| GV returns 0 but exists | You stored a non-zero value, but reading gives 0. Check if you are reading before the EA that sets it has run. | Use GlobalVariableCheck() before reading. Ensure the writing EA is attached and has executed at least one tick. |
| GV disappears after terminal restart | GVs are not saved to disk by default. They exist only while the terminal runs. | If persistence is needed, write GVs to a file in deinit() and reload in init(). Use FileWrite() and FileRead(). |
| Error 4108 (MQL4) or 5400 (MQL5) on set | Variable name exceeds length limit (256 for MT4, 512 for MT5). | Shorten the name. Use abbreviations but keep them readable. |
| Two EAs write to same GV, values inconsistent | Race condition — both EAs read and write without atomicity. | Use GlobalVariableSetOnCondition() or implement a semaphore pattern with a separate lock GV. |
| GV value changes unexpectedly | Another EA or script with the same GV name is modifying it. | Use a unique prefix. Check the Global Variables Viewer to see all variables and their values. |
Performance Considerations
Global Variables are stored in the terminal's memory, not on disk, so read and write operations are fast — typically under 1 microsecond. However, there are limits:
- Maximum 1024 GVs per account. If you exceed this,
GlobalVariableSet()returns false with error 4200. - Write frequency. Writing on every tick (e.g., in
OnTick()) is generally fine, but if you have dozens of EAs doing this simultaneously, you may see slight performance degradation. Batch updates usingOnTimer()with a 1-second interval to reduce write frequency. - Name lookup. GV names are stored in a hash table, so lookup time is O(1) regardless of how many variables exist.
Summary / Recap and Next Steps
You now understand how to use MetaTrader Global Variables for inter-program communication: setting, reading, atomic updates, and cleanup. The key takeaways are:
- GVs are account-specific, persistent only while the terminal runs, and limited to 1024 per account.
- Always use a naming convention and check existence before reading.
- Use
GlobalVariableSetOnCondition()for thread-safe counters and flags. - Clean up your GVs in
deinit()to avoid clutter.
Next steps: Try building a simple multi-EA system where one EA sets a flag when a trade is opened, and another EA reads that
Frequently Asked Questions
Can I use Global Variables to share data between MT4 and MT5 on the same computer?
No. MT4 and MT5 are separate terminal processes with their own GV namespaces. Even if you run both on the same machine, their GVs are isolated. To share data between them, use file-based communication or a named pipe (advanced).
What happens if I create a Global Variable with the same name as an existing one?
The new value overwrites the old one. There is no warning or error — GlobalVariableSet() simply updates it. This is why a naming convention is critical to avoid accidental overwrites between different EAs.
Can I store strings or integers in a Global Variable?
GVs store only double values. For integers, cast to double (e.g., GlobalVariableSet("MyInt", (double)myIntValue)). For strings, you must encode them as numbers — for example, use StringToInteger() to convert a short string to an integer and store that as a double. For longer strings, use file storage instead.
How do I debug Global Variables in real time?
In MT4, press Ctrl+G to open the Global Variables viewer. In MT5, go to Tools → Options → Expert Advisors → Global Variables. Both show all GVs with their current values. You can also write a simple script that loops through all GVs and prints them to the Experts tab.






