Page 1 of 1

The Definitive M1 XAU/USD Scalping Setup: Fibonacci EMAs & MQL4 Alert Indicator

Posted: Thu Aug 13, 2026 7:56 pm
by PTScalper
Hi scalpers,

i hope you are well and all of you have some kind of good trading results.

If you are scalping Gold (XAU/USD) on the 1-minute chart, you already know that traditional moving average crossovers lag too much to capture the explosive, micro-structural momentum shifts of this asset. Gold's high volatility and deep liquidity require a moving average system that reacts dynamically to price action while heavily filtering out the chop of ranging periods.After extensive forward-testing during the London and New York overlaps, the most robust institutional-grade setup relies on a tight cluster of Fibonacci-sequence Exponential Moving Averages (EMAs): 8, 13, 21, and 34.
Here is a complete breakdown of the mechanics, the execution rules, and the MQL4 code to build your own custom alert indicator.

The Fibonacci EMA Framework:

Unlike standard 9/21 or 50/200 setups, a Fibonacci cluster provides dynamic support and resistance bands rather than a single rigid line. Because the EMA calculation places heavier weight on the most recent candles, the sequence fans out during impulse waves and compresses during consolidation.

1.) 8 EMA (The Trigger): Reacts immediately to micro-momentum.

2.) 13 EMA & 21 EMA (The Value Zone): This is where you look for pullbacks. Price reverting to this pocket in a trend represents fair value.

3.) 34 EMA (The Baseline): Determines your overarching directional bias for the next 15–30 minutes.

Execution RulesLong Setup (Buy):

1.) Trend Alignment The EMAs must fan out in perfect ascending order: $EMA_8 > EMA_{13} > EMA_{21} > EMA_{34}$.

2.) The Trigger: Wait for price to pull back into the "Value Zone" (between the 13 and 21 EMAs) without closing below the 34 EMA.Entry:

3.) Enter upon the close of a bullish structural candle (e.g., a pin bar or engulfing candle) that closes back above the 8 EMA.

4.) Invalidation (Stop Loss): Place the hard stop 3-5 pips strictly below the 34 EMA or the recent structural swing low.

5.) Take Profit: Target a 1.5R to 2R, or scale out when the 8 EMA flattens and crosses back below the 13 EMA.

MQL4 Code: Custom Alert Indicator

To avoid staring at the M1 chart all day, you can use this lightweight MQL4 Custom Indicator. It paints arrows on your chart and triggers a terminal alert when the 8 EMA crosses the 13 EMA, strictly filtered by the 34 EMA baseline.

Code: Select all

//+------------------------------------------------------------------+
//|                                       Fib_EMA_Scalper_Alerts.mq4 |
//|                                            Expertise Level: High |
//+------------------------------------------------------------------+
#property copyright "Forum Community"
#property indicator_chart_window
#property indicator_buffers 2
#property indicator_color1 clrLimeGreen
#property indicator_color2 clrRed

//--- Inputs
input int TriggerEMA = 8;
input int ValueEMA   = 13;
input int BaseEMA    = 34;

//--- Buffers for Arrows
double BuyBuffer[];
double SellBuffer[];

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
   SetIndexStyle(0, DRAW_ARROW);
   SetIndexArrow(0, 233); // Up Arrow
   SetIndexBuffer(0, BuyBuffer);
   
   SetIndexStyle(1, DRAW_ARROW);
   SetIndexArrow(1, 234); // Down Arrow
   SetIndexBuffer(1, SellBuffer);
   
   return(INIT_SUCCEEDED);
  }

