Compare commits
2
Commits
6d0c0716fa
..
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
90f97606ea | ||
|
|
36ae668706 |
@@ -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));
|
||||||
|
}
|
||||||
@@ -5,12 +5,12 @@
|
|||||||
//+------------------------------------------------------------------+
|
//+------------------------------------------------------------------+
|
||||||
#property copyright "Copyright 2024, Garfield Heron"
|
#property copyright "Copyright 2024, Garfield Heron"
|
||||||
#property link "https://fetcherpay.com"
|
#property link "https://fetcherpay.com"
|
||||||
#property version "5.7"
|
#property version "5.8"
|
||||||
|
|
||||||
#include <Trade\Trade.mqh>
|
#include <Trade\Trade.mqh>
|
||||||
#include <Trade\PositionInfo.mqh>
|
#include <Trade\PositionInfo.mqh>
|
||||||
|
|
||||||
#define VERSION "Version 5.7 Smart Grid Breakout BO MT5"
|
#define VERSION "Version 5.8 Smart Grid Breakout BO MT5"
|
||||||
#define MAX_TRADES 600
|
#define MAX_TRADES 600
|
||||||
#define MAX_LOG_TRADES 1200
|
#define MAX_LOG_TRADES 1200
|
||||||
|
|
||||||
@@ -1078,6 +1078,35 @@ int CountPendingOrders(int type)
|
|||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// True if this symbol+magic already has any pending order or open position
|
||||||
|
// on the broker, regardless of what gridPlaced (GlobalVariable-backed,
|
||||||
|
// found 2026-08-11 to never actually reach disk in this environment) says.
|
||||||
|
// Used at OnInit to recover from a restart wiping that flag to false while
|
||||||
|
// a grid is still resting live -- without this check, every restart mid-
|
||||||
|
// cycle placed a brand new duplicate grid on top of the old one (see vault
|
||||||
|
// "2026-08-11 Duplicate Grid Orders" note; found 189 stacked pending
|
||||||
|
// orders account-wide, one symbol alone had 29 spanning 24+ hours).
|
||||||
|
bool HasLiveGridPresence()
|
||||||
|
{
|
||||||
|
for(int i = OrdersTotal() - 1; i >= 0; i--)
|
||||||
|
{
|
||||||
|
ulong ticket = OrderGetTicket(i);
|
||||||
|
if(ticket == 0) continue;
|
||||||
|
if(OrderGetString(ORDER_SYMBOL) != _Symbol) continue;
|
||||||
|
if(OrderGetInteger(ORDER_MAGIC) != MagicNum) continue;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
for(int i = PositionsTotal() - 1; i >= 0; i--)
|
||||||
|
{
|
||||||
|
ulong ticket = PositionGetTicket(i);
|
||||||
|
if(ticket == 0) continue;
|
||||||
|
if(PositionGetString(POSITION_SYMBOL) != _Symbol) continue;
|
||||||
|
if(PositionGetInteger(POSITION_MAGIC) != MagicNum) continue;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void CancelAllOrders(string reason)
|
void CancelAllOrders(string reason)
|
||||||
{
|
{
|
||||||
int cancelled = 0;
|
int cancelled = 0;
|
||||||
@@ -1351,6 +1380,20 @@ int OnInit()
|
|||||||
|
|
||||||
LoadGridState();
|
LoadGridState();
|
||||||
|
|
||||||
|
// Self-heal (2026-08-11): gridPlaced is GlobalVariable-backed and was
|
||||||
|
// found to never actually reach disk in this environment (no .gvr file
|
||||||
|
// anywhere under the MT5 data dir) — so a full container restart mid-
|
||||||
|
// cycle silently resets it to false while the grid is still resting
|
||||||
|
// live on the broker, and the code below would place a brand new
|
||||||
|
// duplicate grid on top of it. Trust reality over the flag: if this
|
||||||
|
// symbol+magic already has orders or positions out, we already have a
|
||||||
|
// grid, no matter what LoadGridState() just said.
|
||||||
|
if(!gridPlaced && HasLiveGridPresence())
|
||||||
|
{
|
||||||
|
PrintS("Self-heal: found existing orders/positions on init — recovering gridPlaced=true (see 2026-08-11 duplicate-grid fix)");
|
||||||
|
gridPlaced = true;
|
||||||
|
}
|
||||||
|
|
||||||
// GridHigh/GridLow are NOT persisted (only lastPivotCalcDate is) — if a
|
// GridHigh/GridLow are NOT persisted (only lastPivotCalcDate is) — if a
|
||||||
// prior process already recalculated today before this restart, the
|
// prior process already recalculated today before this restart, the
|
||||||
// date-match guard alone would skip CalculatePivotPoints() and leave the
|
// date-match guard alone would skip CalculatePivotPoints() and leave the
|
||||||
|
|||||||
Reference in New Issue
Block a user