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:
1. Trend Filter: 50-period EMA determines direction (price above = long only, below = short only).
2. Momentum Confirmation: RSI(14) must be above 55 for long entries or below 45 for short entries to avoid low-momentum zones.
3. Volatility Guard: ATR(14) must be below 1.8x its 20-period average to skip extreme volatility.
4. Entry: After both conditions align, enter on the next bar open with fixed SL/TP.
5. 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.