//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
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[])
  {
   int limit = rates_total - prev_calculated;
   if(prev_calculated > 0) limit++;
   
   for(int i = limit - 1; i >= 1; i--)
     {
      double EmaTrig0 = iMA(NULL, 0, TriggerEMA, 0, MODE_EMA, PRICE_CLOSE, i);
      double EmaTrig1 = iMA(NULL, 0, TriggerEMA, 0, MODE_EMA, PRICE_CLOSE, i+1);
      
      double EmaVal0  = iMA(NULL, 0, ValueEMA, 0, MODE_EMA, PRICE_CLOSE, i);
      double EmaVal1  = iMA(NULL, 0, ValueEMA, 0, MODE_EMA, PRICE_CLOSE, i+1);
      
      double EmaBase  = iMA(NULL, 0, BaseEMA, 0, MODE_EMA, PRICE_CLOSE, i);
      
      BuyBuffer[i] = EMPTY_VALUE;
      SellBuffer[i] = EMPTY_VALUE;
      
      // Buy Signal: 8 crosses above 13 AND both are above 34 baseline
      if(EmaTrig1 <= EmaVal1 && EmaTrig0 > EmaVal0 && close[i] > EmaBase)
        {
         BuyBuffer[i] = low[i] - 10 * Point;
         if(i == 1) Alert("XAUUSD M1: Bullish EMA Cross");
        }
        
      // Sell Signal: 8 crosses below 13 AND both are below 34 baseline
      if(EmaTrig1 >= EmaVal1 && EmaTrig0 < EmaVal0 && close[i] < EmaBase)
        {
         SellBuffer[i] = high[i] + 10 * Point;
         if(i == 1) Alert("XAUUSD M1: Bearish EMA Cross");
        }
     }
   return(rates_total);
  }
//+------------------------------------------------------------------+

Re: The Definitive M1 XAU/USD Scalping Setup: Fibonacci EMAs & MQL4 Alert Indicator

Posted: Thu Aug 13, 2026 7:57 pm
by PTScalper
For MT5 traders i prepared it here:

Because MT5 and cTrader use completely different architectures than MT4 (MQL5 uses indicator handles; cTrader uses C#), the code must be completely restructured.

Here are the expert-level ports for both platforms.

MetaTrader 5 (MQL5) Port
In MQL5, we don't call the indicator formula on every tick like in MT4. Instead, we generate "handles" in the OnInit() function to cache the indicators in the terminal's memory, and then use CopyBuffer() to extract the exact array of values we need. This makes it dramatically faster.

Code: Select all

//+------------------------------------------------------------------+
//|                                      Fib_EMA_Scalper_Alerts.mq5  |
//|                                           Expertise Level: High  |
//+------------------------------------------------------------------+
#property copyright "Forum Community"
#property indicator_chart_window
#property indicator_buffers 2
#property indicator_plots   2

//--- Plot 1: Buy Signal
#property indicator_label1  "Buy Signal"
#property indicator_type1   DRAW_ARROW
#property indicator_color1  clrLimeGreen
#property indicator_style1  STYLE_SOLID
#property indicator_width1  2

//--- Plot 2: Sell Signal
#property indicator_label2  "Sell Signal"
#property indicator_type2   DRAW_ARROW
#property indicator_color2  clrRed
#property indicator_style2  STYLE_SOLID
#property indicator_width2  2

//--- Inputs
input int TriggerEMA = 8;
input int ValueEMA   = 13;
input int BaseEMA    = 34;

//--- Buffers
double BuyBuffer[];
double SellBuffer[];

//--- Indicator Handles
int handle_trig;
int handle_val;
int handle_base;

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
   //--- Set up plotting arrays
   SetIndexBuffer(0, BuyBuffer, INDICATOR_DATA);
   PlotIndexSetInteger(0, PLOT_ARROW, 233); // Up Arrow
   
   SetIndexBuffer(1, SellBuffer, INDICATOR_DATA);
   PlotIndexSetInteger(1, PLOT_ARROW, 234); // Down Arrow
   
   //--- Initialize indicator handles
   handle_trig = iMA(_Symbol, _Period, TriggerEMA, 0, MODE_EMA, PRICE_CLOSE);
   handle_val  = iMA(_Symbol, _Period, ValueEMA, 0, MODE_EMA, PRICE_CLOSE);
   handle_base = iMA(_Symbol, _Period, BaseEMA, 0, MODE_EMA, PRICE_CLOSE);
   
   if(handle_trig == INVALID_HANDLE || handle_val == INVALID_HANDLE || handle_base == INVALID_HANDLE)
     {
      Print("Failed to create EMA handles");
      return(INIT_FAILED);
     }
     
   return(INIT_SUCCEEDED);
  }

