fix: 3 duplicate trades in 1 second, London SELL fired against established bullish bias
This commit is contained in:
+54
-17
@@ -5,7 +5,7 @@
|
||||
//| Based on: ORB-All-Sessions.pine + LuxAlgo Order Block Detector |
|
||||
//+------------------------------------------------------------------+
|
||||
#property copyright "NANDR"
|
||||
#property version "1.33"
|
||||
#property version "1.34"
|
||||
#property strict
|
||||
|
||||
#include <Trade\Trade.mqh>
|
||||
@@ -90,6 +90,7 @@ input bool InpWaitForRetest = true; // Wait for ORB Retest
|
||||
input int InpBreakoutExpireBars = 20; // Bars Before Breakout Expires (0=never)
|
||||
input bool InpUseOBRetestEntry = true; // OB Retest Entry (enter on OB boundary retest)
|
||||
input int InpMaxRetestsPerSession = 3; // Max Retest Entries Per Session (per breakout)
|
||||
input bool InpUseSessionBiasFilter = true; // Session Bias Filter: block signals against day bias
|
||||
|
||||
// --- Lot Size & Risk ---
|
||||
input group "═══ Lot Size & Risk ═══"
|
||||
@@ -155,19 +156,21 @@ struct SSession
|
||||
int breakoutBarsAgo;
|
||||
|
||||
int tradesThisSession;
|
||||
bool retestFiredThisBar; // blocks duplicate entries on consecutive ticks within same bar
|
||||
|
||||
void Reset()
|
||||
{
|
||||
orbHigh = 0;
|
||||
orbLow = DBL_MAX;
|
||||
orbBarCount = 0;
|
||||
orbComplete = false;
|
||||
orbStartTime = 0;
|
||||
breakoutDir = 0;
|
||||
inBreakout = false;
|
||||
inRetest = false;
|
||||
breakoutBarsAgo= 0;
|
||||
tradesThisSession = 0;
|
||||
orbHigh = 0;
|
||||
orbLow = DBL_MAX;
|
||||
orbBarCount = 0;
|
||||
orbComplete = false;
|
||||
orbStartTime = 0;
|
||||
breakoutDir = 0;
|
||||
inBreakout = false;
|
||||
inRetest = false;
|
||||
breakoutBarsAgo = 0;
|
||||
tradesThisSession = 0;
|
||||
retestFiredThisBar = false;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -209,6 +212,11 @@ SOrderBlock g_BearOBs[];
|
||||
int g_BullOBCount = 0;
|
||||
int g_BearOBCount = 0;
|
||||
|
||||
// Day bias: direction of the first confirmed ORB breakout of the day (0=none, 1=bull, -1=bear).
|
||||
// When InpUseSessionBiasFilter=true, subsequent session breakouts and all OB entries that
|
||||
// contradict this bias are suppressed, preventing counter-trend trades.
|
||||
int g_GlobalBiasDir = 0;
|
||||
|
||||
// Daily stats
|
||||
datetime g_LastDayReset = 0;
|
||||
int g_TodayTrades = 0;
|
||||
@@ -466,6 +474,10 @@ void UpdateORBSessions()
|
||||
double bar1High = iHigh(g_Symbol, PERIOD_CURRENT, 1);
|
||||
double bar1Low = iLow(g_Symbol, PERIOD_CURRENT, 1);
|
||||
|
||||
// New bar: clear per-bar retest flag so the next wick can trigger a fresh entry
|
||||
for(int s = 0; s < g_SessionCount; s++)
|
||||
g_Sessions[s].retestFiredThisBar = false;
|
||||
|
||||
for(int s = 0; s < g_SessionCount; s++)
|
||||
{
|
||||
if(!g_Sessions[s].enabled) continue;
|
||||
@@ -590,19 +602,35 @@ void DetectBreakouts()
|
||||
|
||||
if(bullBO)
|
||||
{
|
||||
// Bias filter: suppress if day bias is already bearish
|
||||
if(InpUseSessionBiasFilter && g_GlobalBiasDir == -1)
|
||||
{
|
||||
PrintFormat("NANDR EA: [%s] Bullish breakout SUPPRESSED — day bias is BEARISH",
|
||||
g_Sessions[s].name);
|
||||
continue;
|
||||
}
|
||||
g_Sessions[s].breakoutDir = 1;
|
||||
g_Sessions[s].inBreakout = true;
|
||||
g_Sessions[s].breakoutBarsAgo= 0;
|
||||
PrintFormat("NANDR EA: [%s] Bullish ORB breakout at %.2f",
|
||||
g_Sessions[s].name, g_Sessions[s].orbHigh);
|
||||
if(g_GlobalBiasDir == 0) g_GlobalBiasDir = 1; // first breakout of the day sets bias
|
||||
PrintFormat("NANDR EA: [%s] Bullish ORB breakout at %.2f [DayBias=%d]",
|
||||
g_Sessions[s].name, g_Sessions[s].orbHigh, g_GlobalBiasDir);
|
||||
}
|
||||
else if(bearBO)
|
||||
{
|
||||
// Bias filter: suppress if day bias is already bullish
|
||||
if(InpUseSessionBiasFilter && g_GlobalBiasDir == 1)
|
||||
{
|
||||
PrintFormat("NANDR EA: [%s] Bearish breakout SUPPRESSED — day bias is BULLISH",
|
||||
g_Sessions[s].name);
|
||||
continue;
|
||||
}
|
||||
g_Sessions[s].breakoutDir = -1;
|
||||
g_Sessions[s].inBreakout = true;
|
||||
g_Sessions[s].breakoutBarsAgo= 0;
|
||||
PrintFormat("NANDR EA: [%s] Bearish ORB breakout at %.2f",
|
||||
g_Sessions[s].name, g_Sessions[s].orbLow);
|
||||
if(g_GlobalBiasDir == 0) g_GlobalBiasDir = -1; // first breakout of the day sets bias
|
||||
PrintFormat("NANDR EA: [%s] Bearish ORB breakout at %.2f [DayBias=%d]",
|
||||
g_Sessions[s].name, g_Sessions[s].orbLow, g_GlobalBiasDir);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1056,6 +1084,10 @@ void CheckRetestEntriesTick()
|
||||
|
||||
if(dir == 0) continue;
|
||||
|
||||
// One entry per wick touch per bar — prevents 3 duplicate trades on consecutive ticks
|
||||
if(g_Sessions[s].retestFiredThisBar) continue;
|
||||
g_Sessions[s].retestFiredThisBar = true;
|
||||
|
||||
double obTop = 0, obBottom = 0;
|
||||
IsOBNearLevel(orbLevel, dir, obTop, obBottom);
|
||||
if(InpOBRequireConf && obTop == 0) continue;
|
||||
@@ -1066,8 +1098,9 @@ void CheckRetestEntriesTick()
|
||||
if(!InpUseOBRetestEntry) return;
|
||||
|
||||
// ── Bearish OB Retest → SELL at wick touch ───────────────────────
|
||||
// Fires the moment the current bar's live high reaches the OB bottom.
|
||||
// prev bar[1] (or current open) must have been at/below OB bottom.
|
||||
// Suppressed when day bias is bullish (session takes priority).
|
||||
if(InpUseSessionBiasFilter && g_GlobalBiasDir == 1) return;
|
||||
|
||||
for(int i = 0; i < g_BearOBCount; i++)
|
||||
{
|
||||
if(!g_BearOBs[i].active || g_BearOBs[i].traded) continue;
|
||||
@@ -1104,6 +1137,9 @@ void CheckRetestEntriesTick()
|
||||
}
|
||||
|
||||
// ── Bullish OB Retest → BUY at wick touch ────────────────────────
|
||||
// Suppressed when day bias is bearish (session takes priority).
|
||||
if(InpUseSessionBiasFilter && g_GlobalBiasDir == -1) return;
|
||||
|
||||
for(int i = 0; i < g_BullOBCount; i++)
|
||||
{
|
||||
if(!g_BullOBs[i].active || g_BullOBs[i].traded) continue;
|
||||
@@ -1275,6 +1311,7 @@ void CheckDailyReset()
|
||||
g_TodayPnL = 0;
|
||||
g_DayStartEquity = AccountInfoDouble(ACCOUNT_EQUITY);
|
||||
g_TradingHalted = false;
|
||||
g_GlobalBiasDir = 0; // clear day bias — first session breakout will re-establish it
|
||||
|
||||
// Reset all session ORB data for the new day
|
||||
for(int s = 0; s < g_SessionCount; s++)
|
||||
|
||||
Reference in New Issue
Block a user