last ...
This commit is contained in:
@@ -4140,6 +4140,539 @@ class XCXCAEAHelper : XCBase
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
bool IsBlockBasedTriggerBar(
|
||||
XBoxZone &ob,
|
||||
XOHCL &swingBar,
|
||||
XOHCL &breakerBar,
|
||||
XOHCL &outSideBar,
|
||||
ENUM_X_DIRECTION &dir,
|
||||
int barIndex = 0,
|
||||
int loopback = 40,
|
||||
int swingLength = 3 //
|
||||
)
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
// Normalize Args ...
|
||||
ob.Clean();
|
||||
swingBar.Clean();
|
||||
breakerBar.Clean();
|
||||
outSideBar.Clean();
|
||||
dir = X_DIRECTION_NONE;
|
||||
barIndex = NormalizeInt(barIndex, 0);
|
||||
loopback = NormalizeInt(loopback, 30);
|
||||
|
||||
//
|
||||
// Initializing Current Bar ...
|
||||
XOHCL bar;
|
||||
result = bar.Init(
|
||||
GetSymbol(),
|
||||
GetPeriod(),
|
||||
barIndex //
|
||||
);
|
||||
if (!result)
|
||||
{
|
||||
//
|
||||
ob.Clean();
|
||||
bar.Clean();
|
||||
swingBar.Clean();
|
||||
breakerBar.Clean();
|
||||
outSideBar.Clean();
|
||||
dir = X_DIRECTION_NONE;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Detecting Newest Block ...
|
||||
XOHCL iBar;
|
||||
bool has = false;
|
||||
for (int i = barIndex; i < barIndex + loopback; i++)
|
||||
{
|
||||
//
|
||||
// Initialize iBar ...
|
||||
has = iBar.Init(
|
||||
bar.symbol,
|
||||
bar.period,
|
||||
i //
|
||||
);
|
||||
if (!has)
|
||||
{
|
||||
//
|
||||
iBar.Clean();
|
||||
|
||||
//
|
||||
continue;
|
||||
}
|
||||
|
||||
//
|
||||
// Check to Find OB ...
|
||||
has = barAnalyser.IsOrderBlock(
|
||||
iBar,
|
||||
ob,
|
||||
false,
|
||||
true //
|
||||
);
|
||||
if (has)
|
||||
{
|
||||
//
|
||||
iBar.Clean();
|
||||
|
||||
//
|
||||
break;
|
||||
}
|
||||
|
||||
//
|
||||
ob.Clean();
|
||||
iBar.Clean();
|
||||
}
|
||||
|
||||
//
|
||||
// Ensure We Have a Block ...
|
||||
result = ob.IsValid();
|
||||
if (!result)
|
||||
{
|
||||
//
|
||||
ob.Clean();
|
||||
bar.Clean();
|
||||
iBar.Clean();
|
||||
swingBar.Clean();
|
||||
breakerBar.Clean();
|
||||
outSideBar.Clean();
|
||||
dir = X_DIRECTION_NONE;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Set Direction ...
|
||||
dir = ob.dir;
|
||||
int toIDX = ob.ToIndex();
|
||||
int fromIDX = ob.FromIndex();
|
||||
bool isBullish = IsBullish(dir);
|
||||
bool isBearish = IsBearish(dir);
|
||||
|
||||
//
|
||||
// Ensure a Swing Breaked in Block Formation ...
|
||||
// for Bullish we have to Breake a Swing High ...
|
||||
// for Bearish we have to Detect a Swing Low ...
|
||||
// this Breaktion must appear after Block ...
|
||||
ENUM_X_DIRECTION swingDir = X_DIRECTION_NONE;
|
||||
for (int i = barIndex + loopback; i > barIndex; i--)
|
||||
{
|
||||
//
|
||||
// Initialize iBar ...
|
||||
has = iBar.Init(
|
||||
bar.symbol,
|
||||
bar.period,
|
||||
i //
|
||||
);
|
||||
if (!has)
|
||||
{
|
||||
//
|
||||
iBar.Clean();
|
||||
swingBar.Clean();
|
||||
swingDir = X_DIRECTION_NONE;
|
||||
|
||||
//
|
||||
continue;
|
||||
}
|
||||
|
||||
//
|
||||
// Detecting Swing ...
|
||||
has = barAnalyser.IsSwing(
|
||||
iBar,
|
||||
swingDir //
|
||||
);
|
||||
if (!has)
|
||||
{
|
||||
//
|
||||
iBar.Clean();
|
||||
swingBar.Clean();
|
||||
swingDir = X_DIRECTION_NONE;
|
||||
|
||||
//
|
||||
continue;
|
||||
}
|
||||
|
||||
//
|
||||
// Validate Founded Swing ...
|
||||
swingBar = iBar;
|
||||
|
||||
//
|
||||
bool isValidSwingLow =
|
||||
isBearish &&
|
||||
IsBullish(swingDir);
|
||||
|
||||
//
|
||||
bool isValidSwingHigh =
|
||||
isBullish &&
|
||||
IsBearish(swingDir);
|
||||
|
||||
//
|
||||
has =
|
||||
isValidSwingLow ||
|
||||
isValidSwingHigh;
|
||||
if (!has)
|
||||
{
|
||||
//
|
||||
iBar.Clean();
|
||||
swingBar.Clean();
|
||||
swingDir = X_DIRECTION_NONE;
|
||||
|
||||
//
|
||||
continue;
|
||||
}
|
||||
|
||||
//
|
||||
// Validating Swing Place ...
|
||||
|
||||
//
|
||||
bool isSwingLowHasValidPlace =
|
||||
isBearish &&
|
||||
swingBar.low < ob.lower;
|
||||
|
||||
//
|
||||
bool isSwingHighHasValidPlace =
|
||||
isBullish &&
|
||||
swingBar.high > ob.upper;
|
||||
|
||||
//
|
||||
has =
|
||||
isSwingLowHasValidPlace ||
|
||||
isSwingHighHasValidPlace;
|
||||
if (has)
|
||||
{
|
||||
//
|
||||
iBar.Clean();
|
||||
|
||||
//
|
||||
break;
|
||||
}
|
||||
|
||||
//
|
||||
iBar.Clean();
|
||||
swingBar.Clean();
|
||||
swingDir = X_DIRECTION_NONE;
|
||||
}
|
||||
|
||||
//
|
||||
result =
|
||||
swingBar.IsValid() &&
|
||||
HasDirection(swingDir);
|
||||
if (!result)
|
||||
{
|
||||
//
|
||||
ob.Clean();
|
||||
bar.Clean();
|
||||
iBar.Clean();
|
||||
swingBar.Clean();
|
||||
breakerBar.Clean();
|
||||
outSideBar.Clean();
|
||||
dir = X_DIRECTION_NONE;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// now We have Proper Swing ...
|
||||
// Validate Swing Breaktion ...
|
||||
double breakPrice =
|
||||
IsBullish(swingDir)
|
||||
? swingBar.low
|
||||
: swingBar.high;
|
||||
ENUM_X_DIRECTION breakedDir =
|
||||
IsBullish(swingDir)
|
||||
? X_DIRECTION_BEARISH
|
||||
: X_DIRECTION_BULLISH;
|
||||
for (int i = swingBar.Index(); i > barIndex; i--)
|
||||
{
|
||||
//
|
||||
// Initialize iBar ...
|
||||
has = iBar.Init(
|
||||
bar.symbol,
|
||||
bar.period,
|
||||
i //
|
||||
);
|
||||
if (!has)
|
||||
{
|
||||
//
|
||||
iBar.Clean();
|
||||
breakerBar.Clean();
|
||||
|
||||
//
|
||||
continue;
|
||||
}
|
||||
|
||||
//
|
||||
// Check for Breakes ...
|
||||
has = iBar.IsBreaked(
|
||||
breakPrice,
|
||||
breakedDir //
|
||||
);
|
||||
if (!has)
|
||||
{
|
||||
//
|
||||
iBar.Clean();
|
||||
breakerBar.Clean();
|
||||
|
||||
//
|
||||
continue;
|
||||
}
|
||||
|
||||
//
|
||||
// Validate Swing Break must be happens
|
||||
// after Block Formation ...
|
||||
has = iBar.time > ob.to;
|
||||
if (has)
|
||||
{
|
||||
//
|
||||
breakerBar = iBar;
|
||||
|
||||
//
|
||||
iBar.Clean();
|
||||
|
||||
//
|
||||
break;
|
||||
}
|
||||
|
||||
//
|
||||
iBar.Clean();
|
||||
breakerBar.Clean();
|
||||
}
|
||||
|
||||
//
|
||||
result = breakerBar.IsValid();
|
||||
if (!result)
|
||||
{
|
||||
//
|
||||
ob.Clean();
|
||||
bar.Clean();
|
||||
iBar.Clean();
|
||||
swingBar.Clean();
|
||||
breakerBar.Clean();
|
||||
outSideBar.Clean();
|
||||
dir = X_DIRECTION_NONE;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// now we have a Valid Bloc ...
|
||||
// which Breakes a Valid Swing ...
|
||||
|
||||
//
|
||||
// find at least on out side of Block Bar ...
|
||||
for (int i = toIDX; i > barIndex; i--)
|
||||
{
|
||||
//
|
||||
// Initialize iBar ...
|
||||
has = iBar.Init(
|
||||
bar.symbol,
|
||||
bar.period,
|
||||
i //
|
||||
);
|
||||
if (!has)
|
||||
{
|
||||
//
|
||||
iBar.Clean();
|
||||
outSideBar.Clean();
|
||||
|
||||
//
|
||||
continue;
|
||||
}
|
||||
|
||||
//
|
||||
bool isBullishOutside =
|
||||
isBullish &&
|
||||
iBar.high > ob.upper;
|
||||
|
||||
//
|
||||
bool isBearishOutside =
|
||||
isBearish &&
|
||||
iBar.low < ob.lower;
|
||||
|
||||
//
|
||||
has =
|
||||
isBullishOutside ||
|
||||
isBearishOutside;
|
||||
if (has)
|
||||
{
|
||||
//
|
||||
outSideBar = iBar;
|
||||
|
||||
//
|
||||
iBar.Clean();
|
||||
|
||||
//
|
||||
break;
|
||||
}
|
||||
|
||||
//
|
||||
iBar.Clean();
|
||||
outSideBar.Clean();
|
||||
}
|
||||
|
||||
//
|
||||
result = outSideBar.IsValid();
|
||||
if (!result)
|
||||
{
|
||||
//
|
||||
ob.Clean();
|
||||
bar.Clean();
|
||||
iBar.Clean();
|
||||
swingBar.Clean();
|
||||
breakerBar.Clean();
|
||||
outSideBar.Clean();
|
||||
dir = X_DIRECTION_NONE;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// we Are Looking for Bar inside Block ...
|
||||
|
||||
//
|
||||
bool isBullishInside =
|
||||
isBullish &&
|
||||
bar.low < ob.upper &&
|
||||
bar.low > ob.lower;
|
||||
|
||||
//
|
||||
bool isBearishInside =
|
||||
isBearish &&
|
||||
bar.high > ob.lower &&
|
||||
bar.high < ob.upper;
|
||||
|
||||
//
|
||||
result = isBullishInside ||
|
||||
isBearishInside;
|
||||
if (!result)
|
||||
{
|
||||
//
|
||||
ob.Clean();
|
||||
bar.Clean();
|
||||
iBar.Clean();
|
||||
swingBar.Clean();
|
||||
breakerBar.Clean();
|
||||
outSideBar.Clean();
|
||||
dir = X_DIRECTION_NONE;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Since we Ensure have an Inside Block Bar here ...
|
||||
// must to detect a Bar Pattern verification for Triggering ...
|
||||
|
||||
//
|
||||
// Check Bar Pattern for Position ...
|
||||
ENUM_X_DIRECTION patternDir;
|
||||
|
||||
//
|
||||
// Hammer ...
|
||||
bool isHammer = barAnalyser.IsHammer(
|
||||
bar,
|
||||
patternDir //
|
||||
);
|
||||
bool isBullishHammer =
|
||||
isHammer &&
|
||||
IsBullish(patternDir);
|
||||
bool isBearishHammer =
|
||||
isHammer &&
|
||||
IsBearish(patternDir);
|
||||
|
||||
//
|
||||
// Reject ...
|
||||
bool isReject = barAnalyser.IsRejected(
|
||||
bar,
|
||||
patternDir,
|
||||
false, // Force Bar type ...
|
||||
true // Force Fibo Pressure ...
|
||||
);
|
||||
bool isBullishReject =
|
||||
isReject &&
|
||||
IsBullish(patternDir);
|
||||
bool isBearishReject =
|
||||
isReject &&
|
||||
IsBearish(patternDir);
|
||||
|
||||
//
|
||||
// Engulf ...
|
||||
bool isEngulf = barAnalyser.IsEngulfed(
|
||||
bar,
|
||||
patternDir //
|
||||
);
|
||||
bool isBullishEngulf =
|
||||
isEngulf &&
|
||||
IsBullish(patternDir);
|
||||
bool isBearishEngulf =
|
||||
isEngulf &&
|
||||
IsBearish(patternDir);
|
||||
|
||||
//
|
||||
bool isBarBullishPowered =
|
||||
isBullishHammer ||
|
||||
isBullishReject ||
|
||||
isBullishEngulf;
|
||||
|
||||
//
|
||||
bool isBarBearishPowered =
|
||||
isBearishHammer ||
|
||||
isBearishReject ||
|
||||
isBearishEngulf;
|
||||
|
||||
//
|
||||
// Summarizing Result ...
|
||||
|
||||
//
|
||||
bool isBullishTriggered =
|
||||
isBullish &&
|
||||
isBullishInside &&
|
||||
isBarBullishPowered;
|
||||
|
||||
//
|
||||
bool isBearishTriggered =
|
||||
isBearish &&
|
||||
isBearishInside &&
|
||||
isBarBearishPowered;
|
||||
|
||||
//
|
||||
result = isBullishTriggered ||
|
||||
isBearishTriggered;
|
||||
|
||||
//
|
||||
if (!result)
|
||||
{
|
||||
//
|
||||
ob.Clean();
|
||||
bar.Clean();
|
||||
iBar.Clean();
|
||||
swingBar.Clean();
|
||||
breakerBar.Clean();
|
||||
outSideBar.Clean();
|
||||
dir = X_DIRECTION_NONE;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
bar.Clean();
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Protected ...
|
||||
protected:
|
||||
|
||||
@@ -962,7 +962,7 @@ bool DetectDecisionZone(
|
||||
|
||||
//
|
||||
// Custom Senarios ...
|
||||
|
||||
|
||||
//
|
||||
bool isCond1Bullish =
|
||||
//
|
||||
@@ -1627,6 +1627,126 @@ bool CanTriggerCond2(
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Detect Trigger Based On Decision Zone's
|
||||
// Block Based Triggering ...
|
||||
bool CanTriggerCond3(
|
||||
XCXCAEAHelper *helper,
|
||||
XBoxZone &box,
|
||||
ENUM_X_DIRECTION &dir,
|
||||
double &sl,
|
||||
double &tp,
|
||||
int barIndex = 0,
|
||||
int loopback = 10 //
|
||||
)
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
// Normalize Args ...
|
||||
sl = 0;
|
||||
tp = 0;
|
||||
dir = X_DIRECTION_NONE;
|
||||
loopback = NormalizeInt(loopback, 5);
|
||||
barIndex = NormalizeInt(barIndex, 0);
|
||||
|
||||
//
|
||||
// Validate Decision Box ...
|
||||
result = box.IsValid() &&
|
||||
helper != NULL;
|
||||
if (!result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Detect At Least one Outside Bar ...
|
||||
// TODO: Complete this ...
|
||||
|
||||
//
|
||||
// Add Support for a Breaked Swing as Liquidity ...
|
||||
// for Improve Validations ...
|
||||
// TODO: Complete this ...
|
||||
|
||||
//
|
||||
// Detect Block Based Trigger ...
|
||||
XBoxZone ob;
|
||||
XOHCL swing;
|
||||
XOHCL breaker;
|
||||
XOHCL outSide;
|
||||
ENUM_X_DIRECTION passedDir;
|
||||
bool isPassed = helper.IsBlockBasedTriggerBar(
|
||||
ob,
|
||||
swing,
|
||||
breaker,
|
||||
outSide,
|
||||
passedDir,
|
||||
barIndex + 1, // Bar Index ...
|
||||
30, // Loopback ...
|
||||
3 // Swing Length ...
|
||||
);
|
||||
bool isBullishPassed =
|
||||
isPassed &&
|
||||
ob.IsBullish() &&
|
||||
box.IsBullish() &&
|
||||
ob.upper < box.upper &&
|
||||
ob.lower > box.lower;
|
||||
bool isBearishPassed =
|
||||
isPassed &&
|
||||
ob.IsBearish() &&
|
||||
box.IsBearish() &&
|
||||
ob.upper < box.upper &&
|
||||
ob.lower > box.lower;
|
||||
|
||||
//
|
||||
// Summarizing ...
|
||||
|
||||
//
|
||||
bool canTriggerLong =
|
||||
isBullishPassed;
|
||||
|
||||
//
|
||||
bool canTriggerShort =
|
||||
isBearishPassed;
|
||||
|
||||
//
|
||||
result = canTriggerLong ||
|
||||
canTriggerShort;
|
||||
if (result)
|
||||
{
|
||||
//
|
||||
dir = canTriggerLong
|
||||
? X_DIRECTION_BULLISH
|
||||
: X_DIRECTION_BEARISH;
|
||||
|
||||
//
|
||||
// Preparing TP and SL ...
|
||||
|
||||
//
|
||||
sl = canTriggerLong
|
||||
? ob.lower
|
||||
: ob.upper;
|
||||
|
||||
//
|
||||
// Since Here TP Must Calculated
|
||||
// Using R2R we Ignore Target ...
|
||||
tp = 0;
|
||||
}
|
||||
|
||||
//
|
||||
// Cleanup Resources ...
|
||||
|
||||
//
|
||||
ob.Clean();
|
||||
swing.Clean();
|
||||
breaker.Clean();
|
||||
outSide.Clean();
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Helper Functions ...
|
||||
|
||||
|
||||
@@ -591,6 +591,7 @@ class XCXCAEASignaller : XCBase
|
||||
int ppIndex = pIndex + 1;
|
||||
|
||||
//
|
||||
bool has = false;
|
||||
int loopback = 10;
|
||||
|
||||
//
|
||||
@@ -618,16 +619,87 @@ class XCXCAEASignaller : XCBase
|
||||
double tp = 0;
|
||||
ENUM_X_DIRECTION triggerDir = X_DIRECTION_NONE;
|
||||
|
||||
//
|
||||
// Detect All Inside Directional FVGs ...
|
||||
XBoxZone fvgs[];
|
||||
int toIDX = conditions.decisionZone.ToIndex();
|
||||
int fromIDX = conditions.decisionZone.FromIndex();
|
||||
for (int i = fromIDX; i > toIDX; i--)
|
||||
{
|
||||
//
|
||||
XOHCL iBar;
|
||||
XBoxZone iFVG;
|
||||
|
||||
//
|
||||
// Initialize iBar ...
|
||||
has = iBar.Init(
|
||||
conditions.symbol,
|
||||
conditions.period,
|
||||
i //
|
||||
);
|
||||
if (!has)
|
||||
{
|
||||
//
|
||||
iFVG.Clean();
|
||||
iBar.Clean();
|
||||
|
||||
//
|
||||
continue;
|
||||
}
|
||||
|
||||
//
|
||||
// Check iBar has FVG ...
|
||||
has = helper
|
||||
.barAnalyser
|
||||
.IsFVG(
|
||||
iBar,
|
||||
iFVG,
|
||||
true //
|
||||
);
|
||||
if (!has)
|
||||
{
|
||||
//
|
||||
iBar.Clean();
|
||||
iFVG.Clean();
|
||||
|
||||
//
|
||||
continue;
|
||||
}
|
||||
|
||||
//
|
||||
// Check FVG Direction and Placement ...
|
||||
has =
|
||||
iFVG.dir == conditions.decisionZone.dir &&
|
||||
iFVG.upper < conditions.decisionZone.upper &&
|
||||
iFVG.lower > conditions.decisionZone.lower;
|
||||
if (has)
|
||||
{
|
||||
//
|
||||
iFVG.to = cTime;
|
||||
AddRef(
|
||||
iFVG,
|
||||
fvgs //
|
||||
);
|
||||
}
|
||||
|
||||
//
|
||||
iBar.Clean();
|
||||
iFVG.Clean();
|
||||
}
|
||||
bool hasFVGs = HasChild(fvgs);
|
||||
int fvgsCount = ArraySize(fvgs);
|
||||
|
||||
//
|
||||
// Checking Trigger Cond 0 ...
|
||||
bool canTriggerCond0 = CanTriggerCond0(
|
||||
helper,
|
||||
conditions.decisionZone,
|
||||
triggerDir,
|
||||
sl,
|
||||
tp,
|
||||
barIndex //
|
||||
);
|
||||
bool canTriggerCond0 = false;
|
||||
// CanTriggerCond0(
|
||||
// helper,
|
||||
// conditions.decisionZone,
|
||||
// triggerDir,
|
||||
// sl,
|
||||
// tp,
|
||||
// barIndex //
|
||||
// );
|
||||
|
||||
//
|
||||
// Checking Trigger Cond 1 ...
|
||||
@@ -653,13 +725,25 @@ class XCXCAEASignaller : XCBase
|
||||
// barIndex //
|
||||
// );
|
||||
|
||||
//
|
||||
// Checking Trigger Cond 3 ...
|
||||
bool canTriggerCond3 = CanTriggerCond3(
|
||||
helper,
|
||||
conditions.decisionZone,
|
||||
triggerDir,
|
||||
sl,
|
||||
tp,
|
||||
barIndex //
|
||||
);
|
||||
|
||||
//
|
||||
// Update Signal Box To ...
|
||||
conditions.decisionZone.to = cTime;
|
||||
|
||||
//
|
||||
// Draw Decision Zone ...
|
||||
XCBoxObject *iObj;
|
||||
bool has = helper.poiDrawer.DrawBox(
|
||||
has = helper.poiDrawer.DrawBox(
|
||||
conditions.decisionZone,
|
||||
iObj //
|
||||
);
|
||||
@@ -669,12 +753,37 @@ class XCXCAEASignaller : XCBase
|
||||
}
|
||||
ZeroMemory(iObj);
|
||||
|
||||
//
|
||||
// Draw FVGs ...
|
||||
if (hasFVGs)
|
||||
{
|
||||
//
|
||||
for (int i = 0; i < fvgsCount; i++)
|
||||
{
|
||||
//
|
||||
fvgs[i].to = cTime;
|
||||
|
||||
//
|
||||
XCBoxObject *iObj;
|
||||
has = helper.poiDrawer.DrawBox(
|
||||
fvgs[i],
|
||||
iObj //
|
||||
);
|
||||
if (has)
|
||||
{
|
||||
mObjects.Add(iObj);
|
||||
}
|
||||
ZeroMemory(iObj);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Summarizing Result ...
|
||||
result =
|
||||
canTriggerCond0 ||
|
||||
canTriggerCond1 ||
|
||||
canTriggerCond2;
|
||||
canTriggerCond2 ||
|
||||
canTriggerCond3;
|
||||
|
||||
//
|
||||
isBullish = result &&
|
||||
|
||||
Reference in New Issue
Block a user