//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
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[])
  {
   //--- Array setups for handle copying
   double EmaTrig[], EmaVal[], EmaBase[];
   ArraySetAsSeries(EmaTrig, true);
   ArraySetAsSeries(EmaVal, true);
   ArraySetAsSeries(EmaBase, true);
   ArraySetAsSeries(close, true);
   ArraySetAsSeries(high, true);
   ArraySetAsSeries(low, true);

   //--- Determine calculation limit
   int limit = rates_total - prev_calculated;
   if(prev_calculated == 0) limit = rates_total - 1;

   //--- Copy indicator data to arrays
   if(CopyBuffer(handle_trig, 0, 0, limit + 2, EmaTrig) <= 0 ||
      CopyBuffer(handle_val, 0, 0, limit + 2, EmaVal) <= 0 ||
      CopyBuffer(handle_base, 0, 0, limit + 2, EmaBase) <= 0) return(0);

   for(int i = limit; i >= 0 && !IsStopped(); i--)
     {
      BuyBuffer[i] = EMPTY_VALUE;
      SellBuffer[i] = EMPTY_VALUE;
      
      //--- Buy Signal logic
      if(EmaTrig[i+1] <= EmaVal[i+1] && EmaTrig[i] > EmaVal[i] && close[i] > EmaBase[i])
        {
         BuyBuffer[i] = low[i] - (10 * _Point);
         if(i == 0) Alert("XAUUSD M1: Bullish EMA Cross");
        }
        
      //--- Sell Signal logic
      if(EmaTrig[i+1] >= EmaVal[i+1] && EmaTrig[i] < EmaVal[i] && close[i] < EmaBase[i])
        {
         SellBuffer[i] = high[i] + (10 * _Point);
         if(i == 0) Alert("XAUUSD M1: Bearish EMA Cross");
        }
     }
   return(rates_total);
  }
//+------------------------------------------------------------------+

Re: The Definitive M1 XAU/USD Scalping Setup: Fibonacci EMAs & MQL4 Alert Indicator

Posted: Thu Aug 13, 2026 7:57 pm
by PTScalper
For Ctraders:

