Files
MQL5Data/Documents/BKP/xcaea.trigger.block.lib.old.mq5
T

4122 lines
103 KiB
Plaintext

///////////////////////////////////////////////////////
//
// SaherElm IT Center MQL5 Indicator
// -------------------------------------------------
// Name: XCAEAHelper Lib
// Description: Library for XCAEA Signaller ...
//
//
// Maintainer:
// ------------
// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com)
//
//////////////////////////////////////////////////////
//
// Global Properties ...
#property library
#property copyright "Copyright 2023, SaherElm IT Center"
#property link "https://saherelm.ir"
#property version "1.00"
#property description "SaherElm Library for XCAEA Helper"
#property strict
//
// Imports ...
#include "../../Libraries/x-saherelm.common.lib.mq5"
#include "../Classes/xcaea.x-poi.detector.class.mq5"
#include "../Helpers/xcaea.helper.mq5"
//
// Definitions ...
enum ENUM_XCAEA_TIGGER_TYPE
{
XCA_TRIGGER_NONE, // None
XCA_TRIGGER_BULL, // TriggerBull
XCA_TRIGGER_BEAR, // TriggerBear
};
//
bool IsValid(ENUM_XCAEA_TIGGER_TYPE value)
{
return value != XCA_TRIGGER_NONE;
}
//
string ToString(ENUM_XCAEA_TIGGER_TYPE value)
{
return EnumToString(value);
}
//
ENUM_XCAEA_TIGGER_TYPE GetType(string type)
{
//
ENUM_XCAEA_TIGGER_TYPE result = XCA_TRIGGER_NONE;
//
bool isTriggerBull = type == ToString(XCA_TRIGGER_BULL);
bool isTriggerBear = type == ToString(XCA_TRIGGER_BEAR);
//
if (isTriggerBull)
{
result = XCA_TRIGGER_BULL;
}
else if (isTriggerBear)
{
result = XCA_TRIGGER_BEAR;
}
//
return result;
}
//
ENUM_X_DIRECTION GetDirection(ENUM_XCAEA_TIGGER_TYPE value)
{
return value == XCA_TRIGGER_BULL
? X_DIRECTION_BULLISH
: X_DIRECTION_BEARISH;
}
//
// Structues ...
struct XCAEATriggerBlockConfiguration
{
//
// Props ...
//
// Trigger Detection ...
//
double maxAllowedRange; // Maximum Allowed Range
int minAllowedBlockEdgeLength; // Minimum Required Block Edge Length
//
bool forceOBOppositBar; // Force OB to Start by Opposit Bars
bool forceFVGBarType; // Force FVG to Has Same Type of Bars
bool forceGapBarBreakout; // Force FVG's Gap Bar to Breakeout OB Edge Side
bool forceHasSwingBar; // Force Has Propper Swing
bool forceHasLiquidity; // Force Has Following Liquidity Zone
bool forceHasReversalLiquidity; // Force Has Reversal Liquidity Zone
//
// Validating ...
int minZoneLength; // Minimum Length of Consolidation Zone
bool forceHasSwing; // Force Zone's Has Propper Swing
bool forceHasPinBarEntry; // Force Zone's Ends with a Pin Bar
bool forceGapBarsBreakout; // Force Zone's Gap Bar's Breakes Out
double maxZoneRangeInPoints; // Max Zone Range in Point
double maxAllowedEntryDistance; // Max Allowed Entry Distance
//
// Filtering ...
bool filterBasedOnSar; // Filter Trigger Block Based on Sar
bool filterBasedOnRSI; // Filter Trigger Block Based on RSI
bool filterBasedOnADX; // Filter Trigger Block Based on ADX
bool filterBasedOnTrend; // Filter Trigger Block Based on Trend
bool filterBasedOnScores; // Filter Trigger Block Based on Scores
bool filterBasedOnVolumes; // Filter Trigger Block Based on Volumes
//
// Constructor ...
XCAEATriggerBlockConfiguration()
{
Clean();
}
//
// Tools ...
//
// Cleanup ...
void Clean()
{
//
//
// Validating ...
minZoneLength = 0;
forceHasSwing = false;
maxZoneRangeInPoints = 0.0;
forceHasPinBarEntry = false;
forceGapBarsBreakout = false;
maxAllowedEntryDistance = 0.0;
//
// Filtering ...
filterBasedOnSar = false;
filterBasedOnRSI = false;
filterBasedOnADX = false;
filterBasedOnTrend = false;
//
ZeroMemory(this);
}
//
// Preset Configurations ...
//
// Commons Verifications which used in all
// Preset Configurations ...
void ConfigureCommons()
{
//
minZoneLength = 7;
forceHasSwing = true;
maxZoneRangeInPoints = 70;
forceHasPinBarEntry = true;
forceGapBarsBreakout = true;
maxAllowedEntryDistance = 30;
}
//
// Cleanup Range Verifications ...
void CleanRanges()
{
//
maxZoneRangeInPoints = 0;
maxAllowedEntryDistance = 0;
}
//
void ConfigureFullFilter()
{
//
// Apply Common Configurations ...
ConfigureCommons();
//
// Apply Full Filters ...
filterBasedOnSar = true;
filterBasedOnRSI = true;
filterBasedOnADX = true;
filterBasedOnTrend = true;
}
//
void ConfigureFullFilterNoRange()
{
//
// Apply Common Configurations ...
ConfigureCommons();
//
// Clean Ranges ...
CleanRanges();
//
// Apply Full Filters ...
filterBasedOnSar = true;
filterBasedOnRSI = true;
filterBasedOnADX = true;
filterBasedOnTrend = true;
}
//
void ConfigureSarRsiAdxFilter()
{
//
ConfigureFullFilter();
//
filterBasedOnTrend = false;
}
//
void ConfigureSarRsiTrendFilter()
{
//
ConfigureFullFilter();
//
filterBasedOnADX = false;
}
//
void ConfigureSarAdxTrendFilter()
{
//
ConfigureFullFilter();
//
filterBasedOnRSI = false;
}
//
void ConfigureRsiAdxTrendFilter()
{
//
ConfigureFullFilter();
//
filterBasedOnSar = false;
}
//
void ConfigureSarRsiFilter()
{
//
ConfigureFullFilter();
//
filterBasedOnADX = false;
filterBasedOnTrend = false;
}
//
void ConfigureSarAdxFilter()
{
//
ConfigureFullFilter();
//
filterBasedOnRSI = false;
filterBasedOnTrend = false;
}
//
void ConfigureSarTrendFilter()
{
//
ConfigureFullFilter();
//
filterBasedOnRSI = false;
filterBasedOnADX = false;
}
//
void ConfigureRsiAdxFilter()
{
//
ConfigureFullFilter();
//
filterBasedOnSar = false;
filterBasedOnTrend = false;
}
//
void ConfigureRsiTrendFilter()
{
//
ConfigureFullFilter();
//
filterBasedOnSar = false;
filterBasedOnADX = false;
}
//
void ConfigureAdxTrendFilter()
{
//
ConfigureFullFilter();
//
filterBasedOnSar = false;
filterBasedOnRSI = false;
}
//
};
//
struct XTriggerBlock
{
//
// Props ...
XBoxZone ob; // Order Block
XBoxZone fvg; // Fair Value Gap
XOHCL swingBar; // Swing of Trigger
XBoxZone trigger; // Trigger Block
XBoxZone rLiquidity; // Reversal Liquidity
XBoxZone fLiquidity; // Following Liquidity
XCAEAConditions conditions; // Market Conditions
XCAEATriggerBlockConfiguration configuration; // Detection Configuration
//
// Constructor ...
XTriggerBlock()
{
Clean();
}
//
// Tools ...
//
// Cleanup ...
void Clean()
{
//
ob.Clean();
fvg.Clean();
trigger.Clean();
swingBar.Clean();
rLiquidity.Clean();
fLiquidity.Clean();
conditions.Clean();
//
ZeroMemory(this);
}
//
// Validate ...
bool IsValid()
{
//
bool result = false;
//
result = ob.IsValid() &&
fvg.IsValid() &&
trigger.IsValid();
//
return result;
}
//
};
//
// Extensions ...
/**
* Detect a Trigger Block ...
*
* @param triggerBlock: XBoxZone instance reference, The Detected Trigger Block ...
* @param conditions: XCAEAConditions instance reference, The Block Verification Conditions ...
* @param helper: XCXCAEAHelper instance pointer, Specified The Helper Class Instance which used to Detect Conditions ...
* @param config: XCAEATriggerBlockConfiguration instance reference, Specified The Trigger Block Detection Configuration ...
* @param bar_index: int, Specified The Bar Index to Start Detection ...
* @param loopback: int, Specified The Loopback Length to Detect Helper Conditions ...
*
* @return ( bool )
*/
bool DetectTriggerBlock(
XBoxZone &triggerBlock,
XCAEAConditions &conditions,
XCXCAEAHelper *helper,
XCAEATriggerBlockConfiguration &config,
int bar_index = 0,
int loopback = 6 //
)
{
//
bool result = false;
//
conditions.Clean();
triggerBlock.Clean();
//
// Normalize Args ...
loopback = NormalizeInt(loopback, 6);
bar_index = NormalizeInt(bar_index, 0);
//
// Validate Args ...
result = helper != NULL;
if (!result)
{
return result;
}
//
// Provide base Requirements ...
//
string symbol = helper.GetSymbol();
double points = GetPoints(symbol);
ENUM_TIMEFRAMES period = helper.GetPeriod();
//
// Conditions Reading Indexes ...
int zIDX = 0;
int cIDX = zIDX + 1;
int pIDX = cIDX + 1;
int p2IDX = pIDX + 1;
int p3IDX = p2IDX + 1;
int p4IDX = p3IDX + 1;
//
double ll = 0;
double hh = 0;
bool has = false;
ENUM_X_DIRECTION iDir;
//
// Retrieve Current Conditions ...
result = helper.GetConditions(
conditions,
bar_index,
loopback //
);
//
// Retrieve Required Bars ...
//
XOHCL zBar; // Current Start Checking Bar (Usually Used for Triggering) ...
XOHCL cBar; // Current Finished Bar which Start Detecting Structures based on it ( End of Block and FVG Bar ) ...
XOHCL pBar; // Determines Block Gap Bar (all Filtering must applied and Check using this Bar and it's Next Bar) ...
XOHCL p2Bar; // Determines FVG's Start Bar in a Block ...
XOHCL p3Bar; // First Verification of Block ...
XOHCL p4Bar; // Seccond Verification of Block ...
//
result = zBar.Init(
symbol,
period,
bar_index //
);
result =
result &&
zBar.GetPreviousBar(cBar);
result =
result &&
cBar.GetPreviousBar(pBar);
result =
result &&
pBar.GetPreviousBar(p2Bar);
result =
result &&
p2Bar.GetPreviousBar(p3Bar);
result =
result &&
p3Bar.GetPreviousBar(p4Bar);
if (!result)
{
//
zBar.Clean();
cBar.Clean();
pBar.Clean();
p2Bar.Clean();
p3Bar.Clean();
p4Bar.Clean();
conditions.Clean();
triggerBlock.Clean();
//
return result;
}
//
// Detect Based Order Block using CBar ...
result =
helper
.barAnalyser
.IsOB(
cBar,
triggerBlock,
true, // Force FVG Bar Type ...
true // Force Block Two Bar Checking ...
);
//
// Ensure a Block is Detected ...
if (!result)
{
//
zBar.Clean();
cBar.Clean();
pBar.Clean();
p2Bar.Clean();
p3Bar.Clean();
p4Bar.Clean();
conditions.Clean();
triggerBlock.Clean();
//
return result;
}
//
// Reading Some Block Based Requirements ...
//
bool isBullish =
result &&
triggerBlock.IsBullish();
//
bool isBearish =
result &&
triggerBlock.IsBearish();
//
int toIDX = triggerBlock.ToIndex();
int fromIDX = triggerBlock.FromIndex();
//
// Start Validating ...
//
// Validating p2Bar and p3Bar Direction ...
if (result)
{
//
iDir = Opposit(triggerBlock.dir);
//
result =
iDir == p3Bar.GetDirection() ||
iDir == p4Bar.GetDirection();
if (!result)
{
//
zBar.Clean();
cBar.Clean();
pBar.Clean();
p2Bar.Clean();
p3Bar.Clean();
p4Bar.Clean();
conditions.Clean();
triggerBlock.Clean();
//
return result;
}
}
//
// Validating Using Max Range ...
result = config.maxZoneRangeInPoints > 0;
if (result)
{
//
double range = triggerBlock.GetRange();
result = range <= config.maxZoneRangeInPoints * points;
if (!result)
{
//
zBar.Clean();
cBar.Clean();
pBar.Clean();
p2Bar.Clean();
p3Bar.Clean();
p4Bar.Clean();
conditions.Clean();
triggerBlock.Clean();
//
return result;
}
}
//
// Validate Gap Endup with PinBar ...
result = config.forceHasPinBarEntry;
if (result)
{
//
bool isBullishRejected =
isBullish &&
cBar.IsBullish() &&
cBar.GetLowShadow() > cBar.GetHighShadow();
//
bool isBearishRejected =
isBearish &&
cBar.IsBearish() &&
cBar.GetLowShadow() < cBar.GetHighShadow();
//
result = isBullishRejected ||
isBearishRejected;
if (!result)
{
//
zBar.Clean();
cBar.Clean();
pBar.Clean();
p2Bar.Clean();
p3Bar.Clean();
p4Bar.Clean();
conditions.Clean();
triggerBlock.Clean();
//
return result;
}
}
//
// Validating Gap Bar must a Momentum Bar and
// Breakes out Zone's Directional Edge ...
// for Bullish: Upper
// for Bearish: Lower
result = config.forceGapBarsBreakout;
if (result)
{
//
// Gap Bar is PBar ...
//
// Check Gap Bar is Momentum Bar ...
result =
helper
.barAnalyser
.IsMomentum(
pBar,
iDir //
);
bool isBullishMomentum =
result &&
IsBullish(iDir);
bool isBearishMomentum =
result &&
IsBearish(iDir);
//
// Check Gap Bar's Breakout ...
//
bool isBullishBreakedout =
isBullish &&
pBar.IsBullish() &&
isBullishMomentum &&
pBar.GetUp() > triggerBlock.upper &&
pBar.GetDown() < triggerBlock.upper;
//
bool isBearishBreakedout =
isBearish &&
pBar.IsBearish() &&
isBearishMomentum &&
pBar.GetUp() > triggerBlock.lower &&
pBar.GetDown() < triggerBlock.lower;
//
result = isBullishBreakedout ||
isBearishBreakedout;
if (!result)
{
//
zBar.Clean();
cBar.Clean();
pBar.Clean();
p2Bar.Clean();
p3Bar.Clean();
p4Bar.Clean();
conditions.Clean();
triggerBlock.Clean();
//
return result;
}
}
//
// Validate Zone Has Propper Swing ...
// for Bullish: p2Bar or p3Bar must be a Swing Low ...
// for Bearish: p2Bar or p3Bar must be a Swing High ...
result = config.forceHasSwing;
if (result)
{
//
// p2Bar ...
bool isP2BarSwing =
helper
.barAnalyser
.IsSimpleSwing(
p2Bar,
iDir //
);
bool isP2BarSwingLow =
isP2BarSwing &&
IsBullish(iDir);
bool isP2BarSwingHigh =
isP2BarSwing &&
IsBearish(iDir);
//
// p3Bar ...
bool isP3BarSwing =
helper
.barAnalyser
.IsSimpleSwing(
p3Bar,
iDir //
);
bool isP3BarSwingLow =
isP3BarSwing &&
IsBullish(iDir);
bool isP3BarSwingHigh =
isP3BarSwing &&
IsBearish(iDir);
//
bool hasSwingLow =
isBullish &&
(isP2BarSwingLow ||
isP3BarSwingLow);
//
bool hasSwingHigh =
isBearish &&
(isP2BarSwingHigh ||
isP3BarSwingHigh);
//
result =
hasSwingLow ||
hasSwingHigh;
if (!result)
{
//
zBar.Clean();
cBar.Clean();
pBar.Clean();
p2Bar.Clean();
p3Bar.Clean();
p4Bar.Clean();
conditions.Clean();
triggerBlock.Clean();
//
return result;
}
}
//
// Validating Using Swing Length ...
result = config.minZoneLength > 0;
if (result)
{
//
XOHCL fromBar;
has = triggerBlock.FromBar(fromBar);
if (result)
{
//
// Retrieve HH and LL ...
ll = fromBar.FindLowest(config.minZoneLength, MODE_LOW);
hh = fromBar.FindHighest(config.minZoneLength, MODE_HIGH);
//
// Validate Using HH and LL ...
//
bool isBullishValid =
isBullish &&
ll >= triggerBlock.lower;
//
bool isBearishValid =
isBearish &&
hh <= triggerBlock.upper;
//
result = isBullishValid ||
isBearishValid;
if (!result)
{
//
zBar.Clean();
cBar.Clean();
pBar.Clean();
p2Bar.Clean();
p3Bar.Clean();
p4Bar.Clean();
conditions.Clean();
triggerBlock.Clean();
//
return result;
}
//
// Update Zone's From Time ...
triggerBlock.from = GetBarTime(
triggerBlock.symbol,
triggerBlock.period,
fromBar.Index() + config.minZoneLength //
);
}
//
fromBar.Clean();
}
//
// Validate Max Allowed Entry Distance ...
result = config.maxAllowedEntryDistance > 0;
if (result)
{
//
double base =
isBullish
? triggerBlock.upper
: triggerBlock.lower;
double entryDistance = MathAbs(zBar.open - base);
result = entryDistance <= config.maxAllowedEntryDistance * points;
if (!result)
{
//
zBar.Clean();
cBar.Clean();
pBar.Clean();
p2Bar.Clean();
p3Bar.Clean();
p4Bar.Clean();
conditions.Clean();
triggerBlock.Clean();
//
return result;
}
}
//
// Here we Ensure which have a Valid Zone using Different Applied Validations ...
// from now we are Going to Filterd Validate Zones ...
//
// Check Exists Filters or not ...
result = config.filterBasedOnSar ||
config.filterBasedOnRSI ||
config.filterBasedOnADX ||
config.filterBasedOnTrend;
if (result)
{
//
// Do Apply Several Exists Filters ...
//
// SAR Filter ...
if (config.filterBasedOnSar)
{
//
// Reading Conditions Values ...
//
double zSar = conditions.sarBuffer[zIDX];
double cSar = conditions.sarBuffer[cIDX];
double pSar = conditions.sarBuffer[pIDX];
double p2Sar = conditions.sarBuffer[p2IDX];
double p3Sar = conditions.sarBuffer[p3IDX];
double p4Sar = conditions.sarBuffer[p4IDX];
//
// Create Required Conditions ...
//
bool isZSarBullish = zSar < zBar.low;
bool isZSarBearish = zSar > zBar.high;
//
bool isCSarBullish = cSar < cBar.low;
bool isCSarBearish = cSar > cBar.high;
//
bool isPSarBullish = pSar < pBar.low;
bool isPSarBearish = pSar > pBar.high;
//
bool isP2SarBullish = p2Sar < p2Bar.low;
bool isP2SarBearish = p2Sar > p2Bar.high;
//
bool isCSarSwitchedToBullish =
isZSarBullish &&
isCSarBullish &&
!isPSarBullish &&
cBar.IsBullish() &&
cBar.GetUp() > pSar;
//
bool isCSarSwitchedToBearish =
isZSarBearish &&
isCSarBearish &&
!isPSarBearish &&
cBar.IsBearish() &&
cBar.GetDown() < pSar;
//
bool isPSarSwitchedToBullish =
isZSarBullish &&
isCSarBullish &&
isPSarBullish &&
!isP2SarBullish &&
pBar.IsBullish() &&
pBar.GetUp() > p2Sar;
//
bool isPSarSwitchedToBearish =
isZSarBearish &&
isCSarBearish &&
isPSarBearish &&
!isP2SarBearish &&
pBar.IsBearish() &&
pBar.GetDown() < p2Sar;
//
// Summarize Filtering ...
//
bool isBullishFilterd =
isBullish &&
(isCSarSwitchedToBullish ||
isPSarSwitchedToBullish);
//
bool isBearishFilterd =
isBearish &&
(isCSarSwitchedToBearish ||
isPSarSwitchedToBearish);
//
result =
isBullishFilterd ||
isBearishFilterd;
if (!result)
{
//
zBar.Clean();
cBar.Clean();
pBar.Clean();
p2Bar.Clean();
p3Bar.Clean();
p4Bar.Clean();
conditions.Clean();
triggerBlock.Clean();
//
return result;
}
}
//
// RSI Filter ...
if (config.filterBasedOnRSI)
{
//
// Reading Conditions Values ...
//
double rsiTrend = (conditions.rsiOBLevel + conditions.rsiOSLevel) / 2;
//
double zRSI = conditions.rsiBuffer[zIDX];
double cRSI = conditions.rsiBuffer[cIDX];
double pRSI = conditions.rsiBuffer[pIDX];
double p2RSI = conditions.rsiBuffer[p2IDX];
double p3RSI = conditions.rsiBuffer[p3IDX];
double p4RSI = conditions.rsiBuffer[p4IDX];
//
// Create Required Conditions ...
//
bool isZRSIBullish = zRSI > rsiTrend;
bool isZRSIBearish = zRSI < rsiTrend;
//
bool isCRSIBullish = cRSI > rsiTrend;
bool isCRSIBearish = cRSI < rsiTrend;
//
bool isPRSIBullish = pRSI > rsiTrend;
bool isPRSIBearish = pRSI < rsiTrend;
//
bool isP2RSIBullish = p2RSI > rsiTrend;
bool isP2RSIBearish = p2RSI < rsiTrend;
//
bool isP3RSIBullish = p3RSI > rsiTrend;
bool isP3RSIBearish = p3RSI < rsiTrend;
//
// Trending Conditions ...
//
bool isCRSISwitchedToBullish =
isZRSIBullish &&
isCRSIBullish &&
!isPRSIBullish;
//
bool isCRSISwitchedToBearish =
isZRSIBearish &&
isCRSIBearish &&
!isPRSIBearish;
//
bool isPRSISwitchedToBullish =
isZRSIBullish &&
isCRSIBullish &&
isPRSIBullish &&
!isP2RSIBullish;
//
bool isPRSISwitchedToBearish =
isZRSIBearish &&
isCRSIBearish &&
isPRSIBearish &&
!isP2RSIBearish;
//
bool isP2RSISwitchedToBullish =
isZRSIBullish &&
isCRSIBullish &&
isPRSIBullish &&
isP2RSIBullish &&
!isP3RSIBullish;
//
bool isP2RSISwitchedToBearish =
isZRSIBearish &&
isCRSIBearish &&
isPRSIBearish &&
isP2RSIBearish &&
!isP3RSIBearish;
//
// Crosses Conditions ...
//
bool isCBarCrossedOverOS =
zRSI > conditions.rsiOSLevel &&
cRSI > conditions.rsiOSLevel &&
pRSI <= conditions.rsiOSLevel;
//
bool isCBarCrossedUnderOB =
zRSI < conditions.rsiOBLevel &&
cRSI < conditions.rsiOBLevel &&
pRSI >= conditions.rsiOBLevel;
//
bool isPBarCrossedOverOS =
zRSI > conditions.rsiOSLevel &&
cRSI > conditions.rsiOSLevel &&
pRSI > conditions.rsiOSLevel &&
p2RSI <= conditions.rsiOSLevel;
//
bool isPBarCrossedUnderOB =
zRSI < conditions.rsiOBLevel &&
cRSI < conditions.rsiOBLevel &&
pRSI < conditions.rsiOBLevel &&
p2RSI >= conditions.rsiOBLevel;
//
// V Pattern Conditions ...
//
bool isCRSIHasVBullishPattern =
zRSI >= cRSI &&
cRSI > pRSI &&
p2RSI > pRSI &&
cRSI >= p2RSI;
//
bool isCRSIHasVBearishPattern =
zRSI <= cRSI &&
cRSI < pRSI &&
p2RSI < pRSI &&
cRSI <= p2RSI;
//
// Continuation Conditions ...
//
bool isRSIUp =
zRSI >= cRSI &&
(cRSI >= pRSI ||
pRSI >= p2RSI ||
p2RSI >= p3RSI);
//
bool isRSIDown =
zRSI <= cRSI &&
(cRSI <= pRSI ||
pRSI <= p2RSI ||
p2RSI <= p3RSI);
//
// Summarize Filtering ...
//
bool isBullishFilterd =
isBullish &&
(
//
// Grows ...
isRSIUp
//
||
//
// Crosses ...
(isCBarCrossedOverOS ||
isPBarCrossedOverOS)
//
||
//
// V Pattern ...
isCRSIHasVBullishPattern
//
||
//
// Trending ...
(isCRSISwitchedToBullish ||
isPRSISwitchedToBullish ||
isP2RSISwitchedToBullish)
//
);
//
bool isBearishFilterd =
isBearish &&
(
//
// Grows ...
isRSIDown
//
||
//
// Crosses ...
(isCBarCrossedUnderOB ||
isPBarCrossedUnderOB)
//
||
//
// V Pattern ...
isCRSIHasVBearishPattern
//
||
//
// Trending ...
(isCRSISwitchedToBearish ||
isPRSISwitchedToBearish ||
isP2RSISwitchedToBearish)
//
);
//
result =
isBullishFilterd ||
isBearishFilterd;
if (!result)
{
//
zBar.Clean();
cBar.Clean();
pBar.Clean();
p2Bar.Clean();
p3Bar.Clean();
p4Bar.Clean();
conditions.Clean();
triggerBlock.Clean();
//
return result;
}
}
//
// ADX Filter ...
if (config.filterBasedOnADX)
{
//
// Reading Conditions Values ...
//
// ADX ...
double zADX = conditions.adxBuffer[zIDX];
double cADX = conditions.adxBuffer[cIDX];
double pADX = conditions.adxBuffer[pIDX];
double p2ADX = conditions.adxBuffer[p2IDX];
double p3ADX = conditions.adxBuffer[p3IDX];
double p4ADX = conditions.adxBuffer[p4IDX];
//
// ADX +DI ...
double zADXP = conditions.adxpBuffer[zIDX];
double cADXP = conditions.adxpBuffer[cIDX];
double pADXP = conditions.adxpBuffer[pIDX];
double p2ADXP = conditions.adxpBuffer[p2IDX];
double p3ADXP = conditions.adxpBuffer[p3IDX];
double p4ADXP = conditions.adxpBuffer[p4IDX];
//
// ADX -DI ...
double zADXN = conditions.adxnBuffer[zIDX];
double cADXN = conditions.adxnBuffer[cIDX];
double pADXN = conditions.adxnBuffer[pIDX];
double p2ADXN = conditions.adxnBuffer[p2IDX];
double p3ADXN = conditions.adxnBuffer[p3IDX];
double p4ADXN = conditions.adxnBuffer[p4IDX];
//
// Create Required Conditions ...
//
// Grows ...
//
bool isADXUp =
zADX >= cADX &&
(cADX >= pADX ||
pADX >= p2ADX);
//
bool isADXDown =
zADX <= cADX &&
(cADX <= pADX ||
pADX <= p2ADX);
//
// Trending ...
//
bool isZADXBullish = zADX > conditions.adxThreshold;
bool isZADXBearish = zADX < conditions.adxThreshold;
//
bool isCADXBullish = cADX > conditions.adxThreshold;
bool isCADXBearish = cADX < conditions.adxThreshold;
//
bool isPADXBullish = pADX > conditions.adxThreshold;
bool isPADXBearish = pADX < conditions.adxThreshold;
//
bool isP2ADXBullish = p2ADX > conditions.adxThreshold;
bool isP2ADXBearish = p2ADX < conditions.adxThreshold;
//
bool isP3ADXBullish = p3ADX > conditions.adxThreshold;
bool isP3ADXBearish = p3ADX < conditions.adxThreshold;
//
bool isP4ADXBullish = p4ADX > conditions.adxThreshold;
bool isP4ADXBearish = p4ADX < conditions.adxThreshold;
//
bool isCADXSwitchedToBullish =
isZADXBullish &&
isCADXBullish &&
!isPADXBullish;
//
bool isCADXSwitchedToBearish =
isZADXBearish &&
isCADXBearish &&
!isPADXBearish;
//
bool isPADXSwitchedToBullish =
isZADXBullish &&
isCADXBullish &&
isPADXBullish &&
!isP2ADXBullish;
//
bool isPADXSwitchedToBearish =
isZADXBearish &&
isCADXBearish &&
isPADXBearish &&
!isP2ADXBearish;
//
// Powering ...
//
bool isZADXHasBullishPower = zADXP > zADXN;
bool isZADXHasBearishPower = zADXN > zADXP;
//
bool isCADXHasBullishPower = cADXP > cADXN;
bool isCADXHasBearishPower = cADXN > cADXP;
//
bool isPADXHasBullishPower = pADXP > pADXN;
bool isPADXHasBearishPower = pADXN > pADXP;
//
bool isP2ADXHasBullishPower = p2ADXP > p2ADXN;
bool isP2ADXHasBearishPower = p2ADXN > p2ADXP;
//
bool isP3ADXHasBullishPower = p3ADXP > p3ADXN;
bool isP3ADXHasBearishPower = p3ADXN > p3ADXP;
//
bool isP4ADXHasBullishPower = p4ADXP > p4ADXN;
bool isP4ADXHasBearishPower = p4ADXN > p4ADXP;
//
bool isCADXSwitchedToBullishPower =
isZADXHasBullishPower &&
isCADXHasBullishPower &&
!isPADXHasBullishPower;
//
bool isCADXSwitchedToBearishPower =
isZADXHasBearishPower &&
isCADXHasBearishPower &&
!isPADXHasBearishPower;
//
bool isPADXSwitchedToBullishPower =
isZADXHasBullishPower &&
isCADXHasBullishPower &&
isPADXHasBullishPower &&
!isP2ADXHasBullishPower;
//
bool isPADXSwitchedToBearishPower =
isZADXHasBearishPower &&
isCADXHasBearishPower &&
isPADXHasBearishPower &&
!isP2ADXHasBearishPower;
//
// Summarize Filtering ...
//
bool isBullishFilterd =
isBullish &&
(
//
// Grows ...
isADXUp
//
||
//
// Trending ...
(isCADXSwitchedToBullish ||
isPADXSwitchedToBullish)
//
||
//
// Powering ...
(isCADXSwitchedToBullishPower ||
isPADXSwitchedToBullishPower)
//
);
//
bool isBearishFilterd =
isBearish &&
(
//
// Grows ...
isADXDown
//
||
//
// Trending ...
(isCADXSwitchedToBearish ||
isPADXSwitchedToBearish)
//
||
//
// Powering ...
(isCADXSwitchedToBearishPower ||
isPADXSwitchedToBearishPower)
//
);
//
result =
isBullishFilterd ||
isBearishFilterd;
if (!result)
{
//
zBar.Clean();
cBar.Clean();
pBar.Clean();
p2Bar.Clean();
p3Bar.Clean();
p4Bar.Clean();
conditions.Clean();
triggerBlock.Clean();
//
return result;
}
}
//
// TREND Filter ...
if (config.filterBasedOnTrend)
{
//
// Reading Conditions Values ...
//
double zTrend = conditions.trendBuffer[zIDX];
double cTrend = conditions.trendBuffer[cIDX];
double pTrend = conditions.trendBuffer[pIDX];
double p2Trend = conditions.trendBuffer[p2IDX];
double p3Trend = conditions.trendBuffer[p3IDX];
double p4Trend = conditions.trendBuffer[p4IDX];
//
double trends[] = {
zTrend,
cTrend,
pTrend,
p2Trend,
p3Trend,
p4Trend //
};
double trendsMin = GetMin(trends);
double trendsMax = GetMax(trends);
double trendsAVG = GetAverage(trends);
//
double zTrendState = conditions.trendStateBuffer[zIDX];
double cTrendState = conditions.trendStateBuffer[cIDX];
double pTrendState = conditions.trendStateBuffer[pIDX];
double p2TrendState = conditions.trendStateBuffer[p2IDX];
double p3TrendState = conditions.trendStateBuffer[p3IDX];
double p4TrendState = conditions.trendStateBuffer[p4IDX];
//
// Create Required Conditions ...
//
// Grows ...
//
bool isTrendUp =
zTrend >= cTrend &&
cTrend >= trendsAVG &&
cTrend > trendsMin;
//
bool isTrendDown =
zTrend <= cTrend &&
cTrend <= trendsAVG &&
cTrend < trendsMax;
//
// Stating ...
//
bool isCTrendBullish =
zTrendState > 0 &&
cTrendState > 0;
//
bool isCTrendBearish =
zTrendState < 0 &&
cTrendState < 0;
//
bool isPTrendBullish =
zTrendState > 0 &&
cTrendState > 0 &&
pTrendState > 0;
//
bool isPTrendBearish =
zTrendState < 0 &&
cTrendState < 0 &&
pTrendState < 0;
//
bool isP2TrendBullish =
zTrendState > 0 &&
cTrendState > 0 &&
pTrendState > 0 &&
p2TrendState > 0;
//
bool isP2TrendBearish =
zTrendState < 0 &&
cTrendState < 0 &&
pTrendState < 0 &&
p2TrendState < 0;
//
bool isCTrendSwitchedToBullish =
isCTrendBullish &&
!isPTrendBullish;
//
bool isCTrendSwitchedToBearish =
isCTrendBearish &&
!isPTrendBearish;
//
bool isPTrendSwitchedToBullish =
isCTrendBullish &&
isPTrendBullish &&
!isP2TrendBullish;
//
bool isPTrendSwitchedToBearish =
isCTrendBearish &&
isPTrendBearish &&
!isP2TrendBearish;
//
// Summarize Filtering ...
//
bool isBullishFilterd =
isBullish &&
(
//
// Grows ...
isTrendUp
//
||
//
// Trend Stating ...
(isCTrendBullish &&
isPTrendBullish)
//
||
//
// Switching ...
(isCTrendSwitchedToBullish ||
isPTrendSwitchedToBullish)
//
);
//
bool isBearishFilterd =
isBearish &&
(
//
// Grows ...
isTrendDown
//
||
//
// Trend Stating ...
(isCTrendBearish &&
isPTrendBearish)
//
||
//
// Switching ...
(isCTrendSwitchedToBearish ||
isPTrendSwitchedToBearish)
//
);
//
result =
isBullishFilterd ||
isBearishFilterd;
if (!result)
{
//
zBar.Clean();
cBar.Clean();
pBar.Clean();
p2Bar.Clean();
p3Bar.Clean();
p4Bar.Clean();
conditions.Clean();
triggerBlock.Clean();
//
return result;
}
}
//
// SCORE Filter ...
//
// VOLUME Filter ...
}
//
result = triggerBlock.IsValid();
if (result)
{
//
triggerBlock.type =
isBullish
? ToString(XCA_TRIGGER_BULL)
: ToString(XCA_TRIGGER_BEAR);
}
//
// Cleanup Resources ...
//
zBar.Clean();
cBar.Clean();
pBar.Clean();
p2Bar.Clean();
p3Bar.Clean();
p4Bar.Clean();
//
if (!result)
{
//
conditions.Clean();
triggerBlock.Clean();
}
//
return result;
};
bool DetectTriggerBlock1(
XBoxZone &triggerBlock,
XCAEAConditions &conditions,
XCXCAEAHelper *helper,
XCAEATriggerBlockConfiguration &config,
int bar_index = 0,
int loopback = 6 //
)
{
//
bool result = false;
//
conditions.Clean();
triggerBlock.Clean();
//
// Normalize Args ...
loopback = NormalizeInt(loopback, 6);
bar_index = NormalizeInt(bar_index, 0);
//
// Validate Args ...
result = helper != NULL;
if (!result)
{
return result;
}
//
// Provide base Requirements ...
//
string symbol = helper.GetSymbol();
double points = GetPoints(symbol);
ENUM_TIMEFRAMES period = helper.GetPeriod();
//
// Conditions Reading Indexes ...
int zIDX = 0;
int cIDX = zIDX + 1;
int pIDX = cIDX + 1;
int p2IDX = pIDX + 1;
int p3IDX = p2IDX + 1;
int p4IDX = p3IDX + 1;
//
double ll = 0;
double hh = 0;
bool has = false;
ENUM_X_DIRECTION iDir;
//
// Retrieve Current Conditions ...
result = helper.GetConditions(
conditions,
bar_index,
loopback //
);
//
// Retrieve Required Bars ...
//
XOHCL zBar; // Current Start Checking Bar (Usually Used for Triggering) ...
XOHCL cBar; // Current Finished Bar which Start Detecting Structures based on it ( End of Block and FVG Bar ) ...
XOHCL pBar; // Determines Block Gap Bar (all Filtering must applied and Check using this Bar and it's Next Bar) ...
XOHCL p2Bar; // Determines FVG's Start Bar in a Block ...
XOHCL p3Bar; // First Verification of Block ...
XOHCL p4Bar; // Seccond Verification of Block ...
//
result = zBar.Init(
symbol,
period,
bar_index //
);
result =
result &&
zBar.GetPreviousBar(cBar);
result =
result &&
cBar.GetPreviousBar(pBar);
result =
result &&
pBar.GetPreviousBar(p2Bar);
result =
result &&
p2Bar.GetPreviousBar(p3Bar);
result =
result &&
p3Bar.GetPreviousBar(p4Bar);
if (!result)
{
//
zBar.Clean();
cBar.Clean();
pBar.Clean();
p2Bar.Clean();
p3Bar.Clean();
p4Bar.Clean();
conditions.Clean();
triggerBlock.Clean();
//
return result;
}
//
// Detect Based Order Block using CBar ...
result =
helper
.barAnalyser
.IsOB(
cBar,
triggerBlock,
true, // Force FVG Bar Type ...
true // Force Block Two Bar Checking ...
);
//
// Ensure a Block is Detected ...
if (!result)
{
//
zBar.Clean();
cBar.Clean();
pBar.Clean();
p2Bar.Clean();
p3Bar.Clean();
p4Bar.Clean();
conditions.Clean();
triggerBlock.Clean();
//
return result;
}
return result;
//
// Reading Some Block Based Requirements ...
//
bool isBullish =
result &&
triggerBlock.IsBullish();
//
bool isBearish =
result &&
triggerBlock.IsBearish();
//
int toIDX = triggerBlock.ToIndex();
int fromIDX = triggerBlock.FromIndex();
//
// Start Validating ...
//
// Validating p2Bar and p3Bar Direction ...
if (result)
{
//
iDir = Opposit(triggerBlock.dir);
//
result =
iDir == p3Bar.GetDirection() ||
iDir == p4Bar.GetDirection();
if (!result)
{
//
zBar.Clean();
cBar.Clean();
pBar.Clean();
p2Bar.Clean();
p3Bar.Clean();
p4Bar.Clean();
conditions.Clean();
triggerBlock.Clean();
//
return result;
}
}
//
// Validating Using Max Range ...
result = config.maxZoneRangeInPoints > 0;
if (result)
{
//
double range = triggerBlock.GetRange();
result = range <= config.maxZoneRangeInPoints * points;
if (!result)
{
//
zBar.Clean();
cBar.Clean();
pBar.Clean();
p2Bar.Clean();
p3Bar.Clean();
p4Bar.Clean();
conditions.Clean();
triggerBlock.Clean();
//
return result;
}
}
//
// Validate Gap Endup with PinBar ...
result = config.forceHasPinBarEntry;
if (result)
{
//
bool isBullishRejected =
isBullish &&
cBar.IsBullish() &&
cBar.GetLowShadow() > cBar.GetHighShadow();
//
bool isBearishRejected =
isBearish &&
cBar.IsBearish() &&
cBar.GetLowShadow() < cBar.GetHighShadow();
//
result = isBullishRejected ||
isBearishRejected;
if (!result)
{
//
zBar.Clean();
cBar.Clean();
pBar.Clean();
p2Bar.Clean();
p3Bar.Clean();
p4Bar.Clean();
conditions.Clean();
triggerBlock.Clean();
//
return result;
}
}
//
// Validating Gap Bar must a Momentum Bar and
// Breakes out Zone's Directional Edge ...
// for Bullish: Upper
// for Bearish: Lower
result = config.forceGapBarsBreakout;
if (result)
{
//
// Gap Bar is PBar ...
//
// Check Gap Bar is Momentum Bar ...
result =
helper
.barAnalyser
.IsMomentum(
pBar,
iDir //
);
bool isBullishMomentum =
result &&
IsBullish(iDir);
bool isBearishMomentum =
result &&
IsBearish(iDir);
//
// Check Gap Bar's Breakout ...
//
bool isBullishBreakedout =
isBullish &&
pBar.IsBullish() &&
isBullishMomentum &&
pBar.GetUp() > triggerBlock.upper &&
pBar.GetDown() < triggerBlock.upper;
//
bool isBearishBreakedout =
isBearish &&
pBar.IsBearish() &&
isBearishMomentum &&
pBar.GetUp() > triggerBlock.lower &&
pBar.GetDown() < triggerBlock.lower;
//
result = isBullishBreakedout ||
isBearishBreakedout;
if (!result)
{
//
zBar.Clean();
cBar.Clean();
pBar.Clean();
p2Bar.Clean();
p3Bar.Clean();
p4Bar.Clean();
conditions.Clean();
triggerBlock.Clean();
//
return result;
}
}
//
// Validate Zone Has Propper Swing ...
// for Bullish: p2Bar or p3Bar must be a Swing Low ...
// for Bearish: p2Bar or p3Bar must be a Swing High ...
result = config.forceHasSwing;
if (result)
{
//
// p2Bar ...
bool isP2BarSwing =
helper
.barAnalyser
.IsSimpleSwing(
p2Bar,
iDir //
);
bool isP2BarSwingLow =
isP2BarSwing &&
IsBullish(iDir);
bool isP2BarSwingHigh =
isP2BarSwing &&
IsBearish(iDir);
//
// p3Bar ...
bool isP3BarSwing =
helper
.barAnalyser
.IsSimpleSwing(
p3Bar,
iDir //
);
bool isP3BarSwingLow =
isP3BarSwing &&
IsBullish(iDir);
bool isP3BarSwingHigh =
isP3BarSwing &&
IsBearish(iDir);
//
bool hasSwingLow =
isBullish &&
(isP2BarSwingLow ||
isP3BarSwingLow);
//
bool hasSwingHigh =
isBearish &&
(isP2BarSwingHigh ||
isP3BarSwingHigh);
//
result =
hasSwingLow ||
hasSwingHigh;
if (!result)
{
//
zBar.Clean();
cBar.Clean();
pBar.Clean();
p2Bar.Clean();
p3Bar.Clean();
p4Bar.Clean();
conditions.Clean();
triggerBlock.Clean();
//
return result;
}
}
//
// Validating Using Swing Length ...
result = config.minZoneLength > 0;
if (result)
{
//
XOHCL fromBar;
has = triggerBlock.FromBar(fromBar);
if (result)
{
//
// Retrieve HH and LL ...
ll = fromBar.FindLowest(config.minZoneLength, MODE_LOW);
hh = fromBar.FindHighest(config.minZoneLength, MODE_HIGH);
//
// Validate Using HH and LL ...
//
bool isBullishValid =
isBullish &&
ll >= triggerBlock.lower;
//
bool isBearishValid =
isBearish &&
hh <= triggerBlock.upper;
//
result = isBullishValid ||
isBearishValid;
if (!result)
{
//
zBar.Clean();
cBar.Clean();
pBar.Clean();
p2Bar.Clean();
p3Bar.Clean();
p4Bar.Clean();
conditions.Clean();
triggerBlock.Clean();
//
return result;
}
//
// Update Zone's From Time ...
triggerBlock.from = GetBarTime(
triggerBlock.symbol,
triggerBlock.period,
fromBar.Index() + config.minZoneLength //
);
}
//
fromBar.Clean();
}
//
// Validate Max Allowed Entry Distance ...
result = config.maxAllowedEntryDistance > 0;
if (result)
{
//
double base =
isBullish
? triggerBlock.upper
: triggerBlock.lower;
double entryDistance = MathAbs(zBar.open - base);
result = entryDistance <= config.maxAllowedEntryDistance * points;
if (!result)
{
//
zBar.Clean();
cBar.Clean();
pBar.Clean();
p2Bar.Clean();
p3Bar.Clean();
p4Bar.Clean();
conditions.Clean();
triggerBlock.Clean();
//
return result;
}
}
//
// Here we Ensure which have a Valid Zone using Different Applied Validations ...
// from now we are Going to Filterd Validate Zones ...
//
// Check Exists Filters or not ...
result = config.filterBasedOnSar ||
config.filterBasedOnRSI ||
config.filterBasedOnADX ||
config.filterBasedOnTrend;
if (result)
{
//
// Do Apply Several Exists Filters ...
//
// SAR Filter ...
if (config.filterBasedOnSar)
{
//
// Reading Conditions Values ...
//
double zSar = conditions.sarBuffer[zIDX];
double cSar = conditions.sarBuffer[cIDX];
double pSar = conditions.sarBuffer[pIDX];
double p2Sar = conditions.sarBuffer[p2IDX];
double p3Sar = conditions.sarBuffer[p3IDX];
double p4Sar = conditions.sarBuffer[p4IDX];
//
// Create Required Conditions ...
//
bool isZSarBullish = zSar < zBar.low;
bool isZSarBearish = zSar > zBar.high;
//
bool isCSarBullish = cSar < cBar.low;
bool isCSarBearish = cSar > cBar.high;
//
bool isPSarBullish = pSar < pBar.low;
bool isPSarBearish = pSar > pBar.high;
//
bool isP2SarBullish = p2Sar < p2Bar.low;
bool isP2SarBearish = p2Sar > p2Bar.high;
//
bool isCSarSwitchedToBullish =
isZSarBullish &&
isCSarBullish &&
!isPSarBullish &&
cBar.IsBullish() &&
cBar.GetUp() > pSar;
//
bool isCSarSwitchedToBearish =
isZSarBearish &&
isCSarBearish &&
!isPSarBearish &&
cBar.IsBearish() &&
cBar.GetDown() < pSar;
//
bool isPSarSwitchedToBullish =
isZSarBullish &&
isCSarBullish &&
isPSarBullish &&
!isP2SarBullish &&
pBar.IsBullish() &&
pBar.GetUp() > p2Sar;
//
bool isPSarSwitchedToBearish =
isZSarBearish &&
isCSarBearish &&
isPSarBearish &&
!isP2SarBearish &&
pBar.IsBearish() &&
pBar.GetDown() < p2Sar;
//
// Summarize Filtering ...
//
bool isBullishFilterd =
isBullish &&
(isCSarSwitchedToBullish ||
isPSarSwitchedToBullish);
//
bool isBearishFilterd =
isBearish &&
(isCSarSwitchedToBearish ||
isPSarSwitchedToBearish);
//
result =
isBullishFilterd ||
isBearishFilterd;
if (!result)
{
//
zBar.Clean();
cBar.Clean();
pBar.Clean();
p2Bar.Clean();
p3Bar.Clean();
p4Bar.Clean();
conditions.Clean();
triggerBlock.Clean();
//
return result;
}
}
//
// RSI Filter ...
if (config.filterBasedOnRSI)
{
//
// Reading Conditions Values ...
//
double rsiTrend = (conditions.rsiOBLevel + conditions.rsiOSLevel) / 2;
//
double zRSI = conditions.rsiBuffer[zIDX];
double cRSI = conditions.rsiBuffer[cIDX];
double pRSI = conditions.rsiBuffer[pIDX];
double p2RSI = conditions.rsiBuffer[p2IDX];
double p3RSI = conditions.rsiBuffer[p3IDX];
double p4RSI = conditions.rsiBuffer[p4IDX];
//
// Create Required Conditions ...
//
bool isZRSIBullish = zRSI > rsiTrend;
bool isZRSIBearish = zRSI < rsiTrend;
//
bool isCRSIBullish = cRSI > rsiTrend;
bool isCRSIBearish = cRSI < rsiTrend;
//
bool isPRSIBullish = pRSI > rsiTrend;
bool isPRSIBearish = pRSI < rsiTrend;
//
bool isP2RSIBullish = p2RSI > rsiTrend;
bool isP2RSIBearish = p2RSI < rsiTrend;
//
bool isP3RSIBullish = p3RSI > rsiTrend;
bool isP3RSIBearish = p3RSI < rsiTrend;
//
// Trending Conditions ...
//
bool isCRSISwitchedToBullish =
isZRSIBullish &&
isCRSIBullish &&
!isPRSIBullish;
//
bool isCRSISwitchedToBearish =
isZRSIBearish &&
isCRSIBearish &&
!isPRSIBearish;
//
bool isPRSISwitchedToBullish =
isZRSIBullish &&
isCRSIBullish &&
isPRSIBullish &&
!isP2RSIBullish;
//
bool isPRSISwitchedToBearish =
isZRSIBearish &&
isCRSIBearish &&
isPRSIBearish &&
!isP2RSIBearish;
//
bool isP2RSISwitchedToBullish =
isZRSIBullish &&
isCRSIBullish &&
isPRSIBullish &&
isP2RSIBullish &&
!isP3RSIBullish;
//
bool isP2RSISwitchedToBearish =
isZRSIBearish &&
isCRSIBearish &&
isPRSIBearish &&
isP2RSIBearish &&
!isP3RSIBearish;
//
// Crosses Conditions ...
//
bool isCBarCrossedOverOS =
zRSI > conditions.rsiOSLevel &&
cRSI > conditions.rsiOSLevel &&
pRSI <= conditions.rsiOSLevel;
//
bool isCBarCrossedUnderOB =
zRSI < conditions.rsiOBLevel &&
cRSI < conditions.rsiOBLevel &&
pRSI >= conditions.rsiOBLevel;
//
bool isPBarCrossedOverOS =
zRSI > conditions.rsiOSLevel &&
cRSI > conditions.rsiOSLevel &&
pRSI > conditions.rsiOSLevel &&
p2RSI <= conditions.rsiOSLevel;
//
bool isPBarCrossedUnderOB =
zRSI < conditions.rsiOBLevel &&
cRSI < conditions.rsiOBLevel &&
pRSI < conditions.rsiOBLevel &&
p2RSI >= conditions.rsiOBLevel;
//
// V Pattern Conditions ...
//
bool isCRSIHasVBullishPattern =
zRSI >= cRSI &&
cRSI > pRSI &&
p2RSI > pRSI &&
cRSI >= p2RSI;
//
bool isCRSIHasVBearishPattern =
zRSI <= cRSI &&
cRSI < pRSI &&
p2RSI < pRSI &&
cRSI <= p2RSI;
//
// Continuation Conditions ...
//
bool isRSIUp =
zRSI >= cRSI &&
(cRSI >= pRSI ||
pRSI >= p2RSI ||
p2RSI >= p3RSI);
//
bool isRSIDown =
zRSI <= cRSI &&
(cRSI <= pRSI ||
pRSI <= p2RSI ||
p2RSI <= p3RSI);
//
// Summarize Filtering ...
//
bool isBullishFilterd =
isBullish &&
(
//
// Grows ...
isRSIUp
//
||
//
// Crosses ...
(isCBarCrossedOverOS ||
isPBarCrossedOverOS)
//
||
//
// V Pattern ...
isCRSIHasVBullishPattern
//
||
//
// Trending ...
(isCRSISwitchedToBullish ||
isPRSISwitchedToBullish ||
isP2RSISwitchedToBullish)
//
);
//
bool isBearishFilterd =
isBearish &&
(
//
// Grows ...
isRSIDown
//
||
//
// Crosses ...
(isCBarCrossedUnderOB ||
isPBarCrossedUnderOB)
//
||
//
// V Pattern ...
isCRSIHasVBearishPattern
//
||
//
// Trending ...
(isCRSISwitchedToBearish ||
isPRSISwitchedToBearish ||
isP2RSISwitchedToBearish)
//
);
//
result =
isBullishFilterd ||
isBearishFilterd;
if (!result)
{
//
zBar.Clean();
cBar.Clean();
pBar.Clean();
p2Bar.Clean();
p3Bar.Clean();
p4Bar.Clean();
conditions.Clean();
triggerBlock.Clean();
//
return result;
}
}
//
// ADX Filter ...
if (config.filterBasedOnADX)
{
//
// Reading Conditions Values ...
//
// ADX ...
double zADX = conditions.adxBuffer[zIDX];
double cADX = conditions.adxBuffer[cIDX];
double pADX = conditions.adxBuffer[pIDX];
double p2ADX = conditions.adxBuffer[p2IDX];
double p3ADX = conditions.adxBuffer[p3IDX];
double p4ADX = conditions.adxBuffer[p4IDX];
//
// ADX +DI ...
double zADXP = conditions.adxpBuffer[zIDX];
double cADXP = conditions.adxpBuffer[cIDX];
double pADXP = conditions.adxpBuffer[pIDX];
double p2ADXP = conditions.adxpBuffer[p2IDX];
double p3ADXP = conditions.adxpBuffer[p3IDX];
double p4ADXP = conditions.adxpBuffer[p4IDX];
//
// ADX -DI ...
double zADXN = conditions.adxnBuffer[zIDX];
double cADXN = conditions.adxnBuffer[cIDX];
double pADXN = conditions.adxnBuffer[pIDX];
double p2ADXN = conditions.adxnBuffer[p2IDX];
double p3ADXN = conditions.adxnBuffer[p3IDX];
double p4ADXN = conditions.adxnBuffer[p4IDX];
//
// Create Required Conditions ...
//
// Grows ...
//
bool isADXUp =
zADX >= cADX &&
(cADX >= pADX ||
pADX >= p2ADX);
//
bool isADXDown =
zADX <= cADX &&
(cADX <= pADX ||
pADX <= p2ADX);
//
// Trending ...
//
bool isZADXBullish = zADX > conditions.adxThreshold;
bool isZADXBearish = zADX < conditions.adxThreshold;
//
bool isCADXBullish = cADX > conditions.adxThreshold;
bool isCADXBearish = cADX < conditions.adxThreshold;
//
bool isPADXBullish = pADX > conditions.adxThreshold;
bool isPADXBearish = pADX < conditions.adxThreshold;
//
bool isP2ADXBullish = p2ADX > conditions.adxThreshold;
bool isP2ADXBearish = p2ADX < conditions.adxThreshold;
//
bool isP3ADXBullish = p3ADX > conditions.adxThreshold;
bool isP3ADXBearish = p3ADX < conditions.adxThreshold;
//
bool isP4ADXBullish = p4ADX > conditions.adxThreshold;
bool isP4ADXBearish = p4ADX < conditions.adxThreshold;
//
bool isCADXSwitchedToBullish =
isZADXBullish &&
isCADXBullish &&
!isPADXBullish;
//
bool isCADXSwitchedToBearish =
isZADXBearish &&
isCADXBearish &&
!isPADXBearish;
//
bool isPADXSwitchedToBullish =
isZADXBullish &&
isCADXBullish &&
isPADXBullish &&
!isP2ADXBullish;
//
bool isPADXSwitchedToBearish =
isZADXBearish &&
isCADXBearish &&
isPADXBearish &&
!isP2ADXBearish;
//
// Powering ...
//
bool isZADXHasBullishPower = zADXP > zADXN;
bool isZADXHasBearishPower = zADXN > zADXP;
//
bool isCADXHasBullishPower = cADXP > cADXN;
bool isCADXHasBearishPower = cADXN > cADXP;
//
bool isPADXHasBullishPower = pADXP > pADXN;
bool isPADXHasBearishPower = pADXN > pADXP;
//
bool isP2ADXHasBullishPower = p2ADXP > p2ADXN;
bool isP2ADXHasBearishPower = p2ADXN > p2ADXP;
//
bool isP3ADXHasBullishPower = p3ADXP > p3ADXN;
bool isP3ADXHasBearishPower = p3ADXN > p3ADXP;
//
bool isP4ADXHasBullishPower = p4ADXP > p4ADXN;
bool isP4ADXHasBearishPower = p4ADXN > p4ADXP;
//
bool isCADXSwitchedToBullishPower =
isZADXHasBullishPower &&
isCADXHasBullishPower &&
!isPADXHasBullishPower;
//
bool isCADXSwitchedToBearishPower =
isZADXHasBearishPower &&
isCADXHasBearishPower &&
!isPADXHasBearishPower;
//
bool isPADXSwitchedToBullishPower =
isZADXHasBullishPower &&
isCADXHasBullishPower &&
isPADXHasBullishPower &&
!isP2ADXHasBullishPower;
//
bool isPADXSwitchedToBearishPower =
isZADXHasBearishPower &&
isCADXHasBearishPower &&
isPADXHasBearishPower &&
!isP2ADXHasBearishPower;
//
// Summarize Filtering ...
//
bool isBullishFilterd =
isBullish &&
(
//
// Grows ...
isADXUp
//
||
//
// Trending ...
(isCADXSwitchedToBullish ||
isPADXSwitchedToBullish)
//
||
//
// Powering ...
(isCADXSwitchedToBullishPower ||
isPADXSwitchedToBullishPower)
//
);
//
bool isBearishFilterd =
isBearish &&
(
//
// Grows ...
isADXDown
//
||
//
// Trending ...
(isCADXSwitchedToBearish ||
isPADXSwitchedToBearish)
//
||
//
// Powering ...
(isCADXSwitchedToBearishPower ||
isPADXSwitchedToBearishPower)
//
);
//
result =
isBullishFilterd ||
isBearishFilterd;
if (!result)
{
//
zBar.Clean();
cBar.Clean();
pBar.Clean();
p2Bar.Clean();
p3Bar.Clean();
p4Bar.Clean();
conditions.Clean();
triggerBlock.Clean();
//
return result;
}
}
//
// TREND Filter ...
if (config.filterBasedOnTrend)
{
//
// Reading Conditions Values ...
//
double zTrend = conditions.trendBuffer[zIDX];
double cTrend = conditions.trendBuffer[cIDX];
double pTrend = conditions.trendBuffer[pIDX];
double p2Trend = conditions.trendBuffer[p2IDX];
double p3Trend = conditions.trendBuffer[p3IDX];
double p4Trend = conditions.trendBuffer[p4IDX];
//
double trends[] = {
zTrend,
cTrend,
pTrend,
p2Trend,
p3Trend,
p4Trend //
};
double trendsMin = GetMin(trends);
double trendsMax = GetMax(trends);
double trendsAVG = GetAverage(trends);
//
double zTrendState = conditions.trendStateBuffer[zIDX];
double cTrendState = conditions.trendStateBuffer[cIDX];
double pTrendState = conditions.trendStateBuffer[pIDX];
double p2TrendState = conditions.trendStateBuffer[p2IDX];
double p3TrendState = conditions.trendStateBuffer[p3IDX];
double p4TrendState = conditions.trendStateBuffer[p4IDX];
//
// Create Required Conditions ...
//
// Grows ...
//
bool isTrendUp =
zTrend >= cTrend &&
cTrend >= trendsAVG &&
cTrend > trendsMin;
//
bool isTrendDown =
zTrend <= cTrend &&
cTrend <= trendsAVG &&
cTrend < trendsMax;
//
// Stating ...
//
bool isCTrendBullish =
zTrendState > 0 &&
cTrendState > 0;
//
bool isCTrendBearish =
zTrendState < 0 &&
cTrendState < 0;
//
bool isPTrendBullish =
zTrendState > 0 &&
cTrendState > 0 &&
pTrendState > 0;
//
bool isPTrendBearish =
zTrendState < 0 &&
cTrendState < 0 &&
pTrendState < 0;
//
bool isP2TrendBullish =
zTrendState > 0 &&
cTrendState > 0 &&
pTrendState > 0 &&
p2TrendState > 0;
//
bool isP2TrendBearish =
zTrendState < 0 &&
cTrendState < 0 &&
pTrendState < 0 &&
p2TrendState < 0;
//
bool isCTrendSwitchedToBullish =
isCTrendBullish &&
!isPTrendBullish;
//
bool isCTrendSwitchedToBearish =
isCTrendBearish &&
!isPTrendBearish;
//
bool isPTrendSwitchedToBullish =
isCTrendBullish &&
isPTrendBullish &&
!isP2TrendBullish;
//
bool isPTrendSwitchedToBearish =
isCTrendBearish &&
isPTrendBearish &&
!isP2TrendBearish;
//
// Summarize Filtering ...
//
bool isBullishFilterd =
isBullish &&
(
//
// Grows ...
isTrendUp
//
||
//
// Trend Stating ...
(isCTrendBullish &&
isPTrendBullish)
//
||
//
// Switching ...
(isCTrendSwitchedToBullish ||
isPTrendSwitchedToBullish)
//
);
//
bool isBearishFilterd =
isBearish &&
(
//
// Grows ...
isTrendDown
//
||
//
// Trend Stating ...
(isCTrendBearish &&
isPTrendBearish)
//
||
//
// Switching ...
(isCTrendSwitchedToBearish ||
isPTrendSwitchedToBearish)
//
);
//
result =
isBullishFilterd ||
isBearishFilterd;
if (!result)
{
//
zBar.Clean();
cBar.Clean();
pBar.Clean();
p2Bar.Clean();
p3Bar.Clean();
p4Bar.Clean();
conditions.Clean();
triggerBlock.Clean();
//
return result;
}
}
//
// SCORE Filter ...
//
// VOLUME Filter ...
}
//
result = triggerBlock.IsValid();
if (result)
{
//
triggerBlock.type =
isBullish
? ToString(XCA_TRIGGER_BULL)
: ToString(XCA_TRIGGER_BEAR);
}
//
// Cleanup Resources ...
//
zBar.Clean();
cBar.Clean();
pBar.Clean();
p2Bar.Clean();
p3Bar.Clean();
p4Bar.Clean();
//
if (!result)
{
//
conditions.Clean();
triggerBlock.Clean();
}
//
return result;
}
/**
* Detect Trigger Block ...
*
* @param trigger: XTriggerBlock instance Reference, hold founded Trigger Block
* @param helper: XCXCAEAHelper instance Reference Pointer, XCAEA Market nalyser Helper for acc Drawer
* @param config: XCAEATriggerBlockConfiguration instance Reference, Trigger Block Detecting Configuration
* @param bar_index: int, Bar Index to Start Detecting
* @param loopback: int, Loopback Bars Count
*
* @return ( bool )
*/
bool DetectTriggerBlock(
XTriggerBlock &trigger,
XCXCAEAHelper *helper,
XCAEATriggerBlockConfiguration &config,
int bar_index = 0,
int loopback = 10 //
)
{
//
bool result = false;
//
// Normalize Args ...
trigger.Clean();
loopback = NormalizeInt(loopback, 10);
bar_index = NormalizeInt(bar_index, 0);
//
// Validate Args ...
result = helper != NULL;
if (!result)
{
return result;
}
//
// Extract Required Informations ...
//
string symbol = helper.GetSymbol();
ENUM_TIMEFRAMES period = helper.GetPeriod();
//
double points = GetPoints(symbol);
//
// Retrieve Indexed Bar ...
XOHCL zBar;
XOHCL cBar;
XOHCL pBar;
XOHCL p2Bar;
result = zBar.Init(
symbol,
period,
bar_index //
);
result = result &&
zBar.GetPreviousBar(cBar);
result = result &&
cBar.GetPreviousBar(pBar);
result = result &&
pBar.GetPreviousBar(p2Bar);
//
int zIDX = 0;
int cIDX = zIDX + 1;
int pIDX = cIDX + 1;
int p2IDX = pIDX + 1;
int p3IDX = p2IDX + 1;
int p4IDX = p3IDX + 1;
//
// Check Trigger Block Exists ...
result =
result &&
helper
.barAnalyser
.IsTrigger(
cBar,
trigger.trigger,
trigger.ob,
trigger.fvg,
trigger.rLiquidity,
trigger.fLiquidity,
trigger.swingBar,
loopback,
config.maxAllowedRange,
config.minAllowedBlockEdgeLength,
config.forceOBOppositBar,
config.forceFVGBarType,
config.forceGapBarBreakout,
config.forceHasSwingBar,
config.forceHasLiquidity,
config.forceHasReversalLiquidity //
);
//
// Now we Have to Implement Required Validations ...
//
bool isBullish = trigger.trigger.IsBullish();
bool isBearish = trigger.trigger.IsBearish();
//
// First Reading Market Conditions ...
result =
result &&
helper.GetConditions(
trigger.conditions,
bar_index,
loopback //
);
//
// All Custom andAdditional Validations and Filters
// Applied here ...
//
// SAR Filter ...
if (config.filterBasedOnSar)
{
//
if (result)
{
//
// Reading Values ...
//
double zSar = trigger.conditions.sarBuffer[zIDX];
double cSar = trigger.conditions.sarBuffer[cIDX];
double pSar = trigger.conditions.sarBuffer[pIDX];
double p2Sar = trigger.conditions.sarBuffer[p2IDX];
double p3Sar = trigger.conditions.sarBuffer[p3IDX];
double p4Sar = trigger.conditions.sarBuffer[p4IDX];
//
// Preparing Conditions ...
//
bool isZSarBullish = zSar < zBar.low;
bool isZSarBearish = zSar > zBar.high;
//
bool isCSarBullish = cSar < cBar.low;
bool isCSarBearish = cSar > cBar.high;
//
bool isPSarBullish = pSar < pBar.low;
bool isPSarBearish = pSar > pBar.high;
//
bool isP2SarBullish = p2Sar < p2Bar.low;
bool isP2SarBearish = p2Sar > p2Bar.high;
//
bool isCSarSwitchedToBullish =
isZSarBullish &&
isCSarBullish &&
!isPSarBullish &&
cBar.IsBullish() &&
cBar.GetUp() > pSar;
//
bool isCSarSwitchedToBearish =
isZSarBearish &&
isCSarBearish &&
!isPSarBearish &&
cBar.IsBearish() &&
cBar.GetDown() < pSar;
//
bool isPSarSwitchedToBullish =
isZSarBullish &&
isCSarBullish &&
isPSarBullish &&
!isP2SarBullish &&
pBar.IsBullish() &&
pBar.GetUp() > p2Sar;
//
bool isPSarSwitchedToBearish =
isZSarBearish &&
isCSarBearish &&
isPSarBearish &&
!isP2SarBearish &&
pBar.IsBearish() &&
pBar.GetDown() < p2Sar;
//
// Summarize Filtering ...
//
bool isBullishFilterd =
isBullish &&
(isCSarSwitchedToBullish ||
isPSarSwitchedToBullish);
//
bool isBearishFilterd =
isBearish &&
(isCSarSwitchedToBearish ||
isPSarSwitchedToBearish);
//
// Apply Result ....
//
result =
result &&
(isBullishFilterd ||
isBearishFilterd);
}
}
//
// RSI Filter ...
if (config.filterBasedOnRSI)
{
//
if (result)
{
//
// Reading Values ...
//
double rsiTrend = (trigger.conditions.rsiOBLevel + trigger.conditions.rsiOSLevel) / 2;
//
double zRSI = trigger.conditions.rsiBuffer[zIDX];
double cRSI = trigger.conditions.rsiBuffer[cIDX];
double pRSI = trigger.conditions.rsiBuffer[pIDX];
double p2RSI = trigger.conditions.rsiBuffer[p2IDX];
double p3RSI = trigger.conditions.rsiBuffer[p3IDX];
double p4RSI = trigger.conditions.rsiBuffer[p4IDX];
//
// Preparing Conditions ...
//
bool isZRSIBullish = zRSI > rsiTrend;
bool isZRSIBearish = zRSI < rsiTrend;
//
bool isCRSIBullish = cRSI > rsiTrend;
bool isCRSIBearish = cRSI < rsiTrend;
//
bool isPRSIBullish = pRSI > rsiTrend;
bool isPRSIBearish = pRSI < rsiTrend;
//
bool isP2RSIBullish = p2RSI > rsiTrend;
bool isP2RSIBearish = p2RSI < rsiTrend;
//
bool isP3RSIBullish = p3RSI > rsiTrend;
bool isP3RSIBearish = p3RSI < rsiTrend;
//
// Trending Conditions ...
//
bool isCRSISwitchedToBullish =
isZRSIBullish &&
isCRSIBullish &&
!isPRSIBullish;
//
bool isCRSISwitchedToBearish =
isZRSIBearish &&
isCRSIBearish &&
!isPRSIBearish;
//
bool isPRSISwitchedToBullish =
isZRSIBullish &&
isCRSIBullish &&
isPRSIBullish &&
!isP2RSIBullish;
//
bool isPRSISwitchedToBearish =
isZRSIBearish &&
isCRSIBearish &&
isPRSIBearish &&
!isP2RSIBearish;
//
bool isP2RSISwitchedToBullish =
isZRSIBullish &&
isCRSIBullish &&
isPRSIBullish &&
isP2RSIBullish &&
!isP3RSIBullish;
//
bool isP2RSISwitchedToBearish =
isZRSIBearish &&
isCRSIBearish &&
isPRSIBearish &&
isP2RSIBearish &&
!isP3RSIBearish;
//
// Crosses Conditions ...
//
bool isCBarCrossedOverOS =
zRSI > trigger.conditions.rsiOSLevel &&
cRSI > trigger.conditions.rsiOSLevel &&
pRSI <= trigger.conditions.rsiOSLevel;
//
bool isCBarCrossedUnderOB =
zRSI < trigger.conditions.rsiOBLevel &&
cRSI < trigger.conditions.rsiOBLevel &&
pRSI >= trigger.conditions.rsiOBLevel;
//
bool isPBarCrossedOverOS =
zRSI > trigger.conditions.rsiOSLevel &&
cRSI > trigger.conditions.rsiOSLevel &&
pRSI > trigger.conditions.rsiOSLevel &&
p2RSI <= trigger.conditions.rsiOSLevel;
//
bool isPBarCrossedUnderOB =
zRSI < trigger.conditions.rsiOBLevel &&
cRSI < trigger.conditions.rsiOBLevel &&
pRSI < trigger.conditions.rsiOBLevel &&
p2RSI >= trigger.conditions.rsiOBLevel;
//
// V Pattern Conditions ...
//
bool isCRSIHasVBullishPattern =
zRSI >= cRSI &&
cRSI > pRSI &&
p2RSI > pRSI &&
cRSI >= p2RSI;
//
bool isCRSIHasVBearishPattern =
zRSI <= cRSI &&
cRSI < pRSI &&
p2RSI < pRSI &&
cRSI <= p2RSI;
//
// Continuation Conditions ...
//
bool isRSIUp =
zRSI >= cRSI &&
(cRSI >= pRSI ||
pRSI >= p2RSI ||
p2RSI >= p3RSI);
//
bool isRSIDown =
zRSI <= cRSI &&
(cRSI <= pRSI ||
pRSI <= p2RSI ||
p2RSI <= p3RSI);
//
// Summarize Filtering ...
//
bool isBullishFilterd =
isBullish &&
(
//
// Grows ...
isRSIUp
//
||
//
// Crosses ...
(isCBarCrossedOverOS ||
isPBarCrossedOverOS)
//
||
//
// V Pattern ...
isCRSIHasVBullishPattern
//
||
//
// Trending ...
(isCRSISwitchedToBullish ||
isPRSISwitchedToBullish ||
isP2RSISwitchedToBullish)
//
);
//
bool isBearishFilterd =
isBearish &&
(
//
// Grows ...
isRSIDown
//
||
//
// Crosses ...
(isCBarCrossedUnderOB ||
isPBarCrossedUnderOB)
//
||
//
// V Pattern ...
isCRSIHasVBearishPattern
//
||
//
// Trending ...
(isCRSISwitchedToBearish ||
isPRSISwitchedToBearish ||
isP2RSISwitchedToBearish)
//
);
//
// Apply Result ....
//
result =
result &&
(isBullishFilterd ||
isBearishFilterd);
}
}
//
// ADX Filter ...
if (config.filterBasedOnADX)
{
//
if (result)
{
//
// Reading Values ...
//
// ADX ...
double zADX = trigger.conditions.adxBuffer[zIDX];
double cADX = trigger.conditions.adxBuffer[cIDX];
double pADX = trigger.conditions.adxBuffer[pIDX];
double p2ADX = trigger.conditions.adxBuffer[p2IDX];
double p3ADX = trigger.conditions.adxBuffer[p3IDX];
double p4ADX = trigger.conditions.adxBuffer[p4IDX];
//
// ADX +DI ...
double zADXP = trigger.conditions.adxpBuffer[zIDX];
double cADXP = trigger.conditions.adxpBuffer[cIDX];
double pADXP = trigger.conditions.adxpBuffer[pIDX];
double p2ADXP = trigger.conditions.adxpBuffer[p2IDX];
double p3ADXP = trigger.conditions.adxpBuffer[p3IDX];
double p4ADXP = trigger.conditions.adxpBuffer[p4IDX];
//
// ADX -DI ...
double zADXN = trigger.conditions.adxnBuffer[zIDX];
double cADXN = trigger.conditions.adxnBuffer[cIDX];
double pADXN = trigger.conditions.adxnBuffer[pIDX];
double p2ADXN = trigger.conditions.adxnBuffer[p2IDX];
double p3ADXN = trigger.conditions.adxnBuffer[p3IDX];
double p4ADXN = trigger.conditions.adxnBuffer[p4IDX];
//
// Preparing Conditions ...
//
// Grows ...
//
bool isADXUp =
zADX >= cADX &&
(cADX >= pADX ||
pADX >= p2ADX);
//
bool isADXDown =
zADX <= cADX &&
(cADX <= pADX ||
pADX <= p2ADX);
//
// Trending ...
//
bool isZADXBullish = zADX > trigger.conditions.adxThreshold;
bool isZADXBearish = zADX < trigger.conditions.adxThreshold;
//
bool isCADXBullish = cADX > trigger.conditions.adxThreshold;
bool isCADXBearish = cADX < trigger.conditions.adxThreshold;
//
bool isPADXBullish = pADX > trigger.conditions.adxThreshold;
bool isPADXBearish = pADX < trigger.conditions.adxThreshold;
//
bool isP2ADXBullish = p2ADX > trigger.conditions.adxThreshold;
bool isP2ADXBearish = p2ADX < trigger.conditions.adxThreshold;
//
bool isP3ADXBullish = p3ADX > trigger.conditions.adxThreshold;
bool isP3ADXBearish = p3ADX < trigger.conditions.adxThreshold;
//
bool isP4ADXBullish = p4ADX > trigger.conditions.adxThreshold;
bool isP4ADXBearish = p4ADX < trigger.conditions.adxThreshold;
//
bool isCADXSwitchedToBullish =
isZADXBullish &&
isCADXBullish &&
!isPADXBullish;
//
bool isCADXSwitchedToBearish =
isZADXBearish &&
isCADXBearish &&
!isPADXBearish;
//
bool isPADXSwitchedToBullish =
isZADXBullish &&
isCADXBullish &&
isPADXBullish &&
!isP2ADXBullish;
//
bool isPADXSwitchedToBearish =
isZADXBearish &&
isCADXBearish &&
isPADXBearish &&
!isP2ADXBearish;
//
// Powering ...
//
bool isZADXHasBullishPower = zADXP > zADXN;
bool isZADXHasBearishPower = zADXN > zADXP;
//
bool isCADXHasBullishPower = cADXP > cADXN;
bool isCADXHasBearishPower = cADXN > cADXP;
//
bool isPADXHasBullishPower = pADXP > pADXN;
bool isPADXHasBearishPower = pADXN > pADXP;
//
bool isP2ADXHasBullishPower = p2ADXP > p2ADXN;
bool isP2ADXHasBearishPower = p2ADXN > p2ADXP;
//
bool isP3ADXHasBullishPower = p3ADXP > p3ADXN;
bool isP3ADXHasBearishPower = p3ADXN > p3ADXP;
//
bool isP4ADXHasBullishPower = p4ADXP > p4ADXN;
bool isP4ADXHasBearishPower = p4ADXN > p4ADXP;
//
bool isCADXSwitchedToBullishPower =
isZADXHasBullishPower &&
isCADXHasBullishPower &&
!isPADXHasBullishPower;
//
bool isCADXSwitchedToBearishPower =
isZADXHasBearishPower &&
isCADXHasBearishPower &&
!isPADXHasBearishPower;
//
bool isPADXSwitchedToBullishPower =
isZADXHasBullishPower &&
isCADXHasBullishPower &&
isPADXHasBullishPower &&
!isP2ADXHasBullishPower;
//
bool isPADXSwitchedToBearishPower =
isZADXHasBearishPower &&
isCADXHasBearishPower &&
isPADXHasBearishPower &&
!isP2ADXHasBearishPower;
//
// Summarize Filtering ...
//
bool isBullishFilterd =
isBullish &&
(
//
// Grows ...
isADXUp
//
||
//
// Trending ...
(isCADXSwitchedToBullish ||
isPADXSwitchedToBullish)
//
||
//
// Powering ...
(isCADXSwitchedToBullishPower ||
isPADXSwitchedToBullishPower)
//
);
//
bool isBearishFilterd =
isBearish &&
(
//
// Grows ...
isADXDown
//
||
//
// Trending ...
(isCADXSwitchedToBearish ||
isPADXSwitchedToBearish)
//
||
//
// Powering ...
(isCADXSwitchedToBearishPower ||
isPADXSwitchedToBearishPower)
//
);
//
// Apply Result ....
//
result =
result &&
(isBullishFilterd ||
isBearishFilterd);
}
}
//
// TREND Filter ...
if (config.filterBasedOnTrend)
{
//
if (result)
{
//
// Reading Values ...
//
double zTrend = trigger.conditions.trendBuffer[zIDX];
double cTrend = trigger.conditions.trendBuffer[cIDX];
double pTrend = trigger.conditions.trendBuffer[pIDX];
double p2Trend = trigger.conditions.trendBuffer[p2IDX];
double p3Trend = trigger.conditions.trendBuffer[p3IDX];
double p4Trend = trigger.conditions.trendBuffer[p4IDX];
//
double trends[] = {
zTrend,
cTrend,
pTrend,
p2Trend,
p3Trend,
p4Trend //
};
double trendsMin = GetMin(trends);
double trendsMax = GetMax(trends);
double trendsAVG = GetAverage(trends);
//
double zTrendState = trigger.conditions.trendStateBuffer[zIDX];
double cTrendState = trigger.conditions.trendStateBuffer[cIDX];
double pTrendState = trigger.conditions.trendStateBuffer[pIDX];
double p2TrendState = trigger.conditions.trendStateBuffer[p2IDX];
double p3TrendState = trigger.conditions.trendStateBuffer[p3IDX];
double p4TrendState = trigger.conditions.trendStateBuffer[p4IDX];
//
// Preparing Conditions ...
//
// Grows ...
//
bool isTrendUp =
zTrend >= cTrend &&
cTrend >= trendsAVG &&
cTrend > trendsMin;
//
bool isTrendDown =
zTrend <= cTrend &&
cTrend <= trendsAVG &&
cTrend < trendsMax;
//
// Stating ...
//
bool isCTrendBullish =
zTrendState > 0 &&
cTrendState > 0;
//
bool isCTrendBearish =
zTrendState < 0 &&
cTrendState < 0;
//
bool isPTrendBullish =
zTrendState > 0 &&
cTrendState > 0 &&
pTrendState > 0;
//
bool isPTrendBearish =
zTrendState < 0 &&
cTrendState < 0 &&
pTrendState < 0;
//
bool isP2TrendBullish =
zTrendState > 0 &&
cTrendState > 0 &&
pTrendState > 0 &&
p2TrendState > 0;
//
bool isP2TrendBearish =
zTrendState < 0 &&
cTrendState < 0 &&
pTrendState < 0 &&
p2TrendState < 0;
//
bool isCTrendSwitchedToBullish =
isCTrendBullish &&
!isPTrendBullish;
//
bool isCTrendSwitchedToBearish =
isCTrendBearish &&
!isPTrendBearish;
//
bool isPTrendSwitchedToBullish =
isCTrendBullish &&
isPTrendBullish &&
!isP2TrendBullish;
//
bool isPTrendSwitchedToBearish =
isCTrendBearish &&
isPTrendBearish &&
!isP2TrendBearish;
//
// Summarize Filtering ...
//
bool isBullishFilterd =
isBullish &&
(
//
// Grows ...
isTrendUp
//
||
//
// Trend Stating ...
(isCTrendBullish &&
isPTrendBullish)
//
||
//
// Switching ...
(isCTrendSwitchedToBullish ||
isPTrendSwitchedToBullish)
//
);
//
bool isBearishFilterd =
isBearish &&
(
//
// Grows ...
isTrendDown
//
||
//
// Trend Stating ...
(isCTrendBearish &&
isPTrendBearish)
//
||
//
// Switching ...
(isCTrendSwitchedToBearish ||
isPTrendSwitchedToBearish)
//
);
//
// Apply Result ....
//
result =
result &&
(isBullishFilterd ||
isBearishFilterd);
}
}
//
// SCORE Filter ...
if (config.filterBasedOnScores)
{
//
if (result)
{
//
// Reading Values ...
//
double bullishScore = 0;
double bearishScore = 0;
//
trigger.conditions.GenerateScore(
bullishScore,
bearishScore //
);
//
// Preparing Conditions ...
//
bool isScoreBullish = bullishScore > bearishScore;
bool isScoreBearish = bearishScore > bullishScore;
//
// Summarize Filtering ...
//
bool isBullishFilterd =
isBullish &&
isScoreBullish;
//
bool isBearishFilterd =
isBearish &&
isScoreBearish;
//
// Apply Result ....
//
result =
result &&
(isBullishFilterd ||
isBearishFilterd);
}
}
//
// VOLUME Filter ...
if (config.filterBasedOnVolumes)
{
//
if (result)
{
//
// Reading Values ...
//
double bullishVolume = 0;
double bearishVolume = 0;
//
helper
.barAnalyser
.CalculateRangeVolume(
zBar,
bullishVolume,
bearishVolume,
loopback //
);
//
// Preparing Conditions ...
//
bool isVolumeBullish = bullishVolume > bearishVolume;
bool isVolumeBearish = bearishVolume > bullishVolume;
//
// Summarize Filtering ...
//
bool isBullishFilterd =
isBullish &&
isVolumeBullish;
//
bool isBearishFilterd =
isBearish &&
isVolumeBearish;
//
// Apply Result ....
//
result =
result &&
(isBullishFilterd ||
isBearishFilterd);
}
}
//
// Cleanup Resources ...
//
zBar.Clean();
cBar.Clean();
pBar.Clean();
//
if (!result)
{
trigger.Clean();
}
//
// Attach Configuration if Trigger Block Founded ...
if (result)
{
trigger.configuration = config;
}
//
return result;
}
/**
* Draw Specified Trigger Block ...
*
* @param trigger: XTriggerBlock instance Reference, specified Trigger Block to Draw
* @param objects: CArrayObj instance Reference Pointer, Objects Array for Providing Drawn Objects
* @param helper: XCXCAEAHelper instance Reference Pointer, XCAEA Market nalyser Helper for acc Drawer
* @param to: datetime, specified Time for update Trigger parts
*
* @return ( bool )
*/
bool DrawTriggerBlock(
XTriggerBlock &trigger,
CArrayObj *&objects,
XCXCAEAHelper *helper,
datetime to = NULL //
)
{
//
bool result = false;
//
// Validate Args ...
result = helper != NULL &&
trigger.IsValid();
if (!result)
{
return result;
}
//
// Update To ...
bool canUpdateTo = IsValid(to);
if (canUpdateTo)
{
//
trigger.trigger.to = to;
trigger.rLiquidity.to = to;
trigger.fLiquidity.to = to;
}
//
// Draw OB ...
if (trigger.ob.IsValid())
{
//
XCBoxObject *iOBObj;
result = helper.poiDrawer.DrawBox(
trigger.ob,
iOBObj //
);
if (result)
{
objects.Add(iOBObj);
}
ZeroMemory(iOBObj);
//
if (!result)
{
return result;
}
}
//
// Draw FVG ...
if (trigger.fvg.IsValid())
{
//
XCBoxObject *iFVGObj;
result = helper.poiDrawer.DrawBox(
trigger.fvg,
iFVGObj //
);
if (result)
{
//
// Style Object ...
color clr =
trigger.fvg.IsBullish()
? clrAqua
: clrMagenta;
iFVGObj.BoxWidth(2);
iFVGObj.BoxColor(clr);
iFVGObj.BoxStyle(STYLE_SOLID);
//
// Store Object ...
objects.Add(iFVGObj);
}
ZeroMemory(iFVGObj);
//
if (!result)
{
return result;
}
}
//
// Draw Trigger ...
if (trigger.trigger.IsValid())
{
//
XCBoxObject *iTriggerObj;
result = helper.poiDrawer.DrawBox(
trigger.trigger,
iTriggerObj //
);
if (result)
{
objects.Add(iTriggerObj);
}
ZeroMemory(iTriggerObj);
//
if (!result)
{
return result;
}
}
//
// Draw Liquidities ...
//
// Reversla Liquidity ...
if (trigger.rLiquidity.IsValid())
{
//
XCBoxObject *iLiqObj;
result = helper.poiDrawer.DrawBox(
trigger.rLiquidity,
iLiqObj //
);
if (result)
{
objects.Add(iLiqObj);
}
ZeroMemory(iLiqObj);
//
if (!result)
{
return result;
}
}
//
// Following Liquidity ...
if (trigger.fLiquidity.IsValid())
{
//
XCBoxObject *iLiqObj;
result = helper.poiDrawer.DrawBox(
trigger.fLiquidity,
iLiqObj //
);
if (result)
{
objects.Add(iLiqObj);
}
ZeroMemory(iLiqObj);
//
if (!result)
{
return result;
}
}
//
// Draw Swing Bar ...
if (trigger.swingBar.IsValid())
{
//
color swingColor =
trigger.fvg.IsBullish()
? clrAqua
: clrMagenta;
ENUM_X_PRICE swingPType =
trigger.fvg.IsBullish()
? X_PRICE_LOW
: X_PRICE_HIGH;
//
XCBarArrowObject *swingObj;
result = helper.poiDrawer.CreateBarArrow(
trigger.swingBar,
swingObj,
swingPType,
159,
swingColor //
);
if (result)
{
objects.Add(swingObj);
}
ZeroMemory(swingObj);
//
if (!result)
{
return result;
}
}
//
return result;
}
//