MQL4/.github/instructions/mql5-syntax-critical.instructions.md
Rahul Dhangar 669ecde7b7 Initial commit: Documentation and MT4 EA Phases 1-3 complete
- 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
2025-11-04 01:38:41 +05:30

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 expected
  • undeclared 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 const on loop bound variables: use int total not const int total

Error Messages You'll See

  • undeclared identifier
  • 'i' - some operator expected
  • expression 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 array
  • undeclared identifier (for .Create())

4. Function Parameters

Rule

Avoid const Type &parameter 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 identifier
  • cannot convert enum
  • wrong 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 for statement
  • NO use of PositionSelectByIndex() - use PositionGetTicket() 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_FONTSIZE not OBJPROP_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


Last Updated: 2025-11-03
Validated Against: MQL5 Build 3960+