Fixes the duplicate-grid bug found 2026-08-11: gridPlaced (and the
rest of SaveGridState's GlobalVariable-backed state) never reaches
disk in this environment -- confirmed no .gvr file exists anywhere
under the MT5 data dir. Every full container restart mid-cycle wiped
it back to false while a grid was still resting live on the broker,
and OnTick would place a brand new duplicate grid on top of the old,
uncancelled one. Found 189 stacked pending orders account-wide before
cleanup (CancelAllPendingNow.mq5), one symbol alone had 29 spanning
24+ hours of normal cycles -- this has likely been happening on every
watchdog restart for weeks, not just from that day's testing.
Adds HasLiveGridPresence(): checks actual OrdersTotal()/PositionsTotal()
for this symbol+magic. At OnInit, if gridPlaced reads false but real
orders or positions already exist, trust reality over the flag and
recover gridPlaced=true -- so a restart mid-cycle can no longer cause
a duplicate placement, regardless of whether GlobalVariable persistence
ever gets fixed underneath. Deployed and recompiled live (all 14 EAs
confirmed reinitialized as v5.8); not yet validated against a live
container-restart cycle given the risk of disrupting the account
further right after cleanup -- logic mirrors the existing broker-state
query pattern already used in OnTick's monitor branch.
GridHigh/GridLow are never persisted (only lastPivotCalcDate is), so if
two restarts land close together near a server-day boundary, a fresh
process can find lastPivotCalcDate already matching 'today' and skip
CalculatePivotPoints() entirely -- leaving the band at its uninitialized
0/0 and every IsRangingMarket() check failing 'Invalid grid bounds' until
the next real day rollover. Cost XAUUSD/XAGUSD ~17h of dead trading on
2026-07-23 after the drift-enable and sizing deploys landed back-to-back.
Fix: both the OnInit guard and the OnTick day-rollover guard now also
recalc when GridHigh<=0 || GridLow<=0, regardless of date match. The
OnTick path recalcs only (no cancel/reset side effects) when it's the
same-day self-heal case, since that's not a real day transition.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Wind-down (Thu 19:00 server = Thu noon ET -> weekend close): cancel
entry pendings, no new grids, trail tightened to 200/150pts so open
positions walk out at their natural end instead of being chopped at the
midnight deadline. Hard close unchanged as backstop.
Shadow metric: first tick of each new server week, every EA reports what
its weekend-flattened positions would have done through Friday (MTM at
Friday's last H1 close + worst adverse excursion) — quantifies the cost
of the no-Friday policy from live data.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The ea-watchdog inferred tick starvation from expert-log silence, but a
stable placed grid is also silent — it restart-looped the container 11
times on Jul 15-16. The heartbeat fires on any tick once per hour before
every gate (weekend block, stand-down, drawdown), so silence >1h during
market hours now unambiguously means a dead chart feed.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
100 pips was reachable on metals only — FX winners kept cycle-closing
before the trail engaged (GBPUSD +70 pips Jul 15 had an unmoved SL).
Input renamed InpTrailStart -> InpTrailStartPoints so every chart picks
up the new 500 default on recompile without per-chart preset reloads;
metal presets set it back to 1000 explicitly.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Monday's pivots and ATR are built from Friday's session and the first
server hours are the thin Sunday-evening ET market — historically the
only losing weekday (-$121 across 204 trades vs all other days
positive). New CheckMondayStandDown() blocks new grids on Monday
before InpMondayStartHour (default 7 = midnight ET), and because it
sits above the daily pivot recalc, Monday's pivots/ATR are sampled at
the resume hour instead of the rollover. All 17 presets set
InpMondayStartHour=7. Trading week is now Mon 00:00 ET -> Fri 00:00 ET.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
CheckWeekendProtection previously returned true after the one-shot
weekend close, so the EA resumed placing new grids for the rest of
Friday. Now it stays blocked until the next trading day and keeps
sweeping stray positions/pendings while blocked.
All 17 presets: InpWeekendCloseHour 17 -> 7 (server UTC+3), closing
everything at Friday 07:00 server = Thursday midnight ET, per the
no-weekend-carry policy.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
ApplyTrailingStop() runs every 5s on open positions: activates after
1000 pts (100 pips) of profit, trails SL 500 pts (50 pips) behind price.
SL only moves in the profitable direction, never backwards.
New inputs: InpUseTrailingStop, InpTrailStart, InpTrailStop (all presets
set to true/1000/500). EA version bumped 5.0 → 5.1.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Breakout variant of the Smart Grid: uses BUY_STOP/SELL_STOP orders
above resistance and below support rather than mean-reversion limits.
Only trades when trending (ADX filter inverted vs. Grid EA), cancels
orders when market returns to range. Mandatory SL on all presets.
Includes 17 .set files: 3 templates (major/volatile/steady) and 14
per-pair presets covering all Grid EA pairs plus EURCHF, EURGBP,
AUDNZD, XAUUSD, XAGUSD.
First live week (Jun 22–26): +$84.71 from 8 completed cycles.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>