From 01197f91520d47fc3015784ee4c767c85ac29315 Mon Sep 17 00:00:00 2001 From: Hadi Khazaee Asl Date: Fri, 26 Sep 2025 02:17:10 +0330 Subject: [PATCH] last ... --- Documents/BKP/tmp.backtester.codes.mq5 | 191 +++ Experts/x-saherelm.xfima.backtester.ea.mq5 | 191 +-- Libraries/x-saherelm.x-poi.extensions.lib.mq5 | 1161 ++++++++++++----- .../x-saherelm.xfima.x-poi.detector.class.mq5 | 152 +++ XFIMAEA/Libraries/x-saherelm.xfima.lib.mq5 | 31 + 5 files changed, 1216 insertions(+), 510 deletions(-) diff --git a/Documents/BKP/tmp.backtester.codes.mq5 b/Documents/BKP/tmp.backtester.codes.mq5 index be71b017..f836ac8c 100644 --- a/Documents/BKP/tmp.backtester.codes.mq5 +++ b/Documents/BKP/tmp.backtester.codes.mq5 @@ -919,3 +919,194 @@ if (has) { draws.Add(iHighTrend); } + +//////////////////////////////////////////////////////// + +// +// if (HasDirection(marketStructure.signalKeyBarPatternDir)) +// { +// Print("Detected ..."); +// } +// if (marketStructure.ob.IsValid() && marketStructure.fvg.IsValid()) +// { +// Print("Detected ..."); +// } +// if (marketStructure.support.IsValid() || marketStructure.resistance.IsValid()) +// { +// // +// XOHCL pBar; +// XOHCL p2Bar; +// bool has = cBar.GetPreviousBar(pBar); +// has = has && +// pBar.GetPreviousBar(p2Bar); +// if (!has) +// { +// // +// pBar.Clean(); +// p2Bar.Clean(); +// return; +// } + +// // +// // Check For PrevZoneExistanse ... +// has = marketStructure.prevZone.IsValid(); +// if (has) { +// // +// // Draw Prev Zone ... +// XCBoxObject *iPrevZoneObj; +// marketStructure.prevZone.to = pBar.time; +// has = fima2Signaller.poiDrawer.DrawBox( +// marketStructure.prevZone, +// iPrevZoneObj // +// ); +// if (has) +// { +// // +// XPOIStyle style; +// fima2Signaller.poiDrawer.GetBoxStyle( +// style, +// marketStructure.prevZone.dir // +// ); +// style.clr = clrYellow; +// fima2Signaller.poiDrawer.ApplyBoxStyle( +// iPrevZoneObj, +// style // +// ); + +// // +// style.Clean(); +// eaDraws.Add(iPrevZoneObj); +// } +// } + +// // +// if (has) +// { +// Print("Detected ..."); +// } + +// // +// // Cleanup Resources ... +// pBar.Clean(); +// p2Bar.Clean(); +// } + +////////////////////////////////////////////////////////// + + + // + XOHCL pBar; + bool has = cBar.GetPreviousBar(pBar); + if (marketStructure.isPTest) + { + // + // Check For PrevZoneExistanse ... + has = marketStructure.pTestedZone.IsValid(); + if (has) + { + // + // Draw Prev Zone ... + XCBoxObject *iPrevZoneObj; + marketStructure.pTestedZone.to = pBar.time; + has = fima2Signaller.poiDrawer.DrawBox( + marketStructure.pTestedZone, + iPrevZoneObj // + ); + if (has) + { + // + XPOIStyle style; + fima2Signaller.poiDrawer.GetBoxStyle( + style, + marketStructure.pTestedZone.dir // + ); + style.clr = clrYellow; + fima2Signaller.poiDrawer.ApplyBoxStyle( + iPrevZoneObj, + style // + ); + + // + style.Clean(); + eaDraws.Add(iPrevZoneObj); + } + } + + // + Print("Previous Tested ..."); + } + pBar.Clean(); + + + +///////////////////////////////////////////////////////////// + + // + // Previous Bar must Has Support or Resistance ... + + // + // Check Supports ... + idx = GetYoungestBefore( + pForBar.time, + supports // + ); + has = + pForBar.IsValid() && + IsValidIndex(idx); + if (has) + { + pSupport = supports[idx]; + } + + // + // Check Resistances ... + idx = GetYoungestBefore( + pForBar.time, + resistances // + ); + has = + pForBar.IsValid() && + IsValidIndex(idx); + if (has) + { + pResistance = resistances[idx]; + } + + // + bool isPSupportTouched = + pSupport.IsValid() && + pForBar.low < pSupport.upper; + + // + bool isPResistanceTouched = + pResistance.IsValid() && + pForBar.high > pResistance.lower; + + // + has = + isPSupportTouched || + isPResistanceTouched; + structure.isPTest = has; + if (has) + { + // + if (isPSupportTouched) + { + // + // Validate Previously Tested Zone Price ... + structure.pTestedZone = pSupport; + } + else if (isPResistanceTouched) + { + // + // Validate Previously Tested Zone Price ... + structure.pTestedZone = pResistance; + } + + // + } + + +///////////////////////////////////////////////////////////// + + diff --git a/Experts/x-saherelm.xfima.backtester.ea.mq5 b/Experts/x-saherelm.xfima.backtester.ea.mq5 index c8487405..e91aa1ae 100644 --- a/Experts/x-saherelm.xfima.backtester.ea.mq5 +++ b/Experts/x-saherelm.xfima.backtester.ea.mq5 @@ -495,172 +495,47 @@ void OnTick() } // - // if (HasDirection(marketStructure.signalKeyBarPatternDir)) - // { - // Print("Detected ..."); - // } - // if (marketStructure.ob.IsValid() && marketStructure.fvg.IsValid()) - // { - // Print("Detected ..."); - // } - if (marketStructure.support.IsValid() || marketStructure.resistance.IsValid()) + XOHCL pBar; + bool has = cBar.GetPreviousBar(pBar); + if (marketStructure.isPTest) { // - XOHCL pBar; - XOHCL p2Bar; - bool has = cBar.GetPreviousBar(pBar); - has = has && - pBar.GetPreviousBar(p2Bar); - if (!has) - { - // - pBar.Clean(); - p2Bar.Clean(); - return; - } - - // // - // bool isSupportTouched = marketStructure.isSupportTouched; - // bool isResistanceTouched = marketStructure.isResistanceTouched; - // has = - // isSupportTouched || - // isResistanceTouched; - // if (!has) - // { - // // - // pBar.Clean(); - // return; - // } - - // // - // // Here we Have to Detect Previous Support or Resistance ... - // XOHCL prevZoneBar; - // XBoxZone prevZoneBox; - - // // - // // Previous Support ... - // bool hasPrevSupport = isSupportTouched && - // fima2Signaller - // .poiDetector - // .HasSupport( - // pBar, - // prevZoneBar, - // detectorConfig.supportAndResistanceValidationLength, - // detectorConfig.supportAndResistanceMaxAllowedLoopback // - // ); - // if (hasPrevSupport) - // { - // hasPrevSupport = ToSupportBox(prevZoneBar, prevZoneBox, pBar.time); - // } - - // // - // // Previous Resistance ... - // bool hasPrevResistance = isResistanceTouched && - // fima2Signaller - // .poiDetector - // .HasSupport( - // pBar, - // prevZoneBar, - // detectorConfig.supportAndResistanceValidationLength, - // detectorConfig.supportAndResistanceMaxAllowedLoopback // - // ); - // if (hasPrevResistance) - // { - // hasPrevResistance = ToResistanceBox(prevZoneBar, prevZoneBox, pBar.time); - // } - - // // - // has = hasPrevSupport || - // hasPrevResistance; - // if (!has) - // { - // // - // pBar.Clean(); - // prevZoneBox.Clean(); - // prevZoneBar.Clean(); - // return; - // } - - // // - // // Select Youngest ... - // int idx = -1; - - // // - // if (hasPrevSupport) - // { - // // - // idx = GetYoungestBefore( - // marketStructure.support.from, - // fima2Signaller.poiDetector.supports // - // ); - // has = IsValidIndex(idx); - // if (has) - // { - // // - // prevZoneBox.to = pBar.time; - // prevZoneBox = fima2Signaller.poiDetector.supports[idx]; - // } - // } - - // // - // if (hasPrevResistance) - // { - // // - // idx = GetYoungestBefore( - // marketStructure.resistance.from, - // fima2Signaller.poiDetector.resistances // - // ); - // has = IsValidIndex(idx); - // if (has) - // { - // // - // prevZoneBox.to = pBar.time; - // prevZoneBox = fima2Signaller.poiDetector.resistances[idx]; - // } - // } - - // - // Draw Prev Zone ... - // XCBoxObject *iPrevZoneObj; - // prevZoneBox.to = pBar.time; - // has = fima2Signaller.poiDrawer.DrawBox( - // prevZoneBox, - // iPrevZoneObj // - // ); - // if (has) - // { - // // - // XPOIStyle style; - // fima2Signaller.poiDrawer.GetBoxStyle( - // style, - // prevZoneBox.dir // - // ); - // style.clr = clrYellow; - // fima2Signaller.poiDrawer.ApplyBoxStyle( - // iPrevZoneObj, - // style // - // ); - - // // - // style.Clean(); - // eaDraws.Add(iPrevZoneObj); - // } - - // - // Check Prev Zone is Breaked or not ... - // + // Check For PrevZoneExistanse ... + has = marketStructure.pTestedZone.IsValid(); if (has) { - Print("Detected ..."); + // + // Draw Prev Zone ... + XCBoxObject *iPrevZoneObj; + marketStructure.pTestedZone.to = pBar.time; + has = fima2Signaller.poiDrawer.DrawBox( + marketStructure.pTestedZone, + iPrevZoneObj // + ); + if (has) + { + // + XPOIStyle style; + fima2Signaller.poiDrawer.GetBoxStyle( + style, + marketStructure.pTestedZone.dir // + ); + style.clr = clrYellow; + fima2Signaller.poiDrawer.ApplyBoxStyle( + iPrevZoneObj, + style // + ); + + // + style.Clean(); + eaDraws.Add(iPrevZoneObj); + } } // - // Cleanup Resources ... - pBar.Clean(); - p2Bar.Clean(); - // prevZoneBox.Clean(); - // prevZoneBar.Clean(); + Print("Previous Tested ..."); } + pBar.Clean(); // cBar.Clean(); diff --git a/Libraries/x-saherelm.x-poi.extensions.lib.mq5 b/Libraries/x-saherelm.x-poi.extensions.lib.mq5 index b67160d0..c95fafcd 100644 --- a/Libraries/x-saherelm.x-poi.extensions.lib.mq5 +++ b/Libraries/x-saherelm.x-poi.extensions.lib.mq5 @@ -978,28 +978,40 @@ int GetLowest( //+------------------------------------------------------------------+ //| Box | //+------------------------------------------------------------------+ -int GetOldestBefore( +/** + * Extract all items which appears Before Specified Time ... + * + * @param _time: Specified Time ... + * @param dest: refrence collection to hold result ... + * @param source: refrence collection to provides data source ... + * + * @return ( int ) + */ +int GetBeforeItems( datetime _time, + XBoxZone &dest[], XBoxZone &source[] // ) { // - int result = -1; + int result = 0; + + // + // Prepare ... + SpecifiedClean(dest); // // Validate ... - bool has = - HasChild(source) && - IsSpecifiedValid(_time); + int count = ArraySize(source); + bool has = HasChild(source) && + IsSpecifiedValid(_time); if (!has) { return result; } // - int idx = -1; - XBoxZone tmps[]; - int count = ArraySize(source); + // Loop through Items ... for (int i = 0; i < count; i++) { // @@ -1009,58 +1021,52 @@ int GetOldestBefore( // AddIfNotExists( source[i], - tmps // + dest // ); } } - has = HasChild(tmps); - if (!has) - { - // - result = -1; - return result; - } // - idx = GetOldest(tmps); - has = - IsValidIndex(idx) && - FindIndex( - result, - tmps[idx], - source // - ); - - // - // Cleanup Resources ... - SpecifiedClean(tmps); + result = ArraySize(dest); // return result; } -int GetOldestAfter( +/** + * Extract all items which appears After Specified Time ... + * + * @param _time: Specified Time ... + * @param dest: refrence collection to hold result ... + * @param source: refrence collection to provides data source ... + * + * @return ( int ) + */ +int GetAfterItems( datetime _time, + XBoxZone &dest[], XBoxZone &source[] // ) { // - int result = -1; + int result = 0; + + // + // Prepare ... + SpecifiedClean(dest); // // Validate ... - bool has = - HasChild(source) && - IsSpecifiedValid(_time); + int count = ArraySize(source); + bool has = HasChild(source) && + IsSpecifiedValid(_time); if (!has) { return result; } // - int idx = -1; - XBoxZone tmps[]; - int count = ArraySize(source); + // Loop through Items ... for (int i = 0; i < count; i++) { // @@ -1070,302 +1076,52 @@ int GetOldestAfter( // AddIfNotExists( source[i], - tmps // + dest // ); } } - has = HasChild(tmps); - if (!has) - { - // - result = -1; - return result; - } // - idx = GetOldest(tmps); - has = - IsValidIndex(idx) && - FindIndex( - result, - tmps[idx], - source // - ); - - // - // Cleanup Resources ... - SpecifiedClean(tmps); + result = ArraySize(dest); // return result; } -int GetYoungestBefore( - datetime _time, - XBoxZone &source[] // -) -{ - // - int result = -1; - - // - // Validate ... - bool has = - HasChild(source) && - IsSpecifiedValid(_time); - if (!has) - { - return result; - } - - // - int idx = -1; - XBoxZone tmps[]; - int count = ArraySize(source); - for (int i = 0; i < count; i++) - { - // - has = source[i].from < _time; - if (has) - { - // - AddIfNotExists( - source[i], - tmps // - ); - } - } - has = HasChild(tmps); - if (!has) - { - // - result = -1; - return result; - } - - // - idx = GetYoungest(tmps); - has = - IsValidIndex(idx) && - FindIndex( - result, - tmps[idx], - source // - ); - - // - // Cleanup Resources ... - SpecifiedClean(tmps); - - // - return result; -} - -int GetYoungestAfter( - datetime _time, - XBoxZone &source[] // -) -{ - // - int result = -1; - - // - // Validate ... - bool has = - HasChild(source) && - IsSpecifiedValid(_time); - if (!has) - { - return result; - } - - // - int idx = -1; - XBoxZone tmps[]; - int count = ArraySize(source); - for (int i = 0; i < count; i++) - { - // - has = source[i].from > _time; - if (has) - { - // - AddIfNotExists( - source[i], - tmps // - ); - } - } - has = HasChild(tmps); - if (!has) - { - // - result = -1; - return result; - } - - // - idx = GetYoungest(tmps); - has = - IsValidIndex(idx) && - FindIndex( - result, - tmps[idx], - source // - ); - - // - // Cleanup Resources ... - SpecifiedClean(tmps); - - // - return result; -} - -int GetHighestAbove( +/** + * Extract all items which appears Above Specified Value ... + * + * @param _value: Specified Value ... + * @param dest: refrence collection to hold result ... + * @param source: refrence collection to provides data source ... + * + * @return ( int ) + */ +int GetAboveItems( double _value, + XBoxZone &dest[], XBoxZone &source[] // ) { // - int result = -1; + int result = 0; + + // + // Prepare ... + SpecifiedClean(dest); // // Validate ... - bool has = - HasChild(source) && - NotEmptyZero(_value); - if (!has) - { - return result; - } - - // - int idx = -1; - XBoxZone tmps[]; int count = ArraySize(source); - for (int i = 0; i < count; i++) - { - // - has = source[i].upper > _value; - if (has) - { - // - AddIfNotExists( - source[i], - tmps // - ); - } - } - has = HasChild(tmps); - if (!has) - { - // - result = -1; - return result; - } - - // - idx = GetHighest(tmps); - has = - IsValidIndex(idx) && - FindIndex( - result, - tmps[idx], - source // - ); - - // - // Cleanup Resources ... - SpecifiedClean(tmps); - - // - return result; -} - -int GetHighestBelow( - double _value, - XBoxZone &source[] // -) -{ - // - int result = -1; - - // - // Validate ... - bool has = - HasChild(source) && - NotEmptyZero(_value); + bool has = HasChild(source) && + NotEmptyZero(_value); if (!has) { return result; } // - int idx = -1; - XBoxZone tmps[]; - int count = ArraySize(source); - for (int i = 0; i < count; i++) - { - // - has = source[i].upper < _value; - if (has) - { - // - AddIfNotExists( - source[i], - tmps // - ); - } - } - has = HasChild(tmps); - if (!has) - { - // - result = -1; - return result; - } - - // - idx = GetHighest(tmps); - has = - IsValidIndex(idx) && - FindIndex( - result, - tmps[idx], - source // - ); - - // - // Cleanup Resources ... - SpecifiedClean(tmps); - - // - return result; -} - -int GetLowestAbove( - double _value, - XBoxZone &source[] // -) -{ - // - int result = -1; - - // - // Validate ... - bool has = - HasChild(source) && - NotEmptyZero(_value); - if (!has) - { - return result; - } - - // - int idx = -1; - XBoxZone tmps[]; - int count = ArraySize(source); + // Loop through Items ... for (int i = 0; i < count; i++) { // @@ -1375,36 +1131,666 @@ int GetLowestAbove( // AddIfNotExists( source[i], - tmps // + dest // ); } } - has = HasChild(tmps); + + // + result = ArraySize(dest); + + // + return result; +} + +/** + * Extract all items which appears Below Specified Value ... + * + * @param _value: Specified Value ... + * @param dest: refrence collection to hold result ... + * @param source: refrence collection to provides data source ... + * + * @return ( int ) + */ +int GetBelowItems( + double _value, + XBoxZone &dest[], + XBoxZone &source[] // +) +{ + // + int result = 0; + + // + // Prepare ... + SpecifiedClean(dest); + + // + // Validate ... + int count = ArraySize(source); + bool has = HasChild(source) && + NotEmptyZero(_value); if (!has) { - // - result = -1; return result; } // - idx = GetLowest(tmps); + // Loop through Items ... + for (int i = 0; i < count; i++) + { + // + has = source[i].upper < _value; + if (has) + { + // + AddIfNotExists( + source[i], + dest // + ); + } + } + + // + result = ArraySize(dest); + + // + return result; +} + +/** + * Get Oldest Item Index of all items which appears Before Specified Value ... + * + * @param _time: Specified Time ... + * @param source: refrence collection to provides data source ... + * + * @return ( int ) + */ +int GetOldestBefore( + datetime _time, + XBoxZone &source[] // +) +{ + // + int result = -1; + + // + XBoxZone tmps[]; + int tmpsCount = GetBeforeItems( + _time, + tmps, // Dest ... + source // Source ... + ); + bool has = IsValidSize(tmpsCount); + int idx = GetOldest(tmps); has = + has && IsValidIndex(idx) && FindIndex( result, tmps[idx], source // ); - - // - // Cleanup Resources ... SpecifiedClean(tmps); // return result; } +/** + * Get Oldest Item Index of all items which appears After Specified Value ... + * + * @param _time: Specified Time ... + * @param source: refrence collection to provides data source ... + * + * @return ( int ) + */ +int GetOldestAfter( + datetime _time, + XBoxZone &source[] // +) +{ + // + int result = -1; + + // + XBoxZone tmps[]; + int tmpsCount = GetAfterItems( + _time, + tmps, // Dest ... + source // Source ... + ); + bool has = IsValidSize(tmpsCount); + int idx = GetOldest(tmps); + has = + has && + IsValidIndex(idx) && + FindIndex( + result, + tmps[idx], + source // + ); + SpecifiedClean(tmps); + + // + return result; +} + +/** + * Get Oldest Item Index of all items which appears Above Specified Value ... + * + * @param _value: Specified Value ... + * @param source: refrence collection to provides data source ... + * + * @return ( int ) + */ +int GetOldestAbove( + double _value, + XBoxZone &source[] // +) +{ + // + int result = -1; + + // + XBoxZone tmps[]; + int tmpsCount = GetAboveItems( + _value, + tmps, // Dest ... + source // Source ... + ); + bool has = IsValidSize(tmpsCount); + int idx = GetOldest(tmps); + has = + has && + IsValidIndex(idx) && + FindIndex( + result, + tmps[idx], + source // + ); + SpecifiedClean(tmps); + + // + return result; +} + +/** + * Get Oldest Item Index of all items which appears Below Specified Value ... + * + * @param _value: Specified Value ... + * @param source: refrence collection to provides data source ... + * + * @return ( int ) + */ +int GetOldestBelow( + double _value, + XBoxZone &source[] // +) +{ + // + int result = -1; + + // + XBoxZone tmps[]; + int tmpsCount = GetBelowItems( + _value, + tmps, // Dest ... + source // Source ... + ); + bool has = IsValidSize(tmpsCount); + int idx = GetOldest(tmps); + has = + has && + IsValidIndex(idx) && + FindIndex( + result, + tmps[idx], + source // + ); + SpecifiedClean(tmps); + + // + return result; +} + +/** + * Get Youngest Item Index of all items which appears Before Specified Value ... + * + * @param _time: Specified Time ... + * @param source: refrence collection to provides data source ... + * + * @return ( int ) + */ +int GetYoungestBefore( + datetime _time, + XBoxZone &source[] // +) +{ + // + int result = -1; + + // + XBoxZone tmps[]; + int tmpsCount = GetBeforeItems( + _time, + tmps, // Dest ... + source // Source ... + ); + bool has = IsValidSize(tmpsCount); + int idx = GetYoungest(tmps); + has = + has && + IsValidIndex(idx) && + FindIndex( + result, + tmps[idx], + source // + ); + SpecifiedClean(tmps); + + // + return result; +} + +/** + * Get Youngest Item Index of all items which appears After Specified Value ... + * + * @param _time: Specified Time ... + * @param source: refrence collection to provides data source ... + * + * @return ( int ) + */ +int GetYoungestAfter( + datetime _time, + XBoxZone &source[] // +) +{ + // + int result = -1; + + // + XBoxZone tmps[]; + int tmpsCount = GetAfterItems( + _time, + tmps, // Dest ... + source // Source ... + ); + bool has = IsValidSize(tmpsCount); + int idx = GetYoungest(tmps); + has = + has && + IsValidIndex(idx) && + FindIndex( + result, + tmps[idx], + source // + ); + SpecifiedClean(tmps); + + // + return result; +} + +/** + * Get Youngest Item Index of all items which appears Above Specified Value ... + * + * @param _value: Specified Value ... + * @param source: refrence collection to provides data source ... + * + * @return ( int ) + */ +int GetYoungestAbove( + double _value, + XBoxZone &source[] // +) +{ + // + int result = -1; + + // + XBoxZone tmps[]; + int tmpsCount = GetAboveItems( + _value, + tmps, // Dest ... + source // Source ... + ); + bool has = IsValidSize(tmpsCount); + int idx = GetYoungest(tmps); + has = + has && + IsValidIndex(idx) && + FindIndex( + result, + tmps[idx], + source // + ); + SpecifiedClean(tmps); + + // + return result; +} + +/** + * Get Youngest Item Index of all items which appears Below Specified Value ... + * + * @param _value: Specified Value ... + * @param source: refrence collection to provides data source ... + * + * @return ( int ) + */ +int GetYoungestBelow( + double _value, + XBoxZone &source[] // +) +{ + // + int result = -1; + + // + XBoxZone tmps[]; + int tmpsCount = GetBelowItems( + _value, + tmps, // Dest ... + source // Source ... + ); + bool has = IsValidSize(tmpsCount); + int idx = GetYoungest(tmps); + has = + has && + IsValidIndex(idx) && + FindIndex( + result, + tmps[idx], + source // + ); + SpecifiedClean(tmps); + + // + return result; +} + +/** + * Get Highest Item Index of all items which appears Before Specified Value ... + * + * @param _time: Specified Time ... + * @param source: refrence collection to provides data source ... + * + * @return ( int ) + */ +int GetHighestBefore( + datetime _time, + XBoxZone &source[] // +) +{ + // + int result = -1; + + // + XBoxZone tmps[]; + int tmpsCount = GetBeforeItems( + _time, + tmps, // Dest ... + source // Source ... + ); + bool has = IsValidSize(tmpsCount); + int idx = GetHighest(tmps); + has = + has && + IsValidIndex(idx) && + FindIndex( + result, + tmps[idx], + source // + ); + SpecifiedClean(tmps); + + // + return result; +} + +/** + * Get Highest Item Index of all items which appears After Specified Value ... + * + * @param _time: Specified Time ... + * @param source: refrence collection to provides data source ... + * + * @return ( int ) + */ +int GetHighestAfter( + datetime _time, + XBoxZone &source[] // +) +{ + // + int result = -1; + + // + XBoxZone tmps[]; + int tmpsCount = GetAfterItems( + _time, + tmps, // Dest ... + source // Source ... + ); + bool has = IsValidSize(tmpsCount); + int idx = GetHighest(tmps); + has = + has && + IsValidIndex(idx) && + FindIndex( + result, + tmps[idx], + source // + ); + SpecifiedClean(tmps); + + // + return result; +} + +/** + * Get Highest Item Index of all items which appears Above Specified Value ... + * + * @param _value: Specified Value ... + * @param source: refrence collection to provides data source ... + * + * @return ( int ) + */ +int GetHighestAbove( + double _value, + XBoxZone &source[] // +) +{ + // + int result = -1; + + // + XBoxZone tmps[]; + int tmpsCount = GetAboveItems( + _value, + tmps, // Dest ... + source // Source ... + ); + bool has = IsValidSize(tmpsCount); + int idx = GetHighest(tmps); + has = + has && + IsValidIndex(idx) && + FindIndex( + result, + tmps[idx], + source // + ); + SpecifiedClean(tmps); + + // + return result; +} + +/** + * Get Highest Item Index of all items which appears Below Specified Value ... + * + * @param _value: Specified Value ... + * @param source: refrence collection to provides data source ... + * + * @return ( int ) + */ +int GetHighestBelow( + double _value, + XBoxZone &source[] // +) +{ + // + int result = -1; + + // + XBoxZone tmps[]; + int tmpsCount = GetBelowItems( + _value, + tmps, // Dest ... + source // Source ... + ); + bool has = IsValidSize(tmpsCount); + int idx = GetHighest(tmps); + has = + has && + IsValidIndex(idx) && + FindIndex( + result, + tmps[idx], + source // + ); + SpecifiedClean(tmps); + + // + return result; +} + +/** + * Get Lowest Item Index of all items which appears Before Specified Value ... + * + * @param _time: Specified Time ... + * @param source: refrence collection to provides data source ... + * + * @return ( int ) + */ +int GetLowestBefore( + datetime _time, + XBoxZone &source[] // +) +{ + // + int result = -1; + + // + XBoxZone tmps[]; + int tmpsCount = GetBeforeItems( + _time, + tmps, // Dest ... + source // Source ... + ); + bool has = IsValidSize(tmpsCount); + int idx = GetLowest(tmps); + has = + has && + IsValidIndex(idx) && + FindIndex( + result, + tmps[idx], + source // + ); + SpecifiedClean(tmps); + + // + return result; +} + +/** + * Get Lowest Item Index of all items which appears After Specified Value ... + * + * @param _time: Specified Time ... + * @param source: refrence collection to provides data source ... + * + * @return ( int ) + */ +int GetLowestAfter( + datetime _time, + XBoxZone &source[] // +) +{ + // + int result = -1; + + // + XBoxZone tmps[]; + int tmpsCount = GetAfterItems( + _time, + tmps, // Dest ... + source // Source ... + ); + bool has = IsValidSize(tmpsCount); + int idx = GetLowest(tmps); + has = + has && + IsValidIndex(idx) && + FindIndex( + result, + tmps[idx], + source // + ); + SpecifiedClean(tmps); + + // + return result; +} + +/** + * Get Lowest Item Index of all items which appears Above Specified Value ... + * + * @param _value: Specified Value ... + * @param source: refrence collection to provides data source ... + * + * @return ( int ) + */ +int GetLowestAbove( + double _value, + XBoxZone &source[] // +) +{ + // + int result = -1; + + // + XBoxZone tmps[]; + int tmpsCount = GetAboveItems( + _value, + tmps, // Dest ... + source // Source ... + ); + bool has = IsValidSize(tmpsCount); + int idx = GetLowest(tmps); + has = + has && + IsValidIndex(idx) && + FindIndex( + result, + tmps[idx], + source // + ); + SpecifiedClean(tmps); + + // + return result; +} + +/** + * Get Lowest Item Index of all items which appears Below Specified Value ... + * + * @param _value: Specified Value ... + * @param source: refrence collection to provides data source ... + * + * @return ( int ) + */ int GetLowestBelow( double _value, XBoxZone &source[] // @@ -1414,53 +1800,74 @@ int GetLowestBelow( int result = -1; // - // Validate ... - bool has = - HasChild(source) && - NotEmptyZero(_value); - if (!has) - { - return result; - } - - // - int idx = -1; XBoxZone tmps[]; - int count = ArraySize(source); - for (int i = 0; i < count; i++) - { - // - has = source[i].lower < _value; - if (has) - { - // - AddIfNotExists( - source[i], - tmps // - ); - } - } - has = HasChild(tmps); - if (!has) - { - // - result = -1; - return result; - } - - // - idx = GetLowest(tmps); + int tmpsCount = GetBelowItems( + _value, + tmps, // Dest ... + source // Source ... + ); + bool has = IsValidSize(tmpsCount); + int idx = GetLowest(tmps); has = + has && IsValidIndex(idx) && FindIndex( result, tmps[idx], source // ); + SpecifiedClean(tmps); // - // Cleanup Resources ... - SpecifiedClean(tmps); + return result; +} + +/** + * Validate an Item Strength ... + * + * @param item: Specified Item for Validating ... + * @param minAllowedStrength: int, Minimum required Strength in Point ... + * + * @return ( bool ) + */ +bool ValidateStrength( + XBoxZone &item, + int minAllowedStrength = 0 // +) +{ + // + bool result = false; + + // + // Normalize ... + minAllowedStrength = NormalizeInt(minAllowedStrength, 0); + + // + // Validate ... + result = item.IsValid(); + if (!result) + { + return result; + } + + // + // If doent provide Specified Strength Validate Zone ... + result = minAllowedStrength <= 0; + if (result) + { + return result; + } + + // + double points = GetPoints(item.symbol); + double requiredStrength = minAllowedStrength * points; + double itemStrength = item.upper - item.lower; + + // + result = + itemStrength > 0 && + requiredStrength > 0 && + itemStrength > requiredStrength; // return result; @@ -3260,6 +3667,56 @@ bool ToResistanceBox( // return result; } + +/** + * Check Specified Zone is Breaked by Specified Bar or not ... + * + * @param bar: Specified Bar ... + * @param zone: Specified Zone ... + * @param forceBarEdge: bool, flag to Check Breaktion by high ot low ... + * + * @return ( bool ) + */ +bool IsBreaked( + XOHCL &bar, + XBoxZone &zone, + bool forceBarEdge = false // +) +{ + // + bool result = false; + + // + // Validate ... + result = bar.IsValid() && + zone.IsValid(); + if (!result) + { + return result; + } + + // + // Check Break ... + result = + zone.IsBullish() + ? bar.close > zone.upper + : bar.close < zone.lower; + + // + // Apply Force Bar Edge ... + if (forceBarEdge) + { + // + result = + result && + zone.IsBullish() + ? bar.low > zone.upper + : bar.high < zone.lower; + } + + // + 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 daa987b5..eaf25dc0 100644 --- a/XFIMAEA/Classes/x-saherelm.xfima.x-poi.detector.class.mq5 +++ b/XFIMAEA/Classes/x-saherelm.xfima.x-poi.detector.class.mq5 @@ -526,6 +526,7 @@ class XCXFIMAPOIDetector : public XCMarketPatternDetector structure.bar = forBar; // + int idx = -1; bool has = false; int maxAllowedCollecting = 50; ENUM_X_DIRECTION iDir = X_DIRECTION_NONE; @@ -861,6 +862,20 @@ class XCXFIMAPOIDetector : public XCMarketPatternDetector // XBoxZone supportBox; has = ToSupportBox(support, supportBox); + + // + // Validate Zone Strength if Provided ... + if (config.minAllowdSupportAndResistanceStrength > 0) + { + // + has = has && + ValidateStrength( + supportBox, + config.minAllowdSupportAndResistanceStrength // + ); + } + + // if (has) { // @@ -908,6 +923,20 @@ class XCXFIMAPOIDetector : public XCMarketPatternDetector // XBoxZone resistanceBox; has = ToResistanceBox(resistance, resistanceBox); + + // + // Validate Zone Strength if Provided ... + if (config.minAllowdSupportAndResistanceStrength > 0) + { + // + has = has && + ValidateStrength( + resistanceBox, + config.minAllowdSupportAndResistanceStrength // + ); + } + + // if (has) { // @@ -1014,6 +1043,129 @@ class XCXFIMAPOIDetector : public XCMarketPatternDetector structure.zigzagAnalysis = analysis; } } + + // + // COMPLEX Actions ... + + // + // Lockup For Previous Zone ... + has = structure.isSupportTouched || + structure.isResistanceTouched; + if (has) + { + // + if (structure.isSupportTouched) + { + // + idx = GetYoungestBefore( + structure.support.from, + supports // + ); + has = IsValidIndex(idx); + if (has) + { + structure.prevZone = supports[idx]; + } + } + else if (structure.isResistanceTouched) + { + // + idx = GetYoungestBefore( + structure.resistance.from, + resistances // + ); + has = IsValidIndex(idx); + if (has) + { + structure.prevZone = resistances[idx]; + } + } + } + + // + // Checkup for FakeBreaked Zones ... + if (config.detectSupport || + config.detectResistance) + { + // + // Retrieve Previous Bar ... + int idx = -1; + XOHCL pForBar; + XBoxZone pSupport; + XOHCL pBreakerBar; + XBoxZone pResistance; + has = forBar.GetPreviousBar(pForBar); + if (has) + { + // + // Detecting Nearest Above Lows Support ... + idx = GetYoungestAbove( + pForBar.low, + supports // + ); + has = IsValidIndex(idx) && + IsBreaked( + forBar, + supports[idx] // + ); + if (has) + { + pSupport = supports[idx]; + } + + // + // Detecting Nearest Below Highs Resistance ... + idx = GetYoungestBelow( + pForBar.high, + resistances // + ); + has = IsValidIndex(idx) && + IsBreaked( + forBar, + resistances[idx] // + ); + if (has) + { + pResistance = resistances[idx]; + } + + // + // Check at least a zone Exists ... + has = pSupport.IsValid() || + pResistance.IsValid(); + if (has) + { + // + // Support ... + has = pSupport.IsValid(); + if (has) + { + // + structure.isPTest = true; + structure.pTestedZone = pSupport; + // has = FindBreakerBar(); + } + + // + // Resistance ... + has = pResistance.IsValid(); + if (has) + { + // + structure.isPTest = true; + structure.pTestedZone = pResistance; + // has = FindBreakerBar(); + } + } + + // + // Cleanup Resources ... + pForBar.Clean(); + pSupport.Clean(); + pBreakerBar.Clean(); + pResistance.Clean(); + } + } } // diff --git a/XFIMAEA/Libraries/x-saherelm.xfima.lib.mq5 b/XFIMAEA/Libraries/x-saherelm.xfima.lib.mq5 index d03ec4fe..afd682e4 100644 --- a/XFIMAEA/Libraries/x-saherelm.xfima.lib.mq5 +++ b/XFIMAEA/Libraries/x-saherelm.xfima.lib.mq5 @@ -86,7 +86,9 @@ struct XFIMAPatternDetectorConfig // // Support and Resistance ... int supportAndResistanceValidationLength; + int minAllowdSupportAndResistanceStrength; int supportAndResistanceMaxAllowedLoopback; + int supportAndResistanceBreakeValidationLength; // // TrueGap ... @@ -161,7 +163,9 @@ struct XFIMAPatternDetectorConfig trendingNumberOfSwings = 0; trendingSwingShoulders = 0; supportAndResistanceValidationLength = 0; + minAllowdSupportAndResistanceStrength = 0; supportAndResistanceMaxAllowedLoopback = 0; + supportAndResistanceBreakeValidationLength = 0; truwGapApprovedPointMultiplier = 0; flagPatternMinimumPullbackBars = 0; momentumBarRangeLength = 0; @@ -176,6 +180,9 @@ struct XFIMAPatternDetectorConfig maPivotsValidationLength = 0; numberOfRequiredPivotsForAnalysis = 0; maxAllowedLoopbackLengthForAnalysis = 0; + + // + ZeroMemory(this); } /** @@ -229,7 +236,9 @@ struct XFIMAPatternDetectorConfig // // Support and Resistance ... supportAndResistanceValidationLength = 100; + minAllowdSupportAndResistanceStrength = 1; supportAndResistanceMaxAllowedLoopback = 1500; + supportAndResistanceBreakeValidationLength = 3; // // TrueGap ... @@ -360,12 +369,25 @@ struct XFIMAMarketStructure XBoxZone support; XBoxZone resistance; + // + // Previous Support or Resistance based on current ... + // + // Current Support is Touched => Prev Support; + // Current Resistance is Touched => Prev Resistance; + XBoxZone prevZone; + // bool isOBTouched; bool isFVGTouched; bool isSupportTouched; bool isResistanceTouched; + // + // TODO: For Test ... + bool isPTest; + XBoxZone pTestedZone; + XBoxZone recentlyTestedZone; + // // Analysis ... XPivotAnalysis pvAnalysis; @@ -420,6 +442,9 @@ struct XFIMAMarketStructure isSupportTouched = false; isResistanceTouched = false; + // + prevZone.Clean(); + // bar.Clean(); flagSwing.Clean(); @@ -444,6 +469,9 @@ struct XFIMAMarketStructure // SpecifiedClean(trendSwings); + + // + ZeroMemory(this); } // @@ -542,6 +570,9 @@ struct XFIMAMarketStructureDrawerConfig drawFIMAMAPivotsAnalysisPivots = false; drawFIMASARPivotsAnalysisPivots = false; drawFIMAZigZagPivotsAnalysisPivots = false; + + // + ZeroMemory(this); } /**