last ...
This commit is contained in:
@@ -26,6 +26,44 @@
|
||||
//
|
||||
// Definitions ...
|
||||
|
||||
//
|
||||
// Extensions ...
|
||||
void FillLiquidity(
|
||||
XOHCL &lBar,
|
||||
ENUM_X_DIRECTION lDir,
|
||||
XBoxZone &lq,
|
||||
datetime to //
|
||||
)
|
||||
{
|
||||
//
|
||||
// Normalize Args ...
|
||||
lq.Clean();
|
||||
to = NormalizeTime(to);
|
||||
|
||||
//
|
||||
// Validate Args ...
|
||||
bool has = lBar.IsValid() &&
|
||||
HasDirection(lDir);
|
||||
if (!has)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
lq.to = to;
|
||||
lq.dir = lDir;
|
||||
lq.type = "XLQ";
|
||||
lq.from = lBar.time;
|
||||
lq.symbol = lBar.symbol;
|
||||
lq.period = lBar.period;
|
||||
lq.upper = IsBullish(lDir)
|
||||
? lBar.GetDown()
|
||||
: lBar.high;
|
||||
lq.lower = IsBullish(lDir)
|
||||
? lBar.low
|
||||
: lBar.GetUp();
|
||||
}
|
||||
|
||||
//
|
||||
// Implementations ...
|
||||
class XCBarAnalyser : public XCBase
|
||||
@@ -2040,20 +2078,45 @@ class XCBarAnalyser : public XCBase
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check a Bar is a Trigger Box or Not ...
|
||||
*
|
||||
* @param bar: XOHCL instance Referernce, Specified Start Bar to Check ...
|
||||
* @param trigger: XBoxZone instance Reference, Holds Detected Trigger Bar ...
|
||||
* @param ob: XBoxZone instance Reference, Holds Detected Trigger Bar's OB ...
|
||||
* @param fvg: XBoxZone instance Reference, Holds Detected Trigger Bar's FVG ...
|
||||
* @param rLiquidity: XBoxZone instance Reference, Holds Detected Trigger Bar's Reversal Side Liquidity ...
|
||||
* @param fLiquidity: XBoxZone instance Reference, Holds Detected Trigger Bar's Following Side Liquidity ...
|
||||
* @param swingBar: XOHCL instance Referernce, Holds Detected Trigger Bar's Swing ...
|
||||
* @param loopback: int, Loopback Bars Count ...
|
||||
* @param maxAllowedRange: double, Max Allowed Trigger's OB Range ...
|
||||
* @param minAllowedBlockEdgeLength: int, Min Allowed Block Edge Validation Length ...
|
||||
* @param forceOBOppositBar: bool, Force OB to Start by Opposite Bar ...
|
||||
* @param forceFVGBarType: bool, Force FVG to Has Same Bar Type ...
|
||||
* @param forceGapBarBreakout: bool, Force Gap Bar Breakout OB Edge ...
|
||||
* @param forceHasSwingBar: bool, Force Has Swing Bar ...
|
||||
* @param forceHasLiquidity: bool, Force Has Following Liquidity ...
|
||||
* @param forceHasReversalLiquidity: bool, Force Has Reversal Liquidity ...
|
||||
*
|
||||
* @return ( bool )
|
||||
*/
|
||||
bool IsTrigger(
|
||||
XOHCL &bar,
|
||||
XBoxZone &box,
|
||||
XBoxZone &trigger,
|
||||
XBoxZone &ob,
|
||||
XBoxZone &fvg,
|
||||
XBoxZone &liquidity,
|
||||
XBoxZone &rLiquidity,
|
||||
XBoxZone &fLiquidity,
|
||||
XOHCL &swingBar,
|
||||
int loopback = 10,
|
||||
bool forceLiquidity = true,
|
||||
bool forceLiquidityUsed = true,
|
||||
bool forceEntryBar = true,
|
||||
bool forceEntryBarPower = true,
|
||||
bool forceFVGBarType = false,
|
||||
bool forceOBTwoBar = false //
|
||||
double maxAllowedRange = 0.0,
|
||||
int minAllowedBlockEdgeLength = 0,
|
||||
bool forceOBOppositBar = true,
|
||||
bool forceFVGBarType = true,
|
||||
bool forceGapBarBreakout = true,
|
||||
bool forceHasSwingBar = true,
|
||||
bool forceHasLiquidity = true,
|
||||
bool forceHasReversalLiquidity = true //
|
||||
)
|
||||
{
|
||||
//
|
||||
@@ -2063,9 +2126,10 @@ class XCBarAnalyser : public XCBase
|
||||
// Normalize Args ...
|
||||
ob.Clean();
|
||||
fvg.Clean();
|
||||
box.Clean();
|
||||
trigger.Clean();
|
||||
swingBar.Clean();
|
||||
liquidity.Clean();
|
||||
rLiquidity.Clean();
|
||||
fLiquidity.Clean();
|
||||
loopback = NormalizeInt(loopback, 5);
|
||||
|
||||
//
|
||||
@@ -2077,429 +2141,171 @@ class XCBarAnalyser : public XCBase
|
||||
}
|
||||
|
||||
//
|
||||
XOHCL pBar; // Previous of Provided Bar ...
|
||||
XOHCL iBar;
|
||||
XOHCL iPBar;
|
||||
int barIndex;
|
||||
int pBarIndex;
|
||||
ENUM_X_DIRECTION iDir;
|
||||
XOHCL pBar;
|
||||
XOHCL tmpBar;
|
||||
XOHCL tmpPBar;
|
||||
ENUM_X_DIRECTION iDir = X_DIRECTION_NONE;
|
||||
|
||||
//
|
||||
result = bar.GetPreviousBar(pBar);
|
||||
if (!result)
|
||||
|
||||
//
|
||||
// Detect Base Order Block ...
|
||||
result =
|
||||
result &&
|
||||
//
|
||||
// Order Block Detection ...
|
||||
IsOB(
|
||||
pBar,
|
||||
ob,
|
||||
forceFVGBarType,
|
||||
forceOBOppositBar //
|
||||
) &&
|
||||
//
|
||||
// Gap Detection ...
|
||||
IsFVG(
|
||||
pBar,
|
||||
fvg,
|
||||
forceFVGBarType //
|
||||
);
|
||||
if (result)
|
||||
{
|
||||
//
|
||||
ob.Clean();
|
||||
fvg.Clean();
|
||||
box.Clean();
|
||||
pBar.Clean();
|
||||
iBar.Clean();
|
||||
iPBar.Clean();
|
||||
swingBar.Clean();
|
||||
liquidity.Clean();
|
||||
|
||||
//
|
||||
return result;
|
||||
trigger = ob;
|
||||
trigger.type = "XTRG";
|
||||
}
|
||||
|
||||
//
|
||||
barIndex = bar.Index();
|
||||
pBarIndex = pBar.Index();
|
||||
// Reading Requirements ...
|
||||
|
||||
//
|
||||
// Loopback to Find a Block ...
|
||||
for (int i = pBarIndex; i < pBarIndex + loopback; i++)
|
||||
double points = GetPoints(bar.symbol);
|
||||
|
||||
//
|
||||
bool isBullish = ob.IsBullish();
|
||||
bool isBearish = ob.IsBearish();
|
||||
|
||||
//
|
||||
int toIDX = trigger.ToIndex();
|
||||
int fromIDX = trigger.FromIndex();
|
||||
|
||||
//
|
||||
// Validate Gaps Bar Breakeout ...
|
||||
if (result &&
|
||||
forceGapBarBreakout)
|
||||
{
|
||||
//
|
||||
// Inital IBar ...
|
||||
result = iBar.Init(
|
||||
bar.symbol,
|
||||
bar.period,
|
||||
i //
|
||||
);
|
||||
if (!result)
|
||||
{
|
||||
break;
|
||||
}
|
||||
// Extract Gap Bar ...
|
||||
tmpBar.Clean();
|
||||
tmpPBar.Clean();
|
||||
result =
|
||||
//
|
||||
// Retrieve Bars ...
|
||||
fvg.ToBar(tmpBar) &&
|
||||
tmpBar.GetPreviousBar(tmpPBar) &&
|
||||
//
|
||||
// Validate Gap Bar is Momentum Bar ...
|
||||
IsMomentum(
|
||||
tmpPBar,
|
||||
iDir,
|
||||
1 //
|
||||
) &&
|
||||
iDir == fvg.dir &&
|
||||
//
|
||||
// Validate ...
|
||||
(isBullish
|
||||
? tmpPBar.close > ob.upper
|
||||
: tmpPBar.close < ob.lower);
|
||||
|
||||
//
|
||||
// Detect Block ...
|
||||
result = IsOB(
|
||||
iBar,
|
||||
ob,
|
||||
forceFVGBarType,
|
||||
forceOBTwoBar //
|
||||
);
|
||||
tmpBar.Clean();
|
||||
tmpPBar.Clean();
|
||||
}
|
||||
|
||||
//
|
||||
// Validate Range ...
|
||||
if (result &&
|
||||
maxAllowedRange > 0)
|
||||
{
|
||||
//
|
||||
double range = ob.GetRange();
|
||||
result = range <= (maxAllowedRange * points);
|
||||
}
|
||||
|
||||
//
|
||||
// Validating Swing Bar ...
|
||||
if (result &&
|
||||
forceHasSwingBar)
|
||||
{
|
||||
//
|
||||
int swingIDX = -1;
|
||||
result = ob.FromBar(tmpBar);
|
||||
if (result)
|
||||
{
|
||||
//
|
||||
// Validate Block Last Bars ...
|
||||
XOHCL fromBar;
|
||||
XOHCL fromBarPrev;
|
||||
result = ob.FromBar(fromBar);
|
||||
result =
|
||||
result &&
|
||||
fromBar.GetPreviousBar(fromBarPrev);
|
||||
result =
|
||||
result &&
|
||||
(ob.IsBullish()
|
||||
? fromBarPrev.IsBearish()
|
||||
: fromBarPrev.IsBullish());
|
||||
// Detect Swing Bar Index ...
|
||||
if (isBullish)
|
||||
{
|
||||
swingIDX = tmpBar.FindLowestIndex(loopback, MODE_LOW);
|
||||
}
|
||||
else if (isBearish)
|
||||
{
|
||||
swingIDX = tmpBar.FindHighestIndex(loopback, MODE_HIGH);
|
||||
}
|
||||
result = IsValidIndex(swingIDX);
|
||||
if (result)
|
||||
{
|
||||
//
|
||||
// Detect FVG ...
|
||||
result = IsFVG(
|
||||
iBar,
|
||||
fvg,
|
||||
forceFVGBarType //
|
||||
// Initialize Swing Bar ...
|
||||
result = swingBar.Init(
|
||||
bar.symbol,
|
||||
bar.period,
|
||||
swingIDX //
|
||||
);
|
||||
if (result)
|
||||
{
|
||||
//
|
||||
box.Clone(ob);
|
||||
box.type = "XTRG";
|
||||
box.from = fromBarPrev.time;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
fromBar.Clean();
|
||||
fromBarPrev.Clean();
|
||||
}
|
||||
|
||||
//
|
||||
iBar.Clean();
|
||||
}
|
||||
iBar.Clean();
|
||||
|
||||
//
|
||||
// Validate Block Detected ...
|
||||
result = box.IsValid();
|
||||
if (!result)
|
||||
{
|
||||
//
|
||||
ob.Clean();
|
||||
fvg.Clean();
|
||||
box.Clean();
|
||||
pBar.Clean();
|
||||
iBar.Clean();
|
||||
iPBar.Clean();
|
||||
swingBar.Clean();
|
||||
liquidity.Clean();
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
int toIDX = box.ToIndex();
|
||||
int fromIDX = box.FromIndex();
|
||||
bool isBullish = box.IsBullish();
|
||||
bool isBearish = box.IsBearish();
|
||||
|
||||
//
|
||||
// Detect Swing Bar ...
|
||||
int swingBarIDX = -1;
|
||||
int swingLoopback = fromIDX - pBarIndex;
|
||||
if (isBullish)
|
||||
{
|
||||
//
|
||||
// Looking for Swing Low ...
|
||||
swingBarIDX = pBar.FindLowestIndex(swingLoopback, MODE_LOW);
|
||||
}
|
||||
else if (isBearish)
|
||||
{
|
||||
//
|
||||
// Looking for Swing High ...
|
||||
swingBarIDX = pBar.FindHighestIndex(swingLoopback, MODE_LOW);
|
||||
}
|
||||
result = IsValidIndex(swingBarIDX);
|
||||
if (!result)
|
||||
{
|
||||
//
|
||||
ob.Clean();
|
||||
fvg.Clean();
|
||||
box.Clean();
|
||||
pBar.Clean();
|
||||
iBar.Clean();
|
||||
iPBar.Clean();
|
||||
swingBar.Clean();
|
||||
liquidity.Clean();
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Initialize Swing Bar ...
|
||||
result = swingBar.Init(
|
||||
bar.symbol,
|
||||
bar.period,
|
||||
swingBarIDX //
|
||||
);
|
||||
if (!result)
|
||||
{
|
||||
//
|
||||
ob.Clean();
|
||||
fvg.Clean();
|
||||
box.Clean();
|
||||
pBar.Clean();
|
||||
iBar.Clean();
|
||||
iPBar.Clean();
|
||||
swingBar.Clean();
|
||||
liquidity.Clean();
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Update Trigger Box ...
|
||||
if (isBullish)
|
||||
{
|
||||
box.lower = MathMin(box.lower, swingBar.GetDown());
|
||||
}
|
||||
else if (isBearish)
|
||||
{
|
||||
box.upper = MathMin(box.upper, swingBar.GetUp());
|
||||
}
|
||||
|
||||
//
|
||||
// Now we Have to Check Spike from Swing Bar Next till Current Bar ...
|
||||
// To Validate Highs and Lows ...
|
||||
for (int i = pBarIndex; i < pBarIndex + (swingBarIDX - pBarIndex) - 1; i++)
|
||||
{
|
||||
//
|
||||
// Initialize iBar ...
|
||||
result = iBar.Init(
|
||||
bar.symbol,
|
||||
bar.period,
|
||||
i //
|
||||
);
|
||||
result =
|
||||
result &&
|
||||
iBar.GetPreviousBar(iPBar);
|
||||
if (!result)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
//
|
||||
// Since we Go Backward Bars from Current Bar ...
|
||||
// for Bullish: each Bar Low Must over Prev Bar Low ...
|
||||
// for Bearish: each Bar High Must Under Prev Bar High ...
|
||||
if (isBullish)
|
||||
{
|
||||
result = iBar.low > iPBar.low;
|
||||
}
|
||||
else if (isBearish)
|
||||
{
|
||||
result = iBar.high < iPBar.high;
|
||||
}
|
||||
if (!result)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
//
|
||||
iBar.Clean();
|
||||
iPBar.Clean();
|
||||
}
|
||||
iBar.Clean();
|
||||
iPBar.Clean();
|
||||
if (!result)
|
||||
{
|
||||
//
|
||||
ob.Clean();
|
||||
fvg.Clean();
|
||||
box.Clean();
|
||||
pBar.Clean();
|
||||
iBar.Clean();
|
||||
iPBar.Clean();
|
||||
swingBar.Clean();
|
||||
liquidity.Clean();
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// We Have to Make sure Bars until Spikes Closed ...
|
||||
// for Bullish: bars must Close Above box.upper ...
|
||||
// for Bearish: bars must Close Below box.lower ...
|
||||
for (int i = pBarIndex; i < toIDX; i++)
|
||||
{
|
||||
//
|
||||
// Initialize iBar ...
|
||||
result = iBar.Init(
|
||||
bar.symbol,
|
||||
bar.period,
|
||||
i //
|
||||
);
|
||||
result =
|
||||
result &&
|
||||
(isBullish
|
||||
? iBar.close > box.upper
|
||||
: iBar.close < box.lower);
|
||||
|
||||
//
|
||||
if (!result)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
//
|
||||
iBar.Clean();
|
||||
}
|
||||
iBar.Clean();
|
||||
if (!result)
|
||||
{
|
||||
//
|
||||
ob.Clean();
|
||||
fvg.Clean();
|
||||
box.Clean();
|
||||
pBar.Clean();
|
||||
iBar.Clean();
|
||||
iPBar.Clean();
|
||||
swingBar.Clean();
|
||||
liquidity.Clean();
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Now we Have to Detect Spike Breake Ruls ...
|
||||
// for Bullish: bar.low goes Below of pBar.low ...
|
||||
// for Bearish: bar.high goes Above of pBar.high ...
|
||||
if (isBullish)
|
||||
{
|
||||
result = bar.low < pBar.low;
|
||||
}
|
||||
else if (isBearish)
|
||||
{
|
||||
result = bar.high > pBar.high;
|
||||
}
|
||||
if (!result)
|
||||
{
|
||||
//
|
||||
ob.Clean();
|
||||
fvg.Clean();
|
||||
box.Clean();
|
||||
pBar.Clean();
|
||||
iBar.Clean();
|
||||
iPBar.Clean();
|
||||
swingBar.Clean();
|
||||
liquidity.Clean();
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Update Box ...
|
||||
if (isBullish)
|
||||
{
|
||||
box.upper = MathMax(box.upper, bar.GetDown());
|
||||
}
|
||||
else if (isBearish)
|
||||
{
|
||||
box.lower = MathMin(box.lower, bar.GetUp());
|
||||
}
|
||||
box.to = bar.time;
|
||||
|
||||
//
|
||||
toIDX = box.ToIndex();
|
||||
fromIDX = box.FromIndex();
|
||||
|
||||
//
|
||||
// Liquidity ...
|
||||
if (forceLiquidity)
|
||||
{
|
||||
//
|
||||
// Now we Have to Detect Liquidity Zone ...
|
||||
for (int i = fromIDX; i < fromIDX + loopback; i++)
|
||||
{
|
||||
//
|
||||
// Initialize iBar
|
||||
result = iBar.Init(
|
||||
bar.symbol,
|
||||
bar.period,
|
||||
i //
|
||||
);
|
||||
result =
|
||||
result &&
|
||||
IsRejected(
|
||||
iBar,
|
||||
iDir,
|
||||
false, // Force Bar Type ...
|
||||
true // Force Fibo Pressure ...
|
||||
) &&
|
||||
iDir == box.dir &&
|
||||
(isBullish
|
||||
? iBar.low < box.lower
|
||||
: iBar.high > box.upper);
|
||||
// Update Trigger Block based on Swing Bar ...
|
||||
result = swingBar.IsValid();
|
||||
if (result)
|
||||
{
|
||||
//
|
||||
// Filling Liquidity ...
|
||||
liquidity.dir = iDir;
|
||||
liquidity.to = box.to;
|
||||
liquidity.type = "XLQ";
|
||||
liquidity.from = iBar.time;
|
||||
liquidity.symbol = iBar.symbol;
|
||||
liquidity.period = iBar.period;
|
||||
liquidity.upper = isBullish
|
||||
? iBar.GetDown()
|
||||
: iBar.high;
|
||||
liquidity.lower = isBullish
|
||||
? iBar.low
|
||||
: iBar.GetUp();
|
||||
// Update From ...
|
||||
trigger.from = ((datetime)MathMin((int)trigger.from, (int)swingBar.time));
|
||||
|
||||
//
|
||||
result = liquidity.IsValid();
|
||||
if (result)
|
||||
// Update Edge ...
|
||||
if (isBullish)
|
||||
{
|
||||
break;
|
||||
trigger.lower = MathMin(trigger.lower, swingBar.GetDown());
|
||||
}
|
||||
else if (isBearish)
|
||||
{
|
||||
trigger.upper = MathMax(trigger.upper, swingBar.GetUp());
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
iBar.Clean();
|
||||
}
|
||||
iBar.Clean();
|
||||
result = liquidity.IsValid();
|
||||
if (!result)
|
||||
{
|
||||
//
|
||||
ob.Clean();
|
||||
fvg.Clean();
|
||||
box.Clean();
|
||||
pBar.Clean();
|
||||
iBar.Clean();
|
||||
iPBar.Clean();
|
||||
swingBar.Clean();
|
||||
liquidity.Clean();
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Check Liquidity Usage ...
|
||||
if (forceLiquidityUsed)
|
||||
tmpBar.Clean();
|
||||
}
|
||||
|
||||
//
|
||||
// Validate Min Block Edge ...
|
||||
if (result &&
|
||||
minAllowedBlockEdgeLength > 0)
|
||||
{
|
||||
//
|
||||
fromIDX = trigger.FromIndex();
|
||||
if (result)
|
||||
{
|
||||
//
|
||||
// now We have to Ensure Detected Liqudity is Used ...
|
||||
toIDX = box.ToIndex();
|
||||
fromIDX = liquidity.FromIndex();
|
||||
for (int i = fromIDX - 1; i >= toIDX; i--)
|
||||
// Looping Back ...
|
||||
for (int i = fromIDX; i < fromIDX + minAllowedBlockEdgeLength; i++)
|
||||
{
|
||||
//
|
||||
// Initialize iBar ...
|
||||
result = iBar.Init(
|
||||
// Initialize i Bar ...
|
||||
result = tmpBar.Init(
|
||||
bar.symbol,
|
||||
bar.period,
|
||||
i //
|
||||
@@ -2507,130 +2313,173 @@ class XCBarAnalyser : public XCBase
|
||||
result =
|
||||
result &&
|
||||
(isBullish
|
||||
? iBar.low < liquidity.upper
|
||||
: iBar.high > liquidity.lower);
|
||||
if (result)
|
||||
? tmpBar.low > trigger.lower
|
||||
: tmpBar.high > trigger.upper);
|
||||
if (!result)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
//
|
||||
iBar.Clean();
|
||||
tmpBar.Clean();
|
||||
}
|
||||
if (!result)
|
||||
{
|
||||
//
|
||||
ob.Clean();
|
||||
fvg.Clean();
|
||||
box.Clean();
|
||||
pBar.Clean();
|
||||
iBar.Clean();
|
||||
iPBar.Clean();
|
||||
swingBar.Clean();
|
||||
liquidity.Clean();
|
||||
result = tmpBar.IsValid();
|
||||
|
||||
//
|
||||
return result;
|
||||
//
|
||||
// Update Trigger Block ...
|
||||
if (result)
|
||||
{
|
||||
trigger.from = ((datetime)(MathMin((int)trigger.from, (int)tmpBar.time)));
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
tmpBar.Clean();
|
||||
}
|
||||
|
||||
//
|
||||
// Entry Bar ...
|
||||
if (forceEntryBar)
|
||||
// Validating Liquidity ...
|
||||
if (result &&
|
||||
(forceHasLiquidity ||
|
||||
forceHasReversalLiquidity))
|
||||
{
|
||||
//
|
||||
// Validate Bar is Not Opposit Powered Bar ...
|
||||
|
||||
//
|
||||
// Momentum ...
|
||||
bool isMomentum = IsMomentum(
|
||||
bar,
|
||||
iDir,
|
||||
1 //
|
||||
);
|
||||
bool isBullishMomentum =
|
||||
isMomentum &&
|
||||
IsBullish(iDir);
|
||||
bool isBearishMomentum =
|
||||
isMomentum &&
|
||||
IsBearish(iDir);
|
||||
|
||||
//
|
||||
// Engulfed ...
|
||||
bool isEngulfed = IsEngulfed(
|
||||
bar,
|
||||
iDir //
|
||||
);
|
||||
bool isBullishEngulfed =
|
||||
isEngulfed &&
|
||||
IsBullish(iDir);
|
||||
bool isBearishEngulfed =
|
||||
isEngulfed &&
|
||||
IsBearish(iDir);
|
||||
|
||||
//
|
||||
// Rejected ...
|
||||
bool isRejected = IsRejected(
|
||||
bar,
|
||||
iDir,
|
||||
false,
|
||||
true //
|
||||
);
|
||||
bool isBullishRejected =
|
||||
isRejected &&
|
||||
IsBullish(iDir);
|
||||
bool isBearishRejected =
|
||||
isRejected &&
|
||||
IsBearish(iDir);
|
||||
|
||||
//
|
||||
bool isBullishPowered =
|
||||
isBullishMomentum ||
|
||||
isBullishEngulfed ||
|
||||
isBullishRejected;
|
||||
|
||||
//
|
||||
bool isBearishPowered =
|
||||
isBearishMomentum ||
|
||||
isBearishEngulfed ||
|
||||
isBearishRejected;
|
||||
|
||||
//
|
||||
// Make Sure Entry Bar is a Valid Bar ...
|
||||
result =
|
||||
isBullish
|
||||
? !isBearishPowered && (!forceEntryBarPower
|
||||
? true
|
||||
: isBullishPowered)
|
||||
: !isBullishPowered && (!forceEntryBarPower
|
||||
? true
|
||||
: isBearishPowered);
|
||||
if (!result)
|
||||
// Try to Detect Liquidity ...
|
||||
toIDX = ob.ToIndex();
|
||||
for (int i = toIDX; i < toIDX + (loopback * 10); i++)
|
||||
{
|
||||
//
|
||||
ob.Clean();
|
||||
fvg.Clean();
|
||||
box.Clean();
|
||||
pBar.Clean();
|
||||
iBar.Clean();
|
||||
iPBar.Clean();
|
||||
swingBar.Clean();
|
||||
liquidity.Clean();
|
||||
// Initialize i Bar ...
|
||||
result = tmpBar.Init(
|
||||
bar.symbol,
|
||||
bar.period,
|
||||
i //
|
||||
);
|
||||
if (!result)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
// Detect Liquidity ...
|
||||
bool isRejected =
|
||||
result &&
|
||||
IsRejected(
|
||||
tmpBar,
|
||||
iDir,
|
||||
false, // Force Bar Type ...
|
||||
true // Force Fibo Pressure ...
|
||||
);
|
||||
bool isBullishRejected =
|
||||
isRejected &&
|
||||
IsBullish(iDir);
|
||||
bool isBearishRejected =
|
||||
isRejected &&
|
||||
IsBearish(iDir);
|
||||
|
||||
//
|
||||
// Validate Liquidities ...
|
||||
if (isBullish)
|
||||
{
|
||||
//
|
||||
if (isBullishRejected &&
|
||||
forceHasLiquidity &&
|
||||
!fLiquidity.IsValid() &&
|
||||
tmpBar.low < trigger.lower)
|
||||
{
|
||||
//
|
||||
// Filling Following Liquidity ...
|
||||
FillLiquidity(
|
||||
tmpBar,
|
||||
trigger.dir,
|
||||
fLiquidity,
|
||||
trigger.to //
|
||||
);
|
||||
}
|
||||
|
||||
//
|
||||
if (isBearishRejected &&
|
||||
!rLiquidity.IsValid() &&
|
||||
forceHasReversalLiquidity &&
|
||||
tmpBar.high > trigger.upper)
|
||||
{
|
||||
//
|
||||
// Filling Revrsal Liquidity ...
|
||||
FillLiquidity(
|
||||
tmpBar,
|
||||
Opposit(trigger.dir),
|
||||
rLiquidity,
|
||||
trigger.to //
|
||||
);
|
||||
}
|
||||
}
|
||||
else if (isBearish)
|
||||
{
|
||||
//
|
||||
if (isBearishRejected &&
|
||||
forceHasLiquidity &&
|
||||
!fLiquidity.IsValid() &&
|
||||
tmpBar.high > trigger.upper)
|
||||
{
|
||||
//
|
||||
// Filling Following Liquidity ...
|
||||
FillLiquidity(
|
||||
tmpBar,
|
||||
trigger.dir,
|
||||
fLiquidity,
|
||||
trigger.to //
|
||||
);
|
||||
}
|
||||
|
||||
//
|
||||
if (isBullishRejected &&
|
||||
!rLiquidity.IsValid() &&
|
||||
forceHasReversalLiquidity &&
|
||||
tmpBar.low < trigger.lower)
|
||||
{
|
||||
//
|
||||
// Filling Reversal Liquidity ...
|
||||
FillLiquidity(
|
||||
tmpBar,
|
||||
Opposit(trigger.dir),
|
||||
rLiquidity,
|
||||
trigger.to //
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
if ((!forceHasLiquidity
|
||||
? true
|
||||
: fLiquidity.IsValid()) &&
|
||||
(!forceHasReversalLiquidity
|
||||
? true
|
||||
: rLiquidity.IsValid()))
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
//
|
||||
tmpBar.Clean();
|
||||
}
|
||||
tmpBar.Clean();
|
||||
|
||||
//
|
||||
result = (!forceHasLiquidity
|
||||
? true
|
||||
: fLiquidity.IsValid()) &&
|
||||
(!forceHasReversalLiquidity
|
||||
? true
|
||||
: rLiquidity.IsValid());
|
||||
}
|
||||
|
||||
//
|
||||
// Cleanup Resources ...
|
||||
|
||||
//
|
||||
iBar.Clean();
|
||||
pBar.Clean();
|
||||
iPBar.Clean();
|
||||
swingBar.Clean();
|
||||
tmpBar.Clean();
|
||||
tmpPBar.Clean();
|
||||
|
||||
//
|
||||
if (!result)
|
||||
@@ -2638,9 +2487,13 @@ class XCBarAnalyser : public XCBase
|
||||
//
|
||||
ob.Clean();
|
||||
fvg.Clean();
|
||||
box.Clean();
|
||||
trigger.Clean();
|
||||
swingBar.Clean();
|
||||
liquidity.Clean();
|
||||
rLiquidity.Clean();
|
||||
fLiquidity.Clean();
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
Reference in New Issue
Block a user