Summary: Gold Horizon EA is an MQL4 expert advisor for XAUUSD that combines EMA trend detection, RSI momentum confirmation, and ATR volatility filtering. Suitable for H1 timeframe with daily risk controls.




Gold Horizon EA is a stable, low-risk automated trading system designed specifically for Gold (XAUUSD). Unlike aggressive grid or martingale systems that can blow accounts during sustained trends, this EA follows a disciplined trend-confirmation approach . It combines three core filters: EMA trend direction, RSI momentum, and ATR volatility guard to ensure entries only occur in favorable market conditions. Every trade has a fixed stop loss and a 2:1 risk-reward take profit. The EA also includes a daily loss limit, spread control, and Friday close protection to avoid weekend gaps.

Recommended Timeframe: H1

Trading Logic:
  • Trend Filter: 50-period EMA determines direction (price above = long only, below = short only).

  • Momentum Confirmation: RSI(14) must be above 55 for long entries or below 45 for short entries to avoid low-momentum zones.

  • Volatility Guard: ATR(14) must be below 1.8x its 20-period average to skip extreme volatility.

  • Entry: After both conditions align, enter on the next bar open with fixed SL/TP.

  • Risk Management: Fixed stop loss (350 points), take profit (700 points). Daily loss limit 5%, max spread 35 points.


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

    //+------------------------------------------------------------------+
    //| Input Parameters with Comments |
    //+------------------------------------------------------------------+

    input double InpLotSize = 0.01; // Fixed lot size (0.01 for gold)
    input int InpStopLossPoints = 350; // Stop loss in points (350 points = 3500 pips on 5-digit broker)
    input int InpTakeProfitPoints = 700; // Take profit in points (2:1 risk-reward ratio)
    input int InpTrendMAPeriod = 50; // EMA period for trend direction filter
    input int InpRSIPeriod = 14; // RSI period for momentum confirmation
    input double InpRSIThresholdLong = 55.0; // RSI must be above this for long entries
    input double InpRSIThresholdShort = 45.0; // RSI must be below this for short entries
    input int InpATRPeriod = 14; // ATR period for volatility filtering
    input double InpATRMaxMultiplier = 1.8; // Max ATR multiplier (skip if ATR > avgATR this)
    input int InpMagicNumber = 202418; // Unique EA identifier
    input int InpMaxSpread = 35; // Maximum allowed spread in points
    input double InpDailyLossLimit = 5.0; // Daily loss limit as percentage of balance
    input bool InpUseFridayClose = true; // Close all trades before Friday 21:00 GMT

    //+------------------------------------------------------------------+
    //| Global Variables |
    //+------------------------------------------------------------------+

    double g_dailyStartBalance = 0;
    datetime g_lastBarTime = 0;
    bool g_fridayCloseDone = false;
    double g_avgATR = 0;

    //+------------------------------------------------------------------+
    //| Expert Initialization Function |
    //+------------------------------------------------------------------+
    int OnInit()
    {
    g_dailyStartBalance = AccountBalance();
    g_lastBarTime = 0;
    g_fridayCloseDone = false;
    g_avgATR = iATR(_Symbol, PERIOD_H1, InpATRPeriod, 1);
    if(g_avgATR <= 0) g_avgATR = 250
    Point;
    return(INIT_SUCCEEDED);
    }

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

    //+------------------------------------------------------------------+
    //| Daily Loss Protection Check |
    //+------------------------------------------------------------------+
    bool IsDailyLossExceeded()
    {
    double equity = AccountEquity();
    double lossPercent = (g_dailyStartBalance - equity) / g_dailyStartBalance 100;
    return (lossPercent >= InpDailyLossLimit);
    }

    //+------------------------------------------------------------------+
    //| Friday Close Handler |
    //+------------------------------------------------------------------+
    void HandleFridayClose()
    {
    if(!InpUseFridayClose) return;
    if(g_fridayCloseDone) return;

    datetime now = TimeCurrent();
    if(TimeDayOfWeek(now) == 5 && TimeHour(now) >= 21)
    {
    CloseAllOrders();
    g_fridayCloseDone = true;
    }
    else if(TimeDayOfWeek(now) != 5)
    {
    g_fridayCloseDone = false;
    }
    }

    //+------------------------------------------------------------------+
    //| Spread Validation |
    //+------------------------------------------------------------------+
    bool IsSpreadValid()
    {
    int currentSpread = (int)MarketInfo(_Symbol, MODE_SPREAD);
    if(currentSpread > InpMaxSpread)
    {
    Comment("Spread too high: ", currentSpread);
    return false;
    }
    return true;
    }

    //+------------------------------------------------------------------+
    //| Count Open Positions with Magic Number |
    //+------------------------------------------------------------------+
    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() == InpMagicNumber)
    count++;
    }
    }
    return count;
    }

    //+------------------------------------------------------------------+
    //| Close All Orders |
    //+------------------------------------------------------------------+
    void CloseAllOrders()
    {
    for(int i = OrdersTotal() - 1; i >= 0; i--)
    {
    if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
    {
    if(OrderSymbol() == _Symbol && OrderMagicNumber() == InpMagicNumber)
    {
    if(OrderType() == OP_BUY)
    OrderClose(OrderTicket(), OrderLots(), Bid, 3, clrNONE);
    else if(OrderType() == OP_SELL)
    OrderClose(OrderTicket(), OrderLots(), Ask, 3, clrNONE);
    }
    }
    }
    }

    //+------------------------------------------------------------------+
    //| Main Tick Function |
    //+------------------------------------------------------------------+
    void OnTick()
    {
    // Daily loss protection
    if(IsDailyLossExceeded())
    {
    Comment("Daily loss limit reached. No new trades.");
    return;
    }

    // Friday close handler
    HandleFridayClose();

    // Spread validation
    if(!IsSpreadValid())
    return;

    // New bar detection (H1)
    if(Time[0] == g_lastBarTime)
    return;
    g_lastBarTime = Time[0];

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

    // Calculate indicators on closed bar (shift=1)
    double ema = iMA(_Symbol, PERIOD_H1, InpTrendMAPeriod, 0, MODE_EMA, PRICE_CLOSE, 1);
    double close1 = iClose(_Symbol, PERIOD_H1, 1);
    double rsi = iRSI(_Symbol, PERIOD_H1, InpRSIPeriod, PRICE_CLOSE, 1);
    double atr = iATR(_Symbol, PERIOD_H1, InpATRPeriod, 1);
    double prevATR = iATR(_Symbol, PERIOD_H1, InpATRPeriod, 2);

    // Update average ATR (rolling)
    if(atr > 0)
    g_avgATR = (g_avgATR
    0.95) + (atr 0.05);

    // Volatility filter
    if(atr > g_avgATR
    InpATRMaxMultiplier)
    {
    Comment("Volatility too high. ATR: ", atr);
    return;
    }

    int cmd = -1;
    double sl = 0;
    double tp = 0;
    double ask = Ask;
    double bid = Bid;

    // Long condition: price above EMA, RSI above threshold
    if(close1 > ema && rsi > InpRSIThresholdLong)
    {
    cmd = OP_BUY;
    sl = bid - InpStopLossPoints Point;
    tp = bid + InpTakeProfitPoints
    Point;
    }
    // Short condition: price below EMA, RSI below threshold
    else if(close1 < ema && rsi < InpRSIThresholdShort)
    {
    cmd = OP_SELL;
    sl = ask + InpStopLossPoints Point;
    tp = ask - InpTakeProfitPoints
    Point;
    }

    // Execute trade
    if(cmd != -1)
    {
    double price = (cmd == OP_BUY) ? ask : bid;
    int ticket = OrderSend(_Symbol, cmd, InpLotSize, price, 3, sl, tp, "Gold Horizon", InpMagicNumber, 0, clrNONE);
    if(ticket < 0)
    Print("OrderSend failed. Error: ", GetLastError());
    }
    }

    //+------------------------------------------------------------------+
    ``
    Reference: Original MQL4 code inspired by institutional gold trading strategies .

    Disclaimer: Forex and Gold trading involves significant risk of loss. This EA is provided for educational purposes only, without any guarantee of profitability. Always test thoroughly on a demo account before live deployment. Past performance does not guarantee future results.