No description
Find a file
2025-10-31 23:54:15 +00:00
.gitignore Initial commit 2025-10-31 23:53:21 +00:00
LICENSE Initial commit 2025-10-31 23:53:21 +00:00
README.md Update README.md 2025-10-31 23:54:15 +00:00

//+------------------------------------------------------------------+ //| LiquidityFibConfluenceEA_PRO.mq5 | //| 3-4AM & 10-11AM EST | 5M Sweep/FVG → 1M Fib 0.62/0.79 Entry | //| NAS100 ONLY | Visuals | Push | Screenshot | SL 100 pips | //+------------------------------------------------------------------+ #property copyright "Houssam El Fayda" #property link "https://x.ai" #property version "2.00" #property strict #property script_show_inputs

input double LotSize = 0.1; input int Slippage = 3; input int MagicNumber = 987654; input int StopLossPips = 100; input bool EnableDebug = true; input bool EnablePush = true; input bool EnableScreenshot = true; input color ArrowColorBuy = clrLime; input color ArrowColorSell = clrRed;

//--- Allowed symbols (NAS100 variants) string AllowedSymbols[] = {"NAS100", "US100", "USTEC", "NAS100.cash"};

//--- Time Zones datetime est_offset = -5 * 3600; // EST = UTC-5

//--- Global datetime last_bar_time = 0;

//+------------------------------------------------------------------+ //| Expert initialization | //+------------------------------------------------------------------+ int OnInit() { if(Period() != PERIOD_M1) { Alert("Attach this EA to a 1-MINUTE chart!"); return(INIT_FAILED); }

if(!IsNas100Symbol()) { Alert("This EA only works on NAS100 (US100, USTEC, NAS100.cash)"); return(INIT_FAILED); }

Print("LiquidityFibConfluenceEA_PRO initialized on ", _Symbol, " M1"); return(INIT_SUCCEEDED); }

//+------------------------------------------------------------------+ //| Expert tick function | //+------------------------------------------------------------------+ void OnTick() { if(!IsTradeTime()) return; if(!IsNewBar(PERIOD_M5)) return;

if(DetectLiquiditySweep() || DetectFVGHits()) { double fib_062, fib_079; if(GetFibLevels(fib_062, fib_079)) { double entry = 0; bool use_062 = CheckConfluence(fib_062); bool use_079 = CheckConfluence(fib_079);

     if(use_062) entry = fib_062;
     else if(use_079) entry = fib_079;
     else return;

     ENUM_ORDER_TYPE type = (Close[0] > entry) ? ORDER_TYPE_BUY : ORDER_TYPE_SELL;
     double sl = (type == ORDER_TYPE_BUY) ? entry - StopLossPips * _Point : entry + StopLossPips * _Point;
     double tp = GetNextStructureLevel(type);

     if(tp == 0) return;

     OpenPosition(type, entry, sl, tp);
  }

} }

//+------------------------------------------------------------------+ //| Check if symbol is NAS100 | //+------------------------------------------------------------------+ bool IsNas100Symbol() { for(int i = 0; i < ArraySize(AllowedSymbols); i++) if(StringFind(_Symbol, AllowedSymbols[i], 0) != -1) return true; return false; }

//+------------------------------------------------------------------+ //| Trade Time: 3-4 AM & 10-11 AM EST | //+------------------------------------------------------------------+ bool IsTradeTime() { datetime now = TimeCurrent(); datetime est = now + est_offset; int hour = TimeHour(est); return (hour >= 3 && hour < 4) || (hour >= 10 && hour < 11); }

//+------------------------------------------------------------------+ //| Detect 5M Liquidity Sweep | //+------------------------------------------------------------------+ bool DetectLiquiditySweep() { double high[], low[], close[]; if(CopyHigh(_Symbol, PERIOD_M5, 1, 3, high) <= 0 || CopyLow(_Symbol, PERIOD_M5, 1, 3, low) <= 0 || CopyClose(_Symbol, PERIOD_M5, 1, 3, close) <= 0) return false;

if(high[0] > high[1] && close[0] < high[1]) return true; // High sweep if(low[0] < low[1] && close[0] > low[1]) return true; // Low sweep return false; }

//+------------------------------------------------------------------+ //| Detect FVG Hit on 5M | //+------------------------------------------------------------------+ bool DetectFVGHits() { double high[], low[]; if(CopyHigh(_Symbol, PERIOD_M5, 1, 3, high) <= 0 || CopyLow(_Symbol, PERIOD_M5, 1, 3, low) <= 0) return false;

if(low[2] > high[0] || high[2] < low[0]) return true; return false; }

//+------------------------------------------------------------------+ //| Get Fib 0.62 & 0.79 from last 5M swing | //+------------------------------------------------------------------+ bool GetFibLevels(double &fib_062, double &fib_079) { double high[], low[]; if(CopyHigh(_Symbol, PERIOD_M5, 1, 25, high) <= 0 || CopyLow(_Symbol, PERIOD_M5, 1, 25, low) <= 0) return false;

int swing_i = -1; double swing_p = 0; bool is_high = true;

for(int i = 3; i < 20; i++) { if(high[i] > high[i-1] && high[i] > high[i+1] && high[i] > high[i-2] && high[i] > high[i+2]) { swing_i = i; swing_p = high[i]; is_high = true; break; } if(low[i] < low[i-1] && low[i] < low[i+1] && low[i] < low[i-2] && low[i] < low[i+2]) { swing_i = i; swing_p = low[i]; is_high = false; break; } } if(swing_i == -1) return false;

double base = is_high ? ArrayMinimum(low, swing_i, 12) : ArrayMaximum(high, swing_i, 12); if(base <= 0) return false;

double range = MathAbs(swing_p - base); fib_062 = is_high ? swing_p - 0.618 * range : swing_p + 0.618 * range; fib_079 = is_high ? swing_p - 0.786 * range : swing_p + 0.786 * range;

DrawFibLines(swing_p, base, fib_062, fib_079); return true; }

//+------------------------------------------------------------------+ //| Draw Fib Lines on Chart | //+------------------------------------------------------------------+ void DrawFibLines(double high, double low, double f062, double f079) { string name = "Fib_" + IntegerToString(TimeCurrent()); ObjectCreate(0, name, OBJ_TREND, 0, Time[10], high, Time[0], low); ObjectSetInteger(0, name, OBJPROP_COLOR, clrGray); ObjectSetInteger(0, name, OBJPROP_STYLE, STYLE_DOT); ObjectSetInteger(0, name, OBJPROP_WIDTH, 1);

string l062 = name + "_062"; string l079 = name + "_079"; ObjectCreate(0, l062, OBJ_HLINE, 0, 0, f062); ObjectCreate(0, l079, OBJ_HLINE, 0, 0, f079); ObjectSetInteger(0, l062, OBJPROP_COLOR, clrYellow); ObjectSetInteger(0, l079, OBJPROP_COLOR, clrOrange); ObjectSetString(0, l062, OBJPROP_TEXT, "Fib 0.62"); ObjectSetString(0, l079, OBJPROP_TEXT, "Fib 0.79"); }

//+------------------------------------------------------------------+ //| Check Confluence with PD Arrays | //+------------------------------------------------------------------+ bool CheckConfluence(double level) { double tol = 15 * _Point; double fvg = GetLastFVG(); double ob = GetLastOrderBlock(); double rb = GetLastRejectionBlock();

if(fvg > 0 && MathAbs(level - fvg) < tol) { DrawLabel("FVG", level, clrAqua); return true; } if(ob > 0 && MathAbs(level - ob) < tol) { DrawLabel("OB", level, clrGold); return true; } if(rb > 0 && MathAbs(level - rb) < tol) { DrawLabel("RB", level, clrPink); return true; } return false; }

//+------------------------------------------------------------------+ //| Get Last FVG | //+------------------------------------------------------------------+ double GetLastFVG() { double high[], low[]; if(CopyHigh(_Symbol, PERIOD_M5, 1, 5, high) <= 0 || CopyLow(_Symbol, PERIOD_M5, 1, 5, low) <= 0) return 0;

for(int i = 2; i < 4; i++) { if(low[i] > high[i-2]) return (low[i] + high[i-2]) / 2.0; if(high[i] < low[i-2]) return (high[i] + low[i-2]) / 2.0; } return 0; }

//+------------------------------------------------------------------+ //| Get Last Order Block | //+------------------------------------------------------------------+ double GetLastOrderBlock() { double o[], c[], h[], l[]; if(CopyOpen(_Symbol, PERIOD_M5, 1, 10, o) <= 0 || CopyClose(_Symbol, PERIOD_M5, 1, 10, c) <= 0 || CopyHigh(_Symbol, PERIOD_M5, 1, 10, h) <= 0 || CopyLow(_Symbol, PERIOD_M5, 1, 10, l) <= 0) return 0;

for(int i = 1; i < 8; i++) { double body = MathAbs(c[i] - o[i]); double range = h[i] - l[i]; if(body > 0.7 * range && range > 0) return (o[i] + c[i]) / 2.0; } return 0; }

//+------------------------------------------------------------------+ //| Get Last Rejection Block | //+------------------------------------------------------------------+ double GetLastRejectionBlock() { double o[], c[], h[], l[]; if(CopyOpen(_Symbol, PERIOD_M5, 1, 10, o) <= 0 || CopyClose(_Symbol, PERIOD_M5, 1, 10, c) <= 0 || CopyHigh(_Symbol, PERIOD_M5, 1, 10, h) <= 0 || CopyLow(_Symbol, PERIOD_M5, 1, 10, l) <= 0) return 0;

for(int i = 1; i < 8; i++) { double body = MathAbs(c[i] - o[i]); double uw = h[i] - MathMax(o[i], c[i]); double lw = MathMin(o[i], c[i]) - l[i]; if(uw > 2 * body || lw > 2 * body) return (o[i] + c[i]) / 2.0; } return 0; }

//+------------------------------------------------------------------+ //| Get Next 15M Structure (TP) | //+------------------------------------------------------------------+ double GetNextStructureLevel(ENUM_ORDER_TYPE type) { double high[], low[]; if(CopyHigh(_Symbol, PERIOD_M15, 0, 25, high) <= 0 || CopyLow(_Symbol, PERIOD_M15, 0, 25, low) <= 0) return 0;

double last_high = high[ArrayMaximum(high, 15)]; double last_low = low[ArrayMinimum(low, 15)];

return (type == ORDER_TYPE_BUY) ? last_low : last_high; }

//+------------------------------------------------------------------+ //| Open Position with Visuals, Push, Screenshot | //+------------------------------------------------------------------+ void OpenPosition(ENUM_ORDER_TYPE type, double entry, double sl, double tp) { if(PositionExists()) return;

MqlTradeRequest req; MqlTradeResult res; ZeroMemory(req); ZeroMemory(res);

req.action = TRADE_ACTION_DEAL; req.symbol = _Symbol; req.volume = LotSize; req.type = type; req.price = (type == ORDER_TYPE_BUY) ? SymbolInfoDouble(_Symbol, SYMBOL_ASK) : SymbolInfoDouble(_Symbol, SYMBOL_BID); req.sl = NormalizeDouble(sl, _Digits); req.tp = NormalizeDouble(tp, _Digits); req.deviation= Slippage; req.magic = MagicNumber; req.comment = "FibConfluencePRO";

if(!OrderSend(req, res)) { Print("OrderSend failed: ", GetLastError()); return; }

if(res.retcode == TRADE_RETCODE_DONE) { // === Visual Arrow === string arrow_name = "Entry_" + IntegerToString(res.order); ObjectCreate(0, arrow_name, OBJ_ARROW, 0, Time[0], req.price); ObjectSetInteger(0, arrow_name, OBJPROP_ARROWCODE, type == ORDER_TYPE_BUY ? 233 : 234); ObjectSetInteger(0, arrow_name, OBJPROP_COLOR, type == ORDER_TYPE_BUY ? ArrowColorBuy : ArrowColorSell); ObjectSetInteger(0, arrow_name, OBJPROP_WIDTH, 3);

  // === Label ===
  string label = "Trade_" + IntegerToString(res.order);
  ObjectCreate(0, label, OBJ_TEXT, 0, Time[0], req.price);
  ObjectSetString(0, label, OBJPROP_TEXT, (type == ORDER_TYPE_BUY ? "BUY" : "SELL") + 
                  " @ " + DoubleToString(req.price, _Digits));
  ObjectSetInteger(0, label, OBJPROP_COLOR, clrWhite);
  ObjectSetInteger(0, label, OBJPROP_FONTSIZE, 10);

  // === Push Notification ===
  if(EnablePush)
     SendNotification("NAS100 " + (type == ORDER_TYPE_BUY ? "BUY" : "SELL") +
                      " @ " + DoubleToString(req.price, _Digits) +
                      " | SL: " + DoubleToString(sl, _Digits) +
                      " | TP: " + DoubleToString(tp, _Digits));

  // === Screenshot ===
  if(EnableScreenshot)
  {
     string filename = "NAS100_" + (type == ORDER_TYPE_BUY ? "BUY" : "SELL") + 
                       "_" + TimeToString(TimeCurrent(), TIME_DATE|TIME_MINUTES) + ".png";
     StringReplace(filename, ":", "");
     ChartScreenShot(0, filename, 1920, 1080, ALIGN_CENTER);
  }

  Print("TRADE OPENED: ", EnumToString(type), " @ ", req.price, " | TP: ", tp);

} }

//+------------------------------------------------------------------+ //| Draw Label for PD Array | //+------------------------------------------------------------------+ void DrawLabel(string text, double price, color col) { string name = text + "_" + IntegerToString(Time[0]); ObjectCreate(0, name, OBJ_TEXT, 0, Time[5], price); ObjectSetString(0, name, OBJPROP_TEXT, text); ObjectSetInteger(0, name, OBJPROP_COLOR, col); ObjectSetInteger(0, name, OBJPROP_FONTSIZE, 9); }

//+------------------------------------------------------------------+ //| Check if position exists | //+------------------------------------------------------------------+ bool PositionExists() { for(int i = 0; i < PositionsTotal(); i++) { if(PositionGetSymbol(i) == _Symbol && PositionGetInteger(POSITION_MAGIC) == MagicNumber) return true; } return false; }

//+------------------------------------------------------------------+ //| New Bar Detection | //+------------------------------------------------------------------+ bool IsNewBar(ENUM_TIMEFRAMES tf) { datetime curr = iTime(_Symbol, tf, 0); if(curr != last_bar_time) { last_bar_time = curr; return true; } return false; }