diff --git a/Classes/x-saherelm.x-poi.class.mq5 b/Classes/x-saherelm.x-poi.class.mq5 index df1deeb2..701d6f9c 100644 --- a/Classes/x-saherelm.x-poi.class.mq5 +++ b/Classes/x-saherelm.x-poi.class.mq5 @@ -183,6 +183,30 @@ class XCPOIDetector : public XCBaseAlert mSwingRange = value; } + /** + * Get Pullback Range Validation ... + * + * @return ( int ) + */ + int PullbackRange() + { + return mPullbackRange; + } + + /** + * Set Pullback Range Validation ... + * + * @param value: int ... + */ + void PullbackRange(int value) + { + // + value = NormalizeInt(value, 1); + + // + mPullbackRange = value; + } + /** * Get Momentum Detecting Loopback ... * @@ -659,6 +683,9 @@ class XCPOIDetector : public XCBaseAlert SwingRange(7); MomentumLoopback(2); + // + PullbackRange(3); + // MomentumLoopback(2); @@ -775,6 +802,13 @@ class XCPOIDetector : public XCBaseAlert iEvent // ); + // + // Pullback ... + DetetctPullback( + iBar, + iEvent // + ); + // // Consolidation Zone ... DetectConsolidationZone( @@ -955,6 +989,21 @@ class XCPOIDetector : public XCBaseAlert ); } + // + // Pullback ... + has = DetetctPullback( + iBar, + iEvent // + ); + if (has) + { + // + Add( + iEvent, + events // + ); + } + // // Consolidation Zone ... has = DetectConsolidationZone( @@ -1139,6 +1188,27 @@ class XCPOIDetector : public XCBaseAlert state.swingHighs // ); + // + // Pullbacks ... + + // + Copy( + mPullbacks, + state.pullbacks // + ); + + // + Copy( + mBullishPullbacks, + state.bullishPullbacks // + ); + + // + Copy( + mBearishPullbacks, + state.bearishPullbacks // + ); + // // Momentums ... @@ -1802,6 +1872,167 @@ class XCPOIDetector : public XCBaseAlert return result; } + /** + * Detect Pullback ... + * + * @param bar: XOHCL instance ... + * @param state: ENUM_XPOI_EVENTS member ... + * + * @return ( bool ) + */ + bool DetetctPullback( + XOHCL &bar, + ENUM_XPOI_EVENTS &state // + ) + { + // + bool result = false; + + // + state = X_POI_EVENT_NONE; + + // + result = bar.IsValid(); + if (!result) + { + return result; + } + + // + XOHCL sBar; + if (bar.Index() == 0) + { + // + result = sBar.Init( + bar.symbol, + bar.period, + bar.Index() + 1 // + ); + if (!result) + { + // + sBar.Clean(); + return result; + } + } + else + { + sBar = bar; + } + + // + ENUM_X_DIRECTION iDir; + result = mBarAnalyser.IsPullback( + sBar, + iDir, + mPullbackRange, + true // Force Body ... + ); + if (!result) + { + // + sBar.Clean(); + return result; + } + + // + bool isBullish = IsBullish(iDir); + bool isBearish = IsBearish(iDir); + result = isBullish || + isBearish; + if (!result) + { + // + sBar.Clean(); + return result; + } + + // + XOHCL fromBar; + result = fromBar.Init( + bar.symbol, + bar.period, + sBar.Index() + mPullbackRange // + ); + if (!result) + { + // + fromBar.Clean(); + return result; + } + + // + XBoxZone box; + + // + box.dir = iDir; + box.to = sBar.time; + box.from = fromBar.time; + box.symbol = fromBar.symbol; + box.period = fromBar.period; + box.type = ToString(iDir) + "_XPullBK" + box.symbol + "_" + ToString(box.period); + + // + box.upper = + isBullish + ? sBar.high + : fromBar.high; + + // + box.lower = + isBullish + ? fromBar.low + : sBar.low; + + // + result = box.IsValid(); + if (result) + { + // + AddRef( + box, + mPullbacks // + ); + + // + if (isBullish) + { + // + AddRef( + box, + mBullishPullbacks // + ); + } + + // + if (isBearish) + { + // + AddRef( + box, + mBearishPullbacks // + ); + } + + // + state = + isBullish + ? X_BULLISH_PULLBACK_DETECTED + : X_BEARISH_PULLBACK_DETECTED; + } + + // + // Cleanup Resources ... + + // + box.Clean(); + sBar.Clean(); + fromBar.Clean(); + + // + return result; + } + /** * Detect Consolidation Zones ... * @@ -3093,6 +3324,13 @@ class XCPOIDetector : public XCBaseAlert XCSwing *mSwingHighs[]; // Holds Founded Swing Highs ... int mSwingRange; // Swing Detection Range ... + // + // Pullbacks ... + XBoxZone mPullbacks[]; // Holds Founded Pullbacks ... + XBoxZone mBullishPullbacks[]; // Holds Founded Bullish Pullbacks ... + XBoxZone mBearishPullbacks[]; // Holds Founded Bearish Pullbacks ... + int mPullbackRange; // Pullback Detection Range ... + // // Momentums ... XCMomentumBar *mMomentums[]; // Holds Founded Momentum Bars ... diff --git a/Classes/x-saherelm.x-poi.drawer.class.mq5 b/Classes/x-saherelm.x-poi.drawer.class.mq5 index 6fb397a6..5513dbfb 100644 --- a/Classes/x-saherelm.x-poi.drawer.class.mq5 +++ b/Classes/x-saherelm.x-poi.drawer.class.mq5 @@ -3355,6 +3355,7 @@ class XCPOIDrawer : public XCBase bool ignoreSupportZones = false, bool ignoreBullishSharps = false, bool ignoreBullishSpikes = false, + bool ignoreBullishPullbacks = false, bool ignoreBullishMomentums = false, bool ignoreBullishRejections = false, bool ignoreBullishOrderBlocks = false, @@ -3367,6 +3368,7 @@ class XCPOIDrawer : public XCBase bool ignoreResistanceZones = false, bool ignoreBearishSharps = false, bool ignoreBearishSpikes = false, + bool ignoreBearishPullbacks = false, bool ignoreBearishMomentums = false, bool ignoreBearishRejections = false, bool ignoreBearishOrderBlocks = false, @@ -3856,6 +3858,67 @@ class XCPOIDrawer : public XCBase } } + // + // Pullbacks ... + + // + // Bullish ... + if (!ignoreBullishPullbacks) + { + // + int count = state.CountBullishPullbacks(); + if (IsValidSize(count)) + { + // + for (int i = 0; i < count; i++) + { + // + XCBoxObject *iObj; + bool isCreated = DrawBox( + state.bullishPullbacks[i], + iObj // + ); + if (isCreated) + { + // + Add( + (XCBaseObject *)iObj, + drawnObjects // + ); + } + } + } + } + + // + // Bearish ... + if (!ignoreBearishPullbacks) + { + // + int count = state.CountBearishPullbacks(); + if (IsValidSize(count)) + { + // + for (int i = 0; i < count; i++) + { + // + XCBoxObject *iObj; + bool isCreated = DrawBox( + state.bearishPullbacks[i], + iObj // + ); + if (isCreated) + { + // + Add( + (XCBaseObject *)iObj, + drawnObjects // + ); + } + } + } + } + // // Consolidation Zones ... diff --git a/Experts/x-saherelm.xpoi.test.ea.mq5 b/Experts/x-saherelm.xpoi.test.ea.mq5 index d8dc88f3..e158a2c1 100644 --- a/Experts/x-saherelm.xpoi.test.ea.mq5 +++ b/Experts/x-saherelm.xpoi.test.ea.mq5 @@ -342,34 +342,36 @@ void DetectPOIState() stateObjects, // // Bullish ... - showBullishPOIs && true, // SwingLows - showBullishPOIs && true, // DemandZones - showBullishPOIs && true, // SupportZones - showBullishPOIs && true, // BullishSharps - showBullishPOIs && true, // BullishSpikes - showBullishPOIs && true, // BullishMomentums - showBullishPOIs && true, // BullishRejections - showBullishPOIs && true, // BullishOrderBlocks - showBullishPOIs && true, // BullishFairValueGaps - showBullishPOIs && true, // BullishConsolidationZones + showBullishPOIs && true, // SwingLows + showBullishPOIs && true, // DemandZones + showBullishPOIs && true, // SupportZones + showBullishPOIs && true, // BullishSharps + showBullishPOIs && true, // BullishSpikes + showBullishPOIs && false, // BullishPullbacks + showBullishPOIs && true, // BullishMomentums + showBullishPOIs && true, // BullishRejections + showBullishPOIs && true, // BullishOrderBlocks + showBullishPOIs && true, // BullishFairValueGaps + showBullishPOIs && true, // BullishConsolidationZones // // Bearish ... - showBearishPOIs && true, // SwingHighs - showBearishPOIs && true, // SupplyZones - showBearishPOIs && true, // BearishSharps - showBearishPOIs && true, // BearishSpikes - showBearishPOIs && true, // ResistanceZones - showBearishPOIs && true, // BearishMomentums - showBearishPOIs && true, // BearishRejections - showBearishPOIs && true, // BearishOrderBlocks - showBearishPOIs && true, // BearishFairValueGaps - showBearishPOIs && true // BearishConsolidationZones + showBearishPOIs && true, // SwingHighs + showBearishPOIs && true, // SupplyZones + showBearishPOIs && true, // ResistanceZones + showBearishPOIs && true, // BearishSharps + showBearishPOIs && true, // BearishSpikes + showBearishPOIs && false, // BearishPullbacks + showBearishPOIs && true, // BearishMomentums + showBearishPOIs && true, // BearishRejections + showBearishPOIs && true, // BearishOrderBlocks + showBearishPOIs && true, // BearishFairValueGaps + showBearishPOIs && true // BearishConsolidationZones ); // - if (poiEventNotifier.hasNewConsolidationZone) + if (poiEventNotifier.hasNewPullback) { - Print("Consolidation ..."); + Print("Pullback ..."); } // diff --git a/Libraries/x-saherelm.x-poi.lib.mq5 b/Libraries/x-saherelm.x-poi.lib.mq5 index 3438ac97..915c6d79 100644 --- a/Libraries/x-saherelm.x-poi.lib.mq5 +++ b/Libraries/x-saherelm.x-poi.lib.mq5 @@ -76,6 +76,9 @@ enum ENUM_XPOIS // X_BULLISH_SPIKE, X_BEARISH_SPIKE, + // + X_BULLISH_PULLBACK, + X_BEARISH_PULLBACK, }; // @@ -126,6 +129,8 @@ enum ENUM_XPOI_EVENTS X_BEARISH_SHARP_DETECTED, X_BULLISH_SPIKE_DETECTED, X_BEARISH_SPIKE_DETECTED, + X_BULLISH_PULLBACK_DETECTED, + X_BEARISH_PULLBACK_DETECTED, }; // diff --git a/Libraries/x-saherelm.x-poi.state.lib.mq5 b/Libraries/x-saherelm.x-poi.state.lib.mq5 index 26c81bdb..e5dbfa82 100644 --- a/Libraries/x-saherelm.x-poi.state.lib.mq5 +++ b/Libraries/x-saherelm.x-poi.state.lib.mq5 @@ -667,6 +667,12 @@ struct XPOIStateEvents bool hasNewBullishRejection; bool hasNewBearishRejection; + // + // Pullbacks ... + bool hasNewPullback; + bool hasNewBullishPullback; + bool hasNewBearishPullback; + // // Support/Resistance (s) ... bool hasNewSupportZone; @@ -796,6 +802,11 @@ struct XPOIStateEvents hasNewBullishRejection = HasNewBullishRejection(events); hasNewBearishRejection = HasNewBearishRejection(events); + // + hasNewPullback = HasNewPullback(events); + hasNewBullishPullback = HasNewBullishPullback(events); + hasNewBearishPullback = HasNewBearishPullback(events); + // hasNewSupportZone = HasNewSupportZone(events); hasNewResistanceZone = HasNewResistanceZone(events); @@ -890,6 +901,11 @@ struct XPOIState XBoxZone bullishSharps[]; // Holds Founded Bullish Sharps ... XBoxZone bearishSharps[]; // Holds Founded Bearih Sharps ... + // + XBoxZone pullbacks[]; // Holds Founded Pullbacks ... + XBoxZone bullishPullbacks[]; // Holds Founded Bullish Pullbacks ... + XBoxZone bearishPullbacks[]; // Holds Founded Bearish Pullbacks ... + // // Constructor ... void XPOIState() @@ -962,6 +978,12 @@ struct XPOIState Clean(bullishSharps); Clean(bearishSharps); + // + // Pullbaks ... + Clean(pullbacks); + Clean(bullishPullbacks); + Clean(bearishPullbacks); + // // Consolidation Zones ... Clean(consolidationZones); @@ -1020,6 +1042,11 @@ struct XPOIState HasBullishRejections() || HasBearishRejections() || // + // Pullbacks ... + HasPullbacks() || + HasBullishPullbacks() || + HasBearishPullbacks() || + // // Support / Resistance Zones ... HasSupportZones() || HasResistanceZones() || @@ -1197,6 +1224,51 @@ struct XPOIState return ArraySize(bearishRejections); } + // + // Pullbacks ... + + // + // Has ... + + // + bool HasPullbacks() + { + return HasChild(pullbacks); + } + + // + bool HasBullishPullbacks() + { + return HasChild(bullishPullbacks); + } + + // + bool HasBearishPullbacks() + { + return HasChild(bearishPullbacks); + } + + // + // Count ... + + // + int CountPullbacks() + { + return ArraySize(pullbacks); + } + + // + int CountBullishPullbacks() + { + return ArraySize(bullishPullbacks); + } + + // + int CountBearishPullbacks() + { + return ArraySize(bearishPullbacks); + } + // // Support / Resistance Zones ... @@ -5038,6 +5110,34 @@ bool HasNewBearishSharp(ENUM_XPOI_EVENTS &events[]) ); } +// +// Pullbacks ... + +// +bool HasNewPullback(ENUM_XPOI_EVENTS &events[]) +{ + return HasNewBullishPullback(events) || + HasNewBearishPullback(events); +} + +// +bool HasNewBullishPullback(ENUM_XPOI_EVENTS &events[]) +{ + return Contains( + X_BULLISH_PULLBACK_DETECTED, + events // + ); +} + +// +bool HasNewBearishPullback(ENUM_XPOI_EVENTS &events[]) +{ + return Contains( + X_BEARISH_PULLBACK_DETECTED, + events // + ); +} + // // Consolidation Zones ...