diff --git a/NANDR_ORB_OB_EA.mq5 b/NANDR_ORB_OB_EA.mq5 index c63e3ed..3b4d67b 100644 --- a/NANDR_ORB_OB_EA.mq5 +++ b/NANDR_ORB_OB_EA.mq5 @@ -5,7 +5,7 @@ //| Based on: ORB-All-Sessions.pine + LuxAlgo Order Block Detector | //+------------------------------------------------------------------+ #property copyright "NANDR" -#property version "1.30" +#property version "1.31" #property strict #include @@ -94,7 +94,7 @@ input bool InpUseOBRetestEntry = true; // OB Retest Entry (ent input group "═══ Lot Size & Risk ═══" input ENUM_LOT_MODE InpLotMode = LOT_RISK_PERCENT; // Lot Mode input double InpFixedLotSize = 0.05; // Fixed Lot Size -input double InpRiskPercent = 1.0; // Risk % per Trade +input double InpRiskPercent = 0.05; // Risk % per Trade // --- Stop Loss --- input group "═══ Stop Loss ═══" @@ -304,6 +304,20 @@ double CalcLotSize(double slPips) return NormalizeLot(InpFixedLotSize); double lots = riskUSD / (slPips * pipValue); + + // Safety cap: never risk more than 5% of balance per trade regardless of settings. + // This prevents runaway lot sizes caused by an incorrect SL distance (e.g. pip size bug, + // misconfigured pips, or SL that is too tight). + double maxRiskUSD = balance * 5.0 / 100.0; + double maxSafeLots = maxRiskUSD / (slPips * pipValue); + if(lots > maxSafeLots) + { + PrintFormat("NANDR EA: WARNING — Computed lots %.2f exceeds 5%% risk cap. " + "Clamped to %.2f. Check SL pips (%.1f) and pip size (%.5f).", + lots, maxSafeLots, slPips, g_PipSize); + lots = maxSafeLots; + } + return NormalizeLot(lots); } @@ -1545,13 +1559,18 @@ int OnInit() } } - // Pip size (for XAUUSD: 1 pip = 0.1, i.e. 5-digit broker) + // Pip size: 1 pip = 10 points for all standard decimal counts (2, 3, 5). + // digits==2 (XAUUSD): point=0.01 → pip=0.10 → 100 pips = $10 price distance + // digits==3 (USDJPY): point=0.001 → pip=0.01 + // digits==5 (EURUSD): point=0.00001 → pip=0.0001 + // BUG FIX: digits==2 previously used g_PointSize directly (0.01) making 100 pips = $1.00, + // causing a near-zero SL and massively oversized lot on XAUUSD. double tickSize = SymbolInfoDouble(g_Symbol, SYMBOL_TRADE_TICK_SIZE); int digits = (int)SymbolInfoInteger(g_Symbol, SYMBOL_DIGITS); g_PointSize = SymbolInfoDouble(g_Symbol, SYMBOL_POINT); - // For XAUUSD with 2 decimal places, 1 pip = 0.01 (SYMBOL_POINT) - // For XAUUSD with 3 decimal places, 1 pip = 0.01 (10 points) - g_PipSize = (digits == 3 || digits == 5) ? g_PointSize * 10 : g_PointSize; + g_PipSize = (digits == 2 || digits == 3 || digits == 5) ? g_PointSize * 10 : g_PointSize; + PrintFormat("NANDR EA: PipSize=%.5f (digits=%d). 100 pips = %.2f price units.", + g_PipSize, digits, PipsToPrice(100)); // Initialize OB arrays ArrayResize(g_BullOBs, InpOBMaxCount); @@ -1596,11 +1615,24 @@ void OnDeinit(const int reason) Comment(""); } +//+------------------------------------------------------------------+ +//| Returns true if current server time is Saturday or Sunday | +//+------------------------------------------------------------------+ +bool IsWeekend() +{ + MqlDateTime dt; + TimeToStruct(TimeCurrent(), dt); + return (dt.day_of_week == 0 || dt.day_of_week == 6); // 0=Sunday, 6=Saturday +} + //+------------------------------------------------------------------+ //| OnTick | //+------------------------------------------------------------------+ void OnTick() { + // Silence all processing during weekend market closure + if(IsWeekend()) return; + // New bar detection datetime barTime = iTime(g_Symbol, PERIOD_CURRENT, 0); g_IsNewBar = (barTime != g_LastBarTime);