- 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
361 lines
9.4 KiB
Markdown
361 lines
9.4 KiB
Markdown
---
|
|
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
|
|
```mql5
|
|
// ✅ 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
|
|
```mql5
|
|
// ✅ 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
|
|
```mql5
|
|
// ✅ 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
|
|
```mql5
|
|
// 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 ¶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
|
|
```mql5
|
|
// ✅ 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
|
|
```mql5
|
|
// ✅ 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
|
|
```mql5
|
|
// ✅ 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
|
|
```mql5
|
|
// ✅ 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
|
|
```mql5
|
|
// ✅ 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:
|
|
|
|
```bash
|
|
# 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+
|