TriZone Semafor MT4
- Indicators
-
Ahmed Hamed Hamed Eadwan
Hello, I'm Ahmed — a trader and MQL5 developer based in the
United Arab Emirates, and the founder of R protocols.
I've been writing code since 1984 and trading the markets since 2006.
For many years, I developed trading tools for my own use, refining them
through real market experience. - Version: 1.0
TriZone Semafor — 3-Level Exclusive Signal ZigZag (Standalone — Built-in ZigZag, No External Indicators)
If you have ever stared at a chart covered in ZigZag arrows and wondered which ones actually matter — this indicator was built for that frustration.
TriZone Semafor runs three independent ZigZag algorithms simultaneously: Fast (Period 5), Medium (Period 13), and Slow (Period 34). When they detect pivots on the same candle, only the most significant signal survives. Level 3 always overrides Level 2. Level 2 always overrides Level 1. One clean arrow per candle per direction — no stacking, no double-counting.
Why three levels instead of one
A single ZigZag treats all swings equally. The same indicator marks a two-bar pullback and a major trend reversal with identical arrows. TriZone classifies every pivot by significance so you read the chart hierarchy at a glance.
- Level 1 — Fast: Small pullbacks and minor pivots. The structure beneath the structure.
- Level 2 — Medium: Intraday swings and meaningful reactions. The pivots your trading journal references.
- Level 3 — Slow: Major structural turns. The points where trend continuation is genuinely in question.
Each level has its own arrow shape and color so you see the hierarchy instantly, without consulting a legend.
Exclusive signal system
Every candle passes through one rule: if a higher level claims a pivot on that candle, all lower-level claims are removed — not hidden, removed. This happens inside the indicator buffer before anything reaches the chart. The chart reflects the real state, not a layered overlay.
Anti-repaint mode
With AntiRepaint = ON, a signal is only drawn after the configured number of confirmation bars have passed. The arrow you see has already passed its stability window and will not move. The indicator shows the current mode and confirmation depth in the chart title bar — full transparency about what you are reading.
With AntiRepaint = OFF, signals appear immediately on the forming bar. Useful for visual reference. Not recommended for automated logic.
Alert system
Alerts are queued during calculation and delivered only after the exclusivity pass confirms the signal survived. You will never receive a popup for a Level 1 signal overridden by Level 3 a moment later. One confirmed pivot — one alert. Configurable per level independently.
What is included
- Three ZigZag detection levels with fully independent parameters
- Exclusive signal priority at buffer level — highest level wins per candle
- Popup alerts on confirmed pivots only — no phantom alerts
- Anti-repaint mode with configurable confirmation bars per level
- Any symbol, any timeframe — MetaTrader 4
- Single file — zero external dependencies, no DLL, no custom includes
Recommended starting point
Open H1 or H4 with default parameters. The default depths 5 / 13 / 34 follow the standard Fibonacci sequence — a natural fit for most instruments and timeframes.
Level 3 pivots are your structural reference. Level 2 are your intraday reference points. Level 1 shows the minor structure in between. Adjust depth (Period) and confirmation bars (ConfirmBars) to match your style.
Compatibility
MetaTrader 4 — any broker, any symbol, any timeframe. No external libraries. No DLL imports. Single .ex4 file, fully standalone.
iCustom Reference — TriZone_Semafor
Output Buffers
Exclusivity is already applied by the indicator.
Only the highest active level is non-empty per candle.
EMPTY_VALUE = no pivot at that bar/level.
With AntiRepaint ON, read at shift >= max(ConfirmBars1, ConfirmBars2, ConfirmBars3) — default: shift >= 4.
| Buffer | Index | Signal | Content |
|---|---|---|---|
| BufLow1 | 0 | BUY | Level 1 Low pivot price — Fast ZigZag |
| BufHigh1 | 1 | SELL | Level 1 High pivot price — Fast ZigZag |
| BufLow2 | 2 | BUY | Level 2 Low pivot price — Medium ZigZag |
| BufHigh2 | 3 | SELL | Level 2 High pivot price — Medium ZigZag |
| BufLow3 | 4 | BUY | Level 3 Low pivot price — Slow ZigZag |
| BufHigh3 | 5 | SELL | Level 3 High pivot price — Slow ZigZag |
Input Parameters
# = position in iCustom() call (0-based, after Symbol / Period / FileName)
In MT4, ALL input parameters must be passed in order. You cannot skip middle parameters.
Trailing parameters may be omitted (defaults used).
| # | Name | Type | Default | Range | Description |
|---|---|---|---|---|---|
| LEVEL 1 — Fast ZigZag | |||||
| 0 | ColorL1Low | color | clrAqua | color | Arrow color for Level 1 Lows |
| 1 | ColorL1High | color | clrMagenta | color | Arrow color for Level 1 Highs |
| 2 | Period1 | int | 5 | 2-500 | Pivot lookback depth (bars) |
| 3 | Deviation1 | int | 1 | 1-100000 | Minimum deviation in points |
| 4 | Backstep1 | int | 3 | 1-(P-1) | Min bars between consecutive pivots |
| 5 | HighSymbol1 | int | 159 | Wingdings | Arrow for Highs (159=dot, 108=circle, 116=diamond) |
| 6 | LowSymbol1 | int | 159 | Wingdings | Arrow for Lows |
| 7 | ConfirmBars1 | int | 2 | 1-50 | Confirmation bars before signal is final |
| LEVEL 2 — Medium ZigZag | |||||
| 8 | ColorL2Low | color | clrDodgerBlue | color | Arrow color for Level 2 Lows |
| 9 | ColorL2High | color | clrOrchid | color | Arrow color for Level 2 Highs |
| 10 | Period2 | int | 13 | 2-500 | Pivot lookback depth |
| 11 | Deviation2 | int | 8 | 1-100000 | Minimum deviation in points |
| 12 | Backstep2 | int | 5 | 1-(P-1) | Min bars between consecutive pivots |
| 13 | HighSymbol2 | int | 108 | Wingdings | Arrow for Highs |
| 14 | LowSymbol2 | int | 108 | Wingdings | Arrow for Lows |
| 15 | ConfirmBars2 | int | 3 | 1-50 | Confirmation bars |
| LEVEL 3 — Slow ZigZag | |||||
| 16 | ColorL3Low | color | clrGold | color | Arrow color for Level 3 Lows |
| 17 | ColorL3High | color | clrOrangeRed | color | Arrow color for Level 3 Highs |
| 18 | Period3 | int | 34 | 2-500 | Pivot lookback depth |
| 19 | Deviation3 | int | 21 | 1-100000 | Minimum deviation in points |
| 20 | Backstep3 | int | 12 | 1-(P-1) | Min bars between consecutive pivots |
| 21 | HighSymbol3 | int | 116 | Wingdings | Arrow for Highs (116=diamond) |
| 22 | LowSymbol3 | int | 116 | Wingdings | Arrow for Lows |
| 23 | ConfirmBars3 | int | 4 | 1-50 | Confirmation bars |
| INSTANCE MANAGEMENT | |||||
| 24 | InstanceID | string | "A" | any | Unique tag — must differ from any visible chart copy |
| 25 | DebugMode | ENUM_ONOFF | OFF (0) | 0 / 1 | Print diagnostics to Journal |
| 26 | HeadlessMode | ENUM_ONOFF | OFF (0) | 0 / 1 | Set 1 (ON) when using via iCustom — suppresses all UI and alerts |
| ANTI-REPAINT | |||||
| 27 | AntiRepaint | ENUM_ONOFF | ON (1) | 0 / 1 | ON = confirmed signals only — required for stable EA logic |
| 28 | SafeArrows | ENUM_ONOFF | OFF (0) | 0 / 1 | ON = arrows use full retroactive-safe shift (stricter) |
| ALERT SYSTEM | |||||
| 29 | AlertMode | ENUM_ALERT_MODE | 1 (Popup) | 0-3 | 0=None 1=Popup 2=Push 3=All — set 0 inside EA |
| 30 | AlertLevel1 | ENUM_ONOFF | OFF (0) | 0 / 1 | Alert on Level 1 pivots |
| 31 | AlertLevel2 | ENUM_ONOFF | ON (1) | 0 / 1 | Alert on Level 2 pivots |
| 32 | AlertLevel3 | ENUM_ONOFF | ON (1) | 0 / 1 | Alert on Level 3 pivots |
Total: 33 parameters (indices 0-32)
iCustom Code Example
File name: "TriZone_Semafor" (no .ex4) — Always set HeadlessMode = true inside any EA.
In MT4, iCustom returns a double directly for a specific buffer index and shift.
No handle management, no CopyBuffer, no IndicatorRelease needed.
// MT4 iCustom signature:
// double iCustom(symbol, timeframe, "name", params..., bufferIndex, shift)
// We wrap it in a helper function for cleaner EA code.
double TZS_GetBuffer(int bufferIndex, int shift)
{
return iCustom(
Symbol(), // symbol
Period(), // timeframe
"TriZone_Semafor", // exact file name, no .ex4
// ---- Level 1: Fast ----
clrAqua, // #0 ColorL1Low
clrMagenta, // #1 ColorL1High
5, // #2 Period1
1, // #3 Deviation1
3, // #4 Backstep1
159, // #5 HighSymbol1 (dot)
159, // #6 LowSymbol1 (dot)
2, // #7 ConfirmBars1
// ---- Level 2: Medium ----
clrDodgerBlue, // #8 ColorL2Low
clrOrchid, // #9 ColorL2High
13, // #10 Period2
8, // #11 Deviation2
5, // #12 Backstep2
108, // #13 HighSymbol2 (circle)
108, // #14 LowSymbol2 (circle)
3, // #15 ConfirmBars2
// ---- Level 3: Slow ----
clrGold, // #16 ColorL3Low
clrOrangeRed, // #17 ColorL3High
34, // #18 Period3
21, // #19 Deviation3
12, // #20 Backstep3
116, // #21 HighSymbol3 (diamond)
116, // #22 LowSymbol3 (diamond)
4, // #23 ConfirmBars3
// ---- Instance ----
"EA1", // #24 InstanceID — must differ from any chart copy
false, // #25 DebugMode = OFF
true, // #26 HeadlessMode = ON <- required for EA usage
// ---- Anti-Repaint ----
true, // #27 AntiRepaint = ON (stable EA signals)
false, // #28 SafeArrows = OFF
// ---- Alerts: all OFF inside EA ----
0, // #29 AlertMode = ALERT_NONE
false, // #30 AlertLevel1
false, // #31 AlertLevel2
false, // #32 AlertLevel3
// ---- Buffer + Shift ----
bufferIndex, // buffer index (0-5)
shift // bar shift
);
}
// Reading buffers at confirmed shift
void OnTick()
{
int safeShift = 4;
double lo1 = TZS_GetBuffer(0, safeShift); // BufLow1 — Level 1 BUY
double hi1 = TZS_GetBuffer(1, safeShift); // BufHigh1 — Level 1 SELL
double lo2 = TZS_GetBuffer(2, safeShift); // BufLow2 — Level 2 BUY
double hi2 = TZS_GetBuffer(3, safeShift); // BufHigh2 — Level 2 SELL
double lo3 = TZS_GetBuffer(4, safeShift); // BufLow3 — Level 3 BUY
double hi3 = TZS_GetBuffer(5, safeShift); // BufHigh3 — Level 3 SELL
double ev = EMPTY_VALUE;
int buyLevel = (lo3 != ev) ? 3 : (lo2 != ev) ? 2 : (lo1 != ev) ? 1 : 0;
int sellLevel = (hi3 != ev) ? 3 : (hi2 != ev) ? 2 : (hi1 != ev) ? 1 : 0;
if(buyLevel > 0 && sellLevel == 0)
PrintFormat("BUY signal | Level %d | shift %d", buyLevel, safeShift);
else if(sellLevel > 0 && buyLevel == 0)
PrintFormat("SELL signal | Level %d | shift %d", sellLevel, safeShift);
}
// OnDeinit — No handle cleanup needed in MT4
void OnDeinit(const int reason)
{
// MT4 does not use indicator handles — nothing to release.
// iCustom calls are stateless per invocation.
}
Common Mistakes
Most common cause of INIT_PARAMETERS_INCORRECT: InstanceID is already in use by a chart copy of the same indicator. Use a unique string such as "EA1", "EA2" ...
| Mistake | Symptom | Fix |
|---|---|---|
| Same InstanceID as chart copy | INIT_PARAMETERS_INCORRECT | Unique ID: "EA1", "EA2" ... |
| HeadlessMode = false in EA | Indicator draws objects + alerts | Set parameter #26 to true |
| Reading shift = 0 with AntiRepaint | EMPTY_VALUE always — bar not yet confirmed | Read at shift >= 4 |
| AlertMode != 0 inside EA | Alert() popups block Tester execution | Set parameter #29 to 0 |
| Wrong file name in iCustom | Returns 0 / EMPTY_VALUE | Use exact name: "TriZone_Semafor" |
| Missing color parameters in iCustom | Wrong buffer values or 0 returned | Pass ALL 33 parameters in order |
| Wrong parameter order | Incorrect signals or none | Follow the table above exactly (0-32) |
