Why These Errors Keep Showing Up
You've written what looks like a solid Expert Advisor in MQL5, hit F7 to compile, and the MetaEditor error list fills up with red. "undeclared identifier", "type mismatch", "function not defined" — if you've been coding in MQL4 and migrated to MQL5, or you're just starting out, these feel like a brick wall. They're not.
Every single one of these errors has a clear cause and a direct fix. In this guide I'll walk you through the three most common MQL5 compilation errors, show you exactly how to read MetaEditor's error output, and give you the debugging workflow I use every day. By the end you'll be able to open any broken MQL5 file and systematically kill each error without guessing.
Let me be blunt: most of these errors come down to sloppy habits or a misunderstanding of how MQL5's compiler works. It's stricter than MQL4, and that's a good thing — it catches bugs before they cost you real money. Treat the compiler as your first line of defense, not an annoyance.
What You Need Before Starting
- MetaTrader 5 build 2000 or newer (open Help > About in the terminal to check). If you're on an older build, some error messages may look different — update via the broker's website.
- MetaEditor — launches from the MT5 terminal's Tools menu or by pressing F4. I keep it pinned to my taskbar.
- An MQL5 source file (.mq5 for EAs, .mqh for include files) that currently produces compilation errors. If you don't have one, create a new Expert Advisor and deliberately break it.
- Basic understanding of MQL5 syntax — variables, functions, data types. If you're brand new, start with the MQL5 tutorials on the official site before diving into debugging.
If you don't have a broken file handy, create a new Expert Advisor from MetaEditor's File > New > Expert Advisor, then deliberately break it by removing a semicolon or misspelling a variable name. We'll use that for practice. I usually create a test EA called "DebugPractice" and mess up the OnTick() function to simulate real errors.
How MetaEditor Reports Errors (Read This First)
When you compile (F7 or the Compile button), MetaEditor opens the Toolbox panel at the bottom of the window. The Errors tab lists every problem. Each line looks like this:
error: 'myVariable' - undeclared identifier TestEA.mq5 12 7The format is: error type, message, filename, line number, column number. Double-click any line and MetaEditor jumps directly to that position in the code. Always start with the first error. Often one fix clears several downstream errors — I've seen a single missing semicolon generate 20+ errors that all vanished after adding it.
Also watch for warnings (yellow icon) — they don't stop compilation but indicate sloppy code that can fail at runtime. Treat them as errors once the red ones are gone. Common warnings include "possible loss of data due to type conversion" and "unused variable". I fix those immediately because they're signs of logic problems waiting to happen.
One thing most traders overlook: the Compile button in the toolbar turns green when the build succeeds. If it stays red, you've still got errors. I also keep the Toolbox > Compile tab open — it shows the build time and any informational messages. A build time over 2 seconds for a simple EA usually means you've got a huge include file or a circular dependency.
Error 1: Undeclared Identifier
What It Means
You're using a variable, constant, or function name that the compiler hasn't seen a declaration for. In MQL5 every identifier must be declared before it's used — either in the current scope or in a visible include file. This is non-negotiable.
Common Causes
- Typo in the variable name (e.g.,
myVarriableinstead ofmyVariable). I catch myself doing this at least once a week. - Variable declared after it's used (MQL5 is not C# — declarations must appear before usage in the same scope). This trips up coders coming from Python or JavaScript.
- Missing
#includedirective for a file that defines the identifier. You'd be surprised how often people forget#include <Trade/Trade.mqh>and then wonder whyCTradeisn't recognized. - Using MQL4-style
iCustom()orOrderSend()without the MQL5 equivalents. These functions simply don't exist in MQL5. - Forgetting to declare a loop variable:
for(i=0; i<10; i++)whereiwas never declared. In MQL4 this would compile (global scope), in MQL5 it won't.
Step-by-Step Fix
- Double-click the error in the Toolbox to jump to the problematic line. The cursor lands on the exact column.
- Check spelling of the identifier against its declaration. MQL5 is case-sensitive —
myVariableandmyvariableare different. I once spent 30 minutes debugging aClosePositionsvsclosePositionsmismatch. - Look above the current line for the declaration. If it's an input parameter, it should be in the
inputblock near the top of the file. If it's a local variable, it must be declared before any statements in the function. Use Ctrl+Shift+F to search the entire project. - Search the file (Ctrl+F) for the identifier to see if it's declared at all. If not, add the declaration. For a simple integer:
int myVariable; // declaration
myVariable = 10; // usage (fine after declaration)- If the identifier is from an include file (e.g.,
ChartIndicator), verify you have#include <Trade/Trade.mqh>or the correct include at the top of your file. MQL5 uses#includewith angle brackets for system files and quotes for your own files. I keep a standard block at the top of every EA:
#include <Trade/Trade.mqh>
#include <Indicators/Indicators.mqh>
#include <MyLib/MyFunctions.mqh> // my custom stuff- For MQL4-to-MQL5 migration:
OrderSend()becomesCTrade::PositionOpen().iCustom()doesn't exist — useIndicatorCreate()or the indicator handle approach. These are huge topics, but the error tells you exactly which identifier is missing. I've written a separate migration guide for my team, but the key point is: don't try to rename functions line by line. Rewrite the trading logic using theCTradeclass.
Real-World Example
I had a user email me about an EA that compiled fine in MT4 but gave 47 errors in MT5. The first error was 'iMA' - undeclared identifier. In MQL5, iMA() still exists but returns a handle, not an array. The fix was:
// Old MQL4 style (won't compile in MQL5)
double maVal = iMA(NULL, 0, 14, 0, MODE_EMA, PRICE_CLOSE, 1);
// MQL5 style (returns handle, then copy data)
int maHandle = iMA(_Symbol, _Period, 14, 0, MODE_EMA, PRICE_CLOSE);
double maBuffer[];
ArraySetAsSeries(maBuffer, true);
CopyBuffer(maHandle, 0, 0, 3, maBuffer);
double maVal = maBuffer[1];Once that was fixed, 30 of the remaining 46 errors disappeared because they were cascade errors from using maVal as if it were a double.
Error 2: Type Mismatch
What It Means
You're trying to assign a value of one data type to a variable of another, or pass an argument of the wrong type to a function. MQL5 is strongly typed — you can't silently convert a string to an integer. The compiler will flag this every time.
Common Causes
- Assigning a
doubleto anintwithout explicit casting. MQL5 will warn about potential data loss, but if you're assigning a double to an int in a function parameter, it's an error. - Passing a
stringto a function expectingdouble. This happens often withStringToDouble()— people forget to call it. - Using a
datetimevariable wherelongis expected (or vice versa). MQL5 stores datetime as seconds since 1970, but the compiler treats them as distinct types. - Mixing
intanduintin arithmetic without casting. This is rare but bites you in loop conditions. - Returning the wrong type from a function (e.g., returning
stringfrom a function declaredint). The compiler catches this immediately.
Step-by-Step Fix
- Identify the types involved. Hover over the variable or function in MetaEditor — the tooltip shows its type. For function parameters, check the function declaration. I also use the Ctrl+B shortcut to jump to the function definition.
- If you need to convert explicitly, use casting:
(int)myDoubleor(double)myInteger. For string-to-number conversions useStringToDouble()orStringToInteger(). Never rely on implicit conversion. - For datetime issues: MQL5 stores datetime as a
longinternally (seconds since 1970). If you're comparing withTimeCurrent(), make sure both sides are the same type. Use(datetime)TimeCurrent()if needed. I prefer to keep everything as datetime and only convert when necessary. - Check function signatures in the MQL5 Reference — the exact parameter types are documented. For example,
ObjectSetInteger()expectsintfor the property ID, notlong. I keep the reference open in a browser tab while coding. - Watch for implicit conversions that work in MQL4 but fail in MQL5. MQL5 is stricter about
int/doublemixing in arithmetic — you may need to cast. For example,int result = 5 / 2;gives 2 in both, butdouble result = 5 / 2;gives 2.0 in MQL4 but 2 in MQL5 (integer division). You needdouble result = 5.0 / 2;.
Real-World Example
A colleague was getting 'string' to 'double' type mismatch on this line:
double stopLoss = "1.2345";The fix was obvious once you see it:
double stopLoss = StringToDouble("1.2345");But the real issue was deeper: he was reading stop loss values from a file as strings. A better approach is to read them as doubles directly using FileReadDouble() or parse them once. I showed him to use StringToDouble() at the point of file reading, not at assignment.
Error 3: Function Not Defined
What It Means
You're calling a function that the compiler can't find a declaration or definition for. This is different from "undeclared identifier" — here the name is recognized as a function call (because of parentheses), but no matching function exists in scope.
Common Causes
- Typo in the function name. I've done
CalculatAverage()instead ofCalculateAverage()more times than I care to admit. - Function defined after the call (MQL5 requires either a forward declaration or definition before first use). This is the most common cause for beginners.
- Missing
#includefor a file that contains the function. If you wrote a custom function inMyFunctions.mqhbut forget to include it, you'll get this error. - Using a function from a library without importing it (
#importdirective). DLL functions need explicit import. - Calling an MQL4 function that doesn't exist in MQL5 (e.g.,
OrderSelect()). This is a migration issue.
Step-by-Step Fix
- Check the function name for typos. MQL5's standard library uses
PositionSelect()notOrderSelect(). The function names are case-sensitive. - Search the file (Ctrl+F) for the function definition. If it's defined after the call, either move the definition above the call or add a forward declaration at the top of the file:
// Forward declaration
double CalculateAverage(double a, double b);
// Later in the file
double CalculateAverage(double a, double b)
{
return (a + b) / 2.0;
}- For functions from include files: ensure the
#includeline is present and the file path is correct. MetaEditor shows the include file in the Project panel if it loaded correctly. I check the Project > Includes tree to verify the file is there. - For DLL imports: verify the
#importblock has the correct DLL name and function signature. MQL5's DLL import syntax is:
#import "kernel32.dll"
int GetTickCount();
#importNote the semicolon after the function signature — missing it causes cryptic errors.
- If you're porting from MQL4, many functions are different. Use the MQL5 migration guide on the MQL5 documentation site. Common replacements:
| MQL4 Function | MQL5 Equivalent |
|---|---|
| OrderSend() |






