Summary: Gold Thunderbolt EA is a high-profit MQL4 expert advisor for XAUUSD. It uses volatility breakout entries with a controlled grid recovery system and dynamic lot progression. Suitable for M15 timeframe.




Gold Thunderbolt EA is engineered specifically for gold (XAUUSD) to capture high-profit opportunities while maintaining risk controls suitable for gold's explosive moves. The EA identifies volatility compression patterns and enters on breakout with the trend. A carefully managed grid recovery system (max 3 levels) helps recover drawdowns without infinite risk. Dynamic lot sizing based on equity percentage ensures compounding growth. The EA includes a maximum drawdown limiter and time-based filters to avoid low-liquidity sessions.

Recommended Timeframe: M15
Trading Logic:
  • Volatility Detection: Calculate ATR(20) and detect narrowing range (current range < 0.6 <em> average range).

  • Breakout Entry: When price breaks above/below the recent 20-period high/low with momentum confirmation (close > high[1] + spread).

  • Grid Recovery: If first trade goes against direction, place recovery trade at 1.5x distance with 2x lot size (max 3 levels).

  • Risk Control: Equity-based lot sizing (0.01 per $1000 balance), max total risk 8% of equity, no trading during Asian session (00:00-08:00 GMT).


  • ``mql4
    //+------------------------------------------------------------------+
    //| GoldThunderboltEA.mq4 |
    //+------------------------------------------------------------------+
    #property copyright ""
    #property link ""
    #property version "1.00"
    #property strict

    //--- input parameters with comments
    input double RiskPercent = 2.0; // Risk per trade as percentage of equity (2%)
    input int ATRPeriod = 20; // ATR period for volatility detection
    input double RangeCompression = 0.6; // Range compression ratio (current range / avg range) for entry trigger
    input int BreakoutPeriod = 20; // Period for breakout high/low detection
    input double GridDistanceMultiplier = 1.5; // Distance multiplier for grid levels (relative to initial stop)
    input double GridLotMultiplier = 2.0; // Lot multiplier for recovery trades (2x)
    input int MaxGridLevels = 3; // Maximum grid recovery levels (0 = disable grid)
    input double MaxDrawdownPercent = 15.0; // Maximum allowed drawdown percentage (hard stop)
    input bool UseAsianFilter = true; // Filter out Asian session (low volatility)
    input int MagicNumber = 202414; // Unique EA identifier
    input int Slippage = 30; // Maximum slippage in points

    //--- global variables
    double currentEquityStart = 0;
    datetime lastBarTime = 0;
    bool drawdownStop = false;
    double baseLotSize = 0.01;
    double initialATR = 0;

    //+------------------------------------------------------------------+
    //| Expert initialization function |
    //+------------------------------------------------------------------+
    int OnInit()
    {
    currentEquityStart = AccountEquity();
    drawdownStop = false;
    baseLotSize = NormalizeDouble(AccountEquity() RiskPercent / 10000.0, 2);
    if(baseLotSize < 0.01) baseLotSize = 0.01;
    if(baseLotSize > 1.0) baseLotSize = 1.0;
    initialATR = iATR(Symbol(), PERIOD_M15, ATRPeriod, 1);
    return(INIT_SUCCEEDED);
    }

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

    //+------------------------------------------------------------------+
    //| Expert tick function |
    //+------------------------------------------------------------------+
    void OnTick()
    {
    // Maximum drawdown protection
    double currentEquity = AccountEquity();
    double drawdownPercent = (currentEquityStart - currentEquity) / currentEquityStart 100;
    if(drawdownPercent >= MaxDrawdownPercent)
    {
    if(!drawdownStop)
    {
    CloseAllOrders();
    drawdownStop = true;
    Comment("Max drawdown reached. EA stopped.");
    }
    return;
    }

    // Asian session filter (GMT: 00:00 to 08:00)
    if(UseAsianFilter)
    {
    datetime currentTime = TimeCurrent();
    int hourGMT = TimeHour(currentTime);
    if(hourGMT >= 0 && hourGMT < 8)
    {
    Comment("Asian session - no trades");
    return;
    }
    }

    // New bar logic (M15)
    if(Time[0] == lastBarTime)
    return;
    lastBarTime = Time[0];

    // Update base lot size dynamically based on equity
    baseLotSize = NormalizeDouble(AccountEquity()
    RiskPercent / 10000.0, 2);
    if(baseLotSize < 0.01) baseLotSize = 0.01;
    if(baseLotSize > 1.0) baseLotSize = 1.0;

    // Check current positions for grid management
    int currentLevels = CountPositions();
    if(currentLevels > 0)
    {
    ManageGridRecovery();
    return;
    }

    // Volatility compression detection
    double currentRange = iHigh(Symbol(), PERIOD_M15, 1) - iLow(Symbol(), PERIOD_M15, 1);
    double avgRange = iATR(Symbol(), PERIOD_M15, ATRPeriod, 1);
    if(avgRange <= 0) avgRange = currentRange;

    bool isCompressed = (currentRange < avgRange RangeCompression);
    if(!isCompressed)
    {
    Comment("No volatility compression detected");
    return;
    }

    // Breakout detection
    double highBreakout = iHigh(Symbol(), PERIOD_M15, iHighest(Symbol(), PERIOD_M15, MODE_HIGH, BreakoutPeriod, 2));
    double lowBreakout = iLow(Symbol(), PERIOD_M15, iLowest(Symbol(), PERIOD_M15, MODE_LOW, BreakoutPeriod, 2));
    double close1 = iClose(Symbol(), PERIOD_M15, 1);
    double open1 = iOpen(Symbol(), PERIOD_M15, 1);
    double ask = Ask;
    double bid = Bid;

    int cmd = -1;
    double sl = 0, tp = 0;

    // Bullish breakout: close above high breakout with bullish candle
    if(close1 > highBreakout && close1 > open1)
    {
    cmd = OP_BUY;
    sl = bid - (initialATR
    1.5);
    tp = bid + (initialATR 3.0);
    }
    // Bearish breakout: close below low breakout with bearish candle
    else if(close1 < lowBreakout && close1 < open1)
    {
    cmd = OP_SELL;
    sl = ask + (initialATR
    1.5);
    tp = ask - (initialATR 3.0);
    }

    if(cmd != -1)
    {
    double lot = baseLotSize;
    int ticket = OrderSend(Symbol(), cmd, lot, (cmd==OP_BUY?ask:bid), Slippage, sl, tp, "Gold Thunderbolt", MagicNumber, 0, clrNONE);
    if(ticket < 0)
    Print("OrderSend failed: ", GetLastError());
    }
    }

    //+------------------------------------------------------------------+
    //| Manage grid recovery system for open positions |
    //+------------------------------------------------------------------+
    void ManageGridRecovery()
    {
    // Get total floating profit
    double floatingProfit = 0;
    int buyCount = 0, sellCount = 0;
    double avgBuyPrice = 0, avgSellPrice = 0;

    for(int i = OrdersTotal()-1; i >= 0; i--)
    {
    if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
    {
    if(OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber)
    {
    floatingProfit += OrderProfit() + OrderSwap() + OrderCommission();
    if(OrderType() == OP_BUY)
    {
    buyCount++;
    avgBuyPrice += OrderOpenPrice();
    }
    else if(OrderType() == OP_SELL)
    {
    sellCount++;
    avgSellPrice += OrderOpenPrice();
    }
    }
    }
    }

    if(buyCount > 0) avgBuyPrice /= buyCount;
    if(sellCount > 0) avgSellPrice /= sellCount;

    int totalOrders = buyCount + sellCount;

    // Check if we need to add a grid level
    if(totalOrders > 0 && totalOrders < MaxGridLevels)
    {
    double atr = iATR(Symbol(), PERIOD_M15, ATRPeriod, 1);
    double gridDistance = atr
    GridDistanceMultiplier;

    // Determine direction of first trade
    OrderSelect(0, SELECT_BY_POS, MODE_TRADES);
    int firstCmd = OrderType();
    double currentPrice = (firstCmd == OP_BUY) ? Bid : Ask;
    double entryPrice = OrderOpenPrice();

    double distanceFromEntry = MathAbs(currentPrice - entryPrice) / Point;
    double requiredDistance = gridDistance / Point;

    // If price moves against position by grid distance, add recovery trade
    if(distanceFromEntry >= requiredDistance && totalOrders < MaxGridLevels)
    {
    double newLot = baseLotSize MathPow(GridLotMultiplier, totalOrders);
    if(newLot > 1.0) newLot = 1.0;

    int newCmd = firstCmd;
    double sl = 0, tp = 0;

    if(newCmd == OP_BUY)
    {
    sl = currentPrice - (atr
    1.5);
    tp = currentPrice + (atr 2.5);
    }
    else
    {
    sl = currentPrice + (atr
    1.5);
    tp = currentPrice - (atr * 2.5);
    }

    int ticket = OrderSend(Symbol(), newCmd, newLot, currentPrice, Slippage, sl, tp, "Grid Recovery", MagicNumber, 0, clrNONE);
    if(ticket > 0)
    Print("Grid level ", totalOrders+1, " opened");
    }
    }

    // Take profit when overall floating profit becomes positive
    if(floatingProfit > 0 && totalOrders > 0)
    {
    CloseAllOrders();
    Print("Grid closed with profit: ", floatingProfit);
    }
    }

    //+------------------------------------------------------------------+
    //| 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)
    {
    bool result;
    if(OrderType() == OP_BUY)
    result = OrderClose(OrderTicket(), OrderLots(), Bid, Slippage, clrNONE);
    else if(OrderType() == OP_SELL)
    result = OrderClose(OrderTicket(), OrderLots(), Ask, Slippage, clrNONE);
    }
    }
    }
    }
    //+------------------------------------------------------------------+
    ``
    Reference: Original MQL4 code for educational purposes.
    Disclaimer: This EA uses grid recovery which can amplify losses in adverse conditions. High-profit strategies carry correspondingly high risk. This EA is provided as-is without any guarantee of profit. Test thoroughly on demo for at least 3 months before live trading. Past performance does not guarantee future results.