Summary: Golden Phoenix EA is an MQL4 expert advisor for gold (XAUUSD) using adaptive trend following with dual EMA crossover, ATR volatility filter, and daily loss limit. Suitable for H1 timeframe.




Golden Phoenix EA is a robust MQL4 expert advisor designed specifically for gold (XAUUSD) trading. It employs an adaptive trend-following strategy using dual exponential moving averages (EMA) crossover with dynamic confirmation. The EA incorporates ATR-based volatility filtering to avoid whipsaws during low volatility ranging markets. A built-in daily equity protection mechanism and maximum spread control ensure stable operation. Each trade is protected by a trailing stop that locks in profits as the trend extends.

Recommended Timeframe: H1
Trading Logic:
  • Trend Detection: Fast EMA (12) crosses above Slow EMA (26) for uptrend; opposite for downtrend.

  • Entry Confirmation: Price must close beyond the crossover point and ATR(14) > 150 points (minimum volatility).

  • Volatility Filter: ATR value must be below 3x average ATR to avoid extreme volatility spikes.

  • Risk Management: Fixed stop loss (350 points), take profit (700 points), trailing stop activates after 400 points profit.

  • Position Management: Maximum 1 open position, daily loss limit 5% of balance, maximum spread 35 points.


  • ``mql4
    //+------------------------------------------------------------------+
    //| GoldenPhoenixEA.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 FastEMAPeriod = 12; // Fast EMA period for trend detection
    input int SlowEMAPeriod = 26; // Slow EMA period for trend detection
    input int ATRPeriod = 14; // ATR period for volatility filtering
    input int StopLossPoints = 350; // Stop loss in points (350 points for gold)
    input int TakeProfitPoints = 700; // Take profit in points (2:1 risk-reward)
    input int TrailingStart = 400; // Trailing stop activation threshold (points)
    input int TrailingStep = 150; // Trailing stop step (points)
    input int MinVolatility = 150; // Minimum ATR value required to trade (points)
    input double MaxVolatilityMult = 3.0; // Maximum ATR multiplier relative to average
    input int MagicNumber = 202415; // Unique EA identifier
    input int MaxSpread = 35; // Maximum allowed spread (points)
    input double DailyLossLimit = 5.0; // Daily loss limit as percentage of balance
    input bool UseCloseOnFriday = true; // Close all trades before Friday 21:00

    //--- global variables
    double dailyStartBalance = 0;
    datetime lastBarTime = 0;
    bool isFridayCloseExecuted = false;
    double avgATR = 0;

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

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

    //+------------------------------------------------------------------+
    //| 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(UseCloseOnFriday && !isFridayCloseExecuted)
    {
    datetime currentTime = TimeCurrent();
    if(TimeDayOfWeek(currentTime) == 5 && TimeHour(currentTime) >= 21)
    {
    CloseAllOrders();
    isFridayCloseExecuted = true;
    return;
    }
    if(TimeDayOfWeek(currentTime) != 5)
    isFridayCloseExecuted = 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];

    // Check for existing position
    if(CountPositions() > 0)
    {
    ManageTrailingStop();
    return;
    }

    // Get indicator values
    double fastEMA = iMA(Symbol(), PERIOD_H1, FastEMAPeriod, 0, MODE_EMA, PRICE_CLOSE, 1);
    double slowEMA = iMA(Symbol(), PERIOD_H1, SlowEMAPeriod, 0, MODE_EMA, PRICE_CLOSE, 1);
    double fastEMA_prev = iMA(Symbol(), PERIOD_H1, FastEMAPeriod, 0, MODE_EMA, PRICE_CLOSE, 2);
    double slowEMA_prev = iMA(Symbol(), PERIOD_H1, SlowEMAPeriod, 0, MODE_EMA, PRICE_CLOSE, 2);
    double close1 = iClose(Symbol(), PERIOD_H1, 1);

    // ATR volatility filter
    double atr = iATR(Symbol(), PERIOD_H1, ATRPeriod, 1);
    double atrThreshold = avgATR
    MaxVolatilityMult;
    if(atr < MinVolatility)
    {
    Comment("Volatility too low for trend: ", atr);
    return;
    }
    if(atr > atrThreshold && atrThreshold > 0)
    {
    Comment("Volatility spike detected: ", atr);
    return;
    }
    avgATR = (avgATR 0.9) + (atr 0.1);

    int cmd = -1;
    double sl = 0, tp = 0;
    double bid = SymbolInfoDouble(Symbol(), SYMBOL_BID);
    double ask = SymbolInfoDouble(Symbol(), SYMBOL_ASK);

    // Bullish crossover: fast EMA crosses above slow EMA
    if(fastEMA_prev <= slowEMA_prev && fastEMA > slowEMA)
    {
    cmd = OP_BUY;
    sl = bid - StopLossPoints Point;
    tp = bid + TakeProfitPoints
    Point;
    }
    // Bearish crossover: fast EMA crosses below slow EMA
    else if(fastEMA_prev >= slowEMA_prev && fastEMA < slowEMA)
    {
    cmd = OP_SELL;
    sl = ask + StopLossPoints Point;
    tp = ask - TakeProfitPoints
    Point;
    }

    if(cmd != -1)
    {
    int ticket = OrderSend(Symbol(), cmd, LotSize, (cmd==OP_BUY?ask:bid), 3, sl, tp, "Golden Phoenix", MagicNumber, 0, clrNONE);
    if(ticket < 0)
    Print("OrderSend failed. Error: ", GetLastError());
    }
    }

    //+------------------------------------------------------------------+
    //| 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 currentStop = OrderStopLoss();
    double newStop = 0;
    double profitPoints = 0;

    if(OrderType() == OP_BUY)
    {
    profitPoints = (Bid - OrderOpenPrice()) / Point;
    if(profitPoints >= TrailingStart)
    {
    newStop = Bid - (TrailingStep Point);
    if(newStop > currentStop || currentStop == 0)
    {
    if(OrderModify(OrderTicket(), OrderOpenPrice(), newStop, OrderTakeProfit(), 0, clrNONE))
    Print("Trailing stop updated for BUY #", OrderTicket());
    }
    }
    }
    else if(OrderType() == OP_SELL)
    {
    profitPoints = (OrderOpenPrice() - Ask) / Point;
    if(profitPoints >= TrailingStart)
    {
    newStop = Ask + (TrailingStep
    Point);
    if(newStop < currentStop || currentStop == 0)
    {
    if(OrderModify(OrderTicket(), OrderOpenPrice(), newStop, OrderTakeProfit(), 0, clrNONE))
    Print("Trailing stop updated for SELL #", OrderTicket());
    }
    }
    }
    break;
    }
    }
    }
    }

    //+------------------------------------------------------------------+
    //| 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, 3, clrNONE);
    else if(OrderType() == OP_SELL)
    OrderClose(OrderTicket(), OrderLots(), Ask, 3, clrNONE);
    }
    }
    }
    }
    //+------------------------------------------------------------------+
    ``
    Reference: Original MQL4 code for educational purposes.
    Disclaimer: Forex and gold trading involve substantial risk of loss. This EA is provided "as is" without any warranty of profitability. Always backtest and forward test on a demo account before using live funds. Past performance does not guarantee future results.