From 3812246e5c4bbf0a1dee35a10fc19e2a5ba38a41 Mon Sep 17 00:00:00 2001 From: Hadi Khazaee Asl Date: Tue, 23 Sep 2025 16:36:53 +0330 Subject: [PATCH] last works on Detecting Pivots ... - Pivots Detection works Fine; - Analyse Pivots Has some issues and i have to Fix them ... --- Classes/x-saherelm.x-cobject.class.mq5 | 246 +++- Classes/x-saherelm.x-poi.drawer.class.mq5 | 105 +- Experts/x-saherelm.xfima.backtester.ea.mq5 | 297 ++++- Helpers/x-saherelm.xfima.helper.mq5 | 1027 ++++++++++++++++- .../x-saherelm.common.extensions.lib.mq5 | 3 +- Libraries/x-saherelm.x-pivot.analysis.lib.mq5 | 4 +- Libraries/x-saherelm.x-poi.lib.mq5 | 95 -- .../x-saherelm.xfima.signaller.class.mq5 | 18 +- .../x-saherelm.xfima.x-poi.detector.class.mq5 | 282 ++++- 9 files changed, 1934 insertions(+), 143 deletions(-) diff --git a/Classes/x-saherelm.x-cobject.class.mq5 b/Classes/x-saherelm.x-cobject.class.mq5 index 2ac7d50d..0a1d1e87 100644 --- a/Classes/x-saherelm.x-cobject.class.mq5 +++ b/Classes/x-saherelm.x-cobject.class.mq5 @@ -1458,13 +1458,21 @@ class XCPivotAnalysisObject : public XCBaseObject * @param chart_id: Long, Specified Chart ID ... * @param window: Integer, Specified Chart Window ID ... * @param model: XPivotAnalysis, reference model ... + * @param drawPivots: Specified to Draw Pivots or not ... + * @param peakArrow: int, Specified Arrow Code for Peak Pivots ... + * @param valeArrow: int, Specified Arrow Code for Vale Pivots ... + * @param threshold: int, distance between price and arrow in Point ... * * @return ( bool ) */ bool Create( long chart_id, int window, - XPivotAnalysis &model // + XPivotAnalysis &model, + bool drawPivots = true, + int peakArrow = 159, + int valeArrow = 159, + int threshold = 5 // ) { // @@ -1562,6 +1570,70 @@ class XCPivotAnalysisObject : public XCBaseObject ); } + // + // Draw Pivots ... + if (drawPivots && + model.HasPivots()) + { + // + XOHCL iBar; + int arrow = 0; + bool has = false; + string name = NULL; + XCBarArrowObject *iObj; + ENUM_X_PRICE type = X_PRICE_NONE; + int pivotsCount = ArraySize(model.pivots); + for (int i = 0; i < pivotsCount; i++) + { + // + has = model.pivots[i].GetBar(iBar); + if (!has) + { + continue; + } + + // + arrow = model.pivots[i].IsPeak() + ? peakArrow + : valeArrow; + name = model.pivots[i].GetObjectID(); + type = model.pivots[i].IsPeak() + ? X_PRICE_HIGH + : X_PRICE_LOW; + iObj = new XCBarArrowObject(); + has = iObj.CreateByBar( + chart_id, + name, + window, + arrow, + iBar, + type, + threshold // + ); + if (has) + { + // + if (model.pivots[i].IsPeak()) + { + mPeaks.Add(iObj); + } + else + { + mVales.Add(iObj); + } + } + + // + iBar.Clean(); + ZeroMemory(iObj); + } + + // + // Cleanup Resources ... + iBar.Clean(); + ZeroMemory(iObj); + } + // // Setting Object Name ... if (result) @@ -1821,9 +1893,181 @@ class XCPivotAnalysisObject : public XCBaseObject mResistanceBox.Style(value); } + /** + * Set Width ... + * + * @param value: Integer ... + */ + void PeaksWidth(int value) + { + // + // Normalize ... + value = NormalizeInt(value, 1); + + // + // Validate ... + int count = mPeaks.Total(); + bool has = IsValidSize(count); + if (!has) + { + return; + } + + // + XCBarArrowObject *iPeak; + for (int i = 0; i < count; i++) + { + // + iPeak = (XCBarArrowObject *)mPeaks.At(i); + iPeak.ArrowWidth(value); + ZeroMemory(iPeak); + } + } + + /** + * Set Color ... + * + * @param value: Color ... + */ + void PeaksColor(color value) + { + // + // Validate ... + int count = mPeaks.Total(); + bool has = IsValidSize(count); + if (!has) + { + return; + } + + // + XCBarArrowObject *iPeak; + for (int i = 0; i < count; i++) + { + // + iPeak = (XCBarArrowObject *)mPeaks.At(i); + iPeak.ArrowColor(value); + ZeroMemory(iPeak); + } + } + + /** + * Set Arrow Anchor ... + * + * @param value: ENUM_ARROW_ANCHOR member ... + */ + void PeaksAnchor(ENUM_ARROW_ANCHOR value) + { + // + // Validate ... + int count = mPeaks.Total(); + bool has = IsValidSize(count); + if (!has) + { + return; + } + + // + XCBarArrowObject *iPeak; + for (int i = 0; i < count; i++) + { + // + iPeak = (XCBarArrowObject *)mPeaks.At(i); + iPeak.ArrowAnchor(value); + ZeroMemory(iPeak); + } + } + + /** + * Set Width ... + * + * @param value: Integer ... + */ + void ValesWidth(int value) + { + // + // Normalize ... + value = NormalizeInt(value, 1); + + // + // Validate ... + int count = mVales.Total(); + bool has = IsValidSize(count); + if (!has) + { + return; + } + + // + XCBarArrowObject *iVale; + for (int i = 0; i < count; i++) + { + // + iVale = (XCBarArrowObject *)mVales.At(i); + iVale.ArrowWidth(value); + ZeroMemory(iVale); + } + } + + /** + * Set Color ... + * + * @param value: Color ... + */ + void ValesColor(color value) + { + // + // Validate ... + int count = mVales.Total(); + bool has = IsValidSize(count); + if (!has) + { + return; + } + + // + XCBarArrowObject *iVale; + for (int i = 0; i < count; i++) + { + // + iVale = (XCBarArrowObject *)mVales.At(i); + iVale.ArrowColor(value); + ZeroMemory(iVale); + } + } + + /** + * Set Arrow Anchor ... + * + * @param value: ENUM_ARROW_ANCHOR member ... + */ + void ValesAnchor(ENUM_ARROW_ANCHOR value) + { + // + // Validate ... + int count = mVales.Total(); + bool has = IsValidSize(count); + if (!has) + { + return; + } + + // + XCBarArrowObject *iVale; + for (int i = 0; i < count; i++) + { + // + iVale = (XCBarArrowObject *)mVales.At(i); + iVale.ArrowAnchor(value); + ZeroMemory(iVale); + } + } + // private: // + CArrayObj mPeaks; + CArrayObj mVales; CChartObjectTrend mUpper; CChartObjectTrend mLower; XCBoxObject *mSupportBox; diff --git a/Classes/x-saherelm.x-poi.drawer.class.mq5 b/Classes/x-saherelm.x-poi.drawer.class.mq5 index 5e59d887..b290bbd0 100644 --- a/Classes/x-saherelm.x-poi.drawer.class.mq5 +++ b/Classes/x-saherelm.x-poi.drawer.class.mq5 @@ -262,7 +262,7 @@ class XCPOIDrawer : public XCBase // return result; } - + /** * Draw Bar Arrow Object ... * @@ -397,8 +397,8 @@ class XCPOIDrawer : public XCBase ? X_PRICE_HIGH : X_PRICE_LOW; XPOIStyle style = pivot.IsPeak() - ? defaultBullishStyle - : defaultBearishStyle; + ? defaultBearishStyle + : defaultBullishStyle; ENUM_ARROW_ANCHOR anchor = pivot.IsPeak() ? ANCHOR_BOTTOM : ANCHOR_TOP; @@ -431,6 +431,72 @@ class XCPOIDrawer : public XCBase return result; } + /** + * Draw Specified Pivot Collection ... + * + * @param pivots: XPivot, reference Collection to Draw ... + * @param draws: CArrayObj, pointer reference to Hold Drawn Objects ... + * @param peakArrow: int, Specified Arrow Code for Peak Pivots ... + * @param valeArrow: int, Specified Arrow Code for Vale Pivots ... + * @param threshold: int, distance between price and arrow in Point ... + * + * @return ( int ) + */ + int DrawPivots( + XPivot &pivots[], + CArrayObj *&draws, + int peakArrow = 159, + int valeArrow = 159, + int threshold = 5 // + ) + { + // + int result = 0; + + // + // Prepare ... + draws.Clear(); + + // + // Validate ... + if (!HasChild(pivots)) + { + return result; + } + + // + bool has = false; + XCBarArrowObject *iObj; + int count = ArraySize(pivots); + for (int i = 0; i < count; i++) + { + // + // Draw Indexed Pivot ... + has = DrawPivot( + pivots[i], + iObj, + peakArrow, + valeArrow, + threshold // + ); + + // + if (has) + { + draws.Add(iObj); + } + + // + ZeroMemory(iObj); + } + + // + result = draws.Total(); + + // + return result; + } + /** * Draw Specified Box ... * @@ -811,12 +877,21 @@ class XCPOIDrawer : public XCBase * Draw Pivot Analysis ... * * @param analysis: XPivotAnalysis, referece Specified Pivot Analysis ... + * @param object: XCPivotAnalysisObject, pointer reference for Drawn Object ... + * @param drawPivots: Specified to Draw Pivots or not ... + * @param peakArrow: int, Specified Arrow Code for Peak Pivots ... + * @param valeArrow: int, Specified Arrow Code for Vale Pivots ... + * @param threshold: int, distance between price and arrow in Point ... * * @return ( bool ) */ - bool DrawXPivotAnalysis( + bool DrawPivotAnalysis( XPivotAnalysis &analysis, - XCPivotAnalysisObject *&object // + XCPivotAnalysisObject *&object, + bool drawPivots = true, + int peakArrow = 159, + int valeArrow = 159, + int threshold = 5 // ) { // @@ -843,7 +918,11 @@ class XCPOIDrawer : public XCBase result = object.Create( ChartIdentification(), SubWindowIdentification(), - analysis // + analysis, + drawPivots, + peakArrow, + valeArrow, + threshold // ); if (result) { @@ -1263,6 +1342,20 @@ class XCPOIDrawer : public XCBase object.LowerRayRight(true); } + // + // Peak Pivots ... + style = defaultBearishStyle; + object.PeaksColor(style.clr); + object.PeaksWidth(style.width); + object.PeaksAnchor(ANCHOR_BOTTOM); + + // + // Vale Pivots ... + style = defaultBullishStyle; + object.ValesColor(style.clr); + object.ValesWidth(style.width); + object.ValesAnchor(ANCHOR_TOP); + // style.Clean(); } diff --git a/Experts/x-saherelm.xfima.backtester.ea.mq5 b/Experts/x-saherelm.xfima.backtester.ea.mq5 index 2012001a..2ef22f26 100644 --- a/Experts/x-saherelm.xfima.backtester.ea.mq5 +++ b/Experts/x-saherelm.xfima.backtester.ea.mq5 @@ -147,8 +147,8 @@ XCXFIMAStrategy1Signaller *fima1Signaller; // XFIMA1 Signaller ... XCXFIMAStrategy2Signaller *fima2Signaller; // XFIMA2 Signaller ... // -// Drawer and Draws ... -CArrayObj draws; // Drawn Objects ... +// Drawer and eaDraws ... +CArrayObj eaDraws; // Drawn Objects ... // XBarTracker eaBarTracker; // EA Bar Traker ... @@ -258,6 +258,7 @@ int OnInit() // This is Default Configuration ... fimaInputs.Default(); fimaInputs.Hide(); + fimaInputs.showPV = true; fimaInputs.showZigZag = true; // @@ -612,9 +613,9 @@ void OnSignalTriggered(XSignal &signal) // bool has = iObj.Create( - fima2Signaller.fimaPOIDrawer.ChartIdentification(), + fima2Signaller.poiDrawer.ChartIdentification(), iName, - fima2Signaller.fimaPOIDrawer.SubWindowIdentification(), + fima2Signaller.poiDrawer.SubWindowIdentification(), signal.time // ); if (has) @@ -624,7 +625,7 @@ void OnSignalTriggered(XSignal &signal) iObj.Color(iColor); // - draws.Add(iObj); + eaDraws.Add(iObj); } // @@ -815,13 +816,23 @@ void DetectPatterns() // // XFIMA Patetrns ... bool detectFIMAPatterns = true; + // + bool detectFIMAPVPatterns = false; + bool detectFIMAMAPatterns = false; + bool detectFIMASARPatterns = false; + bool detectFIMAZigZagPatterns = false; + // + bool analyseFIMAPVPivots = true; + bool analyseFIMAMAPivots = true; + bool analyseFIMASARPivots = true; + bool analyseFIMAZigZagPivots = true; // // Checking Momentum Bar ... if (detectMomentum) { // - bool isMomentum = fima2Signaller.fimaPOIDetector.IsMomentumBar( + bool isMomentum = fima2Signaller.poiDetector.IsMomentumBar( cBar, iDir // ); @@ -840,7 +851,7 @@ void DetectPatterns() if (detectEngulfed) { // - bool isEngulfed = fima2Signaller.fimaPOIDetector.IsEngulfedBar( + bool isEngulfed = fima2Signaller.poiDetector.IsEngulfedBar( cBar, iDir // ); @@ -859,7 +870,7 @@ void DetectPatterns() if (detectTrueGaped) { // - bool isTrueGaped = fima2Signaller.fimaPOIDetector.IsTrueGapedBar( + bool isTrueGaped = fima2Signaller.poiDetector.IsTrueGapedBar( cBar, iDir // ); @@ -877,7 +888,7 @@ void DetectPatterns() // Checking Pinned Bar ... if (detectPinned) { - bool isPinned = fima2Signaller.fimaPOIDetector.IsPinnedBar( + bool isPinned = fima2Signaller.poiDetector.IsPinnedBar( cBar, iDir // ); @@ -895,7 +906,7 @@ void DetectPatterns() // Checking Star Pattern ... if (detectStarPattern) { - bool isStarPattern = fima2Signaller.fimaPOIDetector.IsStartPattern( + bool isStarPattern = fima2Signaller.poiDetector.IsStartPattern( cBar, iDir // ); @@ -914,7 +925,7 @@ void DetectPatterns() if (detectPiercingPattern) { // - bool isPiercingPattern = fima2Signaller.fimaPOIDetector.IsPiercingPattern( + bool isPiercingPattern = fima2Signaller.poiDetector.IsPiercingPattern( cBar, iDir // ); @@ -933,7 +944,7 @@ void DetectPatterns() if (detectRisingPattern) { // - bool isRisingPattern = fima2Signaller.fimaPOIDetector.IsRisingPattern( + bool isRisingPattern = fima2Signaller.poiDetector.IsRisingPattern( cBar, iDir // ); @@ -953,7 +964,7 @@ void DetectPatterns() { // XOHCL swingBar; - bool isFlagPattern = fima2Signaller.fimaPOIDetector.IsFlagPattern( + bool isFlagPattern = fima2Signaller.poiDetector.IsFlagPattern( cBar, iDir, swingBar // @@ -974,7 +985,7 @@ void DetectPatterns() if (detectSignalKeyBarPattern) { // - bool isSignalKeyBar = fima2Signaller.fimaPOIDetector.IsSignalKeyBarPattern( + bool isSignalKeyBar = fima2Signaller.poiDetector.IsSignalKeyBarPattern( cBar, iDir // ); @@ -994,7 +1005,7 @@ void DetectPatterns() { // XOHCL swings[]; - bool hasSwingTrend = fima2Signaller.fimaPOIDetector.HasSwingTrend( + bool hasSwingTrend = fima2Signaller.poiDetector.HasSwingTrend( cBar, iDir, swings // @@ -1010,7 +1021,7 @@ void DetectPatterns() // CChartObjectTrend *iObj; - has = fima2Signaller.fimaPOIDrawer.DrawSwingTrend( + has = fima2Signaller.poiDrawer.DrawSwingTrend( swings, iDir, iObj, @@ -1018,7 +1029,7 @@ void DetectPatterns() ); if (has) { - draws.Add(iObj); + eaDraws.Add(iObj); } } SpecifiedClean(swings); @@ -1030,7 +1041,7 @@ void DetectPatterns() { // XOHCL swings[]; - bool hasSwingTrend = fima2Signaller.fimaPOIDetector.HasSwingTrend( + bool hasSwingTrend = fima2Signaller.poiDetector.HasSwingTrend( cBar, iDir, swings // @@ -1067,7 +1078,7 @@ void DetectPatterns() { // XOHCL support; - bool hasSupport = fima2Signaller.fimaPOIDetector.HasSupport( + bool hasSupport = fima2Signaller.poiDetector.HasSupport( cBar, support // ); @@ -1081,13 +1092,13 @@ void DetectPatterns() // // Draw Box ... XCBoxObject *iObj; - has = fima2Signaller.fimaPOIDrawer.DrawBox( + has = fima2Signaller.poiDrawer.DrawBox( supportBox, iObj // ); if (has) { - draws.Add(iObj); + eaDraws.Add(iObj); } // @@ -1106,7 +1117,7 @@ void DetectPatterns() { // XOHCL resistance; - bool hasResistance = fima2Signaller.fimaPOIDetector.HasResistance( + bool hasResistance = fima2Signaller.poiDetector.HasResistance( cBar, resistance // ); @@ -1120,13 +1131,13 @@ void DetectPatterns() // // Draw Box ... XCBoxObject *iObj; - has = fima2Signaller.fimaPOIDrawer.DrawBox( + has = fima2Signaller.poiDrawer.DrawBox( resistanceBox, iObj // ); if (has) { - draws.Add(iObj); + eaDraws.Add(iObj); } // @@ -1143,6 +1154,244 @@ void DetectPatterns() // Detecting FIMA Patterns ... if (detectFIMAPatterns) { + // + // Check For PV Pivots ... + if (detectFIMAPVPatterns) + { + // + XPivot pivots[]; + int pivotsCount = fima2Signaller.poiDetector.ExtractPVPivots( + pivots, // Result ... + cBar.Index(), // Bar Index ... + 50, // Required Number of Pivots ... + 1500, // Max Allowed Loopback ... + 10 // Validation Length ... + ); + has = IsValidSize(pivotsCount); + if (has) + { + // + CArrayObj *drawnPivots = new CArrayObj(); + int drawnPivotsCount = fima2Signaller.poiDrawer.DrawPivots( + pivots, + drawnPivots // + ); + has = IsValidSize(drawnPivotsCount); + if (has) + { + // + AddObjects( + drawnPivots, + eaDraws // + ); + + // + Print("Pivots Extracted ..."); + } + + // + ZeroMemory(drawnPivots); + } + } + + // + // Check for MA Patterns ... + if (detectFIMAMAPatterns) + { + // + XPivot pivots[]; + int pivotsCount = fima2Signaller.poiDetector.ExtractMAPivots( + pivots, // Result ... + cBar.Index(), // Bar Index ... + 50, // Required Number of Pivots ... + 1500, // Max Allowed Loopback ... + 0 // Validation Length ... + ); + has = IsValidSize(pivotsCount); + if (has) + { + // + CArrayObj *drawnPivots = new CArrayObj(); + int drawnPivotsCount = fima2Signaller.poiDrawer.DrawPivots( + pivots, + drawnPivots // + ); + has = IsValidSize(drawnPivotsCount); + if (has) + { + // + AddObjects( + drawnPivots, + eaDraws // + ); + + // + Print("Pivots Extracted ..."); + } + + // + ZeroMemory(drawnPivots); + } + } + + // + // Check for SAR Pivots ... + if (detectFIMASARPatterns) + { + // + XPivot pivots[]; + int pivotsCount = fima2Signaller.poiDetector.ExtractSARPivots( + pivots, // Result ... + cBar.Index(), // Bar Index ... + 50, // Required Number of Pivots ... + 1500 // Max Allowed Loopback ... + ); + has = IsValidSize(pivotsCount); + if (has) + { + // + CArrayObj *drawnPivots = new CArrayObj(); + int drawnPivotsCount = fima2Signaller.poiDrawer.DrawPivots( + pivots, + drawnPivots // + ); + has = IsValidSize(drawnPivotsCount); + if (has) + { + // + AddObjects( + drawnPivots, + eaDraws // + ); + + // + Print("Pivots Extracted ..."); + } + + // + ZeroMemory(drawnPivots); + } + } + + // + // Check for ZigZag Pivots ... + if (detectFIMAZigZagPatterns) + { + // + XPivot pivots[]; + int pivotsCount = fima2Signaller.poiDetector.ExtractZigZagPivots( + pivots, + 0, + 50, + 1500 // + ); + has = IsValidSize(pivotsCount); + if (has) + { + // + CArrayObj *drawnPivots = new CArrayObj(); + int drawnPivotsCount = fima2Signaller.poiDrawer.DrawPivots( + pivots, + drawnPivots // + ); + has = IsValidSize(drawnPivotsCount); + if (has) + { + // + AddObjects( + drawnPivots, + eaDraws // + ); + + // + Print("Pivots Extracted ..."); + } + + // + ZeroMemory(drawnPivots); + } + } + + // + // Analysers ... + + // + // Analyse Based on PV ... + if (analyseFIMAPVPivots && false) + { + // + XPivotAnalysis analysis; + has = fima2Signaller.poiDetector.AnalysePVPivots( + analysis, // Result ... + cBar.Index(), // Bar Index ... + 50, // Required Number of Pivots ... + 1500, // Max Allowed Loopback ... + 10 // Validation Length ... + ); + if (has) + { + // + // Draw Analysis ... + XCPivotAnalysisObject *iObj; + has = fima2Signaller.poiDrawer.DrawPivotAnalysis( + analysis, + iObj // + ); + if (has) + { + // + eaDraws.Add(iObj); + + // + Print("FIMA PV Pivots Analysed ..."); + } + } + } + + // + // Analyse Based on MA ... + if (analyseFIMAMAPivots) + { + } + + // + // Analyse Based on SAR ... + if (analyseFIMASARPivots) + { + } + + // + // Analyse Based on ZigZag ... + if (analyseFIMAZigZagPivots) + { + // + XPivotAnalysis analysis; + has = fima2Signaller.poiDetector.AnalyseZigZagPivots( + analysis, // Result ... + cBar.Index(), // Bar Index ... + 50, // Required Number of Pivots ... + 1500 // Max Allowed Loopback ... + ); + if (has) + { + // + // Draw Analysis ... + XCPivotAnalysisObject *iObj; + has = fima2Signaller.poiDrawer.DrawPivotAnalysis( + analysis, + iObj, + true // Draw Pivots ... + ); + if (has) + { + // + eaDraws.Add(iObj); + + // + Print("FIMA ZigZag Pivots Analysed ..."); + } + } + } } // diff --git a/Helpers/x-saherelm.xfima.helper.mq5 b/Helpers/x-saherelm.xfima.helper.mq5 index 260ebc78..50255726 100644 --- a/Helpers/x-saherelm.xfima.helper.mq5 +++ b/Helpers/x-saherelm.xfima.helper.mq5 @@ -23,6 +23,8 @@ // // Imports ... #include "../Classes/x-saherelm.x-helper.class.mq5" +#include "../Libraries/x-saherelm.x-poi.extensions.lib.mq5" +#include "../Libraries/x-saherelm.x-poi.lib.mq5" // // Definitions ... @@ -868,6 +870,1029 @@ class XCXFIMAHelper : public XCBaseHelper return result; } + // + // Pivot Actions ... + + /** + * Extract Specified Kind of Pivots ... + * + * @param pivots: XPivot, refrence Collection to hold Extracted pivots ... + * @param barIndex: int, Specified Bar Index ... + * @param requiredNumberOFPivots: int, Specified which Number of Pivots must be Extracted ... + * @param maxAllowedLoopbackLength: int, Specified Maximum Loopback Length for Pivot Extraction ... + * @param validationLength: int, Specified Pivots Validation Length ignore if <= 0 ... + * + * @return ( int ) + */ + int ExtractPVPivots( + XPivot &pivots[], + int barIndex = 0, + int requiredNumberOFPivots = 50, + int maxAllowedLoopbackLength = 1500, + int validationLength = 0 // + ) + { + // + int result = 0; + + // + // Prepare ... + SpecifiedClean(pivots); + + // + // Normalize ... + barIndex = NormalizeInt(barIndex, 0); + validationLength = NormalizeInt(validationLength, 0); + requiredNumberOFPivots = NormalizeInt(requiredNumberOFPivots, 2); + maxAllowedLoopbackLength = NormalizeInt(maxAllowedLoopbackLength, 50); + + // + // Validate ... + if (mHandler == INVALID_HANDLE) + { + return result; + } + + // + bool lookupPeaks = true; + bool lookupVales = true; + + // + XOHCL iBar; + XPivot iPivot; + bool has = false; + int idx = barIndex - 1; + int samePeaksCount = 0; + int sameValesCount = 0; + double tmpPeaksBuffer[]; + double tmpValesBuffer[]; + string symbol = GetSymbol(); + double iPValue = EMPTY_VALUE; + double iVValue = EMPTY_VALUE; + double pPValue = EMPTY_VALUE; + double pVValue = EMPTY_VALUE; + ENUM_TIMEFRAMES period = GetPeriod(); + ENUM_X_DIRECTION iDir = X_DIRECTION_NONE; + ENUM_X_PIVOT_TYPE iType = X_PIVOT_TYPE_NONE; + int maxAllowed = barIndex + maxAllowedLoopbackLength - 1; + while (idx < maxAllowed && + ArraySize(pivots) < requiredNumberOFPivots) + { + // + idx++; + + // + // Prepare ... + iBar.Clean(); + iPivot.Clean(); + SpecifiedClean(tmpPeaksBuffer); + SpecifiedClean(tmpValesBuffer); + + // + // Ignore First Item ... + if (idx == barIndex) + { + continue; + } + + // + // Initialize Bar ... + has = iBar.Init( + symbol, + period, + idx // + ); + if (!has) + { + continue; + } + + // + // Detecting ... + + // + // Peak ... + if (lookupPeaks) + { + // + // Reading Buffer ... + CopyBuffer( + mHandler, // Handler ... + XFIMA_PEAK_LINE, // Handler Buffer Number ... + idx, // Bar Index ... + 2, // Number of Requirements ... + tmpPeaksBuffer // Buffer ... + ); + ArraySetAsSeries(tmpPeaksBuffer, true); + + // + // Reading Values ... + iPValue = tmpPeaksBuffer[0]; + pPValue = tmpPeaksBuffer[1]; + + // + // Validate Value ... + if (NotEmptyZero(iPValue)) + { + // + // Check New Peak ... + has = + !NotEmptyZero(pPValue) + ? true + : iPValue != pPValue; + if (has) + { + // + // Calculate and Validate Type ... + // Peaks Only Valid when Confirmed by Bar High ... + iType = + iPValue == iBar.high + ? X_PIVOT_TYPE_PEAK + : X_PIVOT_TYPE_NONE; + has = IsXValid(iType); + + // + // Calculate and Validate Dir ... + iDir = IsXPeak(iType) + ? X_DIRECTION_BEARISH + : X_DIRECTION_NONE; + has = has && + HasDirection(iDir); + + // + // Check Validation Length ... + has = + has && + (validationLength <= 0 + ? true + : samePeaksCount >= validationLength); + if (has) + { + // + // Initialize and Validate Pivot ... + has = iPivot.Init( + iPValue, + iBar.time, + symbol, + iDir, + period, + iType // + ); + if (has) + { + // + // Add Pivot to Collection only if not Exists ... + AddIfNotExists( + iPivot, + pivots // + ); + } + } + + // + // Cleanup Resources ... + iPivot.Clean(); + samePeaksCount = 0; + } + else if (iPValue == pPValue) + { + samePeaksCount++; + } + } + } + + // + // Vale ... + if (lookupVales) + { + // + // Reading Buffer ... + CopyBuffer( + mHandler, // Handler ... + XFIMA_VALE_LINE, // Handler Buffer Number ... + idx, // Bar Index ... + 2, // Number of Requirements ... + tmpValesBuffer // Buffer ... + ); + ArraySetAsSeries(tmpValesBuffer, true); + + // + // Reading Values ... + iVValue = tmpValesBuffer[0]; + pVValue = tmpValesBuffer[1]; + + // + // Validate Value ... + if (NotEmptyZero(iVValue)) + { + // + // Check New Vale ... + has = + !NotEmptyZero(pVValue) + ? true + : iVValue != pVValue; + if (has) + { + // + // Calculate and Validate Type ... + // Vales Only Valid when Confirmed by Bar Low ... + iType = + iVValue == iBar.low + ? X_PIVOT_TYPE_VALE + : X_PIVOT_TYPE_NONE; + has = IsXValid(iType); + + // + // Calculate and Validate Dir ... + iDir = IsXVale(iType) + ? X_DIRECTION_BULLISH + : X_DIRECTION_NONE; + has = has && + HasDirection(iDir); + + // + // Check Validation Length ... + has = + has && + (validationLength <= 0 + ? true + : sameValesCount >= validationLength); + if (has) + { + // + // Initialize and Validate Pivot ... + has = iPivot.Init( + iVValue, + iBar.time, + symbol, + iDir, + period, + iType // + ); + if (has) + { + // + // Add Pivot to Collection only if not Exists ... + AddIfNotExists( + iPivot, + pivots // + ); + } + } + + // + // Cleanup Resources ... + iPivot.Clean(); + sameValesCount = 0; + } + else if (iVValue == pVValue) + { + sameValesCount++; + } + } + } + + // + // Cleanup Resources ... + iBar.Clean(); + iPivot.Clean(); + SpecifiedClean(tmpPeaksBuffer); + SpecifiedClean(tmpValesBuffer); + + // + // Check Moving Forward Condition ... + has = + idx < maxAllowed && + ArraySize(pivots) < requiredNumberOFPivots; + if (!has) + { + break; + } + } + + // + result = ArraySize(pivots); + + // + // Cleanup Resources ... + iBar.Clean(); + iPivot.Clean(); + SpecifiedClean(tmpPeaksBuffer); + SpecifiedClean(tmpValesBuffer); + + // + return result; + } + + /** + * Extract Specified Kind of Pivots ... + * + * @param pivots: XPivot, refrence Collection to hold Extracted pivots ... + * @param barIndex: int, Specified Bar Index ... + * @param requiredNumberOFPivots: int, Specified which Number of Pivots must be Extracted ... + * @param maxAllowedLoopbackLength: int, Specified Maximum Loopback Length for Pivot Extraction ... + * @param validationLength: int, Specified Pivots Validation Length ignore if <= 0 ... + * + * @return ( int ) + */ + int ExtractMAPivots( + XPivot &pivots[], + int barIndex = 0, + int requiredNumberOFPivots = 50, + int maxAllowedLoopbackLength = 1500, + int validationLength = 0 // + ) + { + // + int result = 0; + + // + // Prepare ... + SpecifiedClean(pivots); + + // + // Normalize ... + barIndex = NormalizeInt(barIndex, 0); + validationLength = NormalizeInt(validationLength, 0); + requiredNumberOFPivots = NormalizeInt(requiredNumberOFPivots, 2); + maxAllowedLoopbackLength = NormalizeInt(maxAllowedLoopbackLength, 50); + + // + // Validate ... + if (mHandler == INVALID_HANDLE) + { + return result; + } + + // + XOHCL iBar; + XOHCL pBar; + XPivot iPivot; + bool has = false; + double tmpFastMaBuffer[]; + double tmpSlowMaBuffer[]; + int idx = barIndex - 1; + string symbol = GetSymbol(); + double iFValue = EMPTY_VALUE; + double pFValue = EMPTY_VALUE; + double iSValue = EMPTY_VALUE; + double pSValue = EMPTY_VALUE; + bool isSwitchedToBullish = false; + bool isSwitchedToBearish = false; + double iSelectedValue = EMPTY_VALUE; + ENUM_TIMEFRAMES period = GetPeriod(); + ENUM_X_DIRECTION iDir = X_DIRECTION_NONE; + ENUM_X_PIVOT_TYPE iType = X_PIVOT_TYPE_NONE; + int maxAllowed = barIndex + maxAllowedLoopbackLength - 1; + while (idx < maxAllowed && + ArraySize(pivots) < requiredNumberOFPivots) + { + // + idx++; + + // + // Prepare ... + iBar.Clean(); + pBar.Clean(); + iPivot.Clean(); + SpecifiedClean(tmpFastMaBuffer); + SpecifiedClean(tmpSlowMaBuffer); + + // + // Ignore First Item ... + if (idx == barIndex) + { + continue; + } + + // + // Initialize Bar ... + has = iBar.Init( + symbol, + period, + idx // + ); + has = + has && + iBar.GetPreviousBar(pBar); + if (!has) + { + continue; + } + + // + // Reading Buffer ... + + // + // FAST ... + CopyBuffer( + mHandler, // Handler ... + XFIMA_MA_FAST_LINE, // Handler Buffer Number ... + idx, // Bar Index ... + 2, // Number of Requirements ... + tmpFastMaBuffer // Buffer ... + ); + ArraySetAsSeries(tmpFastMaBuffer, true); + + // + // SLOW ... + CopyBuffer( + mHandler, // Handler ... + XFIMA_MA_SLOW_LINE, // Handler Buffer Number ... + idx, // Bar Index ... + 2, // Number of Requirements ... + tmpSlowMaBuffer // Buffer ... + ); + ArraySetAsSeries(tmpSlowMaBuffer, true); + + // + // Reading Values ... + + // + iFValue = tmpFastMaBuffer[0]; + pFValue = tmpFastMaBuffer[1]; + + // + iSValue = tmpSlowMaBuffer[0]; + pSValue = tmpSlowMaBuffer[1]; + + // + // Validate Value ... + has = NotEmptyZero(iFValue) && + NotEmptyZero(iSValue) && + NotEmptyZero(pFValue) && + NotEmptyZero(pSValue); + if (has) + { + // + // Check Direction Changed ... + isSwitchedToBullish = iFValue > iSValue && + pFValue < pSValue; + isSwitchedToBearish = iFValue < iSValue && + pFValue > pSValue; + has = + isSwitchedToBullish || + isSwitchedToBearish; + if (has) + { + // + // Calculate and Validate Type ... + // Peaks Only Valid when Confirmed by Bar High ... + iType = + isSwitchedToBearish + ? X_PIVOT_TYPE_PEAK + : isSwitchedToBullish + ? X_PIVOT_TYPE_VALE + : X_PIVOT_TYPE_NONE; + has = IsXValid(iType); + + // + // Calculate and Validate Dir ... + iDir = IsXPeak(iType) + ? X_DIRECTION_BEARISH + : IsXVale(iType) + ? X_DIRECTION_BULLISH + : X_DIRECTION_NONE; + has = has && + HasDirection(iDir); + + // + // Check Validation ... + if (has && + validationLength > 0) + { + // + // Looping to Validate ... + double tmp[]; + bool isValid = false; + int start = pBar.Index(); + double iFast = EMPTY_VALUE; + double iSlow = EMPTY_VALUE; + int end = start + validationLength; + for (int i = start; i < end; i++) + { + // + // Initialize iBar ... + isValid = iBar.Init( + symbol, + period, + i // + ); + if (!isValid) + { + break; + } + + // + // Reading Fast and Slow Values ... + + // + SpecifiedClean(tmp); + CopyBuffer( + mHandler, // Handler ... + XFIMA_MA_FAST_LINE, // Handler Buffer Number ... + i, // Bar Index ... + 1, // Number of Requirements ... + tmp // Buffer ... + ); + ArraySetAsSeries(tmp, true); + iFast = tmp[0]; + + // + SpecifiedClean(tmp); + CopyBuffer( + mHandler, // Handler ... + XFIMA_MA_SLOW_LINE, // Handler Buffer Number ... + i, // Bar Index ... + 1, // Number of Requirements ... + tmp // Buffer ... + ); + ArraySetAsSeries(tmp, true); + iSlow = tmp[0]; + + // + // Validate ... + isValid = + IsXPeak(iType) + ? (iBar.low > MathMin(iFast, iSlow) || + iBar.GetDown() > MathMin(iFast, iSlow)) + : (iBar.high < MathMax(iFast, iSlow) || + iBar.GetUp() < MathMax(iFast, iSlow)); + if (!isValid) + { + break; + } + + // + // Cleanup Resources ... + SpecifiedClean(tmp); + } + + // + // Cleanup Resources ... + iBar.Clean(); + SpecifiedClean(tmp); + } + + // + if (has) + { + // + // Select Value based on Pivot Type ... + iSelectedValue = IsXPeak(iType) + ? MathMax(iFValue, iSValue) + : MathMin(iFValue, iSValue); + + // + // Initialize and Validate Pivot ... + has = iPivot.Init( + iSelectedValue, + iBar.time, + symbol, + iDir, + period, + iType // + ); + if (has) + { + // + // Add Pivot to Collection only if not Exists ... + AddIfNotExists( + iPivot, + pivots // + ); + } + } + + // + // Cleanup Resources ... + iPivot.Clean(); + } + } + + // + // Cleanup Resources ... + iBar.Clean(); + pBar.Clean(); + iPivot.Clean(); + SpecifiedClean(tmpFastMaBuffer); + SpecifiedClean(tmpSlowMaBuffer); + + // + // Check Moving Forward Condition ... + has = + idx < maxAllowed && + ArraySize(pivots) < requiredNumberOFPivots; + if (!has) + { + break; + } + } + + // + result = ArraySize(pivots); + + // + // Cleanup Resources ... + iBar.Clean(); + pBar.Clean(); + iPivot.Clean(); + SpecifiedClean(tmpFastMaBuffer); + SpecifiedClean(tmpSlowMaBuffer); + + // + return result; + } + + /** + * Extract Specified Kind of Pivots ... + * + * @param pivots: XPivot, refrence Collection to hold Extracted pivots ... + * @param barIndex: int, Specified Bar Index ... + * @param requiredNumberOFPivots: int, Specified which Number of Pivots must be Extracted ... + * @param maxAllowedLoopbackLength: int, Specified Maximum Loopback Length for Pivot Extraction ... + * + * @return ( int ) + */ + int ExtractSARPivots( + XPivot &pivots[], + int barIndex = 0, + int requiredNumberOFPivots = 50, + int maxAllowedLoopbackLength = 1500 // + ) + { + // + int result = 0; + + // + // Prepare ... + SpecifiedClean(pivots); + + // + // Normalize ... + barIndex = NormalizeInt(barIndex, 0); + requiredNumberOFPivots = NormalizeInt(requiredNumberOFPivots, 2); + maxAllowedLoopbackLength = NormalizeInt(maxAllowedLoopbackLength, 50); + + // + // Validate ... + if (mHandler == INVALID_HANDLE) + { + return result; + } + + // + XOHCL iBar; + XOHCL pBar; + XPivot iPivot; + bool has = false; + double tmpSarBuffer[]; + int idx = barIndex - 1; + string symbol = GetSymbol(); + double iValue = EMPTY_VALUE; + double pValue = EMPTY_VALUE; + bool isSwitchedToBullish = false; + bool isSwitchedToBearish = false; + ENUM_TIMEFRAMES period = GetPeriod(); + ENUM_X_DIRECTION iDir = X_DIRECTION_NONE; + ENUM_X_PIVOT_TYPE iType = X_PIVOT_TYPE_NONE; + int maxAllowed = barIndex + maxAllowedLoopbackLength - 1; + while (idx < maxAllowed && + ArraySize(pivots) < requiredNumberOFPivots) + { + // + idx++; + + // + // Prepare ... + iBar.Clean(); + pBar.Clean(); + iPivot.Clean(); + SpecifiedClean(tmpSarBuffer); + + // + // Ignore First Item ... + if (idx == barIndex) + { + continue; + } + + // + // Initialize Bar ... + has = iBar.Init( + symbol, + period, + idx // + ); + has = + has && + iBar.GetPreviousBar(pBar); + if (!has) + { + continue; + } + + // + // Reading Buffer ... + CopyBuffer( + mHandler, // Handler ... + XFIMA_SAR_LINE, // Handler Buffer Number ... + idx, // Bar Index ... + 2, // Number of Requirements ... + tmpSarBuffer // Buffer ... + ); + ArraySetAsSeries(tmpSarBuffer, true); + + // + // Reading Values ... + iValue = tmpSarBuffer[0]; + pValue = tmpSarBuffer[1]; + + // + // Validate Value ... + if (NotEmptyZero(iValue)) + { + // + // Check Sar Direction Changed ... + isSwitchedToBullish = iValue < iBar.low && + pValue > pBar.high; + isSwitchedToBearish = iValue > iBar.high && + pValue < pBar.low; + has = + isSwitchedToBullish || + isSwitchedToBearish; + if (has) + { + // + // Calculate and Validate Type ... + // Peaks Only Valid when Confirmed by Bar High ... + iType = + isSwitchedToBearish + ? X_PIVOT_TYPE_PEAK + : isSwitchedToBullish + ? X_PIVOT_TYPE_VALE + : X_PIVOT_TYPE_NONE; + has = IsXValid(iType); + + // + // Calculate and Validate Dir ... + iDir = IsXPeak(iType) + ? X_DIRECTION_BEARISH + : IsXVale(iType) + ? X_DIRECTION_BULLISH + : X_DIRECTION_NONE; + has = has && + HasDirection(iDir); + + // + // TODO: we can also Add other Validations Here ... + + // + if (has) + { + // + // Initialize and Validate Pivot ... + has = iPivot.Init( + iValue, + iBar.time, + symbol, + iDir, + period, + iType // + ); + if (has) + { + // + // Add Pivot to Collection only if not Exists ... + AddIfNotExists( + iPivot, + pivots // + ); + } + } + + // + // Cleanup Resources ... + iPivot.Clean(); + } + } + + // + // Cleanup Resources ... + iBar.Clean(); + pBar.Clean(); + iPivot.Clean(); + SpecifiedClean(tmpSarBuffer); + + // + // Check Moving Forward Condition ... + has = + idx < maxAllowed && + ArraySize(pivots) < requiredNumberOFPivots; + if (!has) + { + break; + } + } + + // + result = ArraySize(pivots); + + // + // Cleanup Resources ... + iBar.Clean(); + pBar.Clean(); + iPivot.Clean(); + SpecifiedClean(tmpSarBuffer); + + // + return result; + } + + /** + * Extract Specified Kind of Pivots ... + * + * @param pivots: XPivot, refrence Collection to hold Extracted pivots ... + * @param barIndex: int, Specified Bar Index ... + * @param requiredNumberOFPivots: int, Specified which Number of Pivots must be Extracted ... + * @param maxAllowedLoopbackLength: int, Specified Maximum Loopback Length for Pivot Extraction ... + * + * @return ( int ) + */ + int ExtractZigZagPivots( + XPivot &pivots[], + int barIndex = 0, + int requiredNumberOFPivots = 50, + int maxAllowedLoopbackLength = 1500 // + ) + { + // + int result = 0; + + // + // Prepare ... + SpecifiedClean(pivots); + + // + // Normalize ... + barIndex = NormalizeInt(barIndex, 0); + requiredNumberOFPivots = NormalizeInt(requiredNumberOFPivots, 2); + maxAllowedLoopbackLength = NormalizeInt(maxAllowedLoopbackLength, 50); + + // + // Validate ... + if (mHandler == INVALID_HANDLE) + { + return result; + } + + // + XOHCL iBar; + XPivot iPivot; + bool has = false; + int idx = barIndex - 1; + double tmpZigZagBuffer[]; + double iValue = EMPTY_VALUE; + string symbol = GetSymbol(); + ENUM_TIMEFRAMES period = GetPeriod(); + ENUM_X_DIRECTION iDir = X_DIRECTION_NONE; + ENUM_X_PIVOT_TYPE iType = X_PIVOT_TYPE_NONE; + int maxAllowed = barIndex + maxAllowedLoopbackLength - 1; + while (idx < maxAllowed && + ArraySize(pivots) < requiredNumberOFPivots) + { + // + idx++; + + // + // Prepare ... + iBar.Clean(); + iPivot.Clean(); + SpecifiedClean(tmpZigZagBuffer); + + // + // Ignore First Item ... + if (idx == barIndex) + { + continue; + } + + // + // Initialize Bar ... + has = iBar.Init( + symbol, + period, + idx // + ); + if (!has) + { + continue; + } + + // + // Reading Buffer ... + CopyBuffer( + mHandler, // Handler ... + XFIMA_ZIGZAG_LINE, // Handler Buffer Number ... + idx, // Bar Index ... + 1, // Number of Requirements ... + tmpZigZagBuffer // Buffer ... + ); + ArraySetAsSeries(tmpZigZagBuffer, true); + + // + // Read and Validate Value ... + iValue = tmpZigZagBuffer[0]; + has = NotEmptyZero(iValue); + if (!has) + { + // + iBar.Clean(); + continue; + } + + // + // Calculate and Validate Type ... + iType = + iValue == iBar.high + ? X_PIVOT_TYPE_PEAK + : iValue == iBar.low + ? X_PIVOT_TYPE_VALE + : X_PIVOT_TYPE_NONE; + has = IsXValid(iType); + if (!has) + { + // + iBar.Clean(); + continue; + } + + // + // Calculate and Validate Dir ... + iDir = + IsXVale(iType) + ? X_DIRECTION_BULLISH + : IsXPeak(iType) + ? X_DIRECTION_BEARISH + : X_DIRECTION_NONE; + has = HasDirection(iDir); + if (!has) + { + // + iBar.Clean(); + continue; + } + + // + // Initialize and Validate Pivot ... + has = iPivot.Init( + iValue, + iBar.time, + symbol, + iDir, + period, + iType // + ); + if (has) + { + // + // Add Pivot to Collection only if not Exists ... + AddIfNotExists( + iPivot, + pivots // + ); + } + + // + // Cleanup Resources ... + iBar.Clean(); + iPivot.Clean(); + SpecifiedClean(tmpZigZagBuffer); + + // + // Check Moving Forward Condition ... + has = + idx < maxAllowed && + ArraySize(pivots) < requiredNumberOFPivots; + if (!has) + { + break; + } + } + + // + result = ArraySize(pivots); + + // + // Cleanup Resources ... + iBar.Clean(); + iPivot.Clean(); + SpecifiedClean(tmpZigZagBuffer); + + // + return result; + } + // // Values Retrievers ... @@ -1577,7 +2602,6 @@ class XCXFIMAHelper : public XCBaseHelper zigzagBuffer // ); - // int count = ArraySize(zigzagBuffer); if (barIndex >= count) @@ -1611,7 +2635,6 @@ class XCXFIMAHelper : public XCBaseHelper zigzagBuffer // ); - // // Copy Items ... return Copy( diff --git a/Libraries/x-saherelm.common.extensions.lib.mq5 b/Libraries/x-saherelm.common.extensions.lib.mq5 index a5cf9639..c6199be6 100644 --- a/Libraries/x-saherelm.common.extensions.lib.mq5 +++ b/Libraries/x-saherelm.common.extensions.lib.mq5 @@ -5218,7 +5218,8 @@ void AddIfNotExists( void AddsIfNotExists( double &source[], double &dest[], - double smoothingPoint = 3) + double smoothingPoint = 3 // +) { // double smoothingValue = smoothingPoint * GetPoints(_Symbol); diff --git a/Libraries/x-saherelm.x-pivot.analysis.lib.mq5 b/Libraries/x-saherelm.x-pivot.analysis.lib.mq5 index 7b173c00..9a8bb6ac 100644 --- a/Libraries/x-saherelm.x-pivot.analysis.lib.mq5 +++ b/Libraries/x-saherelm.x-pivot.analysis.lib.mq5 @@ -674,7 +674,7 @@ struct XPivotAnalysis // NotEmpty(peakTo) && NotEmpty(peakFrom) && - HasDirection(peakDir) && + // HasDirection(peakDir) && IsSpecifiedValid(toTime) && IsSpecifiedValid(fromTime) // @@ -702,7 +702,7 @@ struct XPivotAnalysis // NotEmpty(valeTo) && NotEmpty(valeFrom) && - HasDirection(valeDir) && + // HasDirection(valeDir) && IsSpecifiedValid(toTime) && IsSpecifiedValid(fromTime) // diff --git a/Libraries/x-saherelm.x-poi.lib.mq5 b/Libraries/x-saherelm.x-poi.lib.mq5 index dd84c9f0..5870add8 100644 --- a/Libraries/x-saherelm.x-poi.lib.mq5 +++ b/Libraries/x-saherelm.x-poi.lib.mq5 @@ -239,101 +239,6 @@ struct XPivot return result; } - /** - * Check Structure Exists in Specified Collection or not ... - * - * @param items: XPivot, reference Array ... - * @param index: int, reference to Holds Founded Index ... - * - * @return ( bool ) - */ - bool IsExists( - XPivot &items[], - int &index // - ) - { - // - bool result = false; - - // - // Prepare ... - index = -1; - - // - // Validate ... - result = - IsValid() && - HasChild(items); - if (!result) - { - return result; - } - - // - int count = ArraySize(items); - for (int i = 0; i < count; i++) - { - // - result = IsSameAs(items[i]); - if (result) - { - // - index = i; - - // - break; - } - } - - // - result = - result && - IsValidIndex(index); - - // - return result; - } - - /** - * Add Structure to Specified Collection only if not Exists ... - * - * @param items: XPivot, reference Array ... - */ - void AddIfNotExists(XPivot &items[]) - { - // - // Validate ... - if (!IsValid()) - { - return; - } - - // - if (!HasChild(items)) - { - // - AddRef( - this, - items // - ); - - // - return; - } - - // - int index = -1; - bool isExists = IsExists(items, index); - if (!isExists) - { - // - AddRef( - this, - items // - ); - } - } - /** * Calculate Pivot Age ... * diff --git a/XFIMAEA/Classes/x-saherelm.xfima.signaller.class.mq5 b/XFIMAEA/Classes/x-saherelm.xfima.signaller.class.mq5 index ed9f6aa7..bb0b9f3b 100644 --- a/XFIMAEA/Classes/x-saherelm.xfima.signaller.class.mq5 +++ b/XFIMAEA/Classes/x-saherelm.xfima.signaller.class.mq5 @@ -43,8 +43,8 @@ class XCXFIMABaseSignaller : public XCBaseSignaller // XFIMAInputs fimaInputs; // XFIMA Inputs ... XCXFIMAHelper *fimaHelper; // XFIMA Indicator Helper ... - XCXFIMAPOIDrawer *fimaPOIDrawer; // XFIMA POI Drawer ... - XCXFIMAPOIDetector *fimaPOIDetector; // XFIMA POI Detector ... + XCXFIMAPOIDrawer *poiDrawer; // XFIMA POI Drawer ... + XCXFIMAPOIDetector *poiDetector; // XFIMA POI Detector ... // // Constructor ... @@ -90,8 +90,8 @@ class XCXFIMABaseSignaller : public XCBaseSignaller } // - fimaPOIDrawer = new XCXFIMAPOIDrawer(); - fimaPOIDetector = new XCXFIMAPOIDetector(); + poiDrawer = new XCXFIMAPOIDrawer(); + poiDetector = new XCXFIMAPOIDetector(fimaHelper); } // @@ -123,12 +123,12 @@ class XCXFIMABaseSignaller : public XCBaseSignaller ZeroMemory(fimaHelper); // - delete fimaPOIDrawer; - ZeroMemory(fimaPOIDrawer); + delete poiDrawer; + ZeroMemory(poiDrawer); // - delete fimaPOIDetector; - ZeroMemory(fimaPOIDetector); + delete poiDetector; + ZeroMemory(poiDetector); } // @@ -199,7 +199,7 @@ class XCXFIMABaseSignaller : public XCBaseSignaller // Validate Fima Helper Requirements ... result = fimaInputs.IsValid() && fimaHelper != NULL && - fimaPOIDetector != NULL; + poiDetector != NULL; // return result; 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 89a472a5..a9b6fa49 100644 --- a/XFIMAEA/Classes/x-saherelm.xfima.x-poi.detector.class.mq5 +++ b/XFIMAEA/Classes/x-saherelm.xfima.x-poi.detector.class.mq5 @@ -36,14 +36,18 @@ class XCXFIMAPOIDetector : public XCMarketPatternDetector public: // // Props ... - XCBarAnalyser *barAnalyser; // Bar Analyser ... + XCBarAnalyser *barAnalyser; // Bar Analyser ... + XCXFIMAHelper *fimaHelper; // XFIMA Helper ... // // Constructor ... - XCXFIMAPOIDetector() + XCXFIMAPOIDetector( + XCXFIMAHelper *_fimaHelper // + ) : XCMarketPatternDetector() { // barAnalyser = new XCBarAnalyser(); + fimaHelper = _fimaHelper; } // @@ -57,7 +61,279 @@ class XCXFIMAPOIDetector : public XCMarketPatternDetector // Actions and Tools ... // - // Tools ... + // Pivot Analysors ... + + /** + * Analyse Market based on Specified Kind of Pivots ... + * + * @param analysis: XPivotAnalysis, reference to hold result ... + * @param barIndex: int, Bar Index ... + * @param requiredNumberOFPivots: int, Specified which Number of Pivots must be Extracted ... + * @param maxAllowedLoopbackLength: int, Specified Maximum Loopback Length for Pivot Extraction ... + * @param validationLength: int, Specified Pivots Validation Length ignore if <= 0 ... + * + * @return ( bool ) + */ + bool AnalysePVPivots( + XPivotAnalysis &analysis, + int barIndex = 0, + int requiredNumberOFPivots = 50, + int maxAllowedLoopbackLength = 1500, + int validationLength = 0 // + ) + { + // + bool result = false; + + // + // Prepare ... + analysis.Clean(); + + // + // Reading Pivots ... + XPivot pivots[]; + int count = ExtractPVPivots( + pivots, // Result ... + barIndex, // Bar Index ... + requiredNumberOFPivots, // Required Number of Pivots ... + maxAllowedLoopbackLength, // Max Allowed Loopback ... + validationLength // Validation Length ... + ); + result = IsValidSize(count); + if (!result) + { + // + SpecifiedClean(pivots); + return result; + } + + // + string symbol = fimaHelper.GetSymbol(); + ENUM_TIMEFRAMES period = fimaHelper.GetPeriod(); + + // + // Initialize Analysis ... + result = analysis.Init( + "XFIMA_XPV", + symbol, + period, + pivots // + ); + + // + // Cleanup Resources ... + if (!result) + { + analysis.Clean(); + } + SpecifiedClean(pivots); + + // + return result; + } + + /** + * Analyse Market based on Specified Kind of Pivots ... + * + * @param analysis: XPivotAnalysis, reference to hold result ... + * @param barIndex: int, Bar Index ... + * @param requiredNumberOFPivots: int, Specified which Number of Pivots must be Extracted ... + * @param maxAllowedLoopbackLength: int, Specified Maximum Loopback Length for Pivot Extraction ... + * + * @return ( bool ) + */ + bool AnalyseZigZagPivots( + XPivotAnalysis &analysis, + int barIndex = 0, + int requiredNumberOFPivots = 50, + int maxAllowedLoopbackLength = 1500 // + ) + { + // + bool result = false; + + // + // Prepare ... + analysis.Clean(); + + // + // Reading Pivots ... + XPivot pivots[]; + int count = ExtractZigZagPivots( + pivots, // Result ... + barIndex, // Bar Index ... + requiredNumberOFPivots, // Required Number of Pivots ... + maxAllowedLoopbackLength // Max Allowed Loopback ... + ); + result = IsValidSize(count); + if (!result) + { + // + SpecifiedClean(pivots); + return result; + } + + // + string symbol = fimaHelper.GetSymbol(); + ENUM_TIMEFRAMES period = fimaHelper.GetPeriod(); + + // + // Initialize Analysis ... + result = analysis.Init( + "XFIMA_XZG", + symbol, + period, + pivots // + ); + + // + // Cleanup Resources ... + if (!result) + { + analysis.Clean(); + } + SpecifiedClean(pivots); + + // + return result; + } + + // + // Pivot Extractors ... + + /** + * Extract Specified Kind of Pivots ... + * + * @param pivots: XPivot, refrence Collection to hold Extracted pivots ... + * @param barIndex: int, Specified Bar Index ... + * @param requiredNumberOFPivots: int, Specified which Number of Pivots must be Extracted ... + * @param maxAllowedLoopbackLength: int, Specified Maximum Loopback Length for Pivot Extraction ... + * @param validationLength: int, Specified Pivots Validation Length ignore if <= 0 ... + * + * @return ( int ) + */ + int ExtractPVPivots( + XPivot &pivots[], + int barIndex = 0, + int requiredNumberOFPivots = 50, + int maxAllowedLoopbackLength = 1500, + int validationLength = 0 // + ) + { + // + int result = 0; + + // + result = fimaHelper.ExtractPVPivots( + pivots, + barIndex, + requiredNumberOFPivots, + maxAllowedLoopbackLength, + validationLength // + ); + + // + return result; + } + + /** + * Extract Specified Kind of Pivots ... + * + * @param pivots: XPivot, refrence Collection to hold Extracted pivots ... + * @param barIndex: int, Specified Bar Index ... + * @param requiredNumberOFPivots: int, Specified which Number of Pivots must be Extracted ... + * @param maxAllowedLoopbackLength: int, Specified Maximum Loopback Length for Pivot Extraction ... + * @param validationLength: int, Specified Pivots Validation Length ignore if <= 0 ... + * + * @return ( int ) + */ + int ExtractMAPivots( + XPivot &pivots[], + int barIndex = 0, + int requiredNumberOFPivots = 50, + int maxAllowedLoopbackLength = 1500, + int validationLength = 0 // + ) + { + // + int result = 0; + + // + result = fimaHelper.ExtractMAPivots( + pivots, + barIndex, + requiredNumberOFPivots, + maxAllowedLoopbackLength, + validationLength // + ); + + // + return result; + } + + /** + * Extract Specified Kind of Pivots ... + * + * @param pivots: XPivot, refrence Collection to hold Extracted pivots ... + * @param barIndex: int, Specified Bar Index ... + * @param requiredNumberOFPivots: int, Specified which Number of Pivots must be Extracted ... + * @param maxAllowedLoopbackLength: int, Specified Maximum Loopback Length for Pivot Extraction ... + * + * @return ( int ) + */ + int ExtractSARPivots( + XPivot &pivots[], + int barIndex = 0, + int requiredNumberOFPivots = 50, + int maxAllowedLoopbackLength = 1500 // + ) + { + // + int result = 0; + + // + result = fimaHelper.ExtractSARPivots( + pivots, + barIndex, + requiredNumberOFPivots, + maxAllowedLoopbackLength // + ); + + // + return result; + } + + /** + * Extract Specified Kind of Pivots ... + * + * @param pivots: XPivot, refrence Collection to hold Extracted pivots ... + * @param barIndex: int, Specified Bar Index ... + * @param requiredNumberOFPivots: int, Specified which Number of Pivots must be Extracted ... + * @param maxAllowedLoopbackLength: int, Specified Maximum Loopback Length for Pivot Extraction ... + * + * @return ( int ) + */ + int ExtractZigZagPivots( + XPivot &pivots[], + int barIndex = 0, + int requiredNumberOFPivots = 50, + int maxAllowedLoopbackLength = 1500 // + ) + { + // + int result = 0; + + // + result = fimaHelper.ExtractZigZagPivots( + pivots, + barIndex, + requiredNumberOFPivots, + maxAllowedLoopbackLength // + ); + + // + return result; + } /** * Destroy ...