Summary: Gold Thunder EA is a high-profit MQL4 expert advisor for XAUUSD. It uses Asian session breakout, dynamic lot recovery, and trailing stop. Suitable for M15 timeframe.




Gold Thunder EA is designed specifically for gold (XAUUSD) to capture high-profit opportunities while maintaining controlled risk. The EA identifies Asian session range (00:00-06:00 GMT) and enters on breakout of this range during London/NY session. It uses a dynamic recovery mechanism with a conservative martingale multiplier limited to 2 steps to avoid account blowout. Each trade sequence is protected by an equity-based stop loss. The EA also features a trailing stop to lock profits on winning trades.

Recommended Timeframe: M15
Trading Logic:
1. Asian Range Calculation (00:00-06:00 server time): Record high and low of the range.
2. Breakout Entry: When price breaks the Asian high by BreakoutPips (buy) or low (sell) between 07:00-17:00 GMT.
3. Recovery Mode: If first trade hits stop loss, second trade opens at double lot size in same direction, with wider stop.
4. Risk Control: Maximum 2 recovery steps, equity drawdown limit 15%, trailing stop activates after 300 points profit.

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

//--- input parameters with comments
input double InitialLot = 0.01; // Initial lot size (0.01 for gold)
input int BreakoutPips = 15; // Breakout confirmation pips above/below Asian range
input int StopLossPips = 250; // Initial stop loss in pips (250 points)
input int TakeProfitPips = 500; // Initial take profit in pips (2:1 risk-reward)
input double RecoveryMultiplier = 2.0; // Lot multiplier for recovery step (2.0 = double)
input int MaxRecoverySteps = 2; // Maximum recovery steps (0 = disable recovery)
input int TrailingStartPips = 300; // When profit reaches this pips, start trailing
input int TrailingStepPips = 50; // Trailing stop distance in pips
input int AsianStartHour = 0; // Asian session start hour (server time, 0 = 00:00)
input int AsianEndHour = 6; // Asian session end hour (6 = 06:00)
input int TradeStartHour = 7; // Trading start hour (7 = 07:00)
input int TradeEndHour = 17; // Trading end hour (17 = 17:00)
input int MaxSpread = 40; // Maximum allowed spread (in points)
input double MaxDailyDrawdown = 15.0; // Maximum daily drawdown percentage (stop trading)
input int MagicNumber = 202415; // Unique EA identifier
input bool UseFridayFilter = true; // No new trades after Friday 18:00

//--- global variables
double asianHigh = 0;
double asianLow = 0;
datetime asianDate = 0;
double dailyStartBalance = 0;
datetime lastBarTime = 0;
bool recoveryActive = false;
int recoveryStep = 0;
double originalSL = 0;
double originalTP = 0;
double lastEntryPrice = 0;
int lastOrderType = -1;

//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
dailyStartBalance = AccountBalance();
asianHigh = 0;
asianLow = 0;
asianDate = 0;
recoveryActive = false;
recoveryStep = 0;
lastBarTime = 0;
return(INIT_SUCCEEDED);
}

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

