diff --git a/Classes/x-saherelm.x-cobject.class.mq5 b/Classes/x-saherelm.x-cobject.class.mq5 index 7a10fbf6..3ab50daa 100644 --- a/Classes/x-saherelm.x-cobject.class.mq5 +++ b/Classes/x-saherelm.x-cobject.class.mq5 @@ -1468,6 +1468,8 @@ class XCPivotAnalysisObject : public XCBaseObject * @param chart_id: Long, Specified Chart ID ... * @param window: Integer, Specified Chart Window ID ... * @param model: XPivotAnalysis, reference model ... + * @param drawTrends: Specified to Draw Trends or not ... + * @param drawZones: Specified to Draw Support and Resistance Zones or not ... * @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 ... @@ -1479,6 +1481,8 @@ class XCPivotAnalysisObject : public XCBaseObject long chart_id, int window, XPivotAnalysis &model, + bool drawTrends = true, + bool drawZones = true, bool drawPivots = true, int peakArrow = 159, int valeArrow = 159, @@ -1502,91 +1506,138 @@ class XCPivotAnalysisObject : public XCBaseObject // // Generate Object ID ... string objID = model.GetObjectID(); - string upperName = model.GetUpperObjectID(); - string lowerName = model.GetLowerObjectID(); // - // Extract Recent Pivots ... - - // - // Creating Upper ... - result = mUpper.Create( - chart_id, - upperName, - window, - model.fromTime, - model.peakFrom, - model.toTime, - model.peakTo // - ); - if (!result) + // Draw Trend Lines ... + mUpper = NULL; + mLower = NULL; + if (drawTrends) { - return result; + // + string upperName = model.GetUpperObjectID(); + string lowerName = model.GetLowerObjectID(); + + // + RemoveObjects(upperName, chart_id, window); + RemoveObjects(lowerName, chart_id, window); + + // + // Creating Upper ... + mUpper = new CChartObjectTrend(); + result = mUpper.Create( + chart_id, + upperName, + window, + model.fromTime, + model.peakFrom, + model.toTime, + model.peakTo // + ); + if (!result) + { + // + // Destroy Trending Objects ... + DestroyObject(mUpper); + DestroyObject(mLower); + + // + return result; + } + + // + // Create Lower ... + mLower = new CChartObjectTrend(); + result = mLower.Create( + chart_id, + lowerName, + window, + model.fromTime, + model.valeFrom, + model.toTime, + model.valeTo // + ); + if (!result) + { + // + // Destroy Trending Objects ... + DestroyObject(mUpper); + DestroyObject(mLower); + + // + return result; + } } // - // Create Lower ... - result = mLower.Create( - chart_id, - lowerName, - window, - model.fromTime, - model.valeFrom, - model.toTime, - model.valeTo // - ); - if (!result) - { - // - mUpper.Detach(); - mUpper.Delete(); - - // - return result; - } - - // - // Support ... - XBoxZone tmpBox; + // Draw Zones ... mSupportBox = NULL; - has = model.HasSupportBox(tmpBox); - if (has) - { - // - datetime to = TimeCurrent(); - string name = model.GetSupportBoxObjectID(); - mSupportBox = new XCBoxObject(); - has = mSupportBox.Create( - chart_id, - window, - name, - tmpBox.upper, - tmpBox.lower, - tmpBox.from, - to // - ); - } - - // - // Resistance ... - tmpBox.Clean(); mResistanceBox = NULL; - has = model.HasResistanceBox(tmpBox); - if (has) + if (drawZones) { // - datetime to = TimeCurrent(); - string name = model.GetResistanceBoxObjectID(); - mResistanceBox = new XCBoxObject(); - has = mResistanceBox.Create( - chart_id, - window, - name, - tmpBox.upper, - tmpBox.lower, - tmpBox.from, - to // - ); + // Support ... + XBoxZone tmpBox; + has = model.HasSupportBox(tmpBox); + if (has) + { + // + datetime to = TimeCurrent(); + string name = model.GetSupportBoxObjectID(); + RemoveObjects(name, chart_id, window); + mSupportBox = new XCBoxObject(); + result = mSupportBox.Create( + chart_id, + window, + name, + tmpBox.upper, + tmpBox.lower, + tmpBox.from, + to // + ); + if (!result) + { + // + DestroyObject(mUpper); + DestroyObject(mLower); + DestroyObject(mSupportBox); + + // + return result; + } + } + + // + // Resistance ... + tmpBox.Clean(); + has = model.HasResistanceBox(tmpBox); + if (has) + { + // + datetime to = TimeCurrent(); + string name = model.GetResistanceBoxObjectID(); + RemoveObjects(name, chart_id, window); + mResistanceBox = new XCBoxObject(); + result = mResistanceBox.Create( + chart_id, + window, + name, + tmpBox.upper, + tmpBox.lower, + tmpBox.from, + to // + ); + if (!result) + { + // + DestroyObject(mUpper); + DestroyObject(mLower); + DestroyObject(mSupportBox); + DestroyObject(mResistanceBox); + + // + return result; + } + } } // @@ -1615,6 +1666,7 @@ class XCPivotAnalysisObject : public XCBaseObject ? peakArrow : valeArrow; name = model.pivots[i].GetObjectID(); + RemoveObjects(name, chart_id, window); type = model.pivots[i].IsPeak() ? X_PRICE_HIGH : X_PRICE_LOW; @@ -1686,6 +1738,8 @@ class XCPivotAnalysisObject : public XCBaseObject Delete(); // + DestroyObject(mUpper); + DestroyObject(mLower); DestroyObject(mSupportBox); DestroyObject(mResistanceBox); } @@ -1706,6 +1760,12 @@ class XCPivotAnalysisObject : public XCBaseObject value = 1; } + // + if (mUpper == NULL) + { + return; + } + // mUpper.Width(value); } @@ -1717,6 +1777,12 @@ class XCPivotAnalysisObject : public XCBaseObject */ void UpperColor(color value) { + // + if (mUpper == NULL) + { + return; + } + // mUpper.Color(value); } @@ -1728,6 +1794,12 @@ class XCPivotAnalysisObject : public XCBaseObject */ void UpperStyle(ENUM_LINE_STYLE value) { + // + if (mUpper == NULL) + { + return; + } + // mUpper.Style(value); } @@ -1739,6 +1811,13 @@ class XCPivotAnalysisObject : public XCBaseObject */ void UpperRayLeft(bool value) { + // + if (mUpper == NULL) + { + return; + } + + // mUpper.RayLeft(value); } @@ -1749,6 +1828,13 @@ class XCPivotAnalysisObject : public XCBaseObject */ void UpperRayRight(bool value) { + // + if (mUpper == NULL) + { + return; + } + + // mUpper.RayRight(value); } @@ -1765,6 +1851,12 @@ class XCPivotAnalysisObject : public XCBaseObject value = 1; } + // + if (mLower == NULL) + { + return; + } + // mLower.Width(value); } @@ -1776,6 +1868,12 @@ class XCPivotAnalysisObject : public XCBaseObject */ void LowerColor(color value) { + // + if (mLower == NULL) + { + return; + } + // mLower.Color(value); } @@ -1787,6 +1885,12 @@ class XCPivotAnalysisObject : public XCBaseObject */ void LowerStyle(ENUM_LINE_STYLE value) { + // + if (mLower == NULL) + { + return; + } + // mLower.Style(value); } @@ -1798,6 +1902,13 @@ class XCPivotAnalysisObject : public XCBaseObject */ void LowerRayLeft(bool value) { + // + if (mLower == NULL) + { + return; + } + + // mLower.RayLeft(value); } @@ -1808,6 +1919,13 @@ class XCPivotAnalysisObject : public XCBaseObject */ void LowerRayRight(bool value) { + // + if (mLower == NULL) + { + return; + } + + // mLower.RayRight(value); } @@ -2100,8 +2218,8 @@ class XCPivotAnalysisObject : public XCBaseObject // CArrayObj mPeaks; CArrayObj mVales; - CChartObjectTrend mUpper; - CChartObjectTrend mLower; + CChartObjectTrend *mUpper; + CChartObjectTrend *mLower; XCBoxObject *mSupportBox; XCBoxObject *mResistanceBox; }; @@ -2137,14 +2255,16 @@ void AddObjects( /** * Destroy Object if Exists ... - * + * * @param object: pointer refrence to Destroy ... */ -void DestroyObject(XCBoxObject *&object) { +void DestroyObject(XCBoxObject *&object) +{ // // Validate ... bool has = object != NULL; - if (!has) { + if (!has) + { return; } @@ -2162,14 +2282,16 @@ void DestroyObject(XCBoxObject *&object) { /** * Destroy Object if Exists ... - * + * * @param object: pointer refrence to Destroy ... */ -void DestroyObject(XCPivotAnalysisObject *&object) { +void DestroyObject(XCPivotAnalysisObject *&object) +{ // // Validate ... bool has = object != NULL; - if (!has) { + if (!has) + { return; } @@ -2185,4 +2307,82 @@ void DestroyObject(XCPivotAnalysisObject *&object) { ZeroMemory(object); } +/** + * Destroy Object if Exists ... + * + * @param object: pointer refrence to Destroy ... + */ +void DestroyObject(CChartObjectTrend *&object) +{ + // + // Validate ... + bool has = object != NULL; + if (!has) + { + return; + } + + // + object.Detach(); + object.Delete(); + + // + delete object; + ZeroMemory(object); +} + +/** + * Remove Drawn Objects from Chart ... + * + * @param tag: Specified Object Name, if NULL remove all Objects ... + * @param chartId: long, Specified Chart ... + * @param subWindow: int Specified Sub Window ... + */ +void RemoveObjects( + string tag = NULL, + long chartId = -1, + int subWindow = -1 // +) +{ + // + // Normalize Args ... + + // + if (chartId == -1) + { + chartId = 0; + } + + // + if (subWindow == -1) + { + subWindow = 0; + } + + // + bool has = false; + string iName = NULL; + for (int iObj = ObjectsTotal(chartId, subWindow) - 1; iObj >= 0; iObj--) + { + // + // Retrieve Object Name ... + iName = ObjectName(chartId, iObj, subWindow); + + // + // Check Can Delete Object or not ... + has = + !IsSpecifiedValid(tag) + ? true + : StringFind(iName, tag) >= 0; + if (has) + { + ObjectDelete(chartId, iName); + } + } + + // + // Redraw Chart ... + ChartRedraw(); +} + // \ No newline at end of file diff --git a/Classes/x-saherelm.x-poi.drawer.class.mq5 b/Classes/x-saherelm.x-poi.drawer.class.mq5 index b4e03af8..2ebac09a 100644 --- a/Classes/x-saherelm.x-poi.drawer.class.mq5 +++ b/Classes/x-saherelm.x-poi.drawer.class.mq5 @@ -835,6 +835,7 @@ class XCPOIDrawer : public XCBase ulong chartId = ChartIdentification(); int subWindow = SubWindowIdentification(); string name = ToXString(dir) + "_Trend_" + ToXString(price1) + "_" + ToXString(price2); + RemoveObjects("_Trend_", chartId, subWindow); // object = new CChartObjectTrend(); @@ -872,6 +873,8 @@ class XCPOIDrawer : public XCBase * * @param analysis: XPivotAnalysis, referece Specified Pivot Analysis ... * @param object: XCPivotAnalysisObject, pointer reference for Drawn Object ... + * @param drawTrends: Specified to Draw Trends or not ... + * @param drawZones: Specified to Draw Support and Resistance Zones or not ... * @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 ... @@ -882,6 +885,8 @@ class XCPOIDrawer : public XCBase bool DrawPivotAnalysis( XPivotAnalysis &analysis, XCPivotAnalysisObject *&object, + bool drawTrends = true, + bool drawZones = true, bool drawPivots = true, int peakArrow = 159, int valeArrow = 159, @@ -913,6 +918,8 @@ class XCPOIDrawer : public XCBase ChartIdentification(), SubWindowIdentification(), analysis, + drawTrends, + drawZones, drawPivots, peakArrow, valeArrow, diff --git a/Documents/BKP/tmp.backtester.codes.mq5 b/Documents/BKP/tmp.backtester.codes.mq5 index 2745b592..18634326 100644 --- a/Documents/BKP/tmp.backtester.codes.mq5 +++ b/Documents/BKP/tmp.backtester.codes.mq5 @@ -993,23 +993,237 @@ if (has) ////////////////////////////////////////////////////////// +// +XOHCL pBar; +bool has = cBar.GetPreviousBar(pBar); +if (marketStructure.isPTest) +{ + // + // Check For PrevZoneExistanse ... + has = marketStructure.pTestedZone.IsValid(); + if (has) + { + // + // Draw Prev Zone ... + XCBoxObject *iPrevZoneObj; + marketStructure.pTestedZone.to = pBar.time; + has = fima2Signaller.poiDrawer.DrawBox( + marketStructure.pTestedZone, + iPrevZoneObj // + ); + if (has) + { + // + XPOIStyle style; + fima2Signaller.poiDrawer.GetBoxStyle( + style, + marketStructure.pTestedZone.dir // + ); + style.clr = clrYellow; + fima2Signaller.poiDrawer.ApplyBoxStyle( + iPrevZoneObj, + style // + ); + + // + style.Clean(); + eaDraws.Add(iPrevZoneObj); + } + } // + Print("Previous Tested ..."); +} +pBar.Clean(); + +///////////////////////////////////////////////////////////// + +// +// Previous Bar must Has Support or Resistance ... + +// +// Check Supports ... +idx = GetYoungestBefore( + pForBar.time, + supports // +); +has = + pForBar.IsValid() && + IsValidIndex(idx); +if (has) +{ + pSupport = supports[idx]; +} + +// +// Check Resistances ... +idx = GetYoungestBefore( + pForBar.time, + resistances // +); +has = + pForBar.IsValid() && + IsValidIndex(idx); +if (has) +{ + pResistance = resistances[idx]; +} + +// +bool isPSupportTouched = + pSupport.IsValid() && + pForBar.low < pSupport.upper; + +// +bool isPResistanceTouched = + pResistance.IsValid() && + pForBar.high > pResistance.lower; + +// +has = + isPSupportTouched || + isPResistanceTouched; +structure.isPTest = has; +if (has) +{ + // + if (isPSupportTouched) + { + // + // Validate Previously Tested Zone Price ... + structure.pTestedZone = pSupport; + } + else if (isPResistanceTouched) + { + // + // Validate Previously Tested Zone Price ... + structure.pTestedZone = pResistance; + } + + // +} + +///////////////////////////////////////////////////////////// + +// // +// // Here We Apply Custom Detecting ... +// detectorConfig.OffDetectors(); +// detectorConfig.detectSupport = true; +// detectorConfig.detectResistance= true; +// detectorConfig.detectSignalKeyBarPattern = true; + +// // +// // Initial Bar for Analysis ... +// // at Signal Time ... +// XOHCL signalBar; +// bool isInited = signalBar.Init( +// signal.symbol, +// signal.period, +// signal.time // +// ); + +// // +// // Analyse Market ... +// fima1Signaller.poiDetector.AnalyseMarket( +// signalBar, +// marketStructure, +// detectorConfig // +// ); +// CArrayObj *iObjects; +// int drawnsCount = fima2Signaller.poiDrawer.DrawMarketStructure( +// marketStructure, +// marketStructureDrawerConfig, +// iObjects // +// ); +// if (IsValidSize(drawnsCount)) +// { +// // +// AddObjects( +// iObjects, +// eaDraws // +// ); +// } + +///////////////////////////////////////////////////////////// + +// +// On Tick Handler ... +void OnTick() +{ + // + eaIsNewBar = eaBarTracker.IsNewBar(); + bool canProcess = eaProcessAllTicks + ? true + : eaIsNewBar; + // + eaExpert.HandleOnTick(); + + // + if (!canProcess) + { + return; + } + + // + fima1Signaller.OnTick(); + fima2Signaller.OnTick(); + + // + // Initial Bar for Analysis ... + XOHCL cBar; + bool isInited = cBar.Init( + _Symbol, + _Period, + 0 // + ); + + // + // Here We Apply Custom Detecting ... + detectorConfig.OffDetectors(); + detectorConfig.detectSupport = true; + detectorConfig.detectResistance = true; + detectorConfig.detectSignalKeyBarPattern = false; + detectorConfig.supportAndResistanceValidationLength = 21; + + // + // Analyse Market ... + fima2Signaller.poiDetector.AnalyseMarket( + cBar, + marketStructure, + detectorConfig // + ); + CArrayObj *iObjects; + int drawnsCount = fima2Signaller.poiDrawer.DrawMarketStructure( + marketStructure, + marketStructureDrawerConfig, + iObjects // + ); + if (IsValidSize(drawnsCount)) + { + // + AddObjects( + iObjects, + eaDraws // + ); + } + + // + // TODO: Remove this ... XOHCL pBar; bool has = cBar.GetPreviousBar(pBar); - if (marketStructure.isPTest) + if (marketStructure.fakeBreakedZone.IsValid()) { // // Check For PrevZoneExistanse ... - has = marketStructure.pTestedZone.IsValid(); + has = marketStructure.fakeBreakedZone.IsValid(); if (has) { // // Draw Prev Zone ... XCBoxObject *iPrevZoneObj; - marketStructure.pTestedZone.to = pBar.time; + marketStructure.fakeBreakedZone.to = pBar.time; has = fima2Signaller.poiDrawer.DrawBox( - marketStructure.pTestedZone, + marketStructure.fakeBreakedZone, iPrevZoneObj // ); if (has) @@ -1018,7 +1232,7 @@ if (has) XPOIStyle style; fima2Signaller.poiDrawer.GetBoxStyle( style, - marketStructure.pTestedZone.dir // + marketStructure.fakeBreakedZone.dir // ); style.clr = clrYellow; fima2Signaller.poiDrawer.ApplyBoxStyle( @@ -1033,124 +1247,30 @@ if (has) } // - Print("Previous Tested ..."); + Print("Fake Breaked Detection ..."); + } + if (HasChild(marketStructure.recentlyTestedZones)) + { + // + int idx = GetYoungest(marketStructure.recentlyTestedZones); + bool has = IsValidIndex(idx); + if (has) + { + // + has = IsTested( + pBar, + marketStructure.recentlyTestedZones[idx] // + ); + } + + // + if (has) + { + Print("PrevZone Exists ..."); + } } pBar.Clean(); - - -///////////////////////////////////////////////////////////// - - // - // Previous Bar must Has Support or Resistance ... - - // - // Check Supports ... - idx = GetYoungestBefore( - pForBar.time, - supports // - ); - has = - pForBar.IsValid() && - IsValidIndex(idx); - if (has) - { - pSupport = supports[idx]; - } - - // - // Check Resistances ... - idx = GetYoungestBefore( - pForBar.time, - resistances // - ); - has = - pForBar.IsValid() && - IsValidIndex(idx); - if (has) - { - pResistance = resistances[idx]; - } - - // - bool isPSupportTouched = - pSupport.IsValid() && - pForBar.low < pSupport.upper; - - // - bool isPResistanceTouched = - pResistance.IsValid() && - pForBar.high > pResistance.lower; - - // - has = - isPSupportTouched || - isPResistanceTouched; - structure.isPTest = has; - if (has) - { - // - if (isPSupportTouched) - { - // - // Validate Previously Tested Zone Price ... - structure.pTestedZone = pSupport; - } - else if (isPResistanceTouched) - { - // - // Validate Previously Tested Zone Price ... - structure.pTestedZone = pResistance; - } - - // - } - - -///////////////////////////////////////////////////////////// - - - - // // - // // Here We Apply Custom Detecting ... - // detectorConfig.OffDetectors(); - // detectorConfig.detectSupport = true; - // detectorConfig.detectResistance= true; - // detectorConfig.detectSignalKeyBarPattern = true; - - // // - // // Initial Bar for Analysis ... - // // at Signal Time ... - // XOHCL signalBar; - // bool isInited = signalBar.Init( - // signal.symbol, - // signal.period, - // signal.time // - // ); - - // // - // // Analyse Market ... - // fima1Signaller.poiDetector.AnalyseMarket( - // signalBar, - // marketStructure, - // detectorConfig // - // ); - // CArrayObj *iObjects; - // int drawnsCount = fima2Signaller.poiDrawer.DrawMarketStructure( - // marketStructure, - // marketStructureDrawerConfig, - // iObjects // - // ); - // if (IsValidSize(drawnsCount)) - // { - // // - // AddObjects( - // iObjects, - // eaDraws // - // ); - // } - - -///////////////////////////////////////////////////////////// - - + // + cBar.Clean(); +} diff --git a/Documents/BKP/x-tmp-market-analyser.codes.mq5 b/Documents/BKP/x-tmp-market-analyser.codes.mq5 new file mode 100644 index 00000000..14786e63 --- /dev/null +++ b/Documents/BKP/x-tmp-market-analyser.codes.mq5 @@ -0,0 +1,826 @@ + +/** + * Analyse Market based on Specified Bar ... + * + * @param forBar: XOHCL, reference Specified Bar for Analyse Market ... + * @param structure: XFIMAMarketStructure, reference to holds result ... + * @param config: XFIMAPatternDetectorConfig, reference to Configure Detector ... + */ +void AnalyseMarket( + XOHCL &forBar, + XFIMAMarketStructure &structure, + XFIMAPatternDetectorConfig &config // +) +{ + // + // Prepare ... + structure.Clean(); + + // + // Validate ... + if (!forBar.IsValid()) + { + return; + } + + // + // Do Analysis ... + + // + structure.bar = forBar; + + // + int idx = -1; + bool has = false; + int maxAllowedCollecting = 50; + ENUM_X_DIRECTION iDir = X_DIRECTION_NONE; + + // + // Detecting POI Based on Config ... + + // + // Order Block ... + if (config.detectOB) + { + // + bool isOB = HasOB( + forBar, + iDir, + structure.ob, + config.obLoopback // + ); + bool isBullishOB = isOB && + IsSpecifiedBullish(iDir); + bool isBearishOB = isOB && + IsSpecifiedBearish(iDir); + if (!isOB) + { + structure.ob.Clean(); + } + + // + // Detect Touches ... + if (isOB) + { + // + AddIfNotExists( + structure.ob, + obs, + maxAllowedCollecting // + ); + + // + XOHCL pBar; + bool has = forBar.GetPreviousBar(pBar); + if (has) + { + // + structure.isOBTouched = + isBullishOB + ? pBar.low < structure.ob.upper + : pBar.high > structure.ob.lower; + } + + // + pBar.Clean(); + } + } + + // + // Fair Value Gap ... + if (config.detectFVG) + { + // + bool isFVG = HasFVG( + forBar, + iDir, + structure.fvg, + config.fvgLoopback // + ); + bool isBullishFVG = isFVG && + IsSpecifiedBullish(iDir); + bool isBearishFVG = isFVG && + IsSpecifiedBearish(iDir); + if (!isFVG) + { + structure.fvg.Clean(); + } + + // + // Detect Touches ... + if (isFVG) + { + // + AddIfNotExists( + structure.fvg, + fvgs, + maxAllowedCollecting // + ); + + // + XOHCL pBar; + bool has = forBar.GetPreviousBar(pBar); + if (has) + { + // + structure.isFVGTouched = + isBullishFVG + ? pBar.low < structure.fvg.upper + : pBar.high > structure.fvg.lower; + } + + // + pBar.Clean(); + } + } + + // + // Checking Momentum Bar ... + if (config.detectMomentum) + { + // + bool isMomentum = IsMomentumBar( + forBar, + iDir, + config.momentumBarRangeLength, + config.momentumBarApprovedMultiplier // + ); + bool isBullishMomentum = isMomentum && + IsSpecifiedBullish(iDir); + bool isBearishMomentum = isMomentum && + IsSpecifiedBearish(iDir); + if (isMomentum) + { + structure.momentumDir = iDir; + } + } + + // + // Checking Engulfed Bar ... + if (config.detectEngulfed) + { + // + bool isEngulfed = IsEngulfedBar( + forBar, + iDir // + ); + bool isBullishEngulfed = isEngulfed && + IsSpecifiedBullish(iDir); + bool isBearishEngulfed = isEngulfed && + IsSpecifiedBearish(iDir); + if (isEngulfed) + { + structure.engulfedDir = iDir; + } + } + + // + // Checking TruGaped Bar ... + if (config.detectTrueGaped) + { + // + bool isTrueGaped = IsTrueGapedBar( + forBar, + iDir, + config.truwGapApprovedPointMultiplier // + ); + bool isBullishTrueGaped = isTrueGaped && + IsSpecifiedBullish(iDir); + bool isBearishTrueGaped = isTrueGaped && + IsSpecifiedBearish(iDir); + if (isTrueGaped) + { + structure.trueGapedDir = iDir; + } + } + + // + // Checking Pinned Bar ... + if (config.detectPinned) + { + // + bool isPinned = IsPinnedBar( + forBar, + iDir, + config.pinnedBaarShadowApprovedMultiplier, + config.pinnedBarMinimumPinBarRangeMultiplier, + config.pinnedBarForceDirection // + ); + bool isBullishPinned = isPinned && + IsSpecifiedBullish(iDir); + bool isBearishPinned = isPinned && + IsSpecifiedBearish(iDir); + if (isPinned) + { + structure.pinnedDir = iDir; + } + } + + // + // Checking Star Pattern ... + if (config.detectStarPattern) + { + // + bool isStarPattern = IsStartPattern( + forBar, + iDir // + ); + bool isBullishStarPattern = isStarPattern && + IsSpecifiedBullish(iDir); + bool isBearishStarPattern = isStarPattern && + IsSpecifiedBearish(iDir); + if (isStarPattern) + { + structure.starPatternDir = iDir; + } + } + + // + // Checking Piercing Pattern ... + if (config.detectPiercingPattern) + { + // + bool isPiercingPattern = IsPiercingPattern( + forBar, + iDir // + ); + bool isBullishPiercingPattern = isPiercingPattern && + IsSpecifiedBullish(iDir); + bool isBearishPiercingPattern = isPiercingPattern && + IsSpecifiedBearish(iDir); + if (isPiercingPattern) + { + structure.piercingPatternDir = iDir; + } + } + + // + // Checking Rising Pattern ... + if (config.detectRisingPattern) + { + // + bool isRisingPattern = IsRisingPattern( + forBar, + iDir // + ); + bool isBullishRisingPattern = isRisingPattern && + IsSpecifiedBullish(iDir); + bool isBearishRisingPattern = isRisingPattern && + IsSpecifiedBearish(iDir); + if (isRisingPattern) + { + structure.risingPatternDir = iDir; + } + } + + // + // Checking Flag Pattern ... + if (config.detectFlagPattern) + { + // + XOHCL swingBar; + bool isFlagPattern = IsFlagPattern( + forBar, + iDir, + swingBar, + config.flagPatternMinimumPullbackBars // + ); + bool isBullishFlagPattern = isFlagPattern && + IsSpecifiedBullish(iDir); + bool isBearishFlagPattern = isFlagPattern && + IsSpecifiedBearish(iDir); + if (isFlagPattern) + { + // + structure.flagSwing = swingBar; + structure.flagPatternDir = iDir; + } + swingBar.Clean(); + } + + // + // Detect SignalKey Bar Pattern ... + if (config.detectSignalKeyBarPattern) + { + // + bool isSignalKeyBar = IsSignalKeyBarPattern( + forBar, + iDir, + config.signalKeyBarShadowApprovedMultiplier, + config.signalKeyBarMinimumPinBarRangeMultiplier, + config.signalKeyBarForceDirection // + ); + bool isBullishSignalKeyBar = isSignalKeyBar && + IsSpecifiedBullish(iDir); + bool isBearishSignalKeyBar = isSignalKeyBar && + IsSpecifiedBearish(iDir); + if (isSignalKeyBar) + { + structure.signalKeyBarPatternDir = iDir; + } + } + + // + // Detect Swing Trend ... + if (config.detectSwingTrend) + { + // + XOHCL swings[]; + bool hasSwingTrend = HasSwingTrend( + forBar, + iDir, + swings, + config.trendingNumberOfSwings, + config.trendingSwingShoulders // + ); + bool hasBullishSwingTrend = hasSwingTrend && + IsSpecifiedBullish(iDir); + bool hasBearishSwingTrend = hasSwingTrend && + IsSpecifiedBearish(iDir); + if (hasSwingTrend) + { + // + Copy( + swings, + structure.trendSwings // + ); + structure.trendDir = iDir; + } + SpecifiedClean(swings); + } + + // + // Detect Supports ... + if (config.detectSupport) + { + // + XOHCL support; + bool hasSupport = HasSupport( + forBar, + support, + config.supportAndResistanceValidationLength, + config.supportAndResistanceMaxAllowedLoopback // + ); + if (hasSupport) + { + // + XBoxZone supportBox; + has = ToSupportBox(support, supportBox); + + // + // Validate Zone Strength if Provided ... + if (config.minAllowdSupportAndResistanceStrength > 0) + { + // + has = has && + ValidateStrength( + supportBox, + config.minAllowdSupportAndResistanceStrength // + ); + } + + // + if (has) + { + // + AddIfNotExists( + supportBox, + supports, + maxAllowedCollecting // + ); + + // + structure.support = supportBox; + } + + // + // Check for Support Touches ... + XOHCL pBar; + has = has && + forBar.GetPreviousBar(pBar); + if (has) + { + structure.isSupportTouched = pBar.low < supportBox.upper; + } + + // + pBar.Clean(); + supportBox.Clean(); + } + support.Clean(); + } + + // + // Detect Resistance ... + if (config.detectResistance) + { + // + XOHCL resistance; + bool hasResistance = HasResistance( + forBar, + resistance, + config.supportAndResistanceValidationLength, + config.supportAndResistanceMaxAllowedLoopback // + ); + if (hasResistance) + { + // + XBoxZone resistanceBox; + has = ToResistanceBox(resistance, resistanceBox); + + // + // Validate Zone Strength if Provided ... + if (config.minAllowdSupportAndResistanceStrength > 0) + { + // + has = has && + ValidateStrength( + resistanceBox, + config.minAllowdSupportAndResistanceStrength // + ); + } + + // + if (has) + { + // + AddIfNotExists( + resistanceBox, + resistances, + maxAllowedCollecting // + ); + + // + structure.resistance = resistanceBox; + } + + // + // Check for Resistance Touches ... + XOHCL pBar; + has = has && + forBar.GetPreviousBar(pBar); + if (has) + { + structure.isResistanceTouched = pBar.high > resistanceBox.upper; + } + + // + pBar.Clean(); + resistanceBox.Clean(); + } + resistance.Clean(); + } + + // + // Analysers ... + + // + // Analyse Based on PV ... + if (config.analyseFIMAPVPivots) + { + // + XPivotAnalysis analysis; + has = AnalysePVPivots( + analysis, // Result ... + forBar.Index(), // Bar Index ... + config.numberOfRequiredPivotsForAnalysis, // Required Number of Pivots ... + config.maxAllowedLoopbackLengthForAnalysis, // Max Allowed Loopback ... + config.pvPivotsValidationLength // Validation Length ... + ); + if (has) + { + structure.pvAnalysis = analysis; + } + } + + // + // Analyse Based on MA ... + if (config.analyseFIMAMAPivots) + { + // + XPivotAnalysis analysis; + has = AnalyseMAPivots( + analysis, // Result ... + forBar.Index(), // Bar Index ... + config.numberOfRequiredPivotsForAnalysis, // Required Number of Pivots ... + config.maxAllowedLoopbackLengthForAnalysis, // Max Allowed Loopback ... + config.pvPivotsValidationLength // Validation Length ... + ); + if (has) + { + structure.maAnalysis = analysis; + } + } + + // + // Analyse Based on SAR ... + if (config.analyseFIMASARPivots) + { + // + XPivotAnalysis analysis; + has = AnalyseSARPivots( + analysis, // Result ... + forBar.Index(), // Bar Index ... + config.numberOfRequiredPivotsForAnalysis, // Required Number of Pivots ... + config.maxAllowedLoopbackLengthForAnalysis // Max Allowed Loopback ... + ); + if (has) + { + structure.sarAnalysis = analysis; + } + } + + // + // Analyse Based on ZigZag ... + if (config.analyseFIMAZigZagPivots) + { + // + XPivotAnalysis analysis; + has = AnalyseZigZagPivots( + analysis, // Result ... + forBar.Index(), // Bar Index ... + config.numberOfRequiredPivotsForAnalysis, // Required Number of Pivots ... + config.maxAllowedLoopbackLengthForAnalysis // Max Allowed Loopback ... + ); + if (has) + { + structure.zigzagAnalysis = analysis; + } + } + + // + // COMPLEX Actions ... + + // + // Lockup For Previous Zone ... + has = structure.isSupportTouched || + structure.isResistanceTouched; + if (has) + { + // + if (structure.isSupportTouched) + { + // + idx = GetYoungestBefore( + structure.support.from, + supports // + ); + has = IsValidIndex(idx); + if (has) + { + structure.prevZone = supports[idx]; + } + } + else if (structure.isResistanceTouched) + { + // + idx = GetYoungestBefore( + structure.resistance.from, + resistances // + ); + has = IsValidIndex(idx); + if (has) + { + structure.prevZone = resistances[idx]; + } + } + } + + // + // Detect Recently Tested Zones ... + if ((config.detectSupport || + config.detectResistance) && + config.recentlyTestedZonesMaxLookup > 0) + { + // + XOHCL iBar; + int idx = -1; + bool has = false; + + // + int start = forBar.Index() + 1; + int end = start + config.recentlyTestedZonesMaxLookup; + for (int i = start; i < end; i++) + { + // + // Initialize Indexed Bar ... + has = forBar.BarAt(i, iBar); + if (!has) + { + continue; + } + + // + // Selecting Support and Resistances ... + + // + // Supports ... + idx = GetYoungestBefore(iBar.time, supports); + has = IsValidIndex(idx); + if (has) + { + // + // Check Testing ... + has = IsTested(iBar, supports[idx]); + if (has) + { + // + AddIfNotExists( + supports[idx], + structure.recentlyTestedZones // + ); + } + } + + // + // Resistances ... + idx = GetYoungestBefore(iBar.time, resistances); + has = IsValidIndex(idx); + if (has) + { + // + // Check Testing ... + has = IsTested(iBar, resistances[idx]); + if (has) + { + // + AddIfNotExists( + resistances[idx], + structure.recentlyTestedZones // + ); + } + } + } + } + + // + // Checkup for FakeBreaked Zones ... + if (config.detectSupport || + config.detectResistance) + { + // + // Retrieve Previous Bar ... + int idx = -1; + XOHCL pForBar; + XOHCL breakerBar; + XBoxZone pSupport; + XOHCL pBreakerBar; + XBoxZone pResistance; + + // + // Selecting Previously Touched Support / Resistance ... + has = forBar.GetPreviousBar(pForBar); + if (has) + { + // + // Detecting Nearest Above Lows Support ... + idx = GetYoungestAbove( + pForBar.low, + supports // + ); + has = IsValidIndex(idx) && + IsBreaked( + forBar, + supports[idx] // + ); + if (has) + { + pSupport = supports[idx]; + } + + // + // Detecting Nearest Below Highs Resistance ... + idx = GetYoungestBelow( + pForBar.high, + resistances // + ); + has = IsValidIndex(idx) && + IsBreaked( + forBar, + resistances[idx] // + ); + if (has) + { + pResistance = resistances[idx]; + } + } + + // + // Check at least a zone Exists ... + // Selecting pTestedZone ... + has = pSupport.IsValid() || + pResistance.IsValid(); + if (has) + { + // + // Support ... + has = pSupport.IsValid(); + if (has) + { + // + structure.isPTest = true; + structure.pTestedZone = pSupport; + } + + // + // Resistance ... + has = pResistance.IsValid(); + if (has) + { + // + structure.isPTest = true; + structure.pTestedZone = pResistance; + } + } + + // + // Check pTestedZone Existance ... + has = structure.isPTest && + structure.pTestedZone.IsValid(); + if (has) + { + // + // Get Breaker Bars ... + XOHCL breakerBars[]; + int breakerBarsCount = GetBreakerBars( + structure.pTestedZone, + breakerBars // + ); + has = IsValidSize(breakerBarsCount); + if (has) + { + // + idx = GetYoungestBar(breakerBars); + has = IsValidIndex(idx); + if (has) + { + breakerBar = breakerBars[idx]; + } + } + + // + SpecifiedClean(breakerBars); + } + + // + // Check Zone Breaker Bar Exists ... + // Validate Zone Fake Breake Langth ... + has = breakerBar.IsValid(); + if (has) + { + // + // Validate Breake Length ... + has = (breakerBar.Index() - pForBar.Index()) <= config.supportAndResistanceBreakeValidationLength; + } + + // + // Cleanup Resources ... + // + if (!has) + { + // + structure.isPTest = false; + structure.pTestedZone.Clean(); + } + pForBar.Clean(); + pSupport.Clean(); + breakerBar.Clean(); + pBreakerBar.Clean(); + pResistance.Clean(); + } +} + +// +// Lockup For Previous Zone ... +has = structure.isSupportTouched || + structure.isResistanceTouched; +if (has) +{ + // + if (structure.isSupportTouched) + { + // + idx = GetYoungestBefore( + structure.support.from, + supports // + ); + has = IsValidIndex(idx); + if (has) + { + structure.prevZone = supports[idx]; + } + } + else if (structure.isResistanceTouched) + { + // + idx = GetYoungestBefore( + structure.resistance.from, + resistances // + ); + has = IsValidIndex(idx); + if (has) + { + structure.prevZone = resistances[idx]; + } + } +} diff --git a/Experts/x-saherelm.xfima.backtester.ea.mq5 b/Experts/x-saherelm.xfima.backtester.ea.mq5 index 80e04160..3451dab0 100644 --- a/Experts/x-saherelm.xfima.backtester.ea.mq5 +++ b/Experts/x-saherelm.xfima.backtester.ea.mq5 @@ -387,6 +387,7 @@ int OnInit() // // Configure XFIMA POI Detector / Drawer ... detectorConfig.Default(); + detectorConfig.FullDetect(); marketStructureDrawerConfig.FullDraw(); // @@ -456,91 +457,8 @@ void OnTick() fima1Signaller.OnTick(); fima2Signaller.OnTick(); - // - // Initial Bar for Analysis ... - XOHCL cBar; - bool isInited = cBar.Init( - _Symbol, - _Period, - 0 // - ); - - // - // Here We Apply Custom Detecting ... - detectorConfig.OffDetectors(); - detectorConfig.detectSupport = true; - detectorConfig.detectResistance = true; - detectorConfig.detectSignalKeyBarPattern = false; - detectorConfig.supportAndResistanceValidationLength = 21; - - // - // Analyse Market ... - fima2Signaller.poiDetector.AnalyseMarket( - cBar, - marketStructure, - detectorConfig // - ); - CArrayObj *iObjects; - int drawnsCount = fima2Signaller.poiDrawer.DrawMarketStructure( - marketStructure, - marketStructureDrawerConfig, - iObjects // - ); - if (IsValidSize(drawnsCount)) - { - // - AddObjects( - iObjects, - eaDraws // - ); - } - - // - // TODO: Remove this ... - XOHCL pBar; - bool has = cBar.GetPreviousBar(pBar); - if (marketStructure.isPTest) - { - // - // Check For PrevZoneExistanse ... - has = marketStructure.pTestedZone.IsValid(); - if (has) - { - // - // Draw Prev Zone ... - XCBoxObject *iPrevZoneObj; - marketStructure.pTestedZone.to = pBar.time; - has = fima2Signaller.poiDrawer.DrawBox( - marketStructure.pTestedZone, - iPrevZoneObj // - ); - if (has) - { - // - XPOIStyle style; - fima2Signaller.poiDrawer.GetBoxStyle( - style, - marketStructure.pTestedZone.dir // - ); - style.clr = clrYellow; - fima2Signaller.poiDrawer.ApplyBoxStyle( - iPrevZoneObj, - style // - ); - - // - style.Clean(); - eaDraws.Add(iPrevZoneObj); - } - } - - // - Print("Previous Tested ..."); - } - pBar.Clean(); - - // - cBar.Clean(); + // // + // AnalyseMarket(0); } // @@ -694,9 +612,6 @@ void OnSignalTriggered(XSignal &signal) return; } - // - return; - // // Draw Signal Vertical Line ... @@ -727,6 +642,14 @@ void OnSignalTriggered(XSignal &signal) // // Alert Issued Signal ... string message = signal.GetMessage(); + + // + int signalBarIndex = GetBarIndex( + signal.symbol, + signal.period, + signal.time // + ); + AnalyseMarket(signalBarIndex); } // @@ -855,4 +778,148 @@ void OnTradeStateChanged(const XOnTradeHandlerState &state) eaExpert.HandleOnTradeStateChanged(state); } +// +void AnalyseMarket(int barIndex = 0) +{ + // + bool has = false; + + // + barIndex = NormalizeInt(barIndex, 0); + + // + string symbol = fima2Signaller.symbol; + ENUM_TIMEFRAMES period = fima2Signaller.period; + + // + // Retrieve Signal Bar ... + XOHCL bar; + has = bar.Init( + symbol, + period, + barIndex // + ); + if (!has) + { + // + bar.Clean(); + return; + } + + // + // TODO: Remove this and add in OnInit() Method ... + + // + // Configuring Detector ... + + // + detectorConfig.detectOB = true; + detectorConfig.detectFVG = true; + + // + detectorConfig.detectSupport = true; + detectorConfig.detectResistance = true; + detectorConfig.detectSwingTrend = true; + + // + detectorConfig.detectPinned = true; + detectorConfig.detectMomentum = true; + detectorConfig.detectEngulfed = true; + detectorConfig.detectTrueGaped = true; + + // + detectorConfig.detectStarPattern = true; + detectorConfig.detectFlagPattern = true; + detectorConfig.detectRisingPattern = true; + detectorConfig.detectPiercingPattern = true; + detectorConfig.detectSignalKeyBarPattern = true; + + // + detectorConfig.analyseFIMAPVPivots = true; + detectorConfig.analyseFIMAMAPivots = false; + detectorConfig.analyseFIMASARPivots = false; + detectorConfig.analyseFIMAZigZagPivots = false; + + // + // Configure Drawer ... + + // + // Recents ... + marketStructureDrawerConfig.drawFakeBreakedZone = true; + marketStructureDrawerConfig.drawRecentlyTestedZones = true; + marketStructureDrawerConfig.drawRecentlyBreakedZones = true; + + // + // XPV ... + marketStructureDrawerConfig.drawFIMAPVPivotsAnalysis = true; + marketStructureDrawerConfig.drawFIMAPVPivotsAnalysisZones = true; + marketStructureDrawerConfig.drawFIMAPVPivotsAnalysisTrends = true; + marketStructureDrawerConfig.drawFIMAPVPivotsAnalysisPivots = true; + + // + // XMA ... + marketStructureDrawerConfig.drawFIMAMAPivotsAnalysis = false; + marketStructureDrawerConfig.drawFIMAMAPivotsAnalysisZones = false; + marketStructureDrawerConfig.drawFIMAMAPivotsAnalysisTrends = false; + marketStructureDrawerConfig.drawFIMAMAPivotsAnalysisPivots = false; + + // + // XSAR ... + marketStructureDrawerConfig.drawFIMASARPivotsAnalysis = false; + marketStructureDrawerConfig.drawFIMASARPivotsAnalysisZones = false; + marketStructureDrawerConfig.drawFIMASARPivotsAnalysisTrends = false; + marketStructureDrawerConfig.drawFIMASARPivotsAnalysisPivots = false; + + // + // XZigZag ... + marketStructureDrawerConfig.drawFIMAZigZagPivotsAnalysis = false; + marketStructureDrawerConfig.drawFIMAZigZagPivotsAnalysisZones = false; + marketStructureDrawerConfig.drawFIMAZigZagPivotsAnalysisTrends = false; + marketStructureDrawerConfig.drawFIMAZigZagPivotsAnalysisPivots = false; + + // + // Analyse Market on Signalling Bar ... + fima2Signaller.poiDetector.AnalyseMarket( + bar, + marketStructure, + detectorConfig // + ); + + // + // Draw Market Structure ... + CArrayObj *marketStructureObjects; + int marketStructureObjectsCount = fima2Signaller.poiDrawer.DrawMarketStructure( + marketStructure, + marketStructureDrawerConfig, + marketStructureObjects // + ); + if (IsValidIndex(marketStructureObjectsCount)) + { + // + // Add Drawn Objects if Necessary ... + } + + // + if (HasChild(marketStructure.recentlyTestedZones)) + { + Print("Recently Tested Zones ..."); + } + + // + if (HasChild(marketStructure.recentlyBreakedZones)) + { + Print("Recently Breaked Zones ..."); + } + + // + if (marketStructure.fakeBreakedZone.IsValid()) + { + Print("Fake Breaked Zone ..."); + } + + // + bar.Clean(); + marketStructureObjects.Clear(); +} + // \ No newline at end of file diff --git a/Libraries/x-saherelm.common.extensions.lib.mq5 b/Libraries/x-saherelm.common.extensions.lib.mq5 index c6199be6..305165af 100644 --- a/Libraries/x-saherelm.common.extensions.lib.mq5 +++ b/Libraries/x-saherelm.common.extensions.lib.mq5 @@ -7124,7 +7124,26 @@ int CalculateSlopeAndIntercept( // int n = end; - _slope = (n * sumXY - sumX * sumY) / (n * sumX2 - sumX * sumX); + double _dividedBy = (n * sumX2 - sumX * sumX); + // if (_dividedBy <= 0 || n <= 0) + // { + // // + // _slope = 0; + // _intercept = 0; + + // // + // result = 0; + // } else { + // // + // _slope = (n * sumXY - sumX * sumY) / _dividedBy; + // _intercept = (sumY - _slope * sumX) / n; + + // // + // result = n; + // } + + // + _slope = (n * sumXY - sumX * sumY) / _dividedBy; _intercept = (sumY - _slope * sumX) / n; // diff --git a/Libraries/x-saherelm.x-pivot.analysis.lib.mq5 b/Libraries/x-saherelm.x-pivot.analysis.lib.mq5 index 772986fb..59a24cd7 100644 --- a/Libraries/x-saherelm.x-pivot.analysis.lib.mq5 +++ b/Libraries/x-saherelm.x-pivot.analysis.lib.mq5 @@ -1140,7 +1140,7 @@ struct XPivotAnalysis } // - result = GetTag() + "_" + symbol + "_" + ToXString(period) + "_" + ToXString(TimeToSeconds(time)); + result = GetTag() + "_" + symbol + "_" + ToXString(period); // return result; @@ -1163,7 +1163,7 @@ struct XPivotAnalysis } // - result = GetTag() + "_" + symbol + "_" + ToXString(period) + "_UPPER_" + ToXString(TimeToSeconds(time)); + result = GetTag() + "_" + symbol + "_" + ToXString(period) + "_UPPER"; // return result; @@ -1186,7 +1186,7 @@ struct XPivotAnalysis } // - result = GetTag() + "_" + symbol + "_" + ToXString(period) + "_LOWER_" + ToXString(TimeToSeconds(time)); + result = GetTag() + "_" + symbol + "_" + ToXString(period) + "_LOWER"; // return result; @@ -1209,7 +1209,7 @@ struct XPivotAnalysis } // - result = GetTag() + "_" + symbol + "_" + ToXString(period) + "_SUPPORT_" + ToXString(TimeToSeconds(time)); + result = GetTag() + "_" + symbol + "_" + ToXString(period) + "_SUPPORT"; // return result; @@ -1232,7 +1232,7 @@ struct XPivotAnalysis } // - result = GetTag() + "_" + symbol + "_" + ToXString(period) + "_RESISTANCE_" + ToXString(TimeToSeconds(time)); + result = GetTag() + "_" + symbol + "_" + ToXString(period) + "_RESISTANCE"; // return result; diff --git a/Libraries/x-saherelm.x-poi.extensions.lib.mq5 b/Libraries/x-saherelm.x-poi.extensions.lib.mq5 index d710100d..f1790011 100644 --- a/Libraries/x-saherelm.x-poi.extensions.lib.mq5 +++ b/Libraries/x-saherelm.x-poi.extensions.lib.mq5 @@ -3790,6 +3790,245 @@ void ValidateBoxes( // } +/** + * Converts a Bar to Pivot ... + * + * @param bar: XOHCL, reference to Specified Bar ... + * @param pivot: XPivot, reference to holds result ... + * @param forDir: ENUM_X_DIRECTION, specified Pivot Direction ... + * @param prefix: string, Specified Pivot Prefix (used for Object Type) ... + * + * @return ( bool ) + */ +bool ToPivot( + XOHCL &bar, + XPivot &pivot, + ENUM_X_DIRECTION forDir, + string prefix = NULL // +) +{ + // + bool result = false; + + // + // Prepare ... + pivot.Clean(); + + // + // Validate ... + result = bar.IsValid() && + HasDirection(forDir); + if (!result) + { + return result; + } + + // + // Check Direction ... + bool isBullish = IsSpecifiedBullish(forDir); + + // + // Prepare Value of Pivot ... + double iValue = + isBullish + ? bar.low + : bar.high; + + // + // Prepare Pivot Type ... + ENUM_X_PIVOT_TYPE iType = + isBullish + ? X_PIVOT_TYPE_VALE + : X_PIVOT_TYPE_PEAK; + + // + // Initialize Pivot ... + result = pivot.Init( + iValue, + bar.time, + bar.symbol, + forDir, + bar.period, + iType // + ); + if (result) + { + // + // Set Prefix if Pivot initialized successfully ... + pivot.prefix = prefix; + } + + // + // Validate ... + result = pivot.IsValid(); + if (!result) + { + pivot.Clean(); + } + + // + return result; +} + +/** + * Converts POI Patterns to Box ... + * + * @param bar: XOHCL, reference to Specified Pattern ... + * @param box: XBoxZone, reference to holds result ... + * @param forDir: ENUM_X_DIRECTION, Specified Pattern Direction ... + * @param prefix: string, Specified Pattern Type ... + * + * @return ( bool ) + */ +bool ToBox( + XOHCL &bar, + XBoxZone &box, + ENUM_X_DIRECTION forDir, + string prefix = NULL // +) +{ + // + bool result = false; + + // + // Prepare ... + box.Clean(); + + // + // Validate ... + result = bar.IsValid() && + HasDirection(forDir); + if (!result) + { + return result; + } + + // + // Flags for Patterns ... + + // + bool isStar = + IsSpecifiedValid(prefix) && + prefix == "Star"; + + // + bool isPiercing = + IsSpecifiedValid(prefix) && + prefix == "Piercing"; + + // + bool isRising = + IsSpecifiedValid(prefix) && + prefix == "Rising"; + + // + bool isFlag = + IsSpecifiedValid(prefix) && + prefix == "Flag"; + + // + bool isSignalKeyBar = + IsSpecifiedValid(prefix) && + prefix == "SignalKeyBar"; + + // + // Validate Pattern ... + result = isStar || + isFlag || + isRising || + isPiercing || + isSignalKeyBar; + if (!result) + { + return result; + } + + // + // Now Try to Initialized Box ... + + // + // Common Configs ... + box.dir = forDir; + box.type = prefix; + box.at = bar.time; + box.from = bar.time; + box.to = TimeCurrent(); + box.symbol = bar.symbol; + box.period = bar.period; + + // + double upper = 0; + double lower = 0; + datetime from = NULL; + bool isBullish = IsSpecifiedBullish(forDir); + + // + int loopback = 0; + ENUM_SERIESMODE uMode = MODE_HIGH; + ENUM_SERIESMODE lMode = MODE_LOW; + + // + // Specified Configs ... + if (isStar) + { + loopback = 2; + } + else if (isPiercing) + { + loopback = 1; + } + else if (isRising) + { + loopback = 5; + } + else if (isFlag) + { + loopback = 1; + } + else if (isSignalKeyBar) + { + loopback = 1; + } + + // + result = IsValidSize(loopback); + if (result) + { + // + from = GetBarTime( + bar.symbol, + bar.period, + bar.Index() + loopback // + ); + upper = bar.FindHighest( + loopback, + uMode // + ); + lower = bar.FindLowest( + loopback, + lMode // + ); + } + + // + box.from = from; + box.upper = upper; + box.lower = lower; + + // + // Validate result ... + result = box.IsValid(); + if (!result) + { + // + box.Clean(); + return result; + } + + // + return result; +} + /** * Converts a Bar to Support Box ... * @@ -3921,8 +4160,8 @@ bool IsBreaked( // Check Break ... result = zone.IsBullish() - ? bar.close > zone.upper - : bar.close < zone.lower; + ? bar.close < zone.lower + : bar.close > zone.upper; // // Apply Force Bar Edge ... @@ -3966,7 +4205,7 @@ bool IsTested( } // - // Check Break ... + // Check Test ... result = zone.IsBullish() ? bar.low < zone.upper @@ -3976,12 +4215,50 @@ bool IsTested( return result; } +/** + * Check Specified Bar is Inside Specified Zone or not ... + * + * @param bar: Specified Bar ... + * @param zone: Specified Zone ... + * + * @return ( bool ) + */ +bool IsInside( + XOHCL &bar, + XBoxZone &zone // +) +{ + // + bool result = false; + + // + // Validate ... + result = bar.IsValid() && + zone.IsValid(); + if (!result) + { + return result; + } + + // + // Check Inside ... + result = + zone.IsBullish() + ? bar.low < zone.upper && + bar.low > zone.lower + : bar.high > zone.lower && + bar.high < zone.upper; + + // + return result; +} + /** * Collect all Bars which Breakes Specified Zone ... - * + * * @param zone: reference to Specified Zone ... * @param dest: reference Collection to hold result ... - * + * * @return ( int ) */ int GetBreakerBars( @@ -4051,6 +4328,156 @@ int GetBreakerBars( // return result; } + +/** + * Collect all Bars which Inside Specified Zone ... + * + * @param zone: reference to Specified Zone ... + * @param dest: reference Collection to hold result ... + * + * @return ( int ) + */ +int GetInsideBars( + XBoxZone &zone, + XOHCL &dest[] // +) +{ + // + int result = 0; + + // + // Validate ... + bool has = zone.IsValid(); + if (!has) + { + return result; + } + + // + // Prepare ... + SpecifiedClean(dest); + + // + // Do Action ... + XOHCL iBar; + int start = zone.ToIndex(); + int end = zone.FromIndex(); + for (int i = start; i < end; i++) + { + // + // Initialize indexed Bar ... + has = iBar.Init( + zone.symbol, + zone.period, + i // + ); + if (!has) + { + continue; + } + + // + has = IsInside( + iBar, + zone // + ); + if (has) + { + // + AddIfNotExists( + iBar, + dest // + ); + } + + // + iBar.Clean(); + } + + // + result = ArraySize(dest); + + // + iBar.Clean(); + + // + return result; +} + +/** + * Collect all Bars which Tested Specified Zone ... + * + * @param zone: reference to Specified Zone ... + * @param dest: reference Collection to hold result ... + * + * @return ( int ) + */ +int GetTesterBars( + XBoxZone &zone, + XOHCL &dest[] // +) +{ + // + int result = 0; + + // + // Validate ... + bool has = zone.IsValid(); + if (!has) + { + return result; + } + + // + // Prepare ... + SpecifiedClean(dest); + + // + // Do Action ... + XOHCL iBar; + int start = zone.ToIndex(); + int end = zone.FromIndex(); + for (int i = start; i < end; i++) + { + // + // Initialize indexed Bar ... + has = iBar.Init( + zone.symbol, + zone.period, + i // + ); + if (!has) + { + continue; + } + + // + has = IsTested( + iBar, + zone // + ); + if (has) + { + // + AddIfNotExists( + iBar, + dest // + ); + } + + // + iBar.Clean(); + } + + // + result = ArraySize(dest); + + // + iBar.Clean(); + + // + return result; +} //+------------------------------------------------------------------+ // \ No newline at end of file diff --git a/Libraries/x-saherelm.x-poi.lib.mq5 b/Libraries/x-saherelm.x-poi.lib.mq5 index 5870add8..a74c9d36 100644 --- a/Libraries/x-saherelm.x-poi.lib.mq5 +++ b/Libraries/x-saherelm.x-poi.lib.mq5 @@ -42,6 +42,9 @@ struct XPivot ENUM_TIMEFRAMES period; // Period ENUM_X_PIVOT_TYPE type; // Type + // + string prefix; // Object Prefix + // // Constructor ... XPivot() @@ -108,6 +111,7 @@ struct XPivot time = NULL; symbol = NULL; period = NULL; + prefix = NULL; dir = X_DIRECTION_NONE; type = X_PIVOT_TYPE_NONE; @@ -429,7 +433,21 @@ struct XPivot */ string GetTag() { - return GetToken(this); + // + string result = NULL; + + // + string token = GetToken(this); + + // + result = + (IsSpecifiedValid(prefix) + ? prefix + "_" + : "") + + token; + + // + 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 c74da29d..629c776a 100644 --- a/XFIMAEA/Classes/x-saherelm.xfima.x-poi.detector.class.mq5 +++ b/XFIMAEA/Classes/x-saherelm.xfima.x-poi.detector.class.mq5 @@ -564,21 +564,6 @@ class XCXFIMAPOIDetector : public XCMarketPatternDetector obs, maxAllowedCollecting // ); - - // - XOHCL pBar; - bool has = forBar.GetPreviousBar(pBar); - if (has) - { - // - structure.isOBTouched = - isBullishOB - ? pBar.low < structure.ob.upper - : pBar.high > structure.ob.lower; - } - - // - pBar.Clean(); } } @@ -612,21 +597,6 @@ class XCXFIMAPOIDetector : public XCMarketPatternDetector fvgs, maxAllowedCollecting // ); - - // - XOHCL pBar; - bool has = forBar.GetPreviousBar(pBar); - if (has) - { - // - structure.isFVGTouched = - isBullishFVG - ? pBar.low < structure.fvg.upper - : pBar.high > structure.fvg.lower; - } - - // - pBar.Clean(); } } @@ -891,16 +861,6 @@ class XCXFIMAPOIDetector : public XCMarketPatternDetector // // Check for Support Touches ... - XOHCL pBar; - has = has && - forBar.GetPreviousBar(pBar); - if (has) - { - structure.isSupportTouched = pBar.low < supportBox.upper; - } - - // - pBar.Clean(); supportBox.Clean(); } support.Clean(); @@ -951,17 +911,6 @@ class XCXFIMAPOIDetector : public XCMarketPatternDetector } // - // Check for Resistance Touches ... - XOHCL pBar; - has = has && - forBar.GetPreviousBar(pBar); - if (has) - { - structure.isResistanceTouched = pBar.high > resistanceBox.upper; - } - - // - pBar.Clean(); resistanceBox.Clean(); } resistance.Clean(); @@ -1047,46 +996,11 @@ class XCXFIMAPOIDetector : public XCMarketPatternDetector // // COMPLEX Actions ... - // - // Lockup For Previous Zone ... - has = structure.isSupportTouched || - structure.isResistanceTouched; - if (has) - { - // - if (structure.isSupportTouched) - { - // - idx = GetYoungestBefore( - structure.support.from, - supports // - ); - has = IsValidIndex(idx); - if (has) - { - structure.prevZone = supports[idx]; - } - } - else if (structure.isResistanceTouched) - { - // - idx = GetYoungestBefore( - structure.resistance.from, - resistances // - ); - has = IsValidIndex(idx); - if (has) - { - structure.prevZone = resistances[idx]; - } - } - } - // // Detect Recently Tested Zones ... if ((config.detectSupport || - config.detectResistance) && - config.recentlyTestedZonesMaxLookup > 0) + config.detectResistance) && + config.recentlyZonesMaxLookupLength > 0) { // XOHCL iBar; @@ -1094,146 +1008,133 @@ class XCXFIMAPOIDetector : public XCMarketPatternDetector bool has = false; // - int start = forBar.Index() + 1; - int end = start + config.recentlyTestedZonesMaxLookup; - for (int i = start; i < end; i++) { + int start = forBar.Index(); + int end = start + config.recentlyZonesMaxLookupLength; + for (int i = start; i < end; i++) + { // // Initialize Indexed Bar ... has = forBar.BarAt(i, iBar); - if (!has) { + if (!has) + { continue; } // // Selecting Support and Resistances ... - + // // Supports ... idx = GetYoungestBefore(iBar.time, supports); has = IsValidIndex(idx); - if (has) { + if (has) + { // // Check Testing ... has = IsTested(iBar, supports[idx]); - if (has) { + if (has) + { // AddIfNotExists( supports[idx], structure.recentlyTestedZones // ); } + + // + // Check Breaked ... + has = IsBreaked(iBar, supports[idx]); + if (has) + { + // + AddIfNotExists( + supports[idx], + structure.recentlyBreakedZones // + ); + } } - + // // Resistances ... idx = GetYoungestBefore(iBar.time, resistances); has = IsValidIndex(idx); - if (has) { + if (has) + { // // Check Testing ... has = IsTested(iBar, resistances[idx]); - if (has) { + if (has) + { // AddIfNotExists( resistances[idx], structure.recentlyTestedZones // ); } + + // + // Check Breaked ... + has = IsBreaked(iBar, resistances[idx]); + if (has) + { + // + AddIfNotExists( + resistances[idx], + structure.recentlyBreakedZones // + ); + } } } } // // Checkup for FakeBreaked Zones ... - if (config.detectSupport || - config.detectResistance) + if ((config.detectSupport || + config.detectResistance) && + HasChild(structure.recentlyBreakedZones)) { // - // Retrieve Previous Bar ... int idx = -1; - XOHCL pForBar; + bool has = false; + + // + // Detect Youngest Recently Breaked Zones ... + idx = GetYoungest(structure.recentlyBreakedZones); + has = IsValidIndex(idx); + if (has) + { + // + structure.fakeBreakedZone = structure.recentlyBreakedZones[idx]; + + // + // Update To Time ... + structure.fakeBreakedZone.to = forBar.time; + } + + // + // Check Price Going Back to Zone Area ... + has = structure.fakeBreakedZone.IsValid(); + if (has) + { + // + // Check Current Bar Acted Based on Zone ... + has = structure.fakeBreakedZone.IsBullish() + ? forBar.close > structure.fakeBreakedZone.upper + : forBar.close < structure.fakeBreakedZone.lower; + } + + // + // Try to Validate Breake Length ... + + // + // Get Youngest Breaker Bar ... XOHCL breakerBar; - XBoxZone pSupport; - XOHCL pBreakerBar; - XBoxZone pResistance; - - // - // Selecting Previously Touched Support / Resistance ... - has = forBar.GetPreviousBar(pForBar); if (has) { // - // Detecting Nearest Above Lows Support ... - idx = GetYoungestAbove( - pForBar.low, - supports // - ); - has = IsValidIndex(idx) && - IsBreaked( - forBar, - supports[idx] // - ); - if (has) - { - pSupport = supports[idx]; - } - - // - // Detecting Nearest Below Highs Resistance ... - idx = GetYoungestBelow( - pForBar.high, - resistances // - ); - has = IsValidIndex(idx) && - IsBreaked( - forBar, - resistances[idx] // - ); - if (has) - { - pResistance = resistances[idx]; - } - } - - // - // Check at least a zone Exists ... - // Selecting pTestedZone ... - has = pSupport.IsValid() || - pResistance.IsValid(); - if (has) - { - // - // Support ... - has = pSupport.IsValid(); - if (has) - { - // - structure.isPTest = true; - structure.pTestedZone = pSupport; - } - - // - // Resistance ... - has = pResistance.IsValid(); - if (has) - { - // - structure.isPTest = true; - structure.pTestedZone = pResistance; - } - } - - // - // Check pTestedZone Existance ... - has = structure.isPTest && - structure.pTestedZone.IsValid(); - if (has) - { - // - // Get Breaker Bars ... XOHCL breakerBars[]; int breakerBarsCount = GetBreakerBars( - structure.pTestedZone, + structure.fakeBreakedZone, breakerBars // ); has = IsValidSize(breakerBarsCount); @@ -1247,36 +1148,381 @@ class XCXFIMAPOIDetector : public XCMarketPatternDetector breakerBar = breakerBars[idx]; } } - - // SpecifiedClean(breakerBars); } + has = breakerBar.IsValid(); // - // Check Zone Breaker Bar Exists ... - // Validate Zone Fake Breake Langth ... - has = breakerBar.IsValid(); + // Validate BreakerBars Length ... if (has) { // - // Validate Breake Length ... - has = (breakerBar.Index() - pForBar.Index()) <= config.supportAndResistanceBreakeValidationLength; + int diff = breakerBar.Index() - forBar.Index(); + + // + has = + config.supportAndResistanceBreakeValidationLength <= 0 + ? true + : diff <= config.supportAndResistanceBreakeValidationLength; + } + + // + if (!has) + { + structure.fakeBreakedZone.Clean(); } // // Cleanup Resources ... + breakerBar.Clean(); + } + + // + // Detect Recently Patterns ... + if (config.recentlyPatternsMaxLookupLength > 0) + { // - if (!has) + XOHCL iBar; + XPivot iPivot; + XBoxZone iBox; + bool has = false; + string iPrefix = NULL; + int start = forBar.Index(); + ENUM_X_SORT_BY iSortBy = X_SORT_BY_DATE; + ENUM_X_DIRECTION iDir = X_DIRECTION_NONE; + ENUM_X_DIRECTION iSortDir = X_DIRECTION_BULLISH; + int end = start + config.recentlyPatternsMaxLookupLength; + + // + // Order Blocks ... + if (config.detectOB) { // - structure.isPTest = false; - structure.pTestedZone.Clean(); + Copy( + obs, + structure.obs // + ); + Sort( + structure.obs, + iSortBy, + iSortDir, + config.recentlyPatternsMaxAllowedCollecting // + ); } - pForBar.Clean(); - pSupport.Clean(); - breakerBar.Clean(); - pBreakerBar.Clean(); - pResistance.Clean(); + + // + // Fair Value Gaps ... + if (config.detectFVG) + { + // + Copy( + fvgs, + structure.fvgs // + ); + Sort( + structure.fvgs, + iSortBy, + iSortDir, + config.recentlyPatternsMaxAllowedCollecting // + ); + } + + // + // Loop through Items ... + for (int i = start; i < end; i++) + { + // + iPivot.Clean(); + + // + // Initialize Indexed Bar ... + has = forBar.BarAt(i, iBar); + if (!has) + { + // + iBar.Clean(); + continue; + } + + // + // Bars Detecting ... + + // + // Momentum Bars ... + if (config.detectMomentum) + { + // + iPrefix = "MomentumBar"; + has = IsMomentumBar( + iBar, + iDir, + config.momentumBarRangeLength, + config.momentumBarApprovedMultiplier // + ); + has = has && + ToPivot( + iBar, + iPivot, + iDir, + iPrefix // + ); + if (has) + { + // + AddIfNotExists( + iPivot, + structure.momentumBars // + ); + } + iPivot.Clean(); + } + + // + // Engulfed Bars ... + if (config.detectEngulfed) + { + // + iPrefix = "EngulfedBar"; + has = IsEngulfedBar( + iBar, + iDir // + ); + has = has && + ToPivot( + iBar, + iPivot, + iDir, + iPrefix // + ); + if (has) + { + // + AddIfNotExists( + iPivot, + structure.engulfBars // + ); + } + iPivot.Clean(); + } + + // + // TruGaped Bars ... + if (config.detectTrueGaped) + { + // + iPrefix = "TruGapedBar"; + has = IsTrueGapedBar( + forBar, + iDir, + config.truwGapApprovedPointMultiplier // + ); + has = has && + ToPivot( + iBar, + iPivot, + iDir, + iPrefix // + ); + if (has) + { + // + AddIfNotExists( + iPivot, + structure.trueGapBars // + ); + } + iPivot.Clean(); + } + + // + // Pin Bars ... + if (config.detectTrueGaped) + { + // + iPrefix = "PinBar"; + has = IsPinnedBar( + forBar, + iDir, + config.pinnedBaarShadowApprovedMultiplier, + config.pinnedBarMinimumPinBarRangeMultiplier, + config.pinnedBarForceDirection // + ); + has = has && + ToPivot( + iBar, + iPivot, + iDir, + iPrefix // + ); + if (has) + { + // + AddIfNotExists( + iPivot, + structure.pinBars // + ); + } + iPivot.Clean(); + } + + // + // Patterns Detecting ... + + // + // Star Pattern ... + if (config.detectStarPattern) + { + // + iPrefix = "Star"; + has = IsStartPattern( + forBar, + iDir // + ); + has = has && + ToBox( + forBar, + iBox, + iDir, + iPrefix // + ); + if (has) + { + // + AddIfNotExists( + iBox, + structure.starPatterns // + ); + } + iBox.Clean(); + } + + // + // Piercing Pattern ... + if (config.detectPiercingPattern) + { + // + iPrefix = "Piercing"; + has = IsPiercingPattern( + forBar, + iDir // + ); + has = has && + ToBox( + forBar, + iBox, + iDir, + iPrefix // + ); + if (has) + { + // + AddIfNotExists( + iBox, + structure.piercingPatterns // + ); + } + iBox.Clean(); + } + + // + // Rising Pattern ... + if (config.detectRisingPattern) + { + // + iPrefix = "Rising"; + has = IsRisingPattern( + forBar, + iDir // + ); + has = has && + ToBox( + forBar, + iBox, + iDir, + iPrefix // + ); + if (has) + { + // + AddIfNotExists( + iBox, + structure.risingPatterns // + ); + } + iBox.Clean(); + } + + // + // Flag Pattern ... + if (config.detectFlagPattern) + { + // + iPrefix = "Flag"; + XOHCL swingBar; + has = IsFlagPattern( + forBar, + iDir, + swingBar, + config.flagPatternMinimumPullbackBars // + ); + has = has && + ToBox( + forBar, + iBox, + iDir, + iPrefix // + ); + if (has) + { + // + AddIfNotExists( + iBox, + structure.flagPatterns // + ); + } + iBox.Clean(); + } + + // + // SignalKey Bar Pattern ... + if (config.detectSignalKeyBarPattern) + { + // + iPrefix = "SignalKeyBar"; + has = IsSignalKeyBarPattern( + forBar, + iDir, + config.signalKeyBarShadowApprovedMultiplier, + config.signalKeyBarMinimumPinBarRangeMultiplier, + config.signalKeyBarForceDirection // + ); + has = has && + ToBox( + forBar, + iBox, + iDir, + iPrefix // + ); + if (has) + { + // + AddIfNotExists( + iBox, + structure.signalKeyBarPatterns // + ); + } + iBox.Clean(); + } + + // + iBar.Clean(); + } + + // + // Cleanup Resources ... + iBar.Clean(); + iBox.Clean(); + iPivot.Clean(); } } diff --git a/XFIMAEA/Classes/x-saherelm.xfima.x-poi.drawer.class.mq5 b/XFIMAEA/Classes/x-saherelm.xfima.x-poi.drawer.class.mq5 index ab15c748..3f28d94d 100644 --- a/XFIMAEA/Classes/x-saherelm.xfima.x-poi.drawer.class.mq5 +++ b/XFIMAEA/Classes/x-saherelm.xfima.x-poi.drawer.class.mq5 @@ -32,6 +32,22 @@ class XCXFIMAPOIDrawer : public XCPOIDrawer // public: // + // Props ... + + // + // Tested Zones ... + color testedBullishColor; + color testedBearishColor; + + // + // Breaked Zones ... + color breakedBullishColor; + color breakedBearishColor; + + // + // FakeBreaked Zones ... + color fakeBreakedBullishColor; + color fakeBreakedBearishColor; // // Constructor ... @@ -75,6 +91,16 @@ class XCXFIMAPOIDrawer : public XCPOIDrawer // boxBullishStyle = defaultBullishStyle; boxBearishStyle = defaultBearishStyle; + + // + testedBullishColor = clrLime; + breakedBullishColor = clrGreen; + fakeBreakedBullishColor = clrYellow; + + // + testedBearishColor = clrRed; + breakedBearishColor = clrDarkRed; + fakeBreakedBearishColor = clrDarkOrange; } // @@ -161,6 +187,135 @@ class XCXFIMAPOIDrawer : public XCPOIDrawer return result; } + /** + * Get Tested Zone Style ... + * + * @param style: reference to hold result ... + * @param zone: Specified Zone ... + * + * @return ( bool ) + */ + bool GetTestedStyle( + XPOIStyle &style, + XBoxZone &zone // + ) + { + // + bool result = false; + + // + style.Clean(); + + // + result = zone.IsValid(); + if (!result) + { + return result; + } + + // + GetBoxStyle( + style, + zone.dir // + ); + + // + style.width = 3; + style.clr = + zone.IsBullish() + ? testedBullishColor + : testedBearishColor; + + // + return result; + } + + /** + * Get Breaked Zone Style ... + * + * @param style: reference to hold result ... + * @param zone: Specified Zone ... + * + * @return ( bool ) + */ + bool GetBreakedStyle( + XPOIStyle &style, + XBoxZone &zone // + ) + { + // + bool result = false; + + // + style.Clean(); + + // + result = zone.IsValid(); + if (!result) + { + return result; + } + + // + GetBoxStyle( + style, + zone.dir // + ); + + // + style.width = 3; + style.clr = + zone.IsBullish() + ? breakedBullishColor + : breakedBearishColor; + + // + return result; + } + + /** + * Get Fake Breaked Zone Style ... + * + * @param style: reference to hold result ... + * @param zone: Specified Zone ... + * + * @return ( bool ) + */ + bool GetFakeBreakedStyle( + XPOIStyle &style, + XBoxZone &zone // + ) + { + // + bool result = false; + + // + style.Clean(); + + // + result = zone.IsValid(); + if (!result) + { + return result; + } + + // + GetBoxStyle( + style, + zone.dir // + ); + + // + style.width = 3; + style.clr = + zone.IsBullish() + ? fakeBreakedBullishColor + : fakeBreakedBearishColor; + + // + return result; + } + /** * Fill Arrow Based Drawing Specs ... * @@ -199,6 +354,102 @@ class XCXFIMAPOIDrawer : public XCPOIDrawer } } + /** + * Apply Tested Style ... + * + * @param object: reference pointer to Object ... + * @param zone: reference to Zone ... + */ + void ApplyTestedStyle( + XCBoxObject *&object, + XBoxZone &zone // + ) + { + // + if (!zone.IsValid() || + object == NULL) + { + return; + } + + // + XPOIStyle style; + if (!GetTestedStyle(style, zone)) + { + return; + } + + // + ApplyBoxStyle( + object, + style // + ); + } + + /** + * Apply Breaked Style ... + * + * @param object: reference pointer to Object ... + * @param zone: reference to Zone ... + */ + void ApplyBreakedStyle( + XCBoxObject *&object, + XBoxZone &zone // + ) + { + // + if (!zone.IsValid() || + object == NULL) + { + return; + } + + // + XPOIStyle style; + if (!GetBreakedStyle(style, zone)) + { + return; + } + + // + ApplyBoxStyle( + object, + style // + ); + } + + /** + * Apply Tested Style ... + * + * @param object: reference pointer to Object ... + * @param zone: reference to Zone ... + */ + void ApplyFakeBreakStyle( + XCBoxObject *&object, + XBoxZone &zone // + ) + { + // + if (!zone.IsValid() || + object == NULL) + { + return; + } + + // + XPOIStyle style; + if (!GetFakeBreakedStyle(style, zone)) + { + return; + } + + // + ApplyBoxStyle( + object, + style // + ); + } + /** * Draw Specified Market Structure Based on Given Configs ... * @@ -229,6 +480,7 @@ class XCXFIMAPOIDrawer : public XCPOIDrawer objects.Clear(); // + int count = 0; bool has = false; int arrowCode = -1; int arrowWidth = 3; @@ -729,6 +981,8 @@ class XCXFIMAPOIDrawer : public XCPOIDrawer has = DrawPivotAnalysis( structure.pvAnalysis, iObj, + config.drawFIMAPVPivotsAnalysisTrends, + config.drawFIMAPVPivotsAnalysisZones, config.drawFIMAPVPivotsAnalysisPivots, bearArrowCode, bullArrowCode // @@ -754,6 +1008,8 @@ class XCXFIMAPOIDrawer : public XCPOIDrawer has = DrawPivotAnalysis( structure.pvAnalysis, iObj, + config.drawFIMAMAPivotsAnalysisTrends, + config.drawFIMAMAPivotsAnalysisZones, config.drawFIMAMAPivotsAnalysisPivots, bearArrowCode, bullArrowCode // @@ -779,6 +1035,8 @@ class XCXFIMAPOIDrawer : public XCPOIDrawer has = DrawPivotAnalysis( structure.pvAnalysis, iObj, + config.drawFIMASARPivotsAnalysisTrends, + config.drawFIMASARPivotsAnalysisZones, config.drawFIMASARPivotsAnalysisPivots, bearArrowCode, bullArrowCode // @@ -804,6 +1062,8 @@ class XCXFIMAPOIDrawer : public XCPOIDrawer has = DrawPivotAnalysis( structure.pvAnalysis, iObj, + config.drawFIMAZigZagPivotsAnalysisTrends, + config.drawFIMAZigZagPivotsAnalysisZones, config.drawFIMAZigZagPivotsAnalysisPivots, bearArrowCode, bullArrowCode // @@ -815,6 +1075,186 @@ class XCXFIMAPOIDrawer : public XCPOIDrawer } } + // + // Fake Breaked Zone ... + if (config.drawFakeBreakedZone && + structure.fakeBreakedZone.IsValid()) + { + // + XCBoxObject *iObj; + has = DrawBox( + structure.fakeBreakedZone, + iObj // + ); + if (has) + { + // + // Apply Style ... + ApplyFakeBreakStyle( + iObj, + structure.fakeBreakedZone // + ); + + // + objects.Add(iObj); + } + + // + ZeroMemory(iObj); + } + + // + // Recently Tested Zones ... + if (config.drawRecentlyTestedZones && + HasChild(structure.recentlyTestedZones)) + { + // + XCBoxObject *iObj; + count = ArraySize(structure.recentlyTestedZones); + for (int i = 0; i < count; i++) + { + // + // Draw Box ... + has = DrawBox( + structure.recentlyTestedZones[i], + iObj // + ); + if (has) + { + // + ApplyTestedStyle( + iObj, + structure.recentlyTestedZones[i] // + ); + + // + objects.Add(iObj); + } + + // + ZeroMemory(iObj); + } + } + + // + // Recently Breaked Zones ... + if (config.drawRecentlyBreakedZones && + HasChild(structure.recentlyBreakedZones)) + { + // + XCBoxObject *iObj; + count = ArraySize(structure.recentlyBreakedZones); + for (int i = 0; i < count; i++) + { + // + // Draw Box ... + has = DrawBox( + structure.recentlyBreakedZones[i], + iObj // + ); + if (has) + { + // + ApplyBreakedStyle( + iObj, + structure.recentlyBreakedZones[i] // + ); + + // + objects.Add(iObj); + } + + // + ZeroMemory(iObj); + } + } + + // + // Draw Recent Patterns ... + if (config.drawRecentPatterns) + { + // + // Pin Bars ... + if (config.drawPinned && + HasChild(structure.pinBars)) + { + // + // TODO: Complete this ... + } + + // + // Engulf Bars ... + if (config.drawEngulfed && + HasChild(structure.engulfBars)) + { + // + // TODO: Complete this ... + } + + // + // TrueGap Bars ... + if (config.drawTrueGaped && + HasChild(structure.trueGapBars)) + { + // + // TODO: Complete this ... + } + + // + // TrueGap Bars ... + if (config.drawMomentum && + HasChild(structure.momentumBars)) + { + // + // TODO: Complete this ... + } + + // + // Flag Pattern ... + if (config.drawFlagPattern && + HasChild(structure.flagPatterns)) + { + // + // TODO: Complete this ... + } + + // + // Star Pattern ... + if (config.drawStarPattern && + HasChild(structure.starPatterns)) + { + // + // TODO: Complete this ... + } + + // + // Rising Pattern ... + if (config.drawRisingPattern && + HasChild(structure.risingPatterns)) + { + // + // TODO: Complete this ... + } + + // + // Piercing Pattern ... + if (config.drawPiercingPattern && + HasChild(structure.piercingPatterns)) + { + // + // TODO: Complete this ... + } + + // + // SignalKeyBar Pattern ... + if (config.drawSignalKeyBarPattern && + HasChild(structure.signalKeyBarPatterns)) + { + // + // TODO: Complete this ... + } + } + // result = objects.Total(); diff --git a/XFIMAEA/Libraries/x-saherelm.xfima.lib.mq5 b/XFIMAEA/Libraries/x-saherelm.xfima.lib.mq5 index 0bdd8b25..05f5c55a 100644 --- a/XFIMAEA/Libraries/x-saherelm.xfima.lib.mq5 +++ b/XFIMAEA/Libraries/x-saherelm.xfima.lib.mq5 @@ -83,9 +83,13 @@ struct XFIMAPatternDetectorConfig int trendingNumberOfSwings; int trendingSwingShoulders; + // + int recentlyPatternsMaxLookupLength; + int recentlyPatternsMaxAllowedCollecting; + // // Support and Resistance ... - int recentlyTestedZonesMaxLookup; + int recentlyZonesMaxLookupLength; int supportAndResistanceValidationLength; int minAllowdSupportAndResistanceStrength; int supportAndResistanceMaxAllowedLoopback; @@ -163,7 +167,9 @@ struct XFIMAPatternDetectorConfig fvgLoopback = 0; trendingNumberOfSwings = 0; trendingSwingShoulders = 0; - recentlyTestedZonesMaxLookup = 0; + recentlyZonesMaxLookupLength = 0; + recentlyPatternsMaxLookupLength = 0; + recentlyPatternsMaxAllowedCollecting = 0; supportAndResistanceValidationLength = 0; minAllowdSupportAndResistanceStrength = 0; supportAndResistanceMaxAllowedLoopback = 0; @@ -237,11 +243,13 @@ struct XFIMAPatternDetectorConfig // // Support and Resistance ... - recentlyTestedZonesMaxLookup = 100; + recentlyZonesMaxLookupLength = 100; + recentlyPatternsMaxLookupLength = 50; + recentlyPatternsMaxAllowedCollecting = 20; supportAndResistanceValidationLength = 100; minAllowdSupportAndResistanceStrength = 1; supportAndResistanceMaxAllowedLoopback = 1500; - supportAndResistanceBreakeValidationLength = 3; + supportAndResistanceBreakeValidationLength = 4; // // TrueGap ... @@ -372,25 +380,33 @@ struct XFIMAMarketStructure XBoxZone support; XBoxZone resistance; + // + XBoxZone obs[]; + XBoxZone fvgs[]; + + // + XPivot pinBars[]; + XPivot engulfBars[]; + XPivot trueGapBars[]; + XPivot momentumBars[]; + + // + XBoxZone flagPatterns[]; + XBoxZone starPatterns[]; + XBoxZone risingPatterns[]; + XBoxZone piercingPatterns[]; + XBoxZone signalKeyBarPatterns[]; + // // Previous Support or Resistance based on current ... // // Current Support is Touched => Prev Support; // Current Resistance is Touched => Prev Resistance; - XBoxZone prevZone; + XBoxZone fakeBreakedZone; // - bool isOBTouched; - bool isFVGTouched; - bool isSupportTouched; - bool isResistanceTouched; - - // - // TODO: For Test ... - bool isPTest; - XOHCL pBreakerBar; - XBoxZone pTestedZone; XBoxZone recentlyTestedZones[]; + XBoxZone recentlyBreakedZones[]; // // Analysis ... @@ -441,13 +457,7 @@ struct XFIMAMarketStructure resistance.Clean(); // - isOBTouched = false; - isFVGTouched = false; - isSupportTouched = false; - isResistanceTouched = false; - - // - prevZone.Clean(); + fakeBreakedZone.Clean(); // bar.Clean(); @@ -471,9 +481,23 @@ struct XFIMAMarketStructure piercingPatternDir = X_DIRECTION_NONE; signalKeyBarPatternDir = X_DIRECTION_NONE; + // + SpecifiedClean(obs); + SpecifiedClean(fvgs); + SpecifiedClean(pinBars); + SpecifiedClean(engulfBars); + SpecifiedClean(trueGapBars); + SpecifiedClean(momentumBars); + SpecifiedClean(flagPatterns); + SpecifiedClean(starPatterns); + SpecifiedClean(risingPatterns); + SpecifiedClean(piercingPatterns); + SpecifiedClean(signalKeyBarPatterns); + // SpecifiedClean(trendSwings); SpecifiedClean(recentlyTestedZones); + SpecifiedClean(recentlyBreakedZones); // ZeroMemory(this); @@ -494,25 +518,21 @@ struct XFIMAMarketStructureDrawerConfig // Props ... // - bool drawSupports; - bool drawResistance; + bool drawOB; // Current Order Block ... + bool drawFVG; // Current Fair Value Gap ... // - bool drawSwingTrend; - bool swingTrendRayLeft; - bool swingTrendRayRight; + bool drawSupports; // Detected Supports ... + bool drawResistance; // Detected Resistances ... // - bool drawOB; - bool drawFVG; + bool drawSwingTrend; // Swing Trend ... + bool swingTrendRayLeft; // Ray Left Swing Trend ... + bool swingTrendRayRight; // Ray Right Swing Trend ... // - bool drawStarPattern; - bool drawFlagPattern; - bool drawRisingPattern; - bool drawPiercingPattern; - bool drawSignalKeyBarPattern; - + // Draw Current Detected Patterns ... + // bool drawPinned; bool drawMomentum; @@ -520,19 +540,48 @@ struct XFIMAMarketStructureDrawerConfig bool drawTrueGaped; // + bool drawStarPattern; + bool drawFlagPattern; + bool drawRisingPattern; + bool drawPiercingPattern; + bool drawSignalKeyBarPattern; + + // + // Draw Recently Zones ... + bool drawRecentPatterns; + bool drawFakeBreakedZone; + bool drawRecentlyTestedZones; + bool drawRecentlyBreakedZones; + + // + // Draw Analysis Pivots ... + + // + // XPV ... bool drawFIMAPVPivotsAnalysis; + bool drawFIMAPVPivotsAnalysisZones; + bool drawFIMAPVPivotsAnalysisTrends; bool drawFIMAPVPivotsAnalysisPivots; // + // XMA ... bool drawFIMAMAPivotsAnalysis; + bool drawFIMAMAPivotsAnalysisZones; + bool drawFIMAMAPivotsAnalysisTrends; bool drawFIMAMAPivotsAnalysisPivots; // + // XSAR ... bool drawFIMASARPivotsAnalysis; + bool drawFIMASARPivotsAnalysisZones; + bool drawFIMASARPivotsAnalysisTrends; bool drawFIMASARPivotsAnalysisPivots; // + // XZIGZAG ... bool drawFIMAZigZagPivotsAnalysis; + bool drawFIMAZigZagPivotsAnalysisZones; + bool drawFIMAZigZagPivotsAnalysisTrends; bool drawFIMAZigZagPivotsAnalysisPivots; // @@ -567,13 +616,35 @@ struct XFIMAMarketStructureDrawerConfig swingTrendRayRight = false; drawPiercingPattern = false; drawSignalKeyBarPattern = false; + + // + drawRecentPatterns = false; + drawFakeBreakedZone = false; + drawRecentlyTestedZones = false; + drawRecentlyBreakedZones = false; + + // drawFIMAPVPivotsAnalysis = false; - drawFIMAMAPivotsAnalysis = false; - drawFIMASARPivotsAnalysis = false; - drawFIMAZigZagPivotsAnalysis = false; + drawFIMAPVPivotsAnalysisZones = false; + drawFIMAPVPivotsAnalysisTrends = false; drawFIMAPVPivotsAnalysisPivots = false; + + // + drawFIMAMAPivotsAnalysis = false; + drawFIMAMAPivotsAnalysisZones = false; + drawFIMAMAPivotsAnalysisTrends = false; drawFIMAMAPivotsAnalysisPivots = false; + + // + drawFIMASARPivotsAnalysis = false; + drawFIMASARPivotsAnalysisZones = false; + drawFIMASARPivotsAnalysisTrends = false; drawFIMASARPivotsAnalysisPivots = false; + + // + drawFIMAZigZagPivotsAnalysis = false; + drawFIMAZigZagPivotsAnalysisZones = false; + drawFIMAZigZagPivotsAnalysisTrends = false; drawFIMAZigZagPivotsAnalysisPivots = false; // @@ -601,14 +672,36 @@ struct XFIMAMarketStructureDrawerConfig swingTrendRayLeft = false; swingTrendRayRight = true; drawSignalKeyBarPattern = true; + + // + drawRecentPatterns = true; + drawFakeBreakedZone = true; + drawRecentlyTestedZones = true; + drawRecentlyBreakedZones = true; + + // drawFIMAPVPivotsAnalysis = true; + drawFIMAPVPivotsAnalysisZones = true; + drawFIMAPVPivotsAnalysisTrends = true; + drawFIMAPVPivotsAnalysisPivots = true; + + // drawFIMAMAPivotsAnalysis = true; + drawFIMAMAPivotsAnalysisZones = true; + drawFIMAMAPivotsAnalysisTrends = true; + drawFIMAMAPivotsAnalysisPivots = true; + + // drawFIMASARPivotsAnalysis = true; + drawFIMASARPivotsAnalysisZones = true; + drawFIMASARPivotsAnalysisTrends = true; + drawFIMASARPivotsAnalysisPivots = true; + + // drawFIMAZigZagPivotsAnalysis = true; - drawFIMAPVPivotsAnalysisPivots = false; - drawFIMAMAPivotsAnalysisPivots = false; - drawFIMASARPivotsAnalysisPivots = false; - drawFIMAZigZagPivotsAnalysisPivots = false; + drawFIMAZigZagPivotsAnalysisZones = true; + drawFIMAZigZagPivotsAnalysisTrends = true; + drawFIMAZigZagPivotsAnalysisPivots = true; } /** @@ -636,13 +729,35 @@ struct XFIMAMarketStructureDrawerConfig swingTrendRayRight = true; drawPiercingPattern = true; drawSignalKeyBarPattern = true; + + // + drawRecentPatterns = true; + drawFakeBreakedZone = true; + drawRecentlyTestedZones = true; + drawRecentlyBreakedZones = true; + + // drawFIMAPVPivotsAnalysis = true; - drawFIMAMAPivotsAnalysis = true; - drawFIMASARPivotsAnalysis = true; - drawFIMAZigZagPivotsAnalysis = true; + drawFIMAPVPivotsAnalysisZones = true; + drawFIMAPVPivotsAnalysisTrends = true; drawFIMAPVPivotsAnalysisPivots = true; + + // + drawFIMAMAPivotsAnalysis = true; + drawFIMAMAPivotsAnalysisZones = true; + drawFIMAMAPivotsAnalysisTrends = true; drawFIMAMAPivotsAnalysisPivots = true; + + // + drawFIMASARPivotsAnalysis = true; + drawFIMASARPivotsAnalysisZones = true; + drawFIMASARPivotsAnalysisTrends = true; drawFIMASARPivotsAnalysisPivots = true; + + // + drawFIMAZigZagPivotsAnalysis = true; + drawFIMAZigZagPivotsAnalysisZones = true; + drawFIMAZigZagPivotsAnalysisTrends = true; drawFIMAZigZagPivotsAnalysisPivots = true; }