Files
MQL5Data/XCAEA/Libraries/xcaea.trigger.block.lib.mq5
T
2025-05-19 15:13:49 +03:30

1647 lines
40 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 ...
//
// 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 Pivots Based on Sar
bool filterBasedOnRSI; // Filter Pivots Based on RSI
bool filterBasedOnADX; // Filter Pivots Based on ADX
bool filterBasedOnTrend; // Filter Pivots Based on Trend
//
// 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;
}
//
};
//
// 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;
//
return result;
}
//