Add CancelAllPendingNow: companion cleanup script to CloseAllNow

Needed today: root-caused the "trades are losing" report to a second,
deeper persistence bug -- gridPlaced (and the rest of SaveGridState's
GlobalVariable-based state) never reaches disk in this environment at
all (no .gvr file exists anywhere under the MT5 data dir). It survives
a same-process EA reinit (input edit) fine, but a full container
restart loses it completely, so every restart made every EA think no
grid was resting and place a fresh one on top of whatever was already
there, uncancelled. Confirmed via ~29 stacked pending orders on some
symbols spanning 24+ hours of normal hourly cycles, not just last
night's restarts -- this has likely been happening on every watchdog
restart for weeks.

Ran it today: cancelled 177 stacked/duplicate pending orders fleet-
wide, 0 remaining. Open positions untouched -- each EA's own OnTick
"Cycle closed?" check self-heals from an empty pending book and places
exactly one clean grid on its next tick.
This commit is contained in:
2026-08-11 10:46:28 -04:00
parent 6d0c0716fa
commit 36ae668706
+45
View File
@@ -0,0 +1,45 @@
//+------------------------------------------------------------------+
//| CancelAllPendingNow.mq5 |
//| One-shot utility: cancel every pending order on the account. |
//| Open positions are left alone -- SL/trail/EA management is |
//| untouched. Companion to CloseAllNow.mq5 (which is the reverse: |
//| closes positions, leaves pendings). Written 2026-08-11 to clean |
//| up duplicate grid orders stacked by the gridPlaced GlobalVariable|
//| not surviving container restarts (see vault note on the |
//| persistence bug) -- each restart made every EA think no grid was|
//| resting and place a brand new one on top of the old, un- |
//| cancelled one. Safe to run any time: any EA that still has zero |
//| orders/positions after this will self-heal and place exactly |
//| one clean fresh grid on its own next tick (see OnTick's |
//| "Cycle closed?" branch). |
//+------------------------------------------------------------------+
#property copyright "Copyright 2026, Garfield Heron"
#property version "1.0"
#property script_show_inputs false
#include <Trade\Trade.mqh>
void OnStart()
{
CTrade trade;
ulong start = GetTickCount64();
int sweep = 0, cancelled = 0;
while(!IsStopped() && GetTickCount64() - start < 600000)
{
for(int i = OrdersTotal() - 1; i >= 0; i--)
{
ulong ticket = OrderGetTicket(i);
if(ticket == 0) continue;
if(trade.OrderDelete(ticket))
cancelled++;
}
if(OrdersTotal() == 0) break;
sweep++;
if(sweep % 5 == 1)
Print("CancelAllPendingNow: sweep ", sweep, " — ", OrdersTotal(), " still pending, retrying...");
Sleep(3000);
}
Print("CancelAllPendingNow: DONE — cancelled ", cancelled, ", remaining ", OrdersTotal(),
". Equity=", DoubleToString(AccountInfoDouble(ACCOUNT_EQUITY), 2),
" Balance=", DoubleToString(AccountInfoDouble(ACCOUNT_BALANCE), 2));
}