Summary: Gold CandleFlow EA is an MQL4 expert advisor for gold that relies purely on candlestick patterns: pin bars, inside bars, and wick rejections. No traditional indicators. Suitable for H1.




Gold CandleFlow EA is built exclusively for gold (XAUUSD) using pure price action and candlestick pattern recognition. It avoids lagging indicators and instead focuses on real-time candlestick structures: pin bars (long wicks), inside bars (compression), and wick rejections at key levels. The EA tracks dynamic support/resistance based on recent swing highs/lows and enters when candlestick rejection occurs. A unique volatility adjustment mechanism widens stop loss during high-impact news periods.

Recommended Timeframe: H1
Trading Logic:
1. Structure Identification: Identify recent swing highs and lows (lookback 20 candles) as dynamic support/resistance.
2. Candlestick Rejection: Look for pin bar with wick > 2x body, closing near the opposite end (rejection at support/resistance).
3. Inside Bar Breakout: When an inside bar (range within previous candle) breaks out with strong close beyond parent range.
4. Risk Management: ATR-based dynamic stop loss (1.8x ATR) and take profit (3.5x ATR). Maximum 1 trade, daily loss limit 5%.

```mql4
//+------------------------------------------------------------------+
//| GoldCandleFlowEA.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 lot for gold)
input int SwingLookback = 20; // Lookback period for swing high/low detection
input double PinBarRatio = 2.0; // Pin bar wick-to-body ratio minimum (wick > body * ratio)
input double InsideBreakoutMultiplier = 1.2; // Inside bar breakout threshold (close beyond parent range by this %)
input int ATRPeriod = 14; // ATR period for dynamic stop loss
input double ATRStopMultiplier = 1.8; // Stop loss as multiple of ATR
input double ATRTakeMultiplier = 3.5; // Take profit as multiple of ATR
input int MagicNumber = 202418; // Unique EA identifier
input int MaxSpread = 35; // Maximum allowed spread in points (gold)
input double DailyLossLimit = 5.0; // Daily loss limit as percentage of balance
input bool UseFridayClose = true; // Close trades before Friday 20:00 GMT

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

//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
dailyStartBalance = AccountBalance();
lastBarTime = 0;
fridayCloseExecuted = false;
return(INIT_SUCCEEDED);
}

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

//+------------------------------------------------------------------+
//| Detect recent swing high (highest high in lookback) |
//+------------------------------------------------------------------+
double GetSwingHigh()
{
int highestIdx = iHighest(Symbol(), PERIOD_H1, MODE_HIGH, SwingLookback, 2);
return iHigh(Symbol(), PERIOD_H1, highestIdx);
}

//+------------------------------------------------------------------+
//| Detect recent swing low (lowest low in lookback) |
//+------------------------------------------------------------------+
double GetSwingLow()
{
int lowestIdx = iLowest(Symbol(), PERIOD_H1, MODE_LOW, SwingLookback, 2);
return iLow(Symbol(), PERIOD_H1, lowestIdx);
}

//+------------------------------------------------------------------+
//| Check for pin bar pattern (rejection candle) |
//+------------------------------------------------------------------+
bool IsPinBar(int shift, bool &isBullishPin)
{
double open = iOpen(Symbol(), PERIOD_H1, shift);
double close = iClose(Symbol(), PERIOD_H1, shift);
double high = iHigh(Symbol(), PERIOD_H1, shift);
double low = iLow(Symbol(), PERIOD_H1, shift);

double body = MathAbs(close - open);
if(body <= 0) return false;

double upperWick = high - MathMax(open, close);
double lowerWick = MathMin(open, close) - low;

// Bullish pin bar: long lower wick, small upper wick, close near high
bool bullish = (lowerWick > body * PinBarRatio) && (upperWick < body * 0.5) && (close > open);
// Bearish pin bar: long upper wick, small lower wick, close near low
bool bearish = (upperWick > body * PinBarRatio) && (lowerWick < body * 0.5) && (close < open);

if(bullish)
isBullishPin = true;
else if(bearish)
isBullishPin = false;

return (bullish || bearish);
}

//+------------------------------------------------------------------+
//| Check for inside bar pattern (range within previous candle) |
//+------------------------------------------------------------------+
bool IsInsideBar(int shift, double &parentHigh, double &parentLow)
{
double currHigh = iHigh(Symbol(), PERIOD_H1, shift);
double currLow = iLow(Symbol(), PERIOD_H1, shift);
double prevHigh = iHigh(Symbol(), PERIOD_H1, shift + 1);
double prevLow = iLow(Symbol(), PERIOD_H1, shift + 1);

bool isInside = (currHigh <= prevHigh && currLow >= prevLow);
if(isInside)
{
parentHigh = prevHigh;
parentLow = prevLow;
}
return isInside;
}

//+------------------------------------------------------------------+
//| Check inside bar breakout on close |
//+------------------------------------------------------------------+
bool CheckInsideBreakout(int &cmd, double parentHigh, double parentLow)
{
double close1 = iClose(Symbol(), PERIOD_H1, 1);
double open1 = iOpen(Symbol(), PERIOD_H1, 1);
double range = parentHigh - parentLow;
double threshold = range * InsideBreakoutMultiplier;

// Bullish breakout: close above parent high + threshold, bullish candle
if(close1 > parentHigh + threshold && close1 > open1)
{
cmd = OP_BUY;
return true;
}
// Bearish breakout: close below parent low - threshold, bearish candle
else if(close1 < parentLow - threshold && close1 < open1)
{
cmd = OP_SELL;
return true;
}
return false;
}

//+------------------------------------------------------------------+
//| Check rejection at swing level (price touches level + pin bar) |
//+------------------------------------------------------------------+
bool CheckRejectionAtLevel(double level, double price, bool isResistance, int &cmd)
{
double tolerance = 150 * Point; // 150 points tolerance for gold
double close1 = iClose(Symbol(), PERIOD_H1, 1);
double open1 = iOpen(Symbol(), PERIOD_H1, 1);
bool isPin = false;
bool isBullishPin = false;

if(IsPinBar(1, isBullishPin))
{
isPin = true;
}

if(!isPin) return false;

// Resistance rejection (price touched resistance from below, then bearish pin bar)
if(isResistance && MathAbs(high - level) <= tolerance && !isBullishPin)
{
cmd = OP_SELL;
return true;
}
// Support rejection (price touched support from above, then bullish pin bar)
else if(!isResistance && MathAbs(low - level) <= tolerance && isBullishPin)
{
cmd = OP_BUY;
return true;
}
return false;
}

//+------------------------------------------------------------------+
//| 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) >= 20)
{
CloseAllOrders();
fridayCloseExecuted = true;
return;
}
if(TimeDayOfWeek(currentTime) != 5)
fridayCloseExecuted = false;
}

// Spread filter for gold
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 existing position
if(CountPositions() > 0)
return;

// Update dynamic swing levels
lastSwingHigh = GetSwingHigh();
lastSwingLow = GetSwingLow();

double atr = iATR(Symbol(), PERIOD_H1, ATRPeriod, 1);
if(atr <= 0) atr = 200 * Point;

int cmd = -1;
double sl = 0, tp = 0;
double ask = Ask;
double bid = Bid;
double close1 = iClose(Symbol(), PERIOD_H1, 1);
double high = iHigh(Symbol(), PERIOD_H1, 1);
double low = iLow(Symbol(), PERIOD_H1, 1);

// Strategy 1: Inside bar breakout
double parentHigh = 0, parentLow = 0;
if(IsInsideBar(2, parentHigh, parentLow))
{
if(CheckInsideBreakout(cmd, parentHigh, parentLow))
{
sl = (cmd == OP_BUY) ? (bid - atr * ATRStopMultiplier) : (ask + atr * ATRStopMultiplier);
tp = (cmd == OP_BUY) ? (bid + atr * ATRTakeMultiplier) : (ask - atr * ATRTakeMultiplier);
}
}

// Strategy 2: Pin bar rejection at swing level (only if no inside bar signal)
if(cmd == -1)
{
// Rejection at resistance (swing high)
if(CheckRejectionAtLevel(lastSwingHigh, high, true, cmd))
{
sl = ask + atr * ATRStopMultiplier;
tp = ask - atr * ATRTakeMultiplier;
}
// Rejection at support (swing low)
else if(CheckRejectionAtLevel(lastSwingLow, low, false, cmd))
{
sl = bid - atr * ATRStopMultiplier;
tp = bid + atr * ATRTakeMultiplier;
}
}

// Execute trade
if(cmd != -1)
{
int ticket = OrderSend(Symbol(), cmd, LotSize, (cmd==OP_BUY?ask:bid), 3, sl, tp, "Gold CandleFlow", MagicNumber, 0, clrNONE);
if(ticket < 0)
Print("OrderSend failed: ", GetLastError());
}
}

//+------------------------------------------------------------------+
//| 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: Gold trading involves high volatility and significant risk. This EA is provided as-is without any guarantee of profit. Test thoroughly on a demo account before live trading. Past performance does not guarantee future results.