// // // // Now we Have to Detect Spike Breake Ruls ... // // for Bullish: bar.low goes Below of pBar.low ... // // for Bearish: bar.high goes Above of pBar.high ... // for (int i = toIDX; i > pBarIndex; i--) // { // // // // Initialize iBar ... // result = iBar.Init( // bar.symbol, // bar.period, // i // // ); // result = // result && // iBar.GetPreviousBar(iPBar); // if (result) // { // // // if (isBullish) // { // result = iBar.low < iPBar.low; // } // else if (isBearish) // { // result = iBar.high > iPBar.high; // } // // // if (result) // { // break; // } // } // // // iBar.Clean(); // iPBar.Clean(); // } // if (!result) // { // // // ob.Clean(); // fvg.Clean(); // box.Clean(); // pBar.Clean(); // iBar.Clean(); // iPBar.Clean(); // swingBar.Clean(); // liquidity.Clean(); // // // return result; // } // // // // Update Box ... // if (isBullish) // { // box.upper = MathMax(box.upper, iBar.GetDown()); // } // else if (isBearish) // { // box.lower = MathMin(box.lower, iBar.GetUp()); // } bool IsTrigger( XOHCL &bar, XBoxZone &box, XBoxZone &ob, XBoxZone &fvg, XBoxZone &liquidity, XOHCL &swingBar, int loopback = 10, int hlDistance = 300, double maxAlowedRange = 0.0, bool forceOBOppositBar = true, bool forceFVGBarType = true, bool forceSwingBar = true, bool forceGapBarBreakout = true, bool forceCheckBarsSequence = true, bool lookingEntry = false, bool forceLiquidity = true, bool forceLiquidityUsed = true, bool forceEntryBar = true, bool forceEntryBarPower = true // ) { // bool result = false; // // Normalize Args ... ob.Clean(); fvg.Clean(); box.Clean(); swingBar.Clean(); liquidity.Clean(); loopback = NormalizeInt(loopback, 5); // // Validate Args ... result = bar.IsValid(); if (!result) { return result; } // XOHCL pBar; XOHCL iBar; XOHCL iPBar; int barIndex; int pBarIndex; ENUM_X_DIRECTION iDir; // result = bar.GetPreviousBar(pBar); if (!result) { // ob.Clean(); fvg.Clean(); box.Clean(); pBar.Clean(); iBar.Clean(); iPBar.Clean(); swingBar.Clean(); liquidity.Clean(); // return result; } // barIndex = bar.Index(); pBarIndex = pBar.Index(); // // Loopback to Find a Block ... for (int i = pBarIndex; i < pBarIndex + loopback; i++) { // // Inital IBar ... result = iBar.Init( bar.symbol, bar.period, i // ); if (!result) { break; } // // Detect Block ... result = IsOB( iBar, ob, forceFVGBarType, forceOBOppositBar // ); if (result) { // // Validate Block Last Bars ... if (forceOBOppositBar) { // XOHCL fromBar; XOHCL fromBarPrev; result = ob.FromBar(fromBar); result = result && fromBar.GetPreviousBar(fromBarPrev); result = result && (ob.IsBullish() ? fromBarPrev.IsBearish() : fromBarPrev.IsBullish()); if (result) { // // Detect FVG ... result = IsFVG( iBar, fvg, forceFVGBarType // ); if (result) { // box.Clone(ob); box.type = "XTRG"; box.from = fromBarPrev.time; break; } } // fromBar.Clean(); fromBarPrev.Clean(); } // break; } // iBar.Clean(); } iBar.Clean(); result = box.IsValid(); if (!result) { // ob.Clean(); fvg.Clean(); box.Clean(); pBar.Clean(); iBar.Clean(); iPBar.Clean(); swingBar.Clean(); liquidity.Clean(); // return result; } // // Filter Using Max Allowed Range ... if (maxAlowedRange > 0) { // result = box.GetRange() <= (maxAlowedRange * GetPoints(bar.symbol)); if (!result) { // ob.Clean(); fvg.Clean(); box.Clean(); pBar.Clean(); iBar.Clean(); iPBar.Clean(); swingBar.Clean(); liquidity.Clean(); // return result; } } // // Validate Gap Bar ... if (forceGapBarBreakout) { // // We Have to Check Gap Bar's Breakout ... result = fvg.ToBar(iBar); result = result && iBar.GetPreviousBar(iPBar); result = result && (box.IsBullish() ? iPBar.close > ob.upper : iPBar.close < ob.lower); if (!result) { // ob.Clean(); fvg.Clean(); box.Clean(); pBar.Clean(); iBar.Clean(); iPBar.Clean(); swingBar.Clean(); liquidity.Clean(); // return result; } // iBar.Clean(); iPBar.Clean(); } // // Validate HH LL Distance ... if (hlDistance > 0) { // result = ob.FromBar(iBar); if (result) { // double ll = iBar.FindLowest(iBar.Index() + hlDistance, MODE_LOW); double hh = iBar.FindHighest(iBar.Index() + hlDistance, MODE_HIGH); // result = ll > 0 && hh > 0 && ob.upper < hh && ob.lower > ll; } // if (!result) { // ob.Clean(); fvg.Clean(); box.Clean(); pBar.Clean(); iBar.Clean(); iPBar.Clean(); swingBar.Clean(); liquidity.Clean(); // return result; } // iBar.Clean(); } // int toIDX = box.ToIndex(); int fromIDX = box.FromIndex(); bool isBullish = box.IsBullish(); bool isBearish = box.IsBearish(); // // We Have to Make sure Bars until Spikes Closed ... // for Bullish: bars must Close Above box.upper ... // for Bearish: bars must Close Below box.lower ... for (int i = pBarIndex; i < toIDX; i++) { // // Initialize iBar ... result = iBar.Init( bar.symbol, bar.period, i // ); result = result && (isBullish ? iBar.close > box.upper : iBar.close < box.lower); // if (!result) { break; } // iBar.Clean(); } iBar.Clean(); if (!result) { // ob.Clean(); fvg.Clean(); box.Clean(); pBar.Clean(); iBar.Clean(); iPBar.Clean(); swingBar.Clean(); liquidity.Clean(); // return result; } // // Detect Swing Bar ... int swingBarIDX = -1; int swingLoopback = fromIDX - pBarIndex; if (isBullish) { // // Looking for Swing Low ... swingBarIDX = pBar.FindLowestIndex(swingLoopback, MODE_LOW); } else if (isBearish) { // // Looking for Swing High ... swingBarIDX = pBar.FindHighestIndex(swingLoopback, MODE_LOW); } result = IsValidIndex(swingBarIDX); if (!result) { // ob.Clean(); fvg.Clean(); box.Clean(); pBar.Clean(); iBar.Clean(); iPBar.Clean(); swingBar.Clean(); liquidity.Clean(); // return result; } // // Initialize Swing Bar ... result = swingBar.Init( bar.symbol, bar.period, swingBarIDX // ); if (forceSwingBar) { // result = result && IsSimpleSwing( swingBar, iDir // ) && iDir == fvg.dir; } if (!result) { // ob.Clean(); fvg.Clean(); box.Clean(); pBar.Clean(); iBar.Clean(); iPBar.Clean(); swingBar.Clean(); liquidity.Clean(); // return result; } // // Update Trigger Box ... if (isBullish) { box.lower = MathMin(box.lower, swingBar.GetDown()); } else if (isBearish) { box.upper = MathMin(box.upper, swingBar.GetUp()); } // // Validating Bar Sequence ... if (forceCheckBarsSequence) { // // Now we Have to Check Spike from Swing Bar Next till Current Bar ... // To Validate Highs and Lows ... for (int i = pBarIndex; i < pBarIndex + (swingBarIDX - pBarIndex) - 1; i++) { // // Initialize iBar ... result = iBar.Init( bar.symbol, bar.period, i // ); result = result && iBar.GetPreviousBar(iPBar); if (!result) { break; } // // Since we Go Backward Bars from Current Bar ... // for Bullish: each Bar Low Must over Prev Bar Low ... // for Bearish: each Bar High Must Under Prev Bar High ... if (isBullish) { // result = result && iBar.low > iPBar.low; } else if (isBearish) { // result = result && iBar.high < iPBar.high; } if (!result) { break; } // iBar.Clean(); iPBar.Clean(); } if (!result) { // ob.Clean(); fvg.Clean(); box.Clean(); pBar.Clean(); iBar.Clean(); iPBar.Clean(); swingBar.Clean(); liquidity.Clean(); // return result; } // box.to = pBar.time; // iBar.Clean(); iPBar.Clean(); } // toIDX = box.ToIndex(); fromIDX = box.FromIndex(); // // Liquidity ... if (forceLiquidity) { // // Checking Swing Bar is Liquidity ... result = IsRejected( swingBar, iDir, true, // Force Bar Type ... true // Foce Fibo Pressure ... ) && iDir == fvg.dir; if (result) { // // Filling Liquidity ... liquidity.dir = iDir; liquidity.to = box.to; liquidity.type = "XLQ"; liquidity.from = swingBar.time; liquidity.symbol = swingBar.symbol; liquidity.period = swingBar.period; liquidity.upper = isBullish ? swingBar.GetDown() : swingBar.high; liquidity.lower = isBullish ? swingBar.low : swingBar.GetUp(); // result = liquidity.IsValid(); } result = liquidity.IsValid(); if (!result) { // ob.Clean(); fvg.Clean(); box.Clean(); pBar.Clean(); iBar.Clean(); iPBar.Clean(); swingBar.Clean(); liquidity.Clean(); // return result; } // // Check Liquidity Usage ... if (forceLiquidityUsed) { // // now We have to Ensure Detected Liqudity is Used ... toIDX = box.ToIndex(); fromIDX = liquidity.FromIndex(); for (int i = fromIDX - 1; i >= toIDX; i--) { // // Initialize iBar ... result = iBar.Init( bar.symbol, bar.period, i // ); result = result && (isBullish ? iBar.low < liquidity.upper : iBar.high > liquidity.lower); if (result) { break; } // iBar.Clean(); } if (!result) { // ob.Clean(); fvg.Clean(); box.Clean(); pBar.Clean(); iBar.Clean(); iPBar.Clean(); swingBar.Clean(); liquidity.Clean(); // return result; } } } // // Looking for Entry ... if (lookingEntry) { // // Entry Bar ... if (forceEntryBar) { // // Validate Bar is Not Opposit Powered Bar ... // // Momentum ... bool isMomentum = IsMomentum( bar, iDir, 1 // ); bool isBullishMomentum = isMomentum && IsBullish(iDir); bool isBearishMomentum = isMomentum && IsBearish(iDir); // // Engulfed ... bool isEngulfed = IsEngulfed( bar, iDir // ); bool isBullishEngulfed = isEngulfed && IsBullish(iDir); bool isBearishEngulfed = isEngulfed && IsBearish(iDir); // // Rejected ... bool isRejected = IsRejected( bar, iDir, false, true // ); bool isBullishRejected = isRejected && IsBullish(iDir); bool isBearishRejected = isRejected && IsBearish(iDir); // bool isBullishPowered = isBullishMomentum || isBullishEngulfed || isBullishRejected; // bool isBearishPowered = isBearishMomentum || isBearishEngulfed || isBearishRejected; // // Make Sure Entry Bar is a Valid Bar ... result = isBullish ? !isBearishPowered && (!forceEntryBarPower ? true : isBullishPowered) : !isBullishPowered && (!forceEntryBarPower ? true : isBearishPowered); if (!result) { // ob.Clean(); fvg.Clean(); box.Clean(); pBar.Clean(); iBar.Clean(); iPBar.Clean(); swingBar.Clean(); liquidity.Clean(); // return result; } } // // Check Entry Bar Sequences ... if (forceCheckBarsSequence) { // // if Sequences is Important ... // we have to detect sequence Breaker Bar ... result = result && (isBullish ? bar.low < pBar.low : bar.high > pBar.high); } // // Validate Bar Close ... result = result && (isBullish ? bar.close > box.lower : bar.close < box.upper); } // if (!lookingEntry) { result = fvg.to == pBar.time; } // // Cleanup Resources ... // iBar.Clean(); pBar.Clean(); iPBar.Clean(); // if (!result) { // ob.Clean(); fvg.Clean(); box.Clean(); swingBar.Clean(); swingBar.Clean(); liquidity.Clean(); } // 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); } } }