- Added comprehensive MQ4/MQ5 comparison documentation (60+ pages) - Added MT4 EA implementation plan and tracking documents (60+ pages) - Phase 1: Core infrastructure with input parameters and data structures - Phase 2: Bar detection system for H4, M30, M15 timeframes - Phase 3: Pattern detection logic (Regular/Irregular Buy/Sell patterns) - Reference files: FINAL_H4_ZONES.mq4, MultiTimeframeZoneEA.mq5, Strategy.md
9.4 KiB
| applyTo |
|---|
| **/*.mq5,**/*.mqh |
CRITICAL MQL5 Syntax Rules (Mandatory for All MQL5 Code)
⚠️ Overview
MQL5 is NOT standard C++. It has critical syntax differences that cause compilation errors if ignored. These rules are mandatory for all _Thivyam MQL5 development.
1. Pointer Member Access ❌ → ✅
Rule
ALWAYS use dot operator (.) for pointer member access
NEVER use arrow operator (->)
Why
MQL5 parser treats -> as two separate operators: - (minus) and > (greater-than), causing parser errors.
Examples
// ✅ CORRECT
CObject *ptr = GetObject();
ptr.Method();
ptr.SetValue(10);
CZoneState *zone = ctx.Zone(); // Returns pointer
zone.IsActive(); // Use dot operator
// ❌ WRONG - Causes compilation errors
ptr->Method(); // Error: 'operand expected'
zone->IsActive(); // Error: 'undeclared identifier'
Error Messages You'll See
'>' - operand expectedundeclared identifier')' - expression expected'Method' - object pointer expected
2. Loop Variable Declaration ❌ → ✅
Rule
NEVER declare variables inside for-loop initializers
ALWAYS declare loop counters BEFORE the for statement
Why
MQL5 does not support C99/C++11 style variable declaration in for-loop initializers.
Examples
// ✅ CORRECT
int i;
for(i = 0; i < 10; i++)
{
Print(i);
}
// Multiple loops
int i, j;
for(i = 0; i < rows; i++)
{
for(j = 0; j < cols; j++)
{
matrix[i][j] = 0;
}
}
// ❌ WRONG - Causes compilation errors
for(int i = 0; i < 10; i++) // Error: undeclared identifier
{
Print(i);
}
Additional Rules
- Use post-increment (
i++) not pre-increment (++i) for better compatibility - Avoid
conston loop bound variables: useint totalnotconst int total
Error Messages You'll See
undeclared identifier'i' - some operator expectedexpression expected
3. Array Declarations ❌ → ✅
Rule
Use dynamic arrays (Type[]) for array manipulation functions
Static arrays (Type[N]) cannot be used with ArraySetAsSeries() and similar functions
Why
MQL5 distinguishes between static (fixed-size) and dynamic (variable-size) arrays, and many built-in functions only work with dynamic arrays.
Examples
// ✅ CORRECT - Dynamic arrays
MqlRates rates[];
ArraySetAsSeries(rates, true);
CopyRates(_Symbol, PERIOD_H1, 0, 100, rates);
double buffer[];
ArrayResize(buffer, 50);
// ❌ WRONG - Static arrays
MqlRates rates[100];
ArraySetAsSeries(rates, true); // Error: cannot be used for static allocated array
Special Cases
// CArrayObj from standard library
CArrayObj m_array;
// ✅ CORRECT - Auto-initializes
CArrayObj() {
// No initialization needed
}
// ❌ WRONG - Create() doesn't exist
CArrayObj() {
m_array.Create(); // Error: undeclared identifier
}
Error Messages You'll See
cannot be used for static allocated arrayundeclared identifier(for.Create())
4. Function Parameters ❌ → ✅
Rule
Avoid const Type ¶meter when passing temporary values
Use pass-by-value (const Type parameter) instead
Why
Temporary values (from ternary operators, function returns) cannot bind to reference parameters in MQL5.
Examples
// ✅ CORRECT
void CreateLabel(const string text)
{
ObjectSetString(0, "label", OBJPROP_TEXT, text);
}
// Called with ternary expression
CreateLabel(minimized ? "" : fullText); // Works fine
// ❌ WRONG
void CreateLabel(const string &text) // Reference parameter
{
ObjectSetString(0, "label", OBJPROP_TEXT, text);
}
CreateLabel(minimized ? "" : fullText); // Error: parameter passed as reference
When to Use References
- Use references for large structures that you DON'T create on-the-fly
- Use value parameters for strings and small types
Error Messages You'll See
parameter passed as reference, variable expected
5. Object Property Constants ❌ → ✅
Rule
Property names must match MQL5 documentation exactly
Common mistakes have similar but incorrect names
Critical Property Names
| ❌ WRONG | ✅ CORRECT | Object Type |
|---|---|---|
OBJPROP_FONT_SIZE |
OBJPROP_FONTSIZE |
All text objects |
OBJPROP_WIDTH |
OBJPROP_XSIZE |
Rectangle Label |
OBJPROP_HEIGHT |
OBJPROP_YSIZE |
Rectangle Label |
OBJPROP_ZORDER |
(doesn't exist) | All objects |
Examples
// ✅ CORRECT
ObjectSetInteger(0, "label", OBJPROP_FONTSIZE, 10);
ObjectSetInteger(0, "rect", OBJPROP_XSIZE, 200);
ObjectSetInteger(0, "rect", OBJPROP_YSIZE, 100);
// ❌ WRONG
ObjectSetInteger(0, "label", OBJPROP_FONT_SIZE, 10); // Underscore
ObjectSetInteger(0, "rect", OBJPROP_WIDTH, 200); // Doesn't exist
ObjectSetInteger(0, "rect", OBJPROP_HEIGHT, 100); // Doesn't exist
ObjectSetInteger(0, "rect", OBJPROP_ZORDER, 0); // Doesn't exist
Error Messages You'll See
undeclared identifiercannot convert enumwrong parameters count
6. Type Casting ❌ → ✅
Rule
Avoid spaces between cast closing paren and pointer asterisk
Store cast results in intermediate variables to avoid parser confusion
Examples
// ✅ CORRECT - No space, intermediate variable
CObject *obj = m_array.At(i);
CH4ZoneContext *ctx = (CH4ZoneContext*)obj;
CZoneState *zone = ctx.Zone();
// ❌ WRONG - Space in cast
CH4ZoneContext *ctx = (CH4ZoneContext *)obj; // Can confuse parser
// ❌ WRONG - Chained operations
CZoneState *zone = ((CH4ZoneContext*)m_array.At(i)).Zone(); // Parser errors
7. Const Correctness ❌ → ✅
Rule
MQL5 is stricter about const than C++
Avoid const on simple local variables and loop bounds
Examples
// ✅ CORRECT
uint total = PositionsTotal();
uint i;
for(i = 0; i < total; i++)
// ⚠️ POTENTIALLY PROBLEMATIC
const uint total = PositionsTotal(); // May cause issues in some contexts
// ✅ CORRECT - Use const for true constants
const double PI = 3.14159;
const int MAX_RETRIES = 3;
8. Position Functions (CRITICAL) ❌ → ✅
Rule
PositionSelectByIndex() does NOT exist in MQL5
Use PositionGetTicket(index) or PositionGetSymbol(index) instead
Why
This is a common error from MT4-to-MT5 migration or incorrect examples. The function simply doesn't exist in the MQL5 API.
Examples
// ✅ CORRECT - Method 1: Get ticket first
int total = PositionsTotal();
int i;
for(i = 0; i < total; i++)
{
ulong ticket = PositionGetTicket(i);
if(ticket == 0)
continue;
// Now access position properties
long magic = PositionGetInteger(POSITION_MAGIC);
double volume = PositionGetDouble(POSITION_VOLUME);
}
// ✅ CORRECT - Method 2: Get symbol (also selects position)
for(i = 0; i < total; i++)
{
string symbol = PositionGetSymbol(i);
if(symbol == "")
continue;
// Access properties for currently selected position
}
// ❌ WRONG - Function doesn't exist!
for(i = 0; i < total; i++)
{
if(!PositionSelectByIndex(i)) // Compilation error!
continue;
}
Error Messages You'll See
undeclared identifier(at the function name)'i' - some operator expected(at the parameter)- Error column numbers pointing inside the function call
Why Errors Are Cryptic
Because the compiler doesn't recognize PositionSelectByIndex, it tries to parse the entire line as an expression, producing confusing errors about operators and variables.
9. Quick Reference Checklist
Before committing MQL5 code, verify:
- All pointer member access uses
.not-> - All loop variables declared before
forstatement - NO use of
PositionSelectByIndex()- usePositionGetTicket()instead - All loop increments use
i++not++i - Dynamic arrays used with
ArraySetAsSeries(),CopyRates() - Function parameters avoid
const string &for temporaries - Object properties use correct names (verify in docs)
- No
CArrayObj.Create()calls - Type casts have no spaces:
(Type*)not(Type *) - No
OBJPROP_ZORDER,OBJPROP_WIDTH,OBJPROP_HEIGHT - Use
OBJPROP_FONTSIZEnotOBJPROP_FONT_SIZE
10. Compilation Verification
Always compile in MetaEditor before considering code complete:
# Windows PowerShell
& "C:\Program Files\MetaTrader 5\MetaEditor64.exe" /compile:"path\to\file.mq5"
Expected Result: 0 errors, 0 warnings
11. Common Error Patterns
If you see these errors, check these causes:
| Error Message | Most Likely Cause | Fix |
|---|---|---|
'>' - operand expected |
Using -> operator |
Change to . |
undeclared identifier (at loop) |
Variable declared in for-loop | Declare before loop |
undeclared identifier + operator expected |
Non-existent function like PositionSelectByIndex() |
Use PositionGetTicket(i) |
cannot be used for static allocated array |
Static array with ArraySetAsSeries() |
Use dynamic array [] |
parameter passed as reference |
Passing temporary to & param |
Use value parameter |
undeclared identifier (property) |
Wrong property name | Check MQL5 docs |
12. Resources
- MQL5 Documentation: https://www.mql5.com/en/docs
- Object Properties: https://www.mql5.com/en/docs/constants/objectconstants/enum_object_property
- Array Functions: https://www.mql5.com/en/docs/array
Last Updated: 2025-11-03
Validated Against: MQL5 Build 3960+