Files
MQL5Data/Documents/BKP/x-saherelm.x-poi.class copy.mq5
T

3334 lines
67 KiB
Plaintext

///////////////////////////////////////////////////////
//
// 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"
//
#include <Arrays/ArrayObj.mqh>
//
// 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)
{
//
if (value < 1)
{
value = 1;
}
//
mSwingRange = value;
}
/**
* Get Momentum Bar Detection Extends Range ...
*
* @return ( int )
*/
int MomentumExtend()
{
return mMomentumExtend;
}
/**
* Set Momentum Bar Detection Extends Range ...
*
* @param value: int ...
*/
void MomentumExtend(int value)
{
//
if (value < 0)
{
value = 0;
}
//
mMomentumExtend = value;
}
/**
* Get Momentum Bar Detection Body Percent ...
*
* @return ( double )
*/
double MomentumBodyPercent()
{
return mMomentumBodyPercent;
}
/**
* Set Momentum Bar Detection Body Percent ...
*
* @param value: double ...
*/
void MomentumBodyPercent(double value)
{
//
if (value < 50)
{
value = 50;
}
//
if (value > 100)
{
value = 100;
}
//
mMomentumBodyPercent = value;
}
/**
* Get Rejection Bar Detection Extends Range ...
*
* @return ( int )
*/
int RejectionExtend()
{
return mRejectionExtend;
}
/**
* Set Rejection Bar Detection Extends Range ...
*
* @param value: int ...
*/
void RejectionExtend(int value)
{
//
if (value < 0)
{
value = 0;
}
//
mRejectionExtend = value;
}
/**
* Get Rejection Bar Detection Shadow Percent ...
*
* @return ( double )
*/
double RejectionShadowPercent()
{
return mRejectionShadowPercent;
}
/**
* Set Rejection Bar Detection Shadow Percent ...
*
* @param value: double ...
*/
void RejectionShadowPercent(double value)
{
//
if (value < 50)
{
value = 50;
}
//
if (value > 100)
{
value = 100;
}
//
mRejectionShadowPercent = 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)
{
//
if (value < 0)
{
value = 0;
}
//
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 OrderBlock Detection Same Bars ...
*
* @return ( int )
*/
int OrderBlockSameBars()
{
return mOrderBlockSameBars;
}
/**
* Set OrderBlock Detection Same Bars ...
*
* @param value: int ...
*/
void OrderBlockSameBars(int value)
{
//
if (value < 2)
{
value = 2;
}
//
mOrderBlockSameBars = value;
}
/**
* Get FairValueGap Detection Same Bars ...
*
* @return ( int )
*/
int FairValueGapSameBars()
{
return mFairValueGapSameBars;
}
/**
* Set FairValueGap Detection Same Bars ...
*
* @param value: int ...
*/
void FairValueGapSameBars(int value)
{
//
if (value < 2)
{
value = 2;
}
//
mFairValueGapSameBars = 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)
{
//
if (value < 1)
{
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)
{
//
if (value < 50)
{
value = 50;
}
//
mConsolidationZoneRangeInPoint = value;
}
/**
* Get Consolidation Zone Upper Applied To ...
*
* @return ( ENUM_APPLIED_PRICE )
*/
ENUM_APPLIED_PRICE ConsolidationZonesLowerAppliedTo()
{
return mConsolidationZonesLowerAppliedTo;
}
/**
* Set Consolidation Zone Upper Applied To ...
*
* @param value: ENUM_APPLIED_PRICE
*/
void ConsolidationZonesLowerAppliedTo(ENUM_APPLIED_PRICE value = PRICE_LOW)
{
mConsolidationZonesLowerAppliedTo = value;
}
/**
* Get Consolidation Zone Lower Applied To ...
*
* @return ( ENUM_APPLIED_PRICE )
*/
ENUM_APPLIED_PRICE ConsolidationZonesUpperAppliedTo()
{
return mConsolidationZonesUpperAppliedTo;
}
/**
* Set Consolidation Zone Lower Applied To ...
*
* @param value: ENUM_APPLIED_PRICE
*/
void ConsolidationZonesUpperAppliedTo(ENUM_APPLIED_PRICE value = PRICE_HIGH)
{
mConsolidationZonesUpperAppliedTo = value;
}
//
// Actions ...
/**
* Apply Default Configurations ...
*/
virtual void Default()
{
//
// Default Props ...
SwingRange(3);
SupResRange(21);
MomentumExtend(1);
RejectionExtend(1);
MaxRequiredPOIs(100);
OrderBlockSameBars(3);
FairValueGapSameBars(3);
MomentumBodyPercent(70);
SupResRangeAsStart(true);
RejectionShadowPercent(70);
MaxAllowedLoopbackForInit(578);
ConsolidationZoneMinLoopback(5);
ConsolidationZoneRangeInPoint(50);
ConsolidationZonesLowerAppliedTo(PRICE_LOW);
ConsolidationZonesUpperAppliedTo(PRICE_HIGH);
}
/**
* 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,
false //
);
//
// Rejection Bar ...
DetectRejection(
iBar,
iEvent,
false //
);
//
// Momentum Bar ...
DetectMomentum(
iBar,
iEvent,
false //
);
//
// Support ...
DetectSupportZone(
iBar,
iEvent,
false //
);
//
// Demand ...
DetectDemandZone(
iBar,
iEvent,
false //
);
//
// Resistance ...
DetectResistanceZone(
iBar,
iEvent,
false //
);
//
// Supply ...
DetectSupplyZone(
iBar,
iEvent,
false //
);
//
// OrderBlock ...
DetectOrderBlock(
iBar,
iEvent,
false //
);
//
// FairValueGap ...
DetectFairValueGap(
iBar,
iEvent,
false //
);
//
// Consolidation Zone ...
DetectConsolidationZone(
iBar,
iEvent,
false //
);
//
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 //
);
//
XCBasePOI *item = NULL;
XCSwing *iSwing = NULL;
if (iEvent == X_SWING_LOW_DETECTED)
{
//
has = GetLastItem(
iSwing,
mSwingLows //
);
}
else if (iEvent == X_SWING_HIGH_DETECTED)
{
//
has = GetLastItem(
iSwing,
mSwingHighs //
);
}
if (has)
{
item = (XCBasePOI *)iSwing;
}
//
has = item != NULL;
if (has)
{
//
NotifyEventListeners(
iEvent,
item //
);
}
}
//
// Momentum Bar ...
has = DetectMomentum(
iBar,
iEvent //
);
if (has)
{
//
Add(
iEvent,
events //
);
//
XCBasePOI *item = NULL;
XCMomentumBar *iMomentum = NULL;
if (iEvent == X_BULLISH_MOMENTUM_BAR_DETECTED)
{
//
has = GetLastItem(
iMomentum,
mBullishMomentumBars //
);
}
else if (iEvent == X_BEARISH_MOMENTUM_BAR_DETECTED)
{
//
has = GetLastItem(
iMomentum,
mBearishMomentumBars //
);
}
if (has)
{
item = (XCBasePOI *)iMomentum;
}
//
has = item != NULL;
if (has)
{
//
NotifyEventListeners(
iEvent,
item //
);
}
}
//
// Rejection Bar ...
has = DetectRejection(
iBar,
iEvent //
);
if (has)
{
//
Add(
iEvent,
events //
);
//
XCBasePOI *item = NULL;
XCRejectionBar *iRejection = NULL;
if (iEvent == X_BULLISH_REJECTION_BAR_DETECTED)
{
//
has = GetLastItem(
iRejection,
mBullishRejectionBars //
);
}
else if (iEvent == X_BEARISH_REJECTION_BAR_DETECTED)
{
//
has = GetLastItem(
iRejection,
mBearishRejectionBars //
);
}
if (has)
{
item = (XCBasePOI *)iRejection;
}
//
has = item != NULL;
if (has)
{
//
NotifyEventListeners(
iEvent,
item //
);
}
}
//
// Support ...
has = DetectSupportZone(
iBar,
iEvent //
);
if (has)
{
//
Add(
iEvent,
events //
);
//
XCBasePOI *item = NULL;
XCSupportZone *iZone = NULL;
has = GetLastItem(
iZone,
mSupportZones //
);
if (has)
{
item = (XCBasePOI *)iZone;
}
//
has = item != NULL;
if (has)
{
//
NotifyEventListeners(
iEvent,
item //
);
}
}
//
// Demand ...
has = DetectDemandZone(
iBar,
iEvent //
);
if (has)
{
//
Add(
iEvent,
events //
);
//
XCBasePOI *item = NULL;
XCDemandZone *iZone = NULL;
has = GetLastItem(
iZone,
mDemandZones //
);
if (has)
{
item = (XCBasePOI *)iZone;
}
//
has = item != NULL;
if (has)
{
//
NotifyEventListeners(
iEvent,
item //
);
}
}
//
// Resistance ...
has = DetectResistanceZone(
iBar,
iEvent //
);
if (has)
{
//
Add(
iEvent,
events //
);
//
XCBasePOI *item = NULL;
XCResistanceZone *iZone = NULL;
has = GetLastItem(
iZone,
mResistanceZones //
);
if (has)
{
item = (XCBasePOI *)iZone;
}
//
has = item != NULL;
if (has)
{
//
NotifyEventListeners(
iEvent,
item //
);
}
}
//
// Supply ...
has = DetectSupplyZone(
iBar,
iEvent //
);
if (has)
{
//
Add(
iEvent,
events //
);
//
XCBasePOI *item = NULL;
XCSupplyZone *iZone = NULL;
has = GetLastItem(
iZone,
mSupplyZones //
);
if (has)
{
item = (XCBasePOI *)iZone;
}
//
has = item != NULL;
if (has)
{
//
NotifyEventListeners(
iEvent,
item //
);
}
}
//
// OrderBlock ...
has = DetectOrderBlock(
iBar,
iEvent //
);
if (has)
{
//
Add(
iEvent,
events //
);
//
XCBasePOI *item = NULL;
XCOrderBlock *iZone = NULL;
if (iEvent == X_BULLISH_ORDERBLOCK_DETECTED)
{
//
has = GetLastItem(
iZone,
mBullishOrderBlocks //
);
}
else if (iEvent == X_BEARISH_ORDERBLOCK_DETECTED)
{
//
has = GetLastItem(
iZone,
mBearishOrderBlocks //
);
}
if (has)
{
item = (XCBasePOI *)iZone;
}
//
has = item != NULL;
if (has)
{
//
NotifyEventListeners(
iEvent,
item //
);
}
}
//
// FairValueGap ...
has = DetectFairValueGap(
iBar,
iEvent //
);
if (has)
{
//
Add(
iEvent,
events //
);
//
XCBasePOI *item = NULL;
XCFVG *iZone = NULL;
if (iEvent == X_BULLISH_FVG_DETECTED)
{
//
has = GetLastItem(
iZone,
mBullishFairValueGaps //
);
}
else if (iEvent == X_BEARISH_FVG_DETECTED)
{
//
has = GetLastItem(
iZone,
mBearishFairValueGaps //
);
}
if (has)
{
item = (XCBasePOI *)iZone;
}
//
has = item != NULL;
if (has)
{
//
NotifyEventListeners(
iEvent,
item //
);
}
}
//
has = DetectConsolidationZone(
iBar,
iEvent //
);
if (has)
{
//
Add(
iEvent,
events //
);
}
//
iBar.Clean();
mLock = false;
// mBarTracker.Waits();
//
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();
//
Copy(
mSwings,
state.swings //
);
//
Copy(
mSwingHighs,
state.swingHighs //
);
//
Copy(
mSwingLows,
state.swingLows //
);
//
Copy(
mMomentumBars,
state.momentumBars //
);
//
Copy(
mBullishMomentumBars,
state.bullishMomentumBars //
);
//
Copy(
mBearishMomentumBars,
state.bearishMomentumBars //
);
//
Copy(
mRejectionBars,
state.rejectionBars //
);
//
Copy(
mBullishRejectionBars,
state.bullishRejectionBars //
);
//
Copy(
mBearishRejectionBars,
state.bearishRejectionBars //
);
//
Copy(
mSupportZones,
state.supportZones //
);
//
Copy(
mResistanceZones,
state.resistanceZones //
);
//
Copy(
mSupplyZones,
state.supplyZones //
);
//
Copy(
mDemandZones,
state.demandZones //
);
//
Copy(
mOrderBlocks,
state.orderBlocks //
);
//
Copy(
mBullishOrderBlocks,
state.bullishOrderBlocks //
);
//
Copy(
mBearishOrderBlocks,
state.bearishOrderBlocks //
);
//
Copy(
mFairValueGaps,
state.fairValueGaps //
);
//
Copy(
mBullishFairValueGaps,
state.bullishFairValueGaps //
);
//
Copy(
mBearishFairValueGaps,
state.bearishFairValueGaps //
);
//
Copy(
mConsolidationZones,
state.consolidationZones //
);
//
Copy(
mBullishConsolidationZones,
state.bullishConsolidationZones //
);
//
Copy(
mBearishConsolidationZones,
state.bearishConsolidationZones //
);
//
}
/**
* Destroy Instance ...
*/
void Destroy()
{
//
mBarTracker.Clean();
ZeroMemory(mBarAnalyser);
//
CleanCollections();
}
//
//
//
//
//
//
/**
* Detect Swing Bars ...
*
* @param bar: XOHCL instance ...
* @param reversal: boolean reversal add to collection ...
*
* @return ( bool )
*/
bool DetectSwing(
XOHCL &bar,
ENUM_XPOI_EVENTS &state,
bool reversal = false //
)
{
//
bool result = false;
//
state = X_POI_EVENT_NONE;
//
result = bar.IsValid();
if (!result)
{
return result;
}
//
ENUM_X_DIRECTION iDir;
result = mBarAnalyser.IsSwing(
bar,
iDir,
mSwingRange //
);
//
result = result &&
HasDirection(iDir);
if (!result)
{
return result;
}
//
bool isBullish = IsBullish(iDir);
bool isBearish = IsBearish(iDir);
//
ENUM_XPOIS type =
isBullish
? X_POI_SWING_LOW
: X_POI_SWING_HIGH;
//
// Swing Object ...
XCSwing *swing;
swing = new XCSwing();
result = swing.Init(
bar,
type //
);
if (!result)
{
return result;
}
//
// Add ...
//
int idx = FindIndex(
swing,
mSwings //
);
result = !IsValidIndex(idx);
if (!result)
{
return result;
}
//
if (reversal)
{
//
ArrayReverse(mSwings);
//
Add(
swing,
mSwings //
);
//
ArrayReverse(mSwings);
}
else
{
//
Add(
swing,
mSwings //
);
}
//
if (isBullish)
{
//
// Add Swings ...
if (reversal)
{
//
ArrayReverse(mSwings);
//
Add(
swing,
mSwings //
);
//
ArrayReverse(mSwings);
}
else
{
//
Add(
swing,
mSwingLows //
);
}
}
else if (isBearish)
{
//
// Add Swings ...
if (reversal)
{
//
ArrayReverse(mSwingHighs);
//
Add(
swing,
mSwingHighs //
);
//
ArrayReverse(mSwingHighs);
}
else
{
//
Add(
swing,
mSwingHighs //
);
}
}
//
state =
isBullish
? X_SWING_LOW_DETECTED
: X_SWING_HIGH_DETECTED;
//
return result;
}
/**
* Detect Momentum Bars ...
*
* @param bar: XOHCL instance ...
* @param reversal: boolean reversal add to collection ...
*
* @return ( bool )
*/
bool DetectMomentum(
XOHCL &bar,
ENUM_XPOI_EVENTS &state,
bool reversal = false //
)
{
//
bool result = false;
//
state = X_POI_EVENT_NONE;
//
result = bar.IsValid();
if (!result)
{
return result;
}
//
ENUM_X_DIRECTION iDir;
result = mBarAnalyser.IsMomentumBar(
bar,
iDir,
mMomentumExtend, // Extends ...
mMomentumBodyPercent // Body Percent ...
);
//
result = result &&
HasDirection(iDir);
if (!result)
{
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(
bar //
);
if (!result)
{
return result;
}
//
int idx = FindIndex(
momentum,
mMomentumBars //
);
result = !IsValidIndex(idx);
if (!result)
{
return result;
}
//
// Add ...
if (reversal)
{
//
ArrayReverse(mMomentumBars);
//
Add(
momentum,
mMomentumBars //
);
//
ArrayReverse(mMomentumBars);
}
else
{
//
Add(
momentum,
mMomentumBars //
);
}
//
if (isBullish)
{
//
// Add Swings ...
if (reversal)
{
//
ArrayReverse(mBullishMomentumBars);
//
Add(
momentum,
mBullishMomentumBars //
);
//
ArrayReverse(mBullishMomentumBars);
}
else
{
//
Add(
momentum,
mBullishMomentumBars //
);
}
}
else if (isBearish)
{
//
// Add Swings ...
if (reversal)
{
//
ArrayReverse(mBearishMomentumBars);
//
Add(
momentum,
mBearishMomentumBars //
);
//
ArrayReverse(mBearishMomentumBars);
}
else
{
//
Add(
momentum,
mBearishMomentumBars //
);
}
}
//
state =
isBullish
? X_BULLISH_MOMENTUM_BAR_DETECTED
: X_BEARISH_MOMENTUM_BAR_DETECTED;
//
return result;
}
/**
* Detect Rejection Bars ...
*
* @param bar: XOHCL instance ...
* @param reversal: boolean reversal add to collection ...
*
* @return ( bool )
*/
bool DetectRejection(
XOHCL &bar,
ENUM_XPOI_EVENTS &state,
bool reversal = false //
)
{
//
bool result = false;
//
state = X_POI_EVENT_NONE;
//
result = bar.IsValid();
if (!result)
{
return result;
}
//
ENUM_X_DIRECTION iDir;
result = mBarAnalyser.IsRejectionBar(
bar,
iDir,
mRejectionExtend, // Extends ...
mRejectionShadowPercent // Shadow Percent ...
);
//
result = result &&
HasDirection(iDir);
if (!result)
{
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(
bar //
);
if (!result)
{
return result;
}
//
int idx = FindIndex(
rejection,
mRejectionBars //
);
result = !IsValidIndex(idx);
if (!result)
{
return result;
}
//
// Add ...
if (reversal)
{
//
ArrayReverse(mRejectionBars);
//
Add(
rejection,
mRejectionBars //
);
//
ArrayReverse(mRejectionBars);
}
else
{
//
Add(
rejection,
mRejectionBars //
);
}
//
if (isBullish)
{
//
// Add Swings ...
if (reversal)
{
//
ArrayReverse(mBullishRejectionBars);
//
Add(
rejection,
mBullishRejectionBars //
);
//
ArrayReverse(mBullishRejectionBars);
}
else
{
//
Add(
rejection,
mBullishRejectionBars //
);
}
}
else if (isBearish)
{
//
// Add Swings ...
if (reversal)
{
//
ArrayReverse(mBearishRejectionBars);
//
Add(
rejection,
mBearishRejectionBars //
);
//
ArrayReverse(mBearishRejectionBars);
}
else
{
//
Add(
rejection,
mBearishRejectionBars //
);
}
}
//
state =
isBullish
? X_BULLISH_REJECTION_BAR_DETECTED
: X_BEARISH_REJECTION_BAR_DETECTED;
//
return result;
}
/**
* Detect Support Zone ...
*
* @param bar: XOHCL instance ...
* @param reversal: boolean reversal add to collection ...
*
* @return ( bool )
*/
bool DetectSupportZone(
XOHCL &bar,
ENUM_XPOI_EVENTS &state,
bool reversal = false,
bool forceActivation = false //
)
{
//
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 (forceActivation)
{
//
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;
}
//
if (reversal)
{
//
ArrayReverse(mSupportZones);
//
Add(
supportZone,
mSupportZones //
);
//
ArrayReverse(mSupportZones);
}
else
{
//
Add(
supportZone,
mSupportZones //
);
}
//
state = X_SUPPORT_ZONE_DETECTED;
//
supportBar.Clean();
//
return result;
}
/**
* Detect Resistance Zone ...
*
* @param bar: XOHCL instance ...
* @param reversal: boolean reversal add to collection ...
*
* @return ( bool )
*/
bool DetectResistanceZone(
XOHCL &bar,
ENUM_XPOI_EVENTS &state,
bool reversal = false,
bool forceActivation = false //
)
{
//
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 (forceActivation)
{
//
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;
}
//
if (reversal)
{
//
ArrayReverse(mResistanceZones);
//
Add(
resistanceZone,
mResistanceZones //
);
//
ArrayReverse(mResistanceZones);
}
else
{
//
Add(
resistanceZone,
mResistanceZones //
);
}
//
state = X_RESISTANCE_ZONE_DETECTED;
//
resistanceBar.Clean();
//
return result;
}
/**
* Detect Supply Zone ...
*
* @param bar: XOHCL instance ...
* @param reversal: boolean reversal add to collection ...
*
* @return ( bool )
*/
bool DetectSupplyZone(
XOHCL &bar,
ENUM_XPOI_EVENTS &state,
bool reversal = false,
bool forceActivation = false //
)
{
//
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 (forceActivation)
{
//
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;
}
//
if (reversal)
{
//
ArrayReverse(mSupplyZones);
//
Add(
supplyZone,
mSupplyZones //
);
//
ArrayReverse(mSupplyZones);
}
else
{
//
Add(
supplyZone,
mSupplyZones //
);
}
//
state = X_SUPPLY_ZONE_DETECTED;
//
supplyBar.Clean();
//
return result;
}
/**
* Detect Demand Zone ...
*
* @param bar: XOHCL instance ...
* @param reversal: boolean reversal add to collection ...
*
* @return ( bool )
*/
bool DetectDemandZone(
XOHCL &bar,
ENUM_XPOI_EVENTS &state,
bool reversal = false,
bool forceActivation = false //
)
{
//
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 (forceActivation)
{
//
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;
}
//
if (reversal)
{
//
ArrayReverse(mDemandZones);
//
Add(
demandZone,
mDemandZones //
);
//
ArrayReverse(mDemandZones);
}
else
{
//
Add(
demandZone,
mDemandZones //
);
}
//
state = X_DEMAND_ZONE_DETECTED;
//
demandBar.Clean();
//
return result;
}
/**
* Detect Order Blocks ...
*
* @param bar: XOHCL instance ...
* @param reversal: boolean reversal add to collection ...
*
* @return ( bool )
*/
bool DetectOrderBlock(
XOHCL &bar,
ENUM_XPOI_EVENTS &state,
bool reversal = false,
bool forceActivation = false //
)
{
//
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 //
);
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 (forceActivation)
{
//
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 ...
if (reversal)
{
//
ArrayReverse(mOrderBlocks);
//
Add(
ob,
mOrderBlocks //
);
//
ArrayReverse(mOrderBlocks);
}
else
{
//
Add(
ob,
mOrderBlocks //
);
}
//
if (isBullish)
{
//
// Add Swings ...
if (reversal)
{
//
ArrayReverse(mBullishOrderBlocks);
//
Add(
ob,
mBullishOrderBlocks //
);
//
ArrayReverse(mBullishOrderBlocks);
}
else
{
//
Add(
ob,
mBullishOrderBlocks //
);
}
}
else if (isBearish)
{
//
// Add Swings ...
if (reversal)
{
//
ArrayReverse(mBearishOrderBlocks);
//
Add(
ob,
mBearishOrderBlocks //
);
//
ArrayReverse(mBearishOrderBlocks);
}
else
{
//
Add(
ob,
mBearishOrderBlocks //
);
}
}
//
state =
isBullish
? X_BULLISH_ORDERBLOCK_DETECTED
: X_BEARISH_ORDERBLOCK_DETECTED;
//
obBar.Clean();
//
return result;
}
/**
* Detect Fair Value Gaps ...
*
* @param bar: XOHCL instance ...
* @param reversal: boolean reversal add to collection ...
*
* @return ( bool )
*/
bool DetectFairValueGap(
XOHCL &bar,
ENUM_XPOI_EVENTS &state,
bool reversal = false,
bool forceActivation = false //
)
{
//
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 (forceActivation)
{
//
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 ...
if (reversal)
{
//
ArrayReverse(mFairValueGaps);
//
Add(
fvg,
mFairValueGaps //
);
//
ArrayReverse(mFairValueGaps);
}
else
{
//
Add(
fvg,
mFairValueGaps //
);
}
//
if (isBullish)
{
//
// Add Swings ...
if (reversal)
{
//
ArrayReverse(mBullishFairValueGaps);
//
Add(
fvg,
mBullishFairValueGaps //
);
//
ArrayReverse(mBullishFairValueGaps);
}
else
{
//
Add(
fvg,
mBullishFairValueGaps //
);
}
}
else if (isBearish)
{
//
// Add Swings ...
if (reversal)
{
//
ArrayReverse(mBearishFairValueGaps);
//
Add(
fvg,
mBearishFairValueGaps //
);
//
ArrayReverse(mBearishFairValueGaps);
}
else
{
//
Add(
fvg,
mBearishFairValueGaps //
);
}
}
//
state =
isBullish
? X_BULLISH_FVG_DETECTED
: X_BEARISH_FVG_DETECTED;
//
fvgEndBar.Clean();
fvgStartBar.Clean();
//
return result;
}
/**
* Detect Consolidation Zones ...
*
* @param bar: XOHCL instance ...
* @param reversal: boolean reversal add to collection ...
*
* @return ( bool )
*/
bool DetectConsolidationZone(
XOHCL &bar,
ENUM_XPOI_EVENTS &state,
bool reversal = false //
)
{
//
bool result = false;
//
state = X_POI_EVENT_NONE;
//
XConsolidationZone cZone;
result = mBarAnalyser.HasConsolidationZone(
bar,
cZone,
mConsolidationZoneMinLoopback,
mConsolidationZoneRangeInPoint,
mConsolidationZonesUpperAppliedTo,
mConsolidationZonesLowerAppliedTo //
);
if (!result)
{
//
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)
{
//
cZone.Clean();
//
return result;
}
//
if (reversal)
{
//
ArrayReverse(mConsolidationZones);
//
AddRef(
cZone,
mConsolidationZones //
);
//
ArrayReverse(mConsolidationZones);
}
else
{
//
AddRef(
cZone,
mConsolidationZones //
);
}
//
if (isBullish)
{
//
// Add Swings ...
if (reversal)
{
//
ArrayReverse(mBullishConsolidationZones);
//
AddRef(
cZone,
mBullishConsolidationZones //
);
//
ArrayReverse(mBullishConsolidationZones);
}
else
{
//
AddRef(
cZone,
mBullishConsolidationZones //
);
}
}
else if (isBearish)
{
//
// Add Swings ...
if (reversal)
{
//
ArrayReverse(mBearishConsolidationZones);
//
AddRef(
cZone,
mBearishConsolidationZones //
);
//
ArrayReverse(mBearishConsolidationZones);
}
else
{
//
AddRef(
cZone,
mBearishConsolidationZones //
);
}
}
//
state =
IsBullish(cZone.dir)
? X_BULLISH_CONSOLIDATION_ZONE_DETECTED
: X_BEARISH_CONSOLIDATION_ZONE_DETECTED;
//
cZone.Clean();
//
return result;
}
//
protected:
//
//
void CleanCollections()
{
//
Clean(mSwings);
Clean(mSwingLows);
Clean(mSwingHighs);
Clean(mDemandZones);
Clean(mSupplyZones);
Clean(mOrderBlocks);
Clean(mMomentumBars);
Clean(mSupportZones);
Clean(mRejectionBars);
Clean(mFairValueGaps);
Clean(mEventListeners);
Clean(mResistanceZones);
Clean(mBullishOrderBlocks);
Clean(mBearishOrderBlocks);
Clean(mConsolidationZones);
Clean(mBullishMomentumBars);
Clean(mBearishMomentumBars);
Clean(mBullishRejectionBars);
Clean(mBearishRejectionBars);
Clean(mBullishFairValueGaps);
Clean(mBearishFairValueGaps);
Clean(mBullishConsolidationZones);
Clean(mBearishConsolidationZones);
}
//
void ReverseCollections()
{
//
ArrayReverse(mSwings);
ArrayReverse(mSwingLows);
ArrayReverse(mSwingHighs);
ArrayReverse(mDemandZones);
ArrayReverse(mSupplyZones);
ArrayReverse(mOrderBlocks);
ArrayReverse(mMomentumBars);
ArrayReverse(mSupportZones);
ArrayReverse(mRejectionBars);
ArrayReverse(mFairValueGaps);
ArrayReverse(mEventListeners);
ArrayReverse(mResistanceZones);
ArrayReverse(mBullishOrderBlocks);
ArrayReverse(mBearishOrderBlocks);
ArrayReverse(mConsolidationZones);
ArrayReverse(mBullishMomentumBars);
ArrayReverse(mBearishMomentumBars);
ArrayReverse(mBullishRejectionBars);
ArrayReverse(mBearishRejectionBars);
ArrayReverse(mBullishFairValueGaps);
ArrayReverse(mBearishFairValueGaps);
ArrayReverse(mBullishConsolidationZones);
ArrayReverse(mBearishConsolidationZones);
}
//
void CleanupUnusedCollections(
int maxAllowed = 0 //
)
{
//
maxAllowed = MaxRequiredPOIs();
//
if (maxAllowed <= 0)
{
return;
}
//
CleanupArray(
mEventListeners,
maxAllowed //
);
//
CleanupArray(
mSwings,
maxAllowed //
);
//
CleanupArray(
mSwingLows,
maxAllowed //
);
//
CleanupArray(
mSwingHighs,
maxAllowed //
);
//
CleanupArray(
mMomentumBars,
maxAllowed //
);
//
CleanupArray(
mBullishMomentumBars,
maxAllowed //
);
//
CleanupArray(
mBearishMomentumBars,
maxAllowed //
);
//
CleanupArray(
mRejectionBars,
maxAllowed //
);
//
CleanupArray(
mBullishRejectionBars,
maxAllowed //
);
//
CleanupArray(
mBearishRejectionBars,
maxAllowed //
);
//
CleanupArray(
mSupportZones,
maxAllowed //
);
//
CleanupArray(
mDemandZones,
maxAllowed //
);
//
CleanupArray(
mSupplyZones,
maxAllowed //
);
//
CleanupArray(
mResistanceZones,
maxAllowed //
);
//
CleanupArray(
mFairValueGaps,
maxAllowed //
);
//
CleanupArray(
mBullishFairValueGaps,
maxAllowed //
);
//
CleanupArray(
mBearishFairValueGaps,
maxAllowed //
);
//
CleanupArray(
mOrderBlocks,
maxAllowed //
);
//
CleanupArray(
mBullishOrderBlocks,
maxAllowed //
);
//
CleanupArray(
mBearishOrderBlocks,
maxAllowed //
);
//
CleanupArray(
mConsolidationZones,
maxAllowed //
);
//
CleanupArray(
mBullishConsolidationZones,
maxAllowed //
);
//
CleanupArray(
mBearishConsolidationZones,
maxAllowed //
);
//
}
/**
* 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 ...
//
XCSwing *mSwings[]; // Holds Founded Swing ...
XCSwing *mSwingLows[]; // Holds Founded Swing Lows ...
XCSwing *mSwingHighs[]; // Holds Founded Swing Highs ...
int mSwingRange; // Swing Detection Range ...
//
XCMomentumBar *mMomentumBars[]; // Holds Founded Momentum Bars ...
XCMomentumBar *mBullishMomentumBars[]; // Holds Founded Bullish Momentum Bars ...
XCMomentumBar *mBearishMomentumBars[]; // Holds Founded Bearish Momentum Bars ...
int mMomentumExtend; // Momentum Bar Detection Extends Range ...
double mMomentumBodyPercent; // Momentum Bar Detection Body Percent ...
//
XCRejectionBar *mRejectionBars[]; // Holds Founded Rejection Bars ...
XCRejectionBar *mBullishRejectionBars[]; // Holds Founded Bullish Rejection Bars ...
XCRejectionBar *mBearishRejectionBars[]; // Holds Founded Bearish Rejection Bars ...
int mRejectionExtend; // Rejection Bar Detection Extends Range ...
double mRejectionShadowPercent; // Rejection Bar Detection Body Percent ...
//
XCSupplyZone *mSupplyZones[]; // Holds Detected Supply Zones ...
XCDemandZone *mDemandZones[]; // Holds Detected Demand Zones ...
//
int mSupResRange; // Support and Resistance Detection Range ...
bool mSupResRangeAsStart; // use Support and Resistance Range as Start ...
XCSupportZone *mSupportZones[]; // Holds Detected Support Zones ...
XCResistanceZone *mResistanceZones[]; // Holds Detected Resistance Zones ...
//
XCFVG *mFairValueGaps[]; // Holds Founded FairValueGaps ...
XCFVG *mBullishFairValueGaps[]; // Holds Founded Bullish FairValueGaps ...
XCFVG *mBearishFairValueGaps[]; // Holds Founded Bearish FairValueGaps ...
int mFairValueGapSameBars; // FairValueGap Detection Same Bars ...
//
XCOrderBlock *mOrderBlocks[]; // Holds Founded OrderBlocks ...
XCOrderBlock *mBullishOrderBlocks[]; // Holds Founded Bullish OrderBlocks ...
XCOrderBlock *mBearishOrderBlocks[]; // Holds Founded Bearish OrderBlocks ...
int mOrderBlockSameBars; // OrderBlock Detection Same Bars ...
//
int mConsolidationZoneMinLoopback; // Minimum Length of Cnsolidation Zone ...
double mConsolidationZoneRangeInPoint; // Consolidation Zone Range in Point ...
XConsolidationZone mConsolidationZones[]; // Holds Founded Consolidation Zones ...
XConsolidationZone mBullishConsolidationZones[]; // Holds Founded Bullish Consolidation Zones ...
XConsolidationZone mBearishConsolidationZones[]; // Holds Founded Bearish Consolidation Zones ...
ENUM_APPLIED_PRICE mConsolidationZonesLowerAppliedTo; // Consolidation Zone Upper Applied To ...
ENUM_APPLIED_PRICE mConsolidationZonesUpperAppliedTo; // Consolidation Zone Lower Applied To ...
//
};
//