fix: Use bar[1] (just-closed) and bar[2] (prior closed) everywhere
This commit is contained in:
+27
-25
@@ -5,7 +5,7 @@
|
||||
//| Based on: ORB-All-Sessions.pine + LuxAlgo Order Block Detector |
|
||||
//+------------------------------------------------------------------+
|
||||
#property copyright "NANDR"
|
||||
#property version "1.00"
|
||||
#property version "1.10"
|
||||
#property strict
|
||||
|
||||
#include <Trade\Trade.mqh>
|
||||
@@ -500,49 +500,48 @@ void UpdateORBSessions()
|
||||
//+------------------------------------------------------------------+
|
||||
bool CheckStrictBreakout(int dir, double orbLevel)
|
||||
{
|
||||
int N = g_BreakoutConfBars; // number of confirmation bars (already shifted)
|
||||
int N = g_BreakoutConfBars;
|
||||
if(N < 2) N = 2;
|
||||
|
||||
// Need at least N+1 bars of history
|
||||
// Need at least N+3 closed bars (all indices shifted +1 vs simple version)
|
||||
int bars = Bars(g_Symbol, PERIOD_CURRENT);
|
||||
if(bars < N + 2) return false;
|
||||
if(bars < N + 3) return false;
|
||||
|
||||
if(dir > 0) // bullish
|
||||
{
|
||||
// low[N] < orbLevel (pre-breakout penetration from below)
|
||||
// Then all N bars: low > orbLevel AND close > orbLevel
|
||||
// Current bar: close > low[1] AND low > orbLevel
|
||||
if(iLow(g_Symbol, PERIOD_CURRENT, N + 1) >= orbLevel) return false;
|
||||
for(int i = 1; i <= N; i++)
|
||||
if(iLow(g_Symbol, PERIOD_CURRENT, N + 2) >= orbLevel) return false;
|
||||
for(int i = 2; i <= N + 1; i++)
|
||||
{
|
||||
if(iLow(g_Symbol, PERIOD_CURRENT, i) <= orbLevel) return false;
|
||||
if(iClose(g_Symbol, PERIOD_CURRENT, i) <= orbLevel) return false;
|
||||
}
|
||||
if(iClose(g_Symbol, PERIOD_CURRENT, 0) <= iLow(g_Symbol, PERIOD_CURRENT, 1)) return false;
|
||||
if(iLow(g_Symbol, PERIOD_CURRENT, 0) <= orbLevel) return false;
|
||||
if(iClose(g_Symbol, PERIOD_CURRENT, 1) <= iLow(g_Symbol, PERIOD_CURRENT, 2)) return false;
|
||||
if(iLow(g_Symbol, PERIOD_CURRENT, 1) <= orbLevel) return false;
|
||||
return true;
|
||||
}
|
||||
else // bearish
|
||||
{
|
||||
if(iHigh(g_Symbol, PERIOD_CURRENT, N + 1) <= orbLevel) return false;
|
||||
for(int i = 1; i <= N; i++)
|
||||
if(iHigh(g_Symbol, PERIOD_CURRENT, N + 2) <= orbLevel) return false;
|
||||
for(int i = 2; i <= N + 1; i++)
|
||||
{
|
||||
if(iHigh(g_Symbol, PERIOD_CURRENT, i) >= orbLevel) return false;
|
||||
if(iClose(g_Symbol, PERIOD_CURRENT, i) >= orbLevel) return false;
|
||||
}
|
||||
if(iClose(g_Symbol, PERIOD_CURRENT, 0) >= iHigh(g_Symbol, PERIOD_CURRENT, 1)) return false;
|
||||
if(iHigh(g_Symbol, PERIOD_CURRENT, 0) >= orbLevel) return false;
|
||||
if(iClose(g_Symbol, PERIOD_CURRENT, 1) >= iHigh(g_Symbol, PERIOD_CURRENT, 2)) return false;
|
||||
if(iHigh(g_Symbol, PERIOD_CURRENT, 1) >= orbLevel) return false;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| Simple breakout: close crosses ORB level |
|
||||
//| Simple breakout: uses bar[1] (just-closed) vs bar[2] |
|
||||
//| Matches Pine Script bar-close evaluation — never checks an |
|
||||
//| in-progress candle so no premature signals at bar open. |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CheckSimpleBreakout(int dir, double orbLevel)
|
||||
{
|
||||
double c0 = iClose(g_Symbol, PERIOD_CURRENT, 0);
|
||||
double c1 = iClose(g_Symbol, PERIOD_CURRENT, 1);
|
||||
double c0 = iClose(g_Symbol, PERIOD_CURRENT, 1); // just-closed bar
|
||||
double c1 = iClose(g_Symbol, PERIOD_CURRENT, 2); // bar before it
|
||||
if(dir > 0) return (c1 <= orbLevel && c0 > orbLevel);
|
||||
else return (c1 >= orbLevel && c0 < orbLevel);
|
||||
}
|
||||
@@ -591,12 +590,15 @@ bool DetectRetest(int sessIdx, int &dir)
|
||||
{
|
||||
if(!g_Sessions[sessIdx].inBreakout) return false;
|
||||
|
||||
double c0 = iClose(g_Symbol, PERIOD_CURRENT, 0);
|
||||
double c1 = iClose(g_Symbol, PERIOD_CURRENT, 1);
|
||||
double h0 = iHigh(g_Symbol, PERIOD_CURRENT, 0);
|
||||
double l0 = iLow(g_Symbol, PERIOD_CURRENT, 0);
|
||||
// Use bar[1] (just-closed bar) as the retest candidate and bar[2] as context.
|
||||
// This mirrors Pine Script: decisions only on completed candles, never on bar[0]
|
||||
// which is only the opening price at new-bar time.
|
||||
double c0 = iClose(g_Symbol, PERIOD_CURRENT, 1); // just-closed bar
|
||||
double c1 = iClose(g_Symbol, PERIOD_CURRENT, 2); // bar before it
|
||||
double h0 = iHigh(g_Symbol, PERIOD_CURRENT, 1);
|
||||
double l0 = iLow(g_Symbol, PERIOD_CURRENT, 1);
|
||||
|
||||
// Bullish retest: previous bar was above ORB, this bar touched it and closed back above
|
||||
// Bullish retest: bar[2] confirmed above ORB high, bar[1] dipped to ORB and closed back above
|
||||
if(g_Sessions[sessIdx].breakoutDir == 1)
|
||||
{
|
||||
bool retest = (c1 > g_Sessions[sessIdx].orbHigh)
|
||||
@@ -604,7 +606,7 @@ bool DetectRetest(int sessIdx, int &dir)
|
||||
&& (c0 >= g_Sessions[sessIdx].orbHigh);
|
||||
if(retest) { dir = 1; return true; }
|
||||
}
|
||||
// Bearish retest: previous bar was below ORB, this bar touched it and closed back below
|
||||
// Bearish retest: bar[2] confirmed below ORB low, bar[1] ticked back to ORB and closed back below
|
||||
else if(g_Sessions[sessIdx].breakoutDir == -1)
|
||||
{
|
||||
bool retest = (c1 < g_Sessions[sessIdx].orbLow)
|
||||
@@ -613,7 +615,7 @@ bool DetectRetest(int sessIdx, int &dir)
|
||||
if(retest) { dir = -1; return true; }
|
||||
}
|
||||
|
||||
// Failed retest
|
||||
// Failed retest — only on a COMPLETED bar, never on bar open
|
||||
if(g_Sessions[sessIdx].breakoutDir == 1
|
||||
&& c0 < g_Sessions[sessIdx].orbHigh && c1 > g_Sessions[sessIdx].orbHigh)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user