//+------------------------------------------------------------------+
//| SMC_Hybrid_EA.mq5 |
//| Copyright 2026 xAI Grok |
//| |
//+------------------------------------------------------------------+
#property copyright "xAI Grok"
#property link ""
#property version "1.00"
#property strict
#property description "EA based on SMC Hybrid Demand Supply with 6 Checklists"
// Inputs
input int MagicNumber = 12345; // Magic Number
input double LotSize = 0.01; // Lot Size
input int Slippage = 3; // Slippage
input int StopLossPips = 50; // Stop Loss in Pips
input int TakeProfitPips = 100; // Take Profit in Pips
input int MaxZoneTouches = 2; // Max touches for unmitigated zone
input double FibLevel = 0.5; // Fibonacci 50% for Premium/Discount
input int ImbMinCandleSize = 20; // Min pips for Imbalance candle
input ENUM_TIMEFRAMES StructureTF = PERIOD_H1; // Timeframe for Market Structure
input ENUM_TIMEFRAMES EntryTF = PERIOD_M5; // Timeframe for Entry
// Buffers for zones
struct Zone {
double high;
double low;
bool isDemand; // true for Demand, false for Supply
int touches;
bool mitigated;
};
Zone demandZones[10];
Zone supplyZones[10];
int demandCount = 0;
int supplyCount = 0;
// Global variables
double fibRetrace;
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit() {
// Initialize
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason) {
// Cleanup
}
//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
void OnTick() {
if (!IsNewBar(EntryTF)) return;
// Step 1: Detect Market Structure and Trend
bool isBullish = IsBullishTrend();
// Step 2: Identify Potential Zones on Structure TF
IdentifyZones();
// Step 3: Filter Zones with 6 Checklists
for (int i = 0; i < demandCount; i++) {
if (FilterZone(demandZones, true, isBullish)) {
// Check for entry if price in zone
if (Ask >= demandZones.low && Ask <= demandZones.high && isBullish) {
OpenBuyOrder();
}
}
}
for (int i = 0; i < supplyCount; i++) {
if (FilterZone(supplyZones, false, isBullish)) {
// Check for entry
if (Bid <= supplyZones.high && Bid >= supplyZones.low && !isBullish) {
OpenSellOrder();
}
}
}
}
// Function to check new bar
bool IsNewBar(ENUM_TIMEFRAMES tf) {
static datetime lastBar = 0;
datetime currentBar = iTime(Symbol(), tf, 0);
if (currentBar != lastBar) {
lastBar = currentBar;
return true;
}
return false;
}
// Determine Trend (Checklist 4: Follow The Trend)
bool IsBullishTrend() {
// Simple: Higher Highs and Higher Lows using Swing on Structure TF
double hh = iHigh(Symbol(), StructureTF, iHighest(Symbol(), StructureTF, MODE_HIGH, 20, 1));
double hl = iLow(Symbol(), StructureTF, iLowest(Symbol(), StructureTF, MODE_LOW, 20, 1));
double prevHH = iHigh(Symbol(), StructureTF, iHighest(Symbol(), StructureTF, MODE_HIGH, 20, 21));
double prevHL = iLow(Symbol(), StructureTF, iLowest(Symbol(), StructureTF, MODE_LOW, 20, 21));
return (hh > prevHH && hl > prevHL);
}
// Identify Demand/Supply Zones (SMC Style: Last Base before strong move)
void IdentifyZones() {
demandCount = 0;
supplyCount = 0;
for (int i = 1; i < Bars(Symbol(), StructureTF) - 1; i++) {
// Find Base (consolidation): small candles
if (MathAbs(iClose(Symbol(), StructureTF, i) - iOpen(Symbol(), StructureTF, i)) < ImbMinCandleSize * Point) {
// Check if followed by strong move (IMB)
if (iClose(Symbol(), StructureTF, i-1) - iOpen(Symbol(), StructureTF, i-1) > ImbMinCandleSize * Point) {
// Demand zone
if (demandCount < 10) {
demandZones[demandCount].low = iLow(Symbol(), StructureTF, i);
demandZones[demandCount].high = iHigh(Symbol(), StructureTF, i);
demandZones[demandCount].isDemand = true;
demandZones[demandCount].touches = 0;
demandZones[demandCount].mitigated = false;
demandCount++;
}
} else if (iOpen(Symbol(), StructureTF, i-1) - iClose(Symbol(), StructureTF, i-1) > ImbMinCandleSize * Point) {
// Supply zone
if (supplyCount < 10) {
supplyZones[supplyCount].low = iLow(Symbol(), StructureTF, i);
supplyZones[supplyCount].high = iHigh(Symbol(), StructureTF, i);
supplyZones[supplyCount].isDemand = false;
supplyZones[supplyCount].touches = 0;
supplyZones[supplyCount].mitigated = false;
supplyCount++;
}
}
}
}
}
// Filter Zone with 6 Checklists
bool FilterZone(Zone &z, bool isDemand, bool isBullish) {
// Checklist 1: BOS / CHoCH
if (!HasBOSorCHoCH(z)) return false;
// Checklist 2: Imbalance (IMB)
if (!HasStrongIMB(z)) return false;
// Checklist 3: Liquidity / Inducement
if (!HasLiquiditySweep(z)) return false;
// Checklist 4: Follow The Trend
if (isDemand && !isBullish) return false;
if (!isDemand && isBullish) return false;
// Checklist 5: Unmitigated Zone
if (z.mitigated || z.touches > MaxZoneTouches) return false;
// Checklist 6: Premium / Discount Zone
if (!IsInDiscountPremium(z, isDemand, isBullish)) return false;
return true;
}
// Checklist 1: Has BOS or CHoCH
bool HasBOSorCHoCH(Zone &z) {
// Simplified: Check if zone break previous structure
double prevSwingHigh = iHigh(Symbol(), StructureTF, iHighest(Symbol(), StructureTF, MODE_HIGH, 10, 1));
double prevSwingLow = iLow(Symbol(), StructureTF, iLowest(Symbol(), StructureTF, MODE_LOW, 10, 1));
if (z.isDemand && z.high > prevSwingHigh) return true; // BOS in uptrend
if (!z.isDemand && z.low < prevSwingLow) return true; // CHoCH in downtrend
return false;
}
// Checklist 2: Has Strong IMB
bool HasStrongIMB(Zone &z) {
// Check for long candle after zone
int shift = iBarShift(Symbol(), StructureTF, z.high, false);
if (MathAbs(iClose(Symbol(), StructureTF, shift-1) - iOpen(Symbol(), StructureTF, shift-1)) > ImbMinCandleSize * Point) return true;
return false;
}
// Checklist 3: Has Liquidity / Inducement
bool HasLiquiditySweep(Zone &z) {
// Check for sweep of nearby high/low before reaching zone
double nearbyHigh = iHigh(Symbol(), StructureTF, 5);
double nearbyLow = iLow(Symbol(), StructureTF, 5);
if (z.isDemand && Close[1] < nearbyLow) return true; // Swept low
if (!z.isDemand && Close[1] > nearbyHigh) return true; // Swept high
return false;
}
// Checklist 6: Premium/Discount (using Fib 50%)
bool IsInDiscountPremium(Zone &z, bool isDemand, bool isBullish) {
// Draw Fib from recent swing
double swingHigh = iHigh(Symbol(), StructureTF, iHighest(Symbol(), StructureTF, MODE_HIGH, 50, 1));
double swingLow = iLow(Symbol(), StructureTF, iLowest(Symbol(), StructureTF, MODE_LOW, 50, 1));
double mid = swingLow + (swingHigh - swingLow) * FibLevel;
if (isBullish && isDemand && z.high < mid) return true; // Demand in Discount
if (isBullish && !isDemand && z.low > mid) return true; // Supply in Premium
if (!isBullish && !isDemand && z.low > mid) return true; // Supply in Premium
if (!isBullish && isDemand && z.high < mid) return true; // Demand in Discount
return false;
}
// Open Buy Order
void OpenBuyOrder() {
double sl = Ask - StopLossPips * Point;
double tp = Ask + TakeProfitPips * Point;
int ticket = OrderSend(Symbol(), OP_BUY, LotSize, Ask, Slippage, sl, tp, "SMC Buy", MagicNumber, 0, Blue);
}
// Open Sell Order
void OpenSellOrder() {
double sl = Bid + StopLossPips * Point;
double tp = Bid - TakeProfitPips * Point;
int ticket = OrderSend(Symbol(), OP_SELL, LotSize, Bid, Slippage, sl, tp, "SMC Sell", MagicNumber, 0, Red);
}
// Update touches and mitigated (call in OnTick or separate)
void UpdateZoneStatus() {
// Logic to count touches and mitigate if broken
// Omitted for brevity, add candle close check beyond zone
}