Summary: Gold Apex Trend EA is an MQL4 expert advisor for XAUUSD that uses H4 trend structure confirmation, ATR volatility filtering, and basket profit targeting. Suitable for H1 timeframe stable operation.




Gold Apex Trend EA is engineered specifically for stable gold trading with a focus on structural trend analysis. Unlike aggressive grid systems that ignore market direction, this EA uses multi-timeframe trend confirmation to ensure trades align with the dominant market structure. The EA identifies key swing points on H4, confirms trend strength with ADX, and enters on H1 pullbacks. Each position is protected by ATR-based stops, and a basket profit mechanism locks in gains. Daily loss limits and spread controls provide additional safety layers.

Recommended Timeframe: H1 (for execution) with H4 for trend reference
Trading Logic:
  • Trend Structure: Identify swing highs/lows on H4 over the last 40 candles to determine trend direction.

  • Trend Strength: ADX(14) > 25 to avoid low-volatility chop.

  • Entry Signal: Price pulls back to H1 EMA(20) in the direction of H4 structure, with confirming candlestick pattern.

  • Risk Management: ATR-based stop loss (1.8x ATR), take profit at 3x ATR. Maximum 2 concurrent positions, daily loss limit 5%.


  • ``mql4
    //+------------------------------------------------------------------+
    //| GoldApexTrendEA.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 for XAUUSD)
    input int H4StructurePeriod = 40; // H4 lookback for swing structure detection
    input int H1EntryMAPeriod = 20; // H1 EMA period for pullback entries
    input int ADXPeriod = 14; // ADX period for trend strength filter
    input int ADXThreshold = 25; // Minimum ADX value to allow entries
    input int ATRPeriod = 14; // ATR period for dynamic stops
    input double ATRStopMultiplier = 1.8; // Stop loss as multiple of ATR
    input double ATRTakeMultiplier = 3.0; // Take profit as multiple of ATR
    input int MaxPositions = 2; // Maximum concurrent positions allowed
    input double BasketProfitPoints = 200; // Combined profit target in points
    input int MagicNumber = 202421; // Unique EA identifier
    input int MaxSpread = 35; // Maximum allowed spread in points
    input double DailyLossLimit = 5.0; // Daily loss limit as percentage
    input bool UseFridayClose = true; // Close trades before Friday 21:00 GMT

    //--- global variables
    double dailyStartBalance = 0;
    datetime lastBarTime = 0;
    bool fridayCloseExecuted = false;
    double avgATR = 0;
    int h4TrendDirection = 0; // 1 = bullish, -1 = bearish
    datetime trendConfirmedTime = 0;

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

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

    //+------------------------------------------------------------------+
    //| Detect H4 trend structure using swing points |
    //+------------------------------------------------------------------+
    int DetectH4TrendStructure()
    {
    // Find recent swing high and swing low on H4
    int swingHighIdx = iHighest(Symbol(), PERIOD_H4, MODE_HIGH, H4StructurePeriod, 1);
    int swingLowIdx = iLowest(Symbol(), PERIOD_H4, MODE_LOW, H4StructurePeriod, 1);

    if(swingHighIdx < 0 || swingLowIdx < 0) return 0;

    double swingHigh = iHigh(Symbol(), PERIOD_H4, swingHighIdx);
    double swingLow = iLow(Symbol(), PERIOD_H4, swingLowIdx);
    double currentClose = iClose(Symbol(), PERIOD_H4, 1);
    double currentHigh = iHigh(Symbol(), PERIOD_H4, 1);
    double currentLow = iLow(Symbol(), PERIOD_H4, 1);

    // Determine trend based on higher highs and higher lows pattern
    bool bullishStructure = (currentHigh > swingHigh && currentLow > swingLow);
    bool bearishStructure = (currentLow < swingLow && currentHigh < swingHigh);

    // Additional confirmation using 200 EMA on H4
    double ema200H4 = iMA(Symbol(), PERIOD_H4, 200, 0, MODE_EMA, PRICE_CLOSE, 1);

    if(bullishStructure && currentClose > ema200H4) return 1;
    if(bearishStructure && currentClose < ema200H4) return -1;

    return 0;
    }

    //+------------------------------------------------------------------+
    //| Check ADX trend strength |
    //+------------------------------------------------------------------+
    bool IsTrendStrong()
    {
    double adx = iADX(Symbol(), PERIOD_H4, ADXPeriod, PRICE_CLOSE, MODE_MAIN, 1);
    return (adx >= ADXThreshold);
    }

    //+------------------------------------------------------------------+
    //| Check pullback entry on H1 |
    //+------------------------------------------------------------------+
    bool CheckPullbackEntry(int trendDir, double &entryPrice, double &sl, double &tp, double atr)
    {
    if(trendDir == 0) return false;

    double ema20H1 = iMA(Symbol(), PERIOD_H1, H1EntryMAPeriod, 0, MODE_EMA, PRICE_CLOSE, 1);
    double close1 = iClose(Symbol(), PERIOD_H1, 1);
    double open1 = iOpen(Symbol(), PERIOD_H1, 1);
    double low1 = iLow(Symbol(), PERIOD_H1, 1);
    double high1 = iHigh(Symbol(), PERIOD_H1, 1);

    if(trendDir == 1) // Bullish - look for pullback to EMA20
    {
    bool pulledToEMA = (low1 <= ema20H1 && close1 > ema20H1);
    bool bullishCandle = (close1 > open1);
    bool confirmMomentum = (close1 > iClose(Symbol(), PERIOD_H1, 2));

    if(pulledToEMA && bullishCandle && confirmMomentum)
    {
    entryPrice = Ask;
    sl = entryPrice - (atr
    ATRStopMultiplier);
    tp = entryPrice + (atr ATRTakeMultiplier);
    return true;
    }
    }
    else if(trendDir == -1) // Bearish - look for pullback to EMA20
    {
    bool pulledToEMA = (high1 >= ema20H1 && close1 < ema20H1);
    bool bearishCandle = (close1 < open1);
    bool confirmMomentum = (close1 < iClose(Symbol(), PERIOD_H1, 2));

    if(pulledToEMA && bearishCandle && confirmMomentum)
    {
    entryPrice = Bid;
    sl = entryPrice + (atr
    ATRStopMultiplier);
    tp = entryPrice - (atr ATRTakeMultiplier);
    return true;
    }
    }
    return false;
    }

    //+------------------------------------------------------------------+
    //| Calculate basket floating profit in points |
    //+------------------------------------------------------------------+
    double CalculateBasketProfitPoints()
    {
    double totalProfit = 0;
    for(int i = OrdersTotal()-1; i >= 0; i--)
    {
    if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
    {
    if(OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber)
    {
    totalProfit += OrderProfit();
    }
    }
    }
    // Convert profit to points approximation
    double pointValue = LotSize
    100; // Approximate for gold, 0.01 lot = $1 per point
    if(pointValue > 0)
    return totalProfit / pointValue;
    return 0;
    }

    //+------------------------------------------------------------------+
    //| Check and execute basket take profit |
    //+------------------------------------------------------------------+
    bool CheckBasketTakeProfit()
    {
    double profitPoints = CalculateBasketProfitPoints();
    if(profitPoints >= BasketProfitPoints)
    {
    CloseAllOrders();
    Print("Basket take profit triggered at ", profitPoints, " points");
    return true;
    }
    return false;
    }

    //+------------------------------------------------------------------+
    //| Manage existing positions - trail stop and basket TP |
    //+------------------------------------------------------------------+
    void ManagePositions(double atr)
    {
    CheckBasketTakeProfit();

    // Trail stop for individual positions
    for(int i = OrdersTotal()-1; i >= 0; i--)
    {
    if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
    {
    if(OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber)
    {
    double trailStep = atr 0.8;
    double newSL = 0;

    if(OrderType() == OP_BUY)
    {
    double profit = Bid - OrderOpenPrice();
    if(profit > atr
    1.2) // Trail after 1.2x ATR profit
    {
    newSL = Bid - trailStep;
    if(newSL > OrderStopLoss())
    OrderModify(OrderTicket(), OrderOpenPrice(), newSL, OrderTakeProfit(), 0, clrNONE);
    }
    }
    else if(OrderType() == OP_SELL)
    {
    double profit = OrderOpenPrice() - Ask;
    if(profit > atr 1.2)
    {
    newSL = Ask + trailStep;
    if(newSL < OrderStopLoss() || OrderStopLoss() == 0)
    OrderModify(OrderTicket(), OrderOpenPrice(), newSL, OrderTakeProfit(), 0, clrNONE);
    }
    }
    }
    }
    }
    }

    //+------------------------------------------------------------------+
    //| 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, 5, clrNONE);
    else if(OrderType() == OP_SELL)
    OrderClose(OrderTicket(), OrderLots(), Ask, 5, clrNONE);
    }
    }
    }
    }

    //+------------------------------------------------------------------+
    //| 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) >= 21)
    {
    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];

    // Get ATR for calculations
    double atr = iATR(Symbol(), PERIOD_H1, ATRPeriod, 1);
    if(atr > 0) avgATR = (avgATR 0.95) + (atr 0.05);

    // Volatility guard - skip if ATR too high
    if(atr > avgATR * 1.6 && avgATR > 0)
    {
    Comment("Volatility too high. ATR: ", atr);
    return;
    }

    // Manage existing positions
    int posCount = CountPositions();
    if(posCount > 0)
    {
    ManagePositions(atr);
    return;
    }

    // Check max positions limit
    if(posCount >= MaxPositions)
    return;

    // Detect H4 trend structure (update every 4 hours)
    static datetime lastTrendCheck = 0;
    if(TimeCurrent() - lastTrendCheck >= 14400)
    {
    h4TrendDirection = DetectH4TrendStructure();
    lastTrendCheck = TimeCurrent();
    }

    // No clear trend, skip trading
    if(h4TrendDirection == 0)
    {
    Comment("No clear H4 trend structure");
    return;
    }

    // Check ADX trend strength
    if(!IsTrendStrong())
    {
    Comment("ADX below threshold, no strong trend");
    return;
    }

    // Check pullback entry
    double entryPrice = 0, sl = 0, tp = 0;
    if(CheckPullbackEntry(h4TrendDirection, entryPrice, sl, tp, atr))
    {
    int cmd = (h4TrendDirection == 1) ? OP_BUY : OP_SELL;
    int ticket = OrderSend(Symbol(), cmd, LotSize, entryPrice, 5, sl, tp, "Gold Apex", MagicNumber, 0, clrNONE);
    if(ticket < 0)
    Print("OrderSend failed: ", GetLastError());
    else
    Print("Entry opened. Direction: ", cmd==OP_BUY?"BUY":"SELL");
    }
    }
    //+------------------------------------------------------------------+
    ``
    Reference: Original MQL4 code designed based on structural trend analysis principles for XAUUSD gold trading.
    Disclaimer: Gold trading involves significant risk due to high volatility and leverage. This EA is provided as-is without any guarantee of profit. Test thoroughly on a demo account before live deployment. Past performance does not guarantee future results.