--- name: fibo-zone-indicator description: > Multi-timeframe Fibonacci retracement + S/R indicator for MetaTrader 5. Draws buy zones (61.8-80.1% retracement) on lower portion of bars with TP/SL lines, plus support/resistance levels and psychological price levels. Built for XAUUSD (gold) but works on any symbol. category: mql5 --- # FiboZone Indicator — MQL5 Implementation ## Overview Indicator สำหรับ XAUUSD — แสดง Fibonacci retracement zones จาก D1/H4/H1 พร้อม: - Buy zone (61.8-80.1%) อยู่ lower portion ของแท่ง - TP/SL lines - Support/Resistance levels (จาก 20 bars ย้อนหลัง) - Psychological price levels ## Key Code Patterns ### MQL5 Array Parameter Syntax **CRITICAL**: When passing arrays OUT of a function (output parameters), use reference-to-array syntax: ```mql5 // WRONG — treats as reference to single element int FindSRLevels(const double &highs[], const double &lows[], int count, SSRLevel &srOut, int maxOut) // CORRECT — reference to array int FindSRLevels(const double &highs[], const double &lows[], int count, SSRLevel &srOut[], int maxOut) ``` Every declaration, definition, and call site must use `[]` on array parameters. Mismatch causes compile errors: `cannot convert 'double[]' to 'double&'`. ### ArrayResize Before Indexing Always `ArrayResize` on output arrays BEFORE writing to them: ```mql5 // WRONG — array out of range for(int i = 0; i < outCount; i++) srOut[i] = filtered[i]; // CORRECT ArrayResize(srOut, outCount); for(int i = 0; i < outCount; i++) srOut[i] = filtered[i]; ``` ### Fibo Zone Calculation — Lower Portion User clarified: Fibo tool 0% = TOP, 100% = BOTTOM. Zone 61.8-80.1% must be in LOWER portion of the bar. **Bullish bar** (close > open): Zone near LOW → subtract from HIGH ```mql5 r.zoneHigh = high - barHeight * 0.618; // closer to high r.zoneLow = high - barHeight * 0.801; // closer to low (lower portion) ``` **Bearish bar** (close < open): Zone near LOW of the bar → add from LOW ```mql5 r.zoneHigh = low + barHeight * 0.801; // closer to high r.zoneLow = low + barHeight * 0.618; // closer to low (lower portion) ``` ### Calculation Test (Manual) Bullish bar: High=4766, Low=4664, Bar=102 ```mql5 // Lower portion of bullish bar: zoneHigh = 4766 - 102 * 0.618 = 4702.96 zoneLow = 4766 - 102 * 0.801 = 4684.30 // Zone: [4684, 4703] ✅ in lower portion (closer to low) ``` Bearish bar: High=4766, Low=4664, Bar=102 ```mql5 // Lower portion of bearish bar: zoneHigh = 4664 + 102 * 0.801 = 4745.70 zoneLow = 4664 + 102 * 0.618 = 4727.04 // Zone: [4727, 4746] ✅ in lower portion ``` ### OBJ_RECTANGLE for Price Zones `OBJ_RECTANGLE` needs distinct time1 and time2 to span chart width: ```mql5 // WRONG — time1 == time2 → zero-width (looks like vertical line) ObjectCreate(0, name, OBJ_RECTANGLE, 0, anchorTime, zoneLow, anchorTime, zoneHigh); // CORRECT — time2 = far future → spans full chart width datetime rightTime = D'2099.12.31 23:59:59'; ObjectCreate(0, name, OBJ_RECTANGLE, 0, anchorTime, zoneLow, rightTime, zoneHigh); ObjectSetInteger(0, name, OBJPROP_FILL, true); ObjectSetInteger(0, name, OBJPROP_COLOR, ColorToARGB(zoneColor, 60)); ``` ### S/R Zone Width Parameter `InpSRZoneWidth` groups similar prices into one S/R zone. Must be smaller than the actual price range: ```mql5 // Example: XAUUSD range ~100 points over 20 bars // zoneWidth = 200 → all bars in ONE zone → only 1-3 S/R lines // zoneWidth = 50 → ~2 zones → more S/R lines input int InpSRZoneWidth = 50; input int InpSRMinHits = 2; // lower from 5 to see more lines input int InpMaxSR = 4; ``` ## Common Bugs Fixed | Bug | Fix | |-----|-----| | `cannot convert double[] to double&` | Change all array params to `&arr[]` syntax | | `array out of range` at line N | Add `ArrayResize(srOut, count)` before `srOut[i] =` | | Rectangle looks like vertical line | Set `time2 = D'2099.12.31'` not `anchorTime` | | Fibo zone in wrong portion | Use high-subtract for bullish, low-add for bearish | | S/R zoneWidth=200, only 3 lines | Reduce to ~50 for XAUUSD range |