Summary: GoldStabilityPro EA is an MQL4 expert advisor for XAUUSD that combines ADX trend filtering with ATR-based dynamic stops. Designed for long-term stable operation on H1 timeframe.
GoldStabilityPro EA is designed specifically for XAUUSD with a focus on long-term stability and capital preservation. Unlike aggressive high-frequency systems, this EA prioritizes trade quality over quantity, executing only when both trend strength and volatility conditions align. The strategy combines ADX for trend filtering and ATR for dynamic position management. Each trade is protected by fixed stop loss and take profit levels based on current market volatility, ensuring risk remains contained. The EA includes daily equity protection, spread control, and Friday close mechanisms.
Recommended Timeframe: H1
Trading Logic:
1. Trend Strength Filter: ADX(14) must be above the ADX_Min threshold (default 25) to ensure a trending market.
2. Directional Filter: DI+ (bullish) or DI- (bearish) determines trade direction based on which is dominant.
3. Volatility Assessment: ATR(14) is calculated and used for dynamic stop loss placement.
4. Entry Confirmation: Price must close beyond the H1 EMA(50) in the direction of the dominant DI.
5. Risk Management: Fixed stop loss (default 300 points) and take profit (default 600 points) with optional ATR-scaling.
```mql4
//+------------------------------------------------------------------+
//| GoldStabilityProEA.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 ADXPeriod = 14; // ADX period for trend strength
input int ADXMinThreshold = 25; // Minimum ADX value (trend required)
input int EMAPeriod = 50; // EMA period for trend direction filter
input int ATRPeriod = 14; // ATR period for volatility reference
input int StopLossPoints = 300; // Stop loss in points (300 points)
input int TakeProfitPoints = 600; // Take profit in points (2:1 ratio)
input bool UseATRScaling = false; // Scale SL/TP based on ATR volatility
input double ATRMultiplier = 1.5; // ATR multiplier for SL when scaling enabled
input int MagicNumber = 202420; // 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;
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
dailyStartBalance = AccountBalance();
lastBarTime = 0;
fridayCloseExecuted = false;
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
Comment("");
}
//+------------------------------------------------------------------+
//| Get ADX trend direction and strength |
//+------------------------------------------------------------------+
int GetADXDirection(double &adxValue, double &diPlus, double &diMinus)
{
adxValue = iADX(Symbol(), PERIOD_H1, ADXPeriod, PRICE_CLOSE, MODE_MAIN, 1);
diPlus = iADX(Symbol(), PERIOD_H1, ADXPeriod, PRICE_CLOSE, MODE_PLUSDI, 1);
diMinus = iADX(Symbol(), PERIOD_H1, ADXPeriod, PRICE_CLOSE, MODE_MINUSDI, 1);
if(adxValue < ADXMinThreshold) return 0; // No trend
if(diPlus > diMinus) return 1; // Bullish trend
if(diMinus > diPlus) return -1; // Bearish trend
return 0;
}
//+------------------------------------------------------------------+
//| Calculate ATR-based dynamic stop loss |
//+------------------------------------------------------------------+
void CalculateDynamicSLTP(int direction, double entryPrice, double &sl, double &tp, double atr)
{
if(UseATRScaling && atr > 0)
{
double dynamicSL = atr * ATRMultiplier / Point;
double dynamicTP = dynamicSL * 2;
if(direction == 1) // Buy
{
sl = entryPrice - dynamicSL * Point;
tp = entryPrice + dynamicTP * Point;
}
else // Sell
{
sl = entryPrice + dynamicSL * Point;
tp = entryPrice - dynamicTP * Point;
}
}
else
{
if(direction == 1) // Buy
{
sl = entryPrice - StopLossPoints * Point;
tp = entryPrice + TakeProfitPoints * Point;
}
else // Sell
{
sl = entryPrice + StopLossPoints * Point;
tp = entryPrice - TakeProfitPoints * Point;
}
}
}
//+------------------------------------------------------------------+
//| Check EMA alignment confirmation |
//+------------------------------------------------------------------+
bool CheckEMAAlignment(int direction)
{
double close1 = iClose(Symbol(), PERIOD_H1, 1);
double ema = iMA(Symbol(), PERIOD_H1, EMAPeriod, 0, MODE_EMA, PRICE_CLOSE, 1);
if(direction == 1) return (close1 > ema);
if(direction == -1) return (close1 < ema);
return false;
}
//+------------------------------------------------------------------+
//| Manage trailing stop for open position |
//+------------------------------------------------------------------+
void ManageTrailingStop()
{
for(int i = OrdersTotal()-1; i >= 0; i--)
{
if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
{
if(OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber)
{
double atr = iATR(Symbol(), PERIOD_H1, ATRPeriod, 1);
double trailStep = (UseATRScaling && atr > 0) ? (atr * 0.5) : (100 * Point);
double newSL = 0;
if(OrderType() == OP_BUY)
{
double profit = Bid - OrderOpenPrice();
if(profit >= 150 * Point) // Minimum profit to start trailing
{
newSL = Bid - trailStep;
if(newSL > OrderStopLoss())
OrderModify(OrderTicket(), OrderOpenPrice(), newSL, OrderTakeProfit(), 0, clrNONE);
}
}
else if(OrderType() == OP_SELL)
{
double profit = OrderOpenPrice() - Ask;
if(profit >= 150 * Point)
{
newSL = Ask + trailStep;
if(newSL < OrderStopLoss() || OrderStopLoss() == 0)
OrderModify(OrderTicket(), OrderOpenPrice(), newSL, OrderTakeProfit(), 0, clrNONE);
}
}
break;
}
}
}
}
//+------------------------------------------------------------------+
//| 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];
// Manage existing position
if(CountPositions() > 0)
{
ManageTrailingStop();
return;
}
// Get ADX direction and strength
double adxValue = 0, diPlus = 0, diMinus = 0;
int direction = GetADXDirection(adxValue, diPlus, diMinus);
if(direction == 0)
{
Comment("No strong trend detected. ADX: ", adxValue);
return;
}
// Check EMA alignment
if(!CheckEMAAlignment(direction))
{
Comment("EMA alignment failed");
return;
}
// Get ATR for dynamic calculations
double atr = iATR(Symbol(), PERIOD_H1, ATRPeriod, 1);
// Determine entry price and calculate SL/TP
double entryPrice = (direction == 1) ? Ask : Bid;
double sl = 0, tp = 0;
CalculateDynamicSLTP(direction, entryPrice, sl, tp, atr);
int cmd = (direction == 1) ? OP_BUY : OP_SELL;
int ticket = OrderSend(Symbol(), cmd, LotSize, entryPrice, 5, sl, tp, "GoldStabilityPro", MagicNumber, 0, clrNONE);
if(ticket < 0)
{
Print("OrderSend failed: ", GetLastError());
}
else
{
Print("Order opened. Direction: ", cmd==OP_BUY?"BUY":"SELL",
" | ADX: ", adxValue, " | DI+: ", diPlus, " | DI-: ", diMinus);
}
}
//+------------------------------------------------------------------+
//| 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);
}
}
}
}
//+------------------------------------------------------------------+
```
Reference: Original MQL4 code based on ADX+ATR trend following methodology.
Disclaimer: Gold trading involves 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 deployment. Past performance does not guarantee future results.