4370 lines
92 KiB
Plaintext
4370 lines
92 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 "../Classes/x-saherelm.x-poi.drawer.class.mq5"
|
|
#include "../Libraries/x-saherelm.x-poi.lib.mq5"
|
|
|
|
//
|
|
#include <Arrays/ArrayObj.mqh>
|
|
|
|
//
|
|
// Implementation ...
|
|
|
|
//
|
|
// POI Detector Class ...
|
|
class XCPOIDetector : public XCBaseAlert
|
|
{
|
|
//
|
|
public:
|
|
//
|
|
XCPOIDrawer mDrawer;
|
|
|
|
//
|
|
// 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 //
|
|
);
|
|
|
|
//
|
|
// 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 Number of POIs which holds ...
|
|
*
|
|
* @return ( int )
|
|
*/
|
|
int MaxNumberOfPOIs()
|
|
{
|
|
return mMaxNumberOfPOIs;
|
|
}
|
|
|
|
/**
|
|
* Set Max Number of POIs which holds ...
|
|
* 0 => Infinity ...
|
|
*
|
|
* @param value: Integer ...
|
|
*/
|
|
void MaxNumberOfPOIs(int value)
|
|
{
|
|
//
|
|
if (value < 0)
|
|
{
|
|
value = 0;
|
|
}
|
|
|
|
//
|
|
mMaxNumberOfPOIs = value;
|
|
}
|
|
|
|
/**
|
|
* Get Number of POI(s) which must Find at Initializations ...
|
|
*
|
|
* @return ( int )
|
|
*/
|
|
int MaxNumberOfRequiredPOIs()
|
|
{
|
|
return mMaxNumberOfRequiredPOIs;
|
|
}
|
|
|
|
/**
|
|
* Set Number of POI(s) which must Find at Initializations ...
|
|
* 2 is Default ...
|
|
*
|
|
* @param value: Integer ...
|
|
*/
|
|
void MaxNumberOfRequiredPOIs(int value)
|
|
{
|
|
//
|
|
if (value < 2)
|
|
{
|
|
value = 2;
|
|
}
|
|
|
|
//
|
|
mMaxNumberOfRequiredPOIs = value;
|
|
}
|
|
|
|
/**
|
|
* Check Is Locked or not ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool IsLocked()
|
|
{
|
|
return mLock;
|
|
}
|
|
|
|
//
|
|
// POI(s) Configs ...
|
|
|
|
//
|
|
// Swings ...
|
|
|
|
/**
|
|
* Get Swing Verification Range Length ...
|
|
*
|
|
* @return ( int )
|
|
*/
|
|
int SwingRange()
|
|
{
|
|
return mSwingRange;
|
|
}
|
|
|
|
/**
|
|
* Set Swing Verification Range Length ...
|
|
*
|
|
* @param value: Integer ...
|
|
*/
|
|
void SwingRange(int value)
|
|
{
|
|
//
|
|
if (value < 0)
|
|
{
|
|
value = 0;
|
|
}
|
|
|
|
//
|
|
mSwingRange = value;
|
|
}
|
|
|
|
//
|
|
// Momentum Bars ...
|
|
|
|
/**
|
|
* Get Momentum Bars must Extends Range ...
|
|
*
|
|
* @return ( int )
|
|
*/
|
|
int MomentumBarExtendRange()
|
|
{
|
|
return mMomentumBarExtendRange;
|
|
}
|
|
|
|
/**
|
|
* Set Momentum Bars must Extends Range ...
|
|
*
|
|
* @param value: Integer ...
|
|
*/
|
|
void MomentumBarExtendRange(int value)
|
|
{
|
|
//
|
|
if (value < 0)
|
|
{
|
|
value = 0;
|
|
}
|
|
|
|
//
|
|
mMomentumBarExtendRange = value;
|
|
}
|
|
|
|
/**
|
|
* Get Momentum Bars Body Percent ...
|
|
*
|
|
* @return ( double )
|
|
*/
|
|
double MomentumBarBodyPercent()
|
|
{
|
|
return mMomentumBarBodyPercent;
|
|
}
|
|
|
|
/**
|
|
* Set Momentum Bars Body Percent ...
|
|
*
|
|
* @param value: Double ...
|
|
*/
|
|
void MomentumBarBodyPercent(double value)
|
|
{
|
|
//
|
|
if (value < 50)
|
|
{
|
|
value = 50;
|
|
}
|
|
|
|
//
|
|
mMomentumBarBodyPercent = value;
|
|
}
|
|
|
|
//
|
|
// Rejection Bars ...
|
|
|
|
/**
|
|
* Get Rejection Bars must Extends Range ...
|
|
*
|
|
* @return ( int )
|
|
*/
|
|
int RejectionBarExtendRange()
|
|
{
|
|
return mRejectionBarExtendRange;
|
|
}
|
|
|
|
/**
|
|
* Set Rejection Bars must Extends Range ...
|
|
*
|
|
* @param value: Integer ...
|
|
*/
|
|
void RejectionBarExtendRange(int value)
|
|
{
|
|
//
|
|
if (value < 0)
|
|
{
|
|
value = 0;
|
|
}
|
|
|
|
//
|
|
mRejectionBarExtendRange = value;
|
|
}
|
|
|
|
/**
|
|
* Get Rejection Bars Shadow Percent ...
|
|
*
|
|
* @return ( double )
|
|
*/
|
|
double RejectionBarShadowPercent()
|
|
{
|
|
return mRejectionBarShadowPercent;
|
|
}
|
|
|
|
/**
|
|
* Set Rejection Bars Shadow Percent ...
|
|
*
|
|
* @param value: Double ...
|
|
*/
|
|
void RejectionBarShadowPercent(double value)
|
|
{
|
|
//
|
|
if (value < 50)
|
|
{
|
|
value = 50;
|
|
}
|
|
|
|
//
|
|
mRejectionBarShadowPercent = value;
|
|
}
|
|
|
|
//
|
|
// Support and Resistance Zone(s) ...
|
|
|
|
/**
|
|
* Get Support and Resistance Range for Verification ...
|
|
*
|
|
* @return ( int )
|
|
*/
|
|
int SupportAndResistanceRange()
|
|
{
|
|
return mSupportAndResistanceRange;
|
|
}
|
|
|
|
/**
|
|
* Set Support and Resistance Range for Verification ...
|
|
*
|
|
* @param value: Integer ...
|
|
*/
|
|
void SupportAndResistanceRange(int value)
|
|
{
|
|
//
|
|
if (value < 2)
|
|
{
|
|
value = 2;
|
|
}
|
|
|
|
//
|
|
mSupportAndResistanceRange = value;
|
|
}
|
|
|
|
//
|
|
// Supply and Demand Zone(s) ...
|
|
|
|
/**
|
|
* Get Supply and Demand Range Verifications ...
|
|
*
|
|
* @return ( int )
|
|
*/
|
|
int SupplyAndDemandRange()
|
|
{
|
|
return mSupplyAndDemandRange;
|
|
}
|
|
|
|
/**
|
|
* Set Supply and Demand Range Verifications ...
|
|
*
|
|
* @param value: Integer ...
|
|
*/
|
|
void SupplyAndDemandRange(int value)
|
|
{
|
|
//
|
|
if (value < 2)
|
|
{
|
|
value = 2;
|
|
}
|
|
|
|
//
|
|
mSupplyAndDemandRange = value;
|
|
}
|
|
|
|
//
|
|
// Order Blocks ...
|
|
|
|
/**
|
|
* Get Order Blocks Detection Bars ...
|
|
*
|
|
* @return ( int )
|
|
*/
|
|
int OrderBlocksSameBars()
|
|
{
|
|
return mOrderBlocksSameBars;
|
|
}
|
|
|
|
/**
|
|
* Set Order Blocks Detection Bars ...
|
|
*
|
|
* @param value: Argument 1
|
|
*/
|
|
void OrderBlocksSameBars(int value)
|
|
{
|
|
//
|
|
if (value < 0)
|
|
{
|
|
value = 0;
|
|
}
|
|
|
|
//
|
|
mOrderBlocksSameBars = value;
|
|
}
|
|
|
|
//
|
|
// Fair Value Gaps ...
|
|
|
|
/**
|
|
* Get Fair Value Gaps Detection Same Bars ...
|
|
*
|
|
* @return ( int )
|
|
*/
|
|
int FairValueGapsSameBars()
|
|
{
|
|
return mFairValueGapsSameBars;
|
|
}
|
|
|
|
/**
|
|
* Set Fair Value Gaps Detection Same Bars ...
|
|
*
|
|
* @param value: Integer ...
|
|
*/
|
|
void FairValueGapsSameBars(int value)
|
|
{
|
|
//
|
|
if (value < 0)
|
|
{
|
|
value = 0;
|
|
}
|
|
|
|
//
|
|
mFairValueGapsSameBars = value;
|
|
}
|
|
|
|
//
|
|
// Ticks Zone ...
|
|
|
|
/**
|
|
* Get Ticks Range Levels ...
|
|
*
|
|
* @return ( int )
|
|
*/
|
|
int TicksRangeZoneLevel()
|
|
{
|
|
return mTicksRangeZoneLevel;
|
|
}
|
|
|
|
/**
|
|
* Set Ticks Range Levels ...
|
|
*
|
|
* @param value: Integer ...
|
|
*/
|
|
void TicksRangeZoneLevel(int value)
|
|
{
|
|
//
|
|
if (value < 2)
|
|
{
|
|
value = 2;
|
|
}
|
|
|
|
//
|
|
mTicksRangeZoneLevel = value;
|
|
}
|
|
|
|
/**
|
|
* Get Ticks Range Zone Loopback Period ...
|
|
*
|
|
* @return ( int )
|
|
*/
|
|
int TicksRangeZoneRange()
|
|
{
|
|
return mTicksRangeZoneRange;
|
|
}
|
|
|
|
/**
|
|
* Set Ticks Range Zone Loopback Period ...
|
|
*
|
|
* @param value: Integer ...
|
|
*/
|
|
void TicksRangeZoneRange(int value)
|
|
{
|
|
//
|
|
if (value < 7)
|
|
{
|
|
value = 7;
|
|
}
|
|
|
|
//
|
|
mTicksRangeZoneRange = value;
|
|
}
|
|
|
|
//
|
|
// Actions ...
|
|
|
|
/**
|
|
* Initialize POI Detector ...
|
|
*/
|
|
void Init()
|
|
{
|
|
DetectRequiredPOIs();
|
|
}
|
|
|
|
/**
|
|
* Update POI(s) ...
|
|
*
|
|
* @param state: an Array Refrence of ENUM_XPOI_EVENTS members ...
|
|
*/
|
|
int Update(
|
|
ENUM_XPOI_EVENTS &state[] //
|
|
)
|
|
{
|
|
//
|
|
int result = 0;
|
|
|
|
//
|
|
Clean(state);
|
|
|
|
//
|
|
// Check Bar Tracker if Waits ...
|
|
if (!mBarTracker.IsNewBar())
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
int zIndex = 0;
|
|
int cIndex = zIndex + 1;
|
|
int pIndex = cIndex + 1;
|
|
|
|
//
|
|
string symbol = GetSymbol();
|
|
ENUM_TIMEFRAMES period = GetPeriod();
|
|
|
|
//
|
|
datetime cTime = TimeCurrent();
|
|
|
|
//
|
|
XOHCL zBar;
|
|
bool isInited = zBar.Init(
|
|
symbol,
|
|
period,
|
|
zIndex //
|
|
);
|
|
if (!isInited)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
XOHCL cBar;
|
|
isInited = cBar.Init(
|
|
symbol,
|
|
period,
|
|
cIndex //
|
|
);
|
|
if (!isInited)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// POI Detecting ...
|
|
bool isDetected = false;
|
|
|
|
//
|
|
// Swings ...
|
|
int swingRange = SwingRange();
|
|
if (swingRange > 0)
|
|
{
|
|
//
|
|
XOHCL swingBar;
|
|
isInited = swingBar.Init(
|
|
symbol,
|
|
period,
|
|
zIndex + swingRange //
|
|
);
|
|
if (isInited)
|
|
{
|
|
//
|
|
// Swing High ...
|
|
isDetected = DetectSwingHigh(swingBar);
|
|
if (isDetected)
|
|
{
|
|
//
|
|
ENUM_XPOI_EVENTS event = X_SWING_HIGH_DETECTED;
|
|
XCSwing *param;
|
|
bool hasItem = GetLastItem(
|
|
param,
|
|
mSwingHighs //
|
|
);
|
|
if (hasItem)
|
|
{
|
|
//
|
|
NotifyEventListeners(
|
|
event,
|
|
param //
|
|
);
|
|
}
|
|
|
|
//
|
|
Add(
|
|
event,
|
|
state //
|
|
);
|
|
}
|
|
|
|
//
|
|
// Swing Low ...
|
|
isDetected = DetectSwingLow(swingBar);
|
|
if (isDetected)
|
|
{
|
|
//
|
|
ENUM_XPOI_EVENTS event = X_SWING_LOW_DETECTED;
|
|
XCSwing *param;
|
|
bool hasItem = GetLastItem(
|
|
param,
|
|
mSwingLows //
|
|
);
|
|
if (hasItem)
|
|
{
|
|
//
|
|
NotifyEventListeners(
|
|
event,
|
|
param //
|
|
);
|
|
}
|
|
|
|
//
|
|
Add(
|
|
event,
|
|
state //
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// Bullish Momentum Bars ...
|
|
isDetected = DetectBullishMomentumBar(cBar);
|
|
if (isDetected)
|
|
{
|
|
//
|
|
ENUM_XPOI_EVENTS event = X_BULLISH_MOMENTUM_BAR_DETECTED;
|
|
XCMomentumBar *param;
|
|
bool hasItem = GetLastItem(
|
|
param,
|
|
mBullishMomentumBars //
|
|
);
|
|
if (hasItem)
|
|
{
|
|
//
|
|
NotifyEventListeners(
|
|
event,
|
|
param //
|
|
);
|
|
}
|
|
|
|
//
|
|
Add(
|
|
event,
|
|
state //
|
|
);
|
|
}
|
|
|
|
//
|
|
// Bearish Momentum Bars ...
|
|
isDetected = DetectBearishMomentumBar(cBar);
|
|
if (isDetected)
|
|
{
|
|
//
|
|
ENUM_XPOI_EVENTS event = X_BEARISH_MOMENTUM_BAR_DETECTED;
|
|
XCMomentumBar *param;
|
|
bool hasItem = GetLastItem(
|
|
param,
|
|
mBearishMomentumBars //
|
|
);
|
|
if (hasItem)
|
|
{
|
|
//
|
|
NotifyEventListeners(
|
|
event,
|
|
param //
|
|
);
|
|
}
|
|
|
|
//
|
|
Add(
|
|
event,
|
|
state //
|
|
);
|
|
}
|
|
|
|
//
|
|
// Bullish Rejection Bars ...
|
|
isDetected = DetectBullishRejectionBar(cBar);
|
|
if (isDetected)
|
|
{
|
|
//
|
|
ENUM_XPOI_EVENTS event = X_BULLISH_REJECTION_BAR_DETECTED;
|
|
XCRejectionBar *param;
|
|
bool hasItem = GetLastItem(
|
|
param,
|
|
mBullishRejectionBars //
|
|
);
|
|
if (hasItem)
|
|
{
|
|
//
|
|
NotifyEventListeners(
|
|
event,
|
|
param //
|
|
);
|
|
}
|
|
|
|
//
|
|
Add(
|
|
event,
|
|
state //
|
|
);
|
|
}
|
|
|
|
//
|
|
// Bearish Rejection Bars ...
|
|
isDetected = DetectBearishRejectionBar(cBar);
|
|
if (isDetected)
|
|
{
|
|
//
|
|
ENUM_XPOI_EVENTS event = X_BEARISH_REJECTION_BAR_DETECTED;
|
|
XCRejectionBar *param;
|
|
bool hasItem = GetLastItem(
|
|
param,
|
|
mBearishRejectionBars //
|
|
);
|
|
if (hasItem)
|
|
{
|
|
//
|
|
NotifyEventListeners(
|
|
event,
|
|
param //
|
|
);
|
|
}
|
|
|
|
//
|
|
Add(
|
|
event,
|
|
state //
|
|
);
|
|
}
|
|
|
|
//
|
|
// Support and Resistance Zones ...
|
|
int supResRange = SupportAndResistanceRange();
|
|
if (supResRange > 0)
|
|
{
|
|
//
|
|
XOHCL supResBar;
|
|
isInited = supResBar.Init(
|
|
symbol,
|
|
period,
|
|
zIndex + supResRange //
|
|
);
|
|
if (isInited)
|
|
{
|
|
//
|
|
// Support Zones ...
|
|
isDetected = DetectSupportZone(supResBar);
|
|
if (isDetected)
|
|
{
|
|
//
|
|
ENUM_XPOI_EVENTS event = X_SUPPORT_ZONE_DETECTED;
|
|
XCSupportZone *param;
|
|
bool hasItem = GetLastItem(
|
|
param,
|
|
mSupportZones //
|
|
);
|
|
if (hasItem)
|
|
{
|
|
//
|
|
NotifyEventListeners(
|
|
event,
|
|
param //
|
|
);
|
|
}
|
|
|
|
//
|
|
Add(
|
|
event,
|
|
state //
|
|
);
|
|
}
|
|
|
|
//
|
|
// Resistance Zones ...
|
|
isDetected = DetectResistanceZone(supResBar);
|
|
if (isDetected)
|
|
{
|
|
//
|
|
ENUM_XPOI_EVENTS event = X_RESISTANCE_ZONE_DETECTED;
|
|
XCResistanceZone *param;
|
|
bool hasItem = GetLastItem(
|
|
param,
|
|
mResistanceZones //
|
|
);
|
|
if (hasItem)
|
|
{
|
|
//
|
|
NotifyEventListeners(
|
|
event,
|
|
param //
|
|
);
|
|
}
|
|
|
|
//
|
|
Add(
|
|
event,
|
|
state //
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// Supply And Demand Zones ...
|
|
int supDemRange = SupplyAndDemandRange();
|
|
if (supDemRange > 0)
|
|
{
|
|
//
|
|
// Supply Zone ...
|
|
isDetected = DetectSupplyZone(cBar);
|
|
if (isDetected)
|
|
{
|
|
//
|
|
ENUM_XPOI_EVENTS event = X_SUPPLY_ZONE_DETECTED;
|
|
XCSupplyZone *param;
|
|
bool hasItem = GetLastItem(
|
|
param,
|
|
mSupplyZones //
|
|
);
|
|
if (hasItem)
|
|
{
|
|
//
|
|
NotifyEventListeners(
|
|
event,
|
|
param //
|
|
);
|
|
}
|
|
|
|
//
|
|
Add(
|
|
event,
|
|
state //
|
|
);
|
|
}
|
|
|
|
//
|
|
// Demand Zone ...
|
|
isDetected = DetectDemandZone(cBar);
|
|
if (isDetected)
|
|
{
|
|
//
|
|
ENUM_XPOI_EVENTS event = X_DEMAND_ZONE_DETECTED;
|
|
XCDemandZone *param;
|
|
bool hasItem = GetLastItem(
|
|
param,
|
|
mDemandZones //
|
|
);
|
|
if (hasItem)
|
|
{
|
|
//
|
|
NotifyEventListeners(
|
|
event,
|
|
param //
|
|
);
|
|
}
|
|
|
|
//
|
|
Add(
|
|
event,
|
|
state //
|
|
);
|
|
}
|
|
}
|
|
|
|
//
|
|
// Order Blocks ...
|
|
int obSameBars = OrderBlocksSameBars();
|
|
if (obSameBars > 0)
|
|
{
|
|
//
|
|
// Bullish Order Block ...
|
|
isDetected = DetectBullishOrderBlock(cBar);
|
|
if (isDetected)
|
|
{
|
|
//
|
|
ENUM_XPOI_EVENTS event = X_BULLISH_ORDERBLOCK_DETECTED;
|
|
XCOrderBlock *param;
|
|
bool hasItem = GetLastItem(
|
|
param,
|
|
mBullishOrderBlocks //
|
|
);
|
|
if (hasItem)
|
|
{
|
|
//
|
|
NotifyEventListeners(
|
|
event,
|
|
param //
|
|
);
|
|
}
|
|
|
|
//
|
|
Add(
|
|
event,
|
|
state //
|
|
);
|
|
}
|
|
|
|
//
|
|
// Bearish Order Block ...
|
|
isDetected = DetectBearishOrderBlock(cBar);
|
|
if (isDetected)
|
|
{
|
|
//
|
|
ENUM_XPOI_EVENTS event = X_BEARISH_ORDERBLOCK_DETECTED;
|
|
XCOrderBlock *param;
|
|
bool hasItem = GetLastItem(
|
|
param,
|
|
mBearishOrderBlocks //
|
|
);
|
|
if (hasItem)
|
|
{
|
|
//
|
|
NotifyEventListeners(
|
|
event,
|
|
param //
|
|
);
|
|
}
|
|
|
|
//
|
|
Add(
|
|
event,
|
|
state //
|
|
);
|
|
}
|
|
}
|
|
|
|
//
|
|
// Fair Value Gaps ...
|
|
int fvgSameBars = FairValueGapsSameBars();
|
|
if (fvgSameBars > 0)
|
|
{
|
|
//
|
|
// Bullish Fair Value Gap ...
|
|
isDetected = DetectBullishFairValueGap(cBar);
|
|
if (isDetected)
|
|
{
|
|
//
|
|
ENUM_XPOI_EVENTS event = X_BULLISH_FVG_DETECTED;
|
|
XCFVG *param;
|
|
bool hasItem = GetLastItem(
|
|
param,
|
|
mBullishFairValueGaps //
|
|
);
|
|
if (hasItem)
|
|
{
|
|
//
|
|
NotifyEventListeners(
|
|
event,
|
|
param //
|
|
);
|
|
}
|
|
|
|
//
|
|
Add(
|
|
event,
|
|
state //
|
|
);
|
|
}
|
|
|
|
//
|
|
// Bearish Fair Value Gap ...
|
|
isDetected = DetectBearishFairValueGap(cBar);
|
|
if (isDetected)
|
|
{
|
|
//
|
|
ENUM_XPOI_EVENTS event = X_BEARISH_FVG_DETECTED;
|
|
XCFVG *param;
|
|
bool hasItem = GetLastItem(
|
|
param,
|
|
mBearishFairValueGaps //
|
|
);
|
|
if (hasItem)
|
|
{
|
|
//
|
|
NotifyEventListeners(
|
|
event,
|
|
param //
|
|
);
|
|
}
|
|
|
|
//
|
|
Add(
|
|
event,
|
|
state //
|
|
);
|
|
}
|
|
}
|
|
|
|
//
|
|
// Ticks Range Zone ...
|
|
int ticksLevels = TicksRangeZoneLevel();
|
|
int ticksRange = TicksRangeZoneRange();
|
|
if (ticksLevels > 0 &&
|
|
ticksRange > 0)
|
|
{
|
|
//
|
|
isDetected = DetectTicksZoneRange(cBar);
|
|
if (isDetected)
|
|
{
|
|
}
|
|
}
|
|
|
|
//
|
|
ValidatePOIs(cBar);
|
|
|
|
//
|
|
CleanupUnusedPOIs();
|
|
|
|
//
|
|
mBarTracker.Waits();
|
|
|
|
//
|
|
result = ArraySize(state);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Destroy Class ...
|
|
*/
|
|
void Destroy()
|
|
{
|
|
//
|
|
DestroyPOIs();
|
|
DestroySessions();
|
|
DestroyEventListeners();
|
|
}
|
|
|
|
//
|
|
// Retrievers ...
|
|
|
|
/**
|
|
* 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(
|
|
mSwingHighs,
|
|
state.swingHighs //
|
|
);
|
|
|
|
//
|
|
Copy(
|
|
mSwingLows,
|
|
state.swingLows //
|
|
);
|
|
|
|
//
|
|
Copy(
|
|
mBullishMomentumBars,
|
|
state.bullishMomentumBars //
|
|
);
|
|
|
|
//
|
|
Copy(
|
|
mBearishMomentumBars,
|
|
state.bearishMomentumBars //
|
|
);
|
|
|
|
//
|
|
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(
|
|
mBullishOrderBlocks,
|
|
state.bullishOrderBlocks //
|
|
);
|
|
|
|
//
|
|
Copy(
|
|
mBearishOrderBlocks,
|
|
state.bearishOrderBlocks //
|
|
);
|
|
|
|
//
|
|
Copy(
|
|
mBullishFairValueGaps,
|
|
state.bullishFairValueGaps //
|
|
);
|
|
|
|
//
|
|
Copy(
|
|
mBearishFairValueGaps,
|
|
state.bearishFairValueGaps //
|
|
);
|
|
|
|
//
|
|
state.ticksZone = mTicksZone;
|
|
|
|
//
|
|
}
|
|
|
|
//
|
|
// Event Listeners ...
|
|
|
|
/**
|
|
* Add Event Listener ...
|
|
*
|
|
* @param listener: TOnPOIEvent instance ...
|
|
*/
|
|
void AddEventListener(TOnPOIEvent listener)
|
|
{
|
|
//
|
|
Add(
|
|
listener,
|
|
mEventListeners //
|
|
);
|
|
}
|
|
|
|
//
|
|
// Destroy ...
|
|
|
|
/**
|
|
* Destroy Detected POI(s) ...
|
|
*/
|
|
void DestroyPOIs()
|
|
{
|
|
//
|
|
Clean(mSwingHighs);
|
|
Clean(mSwingLows);
|
|
|
|
//
|
|
Clean(mBullishMomentumBars);
|
|
Clean(mBearishMomentumBars);
|
|
|
|
//
|
|
Clean(mBullishRejectionBars);
|
|
Clean(mBearishRejectionBars);
|
|
|
|
//
|
|
Clean(mSupportZones);
|
|
Clean(mResistanceZones);
|
|
|
|
//
|
|
Clean(mSupplyZones);
|
|
Clean(mDemandZones);
|
|
|
|
//
|
|
Clean(mBullishOrderBlocks);
|
|
Clean(mBearishOrderBlocks);
|
|
|
|
//
|
|
Clean(mBullishFairValueGaps);
|
|
Clean(mBearishFairValueGaps);
|
|
}
|
|
|
|
/**
|
|
* Destroy Added Sessions ...
|
|
*/
|
|
void DestroySessions()
|
|
{
|
|
}
|
|
|
|
/**
|
|
* Destroy Rejistered Event Handlers ...
|
|
*/
|
|
void DestroyEventListeners()
|
|
{
|
|
Clean(mEventListeners);
|
|
}
|
|
|
|
//
|
|
// Virtual Actions ...
|
|
|
|
/**
|
|
* Apply Default Configurations ...
|
|
*/
|
|
virtual void Default()
|
|
{
|
|
//
|
|
// Common ...
|
|
|
|
//
|
|
MaxNumberOfPOIs(10);
|
|
MaxNumberOfRequiredPOIs(2);
|
|
|
|
//
|
|
SwingRange(2);
|
|
|
|
//
|
|
MomentumBarExtendRange(2);
|
|
MomentumBarBodyPercent(70);
|
|
|
|
//
|
|
RejectionBarExtendRange(0);
|
|
RejectionBarShadowPercent(55);
|
|
|
|
//
|
|
SupportAndResistanceRange(7);
|
|
|
|
//
|
|
SupplyAndDemandRange(144);
|
|
|
|
//
|
|
OrderBlocksSameBars(3);
|
|
|
|
//
|
|
FairValueGapsSameBars(3);
|
|
|
|
//
|
|
TicksRangeZoneLevel(10);
|
|
TicksRangeZoneRange(144);
|
|
}
|
|
|
|
//
|
|
// Detector Functions ...
|
|
|
|
/**
|
|
* Detect Swing High ...
|
|
*
|
|
* @param bar: XOHCL instance ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool DetectSwingHigh(XOHCL &bar)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
result = bar.IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
int range = SwingRange();
|
|
int barIndex = bar.Index();
|
|
result = range > 0 &&
|
|
barIndex >= range;
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result = mBarAnalyser.IsSwingHigh(
|
|
bar,
|
|
range //
|
|
);
|
|
if (result)
|
|
{
|
|
//
|
|
XCSwing *swing;
|
|
swing = new XCSwing();
|
|
result = swing.Init(
|
|
bar,
|
|
X_POI_SWING_HIGH //
|
|
);
|
|
|
|
//
|
|
if (result)
|
|
{
|
|
//
|
|
Add(
|
|
swing,
|
|
mSwingHighs //
|
|
);
|
|
|
|
//
|
|
// XCSwingHighObject *iObj;
|
|
// bool isCreated = mDrawer.CreateSwingHigh(
|
|
// swing,
|
|
// iObj //
|
|
// );
|
|
// if (isCreated)
|
|
// {
|
|
// AddObjectIfNotExists(iObj);
|
|
// }
|
|
}
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Detect Swing Low ...
|
|
*
|
|
* @param bar: XOHCL instance ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool DetectSwingLow(XOHCL &bar)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
result = bar.IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
int range = SwingRange();
|
|
int barIndex = bar.Index();
|
|
result = range > 0 &&
|
|
barIndex >= range;
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result = mBarAnalyser.IsSwingLow(
|
|
bar,
|
|
range //
|
|
);
|
|
if (result)
|
|
{
|
|
//
|
|
XCSwing *swing;
|
|
swing = new XCSwing();
|
|
result = swing.Init(
|
|
bar,
|
|
X_POI_SWING_LOW //
|
|
);
|
|
|
|
//
|
|
if (result)
|
|
{
|
|
//
|
|
Add(
|
|
swing,
|
|
mSwingLows //
|
|
);
|
|
|
|
// //
|
|
// XCSwingLowObject *iObj;
|
|
// bool isCreated = mDrawer.CreateSwingLow(
|
|
// swing,
|
|
// iObj //
|
|
// );
|
|
// if (isCreated)
|
|
// {
|
|
// AddObjectIfNotExists(iObj);
|
|
// }
|
|
}
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Detect Bullish Momentum Bar ...
|
|
*
|
|
* @param bar: XOHCL instance ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool DetectBullishMomentumBar(XOHCL &bar)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
result = bar.IsValid() &&
|
|
bar.Index() > 0;
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
int extendRange = MomentumBarExtendRange();
|
|
double bodyPercent = MomentumBarBodyPercent();
|
|
ENUM_X_DIRECTION dir;
|
|
result = mBarAnalyser.IsMomentumBar(
|
|
bar,
|
|
dir,
|
|
extendRange,
|
|
bodyPercent //
|
|
);
|
|
result =
|
|
result &&
|
|
dir == X_DIRECTION_BULLISH;
|
|
if (result)
|
|
{
|
|
//
|
|
XCMomentumBar *momentumBar;
|
|
momentumBar = new XCMomentumBar();
|
|
result = momentumBar.Init(bar);
|
|
|
|
//
|
|
if (result)
|
|
{
|
|
//
|
|
Add(
|
|
momentumBar,
|
|
mBullishMomentumBars //
|
|
);
|
|
|
|
//
|
|
// XCBullishMomentumObject *iObj;
|
|
// bool isCreated = mDrawer.CreateBullishMomentumBar(
|
|
// momentumBar,
|
|
// iObj //
|
|
// );
|
|
// if (isCreated)
|
|
// {
|
|
// AddObjectIfNotExists(iObj);
|
|
// }
|
|
}
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Detect Bearish Momentum Bar ...
|
|
*
|
|
* @param bar: XOHCL instance ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool DetectBearishMomentumBar(XOHCL &bar)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
result = bar.IsValid() &&
|
|
bar.Index() > 0;
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
int extendRange = MomentumBarExtendRange();
|
|
double bodyPercent = MomentumBarBodyPercent();
|
|
ENUM_X_DIRECTION dir;
|
|
result = mBarAnalyser.IsMomentumBar(
|
|
bar,
|
|
dir,
|
|
extendRange,
|
|
bodyPercent //
|
|
);
|
|
result =
|
|
result &&
|
|
dir == X_DIRECTION_BEARISH;
|
|
if (result)
|
|
{
|
|
//
|
|
XCMomentumBar *momentumBar;
|
|
momentumBar = new XCMomentumBar();
|
|
result = momentumBar.Init(bar);
|
|
|
|
//
|
|
if (result)
|
|
{
|
|
//
|
|
Add(
|
|
momentumBar,
|
|
mBearishMomentumBars //
|
|
);
|
|
|
|
//
|
|
// XCBearishMomentumObject *iObj;
|
|
// bool isCreated = mDrawer.CreateBearishMomentumBar(
|
|
// momentumBar,
|
|
// iObj //
|
|
// );
|
|
// if (isCreated)
|
|
// {
|
|
// AddObjectIfNotExists(iObj);
|
|
// }
|
|
}
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Detect Bullish Rejection Bar ...
|
|
*
|
|
* @param bar: XOHCL instance ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool DetectBullishRejectionBar(XOHCL &bar)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
result = bar.IsValid() &&
|
|
bar.Index() > 0;
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
int extendRange = RejectionBarExtendRange();
|
|
double shadowPercent = RejectionBarShadowPercent();
|
|
ENUM_X_DIRECTION dir;
|
|
result = mBarAnalyser.IsRejectionBar(
|
|
bar,
|
|
dir,
|
|
extendRange,
|
|
shadowPercent //
|
|
);
|
|
result =
|
|
result &&
|
|
dir == X_DIRECTION_BULLISH;
|
|
if (result)
|
|
{
|
|
//
|
|
XCRejectionBar *rejectionBar;
|
|
rejectionBar = new XCRejectionBar();
|
|
result = rejectionBar.Init(bar);
|
|
|
|
//
|
|
if (result)
|
|
{
|
|
//
|
|
Add(
|
|
rejectionBar,
|
|
mBullishRejectionBars //
|
|
);
|
|
|
|
// //
|
|
// XCBullishRejectionObject *iObj;
|
|
// bool isCreated = mDrawer.CreateBullishRejectionBar(
|
|
// rejectionBar,
|
|
// iObj //
|
|
// );
|
|
// if (isCreated)
|
|
// {
|
|
// AddObjectIfNotExists(iObj);
|
|
// }
|
|
}
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Detect Bearish Rejection Bar ...
|
|
*
|
|
* @param bar: XOHCL instance ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool DetectBearishRejectionBar(XOHCL &bar)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
result = bar.IsValid() &&
|
|
bar.Index() > 0;
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
int extendRange = RejectionBarExtendRange();
|
|
double shadowPercent = RejectionBarShadowPercent();
|
|
ENUM_X_DIRECTION dir;
|
|
result = mBarAnalyser.IsRejectionBar(
|
|
bar,
|
|
dir,
|
|
extendRange,
|
|
shadowPercent //
|
|
);
|
|
result =
|
|
result &&
|
|
dir == X_DIRECTION_BEARISH;
|
|
if (result)
|
|
{
|
|
//
|
|
XCRejectionBar *rejectionBar;
|
|
rejectionBar = new XCRejectionBar();
|
|
result = rejectionBar.Init(bar);
|
|
|
|
//
|
|
if (result)
|
|
{
|
|
//
|
|
Add(
|
|
rejectionBar,
|
|
mBearishRejectionBars //
|
|
);
|
|
|
|
//
|
|
// XCBearishRejectionObject *iObj;
|
|
// bool isCreated = mDrawer.CreateBearishRejectionBar(
|
|
// rejectionBar,
|
|
// iObj //
|
|
// );
|
|
// if (isCreated)
|
|
// {
|
|
// AddObjectIfNotExists(iObj);
|
|
// }
|
|
}
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Detect Support Zone ...
|
|
*
|
|
* @param bar: XOHCL instance ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool DetectSupportZone(XOHCL &bar)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
result = bar.IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
int range = SupportAndResistanceRange();
|
|
int barIndex = bar.Index();
|
|
result = range > 0 &&
|
|
barIndex >= range;
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result = mBarAnalyser.IsSupport(
|
|
bar,
|
|
range //
|
|
);
|
|
if (result)
|
|
{
|
|
//
|
|
XCSupportZone *support;
|
|
support = new XCSupportZone();
|
|
result = support.Init(
|
|
bar,
|
|
range //
|
|
);
|
|
|
|
//
|
|
if (result)
|
|
{
|
|
//
|
|
datetime cTime = TimeCurrent();
|
|
support.To(cTime);
|
|
|
|
//
|
|
Add(
|
|
support,
|
|
mSupportZones //
|
|
);
|
|
|
|
// //
|
|
// XCSupportZoneObject *iObj;
|
|
// bool isCreated = mDrawer.CreateSupportZone(
|
|
// support,
|
|
// iObj //
|
|
// );
|
|
// if (isCreated)
|
|
// {
|
|
// AddObjectIfNotExists(iObj);
|
|
// }
|
|
}
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Detect Resistance Zone ...
|
|
*
|
|
* @param bar: XOHCL instance ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool DetectResistanceZone(XOHCL &bar)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
result = bar.IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
int range = SupportAndResistanceRange();
|
|
int barIndex = bar.Index();
|
|
result = range > 0 &&
|
|
barIndex >= range;
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result = mBarAnalyser.IsResistance(
|
|
bar,
|
|
range //
|
|
);
|
|
if (result)
|
|
{
|
|
//
|
|
XCResistanceZone *resistance;
|
|
resistance = new XCResistanceZone();
|
|
result = resistance.Init(
|
|
bar,
|
|
range //
|
|
);
|
|
|
|
//
|
|
if (result)
|
|
{
|
|
//
|
|
Add(
|
|
resistance,
|
|
mResistanceZones //
|
|
);
|
|
|
|
// //
|
|
// XCResistanceZoneObject *iObj;
|
|
// bool isCreated = mDrawer.CreateResistanceZone(
|
|
// resistance,
|
|
// iObj //
|
|
// );
|
|
// if (isCreated)
|
|
// {
|
|
// AddObjectIfNotExists(iObj);
|
|
// }
|
|
}
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Detect Supply Zone ...
|
|
*
|
|
* @param bar: XOHCL instance ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool DetectSupplyZone(XOHCL &bar)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
result = bar.IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
int range = SupplyAndDemandRange();
|
|
result = range > 0;
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
int hhIDX = -1;
|
|
double hh = -1;
|
|
|
|
//
|
|
int llIDX = -1;
|
|
double ll = -1;
|
|
|
|
//
|
|
result = mBarAnalyser
|
|
.CalculateLoopbackHLData(
|
|
hhIDX,
|
|
hh,
|
|
llIDX,
|
|
ll,
|
|
bar,
|
|
range //
|
|
);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
XOHCL supplyBar;
|
|
result = supplyBar.Init(
|
|
bar.symbol,
|
|
bar.period,
|
|
hhIDX //
|
|
);
|
|
if (result)
|
|
{
|
|
//
|
|
XCSupplyZone *supply;
|
|
supply = new XCSupplyZone();
|
|
result = supply.Init(
|
|
supplyBar,
|
|
range //
|
|
);
|
|
|
|
//
|
|
if (result)
|
|
{
|
|
//
|
|
datetime cTime = TimeCurrent();
|
|
supply.To(cTime);
|
|
|
|
//
|
|
Add(
|
|
supply,
|
|
mSupplyZones //
|
|
);
|
|
|
|
// //
|
|
// XCSupplyZoneObject *iObj;
|
|
// bool isCreated = mDrawer.CreateSupplyZone(
|
|
// supply,
|
|
// iObj //
|
|
// );
|
|
// if (isCreated)
|
|
// {
|
|
// AddObjectIfNotExists(iObj);
|
|
// }
|
|
}
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Detect Demand Zone ...
|
|
*
|
|
* @param bar: XOHCL instance ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool DetectDemandZone(XOHCL &bar)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
result = bar.IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
int range = SupplyAndDemandRange();
|
|
result = range > 0;
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
int hhIDX = -1;
|
|
double hh = -1;
|
|
|
|
//
|
|
int llIDX = -1;
|
|
double ll = -1;
|
|
|
|
//
|
|
result = mBarAnalyser
|
|
.CalculateLoopbackHLData(
|
|
hhIDX,
|
|
hh,
|
|
llIDX,
|
|
ll,
|
|
bar,
|
|
range //
|
|
);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
XOHCL demandBar;
|
|
result = demandBar.Init(
|
|
bar.symbol,
|
|
bar.period,
|
|
llIDX //
|
|
);
|
|
if (result)
|
|
{
|
|
//
|
|
XCDemandZone *demand;
|
|
demand = new XCDemandZone();
|
|
result = demand.Init(
|
|
demandBar,
|
|
range //
|
|
);
|
|
|
|
//
|
|
if (result)
|
|
{
|
|
//
|
|
datetime cTime = TimeCurrent();
|
|
demand.To(cTime);
|
|
|
|
//
|
|
Add(
|
|
demand,
|
|
mDemandZones //
|
|
);
|
|
|
|
// //
|
|
// XCDemandZoneObject *iObj;
|
|
// bool isCreated = mDrawer.CreateDemandZone(
|
|
// demand,
|
|
// iObj //
|
|
// );
|
|
// if (isCreated)
|
|
// {
|
|
// AddObjectIfNotExists(iObj);
|
|
// }
|
|
}
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Detect Bullish Order Block ...
|
|
*
|
|
* @param bar: XOHCL instance ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool DetectBullishOrderBlock(XOHCL &bar)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
result = bar.IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
int sameBars = OrderBlocksSameBars();
|
|
result = sameBars > 0;
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
XOHCL obBar;
|
|
ENUM_X_DIRECTION dir;
|
|
result = mBarAnalyser
|
|
.HasOrderBlock(
|
|
bar,
|
|
obBar,
|
|
dir,
|
|
sameBars //
|
|
);
|
|
result =
|
|
result &&
|
|
dir == X_DIRECTION_BULLISH;
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
if (result)
|
|
{
|
|
//
|
|
XCOrderBlock *ob;
|
|
ob = new XCOrderBlock();
|
|
result = ob.Init(
|
|
obBar,
|
|
dir //
|
|
);
|
|
|
|
//
|
|
if (result)
|
|
{
|
|
//
|
|
datetime cTime = TimeCurrent();
|
|
ob.To(cTime);
|
|
|
|
//
|
|
Add(
|
|
ob,
|
|
mBullishOrderBlocks //
|
|
);
|
|
|
|
// //
|
|
// XCBullishOrderBlockObject *iObj;
|
|
// bool isCreated = mDrawer.CreateBullishOrderBlock(
|
|
// ob,
|
|
// iObj //
|
|
// );
|
|
// if (isCreated)
|
|
// {
|
|
// AddObjectIfNotExists(iObj);
|
|
// }
|
|
}
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Detect Bullish Order Block ...
|
|
*
|
|
* @param bar: XOHCL instance ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool DetectBullishOrderBlock(
|
|
XOHCL &bar,
|
|
XCOrderBlock *&ob //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
result = bar.IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
int sameBars = OrderBlocksSameBars();
|
|
result = sameBars > 0;
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
XOHCL obBar;
|
|
ENUM_X_DIRECTION dir;
|
|
result = mBarAnalyser
|
|
.HasOrderBlock(
|
|
bar,
|
|
obBar,
|
|
dir,
|
|
sameBars //
|
|
);
|
|
result =
|
|
result &&
|
|
dir == X_DIRECTION_BULLISH;
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
if (result)
|
|
{
|
|
//
|
|
ob = new XCOrderBlock();
|
|
result = ob.Init(
|
|
obBar,
|
|
dir //
|
|
);
|
|
|
|
//
|
|
if (result)
|
|
{
|
|
//
|
|
datetime cTime = TimeCurrent();
|
|
ob.To(cTime);
|
|
}
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Detect Bearish Order Block ...
|
|
*
|
|
* @param bar: XOHCL instance ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool DetectBearishOrderBlock(XOHCL &bar)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
result = bar.IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
int sameBars = OrderBlocksSameBars();
|
|
result = sameBars > 0;
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
XOHCL obBar;
|
|
ENUM_X_DIRECTION dir;
|
|
result = mBarAnalyser
|
|
.HasOrderBlock(
|
|
bar,
|
|
obBar,
|
|
dir,
|
|
sameBars //
|
|
);
|
|
result =
|
|
result &&
|
|
dir == X_DIRECTION_BEARISH;
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
if (result)
|
|
{
|
|
//
|
|
XCOrderBlock *ob;
|
|
ob = new XCOrderBlock();
|
|
result = ob.Init(
|
|
obBar,
|
|
dir //
|
|
);
|
|
|
|
//
|
|
if (result)
|
|
{
|
|
//
|
|
datetime cTime = TimeCurrent();
|
|
ob.To(cTime);
|
|
|
|
//
|
|
Add(
|
|
ob,
|
|
mBearishOrderBlocks //
|
|
);
|
|
|
|
// //
|
|
// XCBearishOrderBlockObject *iObj;
|
|
// bool isCreated = mDrawer.CreateBearishOrderBlock(
|
|
// ob,
|
|
// iObj //
|
|
// );
|
|
// if (isCreated)
|
|
// {
|
|
// AddObjectIfNotExists(iObj);
|
|
// }
|
|
}
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Detect Bearish Order Block ...
|
|
*
|
|
* @param bar: XOHCL instance ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool DetectBearishOrderBlock(
|
|
XOHCL &bar,
|
|
XCOrderBlock *&ob //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
result = bar.IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
int sameBars = OrderBlocksSameBars();
|
|
result = sameBars > 0;
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
XOHCL obBar;
|
|
ENUM_X_DIRECTION dir;
|
|
result = mBarAnalyser
|
|
.HasOrderBlock(
|
|
bar,
|
|
obBar,
|
|
dir,
|
|
sameBars //
|
|
);
|
|
result =
|
|
result &&
|
|
dir == X_DIRECTION_BEARISH;
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
if (result)
|
|
{
|
|
//
|
|
ob = new XCOrderBlock();
|
|
result = ob.Init(
|
|
obBar,
|
|
dir //
|
|
);
|
|
|
|
//
|
|
if (result)
|
|
{
|
|
//
|
|
datetime cTime = TimeCurrent();
|
|
ob.To(cTime);
|
|
}
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Detect Bullish Fair Value Gap ...
|
|
*
|
|
* @param bar: XOHCL instance ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool DetectBullishFairValueGap(XOHCL &bar)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
result = bar.IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
int sameBars = FairValueGapsSameBars();
|
|
result = sameBars > 0;
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
XOHCL prevBar;
|
|
XOHCL nextBar;
|
|
ENUM_X_DIRECTION dir;
|
|
result = mBarAnalyser
|
|
.HasFairValueGap(
|
|
bar,
|
|
prevBar,
|
|
nextBar,
|
|
dir,
|
|
sameBars //
|
|
);
|
|
result =
|
|
result &&
|
|
dir == X_DIRECTION_BULLISH;
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
if (result)
|
|
{
|
|
//
|
|
XCFVG *fvg;
|
|
fvg = new XCFVG();
|
|
result = fvg.Init(
|
|
prevBar,
|
|
nextBar,
|
|
dir //
|
|
);
|
|
|
|
//
|
|
if (result)
|
|
{
|
|
//
|
|
datetime cTime = TimeCurrent();
|
|
fvg.To(cTime);
|
|
|
|
//
|
|
Add(
|
|
fvg,
|
|
mBullishFairValueGaps //
|
|
);
|
|
|
|
// //
|
|
// XCBullishFairValueGapObject *iObj;
|
|
// bool isCreated = mDrawer.CreateBullishFairValueGap(
|
|
// fvg,
|
|
// iObj //
|
|
// );
|
|
// if (isCreated)
|
|
// {
|
|
// AddObjectIfNotExists(iObj);
|
|
// }
|
|
}
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Detect Bearish Fair Value Gap ...
|
|
*
|
|
* @param bar: XOHCL instance ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool DetectBearishFairValueGap(XOHCL &bar)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
result = bar.IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
int sameBars = FairValueGapsSameBars();
|
|
result = sameBars > 0;
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
XOHCL prevBar;
|
|
XOHCL nextBar;
|
|
ENUM_X_DIRECTION dir;
|
|
result = mBarAnalyser
|
|
.HasFairValueGap(
|
|
bar,
|
|
prevBar,
|
|
nextBar,
|
|
dir,
|
|
sameBars //
|
|
);
|
|
result =
|
|
result &&
|
|
dir == X_DIRECTION_BEARISH;
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
if (result)
|
|
{
|
|
//
|
|
XCFVG *fvg;
|
|
fvg = new XCFVG();
|
|
result = fvg.Init(
|
|
prevBar,
|
|
nextBar,
|
|
dir //
|
|
);
|
|
|
|
//
|
|
if (result)
|
|
{
|
|
//
|
|
datetime cTime = TimeCurrent();
|
|
fvg.To(cTime);
|
|
|
|
//
|
|
Add(
|
|
fvg,
|
|
mBearishFairValueGaps //
|
|
);
|
|
|
|
// //
|
|
// XCBearishFairValueGapObject *iObj;
|
|
// bool isCreated = mDrawer.CreateBearishFairValueGap(
|
|
// fvg,
|
|
// iObj //
|
|
// );
|
|
// if (isCreated)
|
|
// {
|
|
// AddObjectIfNotExists(iObj);
|
|
// }
|
|
}
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
protected:
|
|
//
|
|
|
|
//
|
|
// Actions ...
|
|
|
|
/**
|
|
* Lock ...
|
|
*/
|
|
void Lock()
|
|
{
|
|
mLock = true;
|
|
}
|
|
|
|
/**
|
|
* Unlock ...
|
|
*/
|
|
void Unlock()
|
|
{
|
|
mLock = false;
|
|
}
|
|
|
|
/**
|
|
* Detect Required POI(s) ...
|
|
*
|
|
* @param barIndex: Integer Start bar index ...
|
|
* 0 is Default ...
|
|
*/
|
|
void DetectRequiredPOIs(int barIndex = 0)
|
|
{
|
|
//
|
|
// Validate Reuired POI(s) ...
|
|
int requiredPOIs = MaxNumberOfRequiredPOIs();
|
|
if (requiredPOIs <= 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
// Locking Detector ...
|
|
Lock();
|
|
|
|
//
|
|
// Normalize Bar Index ...
|
|
if (barIndex < 0)
|
|
{
|
|
barIndex = 0;
|
|
}
|
|
|
|
//
|
|
int swingLowsCount = 0;
|
|
int swingHighsCount = 0;
|
|
|
|
//
|
|
int bullishMomentumBarsCount = 0;
|
|
int bearishMomentumBarsCount = 0;
|
|
|
|
//
|
|
int bullishRejectionBarsCount = 0;
|
|
int bearishRejectionBarsCount = 0;
|
|
|
|
//
|
|
int supportZonesCount = 0;
|
|
int resistanceZonesCount = 0;
|
|
|
|
//
|
|
int supplyZonesCount = 0;
|
|
int demandZonesCount = 0;
|
|
|
|
//
|
|
int bullishOrderBlocksCount = 0;
|
|
int bearishOrderBlocksCount = 0;
|
|
|
|
//
|
|
int bullishFairValueGapsCount = 0;
|
|
int bearishFairValueGapsCount = 0;
|
|
|
|
//
|
|
bool canContinue = true;
|
|
|
|
//
|
|
while (canContinue)
|
|
{
|
|
//
|
|
// Swings ...
|
|
int swingRange = SwingRange();
|
|
if (swingRange > 0)
|
|
{
|
|
//
|
|
// Swing Highs ...
|
|
swingHighsCount = DetectRequiredSwingHighs(barIndex);
|
|
if (swingHighsCount == requiredPOIs)
|
|
{
|
|
ArrayReverse(mSwingHighs);
|
|
}
|
|
|
|
//
|
|
// Swing Lows ...
|
|
swingLowsCount = DetectRequiredSwingLows(barIndex);
|
|
if (swingLowsCount == requiredPOIs)
|
|
{
|
|
ArrayReverse(mSwingLows);
|
|
}
|
|
}
|
|
|
|
//
|
|
bool canLookupMomentumBars =
|
|
MomentumBarExtendRange() >= 0 &&
|
|
MomentumBarBodyPercent() > 0;
|
|
if (canLookupMomentumBars)
|
|
{
|
|
//
|
|
//
|
|
// Bullish Momentum Bars ...
|
|
bullishMomentumBarsCount = DetectRequiredBullishMomentumBars(barIndex);
|
|
if (bullishMomentumBarsCount == requiredPOIs)
|
|
{
|
|
ArrayReverse(mBullishMomentumBars);
|
|
}
|
|
|
|
//
|
|
// Bearish Momentum Bars ...
|
|
bearishMomentumBarsCount = DetectRequiredBearishMomentumBars(barIndex);
|
|
if (bearishMomentumBarsCount == requiredPOIs)
|
|
{
|
|
ArrayReverse(mBearishMomentumBars);
|
|
}
|
|
}
|
|
|
|
//
|
|
bool canLookupRejectionBars =
|
|
RejectionBarExtendRange() >= 0 &&
|
|
RejectionBarShadowPercent() > 0;
|
|
if (canLookupRejectionBars)
|
|
{
|
|
//
|
|
//
|
|
// Bullish Rejection Bars ...
|
|
bullishRejectionBarsCount = DetectRequiredBullishRejectionBars(barIndex);
|
|
if (bullishRejectionBarsCount == requiredPOIs)
|
|
{
|
|
ArrayReverse(mBullishRejectionBars);
|
|
}
|
|
|
|
//
|
|
// Bearish Rejection Bars ...
|
|
bearishRejectionBarsCount = DetectRequiredBearishRejectionBars(barIndex);
|
|
if (bearishRejectionBarsCount == requiredPOIs)
|
|
{
|
|
ArrayReverse(mBearishRejectionBars);
|
|
}
|
|
}
|
|
|
|
//
|
|
// Support and Resistance Zones ...
|
|
int supResRange = SupportAndResistanceRange();
|
|
if (supResRange > 0)
|
|
{
|
|
//
|
|
// Support Zone(s) ...
|
|
supportZonesCount = DetectRequiredSupportZones(barIndex);
|
|
if (supportZonesCount == requiredPOIs)
|
|
{
|
|
ArrayReverse(mSupportZones);
|
|
}
|
|
|
|
//
|
|
// Resistance Zone(s) ...
|
|
resistanceZonesCount = DetectRequiredResistanceZones(barIndex);
|
|
if (resistanceZonesCount == requiredPOIs)
|
|
{
|
|
ArrayReverse(mResistanceZones);
|
|
}
|
|
}
|
|
|
|
//
|
|
// Supply and Demand Zones ...
|
|
int supDemRange = SupplyAndDemandRange();
|
|
if (supDemRange > 0)
|
|
{
|
|
//
|
|
supplyZonesCount = DetectRequiredSupplyZones(barIndex);
|
|
if (supplyZonesCount == requiredPOIs)
|
|
{
|
|
ArrayReverse(mSupplyZones);
|
|
}
|
|
|
|
//
|
|
demandZonesCount = DetectRequiredDemandZones(barIndex);
|
|
if (demandZonesCount == requiredPOIs)
|
|
{
|
|
ArrayReverse(mDemandZones);
|
|
}
|
|
}
|
|
|
|
//
|
|
// Oder Blocks ...
|
|
int obSameBars = OrderBlocksSameBars();
|
|
if (obSameBars > 0)
|
|
{
|
|
//
|
|
// Bullish Order Blocks ...
|
|
bullishOrderBlocksCount = DetectRequiredBullishOrderBlocks(barIndex);
|
|
if (bullishOrderBlocksCount == requiredPOIs)
|
|
{
|
|
ArrayReverse(mBullishOrderBlocks);
|
|
}
|
|
|
|
//
|
|
// Bearish Order Blocks ...
|
|
bearishOrderBlocksCount = DetectRequiredBearishOrderBlocks(barIndex);
|
|
if (bearishOrderBlocksCount == requiredPOIs)
|
|
{
|
|
ArrayReverse(mBearishOrderBlocks);
|
|
}
|
|
}
|
|
|
|
//
|
|
// Fair Value Gaps ...
|
|
int fvgSameBars = FairValueGapsSameBars();
|
|
if (fvgSameBars > 0)
|
|
{
|
|
//
|
|
// Bullish Fair Value Gaps ...
|
|
bullishFairValueGapsCount = DetectRequiredBullishFairValueGaps(barIndex);
|
|
if (bullishFairValueGapsCount == requiredPOIs)
|
|
{
|
|
ArrayReverse(mBullishFairValueGaps);
|
|
}
|
|
|
|
//
|
|
// Bearish Fair Value Gaps ...
|
|
bearishFairValueGapsCount = DetectRequiredBearishFairValueGaps(barIndex);
|
|
if (bearishFairValueGapsCount == requiredPOIs)
|
|
{
|
|
ArrayReverse(mBearishFairValueGaps);
|
|
}
|
|
}
|
|
|
|
//
|
|
// Swings ...
|
|
bool canContinueSwingHighs =
|
|
swingRange > 0
|
|
? swingHighsCount < requiredPOIs
|
|
: false;
|
|
bool canContinueSwingLows =
|
|
swingRange > 0
|
|
? swingLowsCount < requiredPOIs
|
|
: false;
|
|
|
|
//
|
|
// Support and Resistance Zones ...
|
|
bool canContinueSupportZones =
|
|
supResRange > 0
|
|
? supportZonesCount < requiredPOIs
|
|
: false;
|
|
bool canContinueResistanceZones =
|
|
supResRange > 0
|
|
? resistanceZonesCount < requiredPOIs
|
|
: false;
|
|
|
|
//
|
|
// Supply and Demand Zones ...
|
|
bool canContinueSupplyZones =
|
|
supDemRange > 0
|
|
? supplyZonesCount < requiredPOIs
|
|
: false;
|
|
bool canContinueDemandZones =
|
|
supDemRange > 0
|
|
? demandZonesCount < requiredPOIs
|
|
: false;
|
|
|
|
//
|
|
// Order Blocks ...
|
|
bool canContinueBullishOrderBlocks =
|
|
obSameBars > 0
|
|
? bullishOrderBlocksCount < requiredPOIs
|
|
: false;
|
|
bool canContinueBearishOrderBlocks =
|
|
obSameBars > 0
|
|
? bearishOrderBlocksCount < requiredPOIs
|
|
: false;
|
|
|
|
//
|
|
// Fair Value Gaps ...
|
|
bool canContinueBullishFairValueGaps =
|
|
fvgSameBars > 0
|
|
? bullishFairValueGapsCount < requiredPOIs
|
|
: false;
|
|
bool canContinueBearishFairValueGaps =
|
|
fvgSameBars > 0
|
|
? bearishFairValueGapsCount < requiredPOIs
|
|
: false;
|
|
|
|
//
|
|
// Rejection Bars ...
|
|
bool canContinueBullishRejectionBars =
|
|
canLookupRejectionBars
|
|
? bullishRejectionBarsCount < requiredPOIs
|
|
: false;
|
|
bool canContinueBearishRejectionBars =
|
|
canLookupRejectionBars
|
|
? bearishRejectionBarsCount < requiredPOIs
|
|
: false;
|
|
|
|
//
|
|
// Momentum Bars ...
|
|
bool canContinueBullishMomentumBars =
|
|
canLookupMomentumBars
|
|
? bullishMomentumBarsCount < requiredPOIs
|
|
: false;
|
|
bool canContinueBearishMomentumBars =
|
|
canLookupMomentumBars
|
|
? bearishMomentumBarsCount < requiredPOIs
|
|
: false;
|
|
|
|
//
|
|
canContinue =
|
|
//
|
|
// Swings ...
|
|
canContinueSwingHighs ||
|
|
canContinueSwingLows ||
|
|
//
|
|
// Support and Resistance Zones ...
|
|
canContinueSupportZones ||
|
|
canContinueResistanceZones ||
|
|
//
|
|
// Supply and Demand Zones ...
|
|
canContinueSupplyZones ||
|
|
canContinueDemandZones ||
|
|
//
|
|
// Order Blocks ...
|
|
canContinueBullishOrderBlocks ||
|
|
canContinueBearishOrderBlocks ||
|
|
//
|
|
// Fair Value Gaps ...
|
|
canContinueBullishFairValueGaps ||
|
|
canContinueBearishFairValueGaps ||
|
|
//
|
|
// Rejection Bars ...
|
|
canContinueBullishRejectionBars ||
|
|
canContinueBearishRejectionBars ||
|
|
//
|
|
// Momentum Bars ...
|
|
canContinueBullishMomentumBars ||
|
|
canContinueBearishMomentumBars
|
|
//
|
|
;
|
|
if (canContinue)
|
|
{
|
|
barIndex++;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Unlocking Detector ...
|
|
Unlock();
|
|
}
|
|
|
|
/**
|
|
* Validate Founded POI(s) ...
|
|
*
|
|
* @param bar: XOHCL instance ...
|
|
*/
|
|
void ValidatePOIs(XOHCL &bar)
|
|
{
|
|
}
|
|
|
|
/**
|
|
* Cleanup Unused Objects ...
|
|
*/
|
|
void CleanupUnusedPOIs()
|
|
{
|
|
//
|
|
int maxAllowed = MaxNumberOfPOIs();
|
|
if (!IsValidSize(maxAllowed))
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
int swingHighsCount = ArraySize(mSwingHighs);
|
|
int swingLowsCount = ArraySize(mSwingLows);
|
|
// int tradingDaysCount = ArraySize(mTradingDays);
|
|
// int marketSessionsCount = ArraySize(mMarketSessions);
|
|
// 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;
|
|
|
|
//
|
|
// Swings ...
|
|
|
|
// //
|
|
// // Swing Highs ...
|
|
// if (swingHighsCount >= maxAllowed)
|
|
// {
|
|
// //
|
|
// ArrayRemove(
|
|
// mSwingHighs,
|
|
// from,
|
|
// count //
|
|
// );
|
|
// }
|
|
|
|
// //
|
|
// // Swing Lows ...
|
|
// if (swingLowsCount >= maxAllowed)
|
|
// {
|
|
// //
|
|
// ArrayRemove(
|
|
// mSwingLows,
|
|
// from,
|
|
// count //
|
|
// );
|
|
// }
|
|
|
|
// //
|
|
// // 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 //
|
|
// );
|
|
// }
|
|
|
|
// //
|
|
// // 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 //
|
|
// );
|
|
// }
|
|
|
|
//
|
|
}
|
|
|
|
/**
|
|
* 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 //
|
|
);
|
|
}
|
|
}
|
|
|
|
void AddObjectIfNotExists(XCBaseObject *object)
|
|
{
|
|
//
|
|
string name = object.ObjName();
|
|
|
|
//
|
|
bool canAdd = true;
|
|
int count = mDrawnObjects.Total();
|
|
if (IsValidSize(count))
|
|
{
|
|
//
|
|
for (int i = 0; i < count; i++)
|
|
{
|
|
//
|
|
string iName = ((XCBaseObject *)mDrawnObjects.At(i)).ObjName();
|
|
|
|
//
|
|
if (name == iName)
|
|
{
|
|
//
|
|
canAdd = false;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
if (canAdd)
|
|
{
|
|
mDrawnObjects.Add(object);
|
|
}
|
|
}
|
|
|
|
//
|
|
private:
|
|
//
|
|
|
|
//
|
|
// Props ...
|
|
|
|
//
|
|
bool mLock; // Lock State ...
|
|
string mSymbol; // Market Symbol ...
|
|
ENUM_TIMEFRAMES mPeriod; // Market Period ...
|
|
int mMaxNumberOfPOIs; // Max Allowed Number of POI(s) which Can Holds ...
|
|
int mMaxNumberOfRequiredPOIs; // Max Allowed Number of POI(s) which Must Find at Initializion Time ...
|
|
|
|
//
|
|
CArrayObj mDrawnObjects; // Drawn Objects ...
|
|
XBarTracker mBarTracker; // Market Bar Tracker ...
|
|
XCBarAnalyser mBarAnalyser; // Bar Analyser ...
|
|
|
|
//
|
|
TOnPOIEvent mEventListeners[]; // Event Listeners ...
|
|
|
|
//
|
|
// POI Props ...
|
|
|
|
//
|
|
// XDay ...
|
|
|
|
//
|
|
// XSession ...
|
|
|
|
//
|
|
// XSwing ...
|
|
int mSwingRange; // Swing Verification Range Length ...
|
|
|
|
//
|
|
// Swing High ...
|
|
|
|
//
|
|
XCSwing *mSwingHighs[]; // Holds Founded Swing Highs ...
|
|
|
|
/**
|
|
* Detect Required Swing Highs ...
|
|
*
|
|
* @param barIndex: Integer Start bar index ...
|
|
* 0 is Default ...
|
|
*
|
|
* @return ( int )
|
|
*/
|
|
int DetectRequiredSwingHighs(int barIndex = 0)
|
|
{
|
|
//
|
|
int result = 0;
|
|
|
|
//
|
|
if (barIndex < 0)
|
|
{
|
|
barIndex = 0;
|
|
}
|
|
|
|
//
|
|
int required = MaxNumberOfRequiredPOIs();
|
|
if (required <= 0)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
int count = ArraySize(mSwingHighs);
|
|
if (count >= required)
|
|
{
|
|
//
|
|
result = count;
|
|
return result;
|
|
}
|
|
|
|
//
|
|
int range = SwingRange();
|
|
if (range < 0 || barIndex < range)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
string symbol = GetSymbol();
|
|
ENUM_TIMEFRAMES period = GetPeriod();
|
|
|
|
//
|
|
XOHCL bar;
|
|
bool isInited = bar.Init(
|
|
symbol,
|
|
period,
|
|
barIndex //
|
|
);
|
|
if (!isInited)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
DetectSwingHigh(bar);
|
|
|
|
//
|
|
result = ArraySize(mSwingHighs);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Swing Low ...
|
|
|
|
//
|
|
XCSwing *mSwingLows[]; // Holds Founded Swing Lows ...
|
|
|
|
/**
|
|
* Detect Required Swing Lows ...
|
|
*
|
|
* @param barIndex: Integer Start bar index ...
|
|
* 0 is Default ...
|
|
*
|
|
* @return ( int )
|
|
*/
|
|
int DetectRequiredSwingLows(int barIndex = 0)
|
|
{
|
|
//
|
|
int result = 0;
|
|
|
|
//
|
|
if (barIndex < 0)
|
|
{
|
|
barIndex = 0;
|
|
}
|
|
|
|
//
|
|
int required = MaxNumberOfRequiredPOIs();
|
|
if (required <= 0)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
int count = ArraySize(mSwingLows);
|
|
if (count >= required)
|
|
{
|
|
//
|
|
result = count;
|
|
return result;
|
|
}
|
|
|
|
//
|
|
int range = SwingRange();
|
|
if (range < 0 || barIndex < range)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
string symbol = GetSymbol();
|
|
ENUM_TIMEFRAMES period = GetPeriod();
|
|
|
|
//
|
|
XOHCL bar;
|
|
bool isInited = bar.Init(
|
|
symbol,
|
|
period,
|
|
barIndex //
|
|
);
|
|
if (!isInited)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
DetectSwingLow(bar);
|
|
|
|
//
|
|
result = ArraySize(mSwingLows);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Momentum Bars ...
|
|
int mMomentumBarExtendRange; // Momentum Bars must Extends Range ...
|
|
double mMomentumBarBodyPercent; // Momentum Bars Body Percent ...
|
|
|
|
//
|
|
// Bullish ...
|
|
XCMomentumBar *mBullishMomentumBars[]; // Holds Founded Bullish Momentum Bars ...
|
|
|
|
/**
|
|
* Detect Required Bullish Momentum Bars ...
|
|
*
|
|
* @param barIndex: Integer Start bar index ...
|
|
* 0 is Default ...
|
|
*
|
|
* @return ( int )
|
|
*/
|
|
int DetectRequiredBullishMomentumBars(int barIndex = 0)
|
|
{
|
|
//
|
|
int result = 0;
|
|
|
|
//
|
|
if (barIndex < 0)
|
|
{
|
|
barIndex = 0;
|
|
}
|
|
|
|
//
|
|
int required = MaxNumberOfRequiredPOIs();
|
|
if (required <= 0)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
int count = ArraySize(mBullishMomentumBars);
|
|
if (count >= required)
|
|
{
|
|
//
|
|
result = count;
|
|
return result;
|
|
}
|
|
|
|
//
|
|
string symbol = GetSymbol();
|
|
ENUM_TIMEFRAMES period = GetPeriod();
|
|
|
|
//
|
|
XOHCL bar;
|
|
bool isInited = bar.Init(
|
|
symbol,
|
|
period,
|
|
barIndex //
|
|
);
|
|
if (!isInited)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
DetectBullishMomentumBar(bar);
|
|
|
|
//
|
|
result = ArraySize(mBullishMomentumBars);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Bearish ...
|
|
XCMomentumBar *mBearishMomentumBars[]; // Holds Founded Bearish Momentum Bars ...
|
|
|
|
/**
|
|
* Detect Required Bearish Momentum Bars ...
|
|
*
|
|
* @param barIndex: Integer Start bar index ...
|
|
* 0 is Default ...
|
|
*
|
|
* @return ( int )
|
|
*/
|
|
int DetectRequiredBearishMomentumBars(int barIndex = 0)
|
|
{
|
|
//
|
|
int result = 0;
|
|
|
|
//
|
|
if (barIndex < 0)
|
|
{
|
|
barIndex = 0;
|
|
}
|
|
|
|
//
|
|
int required = MaxNumberOfRequiredPOIs();
|
|
if (required <= 0)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
int count = ArraySize(mBearishMomentumBars);
|
|
if (count >= required)
|
|
{
|
|
//
|
|
result = count;
|
|
return result;
|
|
}
|
|
|
|
//
|
|
string symbol = GetSymbol();
|
|
ENUM_TIMEFRAMES period = GetPeriod();
|
|
|
|
//
|
|
XOHCL bar;
|
|
bool isInited = bar.Init(
|
|
symbol,
|
|
period,
|
|
barIndex //
|
|
);
|
|
if (!isInited)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
DetectBearishMomentumBar(bar);
|
|
|
|
//
|
|
result = ArraySize(mBearishMomentumBars);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Rejection Bars ...
|
|
int mRejectionBarExtendRange; // Rejection Bars must Extends Range ...
|
|
double mRejectionBarShadowPercent; // Rejection Bars Shadow Percent ...
|
|
|
|
//
|
|
// Bullish ...
|
|
XCRejectionBar *mBullishRejectionBars[]; // Holds Founded Bullish Rejection Bars ...
|
|
|
|
/**
|
|
* Detect Required Bullish Rejection Bars ...
|
|
*
|
|
* @param barIndex: Integer Start bar index ...
|
|
* 0 is Default ...
|
|
*
|
|
* @return ( int )
|
|
*/
|
|
int DetectRequiredBullishRejectionBars(int barIndex = 0)
|
|
{
|
|
//
|
|
int result = 0;
|
|
|
|
//
|
|
if (barIndex < 0)
|
|
{
|
|
barIndex = 0;
|
|
}
|
|
|
|
//
|
|
int required = MaxNumberOfRequiredPOIs();
|
|
if (required <= 0)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
int count = ArraySize(mBullishRejectionBars);
|
|
if (count >= required)
|
|
{
|
|
//
|
|
result = count;
|
|
return result;
|
|
}
|
|
|
|
//
|
|
string symbol = GetSymbol();
|
|
ENUM_TIMEFRAMES period = GetPeriod();
|
|
|
|
//
|
|
XOHCL bar;
|
|
bool isInited = bar.Init(
|
|
symbol,
|
|
period,
|
|
barIndex //
|
|
);
|
|
if (!isInited)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
DetectBullishRejectionBar(bar);
|
|
|
|
//
|
|
result = ArraySize(mBullishRejectionBars);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Bearish ...
|
|
XCRejectionBar *mBearishRejectionBars[]; // Holds Founded Bearish Rejection Bars ...
|
|
|
|
/**
|
|
* Detect Required Bearish Rejection Bars ...
|
|
*
|
|
* @param barIndex: Integer Start bar index ...
|
|
* 0 is Default ...
|
|
*
|
|
* @return ( int )
|
|
*/
|
|
int DetectRequiredBearishRejectionBars(int barIndex = 0)
|
|
{
|
|
//
|
|
int result = 0;
|
|
|
|
//
|
|
if (barIndex < 0)
|
|
{
|
|
barIndex = 0;
|
|
}
|
|
|
|
//
|
|
int required = MaxNumberOfRequiredPOIs();
|
|
if (required <= 0)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
int count = ArraySize(mBearishRejectionBars);
|
|
if (count >= required)
|
|
{
|
|
//
|
|
result = count;
|
|
return result;
|
|
}
|
|
|
|
//
|
|
string symbol = GetSymbol();
|
|
ENUM_TIMEFRAMES period = GetPeriod();
|
|
|
|
//
|
|
XOHCL bar;
|
|
bool isInited = bar.Init(
|
|
symbol,
|
|
period,
|
|
barIndex //
|
|
);
|
|
if (!isInited)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
DetectBearishRejectionBar(bar);
|
|
|
|
//
|
|
result = ArraySize(mBearishRejectionBars);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Support and Resistance Zone ...
|
|
int mSupportAndResistanceRange; // Support and Resistance Range for Verification ...
|
|
|
|
//
|
|
// Support Zone(s) ...
|
|
XCSupportZone *mSupportZones[]; // Holds Founded Support Zones ...
|
|
|
|
/**
|
|
* Detect Required Support Zones ...
|
|
*
|
|
* @param barIndex: Integer Start bar index ...
|
|
* 0 is Default ...
|
|
*
|
|
* @return ( int )
|
|
*/
|
|
int DetectRequiredSupportZones(int barIndex = 0)
|
|
{
|
|
//
|
|
int result = 0;
|
|
|
|
//
|
|
if (barIndex < 0)
|
|
{
|
|
barIndex = 0;
|
|
}
|
|
|
|
//
|
|
int required = MaxNumberOfRequiredPOIs();
|
|
if (required <= 0)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
int count = ArraySize(mSupportZones);
|
|
if (count >= required)
|
|
{
|
|
//
|
|
result = count;
|
|
return result;
|
|
}
|
|
|
|
//
|
|
int range = SupportAndResistanceRange();
|
|
if (range < 0 || barIndex < range)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
string symbol = GetSymbol();
|
|
ENUM_TIMEFRAMES period = GetPeriod();
|
|
|
|
//
|
|
XOHCL bar;
|
|
bool isInited = bar.Init(
|
|
symbol,
|
|
period,
|
|
barIndex //
|
|
);
|
|
if (!isInited)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
DetectSupportZone(bar);
|
|
|
|
//
|
|
result = ArraySize(mSupportZones);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Resistance Zone(s) ...
|
|
XCResistanceZone *mResistanceZones[]; // Holds Founded Resistance Zones ...
|
|
|
|
/**
|
|
* Detect Required Resistance Zones ...
|
|
*
|
|
* @param barIndex: Integer Start bar index ...
|
|
* 0 is Default ...
|
|
*
|
|
* @return ( int )
|
|
*/
|
|
int DetectRequiredResistanceZones(int barIndex = 0)
|
|
{
|
|
//
|
|
int result = 0;
|
|
|
|
//
|
|
if (barIndex < 0)
|
|
{
|
|
barIndex = 0;
|
|
}
|
|
|
|
//
|
|
int required = MaxNumberOfRequiredPOIs();
|
|
if (required <= 0)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
int count = ArraySize(mResistanceZones);
|
|
if (count >= required)
|
|
{
|
|
//
|
|
result = count;
|
|
return result;
|
|
}
|
|
|
|
//
|
|
int range = SupportAndResistanceRange();
|
|
if (range < 0 || barIndex < range)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
string symbol = GetSymbol();
|
|
ENUM_TIMEFRAMES period = GetPeriod();
|
|
|
|
//
|
|
XOHCL bar;
|
|
bool isInited = bar.Init(
|
|
symbol,
|
|
period,
|
|
barIndex //
|
|
);
|
|
if (!isInited)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
DetectResistanceZone(bar);
|
|
|
|
//
|
|
result = ArraySize(mResistanceZones);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Supply and Demand Zones ...
|
|
int mSupplyAndDemandRange; // Supply and Demand Range Verifications ...
|
|
|
|
//
|
|
// Supply Zone(s) ...
|
|
XCSupplyZone *mSupplyZones[]; // Holds Founded Supply Zones ...
|
|
|
|
/**
|
|
* Detect Required Supply Zones ...
|
|
*
|
|
* @param barIndex: Integer Start bar index ...
|
|
* 0 is Default ...
|
|
*
|
|
* @return ( int )
|
|
*/
|
|
int DetectRequiredSupplyZones(int barIndex)
|
|
{
|
|
//
|
|
int result = 0;
|
|
|
|
//
|
|
if (barIndex < 0)
|
|
{
|
|
barIndex = 0;
|
|
}
|
|
|
|
//
|
|
int required = MaxNumberOfRequiredPOIs();
|
|
if (required <= 0)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
int count = ArraySize(mSupplyZones);
|
|
if (count >= required)
|
|
{
|
|
//
|
|
result = count;
|
|
return result;
|
|
}
|
|
|
|
//
|
|
int range = SupplyAndDemandRange();
|
|
if (range < 0)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
string symbol = GetSymbol();
|
|
ENUM_TIMEFRAMES period = GetPeriod();
|
|
|
|
//
|
|
XOHCL bar;
|
|
bool isInited = bar.Init(
|
|
symbol,
|
|
period,
|
|
barIndex //
|
|
);
|
|
if (!isInited)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
DetectSupplyZone(bar);
|
|
|
|
//
|
|
result = ArraySize(mSupplyZones);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Demand Zone(s) ...
|
|
XCDemandZone *mDemandZones[]; // Holds Founded Demand Zones ...
|
|
|
|
/**
|
|
* Detect Required Demand Zones ...
|
|
*
|
|
* @param barIndex: Integer Start bar index ...
|
|
* 0 is Default ...
|
|
*
|
|
* @return ( int )
|
|
*/
|
|
int DetectRequiredDemandZones(int barIndex)
|
|
{
|
|
//
|
|
int result = 0;
|
|
|
|
//
|
|
if (barIndex < 0)
|
|
{
|
|
barIndex = 0;
|
|
}
|
|
|
|
//
|
|
int required = MaxNumberOfRequiredPOIs();
|
|
if (required <= 0)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
int count = ArraySize(mDemandZones);
|
|
if (count >= required)
|
|
{
|
|
//
|
|
result = count;
|
|
return result;
|
|
}
|
|
|
|
//
|
|
int range = SupplyAndDemandRange();
|
|
if (range < 0)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
string symbol = GetSymbol();
|
|
ENUM_TIMEFRAMES period = GetPeriod();
|
|
|
|
//
|
|
XOHCL bar;
|
|
bool isInited = bar.Init(
|
|
symbol,
|
|
period,
|
|
barIndex //
|
|
);
|
|
if (!isInited)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
DetectDemandZone(bar);
|
|
|
|
//
|
|
result = ArraySize(mDemandZones);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Order Blocks ...
|
|
int mOrderBlocksSameBars; // Order Blocks Detection Bars ...
|
|
|
|
//
|
|
// Bullish OB ...
|
|
XCOrderBlock *mBullishOrderBlocks[]; // Holds Founded Bullish Order Blocks ...
|
|
|
|
/**
|
|
* Detect Required Bullish Order Blocks ...
|
|
*
|
|
* @param barIndex: Integer Start bar index ...
|
|
* 0 is Default ...
|
|
*
|
|
* @return ( int )
|
|
*/
|
|
int DetectRequiredBullishOrderBlocks(int barIndex)
|
|
{
|
|
//
|
|
int result = 0;
|
|
|
|
//
|
|
if (barIndex < 0)
|
|
{
|
|
barIndex = 0;
|
|
}
|
|
|
|
//
|
|
int required = MaxNumberOfRequiredPOIs();
|
|
if (required <= 0)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
int count = ArraySize(mBullishOrderBlocks);
|
|
if (count >= required)
|
|
{
|
|
//
|
|
result = count;
|
|
return result;
|
|
}
|
|
|
|
//
|
|
int sameBars = OrderBlocksSameBars();
|
|
if (sameBars < 0)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
string symbol = GetSymbol();
|
|
ENUM_TIMEFRAMES period = GetPeriod();
|
|
|
|
//
|
|
XOHCL bar;
|
|
bool isInited = bar.Init(
|
|
symbol,
|
|
period,
|
|
barIndex //
|
|
);
|
|
if (!isInited)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
DetectBullishOrderBlock(bar);
|
|
|
|
//
|
|
result = ArraySize(mBullishOrderBlocks);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Bearish OB ...
|
|
XCOrderBlock *mBearishOrderBlocks[]; // Holds Founded Bearish Order Blocks ...
|
|
|
|
/**
|
|
* Detect Required Bearish Order Blocks ...
|
|
*
|
|
* @param barIndex: Integer Start bar index ...
|
|
* 0 is Default ...
|
|
*
|
|
* @return ( int )
|
|
*/
|
|
int DetectRequiredBearishOrderBlocks(int barIndex)
|
|
{
|
|
//
|
|
int result = 0;
|
|
|
|
//
|
|
if (barIndex < 0)
|
|
{
|
|
barIndex = 0;
|
|
}
|
|
|
|
//
|
|
int required = MaxNumberOfRequiredPOIs();
|
|
if (required <= 0)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
int count = ArraySize(mBearishOrderBlocks);
|
|
if (count >= required)
|
|
{
|
|
//
|
|
result = count;
|
|
return result;
|
|
}
|
|
|
|
//
|
|
int sameBars = OrderBlocksSameBars();
|
|
if (sameBars < 0)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
string symbol = GetSymbol();
|
|
ENUM_TIMEFRAMES period = GetPeriod();
|
|
|
|
//
|
|
XOHCL bar;
|
|
bool isInited = bar.Init(
|
|
symbol,
|
|
period,
|
|
barIndex //
|
|
);
|
|
if (!isInited)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
DetectBearishOrderBlock(bar);
|
|
|
|
//
|
|
result = ArraySize(mBearishOrderBlocks);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Fair Value Gaps ...
|
|
int mFairValueGapsSameBars; // Fair Value Gaps Detection Same Bars ...
|
|
|
|
//
|
|
// Bullish FVG ...
|
|
XCFVG *mBullishFairValueGaps[]; // Holds Founded Bullish Fair Value Gaps ...
|
|
|
|
/**
|
|
* Detect Required Bullish Fair Value Gaps ...
|
|
*
|
|
* @param barIndex: Integer Start bar index ...
|
|
* 0 is Default ...
|
|
*
|
|
* @return ( int )
|
|
*/
|
|
int DetectRequiredBullishFairValueGaps(int barIndex)
|
|
{
|
|
//
|
|
int result = 0;
|
|
|
|
//
|
|
if (barIndex < 0)
|
|
{
|
|
barIndex = 0;
|
|
}
|
|
|
|
//
|
|
int required = MaxNumberOfRequiredPOIs();
|
|
if (required <= 0)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
int count = ArraySize(mBullishFairValueGaps);
|
|
if (count >= required)
|
|
{
|
|
//
|
|
result = count;
|
|
return result;
|
|
}
|
|
|
|
//
|
|
int sameBars = FairValueGapsSameBars();
|
|
if (sameBars < 0)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
string symbol = GetSymbol();
|
|
ENUM_TIMEFRAMES period = GetPeriod();
|
|
|
|
//
|
|
XOHCL bar;
|
|
bool isInited = bar.Init(
|
|
symbol,
|
|
period,
|
|
barIndex //
|
|
);
|
|
if (!isInited)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
DetectBullishFairValueGap(bar);
|
|
|
|
//
|
|
result = ArraySize(mBullishFairValueGaps);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Bearish FVG ...
|
|
XCFVG *mBearishFairValueGaps[]; // Holds Founded Bearish Fair Value Gaps ...
|
|
|
|
/**
|
|
* Detect Required Bearish Fair Value Gaps ...
|
|
*
|
|
* @param barIndex: Integer Start bar index ...
|
|
* 0 is Default ...
|
|
*
|
|
* @return ( int )
|
|
*/
|
|
int DetectRequiredBearishFairValueGaps(int barIndex)
|
|
{
|
|
//
|
|
int result = 0;
|
|
|
|
//
|
|
if (barIndex < 0)
|
|
{
|
|
barIndex = 0;
|
|
}
|
|
|
|
//
|
|
int required = MaxNumberOfRequiredPOIs();
|
|
if (required <= 0)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
int count = ArraySize(mBearishFairValueGaps);
|
|
if (count >= required)
|
|
{
|
|
//
|
|
result = count;
|
|
return result;
|
|
}
|
|
|
|
//
|
|
int sameBars = FairValueGapsSameBars();
|
|
if (sameBars < 0)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
string symbol = GetSymbol();
|
|
ENUM_TIMEFRAMES period = GetPeriod();
|
|
|
|
//
|
|
XOHCL bar;
|
|
bool isInited = bar.Init(
|
|
symbol,
|
|
period,
|
|
barIndex //
|
|
);
|
|
if (!isInited)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
DetectBearishFairValueGap(bar);
|
|
|
|
//
|
|
result = ArraySize(mBearishFairValueGaps);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Ticks Range Zones ...
|
|
int mTicksRangeZoneLevel; // Ticks Range Levels ...
|
|
int mTicksRangeZoneRange; // Ticks Range Zone Loopback Period ...
|
|
|
|
//
|
|
XCTicksZone *mTicksZone; // Ticks Zone ...
|
|
// XCTicksZoneObject *mTicksZoneObject; // Ticks Zone Object ...
|
|
|
|
/**
|
|
* Detect Ticks Zone Range ...
|
|
*
|
|
* @param bar: XOHCL instance ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool DetectTicksZoneRange(XOHCL &bar)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
result = bar.IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
int ticksLevels = TicksRangeZoneLevel();
|
|
int ticksRange = TicksRangeZoneRange();
|
|
result = ticksLevels > 0 &&
|
|
ticksRange > 0;
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
int startBarIndex = bar.Index() + ticksRange;
|
|
XOHCL startBar;
|
|
result = startBar.Init(
|
|
bar.symbol,
|
|
bar.period,
|
|
startBarIndex //
|
|
);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
mTicksZone = new XCTicksZone();
|
|
result = mTicksZone.Init(
|
|
startBar,
|
|
bar //
|
|
);
|
|
if (!result)
|
|
{
|
|
//
|
|
mTicksZone = NULL;
|
|
return result;
|
|
}
|
|
|
|
// //
|
|
// if (mTicksZoneObject != NULL)
|
|
// {
|
|
// mTicksZoneObject.Destroy();
|
|
// }
|
|
// mDrawer.CreateTicksZone(
|
|
// mTicksZone,
|
|
// mTicksZoneObject //
|
|
// );
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Liquidity Zones ...
|
|
|
|
//
|
|
// Sell Side ...
|
|
|
|
//
|
|
// Buy Side ...
|
|
|
|
//
|
|
};
|
|
|
|
// |