2117 lines
43 KiB
Plaintext
2117 lines
43 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;
|
|
}
|
|
|
|
//
|
|
// 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 //
|
|
);
|
|
}
|
|
|
|
//
|
|
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.reportedAt = TimeCurrent();
|
|
|
|
//
|
|
// TODO: Fill State ...
|
|
}
|
|
|
|
//
|
|
// 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);
|
|
}
|
|
|
|
/**
|
|
* 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);
|
|
}
|
|
|
|
//
|
|
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;
|
|
|
|
//
|
|
bool canContinue = true;
|
|
|
|
//
|
|
while (canContinue)
|
|
{
|
|
//
|
|
// Swing Highs ...
|
|
swingHighsCount = DetectRequiredSwingHighs(barIndex);
|
|
if (swingHighsCount == requiredPOIs)
|
|
{
|
|
ArrayReverse(mSwingHighs);
|
|
}
|
|
|
|
//
|
|
// Swing Lows ...
|
|
swingLowsCount = DetectRequiredSwingLows(barIndex);
|
|
if (swingHighsCount == requiredPOIs)
|
|
{
|
|
ArrayReverse(mSwingLows);
|
|
}
|
|
|
|
//
|
|
// Bullish Momentum Bars ...
|
|
bullishMomentumBarsCount = DetectRequiredBullishMomentumBars(barIndex);
|
|
if (bullishMomentumBarsCount == requiredPOIs)
|
|
{
|
|
ArrayReverse(mBullishMomentumBars);
|
|
}
|
|
|
|
//
|
|
// Bearish Momentum Bars ...
|
|
bearishMomentumBarsCount = DetectRequiredBearishMomentumBars(barIndex);
|
|
if (bearishMomentumBarsCount == requiredPOIs)
|
|
{
|
|
ArrayReverse(mBearishMomentumBars);
|
|
}
|
|
|
|
//
|
|
// Bullish Rejection Bars ...
|
|
bullishRejectionBarsCount = DetectRequiredBullishRejectionBars(barIndex);
|
|
if (bullishRejectionBarsCount == requiredPOIs)
|
|
{
|
|
ArrayReverse(mBullishRejectionBars);
|
|
}
|
|
|
|
//
|
|
// Bearish Rejection Bars ...
|
|
bearishRejectionBarsCount = DetectRequiredBearishRejectionBars(barIndex);
|
|
if (bearishRejectionBarsCount == requiredPOIs)
|
|
{
|
|
ArrayReverse(mBearishRejectionBars);
|
|
}
|
|
|
|
//
|
|
canContinue =
|
|
//
|
|
// Swing Highs ...
|
|
swingHighsCount < requiredPOIs
|
|
//
|
|
||
|
|
//
|
|
// Swing Lows ...
|
|
swingLowsCount < requiredPOIs
|
|
//
|
|
||
|
|
//
|
|
// Bullish Momentum Bars ...
|
|
bullishMomentumBarsCount < requiredPOIs
|
|
//
|
|
||
|
|
//
|
|
// Bearish Momentum Bars ...
|
|
bearishMomentumBarsCount < requiredPOIs
|
|
//
|
|
||
|
|
//
|
|
// Bullish Rejection Bars ...
|
|
bullishRejectionBarsCount < requiredPOIs
|
|
//
|
|
||
|
|
//
|
|
// Bearish Rejection Bars ...
|
|
bearishRejectionBarsCount < requiredPOIs
|
|
//
|
|
;
|
|
if (canContinue)
|
|
{
|
|
barIndex++;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Unlocking Detector ...
|
|
Unlock();
|
|
}
|
|
|
|
/**
|
|
* 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 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 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 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,
|
|
mSwingHighs //
|
|
);
|
|
|
|
// //
|
|
// XCSwingLowObject *iObj;
|
|
// bool isCreated = mDrawer.CreateSwingLow(
|
|
// swing,
|
|
// iObj //
|
|
// );
|
|
// if (isCreated)
|
|
// {
|
|
// AddObjectIfNotExists(iObj);
|
|
// }
|
|
}
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* 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(mSwingHighs);
|
|
|
|
//
|
|
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 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 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 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 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 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 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 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 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 Zone(s) ...
|
|
|
|
//
|
|
// Resistance Zone(s) ...
|
|
|
|
//
|
|
// Supply Zone(s) ...
|
|
|
|
//
|
|
// Demand Zone(s) ...
|
|
|
|
//
|
|
// Order Blocks ...
|
|
|
|
//
|
|
// Bullish OB ...
|
|
|
|
//
|
|
// Bearish OB ...
|
|
|
|
//
|
|
// Fair Value Gaps ...
|
|
|
|
//
|
|
// Bullish FVG ...
|
|
|
|
//
|
|
// Bearish FVG ...
|
|
|
|
//
|
|
// Liquidity Zones ...
|
|
|
|
//
|
|
// Sell Side ...
|
|
|
|
//
|
|
// Buy Side ...
|
|
|
|
//
|
|
};
|
|
|
|
// |