diff --git a/Classes/x-saherelm.x-bar.analyser.class.mq5 b/Classes/x-saherelm.x-bar.analyser.class.mq5 index 01e14dc0..a9481fb9 100644 --- a/Classes/x-saherelm.x-bar.analyser.class.mq5 +++ b/Classes/x-saherelm.x-bar.analyser.class.mq5 @@ -615,6 +615,9 @@ class XCBarAnalyser : public XCBase return result; } + /** + * Detect Range Block ... + */ bool DetectRangeBlocks( XOHCL &bar, XBoxZone &upper, @@ -728,6 +731,97 @@ class XCBarAnalyser : public XCBase return result; } + /** + * Calculate Specified Bars Range Volume ... + * + * @param bar: XOHCL instance reference ... + * @param bullishVolume: double + * @param bearishVolume: double + * @param loopback: int + * + * @return ( bool ) + */ + bool CalculateRangeVolume( + XOHCL &bar, + double &bullishVolume, + double &bearishVolume, + int loopback = 5 // + ) + { + // + bool result = false; + + // + // Normalize Args ... + bullishVolume = 0; + bearishVolume = 0; + loopback = NormalizeInt(loopback, 3); + + // + // Validate ... + result = bar.IsValid(); + if (!result) + { + return result; + } + + // + XOHCL iBar; + bool has = false; + int start = bar.Index(); + int end = start + loopback; + for (int i = start; i <= end; i++) + { + // + iBar.Clean(); + has = iBar.Init( + bar.symbol, + bar.period, + i // + ); + if (!has) + { + // + iBar.Clean(); + + // + break; + } + + // + bool isBullish = iBar.IsBullish(); + bool isBearish = iBar.IsBearish(); + + // + if (isBullish) + { + bullishVolume += (double)iBar.volume; + } + else if (isBearish) + { + bearishVolume += (double)iBar.volume; + } + else + { + // + bullishVolume += (double)iBar.volume; + bearishVolume += (double)iBar.volume; + } + + // + iBar.Clean(); + } + + // + result = iBar.IsValid(); + + // + iBar.Clean(); + + // + return result; + } + /** * Detect Same Bars ... * @@ -1081,838 +1175,6 @@ class XCBarAnalyser : public XCBase // // Actions ... - /** - * Detect Spike ... - * - * @param bar: XOHCL instance reference, Start Bar ... - * @param dir: ENUM_X_DIRECTION member, Event Direction ... - * @param type: ENUM_X_PRICE member, Price Type ... - * @param forcBodyInRange: bool, Use Body in Range Detection ... - * @param rangeExtendMultiplier: double, a Multiplier for Checking Price Range ... - * @param sameBars: int, Specified How Many Same Bars Required for an Spike ... - * - * @return ( bool ) - */ - bool IsSpike( - XOHCL &bar, - ENUM_X_DIRECTION &dir, - int &rootIDX, - ENUM_X_PRICE type = X_PRICE_CLOSE, - bool forcBodyInRange = true, - double rangeExtendMultiplier = 2.0, - int sameBars = 3 // - ) - { - // - bool result = false; - - // - dir = X_DIRECTION_NONE; - sameBars = NormalizeInt(sameBars, 2); - - // - result = IsValid(type) && - bar.IsValid(); - if (!result) - { - return result; - } - - // - // First We Have to Has a Big Change ... - int sharpRootIDX = -1; - result = IsSharp( - bar, - dir, - sharpRootIDX, - type, - forcBodyInRange, - rangeExtendMultiplier // - ); - if (!result) - { - return result; - } - - // - // Check Has Same Bars ... - int sameBarsIndex = -1; - ENUM_X_DIRECTION sameBarsDir; - result = HasSameBars( - bar, - sameBarsDir, - sameBarsIndex, - sameBars // - ); - if (!result) - { - return result; - } - - // - // Check Same Bars Direction sames To Price Change ... - result = sameBarsDir == dir; - if (!result) - { - return result; - } - - // - rootIDX = sharpRootIDX; - - // - return result; - } - - /** - * Check a Bar is Support Bar or not ... - * - * @param bar: XOHCL instance ... - * @param supportBar: XOHCL instance, Provides Fouded Support Bar ... - * @param range: Integer, Specified Verifiation Range ... - * - * @return ( bool ) - */ - bool HasSupport( - XOHCL &bar, - XOHCL &supportBar, - int range = 21 // - ) - { - // - bool result = false; - - // - result = bar.IsValid(); - if (!result) - { - return result; - } - - // - int supportIDX = bar.Index() + range; - result = supportBar.Init( - bar.symbol, - bar.period, - supportIDX // - ); - if (!result) - { - // - supportBar.Clean(); - return result; - } - - // - result = bar.low > supportBar.low; - if (!result) - { - // - supportBar.Clean(); - return result; - } - - // - // Validate Point ... - for (int i = 1; i < range; i++) - { - // - XOHCL iPBar; - XOHCL iNBar; - bool iHas = false; - - // - iHas = iPBar.Init( - bar.symbol, - bar.period, - supportIDX + i // - ); - result = iHas; - if (!result) - { - break; - } - - // - iHas = iNBar.Init( - bar.symbol, - bar.period, - supportIDX - i // - ); - result = iHas; - if (!result) - { - break; - } - - // - result = supportBar.low < iPBar.low && - supportBar.low < iNBar.low; - if (!result) - { - break; - } - } - - // - return result; - } - - /** - * Check a Bar is Resistance Bar or not ... - * - * @param bar: XOHCL instance ... - * @param resistanceBar: XOHCL instance, Provides Fouded Support Bar ... - * @param range: Integer, Specified Verifiation Range ... - * - * @return ( bool ) - */ - bool HasResistance( - XOHCL &bar, - XOHCL &resistanceBar, - int range = 21 // - ) - { - // - bool result = false; - - // - result = bar.IsValid(); - if (!result) - { - return result; - } - - // - int resistanceIDX = bar.Index() + range; - result = resistanceBar.Init( - bar.symbol, - bar.period, - resistanceIDX // - ); - if (!result) - { - // - resistanceBar.Clean(); - return result; - } - - // - result = bar.high < resistanceBar.high; - if (!result) - { - // - resistanceBar.Clean(); - return result; - } - - // - // Validate Point ... - for (int i = 1; i < range; i++) - { - // - XOHCL iPBar; - XOHCL iNBar; - bool iHas = false; - - // - iHas = iPBar.Init( - bar.symbol, - bar.period, - resistanceIDX + i // - ); - result = iHas; - if (!result) - { - break; - } - - // - iHas = iNBar.Init( - bar.symbol, - bar.period, - resistanceIDX - i // - ); - result = iHas; - if (!result) - { - break; - } - - // - result = resistanceBar.high > iPBar.high && - resistanceBar.high > iNBar.high; - if (!result) - { - break; - } - } - - // - return result; - } - - /** - * Detect a Fair Value Gap Based on Given Bar ... - * - * @param bar: XOHCL instance, Specified Start Bar ... - * @param fromBar: XOHCL instance, Provides Start Bar of FVG ... - * @param toBar: XOHCL instance, Provides End Bar of FVG ... - * @param dir: ENUM_X_DIRECTION member, Specified Founded Order Block Direction ... - * @param sameBars: Integer, Specified Min Same Bars for Detecting Order Block ... - * @return ( bool ) - */ - bool HasFairValueGap( - XOHCL &bar, - XOHCL &fromBar, - XOHCL &toBar, - ENUM_X_DIRECTION &dir, - int sameBars = 3 // - ) - { - // - bool result = false; - - // - toBar.Clean(); - fromBar.Clean(); - dir = X_DIRECTION_NONE; - sameBars = NormalizeInt(sameBars, 1); - - // - result = bar.IsValid(); - if (!result) - { - // - toBar.Clean(); - fromBar.Clean(); - return result; - } - - // - int index = 0; - result = HasSameBars( - bar, - dir, - index, - sameBars // - ); - if (!result) - { - return result; - } - - // - bool isBullish = IsBullish(dir); - - // - int to = bar.Index(); - int from = - index > (to + sameBars) - ? to + sameBars - : index; - for (int i = from; i > to; i--) - { - // - result = fromBar.Init( - bar.symbol, - bar.period, - i // - ); - if (!result) - { - break; - } - - // - result = toBar.Init( - bar.symbol, - bar.period, - i - 2 // - ); - if (!result) - { - break; - } - - // - result = isBullish - ? fromBar.high < toBar.low - : fromBar.low > toBar.high; - if (result) - { - break; - } - } - - // - if (!result) - { - // - toBar.Clean(); - fromBar.Clean(); - dir = X_DIRECTION_NONE; - } - - // - return result; - } - - /** - * Detect an Order Block Based on Given Bar ... - * - * @param bar: XOHCL instance, Specified Start Bar ... - * @param ob: XOHCL instance, Fill it if Order Block Found ... - * @param dir: ENUM_X_DIRECTION member, Specified Founded Order Block Direction ... - * @param sameBars: Integer, Specified Min Same Bars for Detecting Order Block ... - * - * @return ( bool ) - */ - bool HasOrderBlock( - XOHCL &bar, - XOHCL &ob, - ENUM_X_DIRECTION &dir, - int sameBars = 3, - bool forceSpike = true, - bool forceFairValueGap = true, - bool forceSupportResistance = true // - ) - { - // - bool result = false; - - // - ob.Clean(); - dir = X_DIRECTION_NONE; - sameBars = NormalizeInt(sameBars, 1); - - // - result = bar.IsValid(); - if (!result) - { - return result; - } - - // - XOHCL sBar; - if (bar.Index() == 0) - { - // - result = bar.GetPreviousBar(sBar); - if (!result) - { - // - sBar.Clean(); - return result; - } - } - else - { - sBar = bar; - } - - // - // First Step We Have to Check Same Bars ... - int spikeRootIDX = -1; - int sameBarsIndex = -1; - result = HasSameBars( - bar, - dir, - sameBarsIndex, - sameBars // - ); - if (!result) - { - // - ob.Clean(); - return result; - } - - // - // Must an Spike Happens ... - if (forceSpike) - { - // - ENUM_X_DIRECTION spikeDir; - result = IsSpike( - bar, - spikeDir, - spikeRootIDX, // Spike Root Index ... - X_PRICE_CLOSE, // Price Type ... - true, // Force Body ... - 1.5, // Range Extend Multiplier ... - sameBars // - ); - result = - result && - dir == spikeDir; - if (!result) - { - // - ob.Clean(); - return result; - } - } - - // - // Select OB Candidate Bars ... - - XOHCL sameBar; - XOHCL rootBar; - XOHCL rootPBar; - result = sameBar.Init( - bar.symbol, - bar.period, - sameBarsIndex + 1 // - ); - if (!result) - { - // - sBar.Clean(); - sameBar.Clean(); - return result; - } - result = rootBar.Init( - bar.symbol, - bar.period, - spikeRootIDX // - ); - if (!result) - { - // - sBar.Clean(); - rootBar.Clean(); - sameBar.Clean(); - return result; - } - result = rootBar.GetPreviousBar(rootPBar); - if (!result) - { - // - sBar.Clean(); - rootBar.Clean(); - sameBar.Clean(); - rootPBar.Clean(); - return result; - } - - // - // Select ob Bar ... - if (rootBar.GetDirection() == Opposit(dir)) - { - ob = rootBar; - } - else if (rootPBar.GetDirection() == Opposit(dir)) - { - ob = rootPBar; - } - else if (sameBar.GetDirection() == Opposit(dir)) - { - ob = sameBar; - } - else - { - ob.Clean(); - } - - // - // Select Order Block Bar ... - result = ob.IsValid(); - ENUM_X_DIRECTION obDir = ob.GetDirection(); - result = - result && - dir == Opposit(obDir); - if (!result) - { - // - sBar.Clean(); - rootBar.Clean(); - sameBar.Clean(); - rootPBar.Clean(); - - // - return result; - } - - // - // if Bullish OB => Supports ... - // if Bearish OB => Resistance ... - if (forceSupportResistance) - { - // - XOHCL supResBar; - - // - // Check Support ... - bool isSupport = HasSupport( - ob, - supResBar // - ); - - // - // Check Resistance ... - bool isResistance = HasResistance( - ob, - supResBar // - ); - - // - supResBar.Clean(); - - // - result = - result && - (IsBullish(dir) - ? isSupport - : isResistance); - - // - if (!result) - { - // - ob.Clean(); - sBar.Clean(); - rootBar.Clean(); - sameBar.Clean(); - rootPBar.Clean(); - - // - return result; - } - } - - // - // Force Check Fair ValueGaps ... - if (forceFairValueGap) - { - // - XOHCL toBar; - XOHCL fromBar; - ENUM_X_DIRECTION fvgDir; - bool isFVG = HasFairValueGap( - bar, - fromBar, - toBar, - fvgDir, - sameBars // - ); - - // - result = - isFVG && - result && - dir == fvgDir; - - // - toBar.Clean(); - fromBar.Clean(); - } - - // - // Cleanup Resource ... - - // - sBar.Clean(); - rootBar.Clean(); - sameBar.Clean(); - rootPBar.Clean(); - - // - return result; - } - - /** - * Check a Bar has Consolidation Zone or not ... - * - * @param bar: XOHCL instance, Specified Start Bar ... - * @param zone: XConsolidationZone instance, consolidation Zone Object ... - * @param minLoopback: int, min Allowed Lopback for Consolidating ... - * @param range: double, Consolidation Range ... - * @param upperAppliedTo: ENUM_X_PRICE member, Upper Selection Price ... - * @param lowerAppliedTo: ENUM_X_PRICE member, Lower Selection Price ... - * - * @return ( bool ) - */ - bool HasConsolidationZone( - XOHCL &bar, - XConsolidationZone &zone, - int minLoopback = 7, - double range = 50, - ENUM_X_PRICE upperAppliedTo = X_PRICE_HIGH, - ENUM_X_PRICE lowerAppliedTo = X_PRICE_LOW // - ) - { - // - bool result = false; - - // - zone.Clean(); - range = NormalizeDouble(range, 50); - minLoopback = NormalizeInt(minLoopback, 7); - - // - result = bar.IsValid(); - if (!result) - { - return result; - } - - // - double points = GetPoints(bar.symbol); - int index = bar.Index() + 1; - int length = minLoopback; - - // - double upperPrice[]; - int upperPriceCount = FillPrice( - upperPrice, - bar, - length, - upperAppliedTo // - ); - - // - double lowerPrice[]; - int lowerPriceCount = FillPrice( - lowerPrice, - bar, - length, - lowerAppliedTo // - ); - - // - result = upperPriceCount == lowerPriceCount && - lowerPriceCount == length; - if (!result) - { - // - Clean(upperPrice); - Clean(lowerPrice); - - // - return result; - } - - // - double upper = upperPrice[ArrayMaximum(upperPrice)]; - double lower = lowerPrice[ArrayMinimum(lowerPrice)]; - - // - bool isBullishBreake = - bar.low > lower && - bar.high > upper && - bar.GetUp() > upper; - bool isBearishBreake = - bar.high < upper && - bar.low < lower && - bar.GetDown() < lower; - result = isBullishBreake || - isBearishBreake; - if (!result) - { - // - Clean(upperPrice); - Clean(lowerPrice); - - // - return result; - } - - // - double delta = upper - lower; - result = delta <= range * points; - if (!result) - { - // - Clean(upperPrice); - Clean(lowerPrice); - - // - return result; - } - - // - while (delta <= range * points) - { - // - length++; - - // - upperPriceCount = FillPrice( - upperPrice, - bar, - length, - upperAppliedTo // - ); - - // - lowerPriceCount = FillPrice( - lowerPrice, - bar, - length, - lowerAppliedTo // - ); - - // - bool isValid = upperPriceCount == lowerPriceCount && - lowerPriceCount == length; - if (!isValid) - { - break; - } - - // - double iUpper = upperPrice[ArrayMaximum(upperPrice)]; - double iLower = lowerPrice[ArrayMinimum(lowerPrice)]; - - // - delta = iUpper - iLower; - if (delta <= range * points) - { - // - upper = iUpper; - lower = iLower; - } - } - - // - Clean(upperPrice); - Clean(lowerPrice); - - // - // Filling Zone ... - zone.upper = upper; - zone.lower = lower; - zone.symbol = bar.symbol; - zone.period = bar.period; - zone.to = iTime( - bar.symbol, - bar.period, - bar.Index() + 1 // - ); - zone.from = iTime( - bar.symbol, - bar.period, - bar.Index() + length // - ); - zone.dir = isBullishBreake - ? X_DIRECTION_BULLISH - : X_DIRECTION_BEARISH; - - // - result = zone.IsValid(); - if (!result) - { - zone.Clean(); - } - - // - return result; - } - - // - // Custom Logics ... - /** * Check a Bar is End of an OrderBlock Bar or Not ... * @@ -3391,31 +2653,31 @@ class XCBarAnalyser : public XCBase return result; } - // - // - // - /** - * Check a Bar is Valid for Specified Direction of Positions ... + * Check Specified Bar is Sequence Edge Breaker Bar or not ... * - * @param bar: XOHCL instance, Start Bar ... - * @param dir: ENUM_X_DIRECTION member, Provide Direction ... + * @param bar: XOHCL instance reference, Specified Bar to Check ... + * @param dir: ENUM_X_DIRECTION member, Holds Founded Direction ... + * @param loopback: int, Specified Loopback ... * * @return ( bool ) */ - bool IsValidForPosition( + bool IsSeqBreakEdge( XOHCL &bar, - ENUM_X_DIRECTION &dir // + ENUM_X_DIRECTION &dir, + int loopback = 3 // ) { // bool result = false; // - int loopback = 3; + // Normalize Args ... dir = X_DIRECTION_NONE; + loopback = NormalizeInt(loopback, 3); // + // Validate Args ... result = bar.IsValid(); if (!result) { @@ -3423,137 +2685,103 @@ class XCBarAnalyser : public XCBase } // - // DOJI ... - ENUM_X_DIRECTION dojiDir; - bool isDoji = IsDoji( - bar, - dojiDir // - ); - bool isBullishDoji = - isDoji && - IsBullish(dojiDir); - bool isBearishDoji = - isDoji && - IsBearish(dojiDir); + bool isBullish = false; + bool isBearish = false; // - // SWING ... - ENUM_X_DIRECTION swingDir; - bool isSwing = IsSwing( - bar, - swingDir // - ); - bool isBullishSwing = - isSwing && - IsBullish(swingDir); - bool isBearishSwing = - isSwing && - IsBearish(swingDir); + // Check Has Sequence or not ... + XOHCL pBar; + XOHCL iBar; + XOHCL iPBar; + bool has = false; + int index = bar.Index(); + int start = index + 1; + int end = start + loopback - 1; + bool hasBullishSeq = true; + bool hasBearishSeq = true; + for (int i = start; i < end; i++) + { + // + // Initialize Indexed Bar(s) ... + has = iBar.Init( + bar.symbol, + bar.period, + i // + ); + has = + has && + iBar.GetPreviousBar(iPBar); + + // + // Bullish Sequence ... + if (hasBullishSeq) + { + // + hasBullishSeq = + has && + iBar.low > iPBar.low; + } + + // + // Bearish Sequence ... + if (hasBearishSeq) + { + // + hasBearishSeq = + has && + iBar.high < iPBar.high; + } + + // + if (!hasBullishSeq && + !hasBearishSeq) + { + break; + } + + // + iBar.Clean(); + iPBar.Clean(); + } + iBar.Clean(); + iPBar.Clean(); // - // HAMMER ... - ENUM_X_DIRECTION hammerDir; - bool isHammer = IsHammer( - bar, - hammerDir // - ); - bool isBullishHammer = - isHammer && - IsBullish(hammerDir); - bool isBearishHammer = - isHammer && - IsBearish(hammerDir); + // Check a Sequence Detect ... + result = hasBullishSeq || + hasBearishSeq; + if (!result) + { + // + pBar.Clean(); + iBar.Clean(); + iPBar.Clean(); + + // + return result; + } // - // ENGULF ... - ENUM_X_DIRECTION engulfDir; - bool isEngulfed = IsEngulfed( - bar, - engulfDir // - ); - bool isBullishEngulfed = - isEngulfed && - IsBullish(engulfDir); - bool isBearishEngulfed = - isEngulfed && - IsBearish(engulfDir); + // Retrieve Previous Bar ... + result = bar.GetPreviousBar(pBar); // - // REJECTED ... - ENUM_X_DIRECTION rejectedDir; - bool isRejected = IsRejected( - bar, - rejectedDir // - ); - bool isBullishRejected = - isRejected && - IsBullish(rejectedDir); - bool isBearishRejected = - isRejected && - IsBearish(rejectedDir); + // Now we Have Ensure has a Sequence ... // - // MOMENTUM ... - ENUM_X_DIRECTION momentumDir; - bool isMomentum = IsMomentum( - bar, - momentumDir // - ); - bool isBullishMomentum = - isMomentum && - IsBullish(momentumDir); - bool isBearishMomentum = - isMomentum && - IsBearish(momentumDir); + isBullish = + result && + hasBearishSeq && + bar.high > pBar.high; // - // PULLBACK ... - ENUM_X_DIRECTION pullbackDir; - bool isPullback = IsPullback( - bar, - pullbackDir // - ); - bool isBullishPullback = - isPullback && - IsBullish(pullbackDir); - bool isBearishPullback = - isPullback && - IsBearish(pullbackDir); - - // - // Summarize Conditions ... - - // - bool isBullishOr = - isBullishDoji || - isBullishSwing || - isBullishHammer || - isBullishEngulfed || - isBullishRejected || - isBullishMomentum || - isBullishPullback; - - // - bool isBearishOr = - isBearishDoji || - isBearishSwing || - isBearishHammer || - isBearishEngulfed || - isBearishRejected || - isBearishMomentum || - isBearishPullback; - - // - bool isBullish = - isBullishOr && - !isBearishOr; - - // - bool isBearish = - !isBullishOr && - isBearishOr; + isBearish = + result && + hasBullishSeq && + bar.low < pBar.low; // + // Summarizing Result ... result = isBullish || isBearish; if (result) @@ -3565,28 +2793,29 @@ class XCBarAnalyser : public XCBase : X_DIRECTION_BEARISH; } + // + // Cleanup Resources ... + pBar.Clean(); + iBar.Clean(); + iPBar.Clean(); + // return result; } - // - // Implement Some Custom Senarios ... - /** - * Calculate Specified Bars Range Volume ... + * Check Specified Bar is Sequence Type Breaker Bar or not ... * - * @param bar: XOHCL instance reference ... - * @param bullishVolume: double - * @param bearishVolume: double - * @param loopback: int + * @param bar: XOHCL instance reference, Specified Bar to Check ... + * @param dir: ENUM_X_DIRECTION member, Holds Founded Direction ... + * @param loopback: int, Specified Loopback ... * * @return ( bool ) */ - bool CalculateRangeVolume( + bool IsSeqBreakType( XOHCL &bar, - double &bullishVolume, - double &bearishVolume, - int loopback = 5 // + ENUM_X_DIRECTION &dir, + int loopback = 3 // ) { // @@ -3594,12 +2823,11 @@ class XCBarAnalyser : public XCBase // // Normalize Args ... - bullishVolume = 0; - bearishVolume = 0; + dir = X_DIRECTION_NONE; loopback = NormalizeInt(loopback, 3); // - // Validate ... + // Validate Args ... result = bar.IsValid(); if (!result) { @@ -3607,58 +2835,601 @@ class XCBarAnalyser : public XCBase } // + bool isBullish = false; + bool isBearish = false; + + // + // Check Has Sequence or not ... XOHCL iBar; bool has = false; - int start = bar.Index(); + int index = bar.Index(); + int start = index + 1; int end = start + loopback; - for (int i = start; i <= end; i++) + bool hasBullishSeq = true; + bool hasBearishSeq = true; + for (int i = start; i < end; i++) { // - iBar.Clean(); + // Initialize Indexed Bar(s) ... has = iBar.Init( bar.symbol, bar.period, i // ); - if (!has) + + // + // Bullish Sequence ... + if (hasBullishSeq) { // - iBar.Clean(); + hasBullishSeq = + has && + iBar.IsBullish(); + } + // + // Bearish Sequence ... + if (hasBearishSeq) + { // + hasBearishSeq = + has && + iBar.IsBearish(); + } + + // + if (!hasBullishSeq && + !hasBearishSeq) + { break; } - // - bool isBullish = iBar.IsBullish(); - bool isBearish = iBar.IsBearish(); - - // - if (isBullish) - { - bullishVolume += (double)iBar.volume; - } - else if (isBearish) - { - bearishVolume += (double)iBar.volume; - } - else - { - // - bullishVolume += (double)iBar.volume; - bearishVolume += (double)iBar.volume; - } - // iBar.Clean(); } - - // - result = iBar.IsValid(); - - // iBar.Clean(); + // + // Check a Sequence Detect ... + result = hasBullishSeq || + hasBearishSeq; + if (!result) + { + // + iBar.Clean(); + + // + return result; + } + + // + // Now we Have Ensure has a Sequence ... + + // + isBullish = + result && + hasBearishSeq && + bar.IsBullish(); + + // + isBearish = + result && + hasBullishSeq && + bar.IsBearish(); + + // + // Summarizing Result ... + result = isBullish || + isBearish; + if (result) + { + // + dir = + isBullish + ? X_DIRECTION_BULLISH + : X_DIRECTION_BEARISH; + } + + // + // Cleanup Resources ... + iBar.Clean(); + + // + return result; + } + + /** + * Check Specified Bar is Fully Sequence Breker Bar or not ... + * + * @param bar: XOHCL instance reference, Specified Bar to Check ... + * @param dir: ENUM_X_DIRECTION member, Holds Founded Direction ... + * @param loopback: int, Specified Loopback ... + * + * @return ( bool ) + */ + bool IsSeqBreak( + XOHCL &bar, + ENUM_X_DIRECTION &dir, + int loopback = 3 // + ) + { + // + bool result = false; + + // + // Normalize Args ... + dir = X_DIRECTION_NONE; + loopback = NormalizeInt(loopback, 3); + + // + // Validate Args ... + result = bar.IsValid(); + if (!result) + { + return result; + } + + // + // Check Seq Edge ... + ENUM_X_DIRECTION seqEdgeDir; + bool isSeqEdgeBreaked = IsSeqBreakEdge( + bar, + seqEdgeDir // + ); + + // + // Check Seq Type ... + ENUM_X_DIRECTION seqTypeDir; + bool isSeqTypeBreaked = IsSeqBreakType( + bar, + seqTypeDir // + ); + + // + // Check Result ... + result = isSeqEdgeBreaked && + isSeqTypeBreaked && + seqEdgeDir == seqTypeDir; + if (result) + { + dir = seqEdgeDir; + } + + // + return result; + } + + // + // + // + + /** + * Check a Bar is Valid for Specified Direction of Positions ... + * + * @param bar: XOHCL instance, Start Bar ... + * @param dir: ENUM_X_DIRECTION member, Provide Direction ... + * + * @return ( bool ) + */ + bool IsValidForTrigger( + XOHCL &bar, + ENUM_X_DIRECTION &dir, + bool allowCond1 = true, + bool allowCond2 = true, + bool allowCond3 = true, + bool allowCond4 = true, + bool allowCond5 = true, + bool allowCond6 = true, + bool allowCond7 = true // + ) + { + // + bool result = false; + + // + // Normalize Args ... + dir = X_DIRECTION_NONE; + + // + // Validate Args ... + result = bar.IsValid(); + if (!result) + { + return result; + } + + // + // Prepare Requirements ... + XOHCL pBar; + XOHCL p2Bar; + int loopback = 3; + bool isBullish = false; + bool isBearish = false; + ENUM_X_DIRECTION iDir = X_DIRECTION_NONE; + + // + // Retrieve Bar's Prev ... + result = bar.GetPreviousBar(pBar); + result = result && + pBar.GetPreviousBar(p2Bar); + + // + // Handle Detect Trigger Bar ... + if (result) + { + // + // Check States ... + + // + // Rejected ... + bool isRejected = IsRejected( + pBar, + iDir, + false, // Force Type ... + true // Force Fibo Pressure ... + ); + bool isBullishRejected = + isRejected && + IsBullish(iDir); + bool isBearishRejected = + isRejected && + IsBearish(iDir); + + // + // Simple Rejected ... + bool isSimpleRejected = IsRejected( + pBar, + iDir, + false, // Force Type ... + false // Force Fibo Pressure ... + ); + bool isSimpleBullishRejected = + isSimpleRejected && + IsBullish(iDir); + bool isSimpleBearishRejected = + isSimpleRejected && + IsBearish(iDir); + + // + // Full Directional Rejection ... + bool isFullRejected = IsRejected( + pBar, + iDir, + true, // Force Type ... + true // Force Fibo Pressure ... + ); + bool isFullBullishRejected = + isFullRejected && + IsBullish(iDir); + bool isFullBearishRejected = + isRejected && + IsBearish(iDir); + + // + // Engulfed ... + bool isEngulfed = IsEngulfed( + pBar, + iDir // + ); + bool isBullishEngulfed = + isEngulfed && + IsBullish(iDir); + bool isBearishEngulfed = + isEngulfed && + IsBearish(iDir); + + // + // Momentum ... + bool isMomentum = IsMomentum( + pBar, + iDir // + ); + bool isBullishMomentum = + isMomentum && + IsBullish(iDir); + bool isBearishMomentum = + isMomentum && + IsBearish(iDir); + + // + // Simple Swing ... + bool isSwing = IsSimpleSwing( + pBar, + iDir // + ); + bool isBullishSwing = + isSwing && + IsBullish(iDir); + bool isBearishSwing = + isSwing && + IsBearish(iDir); + + // + // Full Swing ... + bool isFullSwing = IsSwing( + pBar, + iDir, + 5 // + ); + bool isFullBullishSwing = + isFullSwing && + IsBullish(iDir); + bool isFullBearishSwing = + isFullSwing && + IsBearish(iDir); + + // + // Sequence Breaker ... + bool isSeqBreak = IsSeqBreak( + pBar, + iDir, + 3 // + ); + bool isBullishSeqBreak = + isSeqBreak && + IsBullish(iDir); + bool isBearishSeqBreak = + isSeqBreak && + IsBearish(iDir); + + // + // Now we have to Combine Conditions ... + + // + // Cond 1 ... + bool isBullishCond1 = false; + bool isBearishCond1 = false; + if (allowCond1) + { + // + // Bullish ... + isBullishCond1 = + // + isFullBullishRejected + // + ; + + // + // Bearish ... + isBearishCond1 = + // + isFullBearishRejected + // + ; + } + + // + // Cond 2 ... + bool isBullishCond2 = false; + bool isBearishCond2 = false; + if (allowCond2) + { + // + // Bullish ... + isBullishCond2 = + // + isBullishSwing && + isBullishRejected + // + ; + + // + // Bearish ... + isBearishCond2 = + // + isBearishSwing && + isBearishRejected + // + ; + } + + // + // Cond 3 ... + bool isBullishCond3 = false; + bool isBearishCond3 = false; + if (allowCond3) + { + // + // Bullish ... + isBullishCond3 = + // + isBullishSwing && + (isBullishRejected || + isBullishEngulfed || + isBullishMomentum) + // + ; + + // + // Bearish ... + isBearishCond3 = + // + isBearishSwing && + (isBearishRejected || + isBearishEngulfed || + isBearishMomentum) + // + ; + } + + // + // Cond 4 ... + bool isBullishCond4 = false; + bool isBearishCond4 = false; + if (allowCond4) + { + // + // Bullish ... + isBullishCond4 = + // + isBullishSwing && + isBullishSeqBreak && + (isBullishRejected || + isBullishEngulfed || + isBullishMomentum) + // + ; + + // + // Bearish ... + isBearishCond4 = + // + isBearishSwing && + isBearishSeqBreak && + (isBearishRejected || + isBearishEngulfed || + isBearishMomentum) + // + ; + } + + // + // Cond 5 ... + bool isBullishCond5 = false; + bool isBearishCond5 = false; + if (allowCond5) + { + // + // Bullish ... + isBullishCond5 = + // + isFullBullishSwing && + (isBullishRejected || + isBullishEngulfed || + isBullishMomentum) + // + ; + + // + // Bearish ... + isBearishCond5 = + // + isFullBearishSwing && + (isBearishRejected || + isBearishEngulfed || + isBearishMomentum) + // + ; + } + + // + // Cond 6 ... + bool isBullishCond6 = false; + bool isBearishCond6 = false; + if (allowCond6) + { + // + // Bullish ... + isBullishCond6 = + // + p2Bar.IsBearish() && + pBar.IsBullish() && + pBar.low < p2Bar.low && + pBar.high > p2Bar.high && + pBar.GetDown() <= p2Bar.GetDown() && + (isBullishEngulfed || + isBullishMomentum || + isSimpleBullishRejected) + // + ; + + // + // Bearish ... + isBearishCond6 = + // + p2Bar.IsBullish() && + pBar.IsBearish() && + pBar.high > p2Bar.high && + pBar.low < p2Bar.low && + pBar.GetUp() >= p2Bar.GetUp() && + (isBearishEngulfed || + isBearishMomentum || + isSimpleBearishRejected) + // + ; + } + + // + // Cond 7 ... + bool isBullishCond7 = false; + bool isBearishCond7 = false; + if (allowCond7) + { + // + // Bullish ... + isBullishCond7 = + // + p2Bar.IsBearish() && + pBar.IsBullish() && + pBar.low < p2Bar.low && + pBar.high > p2Bar.high && + pBar.GetUp() >= p2Bar.GetUp() + // + ; + + // + // Bearish ... + isBearishCond7 = + // + p2Bar.IsBullish() && + pBar.IsBearish() && + pBar.high > p2Bar.high && + pBar.low < p2Bar.low && + pBar.GetDown() <= p2Bar.GetDown() + // + ; + } + + // + // Summarizie Result ... + + // + isBullish = + // + isBullishCond1 || + isBullishCond2 || + isBullishCond3 || + isBullishCond4 || + isBullishCond5 || + isBullishCond6 || + isBullishCond7 + // + ; + + // + isBearish = + // + isBearishCond1 || + isBearishCond2 || + isBearishCond3 || + isBearishCond4 || + isBearishCond5 || + isBearishCond6 || + isBearishCond7 + // + ; + } + + // + // Summarize Result ... + result = (isBullish && + !isBearish) || + (isBearish && + !isBullish); + if (result) + { + // + dir = + isBullish + ? X_DIRECTION_BULLISH + : X_DIRECTION_BEARISH; + } + + // + // Cleanup Resources ... + pBar.Clean(); + p2Bar.Clean(); + // return result; } diff --git a/Documents/BKP/tmp.conditionalling.signalling.mq5 b/Documents/BKP/tmp.conditionalling.signalling.mq5 index 6fb5ae8f..1fda2a9b 100644 --- a/Documents/BKP/tmp.conditionalling.signalling.mq5 +++ b/Documents/BKP/tmp.conditionalling.signalling.mq5 @@ -221,3 +221,1189 @@ // // All Requirements based on Cond 1 ... + +/////////////////////////////////////////////////////////////// + + // + XOHCL pBar; + has = bar.GetPreviousBar(pBar); + if (has) + { + // + ENUM_X_DIRECTION seqDir; + + // + bool isSeqBreaked = barAnalyser + .IsSeqBreak( + pBar, + seqDir // + ); + bool isBullishSeqBreaked = + isSeqBreaked && + IsBullish(seqDir); + bool isBearishSeqBreaked = + isSeqBreaked && + IsBearish(seqDir); + + // + if (isSeqBreaked) + { + Print("Detect Sequence Breaker Bar ..."); + } + } + pBar.Clean(); + +/////////////////////////////////////////////////////////////// + + + /** + * Detect Spike ... + * + * @param bar: XOHCL instance reference, Start Bar ... + * @param dir: ENUM_X_DIRECTION member, Event Direction ... + * @param type: ENUM_X_PRICE member, Price Type ... + * @param forcBodyInRange: bool, Use Body in Range Detection ... + * @param rangeExtendMultiplier: double, a Multiplier for Checking Price Range ... + * @param sameBars: int, Specified How Many Same Bars Required for an Spike ... + * + * @return ( bool ) + */ + bool IsSpike( + XOHCL &bar, + ENUM_X_DIRECTION &dir, + int &rootIDX, + ENUM_X_PRICE type = X_PRICE_CLOSE, + bool forcBodyInRange = true, + double rangeExtendMultiplier = 2.0, + int sameBars = 3 // + ) + { + // + bool result = false; + + // + dir = X_DIRECTION_NONE; + sameBars = NormalizeInt(sameBars, 2); + + // + result = IsValid(type) && + bar.IsValid(); + if (!result) + { + return result; + } + + // + // First We Have to Has a Big Change ... + int sharpRootIDX = -1; + result = IsSharp( + bar, + dir, + sharpRootIDX, + type, + forcBodyInRange, + rangeExtendMultiplier // + ); + if (!result) + { + return result; + } + + // + // Check Has Same Bars ... + int sameBarsIndex = -1; + ENUM_X_DIRECTION sameBarsDir; + result = HasSameBars( + bar, + sameBarsDir, + sameBarsIndex, + sameBars // + ); + if (!result) + { + return result; + } + + // + // Check Same Bars Direction sames To Price Change ... + result = sameBarsDir == dir; + if (!result) + { + return result; + } + + // + rootIDX = sharpRootIDX; + + // + return result; + } + + /** + * Check a Bar is Support Bar or not ... + * + * @param bar: XOHCL instance ... + * @param supportBar: XOHCL instance, Provides Fouded Support Bar ... + * @param range: Integer, Specified Verifiation Range ... + * + * @return ( bool ) + */ + bool HasSupport( + XOHCL &bar, + XOHCL &supportBar, + int range = 21 // + ) + { + // + bool result = false; + + // + result = bar.IsValid(); + if (!result) + { + return result; + } + + // + int supportIDX = bar.Index() + range; + result = supportBar.Init( + bar.symbol, + bar.period, + supportIDX // + ); + if (!result) + { + // + supportBar.Clean(); + return result; + } + + // + result = bar.low > supportBar.low; + if (!result) + { + // + supportBar.Clean(); + return result; + } + + // + // Validate Point ... + for (int i = 1; i < range; i++) + { + // + XOHCL iPBar; + XOHCL iNBar; + bool iHas = false; + + // + iHas = iPBar.Init( + bar.symbol, + bar.period, + supportIDX + i // + ); + result = iHas; + if (!result) + { + break; + } + + // + iHas = iNBar.Init( + bar.symbol, + bar.period, + supportIDX - i // + ); + result = iHas; + if (!result) + { + break; + } + + // + result = supportBar.low < iPBar.low && + supportBar.low < iNBar.low; + if (!result) + { + break; + } + } + + // + return result; + } + + /** + * Check a Bar is Resistance Bar or not ... + * + * @param bar: XOHCL instance ... + * @param resistanceBar: XOHCL instance, Provides Fouded Support Bar ... + * @param range: Integer, Specified Verifiation Range ... + * + * @return ( bool ) + */ + bool HasResistance( + XOHCL &bar, + XOHCL &resistanceBar, + int range = 21 // + ) + { + // + bool result = false; + + // + result = bar.IsValid(); + if (!result) + { + return result; + } + + // + int resistanceIDX = bar.Index() + range; + result = resistanceBar.Init( + bar.symbol, + bar.period, + resistanceIDX // + ); + if (!result) + { + // + resistanceBar.Clean(); + return result; + } + + // + result = bar.high < resistanceBar.high; + if (!result) + { + // + resistanceBar.Clean(); + return result; + } + + // + // Validate Point ... + for (int i = 1; i < range; i++) + { + // + XOHCL iPBar; + XOHCL iNBar; + bool iHas = false; + + // + iHas = iPBar.Init( + bar.symbol, + bar.period, + resistanceIDX + i // + ); + result = iHas; + if (!result) + { + break; + } + + // + iHas = iNBar.Init( + bar.symbol, + bar.period, + resistanceIDX - i // + ); + result = iHas; + if (!result) + { + break; + } + + // + result = resistanceBar.high > iPBar.high && + resistanceBar.high > iNBar.high; + if (!result) + { + break; + } + } + + // + return result; + } + + /** + * Detect a Fair Value Gap Based on Given Bar ... + * + * @param bar: XOHCL instance, Specified Start Bar ... + * @param fromBar: XOHCL instance, Provides Start Bar of FVG ... + * @param toBar: XOHCL instance, Provides End Bar of FVG ... + * @param dir: ENUM_X_DIRECTION member, Specified Founded Order Block Direction ... + * @param sameBars: Integer, Specified Min Same Bars for Detecting Order Block ... + * @return ( bool ) + */ + bool HasFairValueGap( + XOHCL &bar, + XOHCL &fromBar, + XOHCL &toBar, + ENUM_X_DIRECTION &dir, + int sameBars = 3 // + ) + { + // + bool result = false; + + // + toBar.Clean(); + fromBar.Clean(); + dir = X_DIRECTION_NONE; + sameBars = NormalizeInt(sameBars, 1); + + // + result = bar.IsValid(); + if (!result) + { + // + toBar.Clean(); + fromBar.Clean(); + return result; + } + + // + int index = 0; + result = HasSameBars( + bar, + dir, + index, + sameBars // + ); + if (!result) + { + return result; + } + + // + bool isBullish = IsBullish(dir); + + // + int to = bar.Index(); + int from = + index > (to + sameBars) + ? to + sameBars + : index; + for (int i = from; i > to; i--) + { + // + result = fromBar.Init( + bar.symbol, + bar.period, + i // + ); + if (!result) + { + break; + } + + // + result = toBar.Init( + bar.symbol, + bar.period, + i - 2 // + ); + if (!result) + { + break; + } + + // + result = isBullish + ? fromBar.high < toBar.low + : fromBar.low > toBar.high; + if (result) + { + break; + } + } + + // + if (!result) + { + // + toBar.Clean(); + fromBar.Clean(); + dir = X_DIRECTION_NONE; + } + + // + return result; + } + + /** + * Detect an Order Block Based on Given Bar ... + * + * @param bar: XOHCL instance, Specified Start Bar ... + * @param ob: XOHCL instance, Fill it if Order Block Found ... + * @param dir: ENUM_X_DIRECTION member, Specified Founded Order Block Direction ... + * @param sameBars: Integer, Specified Min Same Bars for Detecting Order Block ... + * + * @return ( bool ) + */ + bool HasOrderBlock( + XOHCL &bar, + XOHCL &ob, + ENUM_X_DIRECTION &dir, + int sameBars = 3, + bool forceSpike = true, + bool forceFairValueGap = true, + bool forceSupportResistance = true // + ) + { + // + bool result = false; + + // + ob.Clean(); + dir = X_DIRECTION_NONE; + sameBars = NormalizeInt(sameBars, 1); + + // + result = bar.IsValid(); + if (!result) + { + return result; + } + + // + XOHCL sBar; + if (bar.Index() == 0) + { + // + result = bar.GetPreviousBar(sBar); + if (!result) + { + // + sBar.Clean(); + return result; + } + } + else + { + sBar = bar; + } + + // + // First Step We Have to Check Same Bars ... + int spikeRootIDX = -1; + int sameBarsIndex = -1; + result = HasSameBars( + bar, + dir, + sameBarsIndex, + sameBars // + ); + if (!result) + { + // + ob.Clean(); + return result; + } + + // + // Must an Spike Happens ... + if (forceSpike) + { + // + ENUM_X_DIRECTION spikeDir; + result = IsSpike( + bar, + spikeDir, + spikeRootIDX, // Spike Root Index ... + X_PRICE_CLOSE, // Price Type ... + true, // Force Body ... + 1.5, // Range Extend Multiplier ... + sameBars // + ); + result = + result && + dir == spikeDir; + if (!result) + { + // + ob.Clean(); + return result; + } + } + + // + // Select OB Candidate Bars ... + + XOHCL sameBar; + XOHCL rootBar; + XOHCL rootPBar; + result = sameBar.Init( + bar.symbol, + bar.period, + sameBarsIndex + 1 // + ); + if (!result) + { + // + sBar.Clean(); + sameBar.Clean(); + return result; + } + result = rootBar.Init( + bar.symbol, + bar.period, + spikeRootIDX // + ); + if (!result) + { + // + sBar.Clean(); + rootBar.Clean(); + sameBar.Clean(); + return result; + } + result = rootBar.GetPreviousBar(rootPBar); + if (!result) + { + // + sBar.Clean(); + rootBar.Clean(); + sameBar.Clean(); + rootPBar.Clean(); + return result; + } + + // + // Select ob Bar ... + if (rootBar.GetDirection() == Opposit(dir)) + { + ob = rootBar; + } + else if (rootPBar.GetDirection() == Opposit(dir)) + { + ob = rootPBar; + } + else if (sameBar.GetDirection() == Opposit(dir)) + { + ob = sameBar; + } + else + { + ob.Clean(); + } + + // + // Select Order Block Bar ... + result = ob.IsValid(); + ENUM_X_DIRECTION obDir = ob.GetDirection(); + result = + result && + dir == Opposit(obDir); + if (!result) + { + // + sBar.Clean(); + rootBar.Clean(); + sameBar.Clean(); + rootPBar.Clean(); + + // + return result; + } + + // + // if Bullish OB => Supports ... + // if Bearish OB => Resistance ... + if (forceSupportResistance) + { + // + XOHCL supResBar; + + // + // Check Support ... + bool isSupport = HasSupport( + ob, + supResBar // + ); + + // + // Check Resistance ... + bool isResistance = HasResistance( + ob, + supResBar // + ); + + // + supResBar.Clean(); + + // + result = + result && + (IsBullish(dir) + ? isSupport + : isResistance); + + // + if (!result) + { + // + ob.Clean(); + sBar.Clean(); + rootBar.Clean(); + sameBar.Clean(); + rootPBar.Clean(); + + // + return result; + } + } + + // + // Force Check Fair ValueGaps ... + if (forceFairValueGap) + { + // + XOHCL toBar; + XOHCL fromBar; + ENUM_X_DIRECTION fvgDir; + bool isFVG = HasFairValueGap( + bar, + fromBar, + toBar, + fvgDir, + sameBars // + ); + + // + result = + isFVG && + result && + dir == fvgDir; + + // + toBar.Clean(); + fromBar.Clean(); + } + + // + // Cleanup Resource ... + + // + sBar.Clean(); + rootBar.Clean(); + sameBar.Clean(); + rootPBar.Clean(); + + // + return result; + } + + /** + * Check a Bar has Consolidation Zone or not ... + * + * @param bar: XOHCL instance, Specified Start Bar ... + * @param zone: XConsolidationZone instance, consolidation Zone Object ... + * @param minLoopback: int, min Allowed Lopback for Consolidating ... + * @param range: double, Consolidation Range ... + * @param upperAppliedTo: ENUM_X_PRICE member, Upper Selection Price ... + * @param lowerAppliedTo: ENUM_X_PRICE member, Lower Selection Price ... + * + * @return ( bool ) + */ + bool HasConsolidationZone( + XOHCL &bar, + XConsolidationZone &zone, + int minLoopback = 7, + double range = 50, + ENUM_X_PRICE upperAppliedTo = X_PRICE_HIGH, + ENUM_X_PRICE lowerAppliedTo = X_PRICE_LOW // + ) + { + // + bool result = false; + + // + zone.Clean(); + range = NormalizeDouble(range, 50); + minLoopback = NormalizeInt(minLoopback, 7); + + // + result = bar.IsValid(); + if (!result) + { + return result; + } + + // + double points = GetPoints(bar.symbol); + int index = bar.Index() + 1; + int length = minLoopback; + + // + double upperPrice[]; + int upperPriceCount = FillPrice( + upperPrice, + bar, + length, + upperAppliedTo // + ); + + // + double lowerPrice[]; + int lowerPriceCount = FillPrice( + lowerPrice, + bar, + length, + lowerAppliedTo // + ); + + // + result = upperPriceCount == lowerPriceCount && + lowerPriceCount == length; + if (!result) + { + // + Clean(upperPrice); + Clean(lowerPrice); + + // + return result; + } + + // + double upper = upperPrice[ArrayMaximum(upperPrice)]; + double lower = lowerPrice[ArrayMinimum(lowerPrice)]; + + // + bool isBullishBreake = + bar.low > lower && + bar.high > upper && + bar.GetUp() > upper; + bool isBearishBreake = + bar.high < upper && + bar.low < lower && + bar.GetDown() < lower; + result = isBullishBreake || + isBearishBreake; + if (!result) + { + // + Clean(upperPrice); + Clean(lowerPrice); + + // + return result; + } + + // + double delta = upper - lower; + result = delta <= range * points; + if (!result) + { + // + Clean(upperPrice); + Clean(lowerPrice); + + // + return result; + } + + // + while (delta <= range * points) + { + // + length++; + + // + upperPriceCount = FillPrice( + upperPrice, + bar, + length, + upperAppliedTo // + ); + + // + lowerPriceCount = FillPrice( + lowerPrice, + bar, + length, + lowerAppliedTo // + ); + + // + bool isValid = upperPriceCount == lowerPriceCount && + lowerPriceCount == length; + if (!isValid) + { + break; + } + + // + double iUpper = upperPrice[ArrayMaximum(upperPrice)]; + double iLower = lowerPrice[ArrayMinimum(lowerPrice)]; + + // + delta = iUpper - iLower; + if (delta <= range * points) + { + // + upper = iUpper; + lower = iLower; + } + } + + // + Clean(upperPrice); + Clean(lowerPrice); + + // + // Filling Zone ... + zone.upper = upper; + zone.lower = lower; + zone.symbol = bar.symbol; + zone.period = bar.period; + zone.to = iTime( + bar.symbol, + bar.period, + bar.Index() + 1 // + ); + zone.from = iTime( + bar.symbol, + bar.period, + bar.Index() + length // + ); + zone.dir = isBullishBreake + ? X_DIRECTION_BULLISH + : X_DIRECTION_BEARISH; + + // + result = zone.IsValid(); + if (!result) + { + zone.Clean(); + } + + // + return result; + } + +/////////////////////////////////////////////////////////////////// + + // + // DOJI ... + bool isDoji = IsDoji( + bar, + iDir // + ); + bool isBullishDoji = + isDoji && + IsBullish(iDir); + bool isBearishDoji = + isDoji && + IsBearish(iDir); + + // + // SWING ... + bool isSwing = IsSwing( + bar, + iDir // + ); + bool isBullishSwing = + isSwing && + IsBullish(iDir); + bool isBearishSwing = + isSwing && + IsBearish(iDir); + + // + // HAMMER ... + bool isHammer = IsHammer( + bar, + iDir // + ); + bool isBullishHammer = + isHammer && + IsBullish(iDir); + bool isBearishHammer = + isHammer && + IsBearish(iDir); + + // + // ENGULF ... + bool isEngulfed = IsEngulfed( + bar, + iDir // + ); + bool isBullishEngulfed = + isEngulfed && + IsBullish(iDir); + bool isBearishEngulfed = + isEngulfed && + IsBearish(iDir); + + // + // REJECTED ... + bool isRejected = IsRejected( + bar, + iDir // + ); + bool isBullishRejected = + isRejected && + IsBullish(iDir); + bool isBearishRejected = + isRejected && + IsBearish(iDir); + + // + // MOMENTUM ... + bool isMomentum = IsMomentum( + bar, + iDir // + ); + bool isBullishMomentum = + isMomentum && + IsBullish(iDir); + bool isBearishMomentum = + isMomentum && + IsBearish(iDir); + + // + // Summarize Conditions ... + + // + bool isBullishOr = + isBullishDoji || + isBullishSwing || + isBullishHammer || + isBullishEngulfed || + isBullishRejected || + isBullishMomentum; + + // + bool isBearishOr = + isBearishDoji || + isBearishSwing || + isBearishHammer || + isBearishEngulfed || + isBearishRejected || + isBearishMomentum; + + // + bool isBullish = + isBullishOr && + !isBearishOr; + + // + bool isBearish = + !isBullishOr && + isBearishOr; + +/////////////////////////////////////////////////////////////////// + + bool IsVPattern( + XOHCL &bar, + ENUM_X_DIRECTION &dir, + ENUM_X_PRICE pType = X_PRICE_CLOSE, + int loopback = 3 // + ) + { + // + bool result = false; + + // + // Normalize Args ... + dir = X_DIRECTION_NONE; + loopback = NormalizeInt(loopback, 3); + + // + // Loopback Must an Odd Number ... + // here we Validate and Normalize it ... + double iLoopbackCheck = ((double)(loopback - 1)) / 2; + if (iLoopbackCheck != 0) + { + loopback++; + } + + // + // Validate Args ... + result = + bar.IsValid() && + IsValid(pType); + if (!result) + { + return result; + } + + // + XOHCL iBar; + int index = -1; + XOHCL iSwingBar; + double prices[]; + bool has = false; + double iPrice = 0; + int pricesCount = 0; + int swingBarIDX = -1; + int loopbackHalf = 0; + bool isBullish = false; + bool isBearish = false; + bool hasBullishSeq = false; + bool hasBearishSeq = false; + + // + if (result) + { + // + // Retrieve Price Type Collection ... + index = bar.Index(); + pricesCount = FillPrice( + prices, + bar, + loopback, + pType // + ); + result = pricesCount == loopback; + if (result) + { + // + loopbackHalf = (loopback - 1) / 2; + swingBarIDX = index + loopbackHalf + 1; + has = IsValidIndex(swingBarIDX); + + // + // Check for Bullish and Bearish ... + if (has) + { + // + hasBullishSeq = true; + hasBearishSeq = true; + iPrice = prices[swingBarIDX]; + for (int i = 0; i < loopbackHalf - 1; i++) + { + // + // Side Values ... + + // + // Prev ... + double iPPrice = prices[swingBarIDX + i]; + double iP2Price = prices[swingBarIDX + i + 1]; + + // + // Next ... + double iNPrice = prices[swingBarIDX - i]; + double iN2Price = prices[swingBarIDX - i - 1]; + + // + if (hasBullishSeq) + { + // + // For Bullish Seq ... + // Prevs Must: iPPrice < iP2Price + // Nexts Must: iNPrice < iN2Price + hasBullishSeq = + iPrice < iPPrice && + iPrice < iNPrice && + iPPrice <= iP2Price && + iNPrice <= iN2Price; + } + + // + if (hasBearishSeq) + { + // + // For Bearish Seq ... + // Prevs Must: iPPrice > iP2Price + // Nexts Must: iNPrice > iN2Price + hasBearishSeq = + iPrice > iPPrice && + iPrice > iNPrice && + iPPrice >= iP2Price && + iNPrice >= iN2Price; + } + + // + if (!hasBullishSeq && + !hasBearishSeq) + { + break; + } + } + } + + // + result = + has && + (hasBullishSeq || + hasBearishSeq); + } + } + + // + // Here we Make Sure the Propper Sequence is Exists ... + if (result) + { + // + // Try to Check onther Conditions ... + has = iSwingBar.Init( + bar.symbol, + bar.period, + swingBarIDX // + ); + + // + if (has) + { + // + // Draw Requirement to Now ... + string iName = "S_1"; + datetime iTime = iSwingBar.time; + + // + CChartObjectVLine *iObj = new CChartObjectVLine(); + has = iObj.Create( + 0, + iName, + 0, + iTime // + ); + + // + iName = "SP_1"; + iTime = GetBarTime( + bar.symbol, + bar.period, + swingBarIDX + loopbackHalf); + CChartObjectVLine *iObj1 = new CChartObjectVLine(); + has = iObj1.Create( + 0, + iName, + 0, + iTime // + ); + + // + Print("Salam ..."); + } + } + + // + // Summarize Result ... + result = isBullish || + isBearish; + if (result) + { + // + dir = + isBullish + ? X_DIRECTION_BULLISH + : X_DIRECTION_BEARISH; + } + + // + // Cleanup Resource ... + iBar.Clean(); + iSwingBar.Clean(); + + // + return result; + } + +/////////////////////////////////////////////////////////////////// + diff --git a/Classes/x-saherelm.x-poi.class.mq5 b/Documents/BKP/x-saherelm.x-poi.class.mq5 similarity index 100% rename from Classes/x-saherelm.x-poi.class.mq5 rename to Documents/BKP/x-saherelm.x-poi.class.mq5 diff --git a/XCATBEA/Classes/xcatbea.signaller.class.mq5 b/XCATBEA/Classes/xcatbea.signaller.class.mq5 index 4f27493e..012715a2 100644 --- a/XCATBEA/Classes/xcatbea.signaller.class.mq5 +++ b/XCATBEA/Classes/xcatbea.signaller.class.mq5 @@ -1484,6 +1484,17 @@ class XCXCATBEASignaller : XCBase bool isBasedOnPivotZone = conditions.pivotZone.IsValid(); bool isBasedOnTriggerBlock = conditions.triggerBlock.IsValid(); + // + // Reading Current Market Conditions ... + X121XCatbConditions cConditions; + result = + result && + helper.GetConditions( + cConditions, + barIndex, + 10 // + ); + // // Validate Direction of Setuped Conditions ... result = @@ -1491,6 +1502,31 @@ class XCXCATBEASignaller : XCBase (isBullish || isBearish); + // + // Detecting Trigger Bar ... + + // + ENUM_X_DIRECTION triggerDir; + bool isTriggerBar = barAnalyser + .IsValidForTrigger( + bar, + triggerDir, + false, // Allow Cond 1 ... + false, // Allow Cond 2 ... + false, // Allow Cond 3 ... + false, // Allow Cond 4 ... + false, // Allow Cond 5 ... + false, // Allow Cond 6 ... + true // Allow Cond 7 ... + // + ); + bool isBullishTriggerBar = + isTriggerBar && + IsBullish(triggerDir); + bool isBearishTriggerBar = + isTriggerBar && + IsBearish(triggerDir); + // // Do Triggering Senario based on Trigger Block ... if (result && @@ -1543,6 +1579,10 @@ class XCXCATBEASignaller : XCBase } // + // Check atleast 3 Bars Close Outside of applied Edge ... + // Check Current Bar is a Trigger Bar ... + // TODO: Complete this ... + // } //