From bafcb866175e30d93cd24d24df2d9e36fe31b71c Mon Sep 17 00:00:00 2001 From: Hadi Khazaee Asl Date: Thu, 22 May 2025 13:07:31 +0330 Subject: [PATCH] last works on XCZone indicator ... --- Documents/BKP/sample.mq5 | 1744 ++++++++++++++++++ Indicators/x-saherelm.x121.xczone.mq5 | 2420 +++++++++++-------------- 2 files changed, 2816 insertions(+), 1348 deletions(-) diff --git a/Documents/BKP/sample.mq5 b/Documents/BKP/sample.mq5 index 1cf4d7a7..291ce9aa 100644 --- a/Documents/BKP/sample.mq5 +++ b/Documents/BKP/sample.mq5 @@ -778,3 +778,1747 @@ bool IsTrigger( // return result; } + + +///////////////////////////////////// + + +// +void DetectTriggerZone( + int bar_index, // Selected Bar Index + const int prevCalculated, + const int ratesTotal, + const double &open[], + const double &high[], + const double &close[], + const double &low[], + const long &tickVolume[] // +) +{ + // + // Check Prev Bar ... + + // + int lastBarIndex = bar_index + 1; + int maxBarIndex = startCalculationForLastBars > 0 + ? startCalculationForLastBars + : ratesTotal; + bool isFirstBar = + bar_index == maxBarIndex; + + // + // Prevent Calculation ... + if (maxBarIndex - bar_index < minZoneLength) + { + return; + } + + // + int zIDX = 0; + int cIDX = 0; + int pIDX = 0; + int p2IDX = 0; + int p3IDX = 0; + int p4IDX = 0; + double ll = 0; + double hh = 0; + bool has = false; + ENUM_X_DIRECTION iDir; + + // + // 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 ... + + // + has = zBar.Init( + _Symbol, + _Period, + bar_index // + ); + has = + has && + zBar.GetPreviousBar(cBar); + has = + has && + cBar.GetPreviousBar(pBar); + has = + has && + pBar.GetPreviousBar(p2Bar); + has = + has && + p2Bar.GetPreviousBar(p3Bar); + has = + has && + p3Bar.GetPreviousBar(p4Bar); + if (!has) + { + // + zBar.Clean(); + cBar.Clean(); + pBar.Clean(); + p2Bar.Clean(); + p3Bar.Clean(); + p4Bar.Clean(); + + // + return; + } + + // + // Define Zone Structure ... + XBoxZone zone; + + // + // Detect Based Order Block using CBar ... + has = barAnalyser.IsOB( + cBar, + zone, + true, // Force FVG Bar Type ... + true // Force Block Two Bar Checking ... + ); + + // + // Ensure a Block is Detected ... + if (!has) + { + // + zone.Clean(); + zBar.Clean(); + cBar.Clean(); + pBar.Clean(); + p2Bar.Clean(); + p3Bar.Clean(); + p4Bar.Clean(); + + // + return; + } + + // + zIDX = zBar.Index(); + cIDX = cBar.Index(); + pIDX = pBar.Index(); + p2IDX = p2Bar.Index(); + p3IDX = p3Bar.Index(); + p4IDX = p4Bar.Index(); + + // + bool isBullish = + has && + zone.IsBullish(); + + // + bool isBearish = + has && + zone.IsBearish(); + + // + int toIDX = zone.ToIndex(); + int fromIDX = zone.FromIndex(); + + // + // Validating p2Bar and p3Bar Direction ... + if (has) + { + // + iDir = Opposit(zone.dir); + + // + has = + iDir == p3Bar.GetDirection() || + iDir == p4Bar.GetDirection(); + if (!has) + { + // + zone.Clean(); + zBar.Clean(); + cBar.Clean(); + pBar.Clean(); + p2Bar.Clean(); + p3Bar.Clean(); + p4Bar.Clean(); + + // + return; + } + } + + // + // Start Validating Block based on + // Detected One ... + + // + // Validating Using Max Range ... + has = maxZoneRangeInPoints > 0; + if (has) + { + // + double range = zone.GetRange(); + has = range <= maxZoneRangeInPoints * mPoints; + if (!has) + { + // + zone.Clean(); + zBar.Clean(); + cBar.Clean(); + pBar.Clean(); + p2Bar.Clean(); + p3Bar.Clean(); + p4Bar.Clean(); + + // + return; + } + } + + // + // Validate Gap Endup with PinBar ... + has = forceHasPinBarEntry; + if (has) + { + // + bool isBullishRejected = + isBullish && + cBar.IsBullish() && + cBar.GetLowShadow() > cBar.GetHighShadow(); + + // + bool isBearishRejected = + isBearish && + cBar.IsBearish() && + cBar.GetLowShadow() < cBar.GetHighShadow(); + + // + has = isBullishRejected || + isBearishRejected; + if (!has) + { + // + zone.Clean(); + zBar.Clean(); + cBar.Clean(); + pBar.Clean(); + p2Bar.Clean(); + p3Bar.Clean(); + p4Bar.Clean(); + + // + return; + } + } + + // + // Validating Gap Bar must a Momentum Bar and + // Breakes out Zone's Directional Edge ... + // for Bullish: Upper + // for Bearish: Lower + has = forceGapBarsBreakout; + if (has) + { + // + // Gap Bar is PBar ... + + // + // Check Gap Bar is Momentum Bar ... + has = barAnalyser.IsMomentum( + pBar, + iDir // + ); + bool isBullishMomentum = + has && + IsBullish(iDir); + bool isBearishMomentum = + has && + IsBearish(iDir); + + // + // Check Gap Bar's Breakout ... + + // + bool isBullishBreakedout = + isBullish && + pBar.IsBullish() && + isBullishMomentum && + pBar.GetUp() > zone.upper && + pBar.GetDown() < zone.upper; + + // + bool isBearishBreakedout = + isBearish && + pBar.IsBearish() && + isBearishMomentum && + pBar.GetUp() > zone.lower && + pBar.GetDown() < zone.lower; + + // + has = isBullishBreakedout || + isBearishBreakedout; + if (!has) + { + // + zone.Clean(); + zBar.Clean(); + cBar.Clean(); + pBar.Clean(); + p2Bar.Clean(); + p3Bar.Clean(); + p4Bar.Clean(); + + // + return; + } + } + + // + // 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 ... + has = forceHasSwing; + if (has) + { + // + // p2Bar ... + bool isP2BarSwing = + barAnalyser + .IsSimpleSwing( + p2Bar, + iDir // + ); + bool isP2BarSwingLow = + isP2BarSwing && + IsBullish(iDir); + bool isP2BarSwingHigh = + isP2BarSwing && + IsBearish(iDir); + + // + // p3Bar ... + bool isP3BarSwing = + barAnalyser + .IsSimpleSwing( + p3Bar, + iDir // + ); + bool isP3BarSwingLow = + isP3BarSwing && + IsBullish(iDir); + bool isP3BarSwingHigh = + isP3BarSwing && + IsBearish(iDir); + + // + bool hasSwingLow = + isBullish && + (isP2BarSwingLow || + isP3BarSwingLow); + + // + bool hasSwingHigh = + isBearish && + (isP2BarSwingHigh || + isP3BarSwingHigh); + + // + has = + hasSwingLow || + hasSwingHigh; + if (!has) + { + // + zone.Clean(); + zBar.Clean(); + cBar.Clean(); + pBar.Clean(); + p2Bar.Clean(); + p3Bar.Clean(); + p4Bar.Clean(); + + // + return; + } + } + + // + // Validating Using Swing Length ... + has = minZoneLength > 0; + if (has) + { + // + XOHCL fromBar; + has = zone.FromBar(fromBar); + if (has) + { + // + // Retrieve HH and LL ... + ll = fromBar.FindLowest(minZoneLength, MODE_LOW); + hh = fromBar.FindHighest(minZoneLength, MODE_HIGH); + + // + // Validate Using HH and LL ... + + // + bool isBullishValid = + isBullish && + ll >= zone.lower; + + // + bool isBearishValid = + isBearish && + hh <= zone.upper; + + // + has = isBullishValid || + isBearishValid; + if (!has) + { + // + zone.Clean(); + zBar.Clean(); + cBar.Clean(); + pBar.Clean(); + p2Bar.Clean(); + p3Bar.Clean(); + p4Bar.Clean(); + + // + return; + } + + // + // Update Zone's From Time ... + zone.from = GetBarTime( + zone.symbol, + zone.period, + fromBar.Index() + minZoneLength // + ); + } + + // + fromBar.Clean(); + } + + // + // Validate Max Allowed Entry Distance ... + has = maxAllowedEntryDistance > 0; + if (has) + { + // + double base = + isBullish + ? zone.upper + : zone.lower; + double entryDistance = MathAbs(zBar.open - base); + has = entryDistance <= maxAllowedEntryDistance * mPoints; + if (!has) + { + // + zone.Clean(); + zBar.Clean(); + cBar.Clean(); + pBar.Clean(); + p2Bar.Clean(); + p3Bar.Clean(); + p4Bar.Clean(); + + // + return; + } + } + + // + // Here we Ensure which have a Valid Zone using Different Applied Validations ... + // from now we are Going to Filtered Validate Zones ... + + // + // Check Exists Filters or not ... + has = filterBasedOnSar || + filterBasedOnRSI || + filterBasedOnADX || + filterBasedOnTrend; + if (has) + { + // + // Do Apply Several Exists Filters ... + + // + // SAR Filter ... + if (filterBasedOnSar) + { + // + // Reading Conditions Values ... + + // + double zSar = sarBuffer[zIDX]; + double cSar = sarBuffer[cIDX]; + double pSar = sarBuffer[pIDX]; + double p2Sar = sarBuffer[p2IDX]; + double p3Sar = sarBuffer[p3IDX]; + double p4Sar = 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 isBullishFiltered = + isBullish && + (isCSarSwitchedToBullish || + isPSarSwitchedToBullish); + + // + bool isBearishFiltered = + isBearish && + (isCSarSwitchedToBearish || + isPSarSwitchedToBearish); + + // + has = + isBullishFiltered || + isBearishFiltered; + if (!has) + { + // + zone.Clean(); + zBar.Clean(); + cBar.Clean(); + pBar.Clean(); + p2Bar.Clean(); + p3Bar.Clean(); + p4Bar.Clean(); + + // + return; + } + } + + // + // RSI Filter ... + if (filterBasedOnRSI) + { + // + // Reading Conditions Values ... + + // + double rsiTrend = (rsiOBLevel + rsiOSLevel) / 2; + + // + double zRSI = rsiBuffer[zIDX]; + double cRSI = rsiBuffer[cIDX]; + double pRSI = rsiBuffer[pIDX]; + double p2RSI = rsiBuffer[p2IDX]; + double p3RSI = rsiBuffer[p3IDX]; + double p4RSI = 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 > rsiOSLevel && + cRSI > rsiOSLevel && + pRSI <= rsiOSLevel; + + // + bool isCBarCrossedUnderOB = + zRSI < rsiOBLevel && + cRSI < rsiOBLevel && + pRSI >= rsiOBLevel; + + // + bool isPBarCrossedOverOS = + zRSI > rsiOSLevel && + cRSI > rsiOSLevel && + pRSI > rsiOSLevel && + p2RSI <= rsiOSLevel; + + // + bool isPBarCrossedUnderOB = + zRSI < rsiOBLevel && + cRSI < rsiOBLevel && + pRSI < rsiOBLevel && + p2RSI >= 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 isBullishFiltered = + isBullish && + ( + // + // Grows ... + isRSIUp + // + || + // + // Crosses ... + (isCBarCrossedOverOS || + isPBarCrossedOverOS) + // + || + // + // V Pattern ... + isCRSIHasVBullishPattern + // + || + // + // Trending ... + (isCRSISwitchedToBullish || + isPRSISwitchedToBullish || + isP2RSISwitchedToBullish) + // + ); + + // + bool isBearishFiltered = + isBearish && + ( + // + // Grows ... + isRSIDown + // + || + // + // Crosses ... + (isCBarCrossedUnderOB || + isPBarCrossedUnderOB) + // + || + // + // V Pattern ... + isCRSIHasVBearishPattern + // + || + // + // Trending ... + (isCRSISwitchedToBearish || + isPRSISwitchedToBearish || + isP2RSISwitchedToBearish) + // + ); + + // + has = + isBullishFiltered || + isBearishFiltered; + if (!has) + { + // + zone.Clean(); + zBar.Clean(); + cBar.Clean(); + pBar.Clean(); + p2Bar.Clean(); + p3Bar.Clean(); + p4Bar.Clean(); + + // + return; + } + } + + // + // ADX Filter ... + if (filterBasedOnADX) + { + // + // Reading Conditions Values ... + + // + // ADX ... + double zADX = adxBuffer[zIDX]; + double cADX = adxBuffer[cIDX]; + double pADX = adxBuffer[pIDX]; + double p2ADX = adxBuffer[p2IDX]; + double p3ADX = adxBuffer[p3IDX]; + double p4ADX = adxBuffer[p4IDX]; + + // + // ADX +DI ... + double zADXP = adxpBuffer[zIDX]; + double cADXP = adxpBuffer[cIDX]; + double pADXP = adxpBuffer[pIDX]; + double p2ADXP = adxpBuffer[p2IDX]; + double p3ADXP = adxpBuffer[p3IDX]; + double p4ADXP = adxpBuffer[p4IDX]; + + // + // ADX -DI ... + double zADXN = adxnBuffer[zIDX]; + double cADXN = adxnBuffer[cIDX]; + double pADXN = adxnBuffer[pIDX]; + double p2ADXN = adxnBuffer[p2IDX]; + double p3ADXN = adxnBuffer[p3IDX]; + double p4ADXN = 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 > adxThreshold; + bool isZADXBearish = zADX < adxThreshold; + + // + bool isCADXBullish = cADX > adxThreshold; + bool isCADXBearish = cADX < adxThreshold; + + // + bool isPADXBullish = pADX > adxThreshold; + bool isPADXBearish = pADX < adxThreshold; + + // + bool isP2ADXBullish = p2ADX > adxThreshold; + bool isP2ADXBearish = p2ADX < adxThreshold; + + // + bool isP3ADXBullish = p3ADX > adxThreshold; + bool isP3ADXBearish = p3ADX < adxThreshold; + + // + bool isP4ADXBullish = p4ADX > adxThreshold; + bool isP4ADXBearish = p4ADX < 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 isBullishFiltered = + isBullish && + ( + // + // Grows ... + isADXUp + // + || + // + // Trending ... + (isCADXSwitchedToBullish || + isPADXSwitchedToBullish) + // + || + // + // Powering ... + (isCADXSwitchedToBullishPower || + isPADXSwitchedToBullishPower) + // + ); + + // + bool isBearishFiltered = + isBearish && + ( + // + // Grows ... + isADXDown + // + || + // + // Trending ... + (isCADXSwitchedToBearish || + isPADXSwitchedToBearish) + // + || + // + // Powering ... + (isCADXSwitchedToBearishPower || + isPADXSwitchedToBearishPower) + // + ); + + // + has = + isBullishFiltered || + isBearishFiltered; + if (!has) + { + // + zone.Clean(); + zBar.Clean(); + cBar.Clean(); + pBar.Clean(); + p2Bar.Clean(); + p3Bar.Clean(); + p4Bar.Clean(); + + // + return; + } + } + + // + // TREND Filter ... + if (filterBasedOnTrend) + { + // + // Reading Conditions Values ... + + // + double zTrend = trendBuffer[zIDX]; + double cTrend = trendBuffer[cIDX]; + double pTrend = trendBuffer[pIDX]; + double p2Trend = trendBuffer[p2IDX]; + double p3Trend = trendBuffer[p3IDX]; + double p4Trend = trendBuffer[p4IDX]; + + // + double trends[] = { + zTrend, + cTrend, + pTrend, + p2Trend, + p3Trend, + p4Trend // + }; + double trendsMin = GetMin(trends); + double trendsMax = GetMax(trends); + double trendsAVG = GetAverage(trends); + + // + double zTrendState = trendStateBuffer[zIDX]; + double cTrendState = trendStateBuffer[cIDX]; + double pTrendState = trendStateBuffer[pIDX]; + double p2TrendState = trendStateBuffer[p2IDX]; + double p3TrendState = trendStateBuffer[p3IDX]; + double p4TrendState = 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 isBullishFiltered = + isBullish && + ( + // + // Grows ... + isTrendUp + // + || + // + // Trend Stating ... + (isCTrendBullish && + isPTrendBullish) + // + || + // + // Switching ... + (isCTrendSwitchedToBullish || + isPTrendSwitchedToBullish) + // + ); + + // + bool isBearishFiltered = + isBearish && + ( + // + // Grows ... + isTrendDown + // + || + // + // Trend Stating ... + (isCTrendBearish && + isPTrendBearish) + // + || + // + // Switching ... + (isCTrendSwitchedToBearish || + isPTrendSwitchedToBearish) + // + ); + + // + has = + isBullishFiltered || + isBearishFiltered; + if (!has) + { + // + zone.Clean(); + zBar.Clean(); + cBar.Clean(); + pBar.Clean(); + p2Bar.Clean(); + p3Bar.Clean(); + p4Bar.Clean(); + + // + return; + } + } + + // + // SCORE Filter ... + + // + // VOLUME Filter ... + } + + // + // Detect Left Side of Box ... + XOHCL zoneLeftBar; + int idx = fromIDX + 1; + bool isBaseValid = true; + while (isBaseValid) + { + // + // Retrieve iteration Bar ... + has = zoneLeftBar.Init( + _Symbol, + _Period, + idx // + ); + if (!has) + { + // + zoneLeftBar.Clean(); + break; + } + + // + // Check Bar's Validation ... + + // + bool isBullishPassed = + isBullish && + zoneLeftBar.low >= zone.lower; + + // + bool isBearishPassed = + isBearish && + zoneLeftBar.high <= zone.upper; + + // + // Summarize Conditions ... + has = + isBullishPassed || + isBearishPassed; + if (!has) + { + break; + } + + // + idx++; + } + + // + // Ray to Left Side Zone, if Provided ... + if (rayLeft) + { + // + // Update Value ... + fromIDX = zone.FromIndex(); + + // + // Check Last Iteration Bar is Valid Bar ... + // then Update Zone from Time ... + has = zoneLeftBar.IsValid(); + if (has) + { + // + zone.from = zoneLeftBar.time; + fromIDX = zone.FromIndex(); + } + } + + // + // Draw Detected Zone ... + if (drawZones) + { + // + XCBoxObject *iZoneObj; + has = drawer.DrawBox( + zone, + iZoneObj // + ); + if (has) + { + // + ApplyStyle(iZoneObj, zone.dir); + + // + mObjects.Add(iZoneObj); + + // + // TODO: Enable This for Debugging ... + // string message = ToString(zone.dir) + " Zone Detected (" + cBar.time + ") ..."; + // Print(message); + } + ZeroMemory(iZoneObj); + } + + // + // Draw RR Tool ... + if (drawRRofZones) + { + // + double rr[]{ + 1, + 1.5, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10 // + }; + XCRRObject *iRRObj; + iRRObj = new XCRRObject(); + has = iRRObj.CreateBoxRR( + drawer.ChartIdentification(), + drawer.SubWindowIdentification(), + zone, + rr, + rrZoneLength // + ); + if (has) + { + // + int iWidth = 2; + ENUM_LINE_STYLE iStyle = STYLE_SOLID; + + // + iRRObj.TPWidth(iWidth); + iRRObj.SLWidth(iWidth); + iRRObj.EntryWidth(iWidth); + iRRObj.TargetWidth(iWidth); + + // + iRRObj.TPStyle(iStyle); + iRRObj.SLStyle(iStyle); + iRRObj.EntryStyle(iStyle); + iRRObj.TargetStyle(iStyle); + + // + iRRObj.TPColor(clrLime); + iRRObj.SLColor(clrRed); + iRRObj.EntryColor(clrYellow); + iRRObj.TargetColor(clrLightBlue); + + // + mObjects.Add(iRRObj); + } + ZeroMemory(iRRObj); + } + + // + // Handle Alerst ... + bool canAlert = + mEnableAlerts && + prevCalculated > 0; + bool canLogOnly = + mEnableAlerts && + prevCalculated == 0; + if (canAlert || canLogOnly) + { + // + string message = + zone.symbol + "," + + ToString(zone.period) + "> " + + ToString(zone.dir) + + " Zone Detected at: " + ToString(zone.to); + + // + if (canLogOnly) + { + alert.LogAlert(message); + } + else if (canAlert) + { + alert.Alert(message); + } + } + + // + // Cleanup Resources ... + + // + zone.Clean(); + zBar.Clean(); + cBar.Clean(); + pBar.Clean(); + p2Bar.Clean(); + p3Bar.Clean(); + p4Bar.Clean(); + zoneLeftBar.Clean(); +} + + + + // + // Detect Trigger Zone ... + // DetectTriggerZone( + // bar_index, + // prevCalculated, + // ratesTotal, + // open, + // high, + // close, + // low, + // tickVolume // + // ); + + + +// +// Implement all Volume and Delta Tests +// Here for Testing Purposes ... +void DoTest(int bar_index) +{ + // + int lastBarIndex = bar_index + 1; + bool isFirstBar = + startCalculationForLastBars > 0 + ? bar_index == startCalculationForLastBars + : bar_index == firstBarIndex; + + // + // Ignore Tests on First Bar ... + if (isFirstBar || + bar_index == firstBarIndex - 1) + { + return; + } + + // + bool has = false; + string iName = NULL; + color iClr = CLR_NONE; + datetime iTime = GetBarTime( + _Symbol, + _Period, + bar_index // + ); + ENUM_X_DIRECTION iDir = X_DIRECTION_NONE; + + // + // Delta Testing ... + + // + double iDelta = deltaBuffer[bar_index]; + double iDeltaPrev = deltaBuffer[lastBarIndex]; + double iDeltaP2 = deltaBuffer[lastBarIndex + 1]; + + // + bool isDeltaUp = iDelta > iDeltaPrev; + bool isDeltaDown = iDelta < iDeltaPrev; + + // + double iDeltaSignal = deltaSignalBuffer[bar_index]; + double iDeltaSignalPrev = deltaSignalBuffer[lastBarIndex]; + + // + bool isDeltaSignalUp = iDeltaSignal > iDeltaSignalPrev; + bool isDeltaSignalDown = iDeltaSignal < iDeltaSignalPrev; + + // + bool isDeltaSwitchedToBullish = + isDeltaUp && + isDeltaSignalUp && + iDelta > iDeltaSignal && + iDeltaPrev < iDeltaSignalPrev; + + // + bool isDeltaSwitchedToBearish = + isDeltaDown && + isDeltaSignalDown && + iDelta < iDeltaSignal && + iDeltaPrev > iDeltaSignalPrev; + + // + if (false && + (isDeltaSwitchedToBullish || + isDeltaSwitchedToBearish)) + { + // + iDir = isDeltaSwitchedToBullish + ? X_DIRECTION_BULLISH + : X_DIRECTION_BEARISH; + + // + iClr = + IsBullish(iDir) + ? clrAqua + : clrMagenta; + + // + iName = ToString(iDir) + "_Delta_" + ToFormatString(iTime); + + // + CChartObjectVLine *iObj; + iObj = new CChartObjectVLine(); + has = iObj.Create( + 0, + iName, + 0, + iTime // + ); + if (has) + { + // + // Style Object ... + iObj.Color(iClr); + + // + // Store Object ... + mObjects.Add(iObj); + } + } + + // + // Volume Testing ... + + // + double iBullishVolumeSignal = bullishVolumeSignalBuffer[bar_index]; + double iBullishVolumeSignalPrev = bullishVolumeSignalBuffer[lastBarIndex]; + + // + bool isBullishVolumeSignalUp = iBullishVolumeSignal > iBullishVolumeSignalPrev; + bool isBullishVolumeSignalDown = iBullishVolumeSignal < iBullishVolumeSignalPrev; + + // + double iBearishVolumeSignal = bearishVolumeSignalBuffer[bar_index]; + double iBearishVolumeSignalPrev = bearishVolumeSignalBuffer[lastBarIndex]; + + // + bool isBearishVolumeSignalUp = iBearishVolumeSignal > iBearishVolumeSignalPrev; + bool isBearishVolumeSignalDown = iBearishVolumeSignal < iBearishVolumeSignalPrev; + + // + bool isVolumeSwitchdToBullish = + isBullishVolumeSignalUp && + !isBearishVolumeSignalUp && + iBullishVolumeSignal > iBearishVolumeSignal && + iBullishVolumeSignalPrev < iBearishVolumeSignalPrev; + + // + bool isVolumeSwitchdToBearish = + isBearishVolumeSignalUp && + !isBullishVolumeSignalUp && + iBearishVolumeSignal > iBullishVolumeSignal && + iBearishVolumeSignalPrev < iBullishVolumeSignalPrev; + + // + if (false && + (isVolumeSwitchdToBullish || + isVolumeSwitchdToBearish)) + { + // + iDir = isVolumeSwitchdToBullish + ? X_DIRECTION_BULLISH + : X_DIRECTION_BEARISH; + + // + iClr = + IsBullish(iDir) + ? clrAqua + : clrMagenta; + + // + iName = ToString(iDir) + "_Volume_" + ToFormatString(iTime); + + // + CChartObjectVLine *iObj; + iObj = new CChartObjectVLine(); + has = iObj.Create( + 0, + iName, + 0, + iTime // + ); + if (has) + { + // + // Style Object ... + iObj.Color(iClr); + + // + // Store Object ... + mObjects.Add(iObj); + } + } + + // + // Signal Bar ... + + // + double iSignalOpen = openSignalBuffer[bar_index]; + double iSignalOpenPrev = openSignalBuffer[lastBarIndex]; + + // + double iSignalClose = closeSignalBuffer[bar_index]; + double iSignalClosePrev = closeSignalBuffer[lastBarIndex]; + + // + bool isSignalBarBullish = iSignalOpen < iSignalClose; + bool isSignalBarBullishPrev = iSignalOpenPrev < iSignalClosePrev; + + // + bool isSignalBarBearish = iSignalOpen > iSignalClose; + bool isSignalBarBearishPrev = iSignalOpenPrev > iSignalClosePrev; + + // + bool isSignalBarSwitchedToBullish = + isSignalBarBullish && + !isSignalBarBullishPrev; + + // + bool isSignalBarSwitchedToBearish = + isSignalBarBearish && + !isSignalBarBearishPrev; + + // + // HK Signal Bar ... + + // + double iHKSignalOpen = openHKSignalBuffer[bar_index]; + double iHKSignalOpenPrev = openHKSignalBuffer[lastBarIndex]; + + // + double iHKSignalClose = closeHKSignalBuffer[bar_index]; + double iHKSignalClosePrev = closeHKSignalBuffer[lastBarIndex]; + + // + bool isHKSignalBarBullish = iHKSignalOpen < iHKSignalClose; + bool isHKSignalBarBullishPrev = iHKSignalOpenPrev < iHKSignalClosePrev; + + // + bool isHKSignalBarBearish = iHKSignalOpen > iHKSignalClose; + bool isHKSignalBarBearishPrev = iHKSignalOpenPrev > iHKSignalClosePrev; + + // + bool isHKSignalBarSwitchedToBullish = + isHKSignalBarBullish && + !isHKSignalBarBullishPrev; + + // + bool isHKSignalBarSwitchedToBearish = + isHKSignalBarBearish && + !isHKSignalBarBearishPrev; + + // + // SAR ... + + // + double iSarState = sarStateBuffer[bar_index]; + double iSarStatePrev = sarStateBuffer[lastBarIndex]; + + // + bool isSarBullish = iSarState > 0; + bool isSarBullishPrev = iSarStatePrev > 0; + + // + bool isSarBearish = iSarState < 0; + bool isSarBearishPrev = iSarStatePrev < 0; + + // + bool isSarSwitchedToBullish = + isSarBullish && + !isSarBullishPrev; + + // + bool isSarSwitchedToBearish = + isSarBearish && + !isSarBearishPrev; + + // + // Full Testing Senario ... + + // + bool isBullish = + isSarSwitchedToBullish && + isDeltaSwitchedToBullish && + isVolumeSwitchdToBullish && + isSignalBarSwitchedToBullish && + isHKSignalBarSwitchedToBullish; + + // + bool isBearish = + isSarSwitchedToBearish && + isDeltaSwitchedToBearish && + isVolumeSwitchdToBearish && + isSignalBarSwitchedToBearish && + isHKSignalBarSwitchedToBearish; + + // + if (true && + (isBullish || + isBearish)) + { + // + iDir = isBullish + ? X_DIRECTION_BULLISH + : X_DIRECTION_BEARISH; + + // + iClr = + IsBullish(iDir) + ? clrAqua + : clrMagenta; + + // + iName = ToString(iDir) + "_BSB_" + ToFormatString(iTime); + + // + CChartObjectVLine *iObj; + iObj = new CChartObjectVLine(); + has = iObj.Create( + 0, + iName, + 0, + iTime // + ); + if (has) + { + // + // Style Object ... + iObj.Color(iClr); + + // + // Store Object ... + mObjects.Add(iObj); + } + } +} diff --git a/Indicators/x-saherelm.x121.xczone.mq5 b/Indicators/x-saherelm.x121.xczone.mq5 index 93df4c92..1e04b0e2 100644 --- a/Indicators/x-saherelm.x121.xczone.mq5 +++ b/Indicators/x-saherelm.x121.xczone.mq5 @@ -21,6 +21,7 @@ // // Definitions ... + // #define ShortName "X121 XCZone" @@ -32,6 +33,161 @@ #include "../Libraries/x-saherelm.common.lib.mq5" #include "../Libraries/x-saherelm.x-poi.lib.mq5" +// +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; +} + +// +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 + + // + XSignal signal; // Pepared Signal + + // + // Constructor ... + XTriggerBlock() + { + Clean(); + } + + // + // Tools ... + + // + // Cleanup ... + void Clean() + { + // + ob.Clean(); + fvg.Clean(); + signal.Clean(); + trigger.Clean(); + swingBar.Clean(); + rLiquidity.Clean(); + fLiquidity.Clean(); + + // + ZeroMemory(this); + } + + // + // Validate ... + bool IsValid() + { + // + bool result = false; + + // + result = ob.IsValid() && + fvg.IsValid() && + trigger.IsValid(); + + // + return result; + } + + // + bool IsBullish() + { + return IsValid() && + ob.IsBullish(); + } + + // + bool IsBearish() + { + return IsValid() && + ob.IsBearish(); + } + + // + int ToIndex() + { + return trigger.ToIndex(); + } + + // + int FromIndex() + { + return trigger.FromIndex(); + } + + // + ENUM_X_DIRECTION GetDirection() + { + // + ENUM_X_DIRECTION result = X_DIRECTION_NONE; + + // + if (IsValid()) + { + result = ob.dir; + } + + // + return result; + } + + // +}; + // // Inputs ... input group "Market"; @@ -59,51 +215,80 @@ input ENUM_X_MA_METHOD hkSignalBarMethod = X_MA_MODE_EMA; // Hiken Ashi Sign // // Validating ... input group "Validating"; -input int minZoneLength = 7; // Minimum Length of Consolidation Zone -input double maxZoneRangeInPoints = 70; // Max Zone Range in Point -input double maxAllowedEntryDistance = 30; // Max Allowed Entry Distance -input bool forceGapBarsBreakout = true; // Force Zone's Gap Bar's Breakes Out -input bool forceHasSwing = true; // Force Zone's Has Propper Swing -input bool forceHasPinBarEntry = true; // Force Zone's Ends with a Pin Bar // // Filtering ... input group "Filtering"; -input bool filterBasedOnSar = false; // Filter Pivots Based on Sar -input bool filterBasedOnRSI = false; // Filter Pivots Based on RSI -input bool filterBasedOnADX = false; // Filter Pivots Based on ADX -input bool filterBasedOnTrend = false; // Filter Pivots Based on Trend // // Presentation ... input group "Presentation"; -input bool showBars = true; // Show Bars -input bool showHKBars = false; // Show Hiken Ashi Bars -input bool showSar = false; // Show Sar -input bool showTrend = false; // Show Trend -input bool showSignalBars = false; // Show Signal Bars -input bool showHKSignalBars = false; // Show Hiken Ashi Signal Bars -input bool rayLeft = false; // Ray to Left -input bool drawZones = true; // Draw Detected Zones -input bool drawRRofZones = true; // Draw Zone's Risk Reward Ratios -input int boxWidth = 2; // Box Width -input color bullishColor = clrLime; // Bullish Color -input color bearishColor = clrRed; // Bearish Color -input ENUM_LINE_STYLE boxStyle = STYLE_SOLID; // Box Style +input bool showBars = true; // Show Bars +input bool showHKBars = false; // Show Hiken Ashi Bars +input bool showSar = false; // Show Sar +input bool showTrend = false; // Show Trend +input bool showTrendBars = false; // Show Trend Bars +input bool showSignalBars = false; // Show Signal Bars +input bool showHKSignalBars = false; // Show Hiken Ashi Signal Bars // -input int startCalculationForLastBars = 5000; // Calculate Last n Bars +// Draws ... +input bool drawZones = true; // Draw Detected Zones +input bool drawSignals = true; // Draw Zone's Risk Reward Ratios + +// +input int startCalculationForLastBars = 1000; // Calculate Last n Bars int sarArrowCode = 159; // Sar Arrow Code int rrZoneLength = 7; // Draw Risk Reward Ratio till n Bars +// +// Styling ... + +// +// Trigger Block ... +input int tbWidth = 1; // Trigger Block Width +input color tbBullishColor = clrAqua; // Trigger Block Bullish Color +input color tbBearishColor = clrMagenta; // Trigger Block Bearish Color +input ENUM_LINE_STYLE tbStyle = STYLE_DASHDOTDOT; // Trigger Block Style + +// +// OB ... +input int obWidth = 1; // OB Width +input color obBullishColor = clrLime; // OB Bullish Color +input color obBearishColor = clrRed; // OB Bearish Color +input ENUM_LINE_STYLE obStyle = STYLE_DOT; // OB Style + +// +// FVG ... +input int fvgWidth = 2; // FVG Width +input color fvgBullishColor = clrLime; // FVG Bullish Color +input color fvgBearishColor = clrRed; // FVG Bearish Color +input ENUM_LINE_STYLE fvgStyle = STYLE_SOLID; // FVG Style + // // Alert ... input group "Alerts"; -input string alertPrefix = ""; // Alert Prefix -input bool _logAlerts = true; // Log Alerts -input bool _pushAlerts = true; // Push Alerts -input bool _mailAlerts = false; // Mail Alerts -input bool _terminalAlerts = true; // Terminal Alerts +input string alertPrefix = ""; // Alert Prefix +input bool _logAlerts = false; // Log Alerts +input bool _pushAlerts = false; // Push Alerts +input bool _mailAlerts = false; // Mail Alerts +input bool _terminalAlerts = false; // Terminal Alerts + +// +// +// +bool forceHasSwing = true; // Force Blocks to Have Swing +bool forceHasFLiquidity = false; // Force Blocks to Have Following Liquidity +bool forceHasRLiquidity = false; // Force Blocks to Have Reversal Liquidity +bool validateGapSequence = true; // Validate Block's Gap Sequence +bool validateBlockEdgeBreakout = true; // Validate Block's Edge Breakout +bool filterBasedOnDelta = false; // Filter Based on Delta +bool filterBasedOnVolume = false; // Filter Based on Volume +bool filterBasedOnSignalBar = false; // Filter Based on Signal Bar +bool filterBasedOnHKSignalBar = false; // Filter Based on Hiken Ashi Signal Bar +bool filterBasedOnSar = false; // Filter Based on Sar +bool filterBasedOnTrend = false; // Filter Based on Trend +bool filterBasedOnTrendBars = false; // Filter Based on Trend Bars // // Buffers ... @@ -346,11 +531,11 @@ int firstBarIndex; // // Bars Color Variables ... -static color _upColor; -static color _downColor; -static color _lineColor; -static color _bullishColor; -static color _bearishColor; +color _upColor = clrLime; +color _downColor = clrRed; +color _lineColor = clrLime; +color _bullishColor = clrLime; +color _bearishColor = clrRed; // XCAlert *alert; @@ -740,7 +925,6 @@ bool ValidateInputs() rsiOBLevel > 0 && rsiOSLevel > 0 && sarMax > sarStep && - minZoneLength > 2 && barsSignalLength > 2 && deltaSignalLength > 2 && hkSignalBarLength > 2 && @@ -768,8 +952,11 @@ int ExtractMaxLengthOfInputs() int result = 0; // - result = MathMax(minZoneLength, rsiLength); - result = MathMax(result, adxLength); + result = MathMax(adxLength, rsiLength); + result = MathMax(result, barsSignalLength); + result = MathMax(result, deltaSignalLength); + result = MathMax(result, volumeSignalLength); + result = MathMax(result, hkSignalBarLength); // return result; @@ -1359,8 +1546,7 @@ void CalculateValues( : hideColorIDX; // - // Detect Trigger Zone ... - DetectTriggerZone( + DetectTriggerBlock( bar_index, prevCalculated, ratesTotal, @@ -1372,8 +1558,19 @@ void CalculateValues( ); } -// -void DetectTriggerZone( +/** + * Detect Trigger Block ... + * + * @param bar_index: int, Specified Bar Index ... + * @param prevCalculated: int, Provides Previous Calculated Bars ... + * @param ratesTotal: int, Provides All Availabled Bars ... + * @param open: double Collection, Provides Open Prices Time Series ... + * @param high: double Collection, Provides High Prices Time Series ... + * @param close: double Collection, Provides Close Prices Time Series ... + * @param low: double Collection, Provides Low Prices Time Series ... + * @param tickVolume: long Collection, Provides Ticks Volume Prices Time Series ... + */ +void DetectTriggerBlock( int bar_index, // Selected Bar Index const int prevCalculated, const int ratesTotal, @@ -1384,9 +1581,6 @@ void DetectTriggerZone( const long &tickVolume[] // ) { - // - // Check Prev Bar ... - // int lastBarIndex = bar_index + 1; int maxBarIndex = startCalculationForLastBars > 0 @@ -1397,1339 +1591,612 @@ void DetectTriggerZone( // // Prevent Calculation ... - if (maxBarIndex - bar_index < minZoneLength) + if (maxBarIndex - bar_index < maxLength) { return; } // int zIDX = 0; - int cIDX = 0; - int pIDX = 0; - int p2IDX = 0; - int p3IDX = 0; - int p4IDX = 0; - double ll = 0; - double hh = 0; bool has = false; - ENUM_X_DIRECTION iDir; + bool isDone = false; + ENUM_X_DIRECTION iDir = X_DIRECTION_NONE; // // 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 ... - - // + XOHCL iBar; + XOHCL zBar; // Current Start Checking Bar (Usually Used for Triggering) ... has = zBar.Init( _Symbol, _Period, bar_index // ); - has = - has && - zBar.GetPreviousBar(cBar); - has = - has && - cBar.GetPreviousBar(pBar); - has = - has && - pBar.GetPreviousBar(p2Bar); - has = - has && - p2Bar.GetPreviousBar(p3Bar); - has = - has && - p3Bar.GetPreviousBar(p4Bar); - if (!has) + + // + if (showTrendBars) { // - zBar.Clean(); - cBar.Clean(); - pBar.Clean(); - p2Bar.Clean(); - p3Bar.Clean(); - p4Bar.Clean(); + XOHCL zTrendBar; + int zTrendIDX = iBarShift( + _Symbol, + mTrendPeriod, + zBar.time // + ); + isDone = + has && + zTrendBar.Init( + _Symbol, + mTrendPeriod, + zTrendIDX + 1 // + ); + if (isDone) + { + // + XCOHCLObject *iObj; + isDone = drawer.CreateBar( + zTrendBar, + iObj, + zBar.time // + ); + if (isDone) + { + // + // Style Object ... - // - return; + // + // Store Object ... + mObjects.Add(iObj); + } + } + zTrendBar.Clean(); } // // Define Zone Structure ... - XBoxZone zone; + XTriggerBlock tb; // - // Detect Based Order Block using CBar ... - has = barAnalyser.IsOB( - cBar, - zone, - true, // Force FVG Bar Type ... - true // Force Block Two Bar Checking ... - ); + bool validateObBarType = true; + bool validateFVGBarType = true; // - // Ensure a Block is Detected ... - if (!has) + // Detect Based Order Block ... + has = + has && + barAnalyser.IsOB( + zBar, + tb.ob, + validateFVGBarType, // Force FVG Bar Type ... + validateObBarType // Force Block Two Bar Checking ... + ); + + // + // Detect Based Fair Value Gap ... + has = + has && + barAnalyser.IsFVG( + zBar, + tb.fvg, + validateFVGBarType // Force FVG Bar Type ... + ); + + // + // Clone Trigger Block ... + if (has) { - // - zone.Clean(); - zBar.Clean(); - cBar.Clean(); - pBar.Clean(); - p2Bar.Clean(); - p3Bar.Clean(); - p4Bar.Clean(); - - // - return; + tb.trigger = tb.ob; } - // - zIDX = zBar.Index(); - cIDX = cBar.Index(); - pIDX = pBar.Index(); - p2IDX = p2Bar.Index(); - p3IDX = p3Bar.Index(); - p4IDX = p4Bar.Index(); - // bool isBullish = has && - zone.IsBullish(); + tb.IsBullish(); // bool isBearish = has && - zone.IsBearish(); + tb.IsBearish(); // - int toIDX = zone.ToIndex(); - int fromIDX = zone.FromIndex(); + int toIDX = tb.ToIndex(); + int fromIDX = tb.FromIndex(); // - // Validating p2Bar and p3Bar Direction ... - if (has) + // Verifications and Filters ... + + // + int loopback = 144; + + // + // Forces ... + + // + // Force Has Proper Swing ... + if (has && + forceHasSwing) { // - iDir = Opposit(zone.dir); - - // - has = - iDir == p3Bar.GetDirection() || - iDir == p4Bar.GetDirection(); - if (!has) + toIDX = tb.ToIndex(); + fromIDX = tb.FromIndex(); + for (int i = toIDX; i < fromIDX; i++) { // - zone.Clean(); - zBar.Clean(); - cBar.Clean(); - pBar.Clean(); - p2Bar.Clean(); - p3Bar.Clean(); - p4Bar.Clean(); - - // - return; - } - } - - // - // Start Validating Block based on - // Detected One ... - - // - // Validating Using Max Range ... - has = maxZoneRangeInPoints > 0; - if (has) - { - // - double range = zone.GetRange(); - has = range <= maxZoneRangeInPoints * mPoints; - if (!has) - { - // - zone.Clean(); - zBar.Clean(); - cBar.Clean(); - pBar.Clean(); - p2Bar.Clean(); - p3Bar.Clean(); - p4Bar.Clean(); - - // - return; - } - } - - // - // Validate Gap Endup with PinBar ... - has = forceHasPinBarEntry; - if (has) - { - // - bool isBullishRejected = - isBullish && - cBar.IsBullish() && - cBar.GetLowShadow() > cBar.GetHighShadow(); - - // - bool isBearishRejected = - isBearish && - cBar.IsBearish() && - cBar.GetLowShadow() < cBar.GetHighShadow(); - - // - has = isBullishRejected || - isBearishRejected; - if (!has) - { - // - zone.Clean(); - zBar.Clean(); - cBar.Clean(); - pBar.Clean(); - p2Bar.Clean(); - p3Bar.Clean(); - p4Bar.Clean(); - - // - return; - } - } - - // - // Validating Gap Bar must a Momentum Bar and - // Breakes out Zone's Directional Edge ... - // for Bullish: Upper - // for Bearish: Lower - has = forceGapBarsBreakout; - if (has) - { - // - // Gap Bar is PBar ... - - // - // Check Gap Bar is Momentum Bar ... - has = barAnalyser.IsMomentum( - pBar, - iDir // - ); - bool isBullishMomentum = - has && - IsBullish(iDir); - bool isBearishMomentum = - has && - IsBearish(iDir); - - // - // Check Gap Bar's Breakout ... - - // - bool isBullishBreakedout = - isBullish && - pBar.IsBullish() && - isBullishMomentum && - pBar.GetUp() > zone.upper && - pBar.GetDown() < zone.upper; - - // - bool isBearishBreakedout = - isBearish && - pBar.IsBearish() && - isBearishMomentum && - pBar.GetUp() > zone.lower && - pBar.GetDown() < zone.lower; - - // - has = isBullishBreakedout || - isBearishBreakedout; - if (!has) - { - // - zone.Clean(); - zBar.Clean(); - cBar.Clean(); - pBar.Clean(); - p2Bar.Clean(); - p3Bar.Clean(); - p4Bar.Clean(); - - // - return; - } - } - - // - // 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 ... - has = forceHasSwing; - if (has) - { - // - // p2Bar ... - bool isP2BarSwing = - barAnalyser - .IsSimpleSwing( - p2Bar, + // Initialize iBar ... + isDone = iBar.Init( + zBar.symbol, + zBar.period, + i // + ); + isDone = + isDone && + barAnalyser.IsSimpleSwing( + iBar, iDir // - ); - bool isP2BarSwingLow = - isP2BarSwing && - IsBullish(iDir); - bool isP2BarSwingHigh = - isP2BarSwing && - IsBearish(iDir); - - // - // p3Bar ... - bool isP3BarSwing = - barAnalyser - .IsSimpleSwing( - p3Bar, - iDir // - ); - bool isP3BarSwingLow = - isP3BarSwing && - IsBullish(iDir); - bool isP3BarSwingHigh = - isP3BarSwing && - IsBearish(iDir); - - // - bool hasSwingLow = - isBullish && - (isP2BarSwingLow || - isP3BarSwingLow); - - // - bool hasSwingHigh = - isBearish && - (isP2BarSwingHigh || - isP3BarSwingHigh); - - // - has = - hasSwingLow || - hasSwingHigh; - if (!has) - { - // - zone.Clean(); - zBar.Clean(); - cBar.Clean(); - pBar.Clean(); - p2Bar.Clean(); - p3Bar.Clean(); - p4Bar.Clean(); - - // - return; - } - } - - // - // Validating Using Swing Length ... - has = minZoneLength > 0; - if (has) - { - // - XOHCL fromBar; - has = zone.FromBar(fromBar); - if (has) - { - // - // Retrieve HH and LL ... - ll = fromBar.FindLowest(minZoneLength, MODE_LOW); - hh = fromBar.FindHighest(minZoneLength, MODE_HIGH); - - // - // Validate Using HH and LL ... - - // - bool isBullishValid = - isBullish && - ll >= zone.lower; - - // - bool isBearishValid = - isBearish && - hh <= zone.upper; - - // - has = isBullishValid || - isBearishValid; - if (!has) + ) && + iDir == tb.GetDirection(); + if (isDone) { // - zone.Clean(); - zBar.Clean(); - cBar.Clean(); - pBar.Clean(); - p2Bar.Clean(); - p3Bar.Clean(); - p4Bar.Clean(); - - // - return; + bool canSet = + !tb.swingBar.IsValid() + ? true + : (isBullish + ? tb.swingBar.low > iBar.low + : tb.swingBar.high < iBar.high); + if (canSet) + { + tb.swingBar = iBar; + } } // - // Update Zone's From Time ... - zone.from = GetBarTime( - zone.symbol, - zone.period, - fromBar.Index() + minZoneLength // + iBar.Clean(); + } + + // + has = tb.swingBar.IsValid(); + } + + // + // Force Has Liquidity ... + if (has && + (forceHasFLiquidity || + forceHasRLiquidity)) + { + // + toIDX = tb.ToIndex(); + fromIDX = tb.FromIndex(); + for (int i = toIDX; i < fromIDX + loopback; i++) + { + // + // Initialize iBar ... + isDone = iBar.Init( + zBar.symbol, + zBar.period, + i // + ); + + // + bool isRejected = + isDone && + barAnalyser.IsRejected( + iBar, + iDir, + false, // Force Bar Type ... + true // Force Fibo Pressure ... + ); + + // + // Following Liquidity ... + bool isFLiq = + isDone && + isRejected && + iDir == tb.GetDirection() && + (isBullish + ? iBar.low < tb.trigger.lower + : iBar.high > tb.trigger.upper); + if (isFLiq && + forceHasFLiquidity && + !tb.fLiquidity.IsValid()) + { + // + FillLiquidity( + iBar, + iDir, + tb.fLiquidity, + tb.trigger.to // + ); + } + + // + // Reversal Liquidity ... + bool isRLiq = + isDone && + isRejected && + Opposit(iDir) == tb.GetDirection() && + (isBullish + ? iBar.low > tb.trigger.upper + : iBar.high < tb.trigger.lower); + if (isRLiq && + forceHasRLiquidity && + !tb.rLiquidity.IsValid()) + { + // + FillLiquidity( + iBar, + iDir, + tb.rLiquidity, + tb.trigger.to // + ); + } + + // + // Checking Conditions ... + isDone = + (!forceHasFLiquidity + ? true + : tb.fLiquidity.IsValid()) && + (!forceHasRLiquidity + ? true + : tb.rLiquidity.IsValid()); + if (isDone) + { + // + iBar.Clean(); + break; + } + + // + iBar.Clean(); + } + + // + // Checking Conditions ... + has = + (!forceHasFLiquidity + ? true + : tb.fLiquidity.IsValid()) && + (!forceHasRLiquidity + ? true + : tb.rLiquidity.IsValid()); + } + + // + // Validations ... + + // + // Validating Gap Sequence means + // Gap Bars must Follow each Other ... + if (has && + validateGapSequence) + { + // + XOHCL iPBar; + toIDX = tb.fvg.ToIndex(); + fromIDX = tb.fvg.FromIndex(); + + // + for (int i = toIDX; i < fromIDX - 1; i++) + { + // + // Initialize iBar ... + has = iBar.Init( + zBar.symbol, + zBar.period, + i // + ); + has = + has && + iBar.GetPreviousBar(iPBar); + has = + has && + (isBullish + ? iBar.low > iPBar.low + : iBar.high < iPBar.high); + if (!has) + { + break; + } + } + + // + iBar.Clean(); + iPBar.Clean(); + } + + // + // Validate Block Edge Breakout ... + if (has && + validateBlockEdgeBreakout) + { + // + has = tb.fvg.ToBar(iBar); + has = + has && + (isBullish + ? (iBar.GetDown() < tb.ob.upper && + iBar.GetUp() > tb.ob.upper) + : (iBar.GetDown() < tb.ob.lower && + iBar.GetUp() > tb.ob.lower)); + + // + iBar.Clean(); + } + + // + // Filters ... + + // + // DELTA ... + if (has && + filterBasedOnDelta) + { + // + double iDelta = deltaBuffer[bar_index]; + double iDeltaPrev = deltaBuffer[lastBarIndex]; + + // + bool isDeltaUp = iDelta > iDeltaPrev; + bool isDeltaDown = iDelta < iDeltaPrev; + + // + double iDeltaSignal = deltaSignalBuffer[bar_index]; + double iDeltaSignalPrev = deltaSignalBuffer[lastBarIndex]; + + // + bool isDeltaSignalUp = iDeltaSignal > iDeltaSignalPrev; + bool isDeltaSignalDown = iDeltaSignal < iDeltaSignalPrev; + + // + bool isDeltaSwitchedToBullish = + isDeltaUp && + isDeltaSignalUp && + iDelta > iDeltaSignal && + iDeltaPrev < iDeltaSignalPrev; + + // + bool isDeltaSwitchedToBearish = + isDeltaDown && + isDeltaSignalDown && + iDelta < iDeltaSignal && + iDeltaPrev > iDeltaSignalPrev; + + // + has = + has && + (isBullish + ? isDeltaSwitchedToBullish + : isDeltaSwitchedToBearish); + } + + // + // VOLUME ... + if (has && + filterBasedOnVolume) + { + // + double iBullishVolumeSignal = bullishVolumeSignalBuffer[bar_index]; + double iBullishVolumeSignalPrev = bullishVolumeSignalBuffer[lastBarIndex]; + + // + bool isBullishVolumeSignalUp = iBullishVolumeSignal > iBullishVolumeSignalPrev; + bool isBullishVolumeSignalDown = iBullishVolumeSignal < iBullishVolumeSignalPrev; + + // + double iBearishVolumeSignal = bearishVolumeSignalBuffer[bar_index]; + double iBearishVolumeSignalPrev = bearishVolumeSignalBuffer[lastBarIndex]; + + // + bool isBearishVolumeSignalUp = iBearishVolumeSignal > iBearishVolumeSignalPrev; + bool isBearishVolumeSignalDown = iBearishVolumeSignal < iBearishVolumeSignalPrev; + + // + bool isVolumeSwitchdToBullish = + isBullishVolumeSignalUp && + !isBearishVolumeSignalUp && + iBullishVolumeSignal > iBearishVolumeSignal && + iBullishVolumeSignalPrev < iBearishVolumeSignalPrev; + + // + bool isVolumeSwitchdToBearish = + isBearishVolumeSignalUp && + !isBullishVolumeSignalUp && + iBearishVolumeSignal > iBullishVolumeSignal && + iBearishVolumeSignalPrev < iBullishVolumeSignalPrev; + + // + has = + has && + (isBullish + ? isVolumeSwitchdToBullish + : isVolumeSwitchdToBearish); + } + + // + // SIGNAL Bar ... + if (has && + filterBasedOnSignalBar) + { + // + double iSignalOpen = openSignalBuffer[bar_index]; + double iSignalOpenPrev = openSignalBuffer[lastBarIndex]; + + // + double iSignalClose = closeSignalBuffer[bar_index]; + double iSignalClosePrev = closeSignalBuffer[lastBarIndex]; + + // + bool isSignalBarBullish = iSignalOpen < iSignalClose; + bool isSignalBarBullishPrev = iSignalOpenPrev < iSignalClosePrev; + + // + bool isSignalBarBearish = iSignalOpen > iSignalClose; + bool isSignalBarBearishPrev = iSignalOpenPrev > iSignalClosePrev; + + // + bool isSignalBarSwitchedToBullish = + isSignalBarBullish && + !isSignalBarBullishPrev; + + // + bool isSignalBarSwitchedToBearish = + isSignalBarBearish && + !isSignalBarBearishPrev; + + // + has = + has && + (isBullish + ? isSignalBarSwitchedToBullish + : isSignalBarSwitchedToBearish); + } + + // + // HK SIGNAL Bar ... + if (has && + filterBasedOnHKSignalBar) + { + // + double iHKSignalOpen = openHKSignalBuffer[bar_index]; + double iHKSignalOpenPrev = openHKSignalBuffer[lastBarIndex]; + + // + double iHKSignalClose = closeHKSignalBuffer[bar_index]; + double iHKSignalClosePrev = closeHKSignalBuffer[lastBarIndex]; + + // + bool isHKSignalBarBullish = iHKSignalOpen < iHKSignalClose; + bool isHKSignalBarBullishPrev = iHKSignalOpenPrev < iHKSignalClosePrev; + + // + bool isHKSignalBarBearish = iHKSignalOpen > iHKSignalClose; + bool isHKSignalBarBearishPrev = iHKSignalOpenPrev > iHKSignalClosePrev; + + // + bool isHKSignalBarSwitchedToBullish = + isHKSignalBarBullish && + !isHKSignalBarBullishPrev; + + // + bool isHKSignalBarSwitchedToBearish = + isHKSignalBarBearish && + !isHKSignalBarBearishPrev; + + // + has = + has && + (isBullish + ? isHKSignalBarSwitchedToBullish + : isHKSignalBarSwitchedToBearish); + } + + // + // SAR ... + if (has && + filterBasedOnSar) + { + // + double iSarState = sarStateBuffer[bar_index]; + double iSarStatePrev = sarStateBuffer[lastBarIndex]; + + // + bool isSarBullish = iSarState > 0; + bool isSarBullishPrev = iSarStatePrev > 0; + + // + bool isSarBearish = iSarState < 0; + bool isSarBearishPrev = iSarStatePrev < 0; + + // + bool isSarSwitchedToBullish = + isSarBullish && + !isSarBullishPrev; + + // + bool isSarSwitchedToBearish = + isSarBearish && + !isSarBearishPrev; + + // + has = + has && + (isBullish + ? isSarSwitchedToBullish + : isSarSwitchedToBearish); + } + + // + // TREND ... + if (has && + filterBasedOnTrend) + { + // + double iTrendState = trendStateBuffer[bar_index]; + double iTrendStatePrev = trendStateBuffer[lastBarIndex]; + + // + bool isTrendBullish = iTrendState > 0; + bool isTrendBullishPrev = iTrendStatePrev > 0; + + // + bool isTrendBearish = iTrendState < 0; + bool isTrendBearishPrev = iTrendStatePrev < 0; + + // + double trends[]; + int toIDX = tb.ToIndex(); + int fromIDX = tb.FromIndex(); + double iTrend = trendBuffer[toIDX]; + for (int i = toIDX; i <= fromIDX; i++) + { + // + Add( + trendBuffer[i], + trends // ); } + double trendsMin = GetMin(trends); + double trendsMax = GetMax(trends); + double trendsAVG = GetAverage(trends); // - fromBar.Clean(); - } - - // - // Validate Max Allowed Entry Distance ... - has = maxAllowedEntryDistance > 0; - if (has) - { - // - double base = - isBullish - ? zone.upper - : zone.lower; - double entryDistance = MathAbs(zBar.open - base); - has = entryDistance <= maxAllowedEntryDistance * mPoints; - if (!has) - { - // - zone.Clean(); - zBar.Clean(); - cBar.Clean(); - pBar.Clean(); - p2Bar.Clean(); - p3Bar.Clean(); - p4Bar.Clean(); - - // - return; - } - } - - // - // Here we Ensure which have a Valid Zone using Different Applied Validations ... - // from now we are Going to Filtered Validate Zones ... - - // - // Check Exists Filters or not ... - has = filterBasedOnSar || - filterBasedOnRSI || - filterBasedOnADX || - filterBasedOnTrend; - if (has) - { - // - // Do Apply Several Exists Filters ... + bool isTrendUp = + iTrend > trendsMin && + iTrend >= trendsAVG; // - // SAR Filter ... - if (filterBasedOnSar) - { - // - // Reading Conditions Values ... - - // - double zSar = sarBuffer[zIDX]; - double cSar = sarBuffer[cIDX]; - double pSar = sarBuffer[pIDX]; - double p2Sar = sarBuffer[p2IDX]; - double p3Sar = sarBuffer[p3IDX]; - double p4Sar = 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 isBullishFiltered = - isBullish && - (isCSarSwitchedToBullish || - isPSarSwitchedToBullish); - - // - bool isBearishFiltered = - isBearish && - (isCSarSwitchedToBearish || - isPSarSwitchedToBearish); - - // - has = - isBullishFiltered || - isBearishFiltered; - if (!has) - { - // - zone.Clean(); - zBar.Clean(); - cBar.Clean(); - pBar.Clean(); - p2Bar.Clean(); - p3Bar.Clean(); - p4Bar.Clean(); - - // - return; - } - } + bool isTrendDown = + iTrend < trendsMax && + iTrend <= trendsAVG; // - // RSI Filter ... - if (filterBasedOnRSI) - { - // - // Reading Conditions Values ... - - // - double rsiTrend = (rsiOBLevel + rsiOSLevel) / 2; - - // - double zRSI = rsiBuffer[zIDX]; - double cRSI = rsiBuffer[cIDX]; - double pRSI = rsiBuffer[pIDX]; - double p2RSI = rsiBuffer[p2IDX]; - double p3RSI = rsiBuffer[p3IDX]; - double p4RSI = 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 > rsiOSLevel && - cRSI > rsiOSLevel && - pRSI <= rsiOSLevel; - - // - bool isCBarCrossedUnderOB = - zRSI < rsiOBLevel && - cRSI < rsiOBLevel && - pRSI >= rsiOBLevel; - - // - bool isPBarCrossedOverOS = - zRSI > rsiOSLevel && - cRSI > rsiOSLevel && - pRSI > rsiOSLevel && - p2RSI <= rsiOSLevel; - - // - bool isPBarCrossedUnderOB = - zRSI < rsiOBLevel && - cRSI < rsiOBLevel && - pRSI < rsiOBLevel && - p2RSI >= 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 isBullishFiltered = - isBullish && - ( - // - // Grows ... - isRSIUp - // - || - // - // Crosses ... - (isCBarCrossedOverOS || - isPBarCrossedOverOS) - // - || - // - // V Pattern ... - isCRSIHasVBullishPattern - // - || - // - // Trending ... - (isCRSISwitchedToBullish || - isPRSISwitchedToBullish || - isP2RSISwitchedToBullish) - // - ); - - // - bool isBearishFiltered = - isBearish && - ( - // - // Grows ... - isRSIDown - // - || - // - // Crosses ... - (isCBarCrossedUnderOB || - isPBarCrossedUnderOB) - // - || - // - // V Pattern ... - isCRSIHasVBearishPattern - // - || - // - // Trending ... - (isCRSISwitchedToBearish || - isPRSISwitchedToBearish || - isP2RSISwitchedToBearish) - // - ); - - // - has = - isBullishFiltered || - isBearishFiltered; - if (!has) - { - // - zone.Clean(); - zBar.Clean(); - cBar.Clean(); - pBar.Clean(); - p2Bar.Clean(); - p3Bar.Clean(); - p4Bar.Clean(); - - // - return; - } - } + bool isTrendSwitchedToBullish = + isTrendUp && + isTrendBullish && + !isTrendBullishPrev; // - // ADX Filter ... - if (filterBasedOnADX) - { - // - // Reading Conditions Values ... - - // - // ADX ... - double zADX = adxBuffer[zIDX]; - double cADX = adxBuffer[cIDX]; - double pADX = adxBuffer[pIDX]; - double p2ADX = adxBuffer[p2IDX]; - double p3ADX = adxBuffer[p3IDX]; - double p4ADX = adxBuffer[p4IDX]; - - // - // ADX +DI ... - double zADXP = adxpBuffer[zIDX]; - double cADXP = adxpBuffer[cIDX]; - double pADXP = adxpBuffer[pIDX]; - double p2ADXP = adxpBuffer[p2IDX]; - double p3ADXP = adxpBuffer[p3IDX]; - double p4ADXP = adxpBuffer[p4IDX]; - - // - // ADX -DI ... - double zADXN = adxnBuffer[zIDX]; - double cADXN = adxnBuffer[cIDX]; - double pADXN = adxnBuffer[pIDX]; - double p2ADXN = adxnBuffer[p2IDX]; - double p3ADXN = adxnBuffer[p3IDX]; - double p4ADXN = 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 > adxThreshold; - bool isZADXBearish = zADX < adxThreshold; - - // - bool isCADXBullish = cADX > adxThreshold; - bool isCADXBearish = cADX < adxThreshold; - - // - bool isPADXBullish = pADX > adxThreshold; - bool isPADXBearish = pADX < adxThreshold; - - // - bool isP2ADXBullish = p2ADX > adxThreshold; - bool isP2ADXBearish = p2ADX < adxThreshold; - - // - bool isP3ADXBullish = p3ADX > adxThreshold; - bool isP3ADXBearish = p3ADX < adxThreshold; - - // - bool isP4ADXBullish = p4ADX > adxThreshold; - bool isP4ADXBearish = p4ADX < 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 isBullishFiltered = - isBullish && - ( - // - // Grows ... - isADXUp - // - || - // - // Trending ... - (isCADXSwitchedToBullish || - isPADXSwitchedToBullish) - // - || - // - // Powering ... - (isCADXSwitchedToBullishPower || - isPADXSwitchedToBullishPower) - // - ); - - // - bool isBearishFiltered = - isBearish && - ( - // - // Grows ... - isADXDown - // - || - // - // Trending ... - (isCADXSwitchedToBearish || - isPADXSwitchedToBearish) - // - || - // - // Powering ... - (isCADXSwitchedToBearishPower || - isPADXSwitchedToBearishPower) - // - ); - - // - has = - isBullishFiltered || - isBearishFiltered; - if (!has) - { - // - zone.Clean(); - zBar.Clean(); - cBar.Clean(); - pBar.Clean(); - p2Bar.Clean(); - p3Bar.Clean(); - p4Bar.Clean(); - - // - return; - } - } + bool isTrendSwitchedToBearish = + isTrendDown && + isTrendBearish && + !isTrendBearishPrev; // - // TREND Filter ... - if (filterBasedOnTrend) - { - // - // Reading Conditions Values ... - - // - double zTrend = trendBuffer[zIDX]; - double cTrend = trendBuffer[cIDX]; - double pTrend = trendBuffer[pIDX]; - double p2Trend = trendBuffer[p2IDX]; - double p3Trend = trendBuffer[p3IDX]; - double p4Trend = trendBuffer[p4IDX]; - - // - double trends[] = { - zTrend, - cTrend, - pTrend, - p2Trend, - p3Trend, - p4Trend // - }; - double trendsMin = GetMin(trends); - double trendsMax = GetMax(trends); - double trendsAVG = GetAverage(trends); - - // - double zTrendState = trendStateBuffer[zIDX]; - double cTrendState = trendStateBuffer[cIDX]; - double pTrendState = trendStateBuffer[pIDX]; - double p2TrendState = trendStateBuffer[p2IDX]; - double p3TrendState = trendStateBuffer[p3IDX]; - double p4TrendState = 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 isBullishFiltered = - isBullish && - ( - // - // Grows ... - isTrendUp - // - || - // - // Trend Stating ... - (isCTrendBullish && - isPTrendBullish) - // - || - // - // Switching ... - (isCTrendSwitchedToBullish || - isPTrendSwitchedToBullish) - // - ); - - // - bool isBearishFiltered = - isBearish && - ( - // - // Grows ... - isTrendDown - // - || - // - // Trend Stating ... - (isCTrendBearish && - isPTrendBearish) - // - || - // - // Switching ... - (isCTrendSwitchedToBearish || - isPTrendSwitchedToBearish) - // - ); - - // - has = - isBullishFiltered || - isBearishFiltered; - if (!has) - { - // - zone.Clean(); - zBar.Clean(); - cBar.Clean(); - pBar.Clean(); - p2Bar.Clean(); - p3Bar.Clean(); - p4Bar.Clean(); - - // - return; - } - } - - // - // SCORE Filter ... - - // - // VOLUME Filter ... - } - - // - // Detect Left Side of Box ... - XOHCL zoneLeftBar; - int idx = fromIDX + 1; - bool isBaseValid = true; - while (isBaseValid) - { - // - // Retrieve iteration Bar ... - has = zoneLeftBar.Init( - _Symbol, - _Period, - idx // - ); - if (!has) - { - // - zoneLeftBar.Clean(); - break; - } - - // - // Check Bar's Validation ... - - // - bool isBullishPassed = - isBullish && - zoneLeftBar.low >= zone.lower; - - // - bool isBearishPassed = - isBearish && - zoneLeftBar.high <= zone.upper; - - // - // Summarize Conditions ... has = - isBullishPassed || - isBearishPassed; - if (!has) - { - break; - } - - // - idx++; + has && + (isBullish + ? isTrendSwitchedToBullish + : isTrendSwitchedToBearish); } // - // Ray to Left Side Zone, if Provided ... - if (rayLeft) + // Handle Draw ... + if (has && + drawZones) { - // - // Update Value ... - fromIDX = zone.FromIndex(); - - // - // Check Last Iteration Bar is Valid Bar ... - // then Update Zone from Time ... - has = zoneLeftBar.IsValid(); - if (has) - { - // - zone.from = zoneLeftBar.time; - fromIDX = zone.FromIndex(); - } - } - - // - // Draw Detected Zone ... - if (drawZones) - { - // - XCBoxObject *iZoneObj; - has = drawer.DrawBox( - zone, - iZoneObj // - ); - if (has) - { - // - ApplyStyle(iZoneObj, zone.dir); - - // - mObjects.Add(iZoneObj); - - // - // TODO: Enable This for Debugging ... - // string message = ToString(zone.dir) + " Zone Detected (" + cBar.time + ") ..."; - // Print(message); - } - ZeroMemory(iZoneObj); - } - - // - // Draw RR Tool ... - if (drawRRofZones) - { - // - double rr[]{ - 1, - 1.5, - 2, - 3, - 4, - 5, - 6, - 7, - 8, - 9, - 10 // - }; - XCRRObject *iRRObj; - iRRObj = new XCRRObject(); - has = iRRObj.CreateBoxRR( - drawer.ChartIdentification(), - drawer.SubWindowIdentification(), - zone, - rr, - rrZoneLength // - ); - if (has) - { - // - int iWidth = 2; - ENUM_LINE_STYLE iStyle = STYLE_SOLID; - - // - iRRObj.TPWidth(iWidth); - iRRObj.SLWidth(iWidth); - iRRObj.EntryWidth(iWidth); - iRRObj.TargetWidth(iWidth); - - // - iRRObj.TPStyle(iStyle); - iRRObj.SLStyle(iStyle); - iRRObj.EntryStyle(iStyle); - iRRObj.TargetStyle(iStyle); - - // - iRRObj.TPColor(clrLime); - iRRObj.SLColor(clrRed); - iRRObj.EntryColor(clrYellow); - iRRObj.TargetColor(clrLightBlue); - - // - mObjects.Add(iRRObj); - } - ZeroMemory(iRRObj); + DrawTB(tb); } // @@ -2740,14 +2207,16 @@ void DetectTriggerZone( bool canLogOnly = mEnableAlerts && prevCalculated == 0; - if (canAlert || canLogOnly) + if (has && + (canAlert || + canLogOnly)) { // string message = - zone.symbol + "," + - ToString(zone.period) + "> " + - ToString(zone.dir) + - " Zone Detected at: " + ToString(zone.to); + tb.trigger.symbol + "," + + ToString(tb.trigger.period) + "> " + + ToString(tb.trigger.dir) + + " Zone Detected at: " + ToString(tb.trigger.to); // if (canLogOnly) @@ -2764,42 +2233,9 @@ void DetectTriggerZone( // Cleanup Resources ... // - zone.Clean(); + tb.Clean(); zBar.Clean(); - cBar.Clean(); - pBar.Clean(); - p2Bar.Clean(); - p3Bar.Clean(); - p4Bar.Clean(); - zoneLeftBar.Clean(); -} - -// -void ApplyStyle( - XCBoxObject *iObj, - ENUM_X_DIRECTION dir // -) -{ - // - if (!HasDirection(dir) || iObj == NULL) - { - return; - } - - // - int width = boxWidth > 0 - ? boxWidth - : 1; - int clr = IsBullish(dir) - ? bullishColor - : bearishColor; - - // - iObj.BoxColor(clr); - iObj.BoxWidth(width); - iObj.BoxStyle(boxStyle); - - // + iBar.Clean(); } // @@ -2844,4 +2280,292 @@ void HideBars() SetChartBearishColor(CLR_NONE, chartId); } +// +// Draw Specific Trigger Block ... +bool DrawTB( + XTriggerBlock &trigger, + datetime to = NULL // +) +{ + // + bool result = false; + + // + // Validate Args ... + result = 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; + } + + // + bool isBullish = trigger.IsBullish(); + + // + // Draw OB ... + if (trigger.ob.IsValid()) + { + // + XCBoxObject *iOBObj; + result = drawer.DrawBox( + trigger.ob, + iOBObj // + ); + if (result) + { + // + // Style Object ... + + // + color iClr = + isBullish + ? obBullishColor + : obBearishColor; + + // + iOBObj.BoxColor(iClr); + iOBObj.BoxWidth(obWidth); + iOBObj.BoxStyle(obStyle); + + // + // Store Object ... + mObjects.Add(iOBObj); + } + ZeroMemory(iOBObj); + + // + if (!result) + { + return result; + } + } + + // + // Draw FVG ... + if (trigger.fvg.IsValid()) + { + // + XCBoxObject *iFVGObj; + result = drawer.DrawBox( + trigger.fvg, + iFVGObj // + ); + if (result) + { + // + // Style Object ... + + // + color iClr = + isBullish + ? fvgBullishColor + : fvgBearishColor; + + // + iFVGObj.BoxColor(iClr); + iFVGObj.BoxWidth(fvgWidth); + iFVGObj.BoxStyle(fvgStyle); + + // + // Store Object ... + mObjects.Add(iFVGObj); + } + ZeroMemory(iFVGObj); + + // + if (!result) + { + return result; + } + } + + // + // Draw Trigger ... + if (trigger.trigger.IsValid()) + { + // + XCBoxObject *iTriggerObj; + result = drawer.DrawBox( + trigger.trigger, + iTriggerObj // + ); + if (result) + { + // + // Style Object ... + + // + color iClr = + isBullish + ? tbBullishColor + : tbBearishColor; + + // + iTriggerObj.BoxColor(iClr); + iTriggerObj.BoxWidth(tbWidth); + iTriggerObj.BoxStyle(tbStyle); + + // + // Store Object ... + mObjects.Add(iTriggerObj); + } + ZeroMemory(iTriggerObj); + + // + if (!result) + { + return result; + } + } + + // + // Draw Liquidities ... + + // + // Reversla Liquidity ... + if (trigger.rLiquidity.IsValid()) + { + // + XCBoxObject *iLiqObj; + result = drawer.DrawBox( + trigger.rLiquidity, + iLiqObj // + ); + if (result) + { + mObjects.Add(iLiqObj); + } + ZeroMemory(iLiqObj); + + // + if (!result) + { + return result; + } + } + + // + // Following Liquidity ... + if (trigger.fLiquidity.IsValid()) + { + // + XCBoxObject *iLiqObj; + result = drawer.DrawBox( + trigger.fLiquidity, + iLiqObj // + ); + if (result) + { + mObjects.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 = drawer.CreateBarArrow( + trigger.swingBar, + swingObj, + swingPType, + 159, + swingColor // + ); + if (result) + { + mObjects.Add(swingObj); + } + ZeroMemory(swingObj); + + // + if (!result) + { + return result; + } + } + + // + // Draw RR of Signal ... + if (trigger.signal.IsValid() && + rrZoneLength > 0) + { + // + XCRRObject *iRRObj; + iRRObj = new XCRRObject(); + result = iRRObj.Create( + drawer.ChartIdentification(), + drawer.SubWindowIdentification(), + trigger.signal, + rrZoneLength // + ); + if (result) + { + // + int iWidth = 2; + ENUM_LINE_STYLE iStyle = STYLE_SOLID; + + // + iRRObj.TPWidth(iWidth); + iRRObj.SLWidth(iWidth); + iRRObj.EntryWidth(iWidth); + iRRObj.TargetWidth(iWidth); + + // + iRRObj.TPStyle(iStyle); + iRRObj.SLStyle(iStyle); + iRRObj.EntryStyle(iStyle); + iRRObj.TargetStyle(iStyle); + + // + iRRObj.TPColor(clrLime); + iRRObj.SLColor(clrRed); + iRRObj.EntryColor(clrYellow); + iRRObj.TargetColor(clrLightBlue); + + // + mObjects.Add(iRRObj); + } + ZeroMemory(iRRObj); + + // + if (result) + { + return result; + } + } + + // + return result; +} + // \ No newline at end of file