From 80b452fff4dc9e397f071cf2c4ea8e55ac317a3d Mon Sep 17 00:00:00 2001 From: Hadi Khazaee Asl Date: Mon, 16 Jun 2025 01:43:17 +0330 Subject: [PATCH] last ... --- Classes/x-saherelm.x-cobject.class.mq5 | 124 +++--- Classes/x-saherelm.x-poi.drawer.class.mq5 | 13 +- Indicators/x-saherelm.x121.xcatb.v1.mq5 | 504 ++++++++++++++++++---- 3 files changed, 479 insertions(+), 162 deletions(-) diff --git a/Classes/x-saherelm.x-cobject.class.mq5 b/Classes/x-saherelm.x-cobject.class.mq5 index 8d012cfb..b3d418ba 100644 --- a/Classes/x-saherelm.x-cobject.class.mq5 +++ b/Classes/x-saherelm.x-cobject.class.mq5 @@ -48,17 +48,18 @@ enum ENUM_XCHARTOBJECTS enum ENUM_X_CHART_IDS { - X_TO, - X_FROM, - X_UPPER, - X_LOWER, - X_ENTRY, - X_TARGET, - X_SL, - X_TP, - X_BAR_H_SHW, - X_BAR_BDY, - X_BAR_L_SHW, + X_AT, // AT + X_TO, // TO + X_FROM, // FROM + X_UPPER, // UPPER + X_LOWER, // LOWER + X_ENTRY, // ENTRY + X_TARGET, // TARGET + X_SL, // SL + X_TP, // TP + X_BAR_H_SHW, // HSHW + X_BAR_BDY, // BODY + X_BAR_L_SHW, // LSHW }; string ToString(ENUM_X_CHART_IDS value) @@ -67,65 +68,7 @@ string ToString(ENUM_X_CHART_IDS value) string result = NULL; // - switch (value) - { - // - case X_TO: - result = "TO"; - break; - - // - case X_FROM: - result = "FROM"; - break; - - // - case X_UPPER: - result = "UPPER"; - break; - - // - case X_LOWER: - result = "LOWER"; - break; - - // - case X_ENTRY: - result = "ENTRY"; - break; - - // - case X_TARGET: - result = "TARGET"; - break; - - // - case X_SL: - result = "SL"; - break; - - // - case X_TP: - result = "TP"; - break; - - // - case X_BAR_H_SHW: - result = "HSHW"; - break; - - // - case X_BAR_BDY: - result = "BODY"; - break; - - // - case X_BAR_L_SHW: - result = "LSHW"; - break; - - // - } + result = EnumToString(value); // return result; @@ -436,6 +379,8 @@ class XCBaseObject : public CChartObject // }; +// +// Bar Arrow Object ... class XCBarArrowObject : public XCBaseObject { // @@ -990,6 +935,8 @@ class XCRRObject : public XCSignalObject } }; +// +// OHCL, Bar Object ... class XCOHCLObject : public XCBaseObject { // @@ -1304,6 +1251,8 @@ class XCOHCLObject : public XCBaseObject CChartObjectRectangle mLowShadowRect; }; +// +// Box Object ...k class XCBoxObject : public XCBaseObject { // @@ -1328,6 +1277,7 @@ class XCBoxObject : public XCBaseObject double lower, datetime from, datetime to, + datetime at, string prefix = NULL // ) { @@ -1370,6 +1320,34 @@ class XCBoxObject : public XCBaseObject return result; } + // + if (result) + { + // + if (IsValid(at)) + { + // + result = mAt.Create( + chart_id, + name + ToString(X_AT), + window, + at // + ); + } + + // + if (!result) + { + // + mAt.Detach(); + mAt.Delete(); + + // + mRect.Detach(); + mRect.Delete(); + } + } + // if (result) { @@ -1397,6 +1375,7 @@ class XCBoxObject : public XCBaseObject } // + mAt.Width(value); mRect.Width(value); } @@ -1407,6 +1386,8 @@ class XCBoxObject : public XCBaseObject */ void BoxColor(color value) { + // + mAt.Color(value); mRect.Color(value); } @@ -1417,6 +1398,8 @@ class XCBoxObject : public XCBaseObject */ void BoxStyle(ENUM_LINE_STYLE value) { + // + mAt.Style(value); mRect.Style(value); } @@ -1449,6 +1432,7 @@ class XCBoxObject : public XCBaseObject // // Props ... + CChartObjectVLine mAt; CChartObjectRectangle mRect; }; diff --git a/Classes/x-saherelm.x-poi.drawer.class.mq5 b/Classes/x-saherelm.x-poi.drawer.class.mq5 index 20604fa9..86206358 100644 --- a/Classes/x-saherelm.x-poi.drawer.class.mq5 +++ b/Classes/x-saherelm.x-poi.drawer.class.mq5 @@ -602,6 +602,7 @@ class XCPOIDrawer : public XCBase double lower, datetime from, datetime to, + datetime at, color clr = clrYellowGreen, int width = 1, bool fill = false, @@ -658,6 +659,7 @@ class XCPOIDrawer : public XCBase lower, from, to, + at, prefix // ); @@ -690,7 +692,8 @@ class XCPOIDrawer : public XCBase */ bool DrawBox( XBoxZone &box, - XCBoxObject *&object // + XCBoxObject *&object, + bool ignoreAt = true // ) { // @@ -706,6 +709,12 @@ class XCPOIDrawer : public XCBase return result; } + // + if (ignoreAt) + { + box.at = NULL; + } + // int width = 1; bool fill = false; @@ -724,6 +733,7 @@ class XCPOIDrawer : public XCBase box.lower, box.from, box.to, + box.at, clr, width, fill, @@ -800,6 +810,7 @@ class XCPOIDrawer : public XCBase box.lower, box.from, box.to, + box.at, clr, width, fill, diff --git a/Indicators/x-saherelm.x121.xcatb.v1.mq5 b/Indicators/x-saherelm.x121.xcatb.v1.mq5 index f21e6145..96bfe98a 100644 --- a/Indicators/x-saherelm.x121.xcatb.v1.mq5 +++ b/Indicators/x-saherelm.x121.xcatb.v1.mq5 @@ -642,10 +642,22 @@ XCPOIDrawer *mDrawer; XCBarAnalyser *mBarAnalyser; // -XBoxZone mBullishBreakes[]; -XBoxZone mBearishBreakes[]; +int mSamePeakCount = 0; +int mSameValeCount = 0; + +// +double mSamePeakGolden = 0; +double mSameValeGolden = 0; + +// +bool mDetectLiquidities = false; +bool mDetectRangeBreakes = true; + +// XBoxZone mBullishLiquidities[]; XBoxZone mBearishLiquidities[]; +XBoxZone mBullishRangeBreakes[]; +XBoxZone mBearishRangeBreakes[]; // // Event Handlers ... @@ -910,6 +922,14 @@ int OnCalculate( return prev_calculated; } + // + if (prev_calculated == 0) + { + // + string message = "History Started ..."; + Print(message); + } + // // Main Loop ... for (int i = limit - 1; i >= 0 && !IsStopped(); i--) @@ -3218,6 +3238,11 @@ void DoProcess( isBearishTriggerBar // ; + + // + isTriggerBar = false; + isBullishTriggerBar = false; + isBearishTriggerBar = false; } // @@ -3408,6 +3433,14 @@ void DetectPOIs( ? barIndex == startCalculationForLastBars : barIndex == firstBarIndex; + // + // Handle Minimum Required Bars ... + bool isPassedRequiredBars = barIndex < maxBarIndex - 3; + if (!isPassedRequiredBars) + { + return; + } + // // Recieve Bar ... XOHCL iBar; @@ -3427,124 +3460,317 @@ void DetectPOIs( } // + bool isBullish = false; + bool isBearish = false; int maxAllowedPOIs = 50; // ENUM_X_DIRECTION iDir; - + // // Detecting Liquidity ... - bool isLiquidity = - mBarAnalyser - .IsRejected( - iBar, - iDir, - true, - true // - ); - bool isBullishLiquiditySweeped = - isLiquidity && - IsBullish(iDir); - bool isBearishLiquiditySweeped = - isLiquidity && - IsBearish(iDir); - if (isLiquidity) + if (mDetectLiquidities) { // - XBoxZone iLiq; - - // - iLiq.dir = iDir; - iLiq.type = "XLIQ"; - iLiq.upper = - isBullishLiquiditySweeped - ? iBar.GetDown() - : iBar.high; - iLiq.lower = - isBullishLiquiditySweeped - ? iBar.low - : iBar.GetUp(); - iLiq.from = iBar.time; - iLiq.symbol = _Symbol; - iLiq.period = _Period; - iLiq.to = ((datetime)((int)iBar.time + (PeriodSeconds(_Period)))); - - // - if (iLiq.IsValid()) + bool isLiquidity = + mBarAnalyser + .IsRejected( + iBar, + iDir, + true, + true // + ); + bool isBullishLiquiditySweeped = + isLiquidity && + IsBullish(iDir); + bool isBearishLiquiditySweeped = + isLiquidity && + IsBearish(iDir); + if (isLiquidity) { // - if (isBullishLiquiditySweeped) - { - // - has = AddBoxIfNotExists( - iLiq, - mBullishLiquidities // - ); - if (has) - { - // - SortBoxes( - mBullishLiquidities, - maxAllowedPOIs // - ); - } - } - else - { - // - has = AddBoxIfNotExists( - iLiq, - mBearishLiquidities // - ); - if (has) - { - // - SortBoxes( - mBearishLiquidities, - maxAllowedPOIs // - ); - } - } - } + XBoxZone iLiq; - // - iLiq.Clean(); + // + iLiq.dir = iDir; + iLiq.type = "XLIQ"; + iLiq.upper = + isBullishLiquiditySweeped + ? iBar.GetDown() + : iBar.high; + iLiq.lower = + isBullishLiquiditySweeped + ? iBar.low + : iBar.GetUp(); + iLiq.at = iBar.time; + iLiq.from = iBar.time; + iLiq.symbol = _Symbol; + iLiq.period = _Period; + iLiq.to = ((datetime)((int)iBar.time + (PeriodSeconds(_Period)))); + + // + if (iLiq.IsValid()) + { + // + if (isBullishLiquiditySweeped) + { + // + has = AddBoxIfNotExists( + iLiq, + mBullishLiquidities // + ); + if (has) + { + // + SortBoxes( + mBullishLiquidities, + maxAllowedPOIs // + ); + } + } + else + { + // + has = AddBoxIfNotExists( + iLiq, + mBearishLiquidities // + ); + if (has) + { + // + SortBoxes( + mBearishLiquidities, + maxAllowedPOIs // + ); + } + } + } + + // + iLiq.Clean(); + } } // // Detecting Bullish and Bearish Breakes ... - - // - bool isPeakSame = false; - bool isPPeakSame = false; // - bool isPeakOverLast = false; - bool isPPeakOverLast = false; + bool isPeakSame = peakBuffer[barIndex] == peakBuffer[barIndex + 1]; + bool isPPeakSame = peakBuffer[barIndex + 1] == peakBuffer[barIndex + 2]; // - bool isPeakUnderLast = false; - bool isPPeakUnderLast = false; + bool isPeakOverLast = peakBuffer[barIndex] > peakBuffer[barIndex + 1]; + bool isPPeakOverLast = peakBuffer[barIndex + 1] > peakBuffer[barIndex + 2]; // - bool isSamePeakOverLast = false; - bool isSamePeakUnderLast = false; + bool isPeakUnderLast = peakBuffer[barIndex] < peakBuffer[barIndex + 1]; + bool isPPeakUnderLast = peakBuffer[barIndex + 1] < peakBuffer[barIndex + 2]; // - bool isValeSame = false; - bool isPValeSame = false; + bool isSamePeakOverLast = + isPPeakSame && + isPeakOverLast; + bool isSamePeakUnderLast = + isPPeakSame && + isPeakUnderLast; // - bool isValeOverLast = false; - bool isPValeOverLast = false; + bool isValeSame = valeBuffer[barIndex] == valeBuffer[barIndex + 1]; + bool isPValeSame = valeBuffer[barIndex + 1] == valeBuffer[barIndex + 2]; // - bool isValeUnderLast = false; - bool isPValeUnderLast = false; + bool isValeOverLast = valeBuffer[barIndex] > valeBuffer[barIndex + 1]; + bool isPValeOverLast = valeBuffer[barIndex + 1] > valeBuffer[barIndex + 2]; // - bool isSameValeOverLast = false; - bool isSameValeUnderLast = false; + bool isValeUnderLast = valeBuffer[barIndex] < valeBuffer[barIndex + 1]; + bool isPValeUnderLast = valeBuffer[barIndex + 1] < valeBuffer[barIndex + 2]; + + // + bool isSameValeOverLast = + isPValeSame && + isValeOverLast; + bool isSameValeUnderLast = + isPValeSame && + isValeUnderLast; + + // + // Detecting Range Breakes ... + if (mDetectRangeBreakes) + { + // + isBullish = isSamePeakOverLast + // || isSameValeOverLast + ; + isBearish = + isSameValeUnderLast + // || isSamePeakUnderLast + ; + + // + bool basedOnPeak = + isSamePeakOverLast + // || isSamePeakUnderLast + ; + + // + bool basedOnVale = + isSameValeUnderLast + // isSameValeOverLast || + ; + + // + has = isBullish || + isBearish; + + // + if (has) + { + // + XBoxZone iRNGBreak; + + // + iDir = + isBullish + ? X_DIRECTION_BULLISH + : isBearish + ? X_DIRECTION_BEARISH + : X_DIRECTION_NONE; + + // + iRNGBreak.dir = iDir; + iRNGBreak.at = iBar.time; + iRNGBreak.type = "XRNGB"; + iRNGBreak.to = iBar.time; + iRNGBreak.symbol = _Symbol; + iRNGBreak.period = _Period; + + // + int fromIDX = + iBar.Index() + + (basedOnPeak + ? mSamePeakCount + : basedOnVale + ? mSameValeCount + : 0); + datetime from = GetBarTime( + _Symbol, + _Period, + fromIDX // + ); + iRNGBreak.from = from; + + // + double upper = + isBullish + ? basedOnPeak + ? peakBuffer[barIndex] + : basedOnVale + ? mSameValeGolden + : 0 + : isBearish + ? basedOnPeak + ? peakBuffer[barIndex] + : basedOnVale + ? mSameValeGolden + : 0 + : 0; + + // + double lower = + isBullish + ? basedOnPeak + ? mSamePeakGolden + : basedOnVale + ? valeBuffer[barIndex] + : 0 + : isBearish + ? basedOnPeak + ? mSamePeakGolden + : basedOnVale + ? valeBuffer[barIndex] + : 0 + : 0; + + // + iRNGBreak.upper = upper; + iRNGBreak.lower = lower; + + // + // Adding POI ... + has = iRNGBreak.IsValid(); + if (has) + { + // + if (isBullish) + { + // + has = AddBoxIfNotExists( + iRNGBreak, + mBullishRangeBreakes // + ); + if (has) + { + // + SortBoxes( + mBullishRangeBreakes, + maxAllowedPOIs // + ); + } + } + else if (isBearish) + { + // + has = AddBoxIfNotExists( + iRNGBreak, + mBearishRangeBreakes // + ); + if (has) + { + // + SortBoxes( + mBearishRangeBreakes, + maxAllowedPOIs // + ); + } + } + } + } + } + + // + if (isPeakSame) + { + // + mSamePeakGolden = + mSamePeakGolden == 0 + ? iBar.GetUp() + : MathMax(mSamePeakGolden, iBar.GetUp()); + mSamePeakCount++; + } + else + { + // + mSamePeakCount = 0; + mSamePeakGolden = 0; + } + + // + if (isValeSame) + { + // + mSameValeGolden = + mSameValeGolden == 0 + ? iBar.GetDown() + : MathMin(mSameValeGolden, iBar.GetDown()); + mSameValeCount++; + } + else + { + // + mSameValeCount = 0; + mSameValeGolden = 0; + } // // Cleanup Resources ... @@ -3606,6 +3832,39 @@ void ValidatePOIs( barsLength // ); } + + // + // Range Breaks ... + + // + // Bullish ... + count = ArraySize(mBullishRangeBreakes); + has = IsValidSize(count); + if (has) + { + // + ValidateBoxes( + mBullishRangeBreakes, + barIndex, + barsLength // + ); + } + + // + // Bearish ... + count = ArraySize(mBearishRangeBreakes); + has = IsValidSize(count); + if (has) + { + // + ValidateBoxes( + mBearishRangeBreakes, + barIndex, + barsLength // + ); + } + + // } // @@ -3688,6 +3947,69 @@ void DrawPOIs( iBox.Clean(); } } + + // + // Range Breaks ... + + // + // Bullish ... + count = ArraySize(mBullishRangeBreakes); + has = IsValidSize(count); + if (has) + { + // + for (int i = 0; i < count; i++) + { + // + iBox = mBullishRangeBreakes[i]; + iBox.to = to; + + // + XCBoxObject *iObj; + has = mDrawer.DrawBox( + iBox, + iObj // + ); + if (has) + { + mObjects.Add(iObj); + } + + // + iBox.Clean(); + } + } + + // + // Bearish ... + count = ArraySize(mBearishRangeBreakes); + has = IsValidSize(count); + if (has) + { + // + for (int i = 0; i < count; i++) + { + // + iBox = mBearishRangeBreakes[i]; + iBox.to = to; + + // + XCBoxObject *iObj; + has = mDrawer.DrawBox( + iBox, + iObj // + ); + if (has) + { + mObjects.Add(iObj); + } + + // + iBox.Clean(); + } + } + + // } // \ No newline at end of file