/////////////////////////////////////////////////////// // // SaherElm IT Center MQL5 Class Library // -------------------------------------- // Name: XPOI // Description: Provides Point of Interests ... // - Swing Highs; // - Swing Lows; // // Maintainer: // ------------ // Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) // ////////////////////////////////////////////////////// // // Global Properties ... #property library #property copyright "Copyright 2023, SaherElm IT Center" #property link "https://www.saherelm.ir" #property version "1.00" #property strict // // Imports ... // #include "../Classes/x-saherelm.x-alert.class.mq5" #include "../Classes/x-saherelm.x-bar.analyser.class.mq5" #include "../Libraries/x-saherelm.x-poi.state.lib.mq5" // // Implementation ... // // POI Detector Class ... class XCPOIDetector : public XCBaseAlert { // public: // // // Constructors ... /** * Create an Instance ... * * @param symbol: String ... * @param period: ENUM_TIMEFRAMES member ... */ void XCPOIDetector( string symbol, ENUM_TIMEFRAMES period) { // // Attach Required Properties ... mSymbol = symbol; mPeriod = period; // // Initialize Bar Tracker ... mBarTracker.Init( mSymbol, mPeriod // ); // mBarAnalyser = new XCBarAnalyser(); // // Apply Default Configurations ... Default(); } // // Deconstructor ... void ~XCPOIDetector() { Destroy(); } // // Getter(s) / Setter(s) ... /** * Retrieve Detector Symbol ... * * @return ( string ) */ string GetSymbol() { return mSymbol; } /** * Retrieve Detector Period ... * * @return ( ENUM_TIMEFRAMES ) */ ENUM_TIMEFRAMES GetPeriod() { return mPeriod; } /** * Get Max Required POI(s) allowed to Holds ... * * @return ( int ) */ int MaxRequiredPOIs() { return mMaxRequiredPOIs; } /** * Set Max Required POI(s) allowed to Holds ... * * @param value: int ... */ void MaxRequiredPOIs(int value) { // if (value < 0) { value = 5; } // mMaxRequiredPOIs = value; } /** * Get Max Allowed Loopback for POI(s) Detection on Initialization Process ... * * @return ( int ) */ int MaxAllowedLoopbackForInit() { return maxAllowedLoopbackForInit; } /** * Set Max Allowed Loopback for POI(s) Detection on Initialization Process ... * * @param value: int ... */ void MaxAllowedLoopbackForInit(int value) { // if (value < 0) { value = 578; } // maxAllowedLoopbackForInit = value; } // // // /** * Get Swing Range Validation ... * * @return ( int ) */ int SwingRange() { return mSwingRange; } /** * Set Swing Range Validation ... * * @param value: int ... */ void SwingRange(int value) { // value = NormalizeInt(value, 1); // 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 ... * * @return ( int ) */ int MomentumLoopback() { return mMomentumLoopback; } /** * Set Momentum Detecting Loopback ... * * @param value: int ... */ void MomentumLoopback(int value) { // value = NormalizeInt(value, 1); // mMomentumLoopback = value; } /** * Get Rejection Detecting Force Bar Type State ... * * @return ( bool ) */ bool RejectionForceBarType() { return mRejectionForceBarType; } /** * Set Rejection Detecting Force Bar Type State ... * * @param value: bool ... */ void RejectionForceBarType(bool value) { mRejectionForceBarType = value; } /** * Get Rejection Detecting Force Fibo Pressure State ... * * @return ( bool ) */ bool RejectionForceFiboPressure() { return mRejectionForceFiboPressure; } /** * Set Rejection Detecting Force Fibo Pressure State ... * * @param value: bool ... */ void RejectionForceFiboPressure(bool value) { mRejectionForceFiboPressure = value; } /** * Get Minimum Length of Cnsolidation Zone ... * * @return ( int ) */ int ConsolidationZoneMinLoopback() { return mConsolidationZoneMinLoopback; } /** * Set Minimum Length of Cnsolidation Zone ... * * @param value: int ... */ void ConsolidationZoneMinLoopback(int value) { // value = NormalizeInt(value, 1); // mConsolidationZoneMinLoopback = value; } /** * Get Consolidation Zone Range in Point ... * * @return ( double ) */ double ConsolidationZoneRangeInPoint() { return mConsolidationZoneRangeInPoint; } /** * Set Consolidation Zone Range in Point ... * * @param value: double ... */ void ConsolidationZoneRangeInPoint(double value) { // value = NormalizeDouble(value, 0); // mConsolidationZoneRangeInPoint = value; } /** * Get Consolidation Zone Lower Applied To ... * * @return ( ENUM_X_PRICE ) */ ENUM_X_PRICE ConsolidationZonesLowerAppliedTo() { return mConsolidationZonesLowerAppliedTo; } /** * Get Consolidation Zone Lower Applied To ... * * @param value: ENUM_X_PRICE member ... */ void ConsolidationZonesLowerAppliedTo(ENUM_X_PRICE value) { mConsolidationZonesLowerAppliedTo = value; } /** * Get Consolidation Zone Upper Applied To ... * * @return ( ENUM_X_PRICE ) */ ENUM_X_PRICE ConsolidationZonesUpperAppliedTo() { return mConsolidationZonesUpperAppliedTo; } /** * Get Consolidation Zone Upper Applied To ... * * @param value: ENUM_X_PRICE member ... */ void ConsolidationZonesUpperAppliedTo(ENUM_X_PRICE value) { mConsolidationZonesUpperAppliedTo = value; } /** * Get Spike Detection Price Type ... * * @return ( ENUM_X_PRICE ) */ ENUM_X_PRICE SpikePriceType() { return mSpikePriceType; } /** * Set Spike Detection Price Type ... * * @param value: ENUM_X_PRICE member ... */ void SpikePriceType(ENUM_X_PRICE value) { mSpikePriceType = value; } /** * Get Spike Detection Force Body In Range State ... * * @return ( bool ) */ bool SpikeForcBodyInRange() { return mSpikeForcBodyInRange; } /** * Set Spike Detection Force Body In Range State ... * * @param value: bool ... */ void SpikeForcBodyInRange(bool value) { mSpikeForcBodyInRange = value; } /** * Get Spike Detection Range Extends Multiplier ... * * @return ( double ) */ double SpikeRangeExtendMultiplier() { return mSpikeRangeExtendMultiplier; } /** * Set Spike Detection Range Extends Multiplier ... * * @param value: double ... */ void SpikeRangeExtendMultiplier(double value) { // value = NormalizeDouble(value, 1); // mSpikeRangeExtendMultiplier = value; } /** * Get Spike Detection Same Bars ... * * @return ( int ) */ int SpikeSameBars() { return mSpikeSameBars; } /** * Set Spike Detection Same Bars ... * * @param value: int ... */ void SpikeSameBars(int value) { // value = NormalizeInt(value, 1); // mSpikeSameBars = value; } /** * Get Support and Resistance Detection Range ... * * @return ( int ) */ int SupResRange() { return mSupResRange; } /** * Set Support and Resistance Detection Range ... * * @param value: int ... */ void SupResRange(int value) { // value = NormalizeInt(value, 5); // mSupResRange = value; } /** * Get use Support and Resistance Range as Start ... * * @return ( bool ) */ bool SupResRangeAsStart() { return mSupResRangeAsStart; } /** * Set use Support and Resistance Range as Start ... * * @param value: bool ... */ void SupResRangeAsStart(bool value) { mSupResRangeAsStart = value; } /** * Get Force Activations in Supply/Demand and Support/Resistance Detections State ... * * @return ( bool ) */ bool SupResForceActivation() { return mSupResForceActivation; } /** * Set Force Activations in Supply/Demand and Support/Resistance Detections State ... * * @param value: bool ... */ void SupResForceActivation(bool value) { mSupResForceActivation = value; } /** * Get FairValueGap Detection Same Bars ... * * @return ( int ) */ int FairValueGapSameBars() { return mFairValueGapSameBars; } /** * Set FairValueGap Detection Same Bars ... * * @param value: int ... */ void FairValueGapSameBars(int value) { // value = NormalizeInt(value, 2); // mFairValueGapSameBars = value; } /** * Get FairValueGap Detection Force Check Activation State ... * * @return ( bool ) */ bool FairValueGapForceActivation() { return mFairValueGapForceActivation; } /** * Set FairValueGap Detection Force Check Activation State ... * * @param value: bool ... */ void FairValueGapForceActivation(bool value) { mFairValueGapForceActivation = value; } /** * Get OrderBlock Detection Same Bars ... * * @return ( int ) */ int OrderBlockSameBars() { return mOrderBlockSameBars; } /** * Set OrderBlock Detection Same Bars ... * * @param value: int ... */ void OrderBlockSameBars(int value) { // value = NormalizeInt(value, 1); // mOrderBlockSameBars = value; } /** * Get Order Blocs Detection Force Spike State ... * * @return ( bool ) */ bool OrderBlockForceSpike() { return mOrderBlockForceSpike; } /** * Set Order Blocs Detection Force Spike State ... * * @param value: bool ... */ void OrderBlockForceSpike(bool value) { mOrderBlockForceSpike = value; } /** * Get Order Blocs Detection Force Fair Value Gaps State ... * * @return ( bool ) */ bool OrderBlockForceFairValueGap() { return mOrderBlockForceFairValueGap; } /** * Set Order Blocs Detection Force Fair Value Gaps State ... * * @param value: bool ... */ void OrderBlockForceFairValueGap(bool value) { mOrderBlockForceFairValueGap = value; } /** * Get Order Blocs Detection Force Support/Resisatnce ... * * @return ( bool ) */ bool OrderBlockForceSupportResistance() { return mOrderBlockForceSupportResistance; } /** * Set Order Blocs Detection Force Support/Resisatnce ... * * @param value: bool ... */ void OrderBlockForceSupportResistance(bool value) { mOrderBlockForceSupportResistance = value; } /** * Get OrderBlock Detection Force Check Activation State ... * * @return ( bool ) */ bool OrderBlockForceActivation() { return mOrderBlockForceActivation; } /** * Set OrderBlock Detection Force Check Activation State ... * * @param value: bool ... */ void OrderBlockForceActivation(bool value) { mOrderBlockForceActivation = value; } // // // // // // // // Actions ... /** * Apply Default Configurations ... */ virtual void Default() { // // Default Props ... MaxRequiredPOIs(100); MaxAllowedLoopbackForInit(578); // SwingRange(7); MomentumLoopback(2); // PullbackRange(3); // MomentumLoopback(2); // RejectionForceBarType(true); RejectionForceFiboPressure(true); // ConsolidationZoneMinLoopback(7); ConsolidationZoneRangeInPoint(50); ConsolidationZonesLowerAppliedTo(X_PRICE_LOW); ConsolidationZonesUpperAppliedTo(X_PRICE_HIGH); // SpikePriceType(X_PRICE_CLOSE); SpikeForcBodyInRange(true); SpikeRangeExtendMultiplier(2.0); SpikeSameBars(3); // SupResRange(21); SupResRangeAsStart(true); SupResForceActivation(true); // FairValueGapSameBars(3); // OrderBlockSameBars(3); OrderBlockForceSpike(true); OrderBlockForceFairValueGap(true); OrderBlockForceSupportResistance(false); } /** * Add Event Listener ... * * @param listener: TOnPOIEvent instance ... */ void AddEventListener(TOnPOIEvent listener) { // Add( listener, mEventListeners // ); } /** * Initialize Instance ... */ void Init( int barIndex = 0, bool ignoreMaxAllowed = true // ) { // if (barIndex < 0) { barIndex = 0; } // if (maxAllowedLoopbackForInit <= 0) { return; } // mLock = true; bool canContinue = true; int index = barIndex + maxAllowedLoopbackForInit; if (!IsValidIndex(index)) { // mLock = false; return; } // while (canContinue) { // XOHCL iBar; bool has = iBar.Init( mSymbol, mPeriod, index // ); index--; // int count = 0; ENUM_XPOI_EVENTS iEvent = X_POI_EVENT_NONE; // // Swings ... DetectSwing( iBar, iEvent // ); // // Momentum ... DetectMomentum( iBar, iEvent // ); // // Rejection ... DetectRejection( iBar, iEvent // ); // // Pullback ... DetetctPullback( iBar, iEvent // ); // // Consolidation Zone ... DetectConsolidationZone( iBar, iEvent // ); // // Spike ... DetectSharp( iBar, iEvent // ); // // Spike ... DetectSpike( iBar, iEvent // ); // // Support ... DetectSupportZone( iBar, iEvent // ); // // Resistance ... DetectResistanceZone( iBar, iEvent // ); // // Supply ... DetectSupplyZone( iBar, iEvent // ); // // Demand ... DetectDemandZone( iBar, iEvent // ); // // FairValueGap ... DetectFairValueGap( iBar, iEvent // ); // // OrderBlock ... DetectOrderBlock( iBar, iEvent // ); // canContinue = has && index >= 0; // iBar.Clean(); } // ReverseCollections(); // mLock = false; } /** * Update POI(s) ... * @param events: ENUM_XPOI_EVENTS member Collection ... */ void Update( ENUM_XPOI_EVENTS &events[], int barIndex = 0 // ) { // if (barIndex < 0) { barIndex = 0; } // Clean(events); // if (mLock) { return; } // // Check Bar Tracker if Waits ... if (!mBarTracker.IsNewBar()) { return; } // mLock = true; // XOHCL iBar; bool has = iBar.Init( mSymbol, mPeriod, barIndex // ); // if (!has) { // iBar.Clean(); // return; } // int count = 0; ENUM_XPOI_EVENTS iEvent = X_POI_EVENT_NONE; // // Swings ... has = DetectSwing( iBar, iEvent // ); if (has) { // Add( iEvent, events // ); } // // Momentum ... has = DetectMomentum( iBar, iEvent // ); if (has) { // Add( iEvent, events // ); } // // Rejection ... has = DetectRejection( iBar, iEvent // ); if (has) { // Add( iEvent, events // ); } // // Pullback ... has = DetetctPullback( iBar, iEvent // ); if (has) { // Add( iEvent, events // ); } // // Consolidation Zone ... has = DetectConsolidationZone( iBar, iEvent // ); if (has) { // Add( iEvent, events // ); } // // Sharp ... has = DetectSharp( iBar, iEvent // ); if (has) { // Add( iEvent, events // ); } // // Spike ... has = DetectSpike( iBar, iEvent // ); if (has) { // Add( iEvent, events // ); } // // Support ... has = DetectSupportZone( iBar, iEvent // ); if (has) { // Add( iEvent, events // ); } // // Resistance ... has = DetectResistanceZone( iBar, iEvent // ); if (has) { // Add( iEvent, events // ); } // // Supply ... has = DetectSupplyZone( iBar, iEvent // ); if (has) { // Add( iEvent, events // ); } // // Demand ... has = DetectDemandZone( iBar, iEvent // ); if (has) { // Add( iEvent, events // ); } // // FairValueGap ... has = DetectFairValueGap( iBar, iEvent // ); if (has) { // Add( iEvent, events // ); } // // OrderBlock ... has = DetectOrderBlock( iBar, iEvent // ); if (has) { // Add( iEvent, events // ); } // iBar.Clean(); mLock = false; // if (HasChild(events)) { CleanupUnusedCollections(); } } /** * Get Current State of POIs ... * * @param state: XPOIState instance ... */ void GetState( XPOIState &state // ) { // state.Clean(); // state.symbol = mSymbol; state.period = mPeriod; state.time = TimeCurrent(); // // Swings ... // Copy( mSwings, state.swings // ); // Copy( mSwingLows, state.swingLows // ); // Copy( mSwingHighs, state.swingHighs // ); // // Pullbacks ... // Copy( mPullbacks, state.pullbacks // ); // Copy( mBullishPullbacks, state.bullishPullbacks // ); // Copy( mBearishPullbacks, state.bearishPullbacks // ); // // Momentums ... // Copy( mMomentums, state.momentums // ); // Copy( mBullishMomentums, state.bullishMomentums // ); // Copy( mBearishMomentums, state.bearishMomentums // ); // // Rejections ... // Copy( mRejections, state.rejections // ); // Copy( mBullishRejections, state.bullishRejections // ); // Copy( mBearishRejections, state.bearishRejections // ); // // Support and Resistances ... // Copy( mSupportZones, state.supportZones // ); // Copy( mResistanceZones, state.resistanceZones // ); // // Supply and Demand ... // Copy( mSupplyZones, state.supplyZones // ); // Copy( mDemandZones, state.demandZones // ); // // Spikes ... // Copy( mSpikes, state.spikes // ); // Copy( mBullishSpikes, state.bullishSpikes // ); // Copy( mBearishSpikes, state.bearishSpikes // ); // // Sharps ... // Copy( mSharps, state.sharps // ); // Copy( mBullishSharps, state.bullishSharps // ); // Copy( mBearishSharps, state.bearishSharps // ); // // Consolidation Zones ... // Copy( mConsolidationZones, state.consolidationZones // ); // Copy( mBullishConsolidationZones, state.bullishConsolidationZones // ); // Copy( mBearishConsolidationZones, state.bearishConsolidationZones // ); // // Fair Value Gaps ... // Copy( mFairValueGaps, state.fairValueGaps // ); // Copy( mBullishFairValueGaps, state.bullishFairValueGaps // ); // Copy( mBearishFairValueGaps, state.bearishFairValueGaps // ); // // Order Blocks ... // Copy( mOrderBlocks, state.orderBlocks // ); // Copy( mBullishOrderBlocks, state.bullishOrderBlocks // ); // Copy( mBearishOrderBlocks, state.bearishOrderBlocks // ); } /** * Destroy Instance ... */ void Destroy() { // mBarTracker.Clean(); ZeroMemory(mBarAnalyser); // CleanCollections(); } // // // // // // /** * Detect Swing ... * * @param bar: XOHCL instance ... * @param state: ENUM_XPOI_EVENTS member ... * * @return ( bool ) */ bool DetectSwing( 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 = bar.GetPreviousBar(sBar); if (!result) { // sBar.Clean(); return result; } } else { sBar = bar; } // ENUM_X_DIRECTION iDir; result = mBarAnalyser.IsSwing( sBar, iDir, mSwingRange // ); // result = result && HasDirection(iDir); if (!result) { // sBar.Clean(); return result; } // bool checkBar = bar.Index() != sBar.Index(); // bool isBullish = IsBullish(iDir) && (!checkBar ? true : bar.low > sBar.low); bool isBearish = IsBearish(iDir) && (!checkBar ? true : bar.high < sBar.high); result = isBullish || isBearish; if (!result) { // sBar.Clean(); return result; } // XOHCL swingBar; result = sBar.GetPreviousBar(swingBar); if (!result) { // sBar.Clean(); swingBar.Clean(); return result; } // ENUM_XPOIS type = isBullish ? X_POI_SWING_LOW : X_POI_SWING_HIGH; // // Swing Object ... XCSwing *swing; swing = new XCSwing(); result = swing.Init( swingBar, type // ); if (!result) { // sBar.Clean(); swingBar.Clean(); return result; } // // Add ... // int idx = FindIndex( swing, mSwings // ); result = !IsValidIndex(idx); if (!result) { // sBar.Clean(); swingBar.Clean(); return result; } // // Add All Collection ... Add( swing, mSwings // ); // // Bullish Swings (Swing Low) ... if (isBullish) { // Add( swing, mSwingLows // ); } // // Bearish Swings (Swing High) ... if (isBearish) { // Add( swing, mSwingHighs // ); } // // Prepare State ... state = isBullish ? X_SWING_LOW_DETECTED : X_SWING_HIGH_DETECTED; // // Cleanup Resources ... // sBar.Clean(); swingBar.Clean(); // return result; } /** * Detect Momentums ... * * @param bar: XOHCL instance ... * @param state: ENUM_XPOI_EVENTS member ... * * @return ( bool ) */ bool DetectMomentum( 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.IsMomentum( sBar, iDir, mMomentumLoopback // ); // result = result && HasDirection(iDir); if (!result) { // sBar.Clean(); return result; } // bool isBullish = IsBullish(iDir); bool isBearish = IsBearish(iDir); // ENUM_XPOIS type = isBullish ? X_POI_MOMENTUM_BAR : X_POI_MOMENTUM_BAR; // // Swing Object ... XCMomentumBar *momentum; momentum = new XCMomentumBar(); result = momentum.Init( sBar // ); if (!result) { // sBar.Clean(); return result; } // int idx = FindIndex( momentum, mMomentums // ); result = !IsValidIndex(idx); if (!result) { // sBar.Clean(); return result; } // // Momentums ... Add( momentum, mMomentums // ); // if (isBullish) { // Add( momentum, mBullishMomentums // ); } // if (isBearish) { // Add( momentum, mBearishMomentums // ); } // state = isBullish ? X_BULLISH_MOMENTUM_BAR_DETECTED : X_BEARISH_MOMENTUM_BAR_DETECTED; // sBar.Clean(); // return result; } /** * Detect Rejections ... * * @param bar: XOHCL instance ... * @param state: ENUM_XPOI_EVENTS member ... * * @return ( bool ) */ bool DetectRejection( 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.IsRejected( sBar, iDir, mRejectionForceBarType, mRejectionForceFiboPressure // ); // result = result && HasDirection(iDir); if (!result) { // sBar.Clean(); return result; } // bool isBullish = IsBullish(iDir); bool isBearish = IsBearish(iDir); // ENUM_XPOIS type = isBullish ? X_POI_MOMENTUM_BAR : X_POI_MOMENTUM_BAR; // // Swing Object ... XCRejectionBar *rejection; rejection = new XCRejectionBar(); result = rejection.Init( sBar // ); if (!result) { // sBar.Clean(); return result; } // int idx = FindIndex( rejection, mRejections // ); result = !IsValidIndex(idx); if (!result) { // sBar.Clean(); return result; } // Add( rejection, mRejections // ); // if (isBullish) { // Add( rejection, mBullishRejections // ); } // if (isBearish) { // Add( rejection, mBearishRejections // ); } // state = isBullish ? X_BULLISH_REJECTION_BAR_DETECTED : X_BEARISH_REJECTION_BAR_DETECTED; // 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.lower = MathMin(sBar.low, fromBar.low); box.upper = MathMax(sBar.high, fromBar.high); box.type = ToString(iDir) + "_XPullBK" + box.symbol + "_" + ToString(box.period); // 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 ... * * @param bar: XOHCL instance ... * @param state: ENUM_XPOI_EVENTS member ... * * @return ( bool ) */ bool DetectConsolidationZone( XOHCL &bar, ENUM_XPOI_EVENTS &state // ) { // bool result = false; // state = X_POI_EVENT_NONE; // 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; } // XConsolidationZone cZone; result = mBarAnalyser.HasConsolidationZone( sBar, cZone, mConsolidationZoneMinLoopback, mConsolidationZoneRangeInPoint, mConsolidationZonesUpperAppliedTo, mConsolidationZonesLowerAppliedTo // ); if (!result) { // sBar.Clean(); cZone.Clean(); // return result; } // // Add ... // bool isBullish = IsBullish(cZone.dir); bool isBearish = IsBearish(cZone.dir); // int idx = FindIndex( cZone, mConsolidationZones // ); result = !IsValidIndex(idx); if (!result) { // sBar.Clean(); cZone.Clean(); // return result; } // AddRef( cZone, mConsolidationZones // ); // if (isBullish) { // AddRef( cZone, mBullishConsolidationZones // ); } // if (isBearish) { // AddRef( cZone, mBearishConsolidationZones // ); } // state = IsBullish(cZone.dir) ? X_BULLISH_CONSOLIDATION_ZONE_DETECTED : X_BEARISH_CONSOLIDATION_ZONE_DETECTED; // cZone.Clean(); // return result; } /** * Detect Sharp Change ... * * @param bar: XOHCL instance ... * @param state: ENUM_XPOI_EVENTS member ... * * @return ( bool ) */ bool DetectSharp( XOHCL &bar, ENUM_XPOI_EVENTS &state // ) { // bool result = false; // state = X_POI_EVENT_NONE; // result = bar.IsValid(); if (!result) { return result; } // int sharpRootIDX = -1; ENUM_X_DIRECTION iDir; result = mBarAnalyser.IsSharp( bar, iDir, sharpRootIDX, mSpikePriceType, mSpikeForcBodyInRange, mSpikeRangeExtendMultiplier // ); if (!result) { return result; } // bool isBullish = IsBullish(iDir); bool isBearish = IsBearish(iDir); // XOHCL fromBar; result = fromBar.Init( bar.symbol, bar.period, sharpRootIDX // ); if (!result) { // fromBar.Clean(); return result; } // XBoxZone box; // box.dir = iDir; box.to = bar.time; box.from = fromBar.time; box.symbol = fromBar.symbol; box.period = fromBar.period; box.type = ToString(iDir) + "_XSharp" + box.symbol + "_" + ToString(box.period); // box.upper = isBullish ? bar.high : fromBar.high; // box.lower = isBullish ? fromBar.low : bar.low; // result = box.IsValid(); if (result) { // AddRef( box, mSharps // ); // if (isBullish) { // AddRef( box, mBullishSharps // ); } // if (isBearish) { // AddRef( box, mBearishSharps // ); } // state = isBullish ? X_BULLISH_SHARP_DETECTED : X_BEARISH_SHARP_DETECTED; } // // Cleanup Resources ... // box.Clean(); fromBar.Clean(); // return result; } /** * Detect Spike ... * * @param bar: XOHCL instance ... * @param state: ENUM_XPOI_EVENTS member ... * * @return ( bool ) */ bool DetectSpike( XOHCL &bar, ENUM_XPOI_EVENTS &state // ) { // bool result = false; // state = X_POI_EVENT_NONE; // result = bar.IsValid(); if (!result) { return result; } // int rootIDX = -1; ENUM_X_DIRECTION iDir; result = mBarAnalyser.IsSpike( bar, iDir, rootIDX, mSpikePriceType, mSpikeForcBodyInRange, mSpikeRangeExtendMultiplier, mSpikeSameBars // ); if (!result) { return result; } // // Chek Same Bars ... int sameBarsIndex = -1; ENUM_X_DIRECTION sameBarsDir; result = mBarAnalyser.HasSameBars( bar, sameBarsDir, sameBarsIndex, mSpikeSameBars // ); if (!result) { return result; } // // Validate Same Bars Dir and Spike Dir ... result = iDir == sameBarsDir; if (!result) { return result; } // bool isBullish = IsBullish(iDir); bool isBearish = IsBearish(iDir); // XOHCL fromBar; result = fromBar.Init( bar.symbol, bar.period, rootIDX // ); if (!result) { // fromBar.Clean(); return result; } // XBoxZone box; // box.dir = iDir; box.to = bar.time; box.from = fromBar.time; box.symbol = fromBar.symbol; box.period = fromBar.period; box.type = ToString(iDir) + "_XSpike_" + box.symbol + "_" + ToString(box.period); // box.upper = isBullish ? bar.high : fromBar.high; // box.lower = isBullish ? fromBar.low : bar.low; // result = box.IsValid(); if (result) { // AddRef( box, mSpikes // ); // if (isBullish) { // AddRef( box, mBullishSpikes // ); } // if (isBearish) { // AddRef( box, mBearishSpikes // ); } // state = isBullish ? X_BULLISH_SPIKE_DETECTED : X_BEARISH_SPIKE_DETECTED; } // // Cleanup Resources ... // box.Clean(); fromBar.Clean(); // return result; } /** * Detect Support Zone ... * * @param bar: XOHCL instance ... * @param state: ENUM_XPOI_EVENTS member ... * * @return ( bool ) */ bool DetectSupportZone( XOHCL &bar, ENUM_XPOI_EVENTS &state // ) { // bool result = false; // state = X_POI_EVENT_NONE; // result = bar.IsValid(); if (!result) { return result; } // XOHCL supportBar; result = mBarAnalyser .HasSupport( bar, supportBar, mSupResRange // ); if (!result) { // supportBar.Clean(); // return result; } // XCSupportZone *supportZone; supportZone = new XCSupportZone(); result = supportZone.Init( supportBar, mSupResRange, mSupResRangeAsStart // Use Range As Start ... ); if (!result) { // supportBar.Clean(); ZeroMemory(supportZone); // return result; } // // Check Zone Not Activated ... if (mSupResForceActivation) { // XOHCL activationBar; bool isActivationBarBodyIn = false; bool isActivated = supportZone.IsActivated( X_DIRECTION_BULLISH, activationBar, isActivationBarBodyIn, false, bar.period // ); result = !isActivated; if (!result) { // supportBar.Clean(); activationBar.Clean(); ZeroMemory(supportZone); // return result; } // activationBar.Clean(); } // // Add ... // int idx = FindIndex( supportZone, mSupportZones // ); result = !IsValidIndex(idx); if (!result) { // supportBar.Clean(); ZeroMemory(supportZone); // return result; } // Add( supportZone, mSupportZones // ); // state = X_SUPPORT_ZONE_DETECTED; // supportBar.Clean(); // return result; } /** * Detect Resistance Zone ... * * @param bar: XOHCL instance ... * @param state: ENUM_XPOI_EVENTS member ... * * @return ( bool ) */ bool DetectResistanceZone( XOHCL &bar, ENUM_XPOI_EVENTS &state // ) { // bool result = false; // state = X_POI_EVENT_NONE; // result = bar.IsValid(); if (!result) { return result; } // XOHCL resistanceBar; result = mBarAnalyser .HasResistance( bar, resistanceBar, mSupResRange // ); if (!result) { // resistanceBar.Clean(); // return result; } // XCResistanceZone *resistanceZone; resistanceZone = new XCResistanceZone(); result = resistanceZone.Init( resistanceBar, mSupResRange, mSupResRangeAsStart // Use Range As Start ... ); if (!result) { // resistanceBar.Clean(); ZeroMemory(resistanceZone); // return result; } // // Check Zone Not Activated ... if (mSupResForceActivation) { // XOHCL activationBar; bool isActivationBarBodyIn = false; bool isActivated = resistanceZone.IsActivated( X_DIRECTION_BULLISH, activationBar, isActivationBarBodyIn, false, bar.period // ); result = !isActivated; if (!result) { // resistanceBar.Clean(); activationBar.Clean(); ZeroMemory(resistanceZone); // return result; } // activationBar.Clean(); } // // Add ... // int idx = FindIndex( resistanceZone, mResistanceZones // ); result = !IsValidIndex(idx); if (!result) { // resistanceBar.Clean(); ZeroMemory(resistanceZone); // return result; } // Add( resistanceZone, mResistanceZones // ); // state = X_RESISTANCE_ZONE_DETECTED; // resistanceBar.Clean(); // return result; } /** * Detect Supply Zone ... * * @param bar: XOHCL instance ... * @param state: ENUM_XPOI_EVENTS member ... * * @return ( bool ) */ bool DetectSupplyZone( XOHCL &bar, ENUM_XPOI_EVENTS &state // ) { // bool result = false; // state = X_POI_EVENT_NONE; // result = bar.IsValid(); if (!result) { return result; } // int mSupDemRange = mSupResRange * 2; // XOHCL supplyBar; result = mBarAnalyser .HasResistance( bar, supplyBar, mSupDemRange // ); if (!result) { // supplyBar.Clean(); // return result; } // XCSupplyZone *supplyZone; supplyZone = new XCSupplyZone(); result = supplyZone.Init( supplyBar, mSupDemRange, mSupResRangeAsStart // Use Range As Start ... ); if (!result) { // supplyBar.Clean(); ZeroMemory(supplyZone); // return result; } // // Check Zone Not Activated ... if (mSupResForceActivation) { // XOHCL activationBar; bool isActivationBarBodyIn = false; bool isActivated = supplyZone.IsActivated( X_DIRECTION_BULLISH, activationBar, isActivationBarBodyIn, false, bar.period // ); result = !isActivated; if (!result) { // supplyBar.Clean(); activationBar.Clean(); ZeroMemory(supplyZone); // return result; } // activationBar.Clean(); } // // Add ... // int idx = FindIndex( supplyZone, mSupplyZones // ); result = !IsValidIndex(idx); if (!result) { // supplyBar.Clean(); ZeroMemory(supplyZone); // return result; } // Add( supplyZone, mSupplyZones // ); // state = X_SUPPLY_ZONE_DETECTED; // supplyBar.Clean(); // return result; } /** * Detect Demand Zone ... * * @param bar: XOHCL instance ... * @param state: ENUM_XPOI_EVENTS member ... * * @return ( bool ) */ bool DetectDemandZone( XOHCL &bar, ENUM_XPOI_EVENTS &state // ) { // bool result = false; // state = X_POI_EVENT_NONE; // result = bar.IsValid(); if (!result) { return result; } // int mSupDemRange = mSupResRange * 2; // XOHCL demandBar; result = mBarAnalyser .HasSupport( bar, demandBar, mSupDemRange // ); if (!result) { // demandBar.Clean(); // return result; } // XCDemandZone *demandZone; demandZone = new XCDemandZone(); result = demandZone.Init( demandBar, mSupDemRange, mSupResRangeAsStart // Use Range As Start ... ); if (!result) { // demandBar.Clean(); ZeroMemory(demandZone); // return result; } // // Check Zone Not Activated ... if (mSupResForceActivation) { // XOHCL activationBar; bool isActivationBarBodyIn = false; bool isActivated = demandZone.IsActivated( X_DIRECTION_BULLISH, activationBar, isActivationBarBodyIn, false, bar.period // ); result = !isActivated; if (!result) { // demandBar.Clean(); activationBar.Clean(); ZeroMemory(demandZone); // return result; } // activationBar.Clean(); } // // Add ... // int idx = FindIndex( demandZone, mDemandZones // ); result = !IsValidIndex(idx); if (!result) { // demandBar.Clean(); ZeroMemory(demandZone); // return result; } // Add( demandZone, mDemandZones // ); // state = X_DEMAND_ZONE_DETECTED; // demandBar.Clean(); // return result; } /** * Detect Fair Value Gaps ... * * @param bar: XOHCL instance ... * @param state: ENUM_XPOI_EVENTS member ... * * @return ( bool ) */ bool DetectFairValueGap( XOHCL &bar, ENUM_XPOI_EVENTS &state // ) { // bool result = false; // state = X_POI_EVENT_NONE; // result = bar.IsValid(); if (!result) { return result; } // XOHCL fvgStartBar; XOHCL fvgEndBar; ENUM_X_DIRECTION fvgDir; result = mBarAnalyser.HasFairValueGap( bar, fvgStartBar, fvgEndBar, fvgDir, mFairValueGapSameBars // ); if (!result) { // fvgEndBar.Clean(); fvgStartBar.Clean(); // return result; } // XCFVG *fvg; fvg = new XCFVG(); result = fvg.Init( fvgStartBar, fvgEndBar, fvgDir // ); if (!result) { // ZeroMemory(fvg); fvgEndBar.Clean(); fvgStartBar.Clean(); // return result; } // bool isBullish = IsBullish(fvgDir); bool isBearish = IsBearish(fvgDir); // // Check Zone Not Activated ... if (mFairValueGapForceActivation) { // XOHCL activationBar; bool isActivationBarBodyIn = false; bool isActivated = fvg.IsActivated( fvgDir, activationBar, isActivationBarBodyIn, false, bar.period // ); result = !isActivated; if (!result) { // ZeroMemory(fvg); fvgEndBar.Clean(); fvgStartBar.Clean(); activationBar.Clean(); // return result; } // activationBar.Clean(); } // int idx = FindIndex( fvg, mFairValueGaps // ); result = !IsValidIndex(idx); if (!result) { // ZeroMemory(fvg); fvgEndBar.Clean(); fvgStartBar.Clean(); // return result; } // Add( fvg, mFairValueGaps // ); // if (isBullish) { // Add( fvg, mBullishFairValueGaps // ); } // if (isBearish) { // Add( fvg, mBearishFairValueGaps // ); } // state = isBullish ? X_BULLISH_FVG_DETECTED : X_BEARISH_FVG_DETECTED; // fvgEndBar.Clean(); fvgStartBar.Clean(); // return result; } /** * Detect Order Blocks ... * * @param bar: XOHCL instance ... * @param state: ENUM_XPOI_EVENTS member ... * * @return ( bool ) */ bool DetectOrderBlock( XOHCL &bar, ENUM_XPOI_EVENTS &state // ) { // bool result = false; // state = X_POI_EVENT_NONE; // result = bar.IsValid(); if (!result) { return result; } // XOHCL obBar; ENUM_X_DIRECTION obDir; result = mBarAnalyser.HasOrderBlock( bar, obBar, obDir, mOrderBlockSameBars, mOrderBlockForceSpike, mOrderBlockForceFairValueGap, mOrderBlockForceSupportResistance // ); if (!result) { // obBar.Clean(); // return result; } // XCOrderBlock *ob; ob = new XCOrderBlock(); result = ob.Init( obBar, obDir // ); if (!result) { // obBar.Clean(); ZeroMemory(ob); // return result; } // bool isBullish = IsBullish(obDir); bool isBearish = IsBearish(obDir); // // Check Zone Not Activated ... if (mOrderBlockForceActivation) { // XOHCL activationBar; bool isActivationBarBodyIn = false; bool isActivated = ob.IsActivated( obDir, activationBar, isActivationBarBodyIn, false, bar.period // ); result = !isActivated; if (!result) { // obBar.Clean(); activationBar.Clean(); ZeroMemory(ob); // return result; } // activationBar.Clean(); } // int idx = FindIndex( ob, mOrderBlocks // ); result = !IsValidIndex(idx); if (!result) { // obBar.Clean(); ZeroMemory(ob); // return result; } // Add( ob, mOrderBlocks // ); // if (isBullish) { // Add( ob, mBullishOrderBlocks // ); } // if (isBearish) { // Add( ob, mBearishOrderBlocks // ); } // state = isBullish ? X_BULLISH_ORDERBLOCK_DETECTED : X_BEARISH_ORDERBLOCK_DETECTED; // obBar.Clean(); // return result; } // protected: // /** * Notify Event Listeners ... * * @param event: ENUM_XPOI_EVENTS member, Specified Occured Event ... * @param param: XCBasePOI implementation, Specified Event Object ... */ void NotifyEventListeners( ENUM_XPOI_EVENTS event, XCBasePOI *param // ) { // int count = ArraySize(mEventListeners); if (!IsValidSize(count)) { return; } // for (int i = 0; i < count; i++) { // mEventListeners[i]( event, param // ); } } // private: // // // Props ... string mSymbol; // Market Symbol ... ENUM_TIMEFRAMES mPeriod; // Market Period ... XBarTracker mBarTracker; // Market Bar Tracker ... XCBarAnalyser *mBarAnalyser; // Bar Analyser ... // bool mLock; // int mMaxRequiredPOIs; // Max Allowed Holds POI(s) ... int maxAllowedLoopbackForInit; // Max Allowed Loopback for POI(s) Detection on Initialization Process ... // TOnPOIEvent mEventListeners[]; // Event Listeners ... // // Swings ... XCSwing *mSwings[]; // Holds Founded Swing ... XCSwing *mSwingLows[]; // Holds Founded Swing Lows ... 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 ... XCMomentumBar *mBullishMomentums[]; // Holds Founded Bullish Momentum Bars ... XCMomentumBar *mBearishMomentums[]; // Holds Founded Bearish Momentum Bars ... int mMomentumLoopback; // Momentum Detecting Loopback ... // // Rejections ... XCRejectionBar *mRejections[]; // Holds Founded Rejection Bars ... XCRejectionBar *mBullishRejections[]; // Holds Founded Bullish Rejection Bars ... XCRejectionBar *mBearishRejections[]; // Holds Founded Bearish Rejection Bars ... bool mRejectionForceBarType; // Rejection Detecting Force Bar Type ... bool mRejectionForceFiboPressure; // Rejection Detecting Force Fibo Pressure ... // // Consolidation Zones ... XConsolidationZone mConsolidationZones[]; // Holds Founded Consolidation Zones ... XConsolidationZone mBullishConsolidationZones[]; // Holds Founded Bullish Consolidation Zones ... XConsolidationZone mBearishConsolidationZones[]; // Holds Founded Bearish Consolidation Zones ... int mConsolidationZoneMinLoopback; // Minimum Length of Cnsolidation Zone ... double mConsolidationZoneRangeInPoint; // Consolidation Zone Range in Point ... ENUM_X_PRICE mConsolidationZonesLowerAppliedTo; // Consolidation Zone Upper Applied To ... ENUM_X_PRICE mConsolidationZonesUpperAppliedTo; // Consolidation Zone Lower Applied To ... // // Spike/Sharp Zones ... XBoxZone mSharps[]; // Holds Founded Sharps ... XBoxZone mBullishSharps[]; // Holds Founded Bullish Sharps ... XBoxZone mBearishSharps[]; // Holds Founded Bearish Sharps ... XBoxZone mSpikes[]; // Holds Founded Spikes ... XBoxZone mBullishSpikes[]; // Holds Founded Bullish Spikes ... XBoxZone mBearishSpikes[]; // Holds Founded Bearish Spikes ... ENUM_X_PRICE mSpikePriceType; // Spike Detection Price Type ... bool mSpikeForcBodyInRange; // Spike Detection Force Body In Range ... double mSpikeRangeExtendMultiplier; // Spike Detection Range Extends Multiplier ... int mSpikeSameBars; // Spike Detection Same Bars ... // // Support and Resistance ... // Supply and Demand ... // int mSupResRange; // Support and Resistance Detection Range ... bool mSupResRangeAsStart; // use Support and Resistance Range as Start ... bool mSupResForceActivation; // Force Activations in Supply/Demand and Support/Resistance Detections ... // XCSupplyZone *mSupplyZones[]; // Holds Detected Supply Zones ... XCDemandZone *mDemandZones[]; // Holds Detected Demand Zones ... // XCSupportZone *mSupportZones[]; // Holds Detected Support Zones ... XCResistanceZone *mResistanceZones[]; // Holds Detected Resistance Zones ... // // Fair Value Gaps ... XCFVG *mFairValueGaps[]; // Holds Founded FairValueGaps ... XCFVG *mBullishFairValueGaps[]; // Holds Founded Bullish FairValueGaps ... XCFVG *mBearishFairValueGaps[]; // Holds Founded Bearish FairValueGaps ... int mFairValueGapSameBars; // FairValueGap Detection Same Bars ... bool mFairValueGapForceActivation; // FairValueGap Detection Force Check Activation ... // // Order Blocks ... XCOrderBlock *mOrderBlocks[]; // Holds Founded OrderBlocks ... XCOrderBlock *mBullishOrderBlocks[]; // Holds Founded Bullish OrderBlocks ... XCOrderBlock *mBearishOrderBlocks[]; // Holds Founded Bearish OrderBlocks ... int mOrderBlockSameBars; // OrderBlock Detection Same Bars ... bool mOrderBlockForceSpike; // Order Blocs Detection Force Spike ... bool mOrderBlockForceFairValueGap; // Order Blocs Detection Force Fair Value Gaps ... bool mOrderBlockForceSupportResistance; // Order Blocs Detection Force Support/Resisatnce ... bool mOrderBlockForceActivation; // Order Blocs Detection Force Check Activation ... /** * Clean All Collections ... */ void CleanCollections() { // Clean(mSwings); Clean(mSwingLows); Clean(mSwingHighs); Clean(mMomentums); Clean(mBullishMomentums); Clean(mBearishMomentums); Clean(mRejections); Clean(mBullishRejections); Clean(mBearishRejections); Clean(mConsolidationZones); Clean(mBullishConsolidationZones); Clean(mBearishConsolidationZones); Clean(mSpikes); Clean(mBullishSpikes); Clean(mBearishSpikes); Clean(mSupplyZones); Clean(mDemandZones); Clean(mSupportZones); Clean(mResistanceZones); Clean(mFairValueGaps); Clean(mBullishFairValueGaps); Clean(mBearishFairValueGaps); Clean(mOrderBlocks); Clean(mBullishOrderBlocks); Clean(mBearishOrderBlocks); } /** * Reverse Collections ... */ void ReverseCollections() { // ArrayReverse(mSwings); ArrayReverse(mSwingLows); ArrayReverse(mSwingHighs); ArrayReverse(mMomentums); ArrayReverse(mBullishMomentums); ArrayReverse(mBearishMomentums); ArrayReverse(mRejections); ArrayReverse(mBullishRejections); ArrayReverse(mBearishRejections); ArrayReverse(mConsolidationZones); ArrayReverse(mBullishConsolidationZones); ArrayReverse(mBearishConsolidationZones); ArrayReverse(mSpikes); ArrayReverse(mBullishSpikes); ArrayReverse(mBearishSpikes); ArrayReverse(mSupplyZones); ArrayReverse(mDemandZones); ArrayReverse(mSupportZones); ArrayReverse(mResistanceZones); ArrayReverse(mFairValueGaps); ArrayReverse(mBullishFairValueGaps); ArrayReverse(mBearishFairValueGaps); ArrayReverse(mOrderBlocks); ArrayReverse(mBullishOrderBlocks); ArrayReverse(mBearishOrderBlocks); } /** * Cleanup Unused Collection Items ... * * @param maxAllowed: int, Max Allowed ... */ void CleanupUnusedCollections( int maxAllowed = 0 // ) { // maxAllowed = MaxRequiredPOIs(); // if (maxAllowed <= 0) { return; } // CleanupArray(mSwings, maxAllowed); CleanupArray(mSwingLows, maxAllowed); CleanupArray(mSwingHighs, maxAllowed); CleanupArray(mMomentums, maxAllowed); CleanupArray(mBullishMomentums, maxAllowed); CleanupArray(mBearishMomentums, maxAllowed); CleanupArray(mRejections, maxAllowed); CleanupArray(mBullishRejections, maxAllowed); CleanupArray(mBearishRejections, maxAllowed); CleanupArray(mConsolidationZones, maxAllowed); CleanupArray(mBullishConsolidationZones, maxAllowed); CleanupArray(mBearishConsolidationZones, maxAllowed); CleanupArray(mSpikes, maxAllowed); CleanupArray(mBullishSpikes, maxAllowed); CleanupArray(mBearishSpikes, maxAllowed); CleanupArray(mSupplyZones, maxAllowed); CleanupArray(mDemandZones, maxAllowed); CleanupArray(mSupportZones, maxAllowed); CleanupArray(mResistanceZones, maxAllowed); CleanupArray(mFairValueGaps, maxAllowed); CleanupArray(mBullishFairValueGaps, maxAllowed); CleanupArray(mBearishFairValueGaps, maxAllowed); CleanupArray(mOrderBlocks, maxAllowed); CleanupArray(mBullishOrderBlocks, maxAllowed); CleanupArray(mBearishOrderBlocks, maxAllowed); } // }; //