//+-------------------------------------------------------\!/--------------------------------------------------------+ //| MA-200 & Gann MA-HL Indicator - TRUE GANN METHOD | //+-------------------------------------------------------------------------------------------------------------------+ #property description "Dual Moving Average System: MA-200 and TRUE Gann High/Low MA" #property version "1.22" #property copyright "Authentic Gann HiLo Activator Logic" #property indicator_chart_window #property indicator_buffers 9 #property indicator_plots 3 //--- Plot 1: Colored Candles #property indicator_label1 "Colored Candles" #property indicator_type1 DRAW_COLOR_CANDLES #property indicator_color1 C'140,140,140', C'109,188,235', C'255,0,110' // Neutral, Blue Up, Red Down #property indicator_width1 1 //--- Plot 2: MA-HL (Gann High/Low) #property indicator_label2 "MA-HL (Gann)" #property indicator_type2 DRAW_COLOR_LINE #property indicator_color2 clrDodgerBlue, clrOrangeRed #property indicator_style2 STYLE_SOLID #property indicator_width2 3 //--- Plot 3: MA-200 #property indicator_label3 "MA-200" #property indicator_type3 DRAW_COLOR_LINE #property indicator_color3 clrLimeGreen, clrOrange #property indicator_style3 STYLE_SOLID #property indicator_width3 4 //+------------------------------------------------------------------------------------------------------------------+ //| INPUT PARAMETERS | //+------------------------------------------------------------------------------------------------------------------+ input group "=== Moving Average Settings ===" input int MA_HL_Period = 10; // MA-HL Period (Gann R value) input int MA_200_Period = 200; // MA-200 Period input ENUM_MA_METHOD MA_Method = MODE_EMA; // MA Method (Gann uses LWMA) input ENUM_APPLIED_PRICE MA_Price = PRICE_CLOSE; // Applied Price for MA-200 input group "=== Color and Width Settings ===" // MA-HL (Gann) colors and width input color MA_HL_Color_Up = C'109,188,235'; // MA-HL color when uptrend (LOW MA shown) input color MA_HL_Color_Down = C'255,0,110'; // MA-HL color when downtrend (HIGH MA shown) input int MA_HL_Width = 3; // MA-HL line width (input — treated as constant) // MA-200 colors and width input color MA200_Color_Up = clrLimeGreen; // MA-200 color when rising input color MA200_Color_Down = clrOrange; // MA-200 color when falling input int MA200_Width = 6; // MA-200 line width (input — treated as constant) // Candle colors input color CandleColor_Neutral = C'140,140,140'; // Candle neutral color input color CandleColor_Up = C'109,188,235'; // Candle up color (combined signal) input color CandleColor_Down = C'255,0,110'; // Candle down color (combined signal) input group "=== Display Settings ===" input bool CandleColorwithMA200 = true; // Candle coloring with MA-200 filter input group "=== Header Settings ===" input bool ShowSymbolHeader = false; // Show symbol header input int HeaderLR = 177; // Header left-right offset input int HeaderUD = 1; // Header up-down offset input int HeaderSize = 40; // Header font size (input — treated as constant) input color HeaderBackground = C'50,60,70'; // Header background color input group "=== Debug ===" input bool DebugWithSquealers = false; // Enable debug logging //+------------------------------------------------------------------------------------------------------------------+ //| GLOBAL VARIABLES | //+------------------------------------------------------------------------------------------------------------------+ long chartID; string MyName = "MA-200 & Gann MA-HL"; // mutable runtime copies of input settings (these are changeable) int runtime_MA_HL_Width = 0; int runtime_MA200_Width = 0; int runtime_HeaderSize = 0; // Buffers double buf_open[], buf_high[], buf_low[], buf_close[], buf_color[]; double buf_ma_hl[], buf_ma_hl_color[]; double buf_ma200[], buf_ma200_color[]; // Handles - TRUE GANN: MA on HIGH and LOW prices (not rolling highest/lowest) int handle_ma_hl_high; // MA of PRICE_HIGH int handle_ma_hl_low; // MA of PRICE_LOW int handle_ma200; // Object names string SymbolHeaderTextObj = "SymbolHeaderText"; string SymbolHeaderTextShadowObj = "SymbolHeaderTextShadow"; //+------------------------------------------------------------------------------------------------------------------+ //| INITIALIZATION | //+------------------------------------------------------------------------------------------------------------------+ int OnInit() { if (DebugWithSquealers) Print("OnInit Start - Chart ", ChartID()); chartID = ChartID(); // Validate periods if (MA_HL_Period < 1 || MA_200_Period < 1) { Print("Error: Invalid MA periods"); return INIT_PARAMETERS_INCORRECT; } // copy inputs to mutable runtime variables and clamp them runtime_MA_HL_Width = MA_HL_Width; if (runtime_MA_HL_Width < 1) runtime_MA_HL_Width = 1; runtime_MA200_Width = MA200_Width; if (runtime_MA200_Width < 1) runtime_MA200_Width = 1; runtime_HeaderSize = HeaderSize; if (runtime_HeaderSize < 1) runtime_HeaderSize = 10; // Set buffers for candles SetIndexBuffer(0, buf_open, INDICATOR_DATA); SetIndexBuffer(1, buf_high, INDICATOR_DATA); SetIndexBuffer(2, buf_low, INDICATOR_DATA); SetIndexBuffer(3, buf_close, INDICATOR_DATA); SetIndexBuffer(4, buf_color, INDICATOR_COLOR_INDEX); // Set buffers for MA-HL SetIndexBuffer(5, buf_ma_hl, INDICATOR_DATA); SetIndexBuffer(6, buf_ma_hl_color, INDICATOR_COLOR_INDEX); // Set buffers for MA-200 SetIndexBuffer(7, buf_ma200, INDICATOR_DATA); SetIndexBuffer(8, buf_ma200_color, INDICATOR_COLOR_INDEX); PlotIndexSetDouble(0, PLOT_EMPTY_VALUE, 0); PlotIndexSetDouble(1, PLOT_EMPTY_VALUE, 0); PlotIndexSetDouble(2, PLOT_EMPTY_VALUE, 0); // Create MA handles - TRUE GANN METHOD // MA on HIGH prices (not highest high) handle_ma_hl_high = iMA(_Symbol, _Period, MA_HL_Period, 0, MA_Method, PRICE_HIGH); // MA on LOW prices (not lowest low) handle_ma_hl_low = iMA(_Symbol, _Period, MA_HL_Period, 0, MA_Method, PRICE_LOW); // Standard MA-200 handle_ma200 = iMA(_Symbol, _Period, MA_200_Period, 0, MA_Method, MA_Price); if (handle_ma_hl_high == INVALID_HANDLE || handle_ma_hl_low == INVALID_HANDLE || handle_ma200 == INVALID_HANDLE) { Print("Failed to create MA handles"); return INIT_FAILED; } // Apply runtime colors and widths to plots // Plot 2 (index 1) is MA-HL; set its line width PlotIndexSetInteger(1, PLOT_LINE_WIDTH, runtime_MA_HL_Width); // Plot 3 (index 2) is MA-200; set its line width PlotIndexSetInteger(2, PLOT_LINE_WIDTH, runtime_MA200_Width); // Create symbol header if (ShowSymbolHeader) { CreateSymbolHeader(); } IndicatorSetInteger(INDICATOR_DIGITS, _Digits); IndicatorSetString(INDICATOR_SHORTNAME, MyName + " (" + IntegerToString(MA_HL_Period) + "/" + IntegerToString(MA_200_Period) + ")"); if (DebugWithSquealers) Print("OnInit Complete - TRUE GANN METHOD: MA of HIGH/LOW prices"); return INIT_SUCCEEDED; } //+------------------------------------------------------------------------------------------------------------------+ //| DEINITIALIZATION | //+------------------------------------------------------------------------------------------------------------------+ void OnDeinit(const int reason) { if (DebugWithSquealers) Print("OnDeinit - Reason: ", reason); Comment(""); // Release handles if (handle_ma_hl_high != INVALID_HANDLE) IndicatorRelease(handle_ma_hl_high); if (handle_ma_hl_low != INVALID_HANDLE) IndicatorRelease(handle_ma_hl_low); if (handle_ma200 != INVALID_HANDLE) IndicatorRelease(handle_ma200); // Delete objects ObjectDelete(0, SymbolHeaderTextObj); ObjectDelete(0, SymbolHeaderTextShadowObj); } //+------------------------------------------------------------------------------------------------------------------+ //| MAIN CALCULATION - TRUE GANN HILO ACTIVATOR | //+------------------------------------------------------------------------------------------------------------------+ int OnCalculate(const int rates_total, const int prev_calculated, const datetime &time[], const double &open[], const double &high[], const double &low[], const double &close[], const long &tick_volume[], const long &volume[], const int &spread[]) { if (rates_total < MA_200_Period + 1) return 0; // Prepare arrays double ma_hl_high[], ma_hl_low[], ma200[]; ArrayResize(ma_hl_high, rates_total); ArrayResize(ma_hl_low, rates_total); ArrayResize(ma200, rates_total); ArraySetAsSeries(ma_hl_high, false); ArraySetAsSeries(ma_hl_low, false); ArraySetAsSeries(ma200, false); // Copy MA data - TRUE GANN: These are MAs of HIGH and LOW prices if (CopyBuffer(handle_ma_hl_high, 0, 0, rates_total, ma_hl_high) != rates_total || CopyBuffer(handle_ma_hl_low, 0, 0, rates_total, ma_hl_low) != rates_total || CopyBuffer(handle_ma200, 0, 0, rates_total, ma200) != rates_total) { if (DebugWithSquealers) Print("Failed to copy buffer data"); return 0; } // Swing state array for Gann HiLo Activator logic int swing[]; ArrayResize(swing, rates_total); ArraySetAsSeries(swing, false); // Calculate starting index int start_idx = (prev_calculated > 1) ? prev_calculated - 1 : 1; // Initialize first bar if (rates_total > 0) { InitializeFirstBar(0, open, high, low, close, ma_hl_high, ma_hl_low, ma200, swing); } // Calculate all bars using TRUE GANN logic for (int i = start_idx; i < rates_total; i++) { // Copy OHLC buf_open[i] = open[i]; buf_high[i] = high[i]; buf_low[i] = low[i]; buf_close[i] = close[i]; // Copy MA-200 buf_ma200[i] = ma200[i]; // TRUE GANN HILO ACTIVATOR LOGIC // Compare CURRENT close with CURRENT MA values for immediate color change double currentClose = close[i]; double currentMA_High = ma_hl_high[i]; double currentMA_Low = ma_hl_low[i]; // Gann Swing State Logic: // If close < MA(LOW) → Downtrend (-1) // If close > MA(HIGH) → Uptrend (1) // Otherwise → Keep previous state if (currentClose < currentMA_Low) { swing[i] = -1; // Downtrend } else if (currentClose > currentMA_High) { swing[i] = 1; // Uptrend } else { swing[i] = swing[i - 1]; // Keep previous swing state } // Set MA-HL plot based on swing state // Uptrend: show LOW MA (support) // Downtrend: show HIGH MA (resistance) if (swing[i] == 1) { buf_ma_hl[i] = currentMA_Low; buf_ma_hl_color[i] = 0; // Blue (uptrend) } else if (swing[i] == -1) { buf_ma_hl[i] = currentMA_High; buf_ma_hl_color[i] = 1; // Red (downtrend) } else { // Neutral (shouldn't happen after first bar, but just in case) buf_ma_hl[i] = (currentMA_High + currentMA_Low) / 2.0; buf_ma_hl_color[i] = 0; } // Set MA-200 color if (i == 0) buf_ma200_color[i] = 0; else { int ma200Signal = (ma200[i] > ma200[i - 1]) ? 1 : (ma200[i] < ma200[i - 1]) ? -1 : 0; buf_ma200_color[i] = (ma200Signal > 0) ? 0 : 1; // Green/Orange } // Set candle color if (CandleColorwithMA200) { int candleBase = (close[i] > ma200[i]) ? 1 : (close[i] < ma200[i]) ? -1 : 0; int candleSignal = (candleBase == 1 && swing[i] == 1) ? 1 : (candleBase == -1 && swing[i] == -1) ? -1 : 0; buf_color[i] = (candleSignal == 1) ? 1 : (candleSignal == -1) ? 2 : 0; } else { buf_color[i] = (swing[i] == 1) ? 1 : (swing[i] == -1) ? 2 : 0; } // Debug output for verification if (DebugWithSquealers && i == rates_total - 1) { PrintFormat("GANN DEBUG [%d]: Close=%.5f, MA_High=%.5f, MA_Low=%.5f, Swing=%d, Plot=%.5f", i, currentClose, currentMA_High, currentMA_Low, swing[i], buf_ma_hl[i]); } } // Update header UpdateSymbolHeader(rates_total); return rates_total; } //+------------------------------------------------------------------------------------------------------------------+ //| HELPER FUNCTIONS | //+------------------------------------------------------------------------------------------------------------------+ void InitializeFirstBar(int idx, const double &open[], const double &high[], const double &low[], const double &close[], const double &ma_hl_high[], const double &ma_hl_low[], const double &ma200[], int &swing[]) { buf_open[idx] = open[idx]; buf_high[idx] = high[idx]; buf_low[idx] = low[idx]; buf_close[idx] = close[idx]; buf_ma200[idx] = ma200[idx]; buf_ma_hl[idx] = (ma_hl_high[idx] + ma_hl_low[idx]) / 2.0; buf_color[idx] = 0; buf_ma_hl_color[idx] = 0; buf_ma200_color[idx] = 0; swing[idx] = 0; // Neutral start } void CreateSymbolHeader() { string symText = _Symbol + " " + TimeFrameToString(_Period); // Shadow ObjectCreate(0, SymbolHeaderTextShadowObj, OBJ_LABEL, 0, 0, 0); ObjectSetInteger(0, SymbolHeaderTextShadowObj, OBJPROP_CORNER, CORNER_LEFT_UPPER); ObjectSetInteger(0, SymbolHeaderTextShadowObj, OBJPROP_XDISTANCE, HeaderLR + 333); ObjectSetInteger(0, SymbolHeaderTextShadowObj, OBJPROP_YDISTANCE, HeaderUD + 11); ObjectSetString(0, SymbolHeaderTextShadowObj, OBJPROP_TEXT, symText); ObjectSetString(0, SymbolHeaderTextShadowObj, OBJPROP_FONT, "Arial Black"); ObjectSetInteger(0, SymbolHeaderTextShadowObj, OBJPROP_FONTSIZE, runtime_HeaderSize); ObjectSetInteger(0, SymbolHeaderTextShadowObj, OBJPROP_COLOR, HeaderBackground); ObjectSetInteger(0, SymbolHeaderTextShadowObj, OBJPROP_ANCHOR, ANCHOR_RIGHT_UPPER); ObjectSetInteger(0, SymbolHeaderTextShadowObj, OBJPROP_SELECTABLE, false); // Main text ObjectCreate(0, SymbolHeaderTextObj, OBJ_LABEL, 0, 0, 0); ObjectSetInteger(0, SymbolHeaderTextObj, OBJPROP_CORNER, CORNER_LEFT_UPPER); ObjectSetInteger(0, SymbolHeaderTextObj, OBJPROP_XDISTANCE, HeaderLR + 332); ObjectSetInteger(0, SymbolHeaderTextObj, OBJPROP_YDISTANCE, HeaderUD + 12); ObjectSetString(0, SymbolHeaderTextObj, OBJPROP_TEXT, symText); ObjectSetString(0, SymbolHeaderTextObj, OBJPROP_FONT, "Arial Black"); ObjectSetInteger(0, SymbolHeaderTextObj, OBJPROP_FONTSIZE, runtime_HeaderSize); ObjectSetInteger(0, SymbolHeaderTextObj, OBJPROP_COLOR, clrSilver); ObjectSetInteger(0, SymbolHeaderTextObj, OBJPROP_ANCHOR, ANCHOR_RIGHT_UPPER); ObjectSetInteger(0, SymbolHeaderTextObj, OBJPROP_SELECTABLE, false); } void UpdateSymbolHeader(int rates_total) { if (!ShowSymbolHeader || rates_total == 0) return; int lastColor = (int)buf_color[rates_total - 1]; color headerColor = (lastColor == 1) ? C'109,188,235' : (lastColor == 2) ? C'255,0,110' : C'62,62,62'; ObjectSetInteger(0, SymbolHeaderTextObj, OBJPROP_COLOR, headerColor); } string TimeFrameToString(int tf) { switch (tf) { case PERIOD_M1: return "M1"; case PERIOD_M5: return "M5"; case PERIOD_M15: return "M15"; case PERIOD_M30: return "M30"; case PERIOD_H1: return "H1"; case PERIOD_H4: return "H4"; case PERIOD_D1: return "D1"; case PERIOD_W1: return "W1"; case PERIOD_MN1: return "MN"; default: return StringFormat("M%d", tf); } }