Summary: Gold Macro Matrix EA is an MQL4 expert advisor for XAUUSD that combines higher timeframe macro trend filtering with lower timeframe breakout confirmation. Suitable for M30 stable operation.




Gold Macro Matrix EA is engineered specifically for gold (XAUUSD) with a focus on macro trend alignment and breakout precision. Inspired by professional-grade EA structures, this EA first determines the directional bias on a higher timeframe (H1) using EMA trend filters, then waits for volatility confirmation on the execution timeframe (M30) before entering. The EA avoids the common pitfalls of gold trading—false breakouts and sudden reversals—by requiring alignment across multiple timeframes. A fixed stop loss based on ATR ensures each trade's risk is contained, while an adaptive trailing stop locks in profits as the trend develops. The EA includes daily equity protection, spread control, and Friday close mechanisms to safeguard capital.

Recommended Timeframe: M30
Trading Logic:
1. Macro Trend Filter (H1): EMA(50) and EMA(200) determine the primary trend direction.
2. Volatility Confirmation (M30): Price must close beyond the recent 20-period high/low.
3. Entry Trigger: Both macro trend and volatility breakout align in the same direction.
4. Risk Management: ATR-based stop loss (1.5x ATR), take profit at 3x ATR, trailing stop after 1x ATR profit.

```mql4
//+------------------------------------------------------------------+
//| GoldMacroMatrixEA.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 MacroTrendFast = 50; // Fast EMA for macro trend (H1)
input int MacroTrendSlow = 200; // Slow EMA for macro trend (H1)
input int BreakoutPeriod = 20; // Lookback bars for breakout detection
input int ATRPeriod = 14; // ATR period for stop loss
input double ATRStopMultiplier = 1.5; // Stop loss as multiple of ATR
input double ATRTakeMultiplier = 3.0; // Take profit as multiple of ATR
input double TrailingStartATR = 1.0; // Trailing activates at profit (x ATR)
input double TrailingStepATR = 0.5; // Trailing step (x ATR)
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 bool UseFridayClose = true; // Close trades before Friday 21:00 GMT

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

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

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

//+------------------------------------------------------------------+
//| Get macro trend direction from higher timeframe (H1) |
//+------------------------------------------------------------------+
int GetMacroTrend()
{
double closeH1 = iClose(Symbol(), PERIOD_H1, 1);
double emaFast = iMA(Symbol(), PERIOD_H1, MacroTrendFast, 0, MODE_EMA, PRICE_CLOSE, 1);
double emaSlow = iMA(Symbol(), PERIOD_H1, MacroTrendSlow, 0, MODE_EMA, PRICE_CLOSE, 1);

// Bullish: price above both EMAs with fast above slow
bool bullish = (closeH1 > emaFast && closeH1 > emaSlow && emaFast > emaSlow);
// Bearish: price below both EMAs with fast below slow
bool bearish = (closeH1 < emaFast && closeH1 < emaSlow && emaFast < emaSlow);

if(bullish) return 1;
if(bearish) return -1;
return 0;
}

//+------------------------------------------------------------------+
//| Check volatility breakout on execution timeframe (M30) |
//+------------------------------------------------------------------+
bool CheckBreakout(int direction, double &entryPrice, double &sl, double &tp, double atr)
{
if(direction == 0) return false;

// Find highest high and lowest low over BreakoutPeriod
int highIdx = iHighest(Symbol(), PERIOD_M30, MODE_HIGH, BreakoutPeriod, 2);
int lowIdx = iLowest(Symbol(), PERIOD_M30, MODE_LOW, BreakoutPeriod, 2);
double breakoutHigh = iHigh(Symbol(), PERIOD_M30, highIdx);
double breakoutLow = iLow(Symbol(), PERIOD_M30, lowIdx);
double close1 = iClose(Symbol(), PERIOD_M30, 1);
double open1 = iOpen(Symbol(), PERIOD_M30, 1);

if(direction == 1) // Long breakout
{
if(close1 > breakoutHigh && close1 > open1)
{
entryPrice = Ask;
sl = entryPrice - (atr * ATRStopMultiplier);
tp = entryPrice + (atr * ATRTakeMultiplier);
return true;
}
}
else if(direction == -1) // Short breakout
{
if(close1 < breakoutLow && close1 < open1)
{
entryPrice = Bid;
sl = entryPrice + (atr * ATRStopMultiplier);
tp = entryPrice - (atr * ATRTakeMultiplier);
return true;
}
}
return false;
}

//+------------------------------------------------------------------+
//| Manage trailing stop for open position |
//+------------------------------------------------------------------+
void ManageTrailingStop(double atr)
{
for(int i = OrdersTotal()-1; i >= 0; i--)
{
if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
{
if(OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber)
{
double activate = atr * TrailingStartATR;
double step = atr * TrailingStepATR;
double newSL = 0;

if(OrderType() == OP_BUY)
{
double profit = Bid - OrderOpenPrice();
if(profit >= activate)
{
newSL = Bid - step;
if(newSL > OrderStopLoss())
OrderModify(OrderTicket(), OrderOpenPrice(), newSL, OrderTakeProfit(), 0, clrNONE);
}
}
else if(OrderType() == OP_SELL)
{
double profit = OrderOpenPrice() - Ask;
if(profit >= activate)
{
newSL = Ask + step;
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 (M30)
if(Time[0] == lastBarTime)
return;
lastBarTime = Time[0];

// Manage existing position
int posCount = CountPositions();
if(posCount > 0)
{
double atr = iATR(Symbol(), PERIOD_M30, ATRPeriod, 1);
if(atr > 0) ManageTrailingStop(atr);
return;
}

// Get ATR and update average
double atr = iATR(Symbol(), PERIOD_M30, ATRPeriod, 1);
if(atr > 0) avgATR = (avgATR * 0.95) + (atr * 0.05);

// Volatility guard: skip if ATR too high (avoid news spikes)
if(atr > avgATR * 2.0 && avgATR > 0)
{
Comment("Volatility too high. ATR: ", atr);
return;
}

// Get macro trend direction
int macroTrend = GetMacroTrend();
if(macroTrend == 0)
{
Comment("No clear macro trend direction");
return;
}

// Check breakout entry
double entryPrice = 0, sl = 0, tp = 0;
if(CheckBreakout(macroTrend, entryPrice, sl, tp, atr))
{
int cmd = (macroTrend == 1) ? OP_BUY : OP_SELL;
int ticket = OrderSend(Symbol(), cmd, LotSize, entryPrice, 5, sl, tp, "Gold Macro Matrix", MagicNumber, 0, clrNONE);
if(ticket < 0)
Print("OrderSend failed: ", GetLastError());
else
Print("Breakout entry opened. Direction: ", cmd==OP_BUY?"BUY":"SELL");
}
}

//+------------------------------------------------------------------+
//| 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 macro trend EA structures for XAUUSD.
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.