Summary: Gold CandleFlow EA is an MQL4 expert advisor for gold that relies purely on candlestick patterns: pin bars, inside bars, and wick rejections. No traditional indicators. Suitable for H1.




Gold CandleFlow EA is built exclusively for gold (XAUUSD) using pure price action and candlestick pattern recognition. It avoids lagging indicators and instead focuses on real-time candlestick structures: pin bars (long wicks), inside bars (compression), and wick rejections at key levels. The EA tracks dynamic support/resistance based on recent swing highs/lows and enters when candlestick rejection occurs. A unique volatility adjustment mechanism widens stop loss during high-impact news periods.

Recommended Timeframe: H1
Trading Logic:
  • Structure Identification: Identify recent swing highs and lows (lookback 20 candles) as dynamic support/resistance.

  • Candlestick Rejection: Look for pin bar with wick > 2x body, closing near the opposite end (rejection at support/resistance).

  • Inside Bar Breakout: When an inside bar (range within previous candle) breaks out with strong close beyond parent range.

  • Risk Management: ATR-based dynamic stop loss (1.8x ATR) and take profit (3.5x ATR). Maximum 1 trade, daily loss limit 5%.


  • ``mql4
    //+------------------------------------------------------------------+
    //| GoldCandleFlowEA.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 int SwingLookback = 20; // Lookback period for swing high/low detection
    input double PinBarRatio = 2.0; // Pin bar wick-to-body ratio minimum (wick > body ratio)
    input double InsideBreakoutMultiplier = 1.2; // Inside bar breakout threshold (close beyond parent range by this %)
    input int ATRPeriod = 14; // ATR period for dynamic stop loss
    input double ATRStopMultiplier = 1.8; // Stop loss as multiple of ATR
    input double ATRTakeMultiplier = 3.5; // Take profit as multiple of ATR
    input int MagicNumber = 202418; // Unique EA identifier
    input int MaxSpread = 35; // Maximum allowed spread in points (gold)
    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 lastSwingHigh = 0;
    double lastSwingLow = 0;

    //+------------------------------------------------------------------+
    //| Expert initialization function |
    //+------------------------------------------------------------------+
    int OnInit()
    {
    dailyStartBalance = AccountBalance();
    lastBarTime = 0;
    fridayCloseExecuted = false;
    return(INIT_SUCCEEDED);
    }

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

    //+------------------------------------------------------------------+
    //| Detect recent swing high (highest high in lookback) |
    //+------------------------------------------------------------------+
    double GetSwingHigh()
    {
    int highestIdx = iHighest(Symbol(), PERIOD_H1, MODE_HIGH, SwingLookback, 2);
    return iHigh(Symbol(), PERIOD_H1, highestIdx);
    }

    //+------------------------------------------------------------------+
    //| Detect recent swing low (lowest low in lookback) |
    //+------------------------------------------------------------------+
    double GetSwingLow()
    {
    int lowestIdx = iLowest(Symbol(), PERIOD_H1, MODE_LOW, SwingLookback, 2);
    return iLow(Symbol(), PERIOD_H1, lowestIdx);
    }

    //+------------------------------------------------------------------+
    //| Check for pin bar pattern (rejection candle) |
    //+------------------------------------------------------------------+
    bool IsPinBar(int shift, bool &isBullishPin)
    {
    double open = iOpen(Symbol(), PERIOD_H1, shift);
    double close = iClose(Symbol(), PERIOD_H1, shift);
    double high = iHigh(Symbol(), PERIOD_H1, shift);
    double low = iLow(Symbol(), PERIOD_H1, shift);

    double body = MathAbs(close - open);
    if(body <= 0) return false;

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

    // Bullish pin bar: long lower wick, small upper wick, close near high
    bool bullish = (lowerWick > body
    PinBarRatio) && (upperWick < body 0.5) && (close > open);
    // Bearish pin bar: long upper wick, small lower wick, close near low
    bool bearish = (upperWick > body
    PinBarRatio) && (lowerWick < body 0.5) && (close < open);

    if(bullish)
    isBullishPin = true;
    else if(bearish)
    isBullishPin = false;

    return (bullish || bearish);
    }

    //+------------------------------------------------------------------+
    //| Check for inside bar pattern (range within previous candle) |
    //+------------------------------------------------------------------+
    bool IsInsideBar(int shift, double &parentHigh, double &parentLow)
    {
    double currHigh = iHigh(Symbol(), PERIOD_H1, shift);
    double currLow = iLow(Symbol(), PERIOD_H1, shift);
    double prevHigh = iHigh(Symbol(), PERIOD_H1, shift + 1);
    double prevLow = iLow(Symbol(), PERIOD_H1, shift + 1);

    bool isInside = (currHigh <= prevHigh && currLow >= prevLow);
    if(isInside)
    {
    parentHigh = prevHigh;
    parentLow = prevLow;
    }
    return isInside;
    }

    //+------------------------------------------------------------------+
    //| Check inside bar breakout on close |
    //+------------------------------------------------------------------+
    bool CheckInsideBreakout(int &cmd, double parentHigh, double parentLow)
    {
    double close1 = iClose(Symbol(), PERIOD_H1, 1);
    double open1 = iOpen(Symbol(), PERIOD_H1, 1);
    double range = parentHigh - parentLow;
    double threshold = range
    InsideBreakoutMultiplier;

    // Bullish breakout: close above parent high + threshold, bullish candle
    if(close1 > parentHigh + threshold && close1 > open1)
    {
    cmd = OP_BUY;
    return true;
    }
    // Bearish breakout: close below parent low - threshold, bearish candle
    else if(close1 < parentLow - threshold && close1 < open1)
    {
    cmd = OP_SELL;
    return true;
    }
    return false;
    }

    //+------------------------------------------------------------------+
    //| Check rejection at swing level (price touches level + pin bar) |
    //+------------------------------------------------------------------+
    bool CheckRejectionAtLevel(double level, double price, bool isResistance, int &cmd)
    {
    double tolerance = 150 Point; // 150 points tolerance for gold
    double close1 = iClose(Symbol(), PERIOD_H1, 1);
    double open1 = iOpen(Symbol(), PERIOD_H1, 1);
    bool isPin = false;
    bool isBullishPin = false;

    if(IsPinBar(1, isBullishPin))
    {
    isPin = true;
    }

    if(!isPin) return false;

    // Resistance rejection (price touched resistance from below, then bearish pin bar)
    if(isResistance && MathAbs(high - level) <= tolerance && !isBullishPin)
    {
    cmd = OP_SELL;
    return true;
    }
    // Support rejection (price touched support from above, then bullish pin bar)
    else if(!isResistance && MathAbs(low - level) <= tolerance && isBullishPin)
    {
    cmd = OP_BUY;
    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 for gold
    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;

    // Update dynamic swing levels
    lastSwingHigh = GetSwingHigh();
    lastSwingLow = GetSwingLow();

    double atr = iATR(Symbol(), PERIOD_H1, ATRPeriod, 1);
    if(atr <= 0) atr = 200 Point;

    int cmd = -1;
    double sl = 0, tp = 0;
    double ask = Ask;
    double bid = Bid;
    double close1 = iClose(Symbol(), PERIOD_H1, 1);
    double high = iHigh(Symbol(), PERIOD_H1, 1);
    double low = iLow(Symbol(), PERIOD_H1, 1);

    // Strategy 1: Inside bar breakout
    double parentHigh = 0, parentLow = 0;
    if(IsInsideBar(2, parentHigh, parentLow))
    {
    if(CheckInsideBreakout(cmd, parentHigh, parentLow))
    {
    sl = (cmd == OP_BUY) ? (bid - atr
    ATRStopMultiplier) : (ask + atr ATRStopMultiplier);
    tp = (cmd == OP_BUY) ? (bid + atr
    ATRTakeMultiplier) : (ask - atr ATRTakeMultiplier);
    }
    }

    // Strategy 2: Pin bar rejection at swing level (only if no inside bar signal)
    if(cmd == -1)
    {
    // Rejection at resistance (swing high)
    if(CheckRejectionAtLevel(lastSwingHigh, high, true, cmd))
    {
    sl = ask + atr
    ATRStopMultiplier;
    tp = ask - atr ATRTakeMultiplier;
    }
    // Rejection at support (swing low)
    else if(CheckRejectionAtLevel(lastSwingLow, low, false, cmd))
    {
    sl = bid - atr
    ATRStopMultiplier;
    tp = bid + atr * ATRTakeMultiplier;
    }
    }

    // Execute trade
    if(cmd != -1)
    {
    int ticket = OrderSend(Symbol(), cmd, LotSize, (cmd==OP_BUY?ask:bid), 3, sl, tp, "Gold CandleFlow", MagicNumber, 0, clrNONE);
    if(ticket < 0)
    Print("OrderSend failed: ", GetLastError());
    }
    }

    //+------------------------------------------------------------------+
    //| 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: Gold trading involves high volatility and significant risk. 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.