Summary: Gold Candle Stability EA is an MQL4 expert advisor for XAUUSD that trades pure candlestick patterns: inside bars for breakouts and pin bars for reversals. Suitable for H1.




Gold Candle Stability EA is built exclusively around candlestick price action without traditional indicators. It identifies two high-probability K-line patterns on gold: inside bars (consolidation followed by breakout) and pin bars (rejection/reversal signals). The EA filters trades using ATR-based volatility confirmation and includes a trend context filter using a simple moving average. Each trade has fixed stop loss based on the pattern's high/low and take profit at 2x risk. The EA includes equity protection, spread filter, and Friday close mechanism.

Recommended Timeframe: H1
Trading Logic:
  • Inside Bar Pattern: A candle completely inside previous candle's range. Entry when price breaks the mother bar's high/low by 1.5x ATR.

  • Pin Bar Pattern: A candle with long wick (>=2x body) and small body. Entry on close in opposite direction of the wick.

  • Trend Filter (optional): Use EMA(50) to only take long when price above EMA, short when below.

  • Risk Management: Stop loss at pattern extreme (mother bar high/low for inside, pin wick end for pin). Take profit at 2x stop distance.


  • ``mql4
    //+------------------------------------------------------------------+
    //| GoldCandleStabilityEA.mq4 |
    //+------------------------------------------------------------------+
    #property copyright ""
    #property link ""
    #property version "1.00"
    #property strict

    //--- input parameters with comments
    input double LotSize = 0.01; // Fixed lot size (0.01 lot for gold)
    input bool UseTrendFilter = true; // Use EMA50 trend filter (true/false)
    input int TrendMAPeriod = 50; // EMA period for trend filter
    input double InsideBreakoutATR = 1.5; // ATR multiplier for inside bar breakout confirmation
    input double PinBodyRatio = 2.0; // Min wick-to-body ratio for pin bar (wick/body >= this)
    input double RiskReward = 2.0; // Risk reward ratio (TP = SL this)
    input int ATRPeriod = 14; // ATR period for volatility filter
    input double MaxATRMultiplier = 1.8; // Max ATR multiplier (skip high volatility)
    input int MagicNumber = 202418; // Unique EA identifier
    input int MaxSpread = 35; // Maximum allowed spread in points
    input double DailyLossLimit = 5.0; // Daily loss limit as percentage of balance
    input bool UseFridayClose = true; // Close trades before Friday 20:00 GMT

    //--- global variables
    double dailyStartBalance = 0;
    datetime lastBarTime = 0;
    bool fridayCloseExecuted = false;
    double avgATR = 0;

    //+------------------------------------------------------------------+
    //| Expert initialization function |
    //+------------------------------------------------------------------+
    int OnInit()
    {
    dailyStartBalance = AccountBalance();
    lastBarTime = 0;
    fridayCloseExecuted = false;
    avgATR = iATR(Symbol(), PERIOD_H1, ATRPeriod, 1);
    if(avgATR <= 0) avgATR = 250
    Point;
    return(INIT_SUCCEEDED);
    }

    //+------------------------------------------------------------------+
    //| Expert deinitialization function |
    //+------------------------------------------------------------------+
    void OnDeinit(const int reason)
    {
    Comment("");
    }

    //+------------------------------------------------------------------+
    //| Check for Inside Bar pattern |
    //+------------------------------------------------------------------+
    bool IsInsideBar(int &direction, double &entryLevel, double &stopLevel)
    {
    double prevHigh = iHigh(Symbol(), PERIOD_H1, 2);
    double prevLow = iLow(Symbol(), PERIOD_H1, 2);
    double currHigh = iHigh(Symbol(), PERIOD_H1, 1);
    double currLow = iLow(Symbol(), PERIOD_H1, 1);
    double close1 = iClose(Symbol(), PERIOD_H1, 1);

    // Inside bar condition: current bar completely inside previous bar
    bool isInside = (currHigh <= prevHigh && currLow >= prevLow);

    if(!isInside) return false;

    double atr = iATR(Symbol(), PERIOD_H1, ATRPeriod, 1);
    double breakoutDist = atr InsideBreakoutATR;

    // Bullish inside bar breakout (price closed near high)
    if(close1 > (prevHigh - breakoutDist
    0.3))
    {
    direction = 1; // buy
    entryLevel = prevHigh + breakoutDist;
    stopLevel = prevLow - breakoutDist 0.5;
    return true;
    }
    // Bearish inside bar breakout (price closed near low)
    else if(close1 < (prevLow + breakoutDist
    0.3))
    {
    direction = -1; // sell
    entryLevel = prevLow - breakoutDist;
    stopLevel = prevHigh + breakoutDist 0.5;
    return true;
    }

    return false;
    }

    //+------------------------------------------------------------------+
    //| Check for Pin Bar pattern |
    //+------------------------------------------------------------------+
    bool IsPinBar(int &direction, double &entryLevel, double &stopLevel)
    {
    double open = iOpen(Symbol(), PERIOD_H1, 1);
    double close = iClose(Symbol(), PERIOD_H1, 1);
    double high = iHigh(Symbol(), PERIOD_H1, 1);
    double low = iLow(Symbol(), PERIOD_H1, 1);

    double body = MathAbs(close - open);
    double upperWick = high - MathMax(open, close);
    double lowerWick = MathMin(open, close) - low;

    if(body <= 0) return false;

    // Bullish pin bar (hammer): long lower wick, small upper wick, close in upper half
    if(lowerWick >= body
    PinBodyRatio && upperWick < body)
    {
    direction = 1; // buy
    entryLevel = close;
    stopLevel = low - (high - low) 0.3;
    return true;
    }
    // Bearish pin bar (shooting star): long upper wick, small lower wick, close in lower half
    else if(upperWick >= body
    PinBodyRatio && lowerWick < body)
    {
    direction = -1; // sell
    entryLevel = close;
    stopLevel = high + (high - low) 0.3;
    return true;
    }

    return false;
    }

    //+------------------------------------------------------------------+
    //| Expert tick function |
    //+------------------------------------------------------------------+
    void OnTick()
    {
    // Daily equity protection
    double currentEquity = AccountEquity();
    double lossPercent = (dailyStartBalance - currentEquity) / dailyStartBalance
    100;
    if(lossPercent >= DailyLossLimit)
    {
    Comment("Daily loss limit reached. No new trades.");
    return;
    }

    // Friday close before weekend
    if(UseFridayClose && !fridayCloseExecuted)
    {
    datetime currentTime = TimeCurrent();
    if(TimeDayOfWeek(currentTime) == 5 && TimeHour(currentTime) >= 20)
    {
    CloseAllOrders();
    fridayCloseExecuted = true;
    return;
    }
    if(TimeDayOfWeek(currentTime) != 5)
    fridayCloseExecuted = false;
    }

    // Spread filter
    if(MarketInfo(Symbol(), MODE_SPREAD) > MaxSpread)
    {
    Comment("Spread too high: ", MarketInfo(Symbol(), MODE_SPREAD));
    return;
    }

    // New bar logic (H1)
    if(Time[0] == lastBarTime)
    return;
    lastBarTime = Time[0];

    // Check existing position
    if(CountPositions() > 0)
    return;

    // Volatility filter
    double atr = iATR(Symbol(), PERIOD_H1, ATRPeriod, 1);
    if(atr <= 0) atr = avgATR;
    avgATR = (avgATR 0.95) + (atr 0.05);

    if(atr > avgATR MaxATRMultiplier)
    {
    Comment("Volatility too high. ATR: ", atr);
    return;
    }

    // Trend filter (optional)
    double ema = iMA(Symbol(), PERIOD_H1, TrendMAPeriod, 0, MODE_EMA, PRICE_CLOSE, 1);
    double close1 = iClose(Symbol(), PERIOD_H1, 1);
    bool trendUp = (close1 > ema);
    bool trendDown = (close1 < ema);

    int direction = 0;
    double entryLevel = 0;
    double stopLevel = 0;
    int patternType = 0; // 1=inside, 2=pin

    // Check patterns
    int insideDir = 0, pinDir = 0;
    double insideEntry = 0, insideStop = 0, pinEntry = 0, pinStop = 0;

    if(IsInsideBar(insideDir, insideEntry, insideStop))
    {
    direction = insideDir;
    entryLevel = insideEntry;
    stopLevel = insideStop;
    patternType = 1;
    }
    else if(IsPinBar(pinDir, pinEntry, pinStop))
    {
    direction = pinDir;
    entryLevel = pinEntry;
    stopLevel = pinStop;
    patternType = 2;
    }

    // Apply trend filter if enabled
    if(UseTrendFilter)
    {
    if(direction == 1 && !trendUp) direction = 0;
    if(direction == -1 && !trendDown) direction = 0;
    }

    if(direction != 0)
    {
    double sl = 0, tp = 0;
    double ask = Ask;
    double bid = Bid;
    double stopDist = 0;

    if(direction == 1) // Buy
    {
    stopDist = MathAbs(entryLevel - stopLevel);
    sl = stopLevel;
    tp = entryLevel + (stopDist
    RiskReward);
    }
    else // Sell
    {
    stopDist = MathAbs(stopLevel - entryLevel);
    sl = stopLevel;
    tp = entryLevel - (stopDist * RiskReward);
    }

    int ticket = OrderSend(Symbol(), (direction==1?OP_BUY:OP_SELL), LotSize, (direction==1?ask:bid), 3, sl, tp, "Gold Candle EA", MagicNumber, 0, clrNONE);
    if(ticket < 0)
    {
    Print("OrderSend failed: ", GetLastError());
    }
    else
    {
    Print("Trade opened. Pattern: ", (patternType==1?"Inside Bar":"Pin Bar"));
    }
    }
    }

    //+------------------------------------------------------------------+
    //| Count open positions with this MagicNumber |
    //+------------------------------------------------------------------+
    int CountPositions()
    {
    int count = 0;
    for(int i = OrdersTotal()-1; i >= 0; i--)
    {
    if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
    {
    if(OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber)
    count++;
    }
    }
    return count;
    }

    //+------------------------------------------------------------------+
    //| Close all orders for this symbol and magic |
    //+------------------------------------------------------------------+
    void CloseAllOrders()
    {
    for(int i = OrdersTotal()-1; i >= 0; i--)
    {
    if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
    {
    if(OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber)
    {
    if(OrderType() == OP_BUY)
    OrderClose(OrderTicket(), OrderLots(), Bid, 3, clrNONE);
    else if(OrderType() == OP_SELL)
    OrderClose(OrderTicket(), OrderLots(), Ask, 3, clrNONE);
    }
    }
    }
    }
    //+------------------------------------------------------------------+
    ``
    Reference: Original MQL4 code for educational purposes.
    Disclaimer: Trading Gold (XAUUSD) carries significant risk due to high volatility. This EA is provided as-is without any guarantee of profit. Test thoroughly on a demo account before live trading. Past performance does not guarantee future results.