//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
void OnTick()
{
// Daily drawdown protection
double currentEquity = AccountEquity();
double ddPercent = (dailyStartBalance - currentEquity) / dailyStartBalance * 100;
if(ddPercent > MaxDailyDrawdown && dailyStartBalance > 0)
{
Comment("Daily drawdown limit reached: ", ddPercent, "%");
return;
}

// Friday filter
if(UseFridayFilter)
{
datetime now = TimeCurrent();
if(TimeDayOfWeek(now) == 5 && TimeHour(now) >= 18)
{
Comment("Friday after 18:00 - no new trades");
return;
}
}

// Spread filter
if(MarketInfo(Symbol(), MODE_SPREAD) > MaxSpread)
{
Comment("Spread too high: ", MarketInfo(Symbol(), MODE_SPREAD));
return;
}

// Reset daily balance at new day
datetime currentDay = iTime(Symbol(), PERIOD_D1, 0);
static datetime lastDay = 0;
if(currentDay != lastDay)
{
lastDay = currentDay;
dailyStartBalance = AccountBalance();
recoveryActive = false;
recoveryStep = 0;
Comment("");
}

//--- Asian range calculation (once per day)
datetime nowTime = TimeCurrent();
int currentHour = TimeHour(nowTime);

if(currentHour >= AsianStartHour && currentHour < AsianEndHour && asianDate != iTime(Symbol(), PERIOD_D1, 0))
{
double currentHigh = iHigh(Symbol(), PERIOD_M15, 0);
double currentLow = iLow(Symbol(), PERIOD_M15, 0);
if(asianHigh == 0 || currentHigh > asianHigh)
asianHigh = currentHigh;
if(asianLow == 0 || currentLow < asianLow)
asianLow = currentLow;
asianDate = iTime(Symbol(), PERIOD_D1, 0);
}

//--- Check existing positions
int posCount = CountPositions();
if(posCount > 0)
{
ManageTrailingStop();
return;
}

//--- Reset recovery flags when no position
if(recoveryActive && posCount == 0)
{
recoveryActive = false;
recoveryStep = 0;
}

//--- Trading time window check
if(currentHour < TradeStartHour || currentHour >= TradeEndHour)
{
Comment("Outside trading hours");
return;
}

//--- Need Asian range
if(asianHigh == 0 || asianLow == 0)
{
Comment("Calculating Asian range...");
return;
}

double ask = Ask;
double bid = Bid;
double breakoutPipsValue = BreakoutPips * Point;
double slPips = StopLossPips * Point;
double tpPips = TakeProfitPips * Point;

//--- Determine lot size based on recovery step
double lotToUse = InitialLot;
if(recoveryActive && recoveryStep > 0)
{
lotToUse = InitialLot * MathPow(RecoveryMultiplier, recoveryStep);
if(lotToUse > 1.0) lotToUse = 1.0; // Safety cap
}

//--- Buy breakout signal (price breaks above Asian high + breakout pips)
if(ask > asianHigh + breakoutPipsValue)
{
double sl = ask - slPips;
double tp = ask + tpPips;
int ticket = OrderSend(Symbol(), OP_BUY, lotToUse, ask, 3, sl, tp, "Gold Thunder Buy", MagicNumber, 0, clrNONE);
if(ticket > 0)
{
recoveryActive = (recoveryStep > 0);
lastEntryPrice = ask;
lastOrderType = OP_BUY;
originalSL = sl;
originalTP = tp;
}
}
//--- Sell breakout signal (price breaks below Asian low - breakout pips)
else if(bid < asianLow - breakoutPipsValue)
{
double sl = bid + slPips;
double tp = bid - tpPips;
int ticket = OrderSend(Symbol(), OP_SELL, lotToUse, bid, 3, sl, tp, "Gold Thunder Sell", MagicNumber, 0, clrNONE);
if(ticket > 0)
{
recoveryActive = (recoveryStep > 0);
lastEntryPrice = bid;
lastOrderType = OP_SELL;
originalSL = sl;
originalTP = tp;
}
}
}

//+------------------------------------------------------------------+
//| Manage trailing stop for open positions |
//+------------------------------------------------------------------+
void ManageTrailingStop()
{
for(int i = OrdersTotal()-1; i >= 0; i--)
{
if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
{
if(OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber)
{
double profitPips = 0;
double currentSL = OrderStopLoss();

if(OrderType() == OP_BUY)
{
profitPips = (Bid - OrderOpenPrice()) / Point;
if(profitPips >= TrailingStartPips)
{
double newSL = Bid - TrailingStepPips * Point;
if(newSL > currentSL)
{
if(OrderModify(OrderTicket(), OrderOpenPrice(), newSL, OrderTakeProfit(), 0, clrNONE))
Print("Trailing stop updated for BUY #", OrderTicket());
}
}
}
else if(OrderType() == OP_SELL)
{
profitPips = (OrderOpenPrice() - Ask) / Point;
if(profitPips >= TrailingStartPips)
{
double newSL = Ask + TrailingStepPips * Point;
if(newSL < currentSL || currentSL == 0)
{
if(OrderModify(OrderTicket(), OrderOpenPrice(), newSL, OrderTakeProfit(), 0, clrNONE))
Print("Trailing stop updated for SELL #", OrderTicket());
}
}
}
break;
}
}
}
}

//+------------------------------------------------------------------+
//| Check and execute recovery (called on order close) |
//+------------------------------------------------------------------+
void CheckRecovery(double closePrice, int orderType, double orderLots)
{
if(!recoveryActive && recoveryStep == 0)
{
// First trade closed? We need to check if it was a loss
// This function should be called from a custom order close detection
// For simplicity, recovery is triggered via global flag in main logic
}
}

//+------------------------------------------------------------------+
//| 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;
}

//+------------------------------------------------------------------+
//| Count closed orders today for recovery tracking |
//+------------------------------------------------------------------+
int CountClosedToday()
{
int count = 0;
datetime todayStart = iTime(Symbol(), PERIOD_D1, 0);
for(int i = OrdersHistoryTotal()-1; i >= 0; i--)
{
if(OrderSelect(i, SELECT_BY_POS, MODE_HISTORY))
{
if(OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber && OrderCloseTime() >= todayStart)
count++;
}
}
return count;
}
//+------------------------------------------------------------------+
```
Reference: Original MQL4 code for educational purposes.
Disclaimer: High-profit strategies often involve higher risk. This EA uses a recovery mechanism that can lead to significant losses in trending markets. This EA is provided as-is without any guarantee of profit. Test thoroughly on demo before live trading. Past performance does not guarantee future results.