cTrader (C# / cAlgo) Port

cTrader uses standard C# (via their cAlgo API). It is beautifully object-oriented. Instead of dealing with memory buffers and iteration loops manually, you declare indicator instances on Initialize() and simply query their .Result on each bar via the Calculate() method.

Code: Select all

using System;
using cAlgo.API;
using cAlgo.API.Indicators;
using cAlgo.API.Internals;

namespace cAlgo
{
    [Indicator(IsOverlay = true, TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class FibEMAScalperAlerts : Indicator
    {
        [Parameter("Trigger EMA", DefaultValue = 8, Group = "Moving Averages")]
        public int TriggerPeriod { get; set; }

        [Parameter("Value EMA", DefaultValue = 13, Group = "Moving Averages")]
        public int ValuePeriod { get; set; }

        [Parameter("Base EMA", DefaultValue = 34, Group = "Moving Averages")]
        public int BasePeriod { get; set; }

        private ExponentialMovingAverage _triggerEma;
        private ExponentialMovingAverage _valueEma;
        private ExponentialMovingAverage _baseEma;

        protected override void Initialize()
        {
            // Initialize the built-in EMAs
            _triggerEma = Indicators.ExponentialMovingAverage(Bars.ClosePrices, TriggerPeriod);
            _valueEma = Indicators.ExponentialMovingAverage(Bars.ClosePrices, ValuePeriod);
            _baseEma = Indicators.ExponentialMovingAverage(Bars.ClosePrices, BasePeriod);
        }

        public override void Calculate(int index)
        {
            // Wait for enough bars to form
            if (index < BasePeriod) return;

            // Previous and current bar values
            double trigPrev = _triggerEma.Result[index - 1];
            double trigCurr = _triggerEma.Result[index];
            
            double valPrev = _valueEma.Result[index - 1];
            double valCurr = _valueEma.Result[index];
            
            double baseCurr = _baseEma.Result[index];
            double closeCurr = Bars.ClosePrices[index];

            // Setup conditions
            bool crossedAbove = trigPrev <= valPrev && trigCurr > valCurr;
            bool crossedBelow = trigPrev >= valPrev && trigCurr < valCurr;

            // Offset for drawing arrows neatly above/below candles
            double arrowOffset = Symbol.PipSize * 10; 

            // Buy Signal
            if (crossedAbove && closeCurr > baseCurr)
            {
                Chart.DrawIcon("Buy" + index, ChartIconType.UpArrow, index, Bars.LowPrices[index] - arrowOffset, Color.LimeGreen);
                
                if (IsLastBar)
                {
                    Notifications.PlaySound(SoundType.Doorbell);
                    Print("XAUUSD M1: Bullish EMA Cross");
                }
            }

            // Sell Signal
            if (crossedBelow && closeCurr < baseCurr)
            {
                Chart.DrawIcon("Sell" + index, ChartIconType.DownArrow, index, Bars.HighPrices[index] + arrowOffset, Color.Red);
                
                if (IsLastBar)
                {
                    Notifications.PlaySound(SoundType.Doorbell);
                    Print("XAUUSD M1: Bearish EMA Cross");
                }
            }
        }
    }
}

Re: The Definitive M1 XAU/USD Scalping Setup: Fibonacci EMAs & MQL4 Alert Indicator

Posted: Thu Aug 13, 2026 8:00 pm
by PTScalper
And finally in pine script for trading view traders.

Here is the exact translation of the strategy into Pine Script v5.

I have also added the visual plotting for all four Fibonacci EMAs (8, 13, 21, and 34) directly into this script. This way, you don't need to waste four of your allowed TradingView indicator slots just to see the "fan" effect on your chart.

TradingView (Pine Script v5) Port

Code: Select all

//@version=5
indicator("Fib EMA Scalper Alerts - M1 XAUUSD", overlay=true)

// =========================================================================
// INPUTS
// =========================================================================
grp1 = "Moving Averages"
trigger_len = input.int(8,  title="Trigger EMA (Fast)", group=grp1)
value_len   = input.int(13, title="Value EMA (Slow)",   group=grp1)
zone_len    = input.int(21, title="Zone EMA (Visual)",  group=grp1)
base_len    = input.int(34, title="Base EMA (Filter)",  group=grp1)

// =========================================================================
// CALCULATIONS
// =========================================================================
ema_trig = ta.ema(close, trigger_len)
ema_val  = ta.ema(close, value_len)
ema_zone = ta.ema(close, zone_len)
ema_base = ta.ema(close, base_len)

// =========================================================================
// VISUALS: THE FIBONACCI FAN
// =========================================================================
plot(ema_trig, color=color.new(color.aqua, 0),   title="8 EMA",  linewidth=2)
plot(ema_val,  color=color.new(color.orange, 0), title="13 EMA", linewidth=2)
plot(ema_zone, color=color.new(color.yellow, 0), title="21 EMA", linewidth=1)
plot(ema_base, color=color.new(color.red, 0),    title="34 EMA", linewidth=2)

// =========================================================================
// SIGNAL LOGIC
// =========================================================================
// Buy: 8 crosses over 13, and price is above the 34 Baseline
buySignal  = ta.crossover(ema_trig, ema_val) and (close > ema_base)

// Sell: 8 crosses under 13, and price is below the 34 Baseline
sellSignal = ta.crossunder(ema_trig, ema_val) and (close < ema_base)

// =========================================================================
// CHART SHAPES
// =========================================================================
plotshape(series=buySignal,  title="Buy Alert",  style=shape.triangleup,   location=location.belowbar, color=color.green, size=size.small)
plotshape(series=sellSignal, title="Sell Alert", style=shape.triangledown, location=location.abovebar, color=color.red,   size=size.small)

// =========================================================================
// SERVER ALERTS
// =========================================================================
alertcondition(buySignal,  title="Bullish EMA Cross", message="XAUUSD M1: Bullish EMA Cross (8 > 13) - Look for Long Entry")
alertcondition(sellSignal, title="Bearish EMA Cross", message="XAUUSD M1: Bearish EMA Cross (8 < 13) - Look for Short Entry")
How to use the TradingView Alerts:

1.) Unlike MT4/MT5 where the Alert() function fires automatically, TradingView requires you to arm the alert manually:

2.) Add this script to your M1 XAUUSD chart.

3.) Press Alt + A (or click the alarm clock icon on the right toolbar).

4.) In the Condition dropdown, select "Fib EMA Scalper Alerts..."
Select either the Bullish EMA Cross or Bearish EMA Cross. (You will need to create two separate alerts to monitor both directions).

5.) Set Trigger to "Once Per Bar Close" to ensure the 1-minute candle has physically closed and locked the EMA crossover, preventing repaint fakes.

Re: The Definitive M1 XAU/USD Scalping Setup: Fibonacci EMAs & MQL4 Alert Indicator

Posted: Thu Aug 13, 2026 8:00 pm
by PTScalper
I hope that it will help you.
Take a care and have a lot of great trades :-)