diff --git a/Classes/x-saherelm.x-market.pattern.class.mq5 b/Classes/x-saherelm.x-market.pattern.class.mq5 index a5134e8d..d68a45d3 100644 --- a/Classes/x-saherelm.x-market.pattern.class.mq5 +++ b/Classes/x-saherelm.x-market.pattern.class.mq5 @@ -30,6 +30,84 @@ // // Definitions ... +enum ENUM_X_DETECTOR_ZONE_ACTION +{ + X_DETECTOR_ZONE_ACTION_NONE = 0, + // + // Support ... + X_DETECTOR_ZONE_ACTION_MAJOR_SUPPORT_DETECTED = 1, + X_DETECTOR_ZONE_ACTION_MAJOR_SUPPORT_BREAKED = 2, + X_DETECTOR_ZONE_ACTION_MINOR_SUPPORT_DETECTED = 3, + X_DETECTOR_ZONE_ACTION_MINOR_SUPPORT_BREAKED = 4, + // + // Resistance ... + X_DETECTOR_ZONE_ACTION_MAJOR_RESISTANCE_DETECTED = 5, + X_DETECTOR_ZONE_ACTION_MAJOR_RESISTANCE_BREAKED = 6, + X_DETECTOR_ZONE_ACTION_MINOR_RESISTANCE_DETECTED = 7, + X_DETECTOR_ZONE_ACTION_MINOR_RESISTANCE_BREAKED = 8, +}; + +bool IsXValid(ENUM_X_DETECTOR_ZONE_ACTION value) +{ + return value != X_DETECTOR_ZONE_ACTION_NONE; +} + +string ToXString(ENUM_X_DETECTOR_ZONE_ACTION value) +{ + // + string result = NULL; + + // + if (!IsXValid(value)) + { + return result; + } + + // + switch (value) + { + // + case X_DETECTOR_ZONE_ACTION_NONE: + result = "NONE"; + break; + // + case X_DETECTOR_ZONE_ACTION_MAJOR_SUPPORT_DETECTED: + result = "MAJOR_SUPPORT_DETECTED"; + break; + // + case X_DETECTOR_ZONE_ACTION_MAJOR_SUPPORT_BREAKED: + result = "MAJOR_SUPPORT_BREAKED"; + break; + // + case X_DETECTOR_ZONE_ACTION_MINOR_SUPPORT_DETECTED: + result = "MINOR_SUPPORT_DETECTED"; + break; + // + case X_DETECTOR_ZONE_ACTION_MINOR_SUPPORT_BREAKED: + result = "MINOR_SUPPORT_BREAKED"; + break; + // + case X_DETECTOR_ZONE_ACTION_MAJOR_RESISTANCE_DETECTED: + result = "MAJOR_RESISTANCE_DETECTED"; + break; + // + case X_DETECTOR_ZONE_ACTION_MAJOR_RESISTANCE_BREAKED: + result = "MAJOR_RESISTANCE_BREAKED"; + break; + // + case X_DETECTOR_ZONE_ACTION_MINOR_RESISTANCE_DETECTED: + result = "MINOR_RESISTANCE_DETECTED"; + break; + // + case X_DETECTOR_ZONE_ACTION_MINOR_RESISTANCE_BREAKED: + result = "MINOR_RESISTANCE_BREAKED"; + break; + } + + // + return result; +} + // // Implementation ... class XCMarketPatternDetector : public XCBase @@ -40,6 +118,13 @@ class XCMarketPatternDetector : public XCBase // // Props ... + // + XBoxZone zones[]; + XBoxZone majorSupport; + XBoxZone minorSupport; + XBoxZone majorResistance; + XBoxZone minorResistance; + // // Constructor ... XCMarketPatternDetector() @@ -2661,6 +2746,124 @@ class XCMarketPatternDetector : public XCBase return result; } + int UpdateZones( + XOHCL &bar, + ENUM_X_DETECTOR_ZONE_ACTION &actions[], + int loopback = 1500 // + ) + { + // + int result = 0; + + // + // Prepare ... + XClean(actions); + + // + // Normalize ... + loopback = NormalizeInt(loopback, 100); + + // + // Validate ... + bool has = bar.IsValid(); + if (!has) + { + return result; + } + + // + int barIndex = bar.Index(); + + // + // Collect Zones ... + bool hasZone = HasChild(zones); + if (!hasZone) { + // + int start = barIndex; + int end = barIndex + loopback; + for (int i = start; i < end; i++) { + // + // Extract Validated Zones ... + } + } + + // + // Supports ... + bool hasMajorSupport = majorSupport.IsValid(); + bool hasMinorSupport = minorSupport.IsValid(); + + // + // Look For Major Support ... + if (!hasMajorSupport) + { + // + minorSupport.Clean(); + hasMinorSupport = false; + } + + // + // For Looking up Minor Support, we + // have to Ensure Major Support Exists ... + if (hasMajorSupport) + { + // + // Look for Minor Support ... + if (!hasMinorSupport) + { + } + // + // Refine exists Minor Support ... + else + { + } + } + + // + // Resistances ... + bool hasMajorResistance = majorResistance.IsValid(); + bool hasMinorResistance = minorResistance.IsValid(); + + // + // Look For Major Resistance ... + if (!hasMajorResistance) + { + // + minorResistance.Clean(); + hasMinorResistance = false; + } + + // + // For Looking up Minor Resistance, we + // have to Ensure Major Resistance Exists ... + if (hasMajorResistance) + { + // + // Look for Minor Resistance ... + if (!hasMinorResistance) + { + } + // + // Refine exists Minor Resistance ... + else + { + } + } + + // + if (!HasChild(actions)) + { + // + Add( + X_DETECTOR_ZONE_ACTION_NONE, + actions // + ); + } + result = ArraySize(actions); + + // + return result; + } + // // Protected ... protected: diff --git a/Helpers/x-saherelm.xfima.helper.mq5 b/Helpers/x-saherelm.xfima.helper.mq5 index a8ee9470..85fd80a7 100644 --- a/Helpers/x-saherelm.xfima.helper.mq5 +++ b/Helpers/x-saherelm.xfima.helper.mq5 @@ -1221,6 +1221,229 @@ class XCXFIMAHelper : public XCBaseHelper return result; } + /** + * Check Specified Bar has HK Bond Based Trend or not ... + * + * @param dir: ENUM_X_DIRECTION, reference to holds trend direction, if exists ... + * @param barIndex: int, Specified Bar Index ... + * @param validationLength: int, validation of trend ... + * + * @return ( bool ) + */ + bool HasHKBasedTrend( + ENUM_X_DIRECTION &dir, + int barIndex = 0, + int validationLength = 5 // + ) + { + // + bool result = false; + + // + // Prepare ... + dir = X_DIRECTION_NONE; + + // + // Normalize ... + barIndex = NormalizeBarIndex(barIndex); + validationLength = NormalizeInt(validationLength, 1); + + // + // Validate ... + result = IsValid(); + if (!result) + { + return result; + } + + // + // Do ... + + // + // Define Requirements ... + XOHCL iBar; + double hkUpper; + double hkLower; + bool has = false; + int bullishCount = 0; + int bearishCount = 0; + bool isBullish = false; + bool isBearish = false; + + // + // Count Bullish/Bearish Directions ... + int start = barIndex + 1; + int end = start + validationLength; + for (int i = start; i < end; i++) + { + // + // Reading Requirements ... + + // + // Read Indexed Bar ... + iBar.Clean(); + result = iBar.Init( + mSymbol, + mPeriod, + i // + ); + if (!result) + { + break; + } + + // + // Reading Values ... + hkUpper = GetHKBondUpper(i); + hkLower = GetHKBondLower(i); + result = NotEmptyZero(hkUpper) && + NotEmptyZero(hkLower); + if (!result) + { + return result; + } + + // + // Check Trend ... + + // + // Bullish ... + isBullish = iBar.low > hkLower; + if (isBullish) + { + bullishCount++; + } + + // + // Bearish ... + isBearish = iBar.high < hkUpper; + if (isBearish) + { + bearishCount++; + } + + // + iBar.Clean(); + + // + } + + // + // Validate Results ... + isBullish = + bullishCount >= validationLength; + isBearish = + bearishCount >= validationLength; + + // + result = (isBullish && !isBearish) || + (isBearish && !isBullish); + + // + // Setting Direction if Has Trend ... + if (result) + { + // + dir = isBullish + ? X_DIRECTION_BULLISH + : X_DIRECTION_BEARISH; + } + + // + // Cleanup ... + iBar.Clean(); + + // + return result; + } + + /** + * Check Specified Bar has HK Bond Based Trend Switch or not ... + * + * @param dir: ENUM_X_DIRECTION, reference to holds trend direction, if exists ... + * @param barIndex: int, Specified Bar Index ... + * @param validationLength: int, validation of trend ... + * + * @return ( bool ) + */ + bool IsHKBasedTrendSwitch( + ENUM_X_DIRECTION &dir, + int barIndex = 0, + int validationLength = 5 // + ) + { + // + bool result = false; + + // + // Prepare ... + dir = X_DIRECTION_NONE; + + // + // Normalize ... + barIndex = NormalizeBarIndex(barIndex); + validationLength = NormalizeInt(validationLength, 1); + + // + // Validate ... + result = IsValid(); + if (!result) + { + return result; + } + + // + // Do ... + + // + bool hasTrend = HasHKBasedTrend( + dir, + barIndex, + validationLength // + ); + bool isBullish = hasTrend && + IsXBullish(dir); + bool isBearish = hasTrend && + IsXBearish(dir); + + // + bool hasPTrend = HasHKBasedTrend( + dir, + barIndex + 1, + validationLength // + ); + bool isPBullish = hasPTrend && + IsXBullish(dir); + bool isPBearish = hasPTrend && + IsXBearish(dir); + + // + dir = X_DIRECTION_NONE; + + // + // Checking Result ... + isBullish = isBullish && !isPBullish; + isBearish = isBearish && !isPBearish; + + // + result = + (isBullish && !isBearish) || + (isBearish && !isBullish); + if (result) + { + // + dir = isBullish + ? X_DIRECTION_BULLISH + : X_DIRECTION_BEARISH; + } + + // + // Cleanup ... + + // + return result; + } + /** * Check Specified Bar has SAR Switch or not ... * diff --git a/XFIMAEA/Classes/x-saherelm.xfima.signaller.class.mq5 b/XFIMAEA/Classes/x-saherelm.xfima.signaller.class.mq5 index 27eccd1c..3ada567c 100644 --- a/XFIMAEA/Classes/x-saherelm.xfima.signaller.class.mq5 +++ b/XFIMAEA/Classes/x-saherelm.xfima.signaller.class.mq5 @@ -372,56 +372,37 @@ class XCXFIMAStrategy1Signaller : public XCXFIMABaseSignaller structureConfig, barIndex // ); - poiDrawer.drawnObjects.Clear(); - poiDrawer.DrawMarketStructure( - structure, - structureDrawConfig // - ); - - // // - // // Testing Porposes ... - // has = fimaHelper.IsBoundaryFakeBreaked( - // iDir, - // barIndex, - // X_PRICE_CLOSE, - // X_PRICE_CLOSE // + // poiDrawer.drawnObjects.Clear(); + // poiDrawer.DrawMarketStructure( + // structure, + // structureDrawConfig // // ); - // if (has) - // { - // Print("Faked Break ..."); - // } - - // - // Disable Signallers ... - // has = false; - // iDir = X_DIRECTION_NONE; // // Strategy 1 ... - // Works on Support or Resistances Areas ... - has = Strategy1HasSignal( - iBar, - iZone, - iTargets, - iDir, - iFIMAConditions, - structure // - ); + // has = Strategy1HasSignal( + // iBar, + // iZone, + // iTargets, + // iDir, + // iFIMAConditions, + // structure // + // ); // // Strategy 2 ... - // Works on MA Crosses ... + has = false; if (!has) { // - // has = Strategy2HasSignal( - // iBar, - // iZone, - // iTargets, - // iDir, - // iFIMAConditions, - // structure // - // ); + has = Strategy2HasSignal( + iBar, + iZone, + iTargets, + iDir, + iFIMAConditions, + structure // + ); } // @@ -763,7 +744,7 @@ class XCXFIMAStrategy1Signaller : public XCXFIMABaseSignaller // Print("Affected Zone ..."); } - + // // Draw Bar Pattern ... // poiDrawer.DrawPatternAnalysis(barAnalysis, structureDrawConfig.barAnalysisDrawConfig); @@ -905,37 +886,83 @@ class XCXFIMAStrategy1Signaller : public XCXFIMABaseSignaller } // - // Detect Specified MA Cross ... - // result = HasDirection(structure.maCrossDir); + result = false; + bool isBullish = false; + bool isBearish = false; + + // + // Do Signal Detection ... + + // + // result = fimaHelper.HasHKBasedTrend(dir, bar.Index(), 1); + // bool isBullish = result && + // IsXBullish(dir); + // bool isBearish = result && + // IsXBearish(dir); + + // + // Get Bar Pattern ... + // XPatternAnalysis barAnalysis; + // result = + // poiDetector.AnalyseBarPatterns( + // bar, + // barAnalysis, + // structureConfig.barsAnalysisConfig // + // ); + // bool isBullish = barAnalysis.Count(X_DIRECTION_BULLISH) >= 4; + // bool isBearish = barAnalysis.Count(X_DIRECTION_BEARISH) >= 4; // - // Prepare zone ... if (result) { // - zone.to = bar.time; - zone.from = GetBarTime( - bar.symbol, - bar.period, - bar.Index() + 2 // - ); - zone.symbol = bar.symbol; - zone.period = bar.period; - // zone.dir = structure.maCrossDir; - zone.lower = bar.FindLowest(2, MODE_LOW); - zone.upper = bar.FindHighest(2, MODE_HIGH); - // zone.type = name + "_" + ToXString(structure.maCrossDir); + // Draw Bar Patterns Analysis ... + // poiDrawer.DrawPatternAnalysis( + // barAnalysis, + // structureDrawConfig.barAnalysisDrawConfig // + // ); + + // + if (isBullish) + { + Print("Bullish HK Bond Trend ..."); + } + + // + if (isBearish) + { + Print("Bearish HK Bond Trend ..."); + } + + // + Print(ToXString(dir), " Detected ..."); + } + + // + // Cleanup ... + result = false; + dir = X_DIRECTION_NONE; + + // + // Draw Custom Requirements ... + + // + // Prepare Decision Zone ... + if (result) + { + // + // Create Decision Zone and Validate it ... // result = zone.IsValid(); } // - // Check Result ... + // Provide Direction and Targets if Required ... if (result) { // - // dir = structure.maCrossDir; + // Handle Signal Direction ... // // Handle Targets Detection ...