diff --git a/Classes/x-saherelm.x-cobject.class.mq5 b/Classes/x-saherelm.x-cobject.class.mq5 index 88467264..28356ad0 100644 --- a/Classes/x-saherelm.x-cobject.class.mq5 +++ b/Classes/x-saherelm.x-cobject.class.mq5 @@ -44,6 +44,8 @@ enum ENUM_XCHARTOBJECTS X_SIGNAL_OBJ = 8860, X_OHCL_OBJ = 8863, X_RR_OBJ = 8864, + // + // 9860 Custom Object ... }; enum ENUM_X_CHART_IDS diff --git a/Classes/x-saherelm.x-poi.drawer.class.mq5 b/Classes/x-saherelm.x-poi.drawer.class.mq5 index e0c6437a..2c9391b4 100644 --- a/Classes/x-saherelm.x-poi.drawer.class.mq5 +++ b/Classes/x-saherelm.x-poi.drawer.class.mq5 @@ -747,7 +747,7 @@ class XCPOIDrawer : public XCBase if (box.IsBullish()) { // - ApplyStyle( + ApplyBoxStyle( object, boxBullishStyle // ); @@ -755,7 +755,7 @@ class XCPOIDrawer : public XCBase else { // - ApplyStyle( + ApplyBoxStyle( object, boxBearishStyle // ); @@ -1046,7 +1046,7 @@ class XCPOIDrawer : public XCBase /** * Apply Specified Style to Object ... */ - void ApplyStyle( + void ApplyBoxStyle( XCBoxObject *&object, XPOIStyle &style // ) @@ -1067,7 +1067,7 @@ class XCPOIDrawer : public XCBase /** * Apply Specified Style to Object ... */ - void ApplyStyle( + void ApplyBarArrowStyle( XCBarArrowObject *&object, XPOIStyle &style // ) diff --git a/Documents/BKP/xfima.poi.analysis.tmp.code.mq5 b/Documents/BKP/xfima.poi.analysis.tmp.code.mq5 new file mode 100644 index 00000000..cff0f141 --- /dev/null +++ b/Documents/BKP/xfima.poi.analysis.tmp.code.mq5 @@ -0,0 +1,186 @@ + // // + // // Detect At lease Two PEAK and Two Vale ... + // XZigZagPoint tmpPoints[]; + // Copy( + // points, + // tmpPoints // + // ); + + // // + // // Detect Highs ... + + // // + // // Highest High ... + + // // + // XZigZagPoint iZGPeak1; + // XZigZagPoint iZGPeak2; + + // // + // // First ... + // int idx = GetHighest( + // tmpPoints, + // X_ZIGZAG_POINT_TYPE_PEAK // + // ); + // result = IsValidIndex(idx); + // if (!result) + // { + // // + // Clean(); + // iZGPeak1.Clean(); + // iZGPeak2.Clean(); + // SpecifiedClean(tmpPoints); + + // // + // return result; + // } + // iZGPeak1 = tmpPoints[idx]; + // ArrayRemove( + // tmpPoints, + // idx, + // 1 // + // ); + + // // + // // Second ... + // idx = GetHighest( + // tmpPoints, + // X_ZIGZAG_POINT_TYPE_PEAK // + // ); + // result = IsValidIndex(idx); + // if (!result) + // { + // // + // Clean(); + // iZGPeak1.Clean(); + // iZGPeak2.Clean(); + // SpecifiedClean(tmpPoints); + + // // + // return result; + // } + // iZGPeak2 = tmpPoints[idx]; + // ArrayRemove( + // tmpPoints, + // idx, + // 1 // + // ); + + // // + // // Detect Lows ... + + // // + // XZigZagPoint iZGVale1; + // XZigZagPoint iZGVale2; + + // // + // // First ... + // idx = GetLowest( + // tmpPoints, + // X_ZIGZAG_POINT_TYPE_VALE // + // ); + // result = IsValidIndex(idx); + // if (!result) + // { + // // + // Clean(); + // iZGPeak1.Clean(); + // iZGPeak2.Clean(); + // iZGVale1.Clean(); + // iZGVale2.Clean(); + // SpecifiedClean(tmpPoints); + + // // + // return result; + // } + // iZGVale1 = tmpPoints[idx]; + // ArrayRemove( + // tmpPoints, + // idx, + // 1 // + // ); + + // // + // // Second ... + // idx = GetLowest( + // tmpPoints, + // X_ZIGZAG_POINT_TYPE_VALE // + // ); + // result = IsValidIndex(idx); + // if (!result) + // { + // // + // Clean(); + // iZGPeak1.Clean(); + // iZGPeak2.Clean(); + // iZGVale1.Clean(); + // iZGVale2.Clean(); + // SpecifiedClean(tmpPoints); + + // // + // return result; + // } + // iZGVale2 = tmpPoints[idx]; + // ArrayRemove( + // tmpPoints, + // idx, + // 1 // + // ); + + // // + // // Check Directions ... + // bool isBullish = + // // + // (iZGPeak1.time > iZGPeak2.time && + // iZGVale1.time < iZGVale2.time) + // // + // ; + // bool isBearish = + // // + // (iZGPeak1.time < iZGPeak2.time && + // iZGVale1.time > iZGVale2.time) + // // + // ; + // result = + // (isBullish && !isBearish) || + // (isBearish && !isBullish); + // if (!result) + // { + // // + // Clean(); + // iZGPeak1.Clean(); + // iZGPeak2.Clean(); + // iZGVale1.Clean(); + // iZGVale2.Clean(); + // SpecifiedClean(tmpPoints); + + // // + // return result; + // } + + // // + // // Setting Direction ... + // dir = + // isBullish + // ? X_DIRECTION_BULLISH + // : isBearish + // ? X_DIRECTION_BEARISH + // : X_DIRECTION_NONE; + + // // + // // Setting Points ... + // Copy( + // points, + // pivots // + // ); + + + + + // + // Cleanup Resources ... + // iZGPeak1.Clean(); + // iZGPeak2.Clean(); + // iZGVale1.Clean(); + // iZGVale2.Clean(); + // SpecifiedClean(tmpPoints); diff --git a/Experts/x-saherelm.xfima.backtester.ea.mq5 b/Experts/x-saherelm.xfima.backtester.ea.mq5 index 7b8e8a4a..6bb562d5 100644 --- a/Experts/x-saherelm.xfima.backtester.ea.mq5 +++ b/Experts/x-saherelm.xfima.backtester.ea.mq5 @@ -25,8 +25,6 @@ // // Imports ... #include "../Classes/x-saherelm.x-backtester.expert.class.mq5" -#include "../Classes/x-saherelm.x-market.pattern.class.mq5" -#include "../Classes/x-saherelm.x-poi.drawer.class.mq5" #include "../XFIMAEA/Classes/x-saherelm.xfima.signaller.class.mq5" // @@ -140,10 +138,8 @@ input int valeArrowCode = 159; // Vales Arrow Code // // Requirements ... -string eaLogTag; // EA Log Prefix ... -XCBackTesterEA *eaExpert; // EA Expert ... -XCXFIMAPOIDetector *fimaPOIDetector; // EA Fima POI Detector ... -XCMarketPatternDetector *eaPatternDetector; // EA Pattern Detector ... +string eaLogTag; // EA Log Prefix ... +XCBackTesterEA *eaExpert; // EA Expert ... // // Registered Signallers ... @@ -152,8 +148,7 @@ XCXFIMAStrategy2Signaller *fima2Signaller; // XFIMA2 Signaller ... // // Drawer and Draws ... -XCPOIDrawer *eaDrawer; // Ea POI Drawer ... -CArrayObj draws; // Drawn Objects ... +CArrayObj draws; // Drawn Objects ... // XBarTracker eaBarTracker; // EA Bar Traker ... @@ -384,17 +379,6 @@ int OnInit() return INIT_FAILED; } - // - // Instantiate Market Pattern Detector ... - eaPatternDetector = new XCMarketPatternDetector(); - - // - fimaPOIDetector = new XCXFIMAPOIDetector(); - - // - // Instantiate POI Drawer ... - eaDrawer = new XCPOIDrawer(); - // Print(ShortName, ": Initialized Successfully ..."); return INIT_SUCCEEDED; @@ -427,14 +411,6 @@ void OnDeinit(const int reason) // eaBarTracker.Clean(); - // - delete eaDrawer; - ZeroMemory(eaDrawer); - - // - delete eaPatternDetector; - ZeroMemory(eaPatternDetector); - // delete fima1Signaller; ZeroMemory(fima1Signaller); @@ -443,10 +419,6 @@ void OnDeinit(const int reason) delete fima2Signaller; ZeroMemory(fima2Signaller); - // - delete fimaPOIDetector; - ZeroMemory(fimaPOIDetector); - // delete eaExpert; ZeroMemory(eaExpert); @@ -641,9 +613,9 @@ void OnSignalTriggered(XSignal &signal) // bool has = iObj.Create( - eaDrawer.ChartIdentification(), + fima2Signaller.fimaPOIDrawer.ChartIdentification(), iName, - eaDrawer.SubWindowIdentification(), + fima2Signaller.fimaPOIDrawer.SubWindowIdentification(), signal.time // ); if (has) @@ -851,7 +823,7 @@ void DetectPatterns() if (detectMomentum) { // - bool isMomentum = eaPatternDetector.IsMomentumBar( + bool isMomentum = fima2Signaller.fimaPOIDetector.IsMomentumBar( cBar, iDir // ); @@ -870,7 +842,7 @@ void DetectPatterns() if (detectEngulfed) { // - bool isEngulfed = eaPatternDetector.IsEngulfedBar( + bool isEngulfed = fima2Signaller.fimaPOIDetector.IsEngulfedBar( cBar, iDir // ); @@ -889,7 +861,7 @@ void DetectPatterns() if (detectTrueGaped) { // - bool isTrueGaped = eaPatternDetector.IsTrueGapedBar( + bool isTrueGaped = fima2Signaller.fimaPOIDetector.IsTrueGapedBar( cBar, iDir // ); @@ -907,7 +879,7 @@ void DetectPatterns() // Checking Pinned Bar ... if (detectPinned) { - bool isPinned = eaPatternDetector.IsPinnedBar( + bool isPinned = fima2Signaller.fimaPOIDetector.IsPinnedBar( cBar, iDir // ); @@ -925,7 +897,7 @@ void DetectPatterns() // Checking Star Pattern ... if (detectStarPattern) { - bool isStarPattern = eaPatternDetector.IsStartPattern( + bool isStarPattern = fima2Signaller.fimaPOIDetector.IsStartPattern( cBar, iDir // ); @@ -944,7 +916,7 @@ void DetectPatterns() if (detectPiercingPattern) { // - bool isPiercingPattern = eaPatternDetector.IsPiercingPattern( + bool isPiercingPattern = fima2Signaller.fimaPOIDetector.IsPiercingPattern( cBar, iDir // ); @@ -963,7 +935,7 @@ void DetectPatterns() if (detectRisingPattern) { // - bool isRisingPattern = eaPatternDetector.IsRisingPattern( + bool isRisingPattern = fima2Signaller.fimaPOIDetector.IsRisingPattern( cBar, iDir // ); @@ -983,7 +955,7 @@ void DetectPatterns() { // XOHCL swingBar; - bool isFlagPattern = eaPatternDetector.IsFlagPattern( + bool isFlagPattern = fima2Signaller.fimaPOIDetector.IsFlagPattern( cBar, iDir, swingBar // @@ -1004,7 +976,7 @@ void DetectPatterns() if (detectSignalKeyBarPattern) { // - bool isSignalKeyBar = eaPatternDetector.IsSignalKeyBarPattern( + bool isSignalKeyBar = fima2Signaller.fimaPOIDetector.IsSignalKeyBarPattern( cBar, iDir // ); @@ -1024,7 +996,7 @@ void DetectPatterns() { // XOHCL swings[]; - bool hasSwingTrend = eaPatternDetector.HasSwingTrend( + bool hasSwingTrend = fima2Signaller.fimaPOIDetector.HasSwingTrend( cBar, iDir, swings // @@ -1040,7 +1012,7 @@ void DetectPatterns() // CChartObjectTrend *iObj; - has = eaDrawer.DrawSwingTrend( + has = fima2Signaller.fimaPOIDrawer.DrawSwingTrend( swings, iDir, iObj, @@ -1060,7 +1032,7 @@ void DetectPatterns() { // XOHCL swings[]; - bool hasSwingTrend = eaPatternDetector.HasSwingTrend( + bool hasSwingTrend = fima2Signaller.fimaPOIDetector.HasSwingTrend( cBar, iDir, swings // @@ -1097,7 +1069,7 @@ void DetectPatterns() { // XOHCL support; - bool hasSupport = eaPatternDetector.HasSupport( + bool hasSupport = fima2Signaller.fimaPOIDetector.HasSupport( cBar, support // ); @@ -1111,20 +1083,12 @@ void DetectPatterns() // // Draw Box ... XCBoxObject *iObj; - has = eaDrawer.DrawBox( + has = fima2Signaller.fimaPOIDrawer.DrawBox( supportBox, iObj // ); if (has) { - // - // Apply Style ... - eaDrawer.ApplyStyle( - iObj, - eaDrawer.boxBullishStyle // - ); - - // draws.Add(iObj); } @@ -1144,7 +1108,7 @@ void DetectPatterns() { // XOHCL resistance; - bool hasResistance = eaPatternDetector.HasResistance( + bool hasResistance = fima2Signaller.fimaPOIDetector.HasResistance( cBar, resistance // ); @@ -1158,20 +1122,12 @@ void DetectPatterns() // // Draw Box ... XCBoxObject *iObj; - has = eaDrawer.DrawBox( + has = fima2Signaller.fimaPOIDrawer.DrawBox( resistanceBox, iObj // ); if (has) { - // - // Apply Style ... - eaDrawer.ApplyStyle( - iObj, - eaDrawer.boxBearishStyle // - ); - - // draws.Add(iObj); } @@ -1194,93 +1150,30 @@ void DetectPatterns() if (detectZIGZAGPatterns) { // - XZigZagPoint zigzags[]; - int zigzagsCount = fimaPOIDetector.GetZigZagPoint( + // Detect Market Analysis ... + XZigZagAnalysis zAnalysis; + has = fima2Signaller.fimaPOIDetector.AnalyseMarketUsingZigZag( cBar, + cBar.period, fima2Signaller.fimaHelper, - zigzags, + zAnalysis, 15 // ); - has = IsValidSize(zigzagsCount); if (has) { // - // Analyse Using ZigZag ... - XZigZagAnalysis cZGAnalysis; + Print(ShortName + zAnalysis.GetMessage()); // - // Check ZG Analysis Exists ... - has = cZGAnalysis.Analyse( - cBar, - zigzags // + XCZigZagAnalysisObject *iObj; + has = fima2Signaller.fimaPOIDrawer.DrawZigZagMarketAnalysis( + iObj, + zAnalysis // ); - - // - // Check Exists ZG Analysis isn't Same Trend as Prev ... - has = - has && - (!zigzagAnalysis.IsValid() - ? true - : !zigzagAnalysis.IsSameTrendAs(cZGAnalysis)); if (has) { - // - // Update Prev Analysis ... - zigzagAnalysis = cZGAnalysis; - - // - // Notify Only When New Trending Happens ... - Print("Detected ZigZags Pivots Analysis: ", zigzagAnalysis.GetMessage()); - - // - // Draw Trend Line ... - - // - string iObjID = zigzagAnalysis.GetObjectID(); - string iNameType = ToXString(zigzagAnalysis.dir) + "_Trend"; - - // - // Upper Line ... - string iUpperName = iNameType + "_Upper_" + iObjID; - CChartObjectTrend *iUpperObj; - has = eaDrawer.DrawTrendLine( - zigzagAnalysis.lastPeak.value, - zigzagAnalysis.lastPeak.time, - zigzagAnalysis.recentPeak.value, - zigzagAnalysis.recentPeak.time, - iUpperObj, - ToMD5(iUpperName), - true // - ); - - // - // Lower Line ... - string iLowerName = iNameType + "_Lower_" + iObjID; - CChartObjectTrend *iLowerObj; - has = - has && - eaDrawer.DrawTrendLine( - zigzagAnalysis.lastVale.value, - zigzagAnalysis.lastVale.time, - zigzagAnalysis.recentVale.value, - zigzagAnalysis.recentVale.time, - iLowerObj, - ToMD5(iLowerName), - true // - ); - - // - if (has) { - // - // Apply Style on Trend Lines ... - - // - draws.Add(iUpperObj); - draws.Add(iLowerObj); - } + draws.Add(iObj); } - - // } } } diff --git a/XFIMAEA/Classes/x-saherelm.xfima.signaller.class.mq5 b/XFIMAEA/Classes/x-saherelm.xfima.signaller.class.mq5 index 7dc44cf1..ed9f6aa7 100644 --- a/XFIMAEA/Classes/x-saherelm.xfima.signaller.class.mq5 +++ b/XFIMAEA/Classes/x-saherelm.xfima.signaller.class.mq5 @@ -25,6 +25,7 @@ #include "../../Classes/x-saherelm.x-signaller.class.mq5" #include "../../Helpers/x-saherelm.xfima.helper.mq5" #include "../Classes/x-saherelm.xfima.x-poi.detector.class.mq5" +#include "../Classes/x-saherelm.xfima.x-poi.drawer.class.mq5" // // Implementation ... @@ -42,6 +43,7 @@ class XCXFIMABaseSignaller : public XCBaseSignaller // XFIMAInputs fimaInputs; // XFIMA Inputs ... XCXFIMAHelper *fimaHelper; // XFIMA Indicator Helper ... + XCXFIMAPOIDrawer *fimaPOIDrawer; // XFIMA POI Drawer ... XCXFIMAPOIDetector *fimaPOIDetector; // XFIMA POI Detector ... // @@ -88,6 +90,7 @@ class XCXFIMABaseSignaller : public XCBaseSignaller } // + fimaPOIDrawer = new XCXFIMAPOIDrawer(); fimaPOIDetector = new XCXFIMAPOIDetector(); } @@ -119,6 +122,10 @@ class XCXFIMABaseSignaller : public XCBaseSignaller delete fimaHelper; ZeroMemory(fimaHelper); + // + delete fimaPOIDrawer; + ZeroMemory(fimaPOIDrawer); + // delete fimaPOIDetector; ZeroMemory(fimaPOIDetector); 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 c37dd641..7cdde8cf 100644 --- a/XFIMAEA/Classes/x-saherelm.xfima.x-poi.detector.class.mq5 +++ b/XFIMAEA/Classes/x-saherelm.xfima.x-poi.detector.class.mq5 @@ -29,7 +29,7 @@ // // Implementation ... -class XCXFIMAPOIDetector : public XCBase +class XCXFIMAPOIDetector : public XCMarketPatternDetector { // // Public ... @@ -37,7 +37,6 @@ class XCXFIMAPOIDetector : public XCBase // // Props ... XCBarAnalyser *barAnalyser; // Bar Analyser ... - XCMarketPatternDetector *patternDetector; // Pattern Detector ... // // Constructor ... @@ -45,7 +44,6 @@ class XCXFIMAPOIDetector : public XCBase { // barAnalyser = new XCBarAnalyser(); - patternDetector = new XCMarketPatternDetector(); } // @@ -64,15 +62,15 @@ class XCXFIMAPOIDetector : public XCBase * @param bar: XOHCL, Specified Bar for Start ... * @param fimaHelper: XCXFIMAHelper, instance of XFIMA Helper ... * @param zigzagPoints: XZigZagPoint, Array of Founded Points ... - * @param numberOfRequiredPoints: int, Specified Number of required ZigZag Points ... + * @param numberOfRequiredPivots: int, Specified Number of required ZigZag Points ... * * @return ( int ) */ - int GetZigZagPoint( + int GetZigZagPivot( XOHCL &bar, XCXFIMAHelper *&fimaHelper, - XZigZagPoint &zigzagPoints[], - int numberOfRequiredPoints = 5 // + XZigZagPivot &zigzagPivots[], + int numberOfRequiredPivots = 5 // ) { // @@ -80,8 +78,8 @@ class XCXFIMAPOIDetector : public XCBase // // Normalize ... - SpecifiedClean(zigzagPoints); - numberOfRequiredPoints = NormalizeInt(numberOfRequiredPoints, 3); + SpecifiedClean(zigzagPivots); + numberOfRequiredPivots = NormalizeInt(numberOfRequiredPivots, 3); // // Validate ... @@ -106,13 +104,13 @@ class XCXFIMAPOIDetector : public XCBase int iPZGIdx = -1; bool has = false; int start = index; - XZigZagPoint iZGPoint; + XZigZagPivot iZGPoint; datetime iZGTime = NULL; datetime iPZGTime = NULL; int lastZGDetected = start; ENUM_X_DIRECTION iDir = X_DIRECTION_NONE; - ENUM_X_ZIGZAG_POINT_TYPE iType = X_ZIGZAG_POINT_TYPE_NONE; - while (ArraySize(zigzagPoints) < numberOfRequiredPoints) + ENUM_X_ZIGZAG_POINT_TYPE iType = X_ZIGZAG_PIVOT_TYPE_NONE; + while (ArraySize(zigzagPivots) < numberOfRequiredPivots) { // // Reading Last two ZigZag Value ... @@ -131,7 +129,7 @@ class XCXFIMAPOIDetector : public XCBase iPZGTime = NULL; iZGPoint.Clean(); iDir = X_DIRECTION_NONE; - iType = X_ZIGZAG_POINT_TYPE_NONE; + iType = X_ZIGZAG_PIVOT_TYPE_NONE; // start++; @@ -155,7 +153,7 @@ class XCXFIMAPOIDetector : public XCBase iPZGTime = NULL; iZGPoint.Clean(); iDir = X_DIRECTION_NONE; - iType = X_ZIGZAG_POINT_TYPE_NONE; + iType = X_ZIGZAG_PIVOT_TYPE_NONE; // start++; @@ -178,10 +176,10 @@ class XCXFIMAPOIDetector : public XCBase // Check Point Type ... iType = IsSpecifiedBullish(iDir) - ? X_ZIGZAG_POINT_TYPE_PEAK + ? X_ZIGZAG_PIVOT_TYPE_PEAK : IsSpecifiedBearish(iDir) - ? X_ZIGZAG_POINT_TYPE_VALE - : X_ZIGZAG_POINT_TYPE_NONE; + ? X_ZIGZAG_PIVOT_TYPE_VALE + : X_ZIGZAG_PIVOT_TYPE_NONE; has = IsXValid(iType) && HasDirection(iDir); @@ -196,7 +194,7 @@ class XCXFIMAPOIDetector : public XCBase iPZGTime = NULL; iZGPoint.Clean(); iDir = X_DIRECTION_NONE; - iType = X_ZIGZAG_POINT_TYPE_NONE; + iType = X_ZIGZAG_PIVOT_TYPE_NONE; // start++; @@ -219,7 +217,7 @@ class XCXFIMAPOIDetector : public XCBase if (has) { // - iZGPoint.AddIfNotExists(zigzagPoints); + iZGPoint.AddIfNotExists(zigzagPivots); lastZGDetected = iZGIdx + 1; } @@ -233,14 +231,14 @@ class XCXFIMAPOIDetector : public XCBase iPZGTime = NULL; iZGPoint.Clean(); iDir = X_DIRECTION_NONE; - iType = X_ZIGZAG_POINT_TYPE_NONE; + iType = X_ZIGZAG_PIVOT_TYPE_NONE; // start++; } // - result = ArraySize(zigzagPoints); + result = ArraySize(zigzagPivots); // return result; @@ -250,7 +248,9 @@ class XCXFIMAPOIDetector : public XCBase bool AnalyseMarketUsingZigZag( XOHCL &bar, ENUM_TIMEFRAMES forPeriod, - XZigZagAnalysis &analysis // + XCXFIMAHelper *&fimaHelper, + XZigZagAnalysis &analysis, + int numberOfRequiredPivots = 20 // ) { // @@ -270,6 +270,7 @@ class XCXFIMAPOIDetector : public XCBase // // Normalize ... + numberOfRequiredPivots = NormalizeInt(numberOfRequiredPivots, 5); if (!IsSpecifiedValid(forPeriod)) { forPeriod = bar.period; @@ -277,365 +278,55 @@ class XCXFIMAPOIDetector : public XCBase // // Reading XZigZag Points ... + XOHCL iPeriodBar; + result = iPeriodBar.Init( + bar.symbol, + forPeriod, + bar.Index() // + ); + if (!result) + { + // + iPeriodBar.Clean(); + return result; + } + + // + // Reading Required Pivots ... + XZigZagPivot pivots[]; + int pivotsCount = GetZigZagPivot( + iPeriodBar, + fimaHelper, + pivots, + numberOfRequiredPivots // + ); + result = IsValidSize(pivotsCount); + if (!result) + { + // + analysis.Clean(); + iPeriodBar.Clean(); + SpecifiedClean(pivots); + } + + // + // Initialize Analysis Model ... + result = analysis.Analyse( + bar, + pivots // + ); + if (!result) + { + // + analysis.Clean(); + iPeriodBar.Clean(); + SpecifiedClean(pivots); + } // return result; } - // - // Implementing Patrren Detector ... - - /** - * Check Specified Bar is Momentum Bar or not ... - * - * @param bar: XOHCL, Specified Bar ... - * @param dir: ENUM_X_DIRECTION a reference for Direction ... - * @param requiredBars: int, bar range for approve Momentum ... - * @param approvedMultiplier: int, a Multipler for approve Momentum ... - * - * @return ( bool ) - */ - bool IsMomentumBar( - XOHCL &bar, - ENUM_X_DIRECTION &dir, - int requiredBars = 3, - int approvedMultiplier = 2 // - ) - { - // - return patternDetector.IsMomentumBar( - bar, - dir, - requiredBars, - approvedMultiplier // - ); - } - - /** - * Check Specified Bar is Engulfed Bar or not ... - * - * @param bar: XOHCL, Specified Bar ... - * @param dir: ENUM_X_DIRECTION a reference for Direction ... - * - * @return ( bool ) - */ - bool IsEngulfedBar( - XOHCL &bar, - ENUM_X_DIRECTION &dir // - ) - { - // - return patternDetector.IsEngulfedBar( - bar, - dir // - ); - } - - /** - * Check Specified Bar is True Gapped Bar or not ... - * - * @param bar: XOHCL, Specified Bar ... - * @param dir: ENUM_X_DIRECTION a reference for Direction ... - * @param approvedPointMultiplier: double, Gap Validation Multiplier in Point ... - * - * @return ( bool ) - */ - bool IsTrueGapedBar( - XOHCL &bar, - ENUM_X_DIRECTION &dir, - double approvedPointMultiplier = 1 // - ) - { - // - return patternDetector.IsTrueGapedBar( - bar, - dir, - approvedPointMultiplier // - ); - } - - /** - * Check Specified Bar is Pinned Bar or not ... - * - * @param bar: XOHCL, Specified Bar ... - * @param dir: ENUM_X_DIRECTION a reference for Direction ... - * @param shadowApprovedMultiplier: int, Shadow Size Approve Multiplier ... - * @param minimumPinBarRangeMultiplier: doubble, Range Size Approve Multiplier in Point ... - * @param forceDirection: bool, Apply Force Bar Type ... - * - * @return ( bool ) - */ - bool IsPinnedBar( - XOHCL &bar, - ENUM_X_DIRECTION &dir, - int shadowApprovedMultiplier = 3, - double minimumPinBarRangeMultiplier = 4, - bool forceDirection = false // - ) - { - // - return patternDetector.IsPinnedBar( - bar, - dir, - shadowApprovedMultiplier, - minimumPinBarRangeMultiplier, - forceDirection // - ); - } - - /** - * Check Specified Bar has Star Pattern or not ... - * Morning Star => Bullish - * Evening Star => Bearish - * - * @param bar: XOHCL, Specified Bar ... - * @param dir: ENUM_X_DIRECTION a reference for Direction ... - * - * @return ( bool ) - */ - bool IsStartPattern( - XOHCL &bar, - ENUM_X_DIRECTION &dir // - ) - { - // - return patternDetector.IsStartPattern( - bar, - dir // - ); - } - - /** - * Check Specified Bar has Pirecing Pattern or not ... - * Piercing => Bullish - * Dark Cloud Cover => Bearish - * - * @param bar: XOHCL, Specified Bar ... - * @param dir: ENUM_X_DIRECTION a reference for Direction ... - * - * @return ( bool ) - */ - bool IsPiercingPattern( - XOHCL &bar, - ENUM_X_DIRECTION &dir // - ) - { - // - return patternDetector.IsPiercingPattern( - bar, - dir // - ); - } - - /** - * Check Specified Bar has Rising Pattern or not ... - * - * @param bar: XOHCL, Specified Bar ... - * @param dir: ENUM_X_DIRECTION a reference for Direction ... - * - * @return ( bool ) - */ - bool IsRisingPattern( - XOHCL &bar, - ENUM_X_DIRECTION &dir // - ) - { - // - return patternDetector.IsRisingPattern( - bar, - dir // - ); - } - - /** - * Check Specified Bar has Flag Pattern or not ... - * - * @param bar: XOHCL, Specified Bar ... - * @param dir: ENUM_X_DIRECTION a reference for Direction ... - * @param swingBar: XOHCL, Detected Swing Bar ... - * @param minimumPullbackBars: int, Minimum Shoulders of Swing Bar ... - * @param minimumPullbackBars: int, Minimum Shoulders of Swing Bar ... - * - * @return ( bool ) - */ - bool IsFlagPattern( - XOHCL &bar, - ENUM_X_DIRECTION &dir, - XOHCL &swingBar, - int minimumPullbackBars = 3 // - ) - { - // - return patternDetector.IsFlagPattern( - bar, - dir, - swingBar, - minimumPullbackBars // - ); - } - - /** - * Check Specified Bar has SignalKey Bar Pattern or not ... - * - * @param bar: XOHCL, Specified Bar ... - * @param dir: ENUM_X_DIRECTION a reference for Direction ... - * @param shadowApprovedMultiplier: int, Shadow Size Approve Multiplier ... - * @param minimumPinBarRangeMultiplier: doubble, Range Size Approve Multiplier in Point ... - * @param forceDirection: bool, Apply Force Bar Type ... - * - * @return ( bool ) - */ - bool IsSignalKeyBarPattern( - XOHCL &bar, - ENUM_X_DIRECTION &dir, - int shadowApprovedMultiplier = 3, - double minimumPinBarRangeMultiplier = 4, - bool forceDirection = false // - ) - { - // - return patternDetector.IsSignalKeyBarPattern( - bar, - dir, - shadowApprovedMultiplier, - minimumPinBarRangeMultiplier, - forceDirection // - ); - } - - /** - * Check For FVG Exists in Specified Loopback Period ... - * - * @param bar: XOHCL, Specified Bar ... - * @param dir: ENUM_X_DIRECTION a reference for Direction ... - * @param fvg: XBoxZone, reference for Holding FVG ... - * @param maxLoopback: int, Max Allowed Loopback to Lookup FVG ... - * - * @return ( bool ) - */ - bool HasFVG( - XOHCL &bar, - ENUM_X_DIRECTION &dir, - XBoxZone &fvg, - int maxLoopback = 5 // - ) - { - // - return patternDetector.HasFVG( - bar, - dir, - fvg, - maxLoopback // - ); - } - - /** - * Check For OB Exists in Specified Loopback Period ... - * - * @param bar: XOHCL, Specified Bar ... - * @param dir: ENUM_X_DIRECTION a reference for Direction ... - * @param ob: XBoxZone, reference for Holding OB ... - * @param maxLoopback: int, Max Allowed Loopback to Lookup OB ... - * - * @return ( bool ) - */ - bool HasOB( - XOHCL &bar, - ENUM_X_DIRECTION &dir, - XBoxZone &ob, - int maxLoopback = 5 // - ) - { - // - return patternDetector.HasOB( - bar, - dir, - ob, - maxLoopback // - ); - } - - /** - * Check Trend Exists Based on Swings ... - * - * @param bar: XOHCL, Specified Bar ... - * @param dir: ENUM_X_DIRECTION a reference for Direction ... - * @param swings: XOHCL Array, Holds Swings ... - * @param numberOfSwings: int, Number of Swing Points for Detect Trend ... - * @param swingShoulders: int, Swing Shoulders Approvement Length ... - * - * @return ( bool ) - */ - bool HasSwingTrend( - XOHCL &bar, - ENUM_X_DIRECTION &dir, - XOHCL &swings[], - int numberOfSwings = 3, - int swingShoulders = 7 // - ) - { - // - return patternDetector.HasSwingTrend( - bar, - dir, - swings, - numberOfSwings, - swingShoulders // - ); - } - - /** - * Check Specified Bar Has Support or not ... - * - * @param bar: XOHCL, Specified Bar ... - * @param support: XOHCL, Supported Bar ... - * @param validationLength: int, Validation Length ... - * @param maxAllowedLoopback: int, Max Allowed Loopback to Detection ... - * - * @return ( bool ) - */ - bool HasSupport( - XOHCL &bar, - XOHCL &support, - int validationLength = 21, - int maxAllowedLoopback = 1500 // - ) - { - // - return patternDetector.HasSupport( - bar, - support, - validationLength, - maxAllowedLoopback // - ); - } - - /** - * Check Specified Bar Has Resistance or not ... - * - * @param bar: XOHCL, Specified Bar ... - * @param resistence: XOHCL, Resistanced Bar ... - * @param validationLength: int, Validation Length ... - * @param maxAllowedLoopback: int, Max Allowed Loopback to Detection ... - * - * @return ( bool ) - */ - bool HasResistance( - XOHCL &bar, - XOHCL &resistence, - int validationLength = 21, - int maxAllowedLoopback = 1500 // - ) - { - // - return patternDetector.HasResistance( - bar, - resistence, - validationLength, - maxAllowedLoopback // - ); - } - // // Tools ... @@ -647,10 +338,6 @@ class XCXFIMAPOIDetector : public XCBase // delete barAnalyser; ZeroMemory(barAnalyser); - - // - delete patternDetector; - ZeroMemory(patternDetector); } // diff --git a/XFIMAEA/Classes/x-saherelm.xfima.x-poi.drawer.class.mq5 b/XFIMAEA/Classes/x-saherelm.xfima.x-poi.drawer.class.mq5 new file mode 100644 index 00000000..6e8f2518 --- /dev/null +++ b/XFIMAEA/Classes/x-saherelm.xfima.x-poi.drawer.class.mq5 @@ -0,0 +1,141 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Class +// ------------------------------------------------- +// Name: XCXFIMAPoiDrawer ... +// Description: XFIMA POI Drawer Class ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://saherelm.ir" +#property version "1.00" +#property description "SaherElm XFIMA POI Drawer Class" +#property strict + +// +// Imports ... +#include "../../Classes/x-saherelm.x-poi.drawer.class.mq5" +#include "../Libraries/x-saherelm.xfima.lib.mq5" + +// +// Implementation ... +class XCXFIMAPOIDrawer : public XCPOIDrawer +{ + // + public: + // + + /** + * Draw Specified XZigZagMarketStyle on Chart ... + * + * @param object: XCZigZagAnalysisObject, pointer reference to Drawn Object ... + * @param model: XZigZagAnalysis, reference to Model ... + * @param numberOfPivots: int, required number of pivots for Draw Trends ... + * @param rayRight: bool, Ray To Right ... + * @param rayLeft: bool, Ray To Left ... + * + * @return ( bool ) + */ + bool DrawZigZagMarketAnalysis( + XCZigZagAnalysisObject *&object, + XZigZagAnalysis &model, + bool rayRight = false, + bool rayLeft = false, + int numberOfPivots = 2 // + ) + { + // + bool result = false; + + // + // Prepare ... + object = NULL; + + // + // Validate ... + result = model.IsValid(); + if (!result) + { + return result; + } + + // + object = new XCZigZagAnalysisObject(); + result = object.Create( + ChartIdentification(), + SubWindowIdentification(), + model, + numberOfPivots // + ); + if (result) + { + // + // Apply Style ... + bool isBullish = model.IsBullish(); + + // + XPOIStyle style; + if (isBullish) + { + style = defaultBullishStyle; + } + else + { + style = defaultBearishStyle; + } + + // + ApplyZigZagMarketAnalysisStyle( + object, + style, + false, // Ray Right ... + true // Ray Left ... + ); + } + + // + return result; + } + + /** + * Apply Specified Style to Object ... + */ + void ApplyZigZagMarketAnalysisStyle( + XCZigZagAnalysisObject *&object, + XPOIStyle &style, + bool rayRight = false, + bool rayLeft = false // + ) + { + // + bool has = object != NULL; + if (!has) + { + return; + } + + // + object.UpperColor(style.clr); + object.LowerColor(style.clr); + object.UpperWidth(style.width); + object.UpperRayLeft(rayLeft); + object.UpperRayRight(rayRight); + object.LowerWidth(style.width); + object.UpperStyle(style.style); + object.LowerStyle(style.style); + object.LowerRayLeft(rayLeft); + object.LowerRayRight(rayRight); + } + + // +}; + +// \ No newline at end of file diff --git a/XFIMAEA/Libraries/x-saherelm.xfima.lib.mq5 b/XFIMAEA/Libraries/x-saherelm.xfima.lib.mq5 index ca2405cc..f50f084b 100644 --- a/XFIMAEA/Libraries/x-saherelm.xfima.lib.mq5 +++ b/XFIMAEA/Libraries/x-saherelm.xfima.lib.mq5 @@ -22,6 +22,7 @@ // // Imports ... +#include "../../Classes/x-saherelm.x-cobject.class.mq5" #include "../../Helpers/x-saherelm.xfima.helper.mq5" // @@ -34,9 +35,9 @@ // ZigZag Point Type ... enum ENUM_X_ZIGZAG_POINT_TYPE { - X_ZIGZAG_POINT_TYPE_NONE = 0, // None - X_ZIGZAG_POINT_TYPE_PEAK = 1, // PEAK - X_ZIGZAG_POINT_TYPE_VALE = 2, // VALE + X_ZIGZAG_PIVOT_TYPE_NONE = 0, // None + X_ZIGZAG_PIVOT_TYPE_PEAK = 1, // PEAK + X_ZIGZAG_PIVOT_TYPE_VALE = 2, // VALE }; /** @@ -52,7 +53,7 @@ bool IsXValid(ENUM_X_ZIGZAG_POINT_TYPE value) bool result = false; // - result = value != X_ZIGZAG_POINT_TYPE_NONE; + result = value != X_ZIGZAG_PIVOT_TYPE_NONE; // return result; @@ -76,7 +77,7 @@ string ToXString(ENUM_X_ZIGZAG_POINT_TYPE value) /** * Specified ZigZag Point ... **/ -struct XZigZagPoint +struct XZigZagPivot { // // Props ... @@ -89,7 +90,7 @@ struct XZigZagPoint // // Constructor ... - XZigZagPoint() + XZigZagPivot() { Clean(); } @@ -154,7 +155,7 @@ struct XZigZagPoint symbol = NULL; period = NULL; dir = X_DIRECTION_NONE; - type = X_ZIGZAG_POINT_TYPE_NONE; + type = X_ZIGZAG_PIVOT_TYPE_NONE; // ZeroMemory(this); @@ -222,11 +223,11 @@ struct XZigZagPoint /** * Check two Struct are Same or not ... * - * @param item: XZigZagPoint ... + * @param item: XZigZagPivot ... * * @return ( bool ) */ - bool IsSameAs(XZigZagPoint &item) + bool IsSameAs(XZigZagPivot &item) { // bool result = false; @@ -249,13 +250,13 @@ struct XZigZagPoint /** * Check Structure Exists in Specified Collection or not ... * - * @param items: XZigZagPoint, reference Array ... + * @param items: XZigZagPivot, reference Array ... * @param index: int, reference to Holds Founded Index ... * * @return ( bool ) */ bool IsExists( - XZigZagPoint &items[], + XZigZagPivot &items[], int &index // ) { @@ -304,9 +305,9 @@ struct XZigZagPoint /** * Add Structure to Specified Collection only if not Exists ... * - * @param items: XZigZagPoint, reference Array ... + * @param items: XZigZagPivot, reference Array ... */ - void AddIfNotExists(XZigZagPoint &items[]) + void AddIfNotExists(XZigZagPivot &items[]) { // // Validate ... @@ -341,6 +342,144 @@ struct XZigZagPoint } } + /** + * Calculate Pivot Age ... + * + * @return ( int ) + */ + int GetAge() + { + // + int result = -1; + + // + if (!IsValid()) + { + return result; + } + + // + result = GetBarIndex( + symbol, + period, + time // + ); + + // + return result; + } + + /** + * Check to model Has Same Symbol ... + * + * @param item: XZigZagXZigZagPivotAXZigZagPivotnalysis, dest model for Checking ... + * + * @return ( bool ) + */ + bool IsSameSymbolAs(XZigZagPivot &item) + { + // + bool result = false; + + // + result = + IsValid() && + item.IsValid() && + symbol == item.symbol; + + // + return result; + } + + /** + * Check to model Has Same Period ... + * + * @param item: XZigZagPivot, dest model for Checking ... + * + * @return ( bool ) + */ + bool IsSamePeriodAs(XZigZagPivot &item) + { + // + bool result = false; + + // + result = + IsValid() && + item.IsValid() && + period == item.period; + + // + return result; + } + + /** + * Check to model Has Same Symbol/Period ... + * + * @param item: XZigZagPivot, dest model for Checking ... + * + * @return ( bool ) + */ + bool IsSameMarketAs(XZigZagPivot &item) + { + // + bool result = false; + + // + result = + IsValid() && + item.IsValid() && + IsSameSymbolAs(item) && + IsSamePeriodAs(item); + + // + return result; + } + + /** + * Check to model Has Same Type ... + * + * @param item: XZigZagPivot, dest model for Checking ... + * + * @return ( bool ) + */ + bool IsSameTypeAs(XZigZagPivot &item) + { + // + bool result = false; + + // + result = + IsValid() && + item.IsValid() && + type == item.type; + + // + return result; + } + + /** + * Check to model Has Same Direction ... + * + * @param item: XZigZagPivot, dest model for Checking ... + * + * @return ( bool ) + */ + bool IsSameDirectionAs(XZigZagPivot &item) + { + // + bool result = false; + + // + result = + IsValid() && + item.IsValid() && + dir == item.dir; + + // + return result; + } + // // Logging Tools ... @@ -428,22 +567,11 @@ struct XZigZagAnalysis string symbol; // Symbol ... datetime time; // Time ... ENUM_TIMEFRAMES period; // Period ... - XZigZagPoint pivots[]; // ZigZag Pivots ... + XZigZagPivot pivots[]; // ZigZag Pivots ... // ENUM_X_DIRECTION dir; // Direction ... - // - // Pivots ... - - // - XZigZagPoint lastPeak; - XZigZagPoint recentPeak; - - // - XZigZagPoint lastVale; - XZigZagPoint recentVale; - // // Constructor ... XZigZagAnalysis() @@ -458,13 +586,13 @@ struct XZigZagAnalysis * Analyse Market Structure ... * * @param bar: XOHCL, Specified Bar ... - * @param points: XZigZagPoint, Specified ZigZag Points Collection ... + * @param _pivots: XZigZagPivot, Specified ZigZag Points Collection ... * * @return ( bool ) */ bool Analyse( XOHCL &bar, - XZigZagPoint &points[] // + XZigZagPivot &_pivots[] // ) { // @@ -473,8 +601,8 @@ struct XZigZagAnalysis // // Validate ... result = bar.IsValid() && - HasChild(points) && - bar.symbol == points[0].symbol; + HasChild(_pivots) && + bar.symbol == _pivots[0].symbol; if (!result) { // @@ -489,191 +617,83 @@ struct XZigZagAnalysis period = bar.period; // - // Detect At lease Two PEAK and Two Vale ... - XZigZagPoint tmpPoints[]; - Copy( - points, - tmpPoints // + // Extracting Pivots ... + int numberOfPivots = 2; + + // + // Reading Recent Peaks ... + XZigZagPivot recentPeaks[]; + int recentPeaksCount = GetRecent( + _pivots, + recentPeaks, + numberOfPivots, + X_ZIGZAG_PIVOT_TYPE_PEAK // ); // - // Detect Highs ... - - // - // Highest High ... - - // - XZigZagPoint iZGPeak1; - XZigZagPoint iZGPeak2; - - // - // First ... - int idx = GetHighest( - tmpPoints, - X_ZIGZAG_POINT_TYPE_PEAK // - ); - result = IsValidIndex(idx); - if (!result) - { - // - Clean(); - iZGPeak1.Clean(); - iZGPeak2.Clean(); - SpecifiedClean(tmpPoints); - - // - return result; - } - iZGPeak1 = tmpPoints[idx]; - ArrayRemove( - tmpPoints, - idx, - 1 // + // Reading Recent Vales ... + XZigZagPivot recentVales[]; + int recentValesCount = GetRecent( + _pivots, + recentVales, + numberOfPivots, + X_ZIGZAG_PIVOT_TYPE_VALE // ); // - // Second ... - idx = GetHighest( - tmpPoints, - X_ZIGZAG_POINT_TYPE_PEAK // - ); - result = IsValidIndex(idx); - if (!result) - { - // - Clean(); - iZGPeak1.Clean(); - iZGPeak2.Clean(); - SpecifiedClean(tmpPoints); - - // - return result; - } - iZGPeak2 = tmpPoints[idx]; - ArrayRemove( - tmpPoints, - idx, - 1 // - ); - - // - // Detect Lows ... - - // - XZigZagPoint iZGVale1; - XZigZagPoint iZGVale2; - - // - // First ... - idx = GetLowest( - tmpPoints, - X_ZIGZAG_POINT_TYPE_VALE // - ); - result = IsValidIndex(idx); - if (!result) - { - // - Clean(); - iZGPeak1.Clean(); - iZGPeak2.Clean(); - iZGVale1.Clean(); - iZGVale2.Clean(); - SpecifiedClean(tmpPoints); - - // - return result; - } - iZGVale1 = tmpPoints[idx]; - ArrayRemove( - tmpPoints, - idx, - 1 // - ); - - // - // Second ... - idx = GetLowest( - tmpPoints, - X_ZIGZAG_POINT_TYPE_VALE // - ); - result = IsValidIndex(idx); - if (!result) - { - // - Clean(); - iZGPeak1.Clean(); - iZGPeak2.Clean(); - iZGVale1.Clean(); - iZGVale2.Clean(); - SpecifiedClean(tmpPoints); - - // - return result; - } - iZGVale2 = tmpPoints[idx]; - ArrayRemove( - tmpPoints, - idx, - 1 // - ); - - // - // Check Directions ... - bool isBullish = - // - (iZGPeak1.time > iZGPeak2.time && - iZGVale1.time < iZGVale2.time) - // - ; - bool isBearish = - // - (iZGPeak1.time < iZGPeak2.time && - iZGVale1.time > iZGVale2.time) - // - ; + // Validate Pivots ... result = - (isBullish && !isBearish) || - (isBearish && !isBullish); + recentPeaksCount >= numberOfPivots && + recentValesCount >= numberOfPivots; if (!result) { // Clean(); - iZGPeak1.Clean(); - iZGPeak2.Clean(); - iZGVale1.Clean(); - iZGVale2.Clean(); - SpecifiedClean(tmpPoints); + SpecifiedClean(recentPeaks); + SpecifiedClean(recentVales); + + // + return result; + } + + // + // Detect Direction ... + + // + int zIdx = 0; + int pIdx = numberOfPivots - 1; + + // + bool isBullish = + recentPeaks[zIdx].value > recentPeaks[pIdx].value && + recentVales[zIdx].value > recentVales[pIdx].value; + + // + bool isBearish = + recentPeaks[zIdx].value < recentPeaks[pIdx].value && + recentVales[zIdx].value < recentVales[pIdx].value; + + // + result = isBullish || isBearish; + if (!result) + { + // + Clean(); + SpecifiedClean(recentPeaks); + SpecifiedClean(recentVales); // return result; } // - // Setting Direction ... dir = isBullish ? X_DIRECTION_BULLISH - : isBearish - ? X_DIRECTION_BEARISH - : X_DIRECTION_NONE; + : X_DIRECTION_BEARISH; // - // Setting Points ... - Copy( - points, - pivots // - ); - - // - // Assigning Peaks and Vales ... - if (result) - { - // - lastPeak = iZGPeak1; - lastVale = iZGVale1; - recentPeak = iZGPeak2; - recentVale = iZGVale2; - } + Copy(_pivots, pivots); // // Calculate Support and Resistance ... @@ -687,12 +707,8 @@ struct XZigZagAnalysis } // - // Cleanup Resources ... - iZGPeak1.Clean(); - iZGPeak2.Clean(); - iZGVale1.Clean(); - iZGVale2.Clean(); - SpecifiedClean(tmpPoints); + SpecifiedClean(recentPeaks); + SpecifiedClean(recentVales); // return result; @@ -713,12 +729,6 @@ struct XZigZagAnalysis dir = X_DIRECTION_NONE; SpecifiedClean(pivots); - // - lastPeak.Clean(); - lastVale.Clean(); - recentPeak.Clean(); - recentVale.Clean(); - // ZeroMemory(this); } @@ -740,12 +750,7 @@ struct XZigZagAnalysis HasDirection(dir) && IsSpecifiedValid(time) && IsSpecifiedValid(symbol) && - IsSpecifiedValid(period) && - // - lastPeak.IsValid() && - lastVale.IsValid() && - recentPeak.IsValid() && - recentVale.IsValid() + IsSpecifiedValid(period) // ; @@ -792,6 +797,42 @@ struct XZigZagAnalysis return result; } + /** + * Check Market Direction is Bullish or not ... + * + * @return ( bool ) + */ + bool IsBullish() + { + // + bool result = false; + + // + result = IsValid() && + IsSpecifiedBullish(dir); + + // + return result; + } + + /** + * Check Market Direction is Bearish or not ... + * + * @return ( bool ) + */ + bool IsBearish() + { + // + bool result = false; + + // + result = IsValid() && + IsSpecifiedBearish(dir); + + // + return result; + } + /** * Check two item is Same or not ... * @@ -927,6 +968,280 @@ struct XZigZagAnalysis return result; } + // + // Pivots Tools ... + + /** + * Get Highest Specified Pivot ... + * + * @param type: ENUM_X_ZIGZAG_POINT_TYPE, Specified Pivot Type ... + * + * @return ( int ) + */ + int GetHighestPivot( + ENUM_X_ZIGZAG_POINT_TYPE type = X_ZIGZAG_PIVOT_TYPE_NONE // + ) + { + // + int result = -1; + + // + if (!IsValid()) + { + return result; + } + + // + bool has = false; + XZigZagPivot iPivot; + int count = ArraySize(pivots); + for (int i = 0; i < count; i++) + { + // + // Check Type ... + has = + !IsXValid(type) || + (IsXValid(type) && + type == pivots[i].type); + if (!has) + { + continue; + } + + // + // Check Relation based on last Detected Pivot ... + has = !iPivot.IsValid() || + (iPivot.IsValid() && + iPivot.value < pivots[i].value); + if (has) + { + // + result = i; + iPivot = pivots[i]; + } + } + + // + has = + iPivot.IsValid() && + IsValidIndex(result); + iPivot.Clean(); + + // + return result; + } + + /** + * Get Lowest Specified Pivot ... + * + * @param type: ENUM_X_ZIGZAG_POINT_TYPE, Specified Pivot Type ... + * + * @return ( int ) + */ + int GetLowestPivot( + ENUM_X_ZIGZAG_POINT_TYPE type = X_ZIGZAG_PIVOT_TYPE_NONE // + ) + { + // + int result = -1; + + // + if (!IsValid()) + { + return result; + } + + // + bool has = false; + XZigZagPivot iPivot; + int count = ArraySize(pivots); + for (int i = 0; i < count; i++) + { + // + // Check Type ... + has = + !IsXValid(type) || + (IsXValid(type) && + type == pivots[i].type); + if (!has) + { + continue; + } + + // + // Check Relation based on last Detected Pivot ... + has = !iPivot.IsValid() || + (iPivot.IsValid() && + iPivot.value > pivots[i].value); + if (has) + { + // + result = i; + iPivot = pivots[i]; + } + } + + // + has = + iPivot.IsValid() && + IsValidIndex(result); + iPivot.Clean(); + + // + return result; + } + + /** + * Get Oldest Specified Pivot ... + * + * @param type: ENUM_X_ZIGZAG_POINT_TYPE, Specified Pivot Type ... + * + * @return ( int ) + */ + int GetOldestPivot( + ENUM_X_ZIGZAG_POINT_TYPE type = X_ZIGZAG_PIVOT_TYPE_NONE // + ) + { + // + int result = -1; + + // + if (!IsValid()) + { + return result; + } + + // + bool has = false; + XZigZagPivot iPivot; + int count = ArraySize(pivots); + for (int i = 0; i < count; i++) + { + // + // Check Type ... + has = + !IsXValid(type) || + (IsXValid(type) && + type == pivots[i].type); + if (!has) + { + continue; + } + + // + // Check Relation based on last Detected Pivot ... + has = !iPivot.IsValid() || + (iPivot.IsValid() && + iPivot.time > pivots[i].time); + if (has) + { + // + result = i; + iPivot = pivots[i]; + } + } + + // + has = + iPivot.IsValid() && + IsValidIndex(result); + iPivot.Clean(); + + // + return result; + } + + /** + * Get Youngest Specified Pivot ... + * + * @param type: ENUM_X_ZIGZAG_POINT_TYPE, Specified Pivot Type ... + * + * @return ( int ) + */ + int GetYoungestPivot( + ENUM_X_ZIGZAG_POINT_TYPE type = X_ZIGZAG_PIVOT_TYPE_NONE // + ) + { + // + int result = -1; + + // + // Validate ... + if (!IsValid()) + { + return result; + } + + // + bool has = false; + XZigZagPivot iPivot; + int count = ArraySize(pivots); + for (int i = 0; i < count; i++) + { + // + // Check Type ... + has = + !IsXValid(type) || + (IsXValid(type) && + type == pivots[i].type); + if (!has) + { + continue; + } + + // + // Check Relation based on last Detected Pivot ... + has = !iPivot.IsValid() || + (iPivot.IsValid() && + iPivot.time > pivots[i].time); + if (has) + { + // + result = i; + iPivot = pivots[i]; + } + } + + // + has = + iPivot.IsValid() && + IsValidIndex(result); + iPivot.Clean(); + + // + return result; + } + + /** + * Get Recent Number of Specified Type of Pivots ... + * + * @param recent: XZigZagPivot, Collection reference as result ... + * @param numberOfRequiredPivots: int, required number of Pivots ... + * @param type: ENUM_X_ZIGZAG_POINT_TYPE, type of Pivot ... + * + * @return ( int ) + */ + int GetRecentPivots( + XZigZagPivot &recent[], + int numberOfRequiredPivots = 2, + ENUM_X_ZIGZAG_POINT_TYPE type = X_ZIGZAG_PIVOT_TYPE_NONE // + ) + { + // + int result = -1; + + // + result = GetRecent( + pivots, + recent, + numberOfRequiredPivots, + type // + ); + + // + return result; + } + // // Loggint Tools ... @@ -1004,20 +1319,276 @@ struct XZigZagAnalysis // }; +/** + * XZigZagAnalysis Chart Object ... + **/ +class XCZigZagAnalysisObject : public XCBaseObject +{ + // + public: + // + + /** + * Create Object ... + * + * @param chart_id: Long, Specified Chart ID ... + * @param window: Integer, Specified Chart Window ID ... + * @param model: XZigZagAnalysis, reference model ... + * + * @return ( bool ) + */ + bool Create( + long chart_id, + int window, + XZigZagAnalysis &model, + int numberOfPivots = 2 // + ) + { + // + bool result = false; + + // + // Normalize ... + numberOfPivots = NormalizeInt(numberOfPivots, 2); + + // + // Validate ... + result = model.IsValid(); + if (!result) + { + return result; + } + + // + // Generate Object ID ... + string objID = model.GetObjectID(); + string upperName = "Upper_" + objID; + string lowerName = "Lower_" + objID; + + // + // Extract Recent Pivots ... + + // + // Peaks ... + XZigZagPivot rPeaks[]; + int count = model.GetRecentPivots( + rPeaks, + numberOfPivots, + X_ZIGZAG_PIVOT_TYPE_PEAK // + ); + + // + // Vales ... + XZigZagPivot rVales[]; + count = model.GetRecentPivots( + rVales, + numberOfPivots, + X_ZIGZAG_PIVOT_TYPE_VALE // + ); + + // + // Creating Upper ... + result = mUpper.Create( + chart_id, + upperName, + window, + rPeaks[0].time, + rPeaks[0].value, + rPeaks[numberOfPivots - 1].time, + rPeaks[numberOfPivots - 1].value // + ); + if (!result) + { + return result; + } + + // + // Create Lower ... + result = mLower.Create( + chart_id, + lowerName, + window, + rVales[0].time, + rVales[0].value, + rVales[numberOfPivots - 1].time, + rVales[numberOfPivots - 1].value // + ); + if (!result) + { + // + mUpper.Detach(); + mUpper.Delete(); + + // + return result; + } + + // + // Setting Object Name ... + if (result) + { + ObjName(objID); + } + + // + return result; + } + + // + // Virtuals ... + + /** + * Retrieve Object Type ... + * + * @return ( ENUM_XCHARTOBJECTS ) + */ + virtual int Type() + { + return 9860; + } + + // + // Styling ... + + /** + * Set Width ... + * + * @param value: Integer ... + */ + void UpperWidth(int value) + { + // + if (value < 1) + { + value = 1; + } + + // + mUpper.Width(value); + } + + /** + * Set Color ... + * + * @param value: Color ... + */ + void UpperColor(color value) + { + // + mUpper.Color(value); + } + + /** + * Set Style ... + * + * @param value: ENUM_LINE_STYLE member ... + */ + void UpperStyle(ENUM_LINE_STYLE value) + { + // + mUpper.Style(value); + } + + /** + * Specified Upper Ray to Left or not ... + * + * @param value: bool + */ + void UpperRayLeft(bool value) + { + mUpper.RayLeft(value); + } + + /** + * Specified Upper Ray to Right or not ... + * + * @param value: bool + */ + void UpperRayRight(bool value) + { + mUpper.RayRight(value); + } + + /** + * Set Width ... + * + * @param value: Integer ... + */ + void LowerWidth(int value) + { + // + if (value < 1) + { + value = 1; + } + + // + mLower.Width(value); + } + + /** + * Set Color ... + * + * @param value: Color ... + */ + void LowerColor(color value) + { + // + mLower.Color(value); + } + + /** + * Set Style ... + * + * @param value: ENUM_LINE_STYLE member ... + */ + void LowerStyle(ENUM_LINE_STYLE value) + { + // + mLower.Style(value); + } + + /** + * Specified Lower Ray to Left or not ... + * + * @param value: bool + */ + void LowerRayLeft(bool value) + { + mLower.RayLeft(value); + } + + /** + * Specified Lower Ray to Right or not ... + * + * @param value: bool + */ + void LowerRayRight(bool value) + { + mLower.RayRight(value); + } + + // + private: + // + CChartObjectTrend mUpper; + CChartObjectTrend mLower; +}; + // // Extensions ... /** * Get Highest ZigZagPoint Index in Specified Collection ... * - * @param items: XZigZagPoint, Specified Points Collection to Search ... + * @param items: XZigZagPivot, Specified Points Collection to Search ... * @param type: ENUM_X_ZIGZAG_POINT_TYPE, Specified Points Type ... * * @return ( int ) */ int GetHighest( - XZigZagPoint &items[], - ENUM_X_ZIGZAG_POINT_TYPE type = X_ZIGZAG_POINT_TYPE_NONE // + XZigZagPivot &items[], + ENUM_X_ZIGZAG_POINT_TYPE type = X_ZIGZAG_PIVOT_TYPE_NONE // ) { // @@ -1032,7 +1603,7 @@ int GetHighest( // bool has = false; - XZigZagPoint iPoint; + XZigZagPivot iPoint; int count = ArraySize(items); for (int i = 0; i < count; i++) { @@ -1080,14 +1651,14 @@ int GetHighest( /** * Get Lowest ZigZagPoint Index in Specified Collection ... * - * @param items: XZigZagPoint, Specified Points Collection to Search ... + * @param items: XZigZagPivot, Specified Points Collection to Search ... * @param type: ENUM_X_ZIGZAG_POINT_TYPE, Specified Points Type ... * * @return ( int ) */ int GetLowest( - XZigZagPoint &items[], - ENUM_X_ZIGZAG_POINT_TYPE type = X_ZIGZAG_POINT_TYPE_NONE // + XZigZagPivot &items[], + ENUM_X_ZIGZAG_POINT_TYPE type = X_ZIGZAG_PIVOT_TYPE_NONE // ) { // @@ -1102,7 +1673,7 @@ int GetLowest( // bool has = false; - XZigZagPoint iPoint; + XZigZagPivot iPoint; int count = ArraySize(items); for (int i = 0; i < count; i++) { @@ -1147,4 +1718,260 @@ int GetLowest( return result; } +/** + * Get Oldest ZigZagPoint Index in Specified Collection ... + * + * @param items: XZigZagPivot, Specified Points Collection to Search ... + * @param type: ENUM_X_ZIGZAG_POINT_TYPE, Specified Points Type ... + * + * @return ( int ) + */ +int GetOldest( + XZigZagPivot &items[], + ENUM_X_ZIGZAG_POINT_TYPE type = X_ZIGZAG_PIVOT_TYPE_NONE // +) +{ + // + int result = -1; + + // + // Validate ... + if (!HasChild(items)) + { + return result; + } + + // + bool has = false; + XZigZagPivot iPoint; + int count = ArraySize(items); + for (int i = 0; i < count; i++) + { + // + // Passed Type ... + has = !IsXValid(type) + ? true + : type == items[i].type; + + // + // Check Can Assign ... + has = + has && + (!iPoint.IsValid() || + (iPoint.IsValid() && + items[i].GetAge() > iPoint.GetAge())); + if (has) + { + // + result = i; + iPoint = items[i]; + } + } + + // + // Validate Result ... + has = + iPoint.IsValid() && + IsValidIndex(result); + if (!has) + { + // + result = -1; + iPoint.Clean(); + return result; + } + + // + iPoint.Clean(); + + // + return result; +} + +/** + * Get Youngest ZigZagPoint Index in Specified Collection ... + * + * @param items: XZigZagPivot, Specified Points Collection to Search ... + * @param type: ENUM_X_ZIGZAG_POINT_TYPE, Specified Points Type ... + * + * @return ( int ) + */ +int GetYoungest( + XZigZagPivot &items[], + ENUM_X_ZIGZAG_POINT_TYPE type = X_ZIGZAG_PIVOT_TYPE_NONE // +) +{ + // + int result = -1; + + // + // Validate ... + if (!HasChild(items)) + { + return result; + } + + // + bool has = false; + XZigZagPivot iPoint; + int count = ArraySize(items); + for (int i = 0; i < count; i++) + { + // + // Passed Type ... + has = !IsXValid(type) + ? true + : type == items[i].type; + + // + // Check Can Assign ... + has = + has && + (!iPoint.IsValid() || + (iPoint.IsValid() && + items[i].GetAge() < iPoint.GetAge())); + if (has) + { + // + result = i; + iPoint = items[i]; + } + } + + // + // Validate Result ... + has = + iPoint.IsValid() && + IsValidIndex(result); + if (!has) + { + // + result = -1; + iPoint.Clean(); + return result; + } + + // + iPoint.Clean(); + + // + return result; +} + +/** + * Get Recent Number of Specified Type of Pivots ... + * + * @param source: XZigZagPivot, Collection reference as Data Source ... + * @param recent: XZigZagPivot, Collection reference as result ... + * @param numberRequiredItems: int, required number of Pivots ... + * @param type: ENUM_X_ZIGZAG_POINT_TYPE, type of Pivot ... + * + * @return ( int ) + */ +int GetRecent( + XZigZagPivot &source[], + XZigZagPivot &recent[], + int numberRequiredItems = 2, + ENUM_X_ZIGZAG_POINT_TYPE type = X_ZIGZAG_PIVOT_TYPE_NONE // +) +{ + // + int result = 0; + + // + int idx = -1; + bool has = false; + + // + // Prepare ... + SpecifiedClean(recent); + + // + // Normalize ... + numberRequiredItems = NormalizeInt(numberRequiredItems, 1); + + // + result = ArraySize(recent); + + // + XZigZagPivot tmp[]; + Copy( + source, + tmp // + ); + + // + // Looping to Detect Recent Pivots ... + XZigZagPivot iPoint; + while (ArraySize(tmp) > 0 && + ArraySize(recent) < numberRequiredItems) + { + // + // Find Youngest of Type Index ... + idx = GetYoungest( + tmp, + type // + ); + has = IsValidIndex(idx); + if (!has) + { + continue; + } + + // + // Extract Item ... + iPoint = tmp[idx]; + + // + // Remove Item ... + ArrayRemove( + tmp, + idx, + 1 // + ); + + // + // Validate Item and Add it to Recent ... + has = iPoint.IsValid(); + if (has) + { + // + AddRef( + iPoint, + recent // + ); + } + + // + // Check For Breaking Loop ... + + // + // If Detect Recent is Passed ... + has = ArraySize(recent) == numberRequiredItems; + if (has) + { + break; + } + + // + // If not anymore items ... + has = ArraySize(tmp) > 0; + if (!has) + { + break; + } + } + + // + result = ArraySize(recent); + + // + // Cleanup Resources ... + iPoint.Clean(); + SpecifiedClean(tmp); + + // + return result; +} + // \ No newline at end of file