Summary: Gold Aurora EA is an MQL4 expert advisor for XAUUSD that integrates three complementary strategies: EMA trend following, RSI mean reversion, and ATR volatility breakout. Designed for H1 stable operation with strict risk controls.




Gold Aurora EA is a multi-strategy trading system designed specifically for gold (XAUUSD) stability. Unlike single-strategy EAs that fail during specific market regimes, Aurora dynamically switches between three proven approaches based on current market conditions. The EA uses a volatility regime detector to determine whether the market is trending, ranging, or breaking out, then applies the most appropriate strategy. All trades include fixed stop loss and take profit, with a maximum of one position at a time. The system includes daily equity protection, spread control, Friday close mechanism, and a maximum drawdown limiter. No grid, no martingale, no dangerous averaging.

Recommended Timeframe: H1
Trading Logic:
  • Regime Detection: Calculate ATR(20) and compare to 50-period average to classify market as Trending (ATR > 1.5x avg), Ranging (ATR < 0.8x avg), or Breakout.

  • Trending Mode: Use EMA(50) and EMA(200) crossover with ADX(14) > 25 confirmation.

  • Ranging Mode: Use RSI(14) extremes (oversold < 30, overbought > 70) with price near Bollinger Bands.

  • Breakout Mode: Detect when price breaks above 20-period high or below 20-period low with momentum.

  • Risk Control: Fixed SL at 300 points, TP at 600 points. Daily loss limit 5%, max spread 35 points.


  • ``mql4
    //+------------------------------------------------------------------+
    //| GoldAuroraEA.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 = 50; // Fast EMA period for trend mode
    input int SlowEMAPeriod = 200; // Slow EMA period for trend mode
    input int ADXPeriod = 14; // ADX period for trend strength
    input int ADXThreshold = 25; // Minimum ADX for trend mode
    input int RSIPeriod = 14; // RSI period for ranging mode
    input int RSIOversold = 30; // RSI oversold level (buy when below)
    input int RSIOverbought = 70; // RSI overbought level (sell when above)
    input int BBPeriod = 20; // Bollinger Bands period
    input double BBDeviation = 2.0; // Bollinger Bands deviation
    input int BreakoutPeriod = 20; // Lookback period for breakout detection
    input double TrendingATRMultiplier = 1.5; // ATR multiplier to classify trending
    input double RangingATRMultiplier = 0.8; // ATR multiplier to classify ranging
    input int StopLossPoints = 300; // Fixed stop loss in points
    input int TakeProfitPoints = 600; // Fixed take profit in points
    input int MagicNumber = 202421; // Unique EA identifier
    input int MaxSpread = 35; // Maximum allowed spread in points
    input double DailyLossLimit = 5.0; // Daily loss limit as percentage
    input double MaxDrawdownPercent = 15.0; // Maximum equity drawdown limit
    input bool UseFridayClose = true; // Close trades before Friday 21:00 GMT

    //--- global variables
    double dailyStartBalance = 0;
    double peakEquity = 0;
    datetime lastBarTime = 0;
    bool fridayCloseExecuted = false;
    bool drawdownStop = false;
    double avgATR = 0;

    //--- market regime constants
    enum MarketRegime {
    REGIME_TRENDING = 1,
    REGIME_RANGING = 2,
    REGIME_BREAKOUT = 3,
    REGIME_NEUTRAL = 0
    };

    //+------------------------------------------------------------------+
    //| Expert initialization function |
    //+------------------------------------------------------------------+
    int OnInit()
    {
    dailyStartBalance = AccountBalance();
    peakEquity = AccountEquity();
    lastBarTime = 0;
    fridayCloseExecuted = false;
    drawdownStop = false;
    avgATR = iATR(Symbol(), PERIOD_H1, 20, 1);
    if(avgATR <= 0) avgATR = 250 Point;
    return(INIT_SUCCEEDED);
    }

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

    //+------------------------------------------------------------------+
    //| Detect current market regime |
    //+------------------------------------------------------------------+
    MarketRegime DetectRegime()
    {
    double currentATR = iATR(Symbol(), PERIOD_H1, 20, 1);
    double avgATRLong = iATR(Symbol(), PERIOD_H1, 50, 1);
    if(avgATRLong <= 0) avgATRLong = currentATR;

    double ratio = currentATR / avgATRLong;

    // Trending regime: high volatility relative to average
    if(ratio > TrendingATRMultiplier)
    {
    double adx = iADX(Symbol(), PERIOD_H1, ADXPeriod, PRICE_CLOSE, MODE_MAIN, 1);
    if(adx >= ADXThreshold)
    return REGIME_TRENDING;
    }

    // Ranging regime: low volatility
    if(ratio < RangingATRMultiplier)
    {
    return REGIME_RANGING;
    }

    // Check for potential breakout
    double high20 = iHigh(Symbol(), PERIOD_H1, iHighest(Symbol(), PERIOD_H1, MODE_HIGH, BreakoutPeriod, 1));
    double low20 = iLow(Symbol(), PERIOD_H1, iLowest(Symbol(), PERIOD_H1, MODE_LOW, BreakoutPeriod, 1));
    double close1 = iClose(Symbol(), PERIOD_H1, 1);
    double range = high20 - low20;

    if(range > 0 && currentATR > avgATRLong
    1.2)
    {
    if(close1 > high20 || close1 < low20)
    return REGIME_BREAKOUT;
    }

    return REGIME_NEUTRAL;
    }

    //+------------------------------------------------------------------+
    //| Trending strategy - EMA crossover with ADX confirmation |
    //+------------------------------------------------------------------+
    bool GetTrendingSignal(int &cmd, double &sl, double &tp)
    {
    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 fastEMAPrev = iMA(Symbol(), PERIOD_H1, FastEMAPeriod, 0, MODE_EMA, PRICE_CLOSE, 2);
    double slowEMAPrev = iMA(Symbol(), PERIOD_H1, SlowEMAPeriod, 0, MODE_EMA, PRICE_CLOSE, 2);
    double adx = iADX(Symbol(), PERIOD_H1, ADXPeriod, PRICE_CLOSE, MODE_MAIN, 1);
    double diPlus = iADX(Symbol(), PERIOD_H1, ADXPeriod, PRICE_CLOSE, MODE_PLUSDI, 1);
    double diMinus = iADX(Symbol(), PERIOD_H1, ADXPeriod, PRICE_CLOSE, MODE_MINUSDI, 1);

    if(adx < ADXThreshold) return false;

    // Bullish crossover: fast EMA crosses above slow EMA
    if(fastEMAPrev <= slowEMAPrev && fastEMA > slowEMA && diPlus > diMinus)
    {
    cmd = OP_BUY;
    sl = SymbolInfoDouble(Symbol(), SYMBOL_BID) - StopLossPoints Point;
    tp = SymbolInfoDouble(Symbol(), SYMBOL_BID) + TakeProfitPoints
    Point;
    return true;
    }
    // Bearish crossover: fast EMA crosses below slow EMA
    else if(fastEMAPrev >= slowEMAPrev && fastEMA < slowEMA && diMinus > diPlus)
    {
    cmd = OP_SELL;
    sl = SymbolInfoDouble(Symbol(), SYMBOL_ASK) + StopLossPoints Point;
    tp = SymbolInfoDouble(Symbol(), SYMBOL_ASK) - TakeProfitPoints
    Point;
    return true;
    }

    return false;
    }

    //+------------------------------------------------------------------+
    //| Ranging strategy - RSI extremes with Bollinger confirmation |
    //+------------------------------------------------------------------+
    bool GetRangingSignal(int &cmd, double &sl, double &tp)
    {
    double rsi = iRSI(Symbol(), PERIOD_H1, RSIPeriod, PRICE_CLOSE, 1);
    double bbUpper = iBands(Symbol(), PERIOD_H1, BBPeriod, BBDeviation, 0, PRICE_CLOSE, MODE_UPPER, 1);
    double bbLower = iBands(Symbol(), PERIOD_H1, BBPeriod, BBDeviation, 0, PRICE_CLOSE, MODE_LOWER, 1);
    double close1 = iClose(Symbol(), PERIOD_H1, 1);

    // Oversold condition: RSI below threshold and price near lower band
    if(rsi <= RSIOversold && close1 <= bbLower + (bbLower 0.002))
    {
    cmd = OP_BUY;
    sl = SymbolInfoDouble(Symbol(), SYMBOL_BID) - StopLossPoints
    Point;
    tp = SymbolInfoDouble(Symbol(), SYMBOL_BID) + TakeProfitPoints Point;
    return true;
    }
    // Overbought condition: RSI above threshold and price near upper band
    else if(rsi >= RSIOverbought && close1 >= bbUpper - (bbUpper
    0.002))
    {
    cmd = OP_SELL;
    sl = SymbolInfoDouble(Symbol(), SYMBOL_ASK) + StopLossPoints Point;
    tp = SymbolInfoDouble(Symbol(), SYMBOL_ASK) - TakeProfitPoints
    Point;
    return true;
    }

    return false;
    }

    //+------------------------------------------------------------------+
    //| Breakout strategy - fresh range breakout with momentum |
    //+------------------------------------------------------------------+
    bool GetBreakoutSignal(int &cmd, double &sl, double &tp)
    {
    int highestIdx = iHighest(Symbol(), PERIOD_H1, MODE_HIGH, BreakoutPeriod, 2);
    int lowestIdx = iLowest(Symbol(), PERIOD_H1, MODE_LOW, BreakoutPeriod, 2);
    double highBound = iHigh(Symbol(), PERIOD_H1, highestIdx);
    double lowBound = iLow(Symbol(), PERIOD_H1, lowestIdx);
    double close1 = iClose(Symbol(), PERIOD_H1, 1);
    double open1 = iOpen(Symbol(), PERIOD_H1, 1);
    double volume1 = iVolume(Symbol(), PERIOD_H1, 1);
    double avgVolume = iMA(NULL, PERIOD_H1, 20, 0, MODE_SMA, VOLUME, 1);

    // Bullish breakout: close above high with strong momentum (bullish candle, higher volume)
    if(close1 > highBound && close1 > open1 && volume1 > avgVolume 1.2)
    {
    cmd = OP_BUY;
    sl = SymbolInfoDouble(Symbol(), SYMBOL_BID) - StopLossPoints
    Point;
    tp = SymbolInfoDouble(Symbol(), SYMBOL_BID) + TakeProfitPoints Point;
    return true;
    }
    // Bearish breakout: close below low with strong momentum
    else if(close1 < lowBound && close1 < open1 && volume1 > avgVolume
    1.2)
    {
    cmd = OP_SELL;
    sl = SymbolInfoDouble(Symbol(), SYMBOL_ASK) + StopLossPoints Point;
    tp = SymbolInfoDouble(Symbol(), SYMBOL_ASK) - TakeProfitPoints
    Point;
    return true;
    }

    return false;
    }

    //+------------------------------------------------------------------+
    //| Equity protection - track drawdown |
    //+------------------------------------------------------------------+
    bool CheckEquityProtection()
    {
    double currentEquity = AccountEquity();
    if(currentEquity > peakEquity)
    peakEquity = currentEquity;

    double drawdownPercent = (peakEquity - currentEquity) / peakEquity 100;

    if(drawdownPercent >= MaxDrawdownPercent)
    {
    if(!drawdownStop)
    {
    CloseAllOrders();
    drawdownStop = true;
    Comment("Max drawdown reached. EA stopped.");
    }
    return false;
    }

    // Daily loss limit check
    double dailyLossPercent = (dailyStartBalance - currentEquity) / dailyStartBalance
    100;
    if(dailyLossPercent >= DailyLossLimit)
    {
    Comment("Daily loss limit reached. No new trades.");
    return false;
    }

    return true;
    }

    //+------------------------------------------------------------------+
    //| Expert tick function |
    //+------------------------------------------------------------------+
    void OnTick()
    {
    // Equity protection
    if(!CheckEquityProtection())
    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];

    // Update ATR average
    double atr = iATR(Symbol(), PERIOD_H1, 20, 1);
    if(atr > 0) avgATR = (avgATR 0.95) + (atr 0.05);

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

    // Detect market regime
    MarketRegime regime = DetectRegime();
    bool signalGenerated = false;
    int cmd = -1;
    double sl = 0, tp = 0;

    switch(regime)
    {
    case REGIME_TRENDING:
    signalGenerated = GetTrendingSignal(cmd, sl, tp);
    if(signalGenerated)
    Comment("Signal: TRENDING mode");
    break;

    case REGIME_RANGING:
    signalGenerated = GetRangingSignal(cmd, sl, tp);
    if(signalGenerated)
    Comment("Signal: RANGING mode");
    break;

    case REGIME_BREAKOUT:
    signalGenerated = GetBreakoutSignal(cmd, sl, tp);
    if(signalGenerated)
    Comment("Signal: BREAKOUT mode");
    break;

    default:
    Comment("Market regime: NEUTRAL - no trade");
    break;
    }

    if(signalGenerated && cmd != -1)
    {
    double price = (cmd == OP_BUY) ? Ask : Bid;
    int ticket = OrderSend(Symbol(), cmd, LotSize, price, 5, sl, tp, "Gold Aurora", MagicNumber, 0, clrNONE);
    if(ticket < 0)
    Print("OrderSend failed: ", GetLastError());
    else
    Print("Order opened. Regime: ", regime);
    }
    }

    //+------------------------------------------------------------------+
    //| 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 inspired by multi-strategy gold trading principles from market analysis .
    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.