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:
  • Trend Strength Filter: ADX(14) must be above the ADX_Min threshold (default 25) to ensure a trending market.

  • Directional Filter: DI+ (bullish) or DI- (bearish) determines trade direction based on which is dominant.

  • Volatility Assessment: ATR(14) is calculated and used for dynamic stop loss placement.

  • Entry Confirmation: Price must close beyond the H1 EMA(50) in the direction of the dominant DI.

  • 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.