From aa9221195156f9f3d5b097c204c11d353c006783 Mon Sep 17 00:00:00 2001 From: Hadi Khazaee Asl Date: Fri, 20 Jun 2025 19:18:50 +0330 Subject: [PATCH] last works on XCATB V1.0 ... --- Indicators/x-saherelm.x121.xcatb.v1.mq5 | 567 +++++++++++++++--- Libraries/x-saherelm.x-poi.extensions.lib.mq5 | 258 ++++---- 2 files changed, 652 insertions(+), 173 deletions(-) diff --git a/Indicators/x-saherelm.x121.xcatb.v1.mq5 b/Indicators/x-saherelm.x121.xcatb.v1.mq5 index 0d683c67..8744f9ab 100644 --- a/Indicators/x-saherelm.x121.xcatb.v1.mq5 +++ b/Indicators/x-saherelm.x121.xcatb.v1.mq5 @@ -654,6 +654,46 @@ bool mIsBearish = false; XDirectionShift mDirShift; string mTriggerBarConditions; +// +// Counters ... + +// +int mSameSBCount = 0; +int mSameBullishSBCount = 0; +int mSameBearishSBCount = 0; + +// +int mSameKICount = 0; +int mSameBullishKICount = 0; +int mSameBearishKICount = 0; + +// +int mSameHKSCount = 0; +int mSameBullishHKSCount = 0; +int mSameBearishHKSCount = 0; + +// +int mSameSarCount = 0; +int mSameBullishSarCount = 0; +int mSameBearishSarCount = 0; + +// +int mSameTrendCount = 0; +int mSameBullishTrendCount = 0; +int mSameBearishTrendCount = 0; + +// +int mSamePeakCount = 0; +int mSameValeCount = 0; +int mSamePeakGoldenCount = 0; +int mSameValeGoldenCount = 0; + +// +double mSamePeakGoldenMin = 0; +double mSamePeakGoldenMax = 0; +double mSameValeGoldenMin = 0; +double mSameValeGoldenMax = 0; + // // Direction Shift ... @@ -865,9 +905,9 @@ bool isKIBearish = false; bool isKIBearishP = false; // -bool isKISame = false; -bool isBullishKISame = false; -bool isBearishKISame = false; +bool isSameKI = false; +bool isSameBullishKI = false; +bool isSameBearishKI = false; // bool isKISwitchedToBullish = false; @@ -2196,46 +2236,7 @@ void CalculateValues( ); // - // Handling POI(s) ... - - // // - // // Detecting POI(s) ... - // DetectPOIs( - // barIndex, - // prevCalculated, - // ratesTotal, - // open, - // high, - // close, - // low, - // tickVolume // - // ); - - // // - // // Validating ... - // ValidatePOIs( - // barIndex, - // prevCalculated, - // ratesTotal, - // open, - // high, - // close, - // low, - // tickVolume // - // ); - - // // - // // Drawing ... - // DrawPOIs( - // barIndex, - // prevCalculated, - // ratesTotal, - // open, - // high, - // close, - // low, - // tickVolume // - // ); + // Handling Process ... // // Prepare Market Conditions ... @@ -2250,6 +2251,45 @@ void CalculateValues( tickVolume // ); + // + // Detecting POI(s) ... + DetectPOIs( + barIndex, + prevCalculated, + ratesTotal, + open, + high, + close, + low, + tickVolume // + ); + + // + // Validating ... + ValidatePOIs( + barIndex, + prevCalculated, + ratesTotal, + open, + high, + close, + low, + tickVolume // + ); + + // + // Drawing ... + DrawPOIs( + barIndex, + prevCalculated, + ratesTotal, + open, + high, + close, + low, + tickVolume // + ); + // // Do Process on Bars ... DoProcess( @@ -3573,10 +3613,6 @@ void PrepareMarketConditions( isSarBearish && !isSarBearishP; - // - isBullishSarBreakedLast = false; - isBearishSarBreakedLast = false; - // // XSB ... @@ -3596,10 +3632,6 @@ void PrepareMarketConditions( isSBBearish && !isSBBearishP; - // - isBullishSBBreakedLast = false; - isBearishSBBreakedLast = false; - // mSBMin = MathMin(sBarCloseBuffer[pIndex], sBarOpenBuffer[pIndex]); mSBMax = MathMax(sBarCloseBuffer[pIndex], sBarOpenBuffer[pIndex]); @@ -3627,10 +3659,6 @@ void PrepareMarketConditions( isHKSBearish && !isHKSBearishP; - // - isBullishHKSBreakedLast = false; - isBearishHKSBreakedLast = false; - // mHKSMin = MathMin(hkSBarCloseBuffer[pIndex], hkSBarOpenBuffer[pIndex]); mHKSMax = MathMax(hkSBarCloseBuffer[pIndex], hkSBarOpenBuffer[pIndex]); @@ -3651,12 +3679,12 @@ void PrepareMarketConditions( isKIBearishP = kiStateBuffer[p2Index] < 0; // - isKISame = kiBuffer[pIndex] == kiBuffer[p2Index]; - isBullishKISame = - isKISame && + isSameKI = kiBuffer[pIndex] == kiBuffer[p2Index]; + isSameBullishKI = + isSameKI && isKIBullish; - isBearishKISame = - isKISame && + isSameBearishKI = + isSameKI && isKIBearish; // @@ -3667,10 +3695,6 @@ void PrepareMarketConditions( isKIBearish && !isKIBearishP; - // - isBullishKIBreakedLast = false; - isBearishKIBreakedLast = false; - // // XTREND ... @@ -3691,11 +3715,74 @@ void PrepareMarketConditions( !isTrendBearishP; // - isBullishTrendBreakedLast = false; - isBearishTrendBreakedLast = false; + // Detecting Counters and Direction Shifts and it's related Conditions ... // - // Creating Direction Shifts and it's related Conditions ... + // XPV Counters ... + + // + if (isSamePeak) + { + // + mSamePeakCount++; + mSamePeakGoldenMin = + mSamePeakGoldenMin == 0 + ? peakGoldenBuffer[pIndex] + : MathMin(mSamePeakGoldenMin, peakGoldenBuffer[pIndex]); + mSamePeakGoldenMax = + mSamePeakGoldenMax == 0 + ? peakGoldenBuffer[pIndex] + : MathMax(mSamePeakGoldenMax, peakGoldenBuffer[pIndex]); + } + else + { + // + mSamePeakCount = 0; + mSamePeakGoldenMin = 0; + mSamePeakGoldenMax = 0; + } + + // + if (isSameVale) + { + // + mSameValeCount++; + mSameValeGoldenMin = + mSameValeGoldenMin == 0 + ? valeGoldenBuffer[pIndex] + : MathMin(mSameValeGoldenMin, valeGoldenBuffer[pIndex]); + mSameValeGoldenMax = + mSameValeGoldenMax == 0 + ? valeGoldenBuffer[pIndex] + : MathMax(mSameValeGoldenMax, valeGoldenBuffer[pIndex]); + } + else + { + // + mSameValeCount = 0; + mSameValeGoldenMin = 0; + mSameValeGoldenMax = 0; + } + + // + if (isSamePeakGolden) + { + mSamePeakGoldenCount++; + } + else + { + mSamePeakGoldenCount = 0; + } + + // + if (isSameValeGolden) + { + mSameValeGoldenCount++; + } + else + { + mSameValeGoldenCount = 0; + } // // XSB Shifts ... @@ -3767,6 +3854,7 @@ void PrepareMarketConditions( HasChild(mBearishSBChanges); if (mHas) { + isBullishSBBreakedLast = mSBMin > mBearishSBChanges[ArraySize(mBearishSBChanges) - 1].after; } // @@ -3774,6 +3862,64 @@ void PrepareMarketConditions( HasChild(mBullishSBChanges); if (mHas) { + isBearishSBBreakedLast = mSBMax < mBullishSBChanges[ArraySize(mBullishSBChanges) - 1].after; + } + + // + // Counters ... + + // + if (!isSBSwitchedToBullish && + !isSBSwitchedToBearish) + { + // + bool isDBullish = + isSBBullish && + isSBBullishP; + if (isDBullish) + { + mSameBullishSBCount++; + } + else + { + mSameBullishSBCount = 0; + } + + // + bool isDBearish = + isSBBearish && + isSBBearishP; + if (isDBearish) + { + mSameBearishSBCount++; + } + else + { + mSameBearishSBCount = 0; + } + + // + if (isDBullish || + isDBearish) + { + mSameSBCount++; + } + else + { + mSameSBCount = 0; + } + } + else if (isSBSwitchedToBullish) + { + // + mSameSBCount = 0; + mSameBullishSBCount = 0; + } + else if (isSBSwitchedToBearish) + { + // + mSameSBCount = 0; + mSameBearishSBCount = 0; } // @@ -3842,6 +3988,7 @@ void PrepareMarketConditions( HasChild(mBearishSarChanges); if (mHas) { + isBullishSarBreakedLast = sarBuffer[pIndex] > mBearishSarChanges[ArraySize(mBearishSarChanges) - 1].after; } // @@ -3849,6 +3996,64 @@ void PrepareMarketConditions( HasChild(mBullishSarChanges); if (mHas) { + isBearishSarBreakedLast = sarBuffer[pIndex] < mBullishSarChanges[ArraySize(mBullishSarChanges) - 1].after; + } + + // + // Counters ... + + // + if (!isSarSwitchedToBullish && + !isSarSwitchedToBearish) + { + // + bool isDBullish = + isSarBullish && + isSarBullishP; + if (isDBullish) + { + mSameBullishSarCount++; + } + else + { + mSameBullishSarCount = 0; + } + + // + bool isDBearish = + isSarBearish && + isSarBearishP; + if (isDBearish) + { + mSameBearishSarCount++; + } + else + { + mSameBearishSarCount = 0; + } + + // + if (isDBullish || + isDBearish) + { + mSameSarCount++; + } + else + { + mSameSarCount = 0; + } + } + else if (isSarSwitchedToBullish) + { + // + mSameSarCount = 0; + mSameBullishSarCount = 0; + } + else if (isSarSwitchedToBearish) + { + // + mSameSarCount = 0; + mSameBearishSarCount = 0; } // @@ -3921,6 +4126,7 @@ void PrepareMarketConditions( HasChild(mBearishHKSChanges); if (mHas) { + isBullishHKSBreakedLast = mHKSMin > mBearishHKSChanges[ArraySize(mBearishHKSChanges) - 1].after; } // @@ -3928,6 +4134,64 @@ void PrepareMarketConditions( HasChild(mBullishHKSChanges); if (mHas) { + isBearishHKSBreakedLast = mHKSMax < mBullishHKSChanges[ArraySize(mBullishHKSChanges) - 1].after; + } + + // + // Counters ... + + // + if (!isHKSSwitchedToBullish && + !isHKSSwitchedToBearish) + { + // + bool isDBullish = + isHKSBullish && + isHKSBullishP; + if (isDBullish) + { + mSameBullishHKSCount++; + } + else + { + mSameBullishHKSCount = 0; + } + + // + bool isDBearish = + isHKSBearish && + isHKSBearishP; + if (isDBearish) + { + mSameBearishHKSCount++; + } + else + { + mSameBearishHKSCount = 0; + } + + // + if (isDBullish || + isDBearish) + { + mSameHKSCount++; + } + else + { + mSameHKSCount = 0; + } + } + else if (isHKSSwitchedToBullish) + { + // + mSameHKSCount = 0; + mSameBullishHKSCount = 0; + } + else if (isHKSSwitchedToBearish) + { + // + mSameHKSCount = 0; + mSameBearishHKSCount = 0; } // @@ -3996,6 +4260,7 @@ void PrepareMarketConditions( HasChild(mBearishKIChanges); if (mHas) { + isBullishKIBreakedLast = kiBuffer[pIndex] > mBearishKIChanges[ArraySize(mBearishKIChanges) - 1].after; } // @@ -4003,6 +4268,40 @@ void PrepareMarketConditions( HasChild(mBullishKIChanges); if (mHas) { + isBearishKIBreakedLast = kiBuffer[pIndex] < mBullishKIChanges[ArraySize(mBullishKIChanges) - 1].after; + } + + // + // Counters ... + + // + if (isSameKI) + { + mSameKICount++; + } + else + { + mSameKICount = 0; + } + + // + if (isSameBullishKI) + { + mSameBullishKICount++; + } + else + { + mSameBullishKICount = 0; + } + + // + if (isSameBearishKI) + { + mSameBearishKICount++; + } + else + { + mSameBearishKICount = 0; } // @@ -4071,6 +4370,7 @@ void PrepareMarketConditions( HasChild(mBearishTrendChanges); if (mHas) { + isBullishTrendBreakedLast = trendBuffer[pIndex] > mBearishTrendChanges[ArraySize(mBearishTrendChanges) - 1].after; } // @@ -4078,6 +4378,64 @@ void PrepareMarketConditions( HasChild(mBullishTrendChanges); if (mHas) { + isBearishTrendBreakedLast = trendBuffer[pIndex] < mBullishTrendChanges[ArraySize(mBullishTrendChanges) - 1].after; + } + + // + // Counters ... + + // + if (!isTrendSwitchedToBullish && + !isTrendSwitchedToBearish) + { + // + bool isDBullish = + isTrendBullish && + isTrendBullishP; + if (isDBullish) + { + mSameBullishTrendCount++; + } + else + { + mSameBullishTrendCount = 0; + } + + // + bool isDBearish = + isTrendBearish && + isTrendBearishP; + if (isDBearish) + { + mSameBearishTrendCount++; + } + else + { + mSameBearishTrendCount = 0; + } + + // + if (isDBullish || + isDBearish) + { + mSameTrendCount++; + } + else + { + mSameTrendCount = 0; + } + } + else if (isTrendSwitchedToBullish) + { + // + mSameTrendCount = 0; + mSameBullishTrendCount = 0; + } + else if (isTrendSwitchedToBearish) + { + // + mSameTrendCount = 0; + mSameBearishTrendCount = 0; } // @@ -4093,6 +4451,81 @@ void PrepareMarketConditions( mDirShift.Clean(); } +/** + * Detect POI(s) ... + * + * @param barIndex: int, Specified Bar Index ... + * @param prevCalculated: int, Provides Previous Calculated Bars ... + * @param ratesTotal: int, Provides All Availabled Bars ... + * @param open: double Collection, Provides Open Prices Time Series ... + * @param high: double Collection, Provides High Prices Time Series ... + * @param close: double Collection, Provides Close Prices Time Series ... + * @param low: double Collection, Provides Low Prices Time Series ... + * @param tickVolume: long Collection, Provides Ticks Volume Prices Time Series ... + */ +void DetectPOIs( + int barIndex, + const int prevCalculated, + const int ratesTotal, + const double &open[], + const double &high[], + const double &close[], + const double &low[], + const long &tickVolume[] // +) +{ +} + +/** + * Validate Detected POI(s) ... + * + * @param barIndex: int, Specified Bar Index ... + * @param prevCalculated: int, Provides Previous Calculated Bars ... + * @param ratesTotal: int, Provides All Availabled Bars ... + * @param open: double Collection, Provides Open Prices Time Series ... + * @param high: double Collection, Provides High Prices Time Series ... + * @param close: double Collection, Provides Close Prices Time Series ... + * @param low: double Collection, Provides Low Prices Time Series ... + * @param tickVolume: long Collection, Provides Ticks Volume Prices Time Series ... + */ +void ValidatePOIs( + int barIndex, + const int prevCalculated, + const int ratesTotal, + const double &open[], + const double &high[], + const double &close[], + const double &low[], + const long &tickVolume[] // +) +{ +} + +/** + * Draw Detected POI(s) ... + * + * @param barIndex: int, Specified Bar Index ... + * @param prevCalculated: int, Provides Previous Calculated Bars ... + * @param ratesTotal: int, Provides All Availabled Bars ... + * @param open: double Collection, Provides Open Prices Time Series ... + * @param high: double Collection, Provides High Prices Time Series ... + * @param close: double Collection, Provides Close Prices Time Series ... + * @param low: double Collection, Provides Low Prices Time Series ... + * @param tickVolume: long Collection, Provides Ticks Volume Prices Time Series ... + */ +void DrawPOIs( + int barIndex, + const int prevCalculated, + const int ratesTotal, + const double &open[], + const double &high[], + const double &close[], + const double &low[], + const long &tickVolume[] // +) +{ +} + /** * Process Custom Analysing Senarios ... * diff --git a/Libraries/x-saherelm.x-poi.extensions.lib.mq5 b/Libraries/x-saherelm.x-poi.extensions.lib.mq5 index 3e398b96..bb6eadb2 100644 --- a/Libraries/x-saherelm.x-poi.extensions.lib.mq5 +++ b/Libraries/x-saherelm.x-poi.extensions.lib.mq5 @@ -474,108 +474,6 @@ int GetLowest( return result; } -/** - * Validate Boxes ... - * @param box: XBoxZone instance reference for Validate ... - * @param barIndex: int, Bar Index ... - * @param barsLength: int, Bars Length for Validation ... - * - * @return ( bool ) - */ -bool IsBoxValid( - XBoxZone &box, - int barIndex = 0, - int barsLength = 3 // -) -{ - // - bool result = false; - - // - // Normalize Bar Index ... - barIndex = NormalizeInt(barIndex, 0); - barsLength = NormalizeInt(barsLength, 1); - - // - // Ceck Input Box is Valid ... - result = box.IsValid(); - if (!result) - { - return result; - } - - // - // Check Input Box is Breaked or not ... - // Breaktion Found using Counting Over/Under Close Bars ... - bool isBullish = box.IsBullish(); - double appliedPrice = box.GetInDirectionalPrice(); - result = NotEmptyZero(appliedPrice); - if (!result) - { - return result; - } - - // - int toIDX = box.ToIndex(); - - // - XOHCL iBar; - int edgeBreakes = 0; - for (int i = barIndex; i <= toIDX; i++) - { - // - // Initialize Indexed Bar ... - result = iBar.Init( - box.symbol, - box.period, - i // - ); - - // - // Checking Price ... - result = - // - // Checking Bar Validation ... - result && - // - // Checking Price Breaked or not ... - (isBullish - ? iBar.close < box.lower - : iBar.close > box.upper); - if (result) - { - edgeBreakes++; - } - else - { - edgeBreakes = 0; - } - - // - result = edgeBreakes >= barsLength; - if (result) - { - break; - } - - // - iBar.Clean(); - } - - // - iBar.Clean(); - - // - // return true; - - // - result = - edgeBreakes < barsLength; - - // - return result; -} - /** * Find Specified Box Index inside a Collection of Boxes ... * @@ -856,12 +754,14 @@ int Removes( * * @param item: XBoxZone instance Reference, Specified Item to Add ... * @param sources: XBoxZone instance Reference Collection, Source Items Collection ... + * @param maxAllowed: int, Max Allowed Collection Size ... * * @return ( bool ) */ bool AddIfNotExists( XBoxZone &item, - XBoxZone &sources[] // + XBoxZone &sources[], + int maxAllowed = 50 // ) { // @@ -895,12 +795,24 @@ bool AddIfNotExists( sources //; ); + // + if (result && + maxAllowed > 0) + { + // + CleanupArray( + sources, + maxAllowed // + ); + } + // return result; } bool AddIfNotExists( XDirectionShift &item, - XDirectionShift &sources[] // + XDirectionShift &sources[], + int maxAllowed = 50 // ) { // @@ -934,6 +846,17 @@ bool AddIfNotExists( sources //; ); + // + if (result && + maxAllowed > 0) + { + // + CleanupArray( + sources, + maxAllowed // + ); + } + // return result; } @@ -943,12 +866,14 @@ bool AddIfNotExists( * * @param items: XBoxZone instance Reference Collection, Specified Items to Add ... * @param sources: XBoxZone instance Reference Collection, Source Items Collection ... + * @param maxAllowed: int, Max Allowed Collection Size ... * * @return ( int ) */ int AddIfNotExists( XBoxZone &items[], - XBoxZone &sources[] // + XBoxZone &sources[], + int maxAllowed = 50 // ) { // @@ -980,13 +905,23 @@ int AddIfNotExists( // result = after > before; + if (result && + maxAllowed > 0) + { + // + CleanupArray( + sources, + maxAllowed // + ); + } // return result; } int AddIfNotExists( XDirectionShift &items[], - XDirectionShift &sources[] // + XDirectionShift &sources[], + int maxAllowed = 50 // ) { // @@ -1018,6 +953,15 @@ int AddIfNotExists( // result = after > before; + if (result && + maxAllowed > 0) + { + // + CleanupArray( + sources, + maxAllowed // + ); + } // return result; @@ -1027,6 +971,108 @@ int AddIfNotExists( // // +/** + * Validate Boxes ... + * @param box: XBoxZone instance reference for Validate ... + * @param barIndex: int, Bar Index ... + * @param barsLength: int, Bars Length for Validation ... + * + * @return ( bool ) + */ +bool IsBoxValid( + XBoxZone &box, + int barIndex = 0, + int barsLength = 3 // +) +{ + // + bool result = false; + + // + // Normalize Bar Index ... + barIndex = NormalizeInt(barIndex, 0); + barsLength = NormalizeInt(barsLength, 1); + + // + // Ceck Input Box is Valid ... + result = box.IsValid(); + if (!result) + { + return result; + } + + // + // Check Input Box is Breaked or not ... + // Breaktion Found using Counting Over/Under Close Bars ... + bool isBullish = box.IsBullish(); + double appliedPrice = box.GetInDirectionalPrice(); + result = NotEmptyZero(appliedPrice); + if (!result) + { + return result; + } + + // + int toIDX = box.ToIndex(); + + // + XOHCL iBar; + int edgeBreakes = 0; + for (int i = barIndex; i <= toIDX; i++) + { + // + // Initialize Indexed Bar ... + result = iBar.Init( + box.symbol, + box.period, + i // + ); + + // + // Checking Price ... + result = + // + // Checking Bar Validation ... + result && + // + // Checking Price Breaked or not ... + (isBullish + ? iBar.close < box.lower + : iBar.close > box.upper); + if (result) + { + edgeBreakes++; + } + else + { + edgeBreakes = 0; + } + + // + result = edgeBreakes >= barsLength; + if (result) + { + break; + } + + // + iBar.Clean(); + } + + // + iBar.Clean(); + + // + // return true; + + // + result = + edgeBreakes < barsLength; + + // + return result; +} + // void SortBoxes( XBoxZone &items[],