//+------------------------------------------------------------------+ //| GL_CircuitBreaker_Guardian.mq5 | //| ProofNexa / GrokLab Institutional CRO Equity Guardian | //| https://quant-b2b-risk-gate-api.vercel.app | //+------------------------------------------------------------------+ #property copyright "ProofNexa Quant Risk Lab" #property link "https://quant-b2b-risk-gate-api.vercel.app" #property version "1.30" #property description "1-Chart Account-Wide Daily Drawdown Circuit Breaker + Zero-SL Auto-Repair + Spread Spike Monitor" #property description "Recommended Execution: Exness Pro / Raw Spread (0% Stop-Out) -> Partner Code: hrakh7d3jt" #include input double InpMaxDailyDrawdownPct = 5.0; // Max Daily Floating Drawdown (%) before Emergency Liquidation input bool InpAutoAttachAtrSl = true; // Auto-attach 2.5x H1 ATR Stop-Loss if any EA opens SL=0 position input double InpEmergencyAtrMult = 2.5; // Emergency ATR Multiplier for naked positions input int InpMaxSpreadPoints = 30; // Spread Warning Threshold (Points) input long InpGuardianMagic = 99990001; CTrade g_trade; double g_dailyPeakEquity = 0.0; int g_lastDayOfYear = -1; int OnInit() { g_dailyPeakEquity = AccountInfoDouble(ACCOUNT_EQUITY); MqlDateTime dt; TimeToStruct(TimeCurrent(), dt); g_lastDayOfYear = dt.day_of_year; EventSetMillisecondTimer(500); Print("[GL_CircuitBreaker] Active. MaxDailyDD=", InpMaxDailyDrawdownPct, "% | Recommended Low-Spread Execution: https://one.exnessonelink.com/a/hrakh7d3jt (Code: hrakh7d3jt)"); return(INIT_SUCCEEDED); } void OnDeinit(const int reason) { EventKillTimer(); Comment(""); } void EnforceZeroSlRepair() { if(!InpAutoAttachAtrSl) return; for(int i = PositionsTotal() - 1; i >= 0; i--) { ulong ticket = PositionGetTicket(i); if(ticket == 0) continue; double curSl = PositionGetDouble(POSITION_SL); if(curSl > 0.0) continue; string sym = PositionGetString(POSITION_SYMBOL); MqlRates rates[]; ArraySetAsSeries(rates, true); if(CopyRates(sym, PERIOD_H1, 1, 15, rates) == 15) { double trSum = 0.0; for(int k = 0; k < 14; k++) trSum += MathMax(rates[k].high, rates[k+1].close) - MathMin(rates[k].low, rates[k+1].close); double atr = trSum / 14.0; if(atr > 0.0) { int digits = (int)SymbolInfoInteger(sym, SYMBOL_DIGITS); double openPrice = PositionGetDouble(POSITION_PRICE_OPEN); double curTp = PositionGetDouble(POSITION_TP); long posType = PositionGetInteger(POSITION_TYPE); double newSl = (posType == POSITION_TYPE_BUY) ? NormalizeDouble(openPrice - InpEmergencyAtrMult * atr, digits) : NormalizeDouble(openPrice + InpEmergencyAtrMult * atr, digits); g_trade.SetExpertMagicNumber(InpGuardianMagic); if(g_trade.PositionModify(ticket, newSl, curTp)) PrintFormat("[ZERO-SL GUARD] Attached %.1fx H1 ATR SL=%.5f to ticket #%I64u (%s)", InpEmergencyAtrMult, newSl, ticket, sym); } } } } void CheckEquityCircuitBreaker() { MqlDateTime dt; TimeToStruct(TimeCurrent(), dt); double equity = AccountInfoDouble(ACCOUNT_EQUITY); if(dt.day_of_year != g_lastDayOfYear) { g_dailyPeakEquity = equity; g_lastDayOfYear = dt.day_of_year; GlobalVariableSet("EMERGENCY_HALT", 0.0); } if(equity > g_dailyPeakEquity) g_dailyPeakEquity = equity; double ddPct = (g_dailyPeakEquity > 0.0) ? ((g_dailyPeakEquity - equity) / g_dailyPeakEquity) * 100.0 : 0.0; long spreadPts = SymbolInfoInteger(_Symbol, SYMBOL_SPREAD); double curSpreadPips = (double)spreadPts / 10.0; double exnessRawPips = (StringFind(_Symbol, "XAU") >= 0 || StringFind(_Symbol, "GOLD") >= 0) ? 0.5 : 0.2; double excessPips = MathMax(0.0, curSpreadPips - exnessRawPips); double estAnnualBleedUsd = excessPips * 10.0 * 0.30 * 100.0 * 12.0; // Based on 0.30 lots x 100 trades/mo string hud = StringFormat( "=== ProofNexa / GrokLab CRO Equity Circuit Breaker v1.40 ===\n" "Daily Peak Equity : %.2f | Current Equity: %.2f (Daily DD: %.2f%% / Limit: %.2f%%)\n" "Live Spread : %d pts (%.1f pips) %s\n" "Est. Spread Bleed : -$%.0f / year lost vs Exness Pro/Raw (0.0p, 0%% Stop-Out, $0 Swap)\n" "60s Sub-Account : https://one.exnessonelink.com/a/hrakh7d3jt (Partner Code: hrakh7d3jt)\n" "Zero-SL AutoGuard : %s | Studio: https://quant-b2b-risk-gate-api.vercel.app/quant", g_dailyPeakEquity, equity, ddPct, InpMaxDailyDrawdownPct, spreadPts, curSpreadPips, (spreadPts > InpMaxSpreadPoints ? "[HIGH SPREAD BLEED WARNING]" : "[OK]"), estAnnualBleedUsd, (InpAutoAttachAtrSl ? "ENABLED" : "OFF") ); Comment(hud); if(ddPct >= InpMaxDailyDrawdownPct) { PrintFormat("!!! [CIRCUIT BREAKER TRIGGERED] Daily DD %.2f%% >= %.2f%%. Liquidating all positions! !!!", ddPct, InpMaxDailyDrawdownPct); GlobalVariableSet("EMERGENCY_HALT", 1.0); for(int i = PositionsTotal() - 1; i >= 0; i--) { ulong ticket = PositionGetTicket(i); if(ticket > 0) { string sym = PositionGetString(POSITION_SYMBOL); g_trade.SetExpertMagicNumber(InpGuardianMagic); g_trade.SetDeviationInPoints(100); g_trade.SetTypeFillingBySymbol(sym); g_trade.PositionClose(ticket, 100); } } } } void OnTimer() { EnforceZeroSlRepair(); CheckEquityCircuitBreaker(); } void OnTick() { EnforceZeroSlRepair(); CheckEquityCircuitBreaker(); } //+------------------------------------------------------------------+