diff --git a/Classes/z-saherelm.x-bar.analyser.class.mq5 b/Classes/z-saherelm.x-bar.analyser.class.mq5 index def070f5..8b2f5f37 100644 --- a/Classes/z-saherelm.x-bar.analyser.class.mq5 +++ b/Classes/z-saherelm.x-bar.analyser.class.mq5 @@ -232,6 +232,71 @@ class XCBarAnalyser : public XSCBase // // Rejection Bar ... + /** + * Check Specific Bar is Rejection Bar or not ... + * + * @param dir: ENUM_X_DIRECTION member, Specified Direction ... + * @param bar: XOHCL instance, Specified Bar ... + * @param strength: Double, Specified Shadow Percent Range ... + * + * @return ( bool ) + */ + bool IsRejectionBar( + ENUM_X_DIRECTION &dir, + XOHCL &bar, + double strength // + ) + { + // + bool result = false; + + // + if (strength < 20) + { + strength = 20; + } + + // + dir = X_DIRECTION_NONE; + + // + result = bar.IsValid(); + if (!result) + { + return result; + } + + // + double barLowShadow = bar.GetLowShadow(); + double barHighShadow = bar.GetHighShadow(); + double barRange = bar.GetRange(); + double barRangePercent = barRange / 100; + + // + bool isBullishRejectionBar = + barLowShadow > barHighShadow && + barLowShadow > barRangePercent * 40; + + // + bool isBearishRejectionBar = + barHighShadow > barLowShadow && + barHighShadow > barRangePercent * 40; + + // + result = isBullishRejectionBar || + isBearishRejectionBar; + if (result) + { + // + dir = isBullishRejectionBar + ? X_DIRECTION_BULLISH + : X_DIRECTION_BEARISH; + } + + // + return result; + } + /** * Check Specific Bar is Bullish Rejection Bar or not ... * @@ -297,6 +362,51 @@ class XCBarAnalyser : public XSCBase // // Momentum Bar ... + /** + * Check Specific Bar is Momentum Bar or not ... + * + * @param dir: ENUM_X_DIRECTION member, Specified Direction ... + * @param bar: XOHCL instance, Specified Bar ... + * @param strength: Double, Specified Shadow Percent Range ... + * + * @return ( bool ) + */ + bool IsMomentumBar( + ENUM_X_DIRECTION &dir, + XOHCL &bar, + double strength // + ) + { + // + bool result = false; + + // + if (strength < 50) + { + strength = 50; + } + + // + dir = X_DIRECTION_NONE; + + // + double rangePercent = GetBarRangePercent(bar); + bool isStrong = bar.GetBody() > rangePercent * strength; + + // + result = isStrong; + if (result) + { + // + dir = bar.IsBullish() + ? X_DIRECTION_BULLISH + : X_DIRECTION_BEARISH; + } + + // + return result; + } + /** * Check Specific Bar is Bullish Momentum Bar or not ... * @@ -359,6 +469,67 @@ class XCBarAnalyser : public XSCBase return result; } + // + // Engulfing ... + + /** + * Check Bar is Engulfed or not ... + * + * @param dir: ENUM_X_DIRECTION member, Specified Direction ... + * @param bar: XOHCL instance, Speciied Bar ... + * @param loopback: Integer, loopback Length ... + * + * @return ( bool ) + */ + bool IsEngulfed( + ENUM_X_DIRECTION &dir, + XOHCL &bar, + int loopback // + ) + { + // + bool result = false; + + // + dir = X_DIRECTION_NONE; + + // + int hhIDX = 0; + double hh = 0; + + // + int llIDX = 0; + double ll = 0; + + // + result = CalculateLoopbackHLData( + hhIDX, + hh, + llIDX, + ll, + bar, + loopback // + ); + if (!result) + { + return result; + } + + // + result = bar.GetDown() < ll && + bar.GetUp() > hh; + if (result) + { + // + dir = bar.IsBullish() + ? X_DIRECTION_BULLISH + : X_DIRECTION_BEARISH; + } + + // + return result; + } + /** * Check Bar is Bullish Engulfed or not ... * @@ -425,17 +596,172 @@ class XCBarAnalyser : public XSCBase // Bar CHOCH ... /** - * Check Specified Bar Has Bullish CHOCH or not ... - * + * Check Specified Bar Has CHOCH or not ... + * + * @param dir: ENUM_X_DIRECTION member, Specified Direction ... * @param bar: XOHCL instance, Speciied Bar ... * @param loopback: Integer, loopback Length ... * @param forceBody: Boolean, Specified Choch Happens only by Bar's Body ... - * + * + * @return ( bool ) + */ + bool HasCHOCH( + ENUM_X_DIRECTION &dir, + XOHCL &bar, + int loopback = 2, + bool forceBody = false // + ) + { + // + bool result = false; + + // + dir = X_DIRECTION_NONE; + + // + if (loopback < 1) + { + loopback = 1; + } + + // + result = bar.IsValid(); + if (!result) + { + return result; + } + + // + string symbol = bar.symbol; + ENUM_TIMEFRAMES period = bar.period; + + // + // Calculate Loopback Data ... + int index = -1; + int start = -1; + int end = -1; + int count = -1; + result = CalculateLoopBackData( + index, + start, + end, + count, + bar, + loopback // + ); + if (!result) + { + return result; + } + + // + // Calculate Loopback HH and LL Data ... + int hhIDX = -1; + double hh = -1; + int llIDX = -1; + double ll = -1; + result = CalculateLoopbackHLData( + hhIDX, + hh, + llIDX, + ll, + bar, + loopback // + ); + if (!result) + { + return result; + } + + // + bool isBullishDirection = + bar.high > hh && + bar.low > ll; + bool isBearishDirection = + bar.high < hh && + bar.low < ll; + result = isBullishDirection || + isBearishDirection; + if (!result) + { + return result; + } + + // + if (forceBody) + { + // + isBullishDirection = + bar.GetUp() > hh && + bar.GetDown() > ll; + isBearishDirection = + bar.GetUp() < hh && + bar.GetDown() < ll; + result = isBullishDirection || + isBearishDirection; + if (!result) + { + return result; + } + } + + // + // Check Bar's Direction in related to CHOCH Direction ... + result = + isBullishDirection + ? bar.IsBullish() + : bar.IsBearish(); + if (!result) + { + return result; + } + + // + // Set Direction ... + dir = + isBullishDirection + ? X_DIRECTION_BULLISH + : X_DIRECTION_BEARISH; + + // + // Check Loopback End Bar ... + XOHCL endBar; + result = endBar.Init( + symbol, + period, + end - 1 // + ); + if (!result) + { + return result; + } + + // + // End Bar Must be InDirect by Specified Bar ... + result = + isBullishDirection + ? endBar.IsBearish() + : endBar.IsBullish(); + + // + // Check Loopback for Directional Bars ... + + // + return result; + } + + /** + * Check Specified Bar Has Bullish CHOCH or not ... + * + * @param bar: XOHCL instance, Speciied Bar ... + * @param loopback: Integer, loopback Length ... + * @param forceBody: Boolean, Specified Choch Happens only by Bar's Body ... + * * @return ( bool ) */ bool HasBullishCHOCH( XOHCL &bar, - int loopback = 3, + int loopback = 2, bool forceBody = false // ) { @@ -460,16 +786,16 @@ class XCBarAnalyser : public XSCBase /** * Check Specified Bar Has Bearish CHOCH or not ... - * + * * @param bar: XOHCL instance, Speciied Bar ... * @param loopback: Integer, loopback Length ... * @param forceBody: Boolean, Specified Choch Happens only by Bar's Body ... - * + * * @return ( bool ) */ bool HasBearishCHOCH( XOHCL &bar, - int loopback = 3, + int loopback = 2, bool forceBody = false // ) { @@ -492,6 +818,174 @@ class XCBarAnalyser : public XSCBase return result; } + // + // Directions ... + + /** + * Check Specified Bar Possible Direction Pressure ... + * + * @param dir: ENUM_X_DIRECTION member ... + * @param bar: XOHCL instance, Specified Bar ... + * + * @return ( bool ) + */ + bool HasDirection( + ENUM_X_DIRECTION &dir, + XOHCL &bar // + ) + { + // + bool result = false; + + // + dir = X_DIRECTION_NONE; + + // + result = bar.IsValid(); + if (!result) + { + return result; + } + + // + // Check Bar isExtended or not ... + bool isExtended = IsExtended( + bar, + 3 // + ); + + // + // Check Rejection ... + ENUM_X_DIRECTION rejectionDir; + bool isRejection = IsRejectionBar(rejectionDir, bar, 40); + bool isBullishRejection = isRejection && + rejectionDir == X_DIRECTION_BULLISH; + bool isBearishRejection = isRejection && + rejectionDir == X_DIRECTION_BEARISH; + + // + // Check Momentum ... + ENUM_X_DIRECTION momentumDir; + bool isMomentum = IsMomentumBar(momentumDir, bar, 40); + bool isBullisMomentumn = isMomentum && + momentumDir == X_DIRECTION_BULLISH; + bool isBearishMomentum = isMomentum && + momentumDir == X_DIRECTION_BEARISH; + + // + // Check Engulfing ... + ENUM_X_DIRECTION engulfDir; + bool isEngulfed = IsEngulfed( + engulfDir, + bar, + 2 // + ); + bool isBullishEngulfed = isEngulfed && + engulfDir == X_DIRECTION_BULLISH; + bool isBearishEngulfed = isEngulfed && + engulfDir == X_DIRECTION_BEARISH; + + // + // Check CHOCH ... + ENUM_X_DIRECTION chochDir; + bool hasCHOCH = HasCHOCH( + chochDir, + bar, + 2, + false // + ); + bool hasBullishCHOCH = hasCHOCH && + chochDir == X_DIRECTION_BULLISH; + bool hasBearishCHOCH = hasCHOCH && + chochDir == X_DIRECTION_BEARISH; + + // + bool hasBullishDirection = + // + isExtended && + (hasBullishCHOCH || + isBullishEngulfed) && + (isBullisMomentumn || + isBullishRejection) + // + ; + + // + bool hasBearishDirection = + // + isExtended && + (hasBearishCHOCH || + isBearishEngulfed) && + (isBearishMomentum || + isBearishRejection) + // + ; + + // + result = hasBullishDirection || + hasBearishDirection; + if (result) + { + // + dir = hasBullishDirection + ? X_DIRECTION_BULLISH + : X_DIRECTION_BEARISH; + } + + // + return result; + } + + /** + * Check Specified Bar has Possibly Bullish Direction ... + * + * @param bar: XOHCL instance, Specified Bar ... + * + * @return ( virtual bool ) + */ + virtual bool HasBullishDirection( + XOHCL &bar // + ) + { + // + bool result = false; + + // + ENUM_X_DIRECTION dir; + result = HasDirection(dir, bar); + result = + result && + dir == X_DIRECTION_BULLISH; + + // + return result; + } + + /** + * Check Specified Bar has Possibly Bearish Direction ... + * + * @param bar: XOHCL instance, Specified Bar ... + * + * @return ( virtual bool ) + */ + virtual bool HasBearishhDirection( + XOHCL &bar // + ) + { + // + bool result = false; + + // + ENUM_X_DIRECTION dir; + result = HasDirection(dir, bar); + result = + result && + dir == X_DIRECTION_BEARISH; + + // + return result; + } + // protected: // @@ -609,8 +1103,8 @@ class XCBarAnalyser : public XSCBase bar.symbol, bar.period, MODE_HIGH, - start, - count // + count, + start // ); result = IsValidIndex(hhIDX); if (!result) @@ -623,8 +1117,8 @@ class XCBarAnalyser : public XSCBase bar.symbol, bar.period, MODE_LOW, - start, - count // + count, + start // ); result = IsValidIndex(llIDX); if (!result) @@ -667,329 +1161,6 @@ class XCBarAnalyser : public XSCBase return result; } - /** - * Check Specific Bar is Rejection Bar or not ... - * - * @param dir: ENUM_X_DIRECTION member, Specified Direction ... - * @param bar: XOHCL instance, Specified Bar ... - * @param strength: Double, Specified Shadow Percent Range ... - * - * @return ( bool ) - */ - bool IsRejectionBar( - ENUM_X_DIRECTION &dir, - XOHCL &bar, - double strength // - ) - { - // - bool result = false; - - // - if (strength < 20) - { - strength = 20; - } - - // - dir = X_DIRECTION_NONE; - - // - result = bar.IsValid(); - if (!result) - { - return result; - } - - // - double barLowShadow = bar.GetLowShadow(); - double barHighShadow = bar.GetHighShadow(); - double barRange = bar.GetRange(); - double barRangePercent = barRange / 100; - - // - bool isBullishRejectionBar = - barLowShadow > barHighShadow && - barLowShadow > barRangePercent * 40; - - // - bool isBearishRejectionBar = - barHighShadow > barLowShadow && - barHighShadow > barRangePercent * 40; - - // - result = isBullishRejectionBar || - isBearishRejectionBar; - if (result) - { - // - dir = isBullishRejectionBar - ? X_DIRECTION_BULLISH - : X_DIRECTION_BEARISH; - } - - // - return result; - } - - /** - * Check Specific Bar is Momentum Bar or not ... - * - * @param dir: ENUM_X_DIRECTION member, Specified Direction ... - * @param bar: XOHCL instance, Specified Bar ... - * @param strength: Double, Specified Shadow Percent Range ... - * - * @return ( bool ) - */ - bool IsMomentumBar( - ENUM_X_DIRECTION &dir, - XOHCL &bar, - double strength // - ) - { - // - bool result = false; - - // - if (strength < 50) - { - strength = 50; - } - - // - dir = X_DIRECTION_NONE; - - // - double rangePercent = GetBarRangePercent(bar); - bool isStrong = bar.GetBody() > rangePercent * strength; - - // - result = isStrong; - if (result) - { - // - dir = bar.IsBullish() - ? X_DIRECTION_BULLISH - : X_DIRECTION_BEARISH; - } - - // - return result; - } - - /** - * Check Bar is Engulfed or not ... - * - * @param dir: ENUM_X_DIRECTION member, Specified Direction ... - * @param bar: XOHCL instance, Speciied Bar ... - * @param loopback: Integer, loopback Length ... - * - * @return ( bool ) - */ - bool IsEngulfed( - ENUM_X_DIRECTION &dir, - XOHCL &bar, - int loopback // - ) - { - // - bool result = false; - - // - dir = X_DIRECTION_NONE; - - // - int hhIDX = 0; - double hh = 0; - - // - int llIDX = 0; - double ll = 0; - - // - result = CalculateLoopbackHLData( - hhIDX, - hh, - llIDX, - ll, - bar, - loopback // - ); - if (!result) - { - return result; - } - - // - result = bar.GetDown() < ll && - bar.GetUp() > hh; - if (result) - { - // - dir = bar.IsBullish() - ? X_DIRECTION_BULLISH - : X_DIRECTION_BEARISH; - } - - // - return result; - } - - /** - * Check Specified Bar Has CHOCH or not ... - * - * @param dir: ENUM_X_DIRECTION member, Specified Direction ... - * @param bar: XOHCL instance, Speciied Bar ... - * @param loopback: Integer, loopback Length ... - * @param forceBody: Boolean, Specified Choch Happens only by Bar's Body ... - * - * @return ( bool ) - */ - bool HasCHOCH( - ENUM_X_DIRECTION &dir, - XOHCL &bar, - int loopback = 3, - bool forceBody = false // - ) - { - // - bool result = false; - - // - dir = X_DIRECTION_NONE; - - // - if (loopback < 1) - { - loopback = 1; - } - - // - result = bar.IsValid(); - if (!result) - { - return result; - } - - // - string symbol = bar.symbol; - ENUM_TIMEFRAMES period = bar.period; - - // - // Calculate Loopback Data ... - int index = -1; - int start = -1; - int end = -1; - int count = -1; - result = CalculateLoopBackData( - index, - start, - end, - count, - bar, - loopback // - ); - if (!result) - { - return result; - } - - // - // Calculate Loopback HH and LL Data ... - int hhIDX = -1; - double hh = -1; - int llIDX = -1; - double ll = -1; - result = CalculateLoopbackHLData( - hhIDX, - hh, - llIDX, - ll, - bar, - loopback // - ); - if (!result) - { - return result; - } - - // - bool isBullishDirection = - bar.high > hh && - bar.low > ll; - bool isBearishDirection = - bar.high < hh && - bar.low < ll; - result = isBullishDirection || - isBearishDirection; - if (!result) - { - return result; - } - - // - if (forceBody) - { - // - isBullishDirection = - bar.GetUp() > hh && - bar.GetDown() > ll; - isBearishDirection = - bar.GetUp() < hh && - bar.GetDown() < ll; - result = isBullishDirection || - isBearishDirection; - if (!result) - { - return result; - } - } - - // - // Check Bar's Direction in related to CHOCH Direction ... - result = - isBullishDirection - ? bar.IsBullish() - : bar.IsBearish(); - if (!result) - { - return result; - } - - // - // Set Direction ... - dir = - isBullishDirection - ? X_DIRECTION_BULLISH - : X_DIRECTION_BEARISH; - - // - // Check Loopback End Bar ... - XOHCL endBar; - result = endBar.Init( - symbol, - period, - end // - ); - if (!result) - { - return result; - } - - // - // End Bar Must be InDirect by Specified Bar ... - result = - isBullishDirection - ? endBar.IsBearish() - : endBar.IsBullish(); - - // - // Check Loopback for Directional Bars ... - - // - return result; - } - // private: // diff --git a/X121SMCEA/Strategy/x-121.smc.test.strategy.class.mq5 b/X121SMCEA/Strategy/x-121.smc.test.strategy.class.mq5 index f3f6f92d..53342c18 100644 Binary files a/X121SMCEA/Strategy/x-121.smc.test.strategy.class.mq5 and b/X121SMCEA/Strategy/x-121.smc.test.strategy.class.mq5 differ