last ...
This commit is contained in:
@@ -21,9 +21,9 @@
|
||||
|
||||
//
|
||||
// Imports ...
|
||||
#include "../Libraries/xcatbea.lib.mq5"
|
||||
#include "../../Classes/x-saherelm.x-bar.analyser.class.mq5"
|
||||
#include "../../Classes/x-saherelm.x-poi.drawer.class.mq5"
|
||||
#include "../Libraries/xcatbea.lib.mq5"
|
||||
|
||||
//
|
||||
// Definiions ...
|
||||
@@ -145,12 +145,13 @@ struct XTriggerBlockValidationRules
|
||||
bool forceOBBarType; // Force Order Block to Has InDirectional Bars ...
|
||||
int minRequiredOBBar; // Min Required OB Bar ...
|
||||
bool forceFVGBarType; // Force Fair Value Gaps Bars Type ...
|
||||
int liquidityLoopback; // Liquidity Detection Loopback ...
|
||||
double maxAllowedRange; // Max Allowed Order Block Range ...
|
||||
double minAllowedRange; // Min Allowed Order Block Range ...
|
||||
bool forceHasFLiquidity; // Force Order Block To Has Reversal Liquidity ...
|
||||
bool forceHasRLiquidity; // Force Order Block to Has Following Liquidity ...
|
||||
int liquidityLoopback; // Liquidity Detection Loopback ...
|
||||
bool validateGapSequence; // Validate Fair Value Gaps Bar Sequences ...
|
||||
int minAllowedBlockLength; // Min Allowed Block Length ...
|
||||
bool validateBlockEdgeBreakout; // Validate Order Block Edge Breakeout ...
|
||||
|
||||
//
|
||||
@@ -175,6 +176,7 @@ struct XTriggerBlockValidationRules
|
||||
forceHasSwing = false;
|
||||
forceOBBarType = false;
|
||||
forceFVGBarType = false;
|
||||
minAllowedBlockLength = 0;
|
||||
forceHasFLiquidity = false;
|
||||
forceHasRLiquidity = false;
|
||||
validateGapSequence = false;
|
||||
@@ -203,7 +205,11 @@ struct XTriggerBlockFilters
|
||||
bool filterBasedOnHKSignalBar; // Filter Based On HK Signal Bar ...
|
||||
|
||||
//
|
||||
int bosLoopback; // PV Based Filtering BOS Lookup ...
|
||||
int bosLoopback; // PV Based Filtering BOS Lookup ...
|
||||
bool forceSarSwitched; // SAR Switched on Sides for Filtering ...
|
||||
bool forceSarOnBothSide; // SAR Check on Both Sides for Filtering ...
|
||||
bool forceSarHasBreakout; // SAR Must Has Reversal Direction in Trigger Block ...
|
||||
bool forceSarHasReversalSide; // SAR Must Has Reversal Direction in Trigger Block ...
|
||||
|
||||
//
|
||||
// Constructor(s) ...
|
||||
@@ -233,6 +239,10 @@ struct XTriggerBlockFilters
|
||||
|
||||
//
|
||||
bosLoopback = 0;
|
||||
forceSarSwitched = false;
|
||||
forceSarOnBothSide = false;
|
||||
forceSarHasBreakout = false;
|
||||
forceSarHasReversalSide = false;
|
||||
|
||||
//
|
||||
ZeroMemory(this);
|
||||
@@ -409,6 +419,7 @@ bool DetectTriggerBlock1(
|
||||
// validations.liquidityLoopback = 144;
|
||||
// validations.forceHasFLiquidity = true;
|
||||
// validations.forceHasRLiquidity = true;
|
||||
// validations.minAllowedBlockLength = 7;
|
||||
|
||||
//
|
||||
// Apply Validations ...
|
||||
@@ -434,8 +445,13 @@ bool DetectTriggerBlock1(
|
||||
|
||||
//
|
||||
// TODO: Remove this ...
|
||||
filters.bosLoopback = 30;
|
||||
filters.filterBasedOnPV = true;
|
||||
// filters.bosLoopback = 0;
|
||||
// filters.filterBasedOnPV = true;
|
||||
// filters.filterBasedOnSar = false;
|
||||
// filters.forceSarSwitched = false;
|
||||
// filters.forceSarOnBothSide = true;
|
||||
// filters.forceSarHasBreakout = true;
|
||||
// filters.forceSarHasReversalSide = false;
|
||||
|
||||
//
|
||||
// Apply Filtering ...
|
||||
@@ -937,6 +953,75 @@ bool ValidateTriggerBlock(
|
||||
iBar.Clean();
|
||||
}
|
||||
|
||||
//
|
||||
// Validating Block Length Based on Direction ...
|
||||
if (result &&
|
||||
validations.minAllowedBlockLength)
|
||||
{
|
||||
//
|
||||
count = 0;
|
||||
fromIDX = triggerBlock.FromIndex();
|
||||
int sIDX = fromIDX;
|
||||
has = true;
|
||||
while (has)
|
||||
{
|
||||
//
|
||||
// Initialize iBar ...
|
||||
has = iBar.Init(
|
||||
conditions.symbol,
|
||||
conditions.period,
|
||||
sIDX //
|
||||
);
|
||||
|
||||
//
|
||||
has =
|
||||
has &&
|
||||
(isBullish
|
||||
? iBar.low > triggerBlock.trigger.lower
|
||||
: iBar.high < triggerBlock.trigger.upper);
|
||||
|
||||
//
|
||||
if (!has)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
//
|
||||
sIDX++;
|
||||
count++;
|
||||
iBar.Clean();
|
||||
}
|
||||
|
||||
//
|
||||
result =
|
||||
iBar.IsValid() &&
|
||||
count >= validations.minAllowedBlockLength;
|
||||
if (result)
|
||||
{
|
||||
//
|
||||
// Update Trigger Block ...
|
||||
bool usaMinAllowedForBlockLength = false;
|
||||
if (usaMinAllowedForBlockLength)
|
||||
{
|
||||
fromIDX = fromIDX + validations.minAllowedBlockLength;
|
||||
}
|
||||
else
|
||||
{
|
||||
fromIDX = sIDX - 1;
|
||||
}
|
||||
|
||||
//
|
||||
triggerBlock.trigger.from = GetBarTime(
|
||||
conditions.symbol,
|
||||
conditions.period,
|
||||
fromIDX //
|
||||
);
|
||||
}
|
||||
|
||||
//
|
||||
iBar.Clean();
|
||||
}
|
||||
|
||||
//
|
||||
if (!result)
|
||||
{
|
||||
@@ -1057,12 +1142,20 @@ bool FilterTriggerBlock(
|
||||
// For PV Filtering ...
|
||||
|
||||
//
|
||||
// Detect Bos ...
|
||||
// Detect BOS ...
|
||||
|
||||
//
|
||||
// When Loopback for BOS has Specified Value ...
|
||||
// we Lookup for BOS on Specific Period ...
|
||||
if (filters.bosLoopback > 0)
|
||||
{
|
||||
//
|
||||
has = true;
|
||||
int fBOSIDX = -1;
|
||||
int rBOSIDX = -1;
|
||||
bool isBOS = false;
|
||||
bool isFBOS = false;
|
||||
bool isRBOS = false;
|
||||
bool isPeakOverLast = false;
|
||||
bool isValeUnderLast = false;
|
||||
toIDX = triggerBlock.ob.ToIndex();
|
||||
@@ -1088,6 +1181,26 @@ bool FilterTriggerBlock(
|
||||
iVale > 0 &&
|
||||
iVale < iPVale;
|
||||
|
||||
//
|
||||
isFBOS =
|
||||
isBullish
|
||||
? isPeakOverLast
|
||||
: isValeUnderLast;
|
||||
if (isFBOS)
|
||||
{
|
||||
fBOSIDX = sIDX;
|
||||
}
|
||||
|
||||
//
|
||||
isRBOS =
|
||||
isBullish
|
||||
? isValeUnderLast
|
||||
: isPeakOverLast;
|
||||
if (isRBOS)
|
||||
{
|
||||
rBOSIDX = sIDX;
|
||||
}
|
||||
|
||||
//
|
||||
isBOS =
|
||||
(isBullish &&
|
||||
@@ -1106,7 +1219,210 @@ bool FilterTriggerBlock(
|
||||
}
|
||||
|
||||
//
|
||||
result = isBOS;
|
||||
isFBOS = IsValidIndex(fBOSIDX);
|
||||
isRBOS = IsValidIndex(rBOSIDX);
|
||||
|
||||
//
|
||||
result = isBOS &&
|
||||
isFBOS &&
|
||||
!isRBOS;
|
||||
}
|
||||
|
||||
//
|
||||
// When Loopback for BOS has not Specified Value ...
|
||||
// we Lookup for BOS on GAP End Bar ...
|
||||
if (filters.bosLoopback <= 0)
|
||||
{
|
||||
//
|
||||
toIDX = triggerBlock.ToIndex();
|
||||
|
||||
//
|
||||
// Initialize iBar ...
|
||||
result = iBar.Init(
|
||||
conditions.symbol,
|
||||
conditions.period,
|
||||
toIDX //
|
||||
);
|
||||
result =
|
||||
result &&
|
||||
(isBullish ? iBar.high > helper.GetPeak(toIDX + 1)
|
||||
: iBar.low < helper.GetVale(toIDX + 1));
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Filter Based on SAR ...
|
||||
if (result &&
|
||||
filters.filterBasedOnSar)
|
||||
{
|
||||
//
|
||||
toIDX = triggerBlock.ToIndex();
|
||||
fromIDX = triggerBlock.FromIndex();
|
||||
|
||||
//
|
||||
double iSarState = helper.GetSarState(toIDX);
|
||||
double iPSarState = helper.GetSarState(toIDX + 1);
|
||||
|
||||
//
|
||||
double iFSarState = helper.GetSarState(fromIDX);
|
||||
double iPFSarState = helper.GetSarState(fromIDX + 1);
|
||||
|
||||
//
|
||||
bool isSarBullish =
|
||||
iSarState > 0;
|
||||
|
||||
//
|
||||
bool isSarBearish =
|
||||
iSarState < 0;
|
||||
|
||||
//
|
||||
bool isFSarBullish =
|
||||
iFSarState > 0;
|
||||
|
||||
//
|
||||
bool isFSarBearish =
|
||||
iFSarState < 0;
|
||||
|
||||
//
|
||||
bool isSarSwitchedToBullish =
|
||||
iSarState > 0 &&
|
||||
iPSarState <= 0;
|
||||
|
||||
//
|
||||
bool isSarSwitchedToBearish =
|
||||
iSarState < 0 &&
|
||||
iPSarState >= 0;
|
||||
|
||||
//
|
||||
bool isFSarSwitchedToBullish =
|
||||
iFSarState > 0 &&
|
||||
iPFSarState <= 0;
|
||||
|
||||
//
|
||||
bool isFSarSwitchedToBearish =
|
||||
iFSarState < 0 &&
|
||||
iPFSarState >= 0;
|
||||
|
||||
//
|
||||
// Creating Filters ...
|
||||
|
||||
//
|
||||
bool isToFilterPassed =
|
||||
!filters.forceSarSwitched
|
||||
? (isBullish
|
||||
? isSarBullish
|
||||
: isSarBearish)
|
||||
: (isBullish
|
||||
? isSarSwitchedToBullish
|
||||
: isSarSwitchedToBearish);
|
||||
|
||||
//
|
||||
bool isFromFilterPassed =
|
||||
!filters.forceSarSwitched
|
||||
? (isBullish
|
||||
? isFSarBullish
|
||||
: isFSarBearish)
|
||||
: (isBullish
|
||||
? isFSarSwitchedToBullish
|
||||
: isFSarSwitchedToBearish);
|
||||
|
||||
//
|
||||
result =
|
||||
!filters.forceSarOnBothSide
|
||||
? isToFilterPassed
|
||||
: isToFilterPassed &&
|
||||
isFromFilterPassed;
|
||||
|
||||
//
|
||||
// Check Sar Has Reversal Direction inside Trigger Block ...
|
||||
if (result &&
|
||||
filters.forceSarHasReversalSide)
|
||||
{
|
||||
//
|
||||
toIDX = triggerBlock.ToIndex();
|
||||
fromIDX = triggerBlock.FromIndex();
|
||||
for (int i = toIDX; i < fromIDX; i++)
|
||||
{
|
||||
//
|
||||
double iSarState = helper.GetSarState(i);
|
||||
|
||||
//
|
||||
has =
|
||||
isBullish
|
||||
? iSarState > 0
|
||||
: iSarState < 0;
|
||||
if (has)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
result = has;
|
||||
}
|
||||
|
||||
//
|
||||
// Force Sar Breakouts ...
|
||||
// in this Senario Sar must in following Direction and
|
||||
// there is not any Switches ...
|
||||
// but must breakout Bar the last in Reversal Direction
|
||||
// of Sar ...
|
||||
if (result &&
|
||||
filters.forceSarHasBreakout)
|
||||
{
|
||||
//
|
||||
bool isSarBullishStart =
|
||||
//
|
||||
(
|
||||
//
|
||||
// Current SAR is Directional ...
|
||||
conditions.isSarBullish &&
|
||||
//
|
||||
// Previous InDirectional Sar Exists ...
|
||||
helper.lastSarBearish.IsValid() &&
|
||||
//
|
||||
// Current Close is Over previous Sar ...
|
||||
conditions.bars[cIDX].close > helper.lastSarBearish.after &&
|
||||
//
|
||||
// Before Close is not Over previous Sar ...
|
||||
conditions.bars[pIDX].close <= helper.lastSarBearish.after
|
||||
//
|
||||
)
|
||||
//
|
||||
;
|
||||
|
||||
//
|
||||
bool isSarBearishStart =
|
||||
//
|
||||
(
|
||||
//
|
||||
// Current SAR is Directional ...
|
||||
conditions.isSarBearish &&
|
||||
//
|
||||
// Previous InDirectional Sar Exists ...
|
||||
helper.lastSarBullish.IsValid() &&
|
||||
//
|
||||
// Current Close is Under previous ...
|
||||
conditions.bars[cIDX].close < helper.lastSarBullish.after &&
|
||||
//
|
||||
// Before Close is not Under previous ...
|
||||
conditions.bars[pIDX].close >= helper.lastSarBullish.after
|
||||
//
|
||||
)
|
||||
//
|
||||
;
|
||||
|
||||
//
|
||||
result =
|
||||
isBullish
|
||||
? isSarBullishStart
|
||||
: isSarBearishStart;
|
||||
}
|
||||
|
||||
//
|
||||
if (result)
|
||||
{
|
||||
Print("Filter Passed ...");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user