diff --git a/Classes/x-saherelm.x-market.pattern.class.mq5 b/Classes/x-saherelm.x-market.pattern.class.mq5 index 596a4955..60d9b135 100644 --- a/Classes/x-saherelm.x-market.pattern.class.mq5 +++ b/Classes/x-saherelm.x-market.pattern.class.mq5 @@ -232,60 +232,6 @@ class XCMarketPatternDetector : public XCBase // // Detectors ... - bool IsPeak( - XOHCL &bar, - int validationLength = 7 // - ) { - // - bool result = false; - - // - // Normalize ... - validationLength = NormalizeInt(validationLength, 2); - - // - // Validate ... - result = bar.IsValid(); - if (!result) - { - return result; - } - - // - // Define Requirements ... - result = bar.FindHighest(validationLength, MODE_HIGH) <= bar.high; - - // - return result; - } - - bool IsVale( - XOHCL &bar, - int validationLength = 7 // - ) { - // - bool result = false; - - // - // Normalize ... - validationLength = NormalizeInt(validationLength, 2); - - // - // Validate ... - result = bar.IsValid(); - if (!result) - { - return result; - } - - // - // Define Requirements ... - result = bar.FindLowest(validationLength, MODE_LOW) >= bar.low; - - // - return result; - } - /** * Check Specified Bar is Peak or Vale ... * @@ -298,7 +244,9 @@ class XCMarketPatternDetector : public XCBase bool IsPV( XOHCL &bar, ENUM_X_DIRECTION &dir, - int validationLength = 7 // + int validationLength = 7, + ENUM_X_PRICE peakPriceType = X_PRICE_HIGH, // + ENUM_X_PRICE valePriceType = X_PRICE_LOW // ) { // @@ -314,64 +262,55 @@ class XCMarketPatternDetector : public XCBase // // Validate ... - result = bar.IsValid(); + result = bar.IsValid() && + IsXValid(peakPriceType) && + IsXValid(valePriceType); if (!result) { return result; } // - // Define Requirements ... - XOHCL iBar; - bool isPeak = true; - bool isVale = true; - int start = bar.Index(); - int end = start + validationLength; - for (int i = start; i < end; i++) - { - // - iBar.Clean(); - result = bar.BarAt(i, iBar); - if (!result) - { - // - isVale = false; - isPeak = false; - - // - break; - } - - // - isPeak = - isPeak && - iBar.high <= bar.high; - - // - isVale = - isVale && - iBar.low >= bar.low; - - // - if (!isPeak && !isVale) - { - break; - } - } + int valeIndex = -1; + double vale = bar.FindLowest( + valeIndex, + validationLength, + valePriceType // + ); + double barVale = bar.GetPrice(valePriceType); + bool isVale = + NotEmptyZero(vale) && + NotEmptyZero(barVale) && + IsValidIndex(valeIndex) && + vale >= barVale; // - result = - (isPeak && !isVale) || - (isVale && !isPeak); - if (!result) - { - return result; - } + int peakIndex = -1; + double peak = bar.FindHighest( + peakIndex, + validationLength, + peakPriceType // + ); + double barPeak = bar.GetPrice(peakPriceType); + bool isPeak = + NotEmptyZero(peak) && + NotEmptyZero(barPeak) && + IsValidIndex(peakIndex) && + peak <= barPeak; // - dir = isVale - ? X_DIRECTION_BULLISH - : X_DIRECTION_BEARISH; + result = (isVale && !isPeak) || + (isPeak && !isVale); + if (result) + { + // + dir = + isVale + ? X_DIRECTION_BULLISH + : isPeak + ? X_DIRECTION_BEARISH + : X_DIRECTION_NONE; + } // // Get Result ... @@ -379,7 +318,6 @@ class XCMarketPatternDetector : public XCBase // // Cleanup Resources ... - iBar.Clean(); // return result; diff --git a/Helpers/x-saherelm.xfima.helper.mq5 b/Helpers/x-saherelm.xfima.helper.mq5 index 838810df..f4269fda 100644 --- a/Helpers/x-saherelm.xfima.helper.mq5 +++ b/Helpers/x-saherelm.xfima.helper.mq5 @@ -3364,7 +3364,7 @@ class XCXFIMAHelper : public XCBaseHelper maxAllowedLoopbackLength = NormalizeInt(maxAllowedLoopbackLength, 50); // - pvValidationLength = NormalizeInt(pvValidationLength, 2); + pvValidationLength = NormalizeInt(pvValidationLength, 0); // momentumBarValidationLength = NormalizeInt(momentumBarValidationLength, 2); @@ -3392,12 +3392,14 @@ class XCXFIMAHelper : public XCBaseHelper XOHCL iBar; XOHCL tmpBar; XPivot iPivot; + int count = 0; string iPrefix = NULL; - ENUM_X_DIRECTION iDir; int idx = barIndex - 1; double iMin = EMPTY_VALUE; double iMax = EMPTY_VALUE; double iValue = EMPTY_VALUE; + ENUM_X_DIRECTION iDir = X_DIRECTION_NONE; + ENUM_X_DIRECTION tmpDir = X_DIRECTION_NONE; ENUM_X_PIVOT_TYPE iType = X_PIVOT_TYPE_NONE; int end = barIndex + maxAllowedLoopbackLength; while ( @@ -3430,83 +3432,146 @@ class XCXFIMAHelper : public XCBaseHelper // // PV ... - has = patternDetector.IsPV( - iBar, - iDir, - pvValidationLength // - ); - if (has) + bool isPV = false; + bool isPeak = false; + bool isVale = false; + tmpDir = X_DIRECTION_NONE; + if (pvValidationLength > 0) { // - iPrefix = - IsXBullish(iDir) - ? "XLow" - : "XHigh"; + isPV = patternDetector.IsPV( + iBar, + tmpDir, + pvValidationLength // + ); + isPeak = isPV && + IsXBearish(tmpDir); + isVale = isPV && + IsXBullish(tmpDir); + if (isPV) + { + iPrefix += isPeak ? "XPK" : "XVL"; + } + + // + // Continue Loopback if PV Validation Provided and not isPV ... + if (!isPV) + { + continue; + } } // // Momentum Bar ... - if (!has) + bool isMomentum = patternDetector.IsMomentumBar( + iBar, + iDir, + momentumBarValidationLength, + momentumBarApprovedMultiplier // + ); + if (isMomentum) { // - has = patternDetector.IsMomentumBar( - iBar, - iDir, - momentumBarValidationLength, - momentumBarApprovedMultiplier // - ); - if (has) + if (!IsXValid(tmpDir)) { - iPrefix = "XMomentum"; + tmpDir = iDir; + } + + // + if (iDir != tmpDir) + { + isMomentum = false; + } + else + { + // + count++; + iPrefix += (IsXValid(iPrefix) ? "_" : "") + "MNTM"; } } // // Engulf Bar ... - if (!has) + bool isEngulfed = patternDetector.IsEngulfedBar( + iBar, + iDir // + ); + if (isEngulfed) { // - has = patternDetector.IsEngulfedBar( - iBar, - iDir // - ); - if (has) + if (!IsXValid(tmpDir)) { - iPrefix = "XEngulfed"; + tmpDir = iDir; + } + + // + if (iDir != tmpDir) + { + isEngulfed = false; + } + else + { + // + count++; + iPrefix += (IsXValid(iPrefix) ? "_" : "") + "ENGLF"; } } // // True Gap ... - if (!has) + bool isTrueGaped = patternDetector.IsTrueGapedBar( + iBar, + iDir, + trueGapApprovedStrength // + ); + if (isTrueGaped) { // - has = patternDetector.IsTrueGapedBar( - iBar, - iDir, - trueGapApprovedStrength // - ); - if (has) + if (!IsXValid(tmpDir)) { - iPrefix = "XTrueGap"; + tmpDir = iDir; + } + + // + if (iDir != tmpDir) + { + isTrueGaped = false; + } + else + { + // + count++; + iPrefix += (IsXValid(iPrefix) ? "_" : "") + "TG"; } } // // Pin Bar ... - if (!has) + bool isPinned = patternDetector.IsPinnedBar( + iBar, + iDir, + pinBarShadowApprovedMultiplier, + pinBarRangeMultiplier, + pinBarForceDirection // + ); + if (isPinned) { // - has = patternDetector.IsPinnedBar( - iBar, - iDir, - pinBarShadowApprovedMultiplier, - pinBarRangeMultiplier, - pinBarForceDirection // - ); - if (has) + if (!IsXValid(tmpDir)) { - iPrefix = "XPinned"; + tmpDir = iDir; + } + + // + if (iDir != tmpDir) + { + isPinned = false; + } + else + { + // + count++; + iPrefix += (IsXValid(iPrefix) ? "_" : "") + "PND"; } } @@ -3515,85 +3580,155 @@ class XCXFIMAHelper : public XCBaseHelper // // Star Pattern ... - if (!has) + bool isStarPattern = patternDetector.IsStartPattern( + iBar, + iDir // + ); + if (isStarPattern) { // - has = patternDetector.IsStartPattern( - iBar, - iDir // - ); - if (has) + if (!IsXValid(tmpDir)) { - iPrefix = "XStar"; + tmpDir = iDir; + } + + // + if (iDir != tmpDir) + { + isStarPattern = false; + } + else + { + // + count++; + iPrefix += (IsXValid(iPrefix) ? "_" : "") + "STR"; } } // // Piercing Pattern ... - if (!has) + bool isPiercingPattern = patternDetector.IsPiercingPattern( + iBar, + iDir // + ); + if (isPiercingPattern) { // - has = patternDetector.IsPiercingPattern( - iBar, - iDir // - ); - if (has) + if (!IsXValid(tmpDir)) { - iPrefix = "XPiercing"; + tmpDir = iDir; + } + + // + if (iDir != tmpDir) + { + isPiercingPattern = false; + } + else + { + // + count++; + iPrefix += (IsXValid(iPrefix) ? "_" : "") + "PRCG"; } } // // Rising Pattern ... - if (!has) + bool isRisingPattern = patternDetector.IsRisingPattern( + iBar, + iDir // + ); + if (isRisingPattern) { // - has = patternDetector.IsRisingPattern( - iBar, - iDir // - ); - if (has) + if (!IsXValid(tmpDir)) { - iPrefix = "XRising"; + tmpDir = iDir; + } + + // + if (iDir != tmpDir) + { + isRisingPattern = false; + } + else + { + // + count++; + iPrefix += (IsXValid(iPrefix) ? "_" : "") + "RSG"; } } // // Flag Pattern ... - if (!has) + bool isFlagPattern = patternDetector.IsFlagPattern( + iBar, + iDir, + tmpBar, + flagPatternPullbackLength // + ); + if (isFlagPattern) { // - has = patternDetector.IsFlagPattern( - iBar, - iDir, - tmpBar, - flagPatternPullbackLength // - ); - if (has) + if (!IsXValid(tmpDir)) { - iPrefix = "XFlag"; + tmpDir = iDir; + } + + // + if (iDir != tmpDir) + { + isFlagPattern = false; + } + else + { + // + count++; + iPrefix += (IsXValid(iPrefix) ? "_" : "") + "FLG"; } } // // Signal Key Pattern ... - if (!has) + bool isSignalKeyPattern = patternDetector.IsSignalKeyBarPattern( + iBar, + iDir, + pinBarShadowApprovedMultiplier, + pinBarRangeMultiplier, + pinBarForceDirection // + ); + if (isSignalKeyPattern) { // - has = patternDetector.IsSignalKeyBarPattern( - iBar, - iDir, - pinBarShadowApprovedMultiplier, - pinBarRangeMultiplier, - pinBarForceDirection // - ); - if (has) + if (!IsXValid(tmpDir)) { - iPrefix = "XSignalKey"; + tmpDir = iDir; + } + + // + if (iDir != tmpDir) + { + isSignalKeyPattern = false; + } + else + { + // + count++; + iPrefix += (IsXValid(iPrefix) ? "_" : "") + "SKB"; } } // + has = + isPinned || + isMomentum || + isEngulfed || + isTrueGaped || + isStarPattern || + isFlagPattern || + isRisingPattern || + isPiercingPattern || + isSignalKeyPattern; if (!has) { continue;