diff --git a/Documents/BKP/tmp.backtester.codes.mq5 b/Documents/BKP/tmp.backtester.codes.mq5 index f836ac8c..2745b592 100644 --- a/Documents/BKP/tmp.backtester.codes.mq5 +++ b/Documents/BKP/tmp.backtester.codes.mq5 @@ -1107,6 +1107,50 @@ if (has) } +///////////////////////////////////////////////////////////// + + + + // // + // // Here We Apply Custom Detecting ... + // detectorConfig.OffDetectors(); + // detectorConfig.detectSupport = true; + // detectorConfig.detectResistance= true; + // detectorConfig.detectSignalKeyBarPattern = true; + + // // + // // Initial Bar for Analysis ... + // // at Signal Time ... + // XOHCL signalBar; + // bool isInited = signalBar.Init( + // signal.symbol, + // signal.period, + // signal.time // + // ); + + // // + // // Analyse Market ... + // fima1Signaller.poiDetector.AnalyseMarket( + // signalBar, + // marketStructure, + // detectorConfig // + // ); + // CArrayObj *iObjects; + // int drawnsCount = fima2Signaller.poiDrawer.DrawMarketStructure( + // marketStructure, + // marketStructureDrawerConfig, + // iObjects // + // ); + // if (IsValidSize(drawnsCount)) + // { + // // + // AddObjects( + // iObjects, + // eaDraws // + // ); + // } + + ///////////////////////////////////////////////////////////// diff --git a/Experts/x-saherelm.xfima.backtester.ea.mq5 b/Experts/x-saherelm.xfima.backtester.ea.mq5 index e91aa1ae..80e04160 100644 --- a/Experts/x-saherelm.xfima.backtester.ea.mq5 +++ b/Experts/x-saherelm.xfima.backtester.ea.mq5 @@ -464,6 +464,7 @@ void OnTick() _Period, 0 // ); + // // Here We Apply Custom Detecting ... detectorConfig.OffDetectors(); @@ -495,6 +496,7 @@ void OnTick() } // + // TODO: Remove this ... XOHCL pBar; bool has = cBar.GetPreviousBar(pBar); if (marketStructure.isPTest) @@ -692,6 +694,9 @@ void OnSignalTriggered(XSignal &signal) return; } + // + return; + // // Draw Signal Vertical Line ... @@ -719,45 +724,6 @@ void OnSignalTriggered(XSignal &signal) eaDraws.Add(iObj); } - // // - // // Here We Apply Custom Detecting ... - // detectorConfig.OffDetectors(); - // detectorConfig.detectSupport = true; - // detectorConfig.detectResistance= true; - // detectorConfig.detectSignalKeyBarPattern = true; - - // // - // // Initial Bar for Analysis ... - // // at Signal Time ... - // XOHCL signalBar; - // bool isInited = signalBar.Init( - // signal.symbol, - // signal.period, - // signal.time // - // ); - - // // - // // Analyse Market ... - // fima1Signaller.poiDetector.AnalyseMarket( - // signalBar, - // marketStructure, - // detectorConfig // - // ); - // CArrayObj *iObjects; - // int drawnsCount = fima2Signaller.poiDrawer.DrawMarketStructure( - // marketStructure, - // marketStructureDrawerConfig, - // iObjects // - // ); - // if (IsValidSize(drawnsCount)) - // { - // // - // AddObjects( - // iObjects, - // eaDraws // - // ); - // } - // // Alert Issued Signal ... string message = signal.GetMessage(); diff --git a/Libraries/x-saherelm.x-ohcl.lib.mq5 b/Libraries/x-saherelm.x-ohcl.lib.mq5 index b6540834..a2ab693d 100644 --- a/Libraries/x-saherelm.x-ohcl.lib.mq5 +++ b/Libraries/x-saherelm.x-ohcl.lib.mq5 @@ -1504,6 +1504,86 @@ struct XOHCL return result; } + // + // Same Checkers ... + + // + bool IsSameAs(XOHCL &item) + { + // + bool result = false; + + // + result = IsValid() && + item.IsValid() && + IsSameTime(item) && + IsSameMarket(item); + + // + return result; + } + + // + bool IsSameTime(XOHCL &item) + { + // + bool result = false; + + // + result = IsValid() && + item.IsValid() && + time == item.time; + + // + return result; + } + + // + bool IsSameSymbol(XOHCL &item) + { + // + bool result = false; + + // + result = IsValid() && + item.IsValid() && + symbol == item.symbol; + + // + return result; + } + + // + bool IsSamePeriod(XOHCL &item) + { + // + bool result = false; + + // + result = IsValid() && + item.IsValid() && + period == item.period; + + // + return result; + } + + // + bool IsSameMarket(XOHCL &item) + { + // + bool result = false; + + // + result = IsValid() && + item.IsValid() && + IsSameSymbol(item) && + IsSamePeriod(item); + + // + return result; + } + // // Other ... string GetTag(string prefix = "") diff --git a/Libraries/x-saherelm.x-poi.extensions.lib.mq5 b/Libraries/x-saherelm.x-poi.extensions.lib.mq5 index c95fafcd..d710100d 100644 --- a/Libraries/x-saherelm.x-poi.extensions.lib.mq5 +++ b/Libraries/x-saherelm.x-poi.extensions.lib.mq5 @@ -2596,6 +2596,56 @@ bool ExtractResistances( //+------------------------------------------------------------------+ //| Find Index | //+------------------------------------------------------------------+ +/** + * Find Specified Item index in a Collection ... + * + * @param index: int, reference to Hold Index if Exists ... + * @param item: Specified item to Detect ... + * @param source: Collection to Search for item ... + * + * @return ( bool ) + */ +bool FindIndex( + int &index, + XOHCL &item, + XOHCL &source[] // +) +{ + // + bool result = false; + + // + index = -1; + + // + int count = ArraySize(source); + result = item.IsValid() && + IsValidSize(count); + if (!result) + { + return result; + } + + // + for (int i = 0; i < count; i++) + { + // + bool isSame = item.IsSameAs(source[i]); + if (isSame) + { + // + index = i; + break; + } + } + + // + result = IsValidIndex(index); + + // + return result; +} + /** * Find Specified Item index in a Collection ... * @@ -2750,6 +2800,54 @@ bool FindIndex( //+------------------------------------------------------------------+ //| Remove | //+------------------------------------------------------------------+ +/** + * Remove Specified Item from a Collection ... + * + * @param item: Specified Item ... + * @param source: Specified Collection for Remove item from it ... + * + * @return ( bool ) + */ +bool Remove( + XOHCL &item, + XOHCL &source[] // +) +{ + // + bool result = false; + + // + result = + item.IsValid() && + HasChild(source); + if (!result) + { + return result; + } + + // + int idx = -1; + result = FindIndex( + idx, + item, + source // + ); + if (!result) + { + return result; + } + + // + result = ArrayRemove( + source, + idx, + 1 // + ); + + // + return result; +} + /** * Remove Specified Item from a Collection ... * @@ -2894,6 +2992,67 @@ bool Remove( return result; } +/** + * Remove Specified items from a Collection ... + * + * @param items: Specified Items to Remove ... + * @param sources: Sepcified Collection for Removing items from it ... + * + * @return ( int ) + */ +int Removes( + XOHCL &items[], + XOHCL &sources[] // +) +{ + // + int result = 0; + + // + bool has = HasChild(items) && + HasChild(sources); + if (!has) + { + return result; + } + + // + int idx = -1; + has = false; + int count = ArraySize(items); + for (int i = 0; i < count; i++) + { + // + // Detect Item Index in Collection ... + has = FindIndex( + idx, + items[i], + sources // + ); + if (has) + { + // + // Remove Detected Index from Collection ... + has = ArrayRemove( + sources, + idx, + 1 // + ); + + // + if (has) + { + // + // Count Removed Items ... + result++; + } + } + } + + // + return result; +} + /** * Remove Specified items from a Collection ... * @@ -3081,6 +3240,69 @@ int Removes( //+------------------------------------------------------------------+ //| Add If Not Exists | //+------------------------------------------------------------------+ +/** + * Add Specified Item to Specified Collection, if not Exists ... + * + * @param item: Item to Add ... + * @param sources: Collection to Add item ... + * @param maxAllowed: int, Max Allowed Collection Size ... + * + * @return ( bool ) + */ +bool AddIfNotExists( + XOHCL &item, + XOHCL &sources[], + int maxAllowed = 0 // +) +{ + // + bool result = false; + + // + // Validate Args ... + result = item.IsValid(); + if (!result) + { + return result; + } + + // + // Check Item Exists or not ... + int idx = -1; + bool isExists = FindIndex( + idx, + item, + sources // + ); + result = !isExists; + if (!result) + { + return result; + } + + // + AddRef( + item, + sources // + ); + + // + // Handle Cleanup Collection + // if Max Reached ... + if (result && + maxAllowed > 0) + { + // + CleanupArray( + sources, + maxAllowed // + ); + } + + // + return result; +} + /** * Add Specified Item to Specified Collection, if not Exists ... * @@ -3674,7 +3896,7 @@ bool ToResistanceBox( * @param bar: Specified Bar ... * @param zone: Specified Zone ... * @param forceBarEdge: bool, flag to Check Breaktion by high ot low ... - * + * * @return ( bool ) */ bool IsBreaked( @@ -3717,6 +3939,118 @@ bool IsBreaked( // return result; } + +/** + * Check Specified Zone is Tested by Specified Bar or not ... + * + * @param bar: Specified Bar ... + * @param zone: Specified Zone ... + * + * @return ( bool ) + */ +bool IsTested( + XOHCL &bar, + XBoxZone &zone // +) +{ + // + bool result = false; + + // + // Validate ... + result = bar.IsValid() && + zone.IsValid(); + if (!result) + { + return result; + } + + // + // Check Break ... + result = + zone.IsBullish() + ? bar.low < zone.upper + : bar.high > zone.lower; + + // + return result; +} + +/** + * Collect all Bars which Breakes Specified Zone ... + * + * @param zone: reference to Specified Zone ... + * @param dest: reference Collection to hold result ... + * + * @return ( int ) + */ +int GetBreakerBars( + XBoxZone &zone, + XOHCL &dest[] // +) +{ + // + int result = 0; + + // + // Validate ... + bool has = zone.IsValid(); + if (!has) + { + return result; + } + + // + // Prepare ... + SpecifiedClean(dest); + + // + // Do Action ... + XOHCL iBar; + int start = zone.ToIndex(); + int end = zone.FromIndex(); + for (int i = start; i < end; i++) + { + // + // Initialize indexed Bar ... + has = iBar.Init( + zone.symbol, + zone.period, + i // + ); + if (!has) + { + continue; + } + + // + has = IsBreaked( + iBar, + zone, + false // Breakes by Close ... + ); + if (has) + { + // + AddIfNotExists( + iBar, + dest // + ); + } + + // + iBar.Clean(); + } + + // + result = ArraySize(dest); + + // + iBar.Clean(); + + // + return result; +} //+------------------------------------------------------------------+ // \ No newline at end of file diff --git a/XFIMAEA/Classes/x-saherelm.xfima.x-poi.detector.class.mq5 b/XFIMAEA/Classes/x-saherelm.xfima.x-poi.detector.class.mq5 index eaf25dc0..c74da29d 100644 --- a/XFIMAEA/Classes/x-saherelm.xfima.x-poi.detector.class.mq5 +++ b/XFIMAEA/Classes/x-saherelm.xfima.x-poi.detector.class.mq5 @@ -1082,6 +1082,67 @@ class XCXFIMAPOIDetector : public XCMarketPatternDetector } } + // + // Detect Recently Tested Zones ... + if ((config.detectSupport || + config.detectResistance) && + config.recentlyTestedZonesMaxLookup > 0) + { + // + XOHCL iBar; + int idx = -1; + bool has = false; + + // + int start = forBar.Index() + 1; + int end = start + config.recentlyTestedZonesMaxLookup; + for (int i = start; i < end; i++) { + // + // Initialize Indexed Bar ... + has = forBar.BarAt(i, iBar); + if (!has) { + continue; + } + + // + // Selecting Support and Resistances ... + + // + // Supports ... + idx = GetYoungestBefore(iBar.time, supports); + has = IsValidIndex(idx); + if (has) { + // + // Check Testing ... + has = IsTested(iBar, supports[idx]); + if (has) { + // + AddIfNotExists( + supports[idx], + structure.recentlyTestedZones // + ); + } + } + + // + // Resistances ... + idx = GetYoungestBefore(iBar.time, resistances); + has = IsValidIndex(idx); + if (has) { + // + // Check Testing ... + has = IsTested(iBar, resistances[idx]); + if (has) { + // + AddIfNotExists( + resistances[idx], + structure.recentlyTestedZones // + ); + } + } + } + } + // // Checkup for FakeBreaked Zones ... if (config.detectSupport || @@ -1091,9 +1152,13 @@ class XCXFIMAPOIDetector : public XCMarketPatternDetector // Retrieve Previous Bar ... int idx = -1; XOHCL pForBar; + XOHCL breakerBar; XBoxZone pSupport; XOHCL pBreakerBar; XBoxZone pResistance; + + // + // Selecting Previously Touched Support / Resistance ... has = forBar.GetPreviousBar(pForBar); if (has) { @@ -1128,43 +1193,90 @@ class XCXFIMAPOIDetector : public XCMarketPatternDetector { pResistance = resistances[idx]; } + } + // + // Check at least a zone Exists ... + // Selecting pTestedZone ... + has = pSupport.IsValid() || + pResistance.IsValid(); + if (has) + { // - // Check at least a zone Exists ... - has = pSupport.IsValid() || - pResistance.IsValid(); + // Support ... + has = pSupport.IsValid(); if (has) { // - // Support ... - has = pSupport.IsValid(); - if (has) - { - // - structure.isPTest = true; - structure.pTestedZone = pSupport; - // has = FindBreakerBar(); - } + structure.isPTest = true; + structure.pTestedZone = pSupport; + } + // + // Resistance ... + has = pResistance.IsValid(); + if (has) + { // - // Resistance ... - has = pResistance.IsValid(); + structure.isPTest = true; + structure.pTestedZone = pResistance; + } + } + + // + // Check pTestedZone Existance ... + has = structure.isPTest && + structure.pTestedZone.IsValid(); + if (has) + { + // + // Get Breaker Bars ... + XOHCL breakerBars[]; + int breakerBarsCount = GetBreakerBars( + structure.pTestedZone, + breakerBars // + ); + has = IsValidSize(breakerBarsCount); + if (has) + { + // + idx = GetYoungestBar(breakerBars); + has = IsValidIndex(idx); if (has) { - // - structure.isPTest = true; - structure.pTestedZone = pResistance; - // has = FindBreakerBar(); + breakerBar = breakerBars[idx]; } } // - // Cleanup Resources ... - pForBar.Clean(); - pSupport.Clean(); - pBreakerBar.Clean(); - pResistance.Clean(); + SpecifiedClean(breakerBars); } + + // + // Check Zone Breaker Bar Exists ... + // Validate Zone Fake Breake Langth ... + has = breakerBar.IsValid(); + if (has) + { + // + // Validate Breake Length ... + has = (breakerBar.Index() - pForBar.Index()) <= config.supportAndResistanceBreakeValidationLength; + } + + // + // Cleanup Resources ... + // + if (!has) + { + // + structure.isPTest = false; + structure.pTestedZone.Clean(); + } + pForBar.Clean(); + pSupport.Clean(); + breakerBar.Clean(); + pBreakerBar.Clean(); + pResistance.Clean(); } } diff --git a/XFIMAEA/Libraries/x-saherelm.xfima.lib.mq5 b/XFIMAEA/Libraries/x-saherelm.xfima.lib.mq5 index afd682e4..0bdd8b25 100644 --- a/XFIMAEA/Libraries/x-saherelm.xfima.lib.mq5 +++ b/XFIMAEA/Libraries/x-saherelm.xfima.lib.mq5 @@ -85,6 +85,7 @@ struct XFIMAPatternDetectorConfig // // Support and Resistance ... + int recentlyTestedZonesMaxLookup; int supportAndResistanceValidationLength; int minAllowdSupportAndResistanceStrength; int supportAndResistanceMaxAllowedLoopback; @@ -162,6 +163,7 @@ struct XFIMAPatternDetectorConfig fvgLoopback = 0; trendingNumberOfSwings = 0; trendingSwingShoulders = 0; + recentlyTestedZonesMaxLookup = 0; supportAndResistanceValidationLength = 0; minAllowdSupportAndResistanceStrength = 0; supportAndResistanceMaxAllowedLoopback = 0; @@ -235,6 +237,7 @@ struct XFIMAPatternDetectorConfig // // Support and Resistance ... + recentlyTestedZonesMaxLookup = 100; supportAndResistanceValidationLength = 100; minAllowdSupportAndResistanceStrength = 1; supportAndResistanceMaxAllowedLoopback = 1500; @@ -385,8 +388,9 @@ struct XFIMAMarketStructure // // TODO: For Test ... bool isPTest; + XOHCL pBreakerBar; XBoxZone pTestedZone; - XBoxZone recentlyTestedZone; + XBoxZone recentlyTestedZones[]; // // Analysis ... @@ -469,6 +473,7 @@ struct XFIMAMarketStructure // SpecifiedClean(trendSwings); + SpecifiedClean(recentlyTestedZones); // ZeroMemory(this);