From 5dc8ddb7da5e34f9dc0faeff6c1b1bdd267c0c75 Mon Sep 17 00:00:00 2001 From: Hadi Khazaee Asl Date: Thu, 24 Oct 2024 21:17:05 +0330 Subject: [PATCH] Last Works On Correction HasObjectsFunctions till Market Session Objects ... --- Classes/x-saherelm.x-chart-objects.class.mq5 | 148 +- Classes/x-saherelm.x-poi.class.mq5 | 2059 ++++++++++++++++-- Experts/x-saherelm.x-121.smc.ea.mq5 | 22 +- Libraries/x-saherelm.common.lib.mq5 | 34 +- Libraries/x-saherelm.x-poi.lib.mq5 | 36 +- 5 files changed, 2032 insertions(+), 267 deletions(-) diff --git a/Classes/x-saherelm.x-chart-objects.class.mq5 b/Classes/x-saherelm.x-chart-objects.class.mq5 index 94691405..8e3fe276 100644 --- a/Classes/x-saherelm.x-chart-objects.class.mq5 +++ b/Classes/x-saherelm.x-chart-objects.class.mq5 @@ -46,6 +46,8 @@ enum ENUM_XCHARTOBJECTS X_DEMAND_ZONE, X_BULLISH_ORDERBLOCK, X_BEARISH_ORDERBLOCK, + X_BULLISH_FVG, + X_BEARISH_FVG, }; enum ENUM_X_CHART_IDS @@ -105,9 +107,51 @@ string ToString(ENUM_X_CHART_IDS value) // // Global Chart Objects ... +// +// Bas Chart Object ... +class XCBaseObject : public CChartObject +{ + // + public: + // + + // + // Getter(s) / Setter(s) ... + + /** + * Get Object Specified Name ... + * + * @return ( string ) + */ + string ObjName() + { + return mObjName; + } + + /** + * Set Object Specified Name ... + * + * @param value: String ... + */ + void ObjName(string value) + { + mObjName = value; + } + + // + private: + // + + // + // Props ... + string mObjName; // Object Specified Name ... + + // +}; + // // From To Chart Object ... -class XCFromToObject : public CChartObject +class XCFromToObject : public XCBaseObject { // public: @@ -141,19 +185,15 @@ class XCFromToObject : public CChartObject const string name, const int window, const datetime from, - const datetime to, - const string objprefix = NULL // + const datetime to // ) { // bool result = false; - // - string mPrefix = (IsValid(objprefix) ? objprefix + "_" : ""); - // string mFromVLineName = - mPrefix + ToString(X_FROM) + "_" + name; + ToString(X_FROM) + "_" + name; result = mFromVLine.Create(chart_id, mFromVLineName, window, from); if (!result) { @@ -162,13 +202,17 @@ class XCFromToObject : public CChartObject // string mToVLineName = - mPrefix + ToString(X_TO) + "_" + name; + ToString(X_TO) + "_" + name; result = mToVLine.Create(chart_id, mToVLineName, window, to); if (!result) { return result; } + // + // Set Object Name ... + ObjName(name); + // return result; } @@ -246,7 +290,7 @@ class XCFromToObject : public CChartObject // // Zone Chart Object ... -class XCZoneObject : public CChartObject +class XCZoneObject : public XCBaseObject { // public: @@ -321,6 +365,11 @@ class XCZoneObject : public CChartObject !IsValid(objprefix) ? "" : objprefix + "_"; + result = Name(prefix); + if (!result) + { + return result; + } // // Check Params For Rectangle ... @@ -393,6 +442,12 @@ class XCZoneObject : public CChartObject } } + // + if (result) + { + ObjName(name); + } + // return result; } @@ -570,8 +625,7 @@ class XCTardeDayObject : public XCFromToObject name, window, day.from, - day.to, - "XTDAY" // + day.to // ); // @@ -639,14 +693,12 @@ class XCMarketSessionObject : public XCFromToObject bool result = false; // - string sessionLabel = ToString(session.session); result = Create( chart_id, name, window, session.from, - session.to, - sessionLabel // + session.to // ); // @@ -982,3 +1034,71 @@ class XCBearishOrderBlockObject : public XCZoneObject }; // +// Bullish FVG ... + +class XCBullishFVGObject : public XCZoneObject +{ + // + public: + // + + // + // Constructors ... + void XCBullishFVGObject() + { + } + + // + // Deconstructors ... + void ~XCBullishFVGObject() + { + } + + /** + * Retrieve Object Type ... + * + * @return ( ENUM_XCHARTOBJECTS ) + */ + virtual ENUM_XCHARTOBJECTS Type() + { + return X_BULLISH_FVG; + } + + // +}; + +// +// Bearish FVG ... + +class XCBearishFVGObject : public XCZoneObject +{ + // + public: + // + + // + // Constructors ... + void XCBearishFVGObject() + { + } + + // + // Deconstructors ... + void ~XCBearishFVGObject() + { + } + + /** + * Retrieve Object Type ... + * + * @return ( ENUM_XCHARTOBJECTS ) + */ + virtual ENUM_XCHARTOBJECTS Type() + { + return X_BEARISH_FVG; + } + + // +}; + +// diff --git a/Classes/x-saherelm.x-poi.class.mq5 b/Classes/x-saherelm.x-poi.class.mq5 index 0c33c2d4..26ca0a93 100644 --- a/Classes/x-saherelm.x-poi.class.mq5 +++ b/Classes/x-saherelm.x-poi.class.mq5 @@ -1715,6 +1715,269 @@ class XCPOI : public XSCBaseAlert mRequiredBarsForBearishOrderBlock = value; } + // + // Fair Value Gaps ... + + // + // Bullis FVGs ... + + /** + * Get Draw Bullish Fair Value Gaps ... + * + * @return ( bool ) + */ + bool AllowDrawBullishFVGs() + { + return mAllowDrawBullishFVGs; + } + + /** + * Set Draw Bullish Fair Value Gaps ... + * + * @param value: Boolean ... + */ + void AllowDrawBullishFVGs(bool value) + { + mAllowDrawBullishFVGs = value; + } + + /** + * Get Bullish FVG Force Middle Bar Check ... + * + * @return ( bool ) + */ + bool BullishFVGForceMiddleBarCheck() + { + return mBullishFVGForceMiddleBarCheck; + } + + /** + * Set Bullish FVG Force Middle Bar Check ... + * + * @param value: Boolean ... + */ + void BullishFVGForceMiddleBarCheck(bool value) + { + mBullishFVGForceMiddleBarCheck = value; + } + + /** + * Get Bullish FVG Force Check Last Bar Direction ... + * + * @return ( bool ) + */ + bool BullishFVGForceCheckLastBarDirection() + { + return mBullishFVGForceCheckLastBarDirection; + } + + /** + * Set Bullish FVG Force Check Last Bar Direction ... + * + * @param value: Boolean ... + */ + void BullishFVGForceCheckLastBarDirection(bool value) + { + mBullishFVGForceCheckLastBarDirection = value; + } + + /** + * Get Bullish FVG Width ... + * + * @return ( int ) + */ + int BullishFVGWidth() + { + return mBullishFVGWidth; + } + + /** + * Set Bullish FVG Width ... + * + * @param value: Integer ... + */ + void BullishFVGWidth(int value) + { + // + if (value < 1) + { + value = 1; + } + + // + mBullishFVGWidth = value; + } + + /** + * Get Bullish FVG Color ... + * + * @return ( color ) + */ + color BullishFVGColor() + { + return mBullishFVGColor; + } + + /** + * Set Bullish FVG Color ... + * + * @param value: Color ... + */ + void BullishFVGColor(color value) + { + mBullishFVGColor = value; + } + + /** + * Get Bullish FVG Style ... + * + * @return ( ENUM_LINE_STYLE ) + */ + ENUM_LINE_STYLE BullishFVGStyle() + { + return mBullishFVGStyle; + } + + /** + * Set Bullish FVG Style ... + * + * @param value: ENUM_LINE_STYLE member ... + */ + void BullishFVGStyle(ENUM_LINE_STYLE value) + { + mBullishFVGStyle = value; + } + + // + // Bullis FVGs ... + + /** + * Get Draw Bearish Fair Value Gaps ... + * + * @return ( bool ) + */ + bool AllowDrawBearishFVGs() + { + return mAllowDrawBearishFVGs; + } + + /** + * Set Draw Bearish Fair Value Gaps ... + * + * @param value: Boolean ... + */ + void AllowDrawBearishFVGs(bool value) + { + mAllowDrawBearishFVGs = value; + } + + /** + * Get Bearish FVG Force Middle Bar Check ... + * + * @return ( bool ) + */ + bool BearishFVGForceMiddleBarCheck() + { + return mBearishFVGForceMiddleBarCheck; + } + + /** + * Set Bearish FVG Force Middle Bar Check ... + * + * @param value: Boolean ... + */ + void BearishFVGForceMiddleBarCheck(bool value) + { + mBearishFVGForceMiddleBarCheck = value; + } + + /** + * Get Bearish FVG Force Check Last Bar Direction ... + * + * @return ( bool ) + */ + bool BearishFVGForceCheckLastBarDirection() + { + return mBearishFVGForceCheckLastBarDirection; + } + + /** + * Set Bearish FVG Force Check Last Bar Direction ... + * + * @param value: Boolean ... + */ + void BearishFVGForceCheckLastBarDirection(bool value) + { + mBearishFVGForceCheckLastBarDirection = value; + } + + /** + * Get Bearish FVG Width ... + * + * @return ( int ) + */ + int BearishFVGWidth() + { + return mBearishFVGWidth; + } + + /** + * Set Bearish FVG Width ... + * + * @param value: Integer ... + */ + void BearishFVGWidth(int value) + { + // + if (value < 1) + { + value = 1; + } + + // + mBearishFVGWidth = value; + } + + /** + * Get Bearish FVG Color ... + * + * @return ( color ) + */ + color BearishFVGColor() + { + return mBearishFVGColor; + } + + /** + * Set Bearish FVG Color ... + * + * @param value: Color ... + */ + void BearishFVGColor(color value) + { + mBearishFVGColor = value; + } + + /** + * Get Bearish FVG Style ... + * + * @return ( ENUM_LINE_STYLE ) + */ + ENUM_LINE_STYLE BearishFVGStyle() + { + return mBearishFVGStyle; + } + + /** + * Set Bearish FVG Style ... + * + * @param value: ENUM_LINE_STYLE member ... + */ + void BearishFVGStyle(ENUM_LINE_STYLE value) + { + mBearishFVGStyle = value; + } + // // Actions ... @@ -1975,23 +2238,28 @@ class XCPOI : public XSCBaseAlert if (isSingHigh) { // - AddRef( + bool isAdded = AddBar( + X_POI_SWING_HIGH, pBar, mSwingHighs // ); - swingHighsCount = ArraySize(mSwingHighs); // - DrawSwingHighs(); + if (isAdded) + { + // + swingHighsCount = ArraySize(mSwingHighs); + DrawSwingHighs(); - // - ENUM_XPOI_EVENTS event = X_SWING_HIGH_DETECTED; - Add( - event, - state // - ); - OnSwingHighEvent(event, pBar); - NotifySwingHighEventListeners(event, pBar); + // + ENUM_XPOI_EVENTS event = X_SWING_HIGH_DETECTED; + Add( + event, + state // + ); + OnSwingHighEvent(event, pBar); + NotifySwingHighEventListeners(event, pBar); + } } // @@ -2003,23 +2271,28 @@ class XCPOI : public XSCBaseAlert if (isSingLow) { // - AddRef( + bool isAdded = AddBar( + X_POI_SWING_LOW, pBar, mSwingLows // ); - swingLowsCount = ArraySize(mSwingLows); // - DrawSwingLows(); + if (isAdded) + { + // + swingLowsCount = ArraySize(mSwingLows); + DrawSwingLows(); - // - ENUM_XPOI_EVENTS event = X_SWING_LOW_DETECTED; - Add( - event, - state // - ); - OnSwingLowEvent(event, pBar); - NotifySwingLowEventListeners(event, pBar); + // + ENUM_XPOI_EVENTS event = X_SWING_LOW_DETECTED; + Add( + event, + state // + ); + OnSwingLowEvent(event, pBar); + NotifySwingLowEventListeners(event, pBar); + } } // @@ -2043,23 +2316,28 @@ class XCPOI : public XSCBaseAlert if (isMomentumBar) { // - AddRef( + bool isAdded = AddBar( + X_POI_MOMENTUM_BAR, cBar, mMomentumBars // ); - momentumBarsCount = ArraySize(mMomentumBars); // - DrawMomentumBars(); + if (isAdded) + { + // + momentumBarsCount = ArraySize(mMomentumBars); + DrawMomentumBars(); - // - ENUM_XPOI_EVENTS event = X_MOMENTUM_BAR_DETECTED; - Add( - event, - state // - ); - OnMomentumBarEvent(event, cBar); - NotifyMomentumBarEventListeners(event, cBar); + // + ENUM_XPOI_EVENTS event = X_MOMENTUM_BAR_DETECTED; + Add( + event, + state // + ); + OnMomentumBarEvent(event, cBar); + NotifyMomentumBarEventListeners(event, cBar); + } } // @@ -2091,23 +2369,28 @@ class XCPOI : public XSCBaseAlert if (isRejectionBar) { // - AddRef( + bool isAdded = AddBar( + X_POI_REJECTION_BAR, iRBar, mRejectionBars // ); - rejectionBarsCount = ArraySize(mRejectionBars); // - DrawRejectionBars(); + if (isAdded) + { + // + rejectionBarsCount = ArraySize(mRejectionBars); + DrawRejectionBars(); - // - ENUM_XPOI_EVENTS event = X_REJECTION_BAR_DETECTED; - Add( - event, - state // - ); - OnRejectionBarEvent(event, iRBar); - NotifyRejectionBarEventListeners(event, iRBar); + // + ENUM_XPOI_EVENTS event = X_REJECTION_BAR_DETECTED; + Add( + event, + state // + ); + OnRejectionBarEvent(event, iRBar); + NotifyRejectionBarEventListeners(event, iRBar); + } } } @@ -2128,13 +2411,17 @@ class XCPOI : public XSCBaseAlert if (hasSupport) { // - bool isAdded = AddSupportZone(support); + bool isAdded = AddBar( + X_POI_SUPPORT_ZONE, + support, + mSupportZones // + ); + + // if (isAdded) { // supportZonesCount = ArraySize(mSupportZones); - - // DrawSupportZones(); // @@ -2162,13 +2449,17 @@ class XCPOI : public XSCBaseAlert if (hasResistance) { // - bool isAdded = AddResistanceZone(resistance); + bool isAdded = AddBar( + X_POI_RESISTANCE_ZONE, + resistance, + mResistanceZones // + ); + + // if (isAdded) { // resistanceZonesCount = ArraySize(mResistanceZones); - - // DrawResistanceZones(); // @@ -2454,7 +2745,7 @@ class XCPOI : public XSCBaseAlert { // XZone obZone; - bool isAdded = AddOrderBlock( + bool isAdded = AddZone( obZone, // Dest ... bullOB, cBar.time, @@ -2492,7 +2783,7 @@ class XCPOI : public XSCBaseAlert { // XZone zone; - bool isAdded = AddOrderBlock( + bool isAdded = AddZone( zone, // bearOB, cBar.time, @@ -2516,9 +2807,101 @@ class XCPOI : public XSCBaseAlert } } + // + // Fair Value Gaps ... + double upper; + double lower; + datetime start; + datetime end; + + // + // Bullish FVGs ... + int bullishFVGsCount = ArraySize(mBullishFVGs); + bool hasBullishFVG = cBar.HasBullishFVG( + upper, + lower, + start, + end, + BullishFVGForceMiddleBarCheck(), + BullishFVGForceCheckLastBarDirection() // + ); + if (hasBullishFVG) + { + // + XZone zone; + bool isAdded = AddZone( + zone, + upper, + lower, + start, + end, + X_POI_BULLISH_FVG, + mBullishFVGs // + ); + if (isAdded) + { + // + bullishFVGsCount = ArraySize(mBullishFVGs); + DrawBullishFVGs(); + + // + ENUM_XPOI_EVENTS event = X_BULLISH_FVG_DETECTED; + Add( + event, + state // + ); + OnBullishFVGEvent(event, zone); + NotifyBullishFVGEventListeners(event, zone); + } + } + + // + // Bearish FVGs ... + int bearishFVGsCount = ArraySize(mBearishFVGs); + bool hasBearishFVG = cBar.HasBearishFVG( + upper, + lower, + start, + end, + BearishFVGForceMiddleBarCheck(), + BearishFVGForceCheckLastBarDirection() // + ); + if (hasBearishFVG) + { + // + XZone zone; + bool isAdded = AddZone( + zone, + upper, + lower, + start, + end, + X_POI_BEARISH_FVG, + mBearishFVGs // + ); + if (isAdded) + { + // + bearishFVGsCount = ArraySize(mBearishFVGs); + DrawBearishFVGs(); + + // + ENUM_XPOI_EVENTS event = X_BEARISH_FVG_DETECTED; + Add( + event, + state // + ); + OnBearishFVGEvent(event, zone); + NotifyBearishFVGEventListeners(event, zone); + } + } + // // ... + // + CleanupUnusedPOIs(); + // mBarTracker.Waits(); @@ -2557,6 +2940,8 @@ class XCPOI : public XSCBaseAlert AllowDrawSwingHighs(state); AllowDrawTradingDays(state); AllowDrawSupplyZones(state); + AllowDrawBullishFVGs(state); + AllowDrawBearishFVGs(state); AllowDrawDemandZones(state); AllowDrawSupportZones(state); AllowDrawMomentumBars(state); @@ -2764,6 +3149,25 @@ class XCPOI : public XSCBaseAlert BearishOrderBlockStyle(STYLE_DASHDOT); RequiredBarsForBearishOrderBlock(3); + // + // Fair Value Gaps ... + + // + // Bullish FVGs ... + BullishFVGWidth(1); + BullishFVGColor(clrAqua); + BullishFVGStyle(STYLE_DASHDOTDOT); + BullishFVGForceMiddleBarCheck(true); + BullishFVGForceCheckLastBarDirection(true); + + // + // Bearish FVGs ... + BearishFVGWidth(1); + BearishFVGColor(clrMagenta); + BearishFVGStyle(STYLE_DASHDOTDOT); + BearishFVGForceMiddleBarCheck(true); + BearishFVGForceCheckLastBarDirection(true); + // } @@ -3163,6 +3567,69 @@ class XCPOI : public XSCBaseAlert ); } + // + // Fai Value Gaps ... + + // + // Bullish FVGs ... + + /** + * Calls When new Bullish FVG Event ... + * + * @param event: ENUM_XPOI_EVENTS member ... + * @param zone: XZone instance ... + */ + virtual void OnBullishFVGEvent( + ENUM_XPOI_EVENTS event, + XZone &zone // + ) + { + } + + /** + * Register an Event Listener for New Bullish FVG Event ... + * + * @param listener: TXZoneEventHandler instance ... + */ + void AddBullishFVGEventListener(TXZoneEventHandler listener) + { + // + Add( + listener, + mBullishFVGEventListeners // + ); + } + + // + // Bearish FVGs ... + + /** + * Calls When new Bearish FVG Event ... + * + * @param event: ENUM_XPOI_EVENTS member ... + * @param zone: XZone instance ... + */ + virtual void OnBearishFVGEvent( + ENUM_XPOI_EVENTS event, + XZone &zone // + ) + { + } + + /** + * Register an Event Listener for New Bearish FVG Event ... + * + * @param listener: TXZoneEventHandler instance ... + */ + void AddBearishFVGEventListener(TXZoneEventHandler listener) + { + // + Add( + listener, + mBearishFVGEventListeners // + ); + } + // protected: // @@ -3373,13 +3840,17 @@ class XCPOI : public XSCBaseAlert if (isSwingHigh) { // - AddRef( + bool isAdded = AddBar( + X_POI_SWING_HIGH, cBar, mSwingHighs // ); // - swingHighsCount = ArraySize(mSwingHighs); + if (isAdded) + { + swingHighsCount = ArraySize(mSwingHighs); + } } } @@ -3393,13 +3864,17 @@ class XCPOI : public XSCBaseAlert if (isSwingLow) { // - AddRef( + bool isAdded = AddBar( + X_POI_SWING_LOW, cBar, mSwingLows // ); // - swingLowsCount = ArraySize(mSwingLows); + if (isAdded) + { + swingLowsCount = ArraySize(mSwingLows); + } } } @@ -3433,13 +3908,17 @@ class XCPOI : public XSCBaseAlert if (isMomentumBar) { // - AddRef( + bool isAdded = AddBar( + X_POI_MOMENTUM_BAR, cBar, mMomentumBars // ); // - momentumBarsCount = ArraySize(mMomentumBars); + if (isAdded) + { + momentumBarsCount = ArraySize(mMomentumBars); + } } } @@ -3465,13 +3944,17 @@ class XCPOI : public XSCBaseAlert if (isRejectionBar) { // - AddRef( + bool isAdded = AddBar( + X_POI_REJECTION_BAR, cBar, mRejectionBars // ); // - rejectionBarsCount = ArraySize(mRejectionBars); + if (isAdded) + { + rejectionBarsCount = ArraySize(mRejectionBars); + } } } @@ -3495,7 +3978,13 @@ class XCPOI : public XSCBaseAlert if (hasSupport) { // - bool isAdded = AddSupportZone(support); + bool isAdded = AddBar( + X_POI_SUPPORT_ZONE, + support, + mSupportZones // + ); + + // if (isAdded) { supportZonesCount = ArraySize(mSupportZones); @@ -3520,7 +4009,13 @@ class XCPOI : public XSCBaseAlert if (hasResistance) { // - bool isAdded = AddResistanceZone(resistance); + bool isAdded = AddBar( + X_POI_RESISTANCE_ZONE, + resistance, + mResistanceZones // + ); + + // if (isAdded) { resistanceZonesCount = ArraySize(mResistanceZones); @@ -3745,7 +4240,7 @@ class XCPOI : public XSCBaseAlert { // XZone zone; - bool isAdded = AddOrderBlock( + bool isAdded = AddZone( zone, // ob, cBar.time, @@ -3774,7 +4269,7 @@ class XCPOI : public XSCBaseAlert { // XZone zone; - bool isAdded = AddOrderBlock( + bool isAdded = AddZone( zone, // ob, cBar.time, @@ -3788,6 +4283,85 @@ class XCPOI : public XSCBaseAlert } } + // + // Fair Value Gaps ... + + // + // Bullish FVGs ... + int bullishFVGsCount = ArraySize(mBullishFVGs); + if (bullishFVGsCount < requiredPOIs) + { + // + double upper; + double lower; + datetime start; + datetime end; + bool hasBullishFVG = cBar.HasBullishFVG( + upper, + lower, + start, + end, + BullishFVGForceMiddleBarCheck(), + BullishFVGForceCheckLastBarDirection() // + ); + if (hasBullishFVG) + { + // + XZone zone; + bool isAdded = AddZone( + zone, + upper, + lower, + start, + end, + X_POI_BULLISH_FVG, + mBullishFVGs // + ); + if (isAdded) + { + bullishFVGsCount = ArraySize(mBullishFVGs); + } + } + } + + // + // Bearish FVGs ... + int bearishFVGsCount = ArraySize(mBearishFVGs); + if (bearishFVGsCount < requiredPOIs) + { + // + double upper; + double lower; + datetime start; + datetime end; + bool hasBearishFVG = cBar.HasBearishFVG( + upper, + lower, + start, + end, + BearishFVGForceMiddleBarCheck(), + BearishFVGForceCheckLastBarDirection() // + ); + if (hasBearishFVG) + { + // + XZone zone; + bool isAdded = AddZone( + zone, + upper, + lower, + start, + end, + X_POI_BEARISH_FVG, + mBearishFVGs // + ); + if (isAdded) + { + bearishFVGsCount = ArraySize(mBearishFVGs); + } + } + } + // // Detect Required Conditions for Loop ... // @@ -3825,7 +4399,11 @@ class XCPOI : public XSCBaseAlert // // Order Blocks ... bullishOrderBlocksCount < requiredPOIs || - bearishOrderBlocksCount < requiredPOIs + bearishOrderBlocksCount < requiredPOIs || + // + // Fair Value Gaps ... + bullishFVGsCount < requiredPOIs || + bearishFVGsCount < requiredPOIs // ; if (canContinue) @@ -4022,6 +4600,35 @@ class XCPOI : public XSCBaseAlert ); Clean(tmpZones); + // + // Fair Value Gaps ... + + // + Copy( + mBullishFVGs, + tmpZones // + ); + Clean(mBullishFVGs); + ArrayReverse(tmpZones); + Copy( + tmpZones, + mBullishFVGs // + ); + Clean(tmpZones); + + // + Copy( + mBearishFVGs, + tmpZones // + ); + Clean(mBearishFVGs); + ArrayReverse(tmpZones); + Copy( + tmpZones, + mBearishFVGs // + ); + Clean(tmpZones); + // // ... @@ -4039,32 +4646,45 @@ class XCPOI : public XSCBaseAlert void DestroyPOIs() { // + // Trading Days ... DestroyTradingDays(); // + // Market Sessions ... DestroyMarketSessions(); // + // Momentum Bars ... + DestroyMomentumBars(); + + // + // Rejection Bars ... + DestroyRejectionBars(); + + // + // Swing High and Zone (s) ... DestroySwingHighs(); DestroySwingLows(); // - DestroyMomentumBars(); - - // - DestroyRejectionBars(); - - // + // Support and Resistance Zones ... DestroySupportZones(); DestroyResistanceZones(); // + // Supply and Demand Zones ... DestroySupplyZones(); DestroyDemandZones(); // + // Order Blocks ... DestroyBullishOrderBlocks(); DestroyBearishOrderBlocks(); + + // + // Fai Value Gaps ... + DestroyBullishFVGs(); + DestroyBearishFVGs(); } /** @@ -4163,6 +4783,22 @@ class XCPOI : public XSCBaseAlert Clean(mBearishOrderBlocks); } + /** + * Destroy Bullish FVGs ... + */ + void DestroyBullishFVGs() + { + Clean(mBullishFVGs); + } + + /** + * Destroy Bearish FVGs ... + */ + void DestroyBearishFVGs() + { + Clean(mBearishFVGs); + } + // // Draw Actions ... @@ -4172,32 +4808,45 @@ class XCPOI : public XSCBaseAlert void DrawPOIs() { // + // Trading Days ... DrawTradingDays(); // + // Market Sessions ... DrawMarketSessions(); // + // Momentum Bars ... + DrawMomentumBars(); + + // + // Rejection Bars ... + DrawRejectionBars(); + + // + // Swing High and Low (s) ... DrawSwingHighs(); DrawSwingLows(); // - DrawMomentumBars(); - - // - DrawRejectionBars(); - - // + // Support and Resistance (s) ... DrawSupportZones(); DrawResistanceZones(); // + // Supply and Demand Zones ... DrawSupplyZones(); DrawDemandZones(); // + // Order Blocks ... DrawBullishOrderBlocks(); DrawBearishOrderBlocks(); + + // + // Fair Value Gaps ... + DrawBullishFVGs(); + DrawBearishFVGs(); } /** @@ -4227,9 +4876,8 @@ class XCPOI : public XSCBaseAlert // string iName = iDay.GetTag(); - int iIDX = HasObject( - iName, - mTradingDayObjects // + int iIDX = HasTradingDayObject( + iName // ); if (IsValidIndex(iIDX)) { @@ -4241,6 +4889,50 @@ class XCPOI : public XSCBaseAlert } } + /** + * Check a Trading Day is Drawn Before or not ... + * + * @param name: String ... + * + * @return ( int ) + */ + int HasTradingDayObject( + string name // + ) + { + // + int result = -1; + + // + if (!IsValid(name)) + { + return result; + } + + // + int count = mTradingDayObjects.Total(); + if (!IsValidSize(count)) + { + return result; + } + + // + for (int i = 0; i < count; i++) + { + // + string objName = ((XCBaseObject *)mTradingDayObjects.At(i)).ObjName(); + if (objName == name) + { + // + result = i; + break; + } + } + + // + return result; + } + /** * Draw Swing Highs ... */ @@ -4268,9 +4960,8 @@ class XCPOI : public XSCBaseAlert // string iName = iSwing.GetTag(ToString(X_POI_SWING_HIGH)); - int iIDX = HasObject( - iName, - mSwingHighObjects // + int iIDX = HasSwingHighObject( + iName // ); if (IsValidIndex(iIDX)) { @@ -4282,6 +4973,50 @@ class XCPOI : public XSCBaseAlert } } + /** + * Check a Swing High is Drawn Before or not ... + * + * @param name: String ... + * + * @return ( int ) + */ + int HasSwingHighObject( + string name // + ) + { + // + int result = -1; + + // + if (!IsValid(name)) + { + return result; + } + + // + int count = mSwingHighObjects.Total(); + if (!IsValidSize(count)) + { + return result; + } + + // + for (int i = 0; i < count; i++) + { + // + string objName = ((CChartObjectArrow *)mSwingHighObjects.At(i)).Name(); + if (objName == name) + { + // + result = i; + break; + } + } + + // + return result; + } + /** * Draw Swing Lows ... */ @@ -4309,9 +5044,8 @@ class XCPOI : public XSCBaseAlert // string iName = iSwing.GetTag(ToString(X_POI_SWING_LOW)); - int iIDX = HasObject( - iName, - mSwingLowObjects // + int iIDX = HasSwingLowObject( + iName // ); if (IsValidIndex(iIDX)) { @@ -4323,6 +5057,50 @@ class XCPOI : public XSCBaseAlert } } + /** + * Check a Swing Low is Drawn Before or not ... + * + * @param name: String ... + * + * @return ( int ) + */ + int HasSwingLowObject( + string name // + ) + { + // + int result = -1; + + // + if (!IsValid(name)) + { + return result; + } + + // + int count = mSwingLowObjects.Total(); + if (!IsValidSize(count)) + { + return result; + } + + // + for (int i = 0; i < count; i++) + { + // + string objName = ((CChartObjectArrow *)mSwingLowObjects.At(i)).Name(); + if (objName == name) + { + // + result = i; + break; + } + } + + // + return result; + } + /** * Draw Momentum Bars ... */ @@ -4350,9 +5128,8 @@ class XCPOI : public XSCBaseAlert // string iName = iBar.GetTag(ToString(X_POI_MOMENTUM_BAR)); - int iIDX = HasObject( - iName, - mMomentumBarObjects // + int iIDX = HasMomentumBarObject( + iName // ); if (IsValidIndex(iIDX)) { @@ -4364,6 +5141,50 @@ class XCPOI : public XSCBaseAlert } } + /** + * Check a Momentum Bar is Drawn Before or not ... + * + * @param name: String ... + * + * @return ( int ) + */ + int HasMomentumBarObject( + string name // + ) + { + // + int result = -1; + + // + if (!IsValid(name)) + { + return result; + } + + // + int count = mMomentumBarObjects.Total(); + if (!IsValidSize(count)) + { + return result; + } + + // + for (int i = 0; i < count; i++) + { + // + string objName = ((CChartObjectArrow *)mMomentumBarObjects.At(i)).Name(); + if (objName == name) + { + // + result = i; + break; + } + } + + // + return result; + } + /** * Draw Rejection Bars ... */ @@ -4391,9 +5212,8 @@ class XCPOI : public XSCBaseAlert // string iName = iBar.GetTag(ToString(X_POI_REJECTION_BAR)); - int iIDX = HasObject( - iName, - mRejectionBarObjects // + int iIDX = HasRejectionBarObject( + iName // ); if (IsValidIndex(iIDX)) { @@ -4405,6 +5225,50 @@ class XCPOI : public XSCBaseAlert } } + /** + * Check a Rejection Bar is Drawn Before or not ... + * + * @param name: String ... + * + * @return ( int ) + */ + int HasRejectionBarObject( + string name // + ) + { + // + int result = -1; + + // + if (!IsValid(name)) + { + return result; + } + + // + int count = mMomentumBarObjects.Total(); + if (!IsValidSize(count)) + { + return result; + } + + // + for (int i = 0; i < count; i++) + { + // + string objName = ((CChartObjectArrow *)mRejectionBarObjects.At(i)).Name(); + if (objName == name) + { + // + result = i; + break; + } + } + + // + return result; + } + /** * Draw Market Sessions ... */ @@ -4432,9 +5296,8 @@ class XCPOI : public XSCBaseAlert // string iName = iMarketSession.GetTag(); - int iIDX = HasObject( - iName, - mMarketSessionObjects // + int iIDX = HasMarketessionObject( + iName // ); if (IsValidIndex(iIDX)) { @@ -4446,6 +5309,50 @@ class XCPOI : public XSCBaseAlert } } + /** + * Check a Market Session is Drawn Before or not ... + * + * @param name: String ... + * + * @return ( int ) + */ + int HasMarketessionObject( + string name // + ) + { + // + int result = -1; + + // + if (!IsValid(name)) + { + return result; + } + + // + int count = mMarketSessionObjects.Total(); + if (!IsValidSize(count)) + { + return result; + } + + // + for (int i = 0; i < count; i++) + { + // + string objName = ((XCMarketSessionObject *)mMarketSessionObjects.At(i)).ObjName(); + if (objName == name) + { + // + result = i; + break; + } + } + + // + return result; + } + /** * Draw Support Zones ... */ @@ -4472,7 +5379,7 @@ class XCPOI : public XSCBaseAlert XOHCL iSupportZone = mSupportZones[i]; // - string iName = iSupportZone.GetTag(ToString(X_POI_SUPPORT)); + string iName = iSupportZone.GetTag(ToString(X_POI_SUPPORT_ZONE)); int iIDX = HasObject( iName, mSupportZoneObjects // @@ -4513,7 +5420,7 @@ class XCPOI : public XSCBaseAlert XOHCL iResistanceZone = mResistanceZones[i]; // - string iName = iResistanceZone.GetTag(ToString(X_POI_RESISTANCE)); + string iName = iResistanceZone.GetTag(ToString(X_POI_RESISTANCE_ZONE)); int iIDX = HasObject( iName, mResistanceZoneObjects // @@ -4524,7 +5431,7 @@ class XCPOI : public XSCBaseAlert } // - CreateResistanceZoneObject(iResistanceZone, iName); + // CreateResistanceZoneObject(iResistanceZone, iName); } } @@ -4692,6 +5599,88 @@ class XCPOI : public XSCBaseAlert } } + /** + * Draw Bullish FVGs ... + */ + void DrawBullishFVGs() + { + // + bool allow = AllowDrawBullishFVGs(); + if (!allow) + { + return; + } + + // + int count = ArraySize(mBullishFVGs); + if (!IsValidSize(count)) + { + return; + } + + // + for (int i = 0; i < count; i++) + { + // + XZone iFVG = mBullishFVGs[i]; + + // + string iName = iFVG.GetTag(); + int iIDX = HasObject( + iName, + mBullishFVGObjects // + ); + if (IsValidIndex(iIDX)) + { + continue; + } + + // + CreateBullishFVGObject(iFVG, iName); + } + } + + /** + * Draw Bearish FVGs ... + */ + void DrawBearishFVGs() + { + // + bool allow = AllowDrawBearishFVGs(); + if (!allow) + { + return; + } + + // + int count = ArraySize(mBearishFVGs); + if (!IsValidSize(count)) + { + return; + } + + // + for (int i = 0; i < count; i++) + { + // + XZone iFVG = mBearishFVGs[i]; + + // + string iName = iFVG.GetTag(); + int iIDX = HasObject( + iName, + mBearishFVGObjects // + ); + if (IsValidIndex(iIDX)) + { + continue; + } + + // + CreateBearishFVGObject(iFVG, iName); + } + } + // /** @@ -4700,18 +5689,45 @@ class XCPOI : public XSCBaseAlert void DestroyObjects() { // + // Trading Days ... + DestroyTradingTradingDayObjects(); + + // + // Market Sessions ... + DestroyMarketSessionObjects(); + + // + // Momentum Bars ... + DestroyMomentumBarObjects(); + + // + // Rejection Bars ... + DestroyRejectionBarObjects(); + + // + // Swing High and Low (s) ... DestroySwingLowObjects(); DestroySwingHighObjects(); + + // + // Support and Resistanc (s) ... + DestroySupportZoneObjects(); + DestroyResistanceZoneObjects(); + + // + // Supply and Demand Zones .. DestroySupplyZoneObjects(); DestroyDemandZoneObjects(); - DestroyMomentumBarObjects(); - DestroySupportZoneObjects(); - DestroyRejectionBarObjects(); - DestroyMarketSessionObjects(); - DestroyResistanceZoneObjects(); - DestroyTradingTradingDayObjects(); + + // + // Order Blocks ... DestroyBullishOrderBlockObjects(); DestroyBearishOrderBlockObjects(); + + // + // Fair Value Gaps ... + DestroyBullishFVGObjects(); + DestroyBearishFVGObjects(); } /** @@ -4810,6 +5826,22 @@ class XCPOI : public XSCBaseAlert mBearishOrderBlockObjects.Clear(); } + /** + * Destroy Bullish FVG Drawn Objects ... + */ + void DestroyBullishFVGObjects() + { + mBullishFVGObjects.Clear(); + } + + /** + * Destroy Bearish FVG Drawn Objects ... + */ + void DestroyBearishFVGObjects() + { + mBearishFVGObjects.Clear(); + } + // // ... @@ -4846,15 +5878,14 @@ class XCPOI : public XSCBaseAlert for (int i = 0; i < count; i++) { // - CChartObject iObj = array.At(i); - - // - if (iObj.Name() == name) - { - // - result = i; - break; - } + // XCBaseObject *iObj = ((XCBaseObject *)array.At(i)); + // string objName = iObj.ObjName(); + // if (objName == name) + // { + // // + // result = i; + // break; + // } } // @@ -5294,24 +6325,120 @@ class XCPOI : public XSCBaseAlert } } + // + // Fair Value Gaps ... + + /** + * Notify New Bullish FVG Event Handlers ... + * + * @param event: ENUM_XPOI_EVENTS member ... + * @param bar: XZone instance ... + */ + void NotifyBullishFVGEventListeners( + ENUM_XPOI_EVENTS event, + XZone &zone // + ) + { + // + if (!zone.IsValid()) + { + return; + } + + // + int count = ArraySize(mBullishFVGEventListeners); + if (!IsValidSize(count)) + { + return; + } + + // + for (int i = 0; i < count; i++) + { + // + TXZoneEventHandler iListener = mBullishFVGEventListeners[i]; + iListener(event, zone); + } + } + + /** + * Notify New Bearish FVG Event Handlers ... + * + * @param event: ENUM_XPOI_EVENTS member ... + * @param bar: XZone instance ... + */ + void NotifyBearishFVGEventListeners( + ENUM_XPOI_EVENTS event, + XZone &zone // + ) + { + // + if (!zone.IsValid()) + { + return; + } + + // + int count = ArraySize(mBearishFVGEventListeners); + if (!IsValidSize(count)) + { + return; + } + + // + for (int i = 0; i < count; i++) + { + // + TXZoneEventHandler iListener = mBearishFVGEventListeners[i]; + iListener(event, zone); + } + } + /** * Destroy all Registered Event Listeners ... */ void DestroyEventListeners() { // + // Trading Days ... + Clean(mTradingDayEventListeners); + + // + // Market Sessions ... + Clean(mMarketSessionEventListeners); + + // + // Momentum Bars ... + Clean(mMomentumBarEventListeners); + + // + // Rejection Bars ... + Clean(mRejectionBarEventListeners); + + // + // Swing High and Low (s) ... Clean(mSwingLowEventListeners); Clean(mSwingHighEventListeners); - Clean(mTradingDayEventListeners); + + // + // Support and Resistance Zones ... + Clean(mSupportZoneEventListeners); + Clean(mResistanceZoneEventListeners); + + // + // Supply and Demand Zones ... Clean(mSupplyZoneEventListeners); Clean(mDemandZoneEventListeners); - Clean(mMomentumBarEventListeners); - Clean(mSupportZoneEventListeners); - Clean(mRejectionBarEventListeners); - Clean(mMarketSessionEventListeners); - Clean(mResistanceZoneEventListeners); + + // + // Order Blocks ... Clean(mBullishOrderBlockEventListeners); Clean(mBearishOrderBlockEventListeners); + + // + // Fair Value Gaps ... + Clean(mBullishFVGEventListeners); + Clean(mBearishFVGEventListeners); } // @@ -5592,66 +6719,30 @@ class XCPOI : public XSCBaseAlert } // - - /** - * Add Specific Support Zone if it's Not Exists ... - * - * @param support: XOHCL instance ... - */ - bool AddSupportZone(XOHCL &support) - { - // - bool result = false; - - // - result = support.IsValid(); - if (!result) - { - return result; - } - - // - int idx = FindSupportZoneIndex(support); - result = !IsValidIndex(idx); - if (!result) - { - return result; - } - - // - int before = ArraySize(mSupportZones); - int after = AddRef( - support, - mSupportZones // - ); - - // - result = before == after - 1; - - // - return result; - } - - /** - * Find Specific Support Zone Index ... - * - * @param support: XOHCL instance ... - * - * @return ( int ) - */ - int FindSupportZoneIndex(XOHCL &support) + int FindBarIndex( + ENUM_XPOIS type, + XOHCL &bar, + XOHCL &list[] // + ) { // int result = -1; // - if (!support.IsValid()) + bool isValidType = + type == X_POI_SWING_LOW || + type == X_POI_SWING_HIGH || + type == X_POI_SUPPORT_ZONE || + type == X_POI_MOMENTUM_BAR || + type == X_POI_REJECTION_BAR || + type == X_POI_RESISTANCE_ZONE; + if (!isValidType) { return result; } // - int count = ArraySize(mSupportZones); + int count = ArraySize(list); if (!IsValidSize(count)) { return result; @@ -5661,11 +6752,56 @@ class XCPOI : public XSCBaseAlert for (int i = 0; i < count; i++) { // - XOHCL iSupport = mSupportZones[i]; + XOHCL iBar = list[i]; // - if (iSupport.low == support.low && - iSupport.GetDown() == support.GetDown()) + bool isSameLow = + bar.low == iBar.low; + + // + bool isSameHigh = + bar.high == iBar.high; + + // + bool isSameUp = + bar.GetUp() == iBar.GetUp(); + + // + bool isSameDown = + bar.GetDown() == iBar.GetDown(); + + // + // Check Conditions Based On Type ... + bool canBreak = false; + if (type == X_POI_SWING_LOW || + type == X_POI_SWING_HIGH || + type == X_POI_MOMENTUM_BAR || + type == X_POI_REJECTION_BAR) + { + // + canBreak = + isSameUp && + isSameLow && + isSameHigh && + isSameDown; + } + else if (type == X_POI_SUPPORT_ZONE) + { + // + canBreak = + isSameLow && + isSameDown; + } + else if (type == X_POI_RESISTANCE_ZONE) + { + // + canBreak = + isSameUp && + isSameHigh; + } + + // + if (canBreak) { // result = i; @@ -5677,25 +6813,42 @@ class XCPOI : public XSCBaseAlert return result; } - /** - * Add Specific Resistance Zone if it's Not Exists ... - * - * @param resistance: XOHCL instance ... - */ - bool AddResistanceZone(XOHCL &resistance) + // + bool AddBar( + ENUM_XPOIS type, + XOHCL &bar, + XOHCL &list[] // + ) { // bool result = false; // - result = resistance.IsValid(); + result = bar.IsValid(); if (!result) { return result; } // - int idx = FindResistanceZoneIndex(resistance); + result = + type == X_POI_SWING_LOW || + type == X_POI_SWING_HIGH || + type == X_POI_SUPPORT_ZONE || + type == X_POI_MOMENTUM_BAR || + type == X_POI_REJECTION_BAR || + type == X_POI_RESISTANCE_ZONE; + if (!result) + { + return result; + } + + // + int idx = FindBarIndex( + type, + bar, + list // + ); result = !IsValidIndex(idx); if (!result) { @@ -5703,60 +6856,11 @@ class XCPOI : public XSCBaseAlert } // - int before = ArraySize(mResistanceZones); - int after = AddRef( - resistance, - mResistanceZones // + AddRef( + bar, + list // ); - // - result = before == after - 1; - - // - return result; - } - - /** - * Find Specific Resistance Zone Index ... - * - * @param resistance: XOHCL instance ... - * - * @return ( int ) - */ - int FindResistanceZoneIndex(XOHCL &resistance) - { - // - int result = -1; - - // - if (!resistance.IsValid()) - { - return result; - } - - // - int count = ArraySize(mResistanceZones); - if (!IsValidSize(count)) - { - return result; - } - - // - for (int i = 0; i < count; i++) - { - // - XOHCL iResistance = mResistanceZones[i]; - - // - if (iResistance.high == resistance.high && - iResistance.GetUp() == resistance.GetUp()) - { - // - result = i; - break; - } - } - // return result; } @@ -5807,7 +6911,7 @@ class XCPOI : public XSCBaseAlert } /** - * Add Specific Order Block to List ... + * Add Specific Zone to List ... * * @param ob: XOHCL ... * @param endTime: Datetime ... @@ -5816,7 +6920,7 @@ class XCPOI : public XSCBaseAlert * * @return ( bool ) */ - bool AddOrderBlock( + bool AddZone( XZone &zone, XOHCL &ob, datetime endTime, @@ -5828,7 +6932,9 @@ class XCPOI : public XSCBaseAlert bool result = false; // - result = type == X_POI_BULLISH_ORDERBLOCK || + result = type == X_POI_SUPPORT_ZONE || + type == X_POI_RESISTANCE_ZONE || + type == X_POI_BULLISH_ORDERBLOCK || type == X_POI_BEARISH_ORDERBLOCK; if (!result) { @@ -5875,6 +6981,370 @@ class XCPOI : public XSCBaseAlert return result; } + /** + * Initiate and Add Specific Zone to List ... + * + * @param zone: XZone instance ... + * @param upper: Double ... + * @param lower: Double ... + * @param start: DateTime ... + * @param end: DateTime ... + * @param type: ENUM_XPOIS member ... + * @param list: XZone instance Collection ... + * + * @return ( bool ) + */ + bool AddZone( + XZone &zone, + double upper, + double lower, + datetime start, + datetime end, + ENUM_XPOIS type, + XZone &list[] // + ) + { + // + bool result = false; + + // + result = zone.Init( + upper, + lower, + ToString(type), + start, + end // + ); + if (!result) + { + return result; + } + + // + int idx = FindZoneIndex( + zone, + list // + ); + result = !IsValidIndex(idx); + if (!result) + { + return result; + } + + // + AddRef( + zone, + list // + ); + + // + return result; + } + + /** + * Cleanup Unused Objects ... + */ + void CleanupUnusedPOIs() + { + // + int maxAllowed = MaxNumberOfPOIs(); + if (!IsValidSize(maxAllowed)) + { + return; + } + + // + int tradingDaysCount = ArraySize(mTradingDays); + int marketSessionsCount = ArraySize(mMarketSessions); + int swingHighsCount = ArraySize(mSwingHighs); + int swingLowsCount = ArraySize(mSwingLows); + int momentumBarsCount = ArraySize(mMomentumBars); + int rejectionBarsCount = ArraySize(mRejectionBars); + int supportZonesCount = ArraySize(mSupportZones); + int resistanceZonesCount = ArraySize(mResistanceZones); + int supplyZonesCount = ArraySize(mSupplyZones); + int demandZonesCount = ArraySize(mDemandZones); + int bullishOBsCount = ArraySize(mBullishOrderBlocks); + int bearishOBsCount = ArraySize(mBearishOrderBlocks); + int bullishFVGsCount = ArraySize(mBullishFVGs); + int bearishFVGsCount = ArraySize(mBearishFVGs); + + // + int from = 0; + int requiredPOIs = MaxNumberOfRequiredPOIs(); + int count = maxAllowed - requiredPOIs; + int to = count - 1; + + // + // Trading Days ... + if (tradingDaysCount >= maxAllowed) + { + // + ArrayRemove( + mTradingDays, + from, + count // + ); + + // + mTradingDayObjects.DeleteRange( + from, + to // + ); + } + + // + // Market Sessions ... + if (marketSessionsCount >= maxAllowed) + { + // + ArrayRemove( + mMarketSessions, + from, + count // + ); + + // + mMarketSessionObjects.DeleteRange( + from, + to // + ); + } + + // + // Momentum Bars ... + if (momentumBarsCount >= maxAllowed) + { + // + ArrayRemove( + mMomentumBars, + from, + count // + ); + + // + mMomentumBarObjects.DeleteRange( + from, + to // + ); + } + + // + // Rejection Bars ... + if (rejectionBarsCount >= maxAllowed) + { + // + ArrayRemove( + mRejectionBars, + from, + count // + ); + + // + mRejectionBarObjects.DeleteRange( + from, + to // + ); + } + + // + // Swing High and Low (s) ... + + // + // Swing Highs ... + if (swingHighsCount >= maxAllowed) + { + // + ArrayRemove( + mSwingHighs, + from, + count // + ); + + // + mSwingHighObjects.DeleteRange( + from, + to // + ); + } + + // + // Swing Lows ... + if (swingLowsCount >= maxAllowed) + { + // + ArrayRemove( + mSwingLows, + from, + count // + ); + + // + mSwingLowObjects.DeleteRange( + from, + to // + ); + } + + // + // Support and Resistance Zones ... + + // + // Support Zones ... + if (supportZonesCount >= maxAllowed) + { + // + ArrayRemove( + mSupportZones, + from, + count // + ); + + // + mSupportZoneObjects.DeleteRange( + from, + to // + ); + } + + // + // Resistance Zones ... + if (resistanceZonesCount >= maxAllowed) + { + // + ArrayRemove( + mResistanceZones, + from, + count // + ); + + // + mResistanceZoneObjects.DeleteRange( + from, + to // + ); + } + + // + // Supply and Demand Zones ... + + // + // Supply Zones ... + if (supplyZonesCount >= maxAllowed) + { + // + ArrayRemove( + mSupplyZones, + from, + count // + ); + + // + mSupplyZoneObjects.DeleteRange( + from, + to // + ); + } + + // + // Demand Zones ... + if (demandZonesCount >= maxAllowed) + { + // + ArrayRemove( + mDemandZones, + from, + count // + ); + + // + mDemandZoneObjects.DeleteRange( + from, + to // + ); + } + + // + // Order Blocks ... + + // + // Bullish Order Blocks ... + if (bullishOBsCount >= maxAllowed) + { + // + ArrayRemove( + mBullishOrderBlocks, + from, + count // + ); + + // + mBullishOrderBlockObjects.DeleteRange( + from, + to // + ); + } + + // + // Bearish Order Blocks ... + if (bearishOBsCount >= maxAllowed) + { + // + ArrayRemove( + mBearishOrderBlocks, + from, + count // + ); + + // + mBearishOrderBlockObjects.DeleteRange( + from, + to // + ); + } + + // + // Fair Vakue Gaps ... + + // + // Bullish FVGs ... + if (bullishFVGsCount >= maxAllowed) + { + // + ArrayRemove( + mBullishFVGs, + from, + count // + ); + + // + mBullishFVGObjects.DeleteRange( + from, + to // + ); + } + + // + // Bearish FVGs ... + if (bearishFVGsCount >= maxAllowed) + { + // + ArrayRemove( + mBearishFVGs, + from, + count // + ); + + // + mBearishFVGObjects.DeleteRange( + from, + to // + ); + } + + // + } + // private: // @@ -6672,6 +8142,125 @@ class XCPOI : public XSCBaseAlert mBearishOrderBlockObjects.Add(iObj); } + // + // Fair Value Gaps ... + + // + // Bullish Fair Value Gaps ... + + // + bool mAllowDrawBullishFVGs; // Draw Bullish Fair Value Gaps ... + bool mBullishFVGForceMiddleBarCheck; // Bullish FVG Force Middle Bar Check ... + bool mBullishFVGForceCheckLastBarDirection; // Bullish FVG Check Last Bar Direction ... + int mBullishFVGWidth; // Bullish FVG Width ... + color mBullishFVGColor; // Bullish FVG Color ... + ENUM_LINE_STYLE mBullishFVGStyle; // Bullish FVG Style ... + XZone mBullishFVGs[]; // Bullish FVGs ... + CArrayObj mBullishFVGObjects; // Bullish FVG Objects ... + TXZoneEventHandler mBullishFVGEventListeners[]; // Bullish FVG Event Listeners ... + + /** + * Create an Object to Represent Bullish FVG on Chart ... + + * @param bar: XZone instance ... + * @param name: String ... + */ + void CreateBullishFVGObject( + XZone &zone, + string name // + ) + { + // + if (!zone.IsValid() || + !IsValid(name)) + { + return; + } + + // + XCBullishFVGObject *iObj; + iObj = new XCBullishFVGObject(); + bool isCreated = iObj.CreateByZone( + ChartID(), + name, + Window(), + zone, + NULL, // Object Prefix ... + true // Force Draw Rect ... + ); + if (!isCreated) + { + return; + } + + // + // Configure Object ... + iObj.ZoneColor(BullishFVGColor()); + iObj.ZoneStyle(BullishFVGStyle()); + iObj.ZoneWidth(BullishFVGWidth()); + + // + mBullishFVGObjects.Add(iObj); + } + + // + // Bearish Fair Value Gaps ... + + // + bool mAllowDrawBearishFVGs; // Draw Bearish Fair Value Gaps ... + bool mBearishFVGForceMiddleBarCheck; // Bearish FVG Force Middle Bar Check ... + bool mBearishFVGForceCheckLastBarDirection; // Bearish FVG Check Last Bar Direction ... + int mBearishFVGWidth; // Bearish FVG Width ... + color mBearishFVGColor; // Bearish FVG Color ... + ENUM_LINE_STYLE mBearishFVGStyle; // Bearish FVG Style ... + XZone mBearishFVGs[]; // Bearish FVGs ... + CArrayObj mBearishFVGObjects; // Bearish FVG Objects ... + TXZoneEventHandler mBearishFVGEventListeners[]; // Bearish FVG Event Listeners ... + + /** + * Create an Object to Represent Bearish FVG on Chart ... + + * @param bar: XZone instance ... + * @param name: String ... + */ + void CreateBearishFVGObject( + XZone &zone, + string name // + ) + { + // + if (!zone.IsValid() || + !IsValid(name)) + { + return; + } + + // + XCBearishFVGObject *iObj; + iObj = new XCBearishFVGObject(); + bool isCreated = iObj.CreateByZone( + ChartID(), + name, + Window(), + zone, + NULL, // Object Prefix ... + true // Force Draw Rect ... + ); + if (!isCreated) + { + return; + } + + // + // Configure Object ... + iObj.ZoneColor(BearishFVGColor()); + iObj.ZoneStyle(BearishFVGStyle()); + iObj.ZoneWidth(BearishFVGWidth()); + + // + mBearishFVGObjects.Add(iObj); + } + // }; diff --git a/Experts/x-saherelm.x-121.smc.ea.mq5 b/Experts/x-saherelm.x-121.smc.ea.mq5 index 157e5710..4e463a5e 100644 --- a/Experts/x-saherelm.x-121.smc.ea.mq5 +++ b/Experts/x-saherelm.x-121.smc.ea.mq5 @@ -431,13 +431,21 @@ bool InitEA() _Period // ); eaPOI.EnableDrawPOIs(); - eaPOI.AllowDrawSwingLows(false); - eaPOI.AllowDrawSwingHighs(false); - eaPOI.AllowDrawMomentumBars(false); - eaPOI.AllowDrawSupportZones(false); - eaPOI.AllowDrawRejectionBars(false); - eaPOI.AllowDrawMarketSessions(false); - eaPOI.AllowDrawResistanceZones(false); + // eaPOI.AllowDrawSwingLows(false); + // eaPOI.AllowDrawSwingHighs(false); + // eaPOI.AllowDrawBullishFVGs(false); + // eaPOI.AllowDrawBearishFVGs(false); + // eaPOI.AllowDrawSupplyZones(false); + // eaPOI.AllowDrawDemandZones(false); + // eaPOI.AllowDrawMomentumBars(false); + // eaPOI.AllowDrawSupportZones(false); + // eaPOI.AllowDrawRejectionBars(false); + // eaPOI.AllowDrawMarketSessions(false); + // eaPOI.AllowDrawResistanceZones(false); + // eaPOI.AllowDrawBullishOrderBlocks(false); + // eaPOI.AllowDrawBearishOrderBlocks(false); + + // eaPOI.Init(); // // diff --git a/Libraries/x-saherelm.common.lib.mq5 b/Libraries/x-saherelm.common.lib.mq5 index 0dd9620f..c54bfd82 100644 --- a/Libraries/x-saherelm.common.lib.mq5 +++ b/Libraries/x-saherelm.common.lib.mq5 @@ -3701,7 +3701,10 @@ struct XOHCL bool HasBullishFVG( double &upper, double &lower, - bool forceMiddleBarCheck = true // + datetime &start, + datetime &end, + bool forceMiddleBarCheck = true, + bool forceCheckLastBarDirection = false // ) { // @@ -3711,6 +3714,10 @@ struct XOHCL upper = 0; lower = 0; + // + end = NULL; + start = NULL; + // // Validate Content and Ignore 0 Bar // since it is not Completed ... @@ -3722,7 +3729,10 @@ struct XOHCL // // Current Bar Must be Bullish ... - result = IsBullish(); + result = + !forceCheckLastBarDirection + ? true + : IsBullish(); if (!result) { return result; @@ -3793,8 +3803,10 @@ struct XOHCL if (result) { // + end = time; upper = low; lower = ppBar.high; + start = ppBar.time; } // @@ -3806,7 +3818,10 @@ struct XOHCL bool HasBearishFVG( double &upper, double &lower, - bool forceMiddleBarCheck = true // + datetime &start, + datetime &end, + bool forceMiddleBarCheck = true, + bool forceCheckLastBarDirection = false // ) { // @@ -3816,6 +3831,10 @@ struct XOHCL upper = 0; lower = 0; + // + end = NULL; + start = NULL; + // // Validate Content and Ignore 0 Bar // since it is not Completed ... @@ -3827,7 +3846,10 @@ struct XOHCL // // Current Bar Must be Bearish ... - result = IsBearish(); + result = + !forceCheckLastBarDirection + ? true + : IsBullish(); if (!result) { return result; @@ -3898,8 +3920,10 @@ struct XOHCL if (result) { // - upper = ppBar.low; + end = time; lower = high; + upper = ppBar.low; + start = ppBar.time; } // diff --git a/Libraries/x-saherelm.x-poi.lib.mq5 b/Libraries/x-saherelm.x-poi.lib.mq5 index 409a1c62..6be854f3 100644 --- a/Libraries/x-saherelm.x-poi.lib.mq5 +++ b/Libraries/x-saherelm.x-poi.lib.mq5 @@ -33,6 +33,12 @@ // All Available POI(s) ... enum ENUM_XPOIS { + // + // Trading Day ... + X_POI_TRADING_DAY, // Trading Day ... + // + // Market Session ... + X_POI_MARKET_SESSION, // Market Session ... // // Momentum Bar ... X_POI_MOMENTUM_BAR, // Momentum Bar ... @@ -45,8 +51,8 @@ enum ENUM_XPOIS X_POI_SWING_LOW, // Simple Swing Low ... // // Support nad Resistance ... - X_POI_SUPPORT, // Support Zone ... - X_POI_RESISTANCE, // Resistance Zone ... + X_POI_SUPPORT_ZONE, // Support Zone ... + X_POI_RESISTANCE_ZONE, // Resistance Zone ... // // Supply and Demand Zones ... X_POI_SUPPLY_ZONE, // Supply Zone ... @@ -261,7 +267,7 @@ struct XTradeDay } // - result = "XDay_" + ToFormatString(from) + "_" + ToFormatString(to); + result = ToString(X_POI_TRADING_DAY) + "_" + ToFormatString(from) + "_" + ToFormatString(to); // return result; @@ -320,7 +326,10 @@ struct XMarketSession // result = - ToFormatString(from) + "_" + + ToString(X_POI_MARKET_SESSION) + "_" + + ToString(session) + "_" + + ToFormatString(from) + + "_" + ToFormatString(to) + "_"; // @@ -483,6 +492,16 @@ string ToString(ENUM_XPOIS value) // switch (value) { + // + case X_POI_TRADING_DAY: + result = "XTDAY"; + break; + + // + case X_POI_MARKET_SESSION: + result = "XMSESS"; + break; + // case X_POI_MOMENTUM_BAR: result = "XMNTMB"; @@ -504,12 +523,12 @@ string ToString(ENUM_XPOIS value) break; // - case X_POI_SUPPORT: + case X_POI_SUPPORT_ZONE: result = "XSUP"; break; // - case X_POI_RESISTANCE: + case X_POI_RESISTANCE_ZONE: result = "XRES"; break; @@ -573,6 +592,11 @@ string ToString(ENUM_XSESSION value) result = "Tokyo"; break; + // + case X_FRANKFORT: + result = "FrankGurt"; + break; + // case X_LONDON: result = "London";