1204 lines
23 KiB
Plaintext
1204 lines
23 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-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 ...
|
|
ApplyDefaultConfig();
|
|
}
|
|
|
|
//
|
|
// 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;
|
|
}
|
|
|
|
//
|
|
// 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;
|
|
int ppIndex = pIndex + 1;
|
|
|
|
//
|
|
datetime cTime = TimeCurrent();
|
|
|
|
//
|
|
XOHCL zBar;
|
|
bool isInited = zBar.Init(
|
|
mSymbol,
|
|
mPeriod,
|
|
zIndex //
|
|
);
|
|
if (!isInited)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
XOHCL cBar;
|
|
isInited = cBar.Init(
|
|
mSymbol,
|
|
mPeriod,
|
|
cIndex //
|
|
);
|
|
if (!isInited)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
XOHCL pBar;
|
|
isInited = pBar.Init(
|
|
mSymbol,
|
|
mPeriod,
|
|
pIndex //
|
|
);
|
|
if (!isInited)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
XOHCL ppBar;
|
|
isInited = ppBar.Init(
|
|
mSymbol,
|
|
mPeriod,
|
|
ppIndex //
|
|
);
|
|
if (!isInited)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
XOHCL zDayBar;
|
|
isInited = zDayBar.Init(
|
|
mSymbol,
|
|
PERIOD_D1,
|
|
zIndex //
|
|
);
|
|
if (!isInited)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
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 ...
|
|
|
|
//
|
|
// Destroy ...
|
|
|
|
/**
|
|
* Destroy Detected POI(s) ...
|
|
*/
|
|
void DestroyPOIs()
|
|
{
|
|
}
|
|
|
|
/**
|
|
* Destroy Added Sessions ...
|
|
*/
|
|
void DestroySessions()
|
|
{
|
|
}
|
|
|
|
/**
|
|
* Destroy Rejistered Event Handlers ...
|
|
*/
|
|
void DestroyEventListeners()
|
|
{
|
|
}
|
|
|
|
//
|
|
// Virtual Actions ...
|
|
|
|
/**
|
|
* Apply Default Configurations ...
|
|
*/
|
|
virtual void ApplyDefaultConfig()
|
|
{
|
|
//
|
|
// Common ...
|
|
|
|
//
|
|
MaxNumberOfPOIs(10);
|
|
MaxNumberOfRequiredPOIs(2);
|
|
|
|
//
|
|
SwingRange(2);
|
|
|
|
//
|
|
}
|
|
|
|
//
|
|
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;
|
|
|
|
//
|
|
bool canContinue = true;
|
|
|
|
//
|
|
while (canContinue)
|
|
{
|
|
//
|
|
// Swing Highs ...
|
|
swingHighsCount = DetectRequiredSwingHighs(barIndex);
|
|
|
|
//
|
|
// Swing Lows ...
|
|
swingLowsCount = DetectRequiredSwingLows(barIndex);
|
|
|
|
//
|
|
canContinue =
|
|
//
|
|
// Swing Highs ...
|
|
swingHighsCount < requiredPOIs
|
|
//
|
|
||
|
|
//
|
|
// Swing Lows ...
|
|
swingLowsCount < requiredPOIs
|
|
//
|
|
;
|
|
if (canContinue)
|
|
{
|
|
barIndex++;
|
|
}
|
|
}
|
|
|
|
//
|
|
swingHighsCount = ArraySize(mSwingHighs);
|
|
swingLowsCount = ArraySize(mSwingLows);
|
|
|
|
//
|
|
// Unlocking Detector ...
|
|
Unlock();
|
|
}
|
|
|
|
/**
|
|
* Cleanup Unused Objects ...
|
|
*/
|
|
void CleanupUnusedPOIs()
|
|
{
|
|
//
|
|
int maxAllowed = MaxNumberOfPOIs();
|
|
if (!IsValidSize(maxAllowed))
|
|
{
|
|
return;
|
|
}
|
|
|
|
// //
|
|
// int tradingDaysCount = ArraySize(mTradingDays);
|
|
// int marketSessionsCount = ArraySize(mMarketSessions);
|
|
// int swingHighsCount = ArraySize(mSwingHighs);
|
|
// int swingLowsCount = ArraySize(mSwingLows);
|
|
// int momentumBarsCount = ArraySize(mMomentumBars);
|
|
// int rejectionBarsCount = ArraySize(mRejectionBars);
|
|
// int supportZonesCount = ArraySize(mSupportZones);
|
|
// int resistanceZonesCount = ArraySize(mResistanceZones);
|
|
// int supplyZonesCount = ArraySize(mSupplyZones);
|
|
// int demandZonesCount = ArraySize(mDemandZones);
|
|
// int bullishOBsCount = ArraySize(mBullishOrderBlocks);
|
|
// int bearishOBsCount = ArraySize(mBearishOrderBlocks);
|
|
// int bullishFVGsCount = ArraySize(mBullishFVGs);
|
|
// int bearishFVGsCount = ArraySize(mBearishFVGs);
|
|
|
|
// //
|
|
// int from = 0;
|
|
// int requiredPOIs = MaxNumberOfRequiredPOIs();
|
|
// int count = maxAllowed - requiredPOIs;
|
|
// int to = count - 1;
|
|
|
|
// //
|
|
// // Trading Days ...
|
|
// if (tradingDaysCount >= maxAllowed)
|
|
// {
|
|
// //
|
|
// ArrayRemove(
|
|
// mTradingDays,
|
|
// from,
|
|
// count //
|
|
// );
|
|
|
|
// //
|
|
// mTradingDayObjects.DeleteRange(
|
|
// from,
|
|
// to //
|
|
// );
|
|
// }
|
|
|
|
// //
|
|
// // Market Sessions ...
|
|
// if (marketSessionsCount >= maxAllowed)
|
|
// {
|
|
// //
|
|
// ArrayRemove(
|
|
// mMarketSessions,
|
|
// from,
|
|
// count //
|
|
// );
|
|
|
|
// //
|
|
// mMarketSessionObjects.DeleteRange(
|
|
// from,
|
|
// to //
|
|
// );
|
|
// }
|
|
|
|
// //
|
|
// // Momentum Bars ...
|
|
// if (momentumBarsCount >= maxAllowed)
|
|
// {
|
|
// //
|
|
// ArrayRemove(
|
|
// mMomentumBars,
|
|
// from,
|
|
// count //
|
|
// );
|
|
|
|
// //
|
|
// mMomentumBarObjects.DeleteRange(
|
|
// from,
|
|
// to //
|
|
// );
|
|
// }
|
|
|
|
// //
|
|
// // Rejection Bars ...
|
|
// if (rejectionBarsCount >= maxAllowed)
|
|
// {
|
|
// //
|
|
// ArrayRemove(
|
|
// mRejectionBars,
|
|
// from,
|
|
// count //
|
|
// );
|
|
|
|
// //
|
|
// mRejectionBarObjects.DeleteRange(
|
|
// from,
|
|
// to //
|
|
// );
|
|
// }
|
|
|
|
// //
|
|
// // Swing High and Low (s) ...
|
|
|
|
// //
|
|
// // Swing Highs ...
|
|
// if (swingHighsCount >= maxAllowed)
|
|
// {
|
|
// //
|
|
// ArrayRemove(
|
|
// mSwingHighs,
|
|
// from,
|
|
// count //
|
|
// );
|
|
|
|
// //
|
|
// mSwingHighObjects.DeleteRange(
|
|
// from,
|
|
// to //
|
|
// );
|
|
// }
|
|
|
|
// //
|
|
// // Swing Lows ...
|
|
// if (swingLowsCount >= maxAllowed)
|
|
// {
|
|
// //
|
|
// ArrayRemove(
|
|
// mSwingLows,
|
|
// from,
|
|
// count //
|
|
// );
|
|
|
|
// //
|
|
// mSwingLowObjects.DeleteRange(
|
|
// from,
|
|
// to //
|
|
// );
|
|
// }
|
|
|
|
// //
|
|
// // Support and Resistance Zones ...
|
|
|
|
// //
|
|
// // Support Zones ...
|
|
// if (supportZonesCount >= maxAllowed)
|
|
// {
|
|
// //
|
|
// ArrayRemove(
|
|
// mSupportZones,
|
|
// from,
|
|
// count //
|
|
// );
|
|
|
|
// //
|
|
// mSupportZoneObjects.DeleteRange(
|
|
// from,
|
|
// to //
|
|
// );
|
|
// }
|
|
|
|
// //
|
|
// // Resistance Zones ...
|
|
// if (resistanceZonesCount >= maxAllowed)
|
|
// {
|
|
// //
|
|
// ArrayRemove(
|
|
// mResistanceZones,
|
|
// from,
|
|
// count //
|
|
// );
|
|
|
|
// //
|
|
// mResistanceZoneObjects.DeleteRange(
|
|
// from,
|
|
// to //
|
|
// );
|
|
// }
|
|
|
|
// //
|
|
// // Supply and Demand Zones ...
|
|
|
|
// //
|
|
// // Supply Zones ...
|
|
// if (supplyZonesCount >= maxAllowed)
|
|
// {
|
|
// //
|
|
// ArrayRemove(
|
|
// mSupplyZones,
|
|
// from,
|
|
// count //
|
|
// );
|
|
|
|
// //
|
|
// mSupplyZoneObjects.DeleteRange(
|
|
// from,
|
|
// to //
|
|
// );
|
|
// }
|
|
|
|
// //
|
|
// // Demand Zones ...
|
|
// if (demandZonesCount >= maxAllowed)
|
|
// {
|
|
// //
|
|
// ArrayRemove(
|
|
// mDemandZones,
|
|
// from,
|
|
// count //
|
|
// );
|
|
|
|
// //
|
|
// mDemandZoneObjects.DeleteRange(
|
|
// from,
|
|
// to //
|
|
// );
|
|
// }
|
|
|
|
// //
|
|
// // Order Blocks ...
|
|
|
|
// //
|
|
// // Bullish Order Blocks ...
|
|
// if (bullishOBsCount >= maxAllowed)
|
|
// {
|
|
// //
|
|
// ArrayRemove(
|
|
// mBullishOrderBlocks,
|
|
// from,
|
|
// count //
|
|
// );
|
|
|
|
// //
|
|
// mBullishOrderBlockObjects.DeleteRange(
|
|
// from,
|
|
// to //
|
|
// );
|
|
// }
|
|
|
|
// //
|
|
// // Bearish Order Blocks ...
|
|
// if (bearishOBsCount >= maxAllowed)
|
|
// {
|
|
// //
|
|
// ArrayRemove(
|
|
// mBearishOrderBlocks,
|
|
// from,
|
|
// count //
|
|
// );
|
|
|
|
// //
|
|
// mBearishOrderBlockObjects.DeleteRange(
|
|
// from,
|
|
// to //
|
|
// );
|
|
// }
|
|
|
|
// //
|
|
// // Fair Vakue Gaps ...
|
|
|
|
// //
|
|
// // Bullish FVGs ...
|
|
// if (bullishFVGsCount >= maxAllowed)
|
|
// {
|
|
// //
|
|
// ArrayRemove(
|
|
// mBullishFVGs,
|
|
// from,
|
|
// count //
|
|
// );
|
|
|
|
// //
|
|
// mBullishFVGObjects.DeleteRange(
|
|
// from,
|
|
// to //
|
|
// );
|
|
// }
|
|
|
|
// //
|
|
// // Bearish FVGs ...
|
|
// if (bearishFVGsCount >= maxAllowed)
|
|
// {
|
|
// //
|
|
// ArrayRemove(
|
|
// mBearishFVGs,
|
|
// from,
|
|
// count //
|
|
// );
|
|
|
|
// //
|
|
// mBearishFVGObjects.DeleteRange(
|
|
// from,
|
|
// to //
|
|
// );
|
|
// }
|
|
|
|
//
|
|
}
|
|
|
|
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 ...
|
|
|
|
//
|
|
// 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;
|
|
}
|
|
|
|
//
|
|
bool isSwing = true;
|
|
for (int i = 1; i <= range; i++)
|
|
{
|
|
//
|
|
// Prev Bar ...
|
|
XOHCL iPrevBar;
|
|
isInited = iPrevBar.Init(
|
|
symbol,
|
|
period,
|
|
barIndex + i //
|
|
);
|
|
if (!isInited)
|
|
{
|
|
//
|
|
isSwing = false;
|
|
break;
|
|
}
|
|
|
|
//
|
|
// Next Bar ...
|
|
XOHCL iNextBar;
|
|
isInited = iNextBar.Init(
|
|
symbol,
|
|
period,
|
|
barIndex - i //
|
|
);
|
|
if (!isInited)
|
|
{
|
|
//
|
|
isSwing = false;
|
|
break;
|
|
}
|
|
|
|
//
|
|
isSwing = bar.high >= iPrevBar.high &&
|
|
bar.high >= iNextBar.high;
|
|
if (!isSwing)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
if (isSwing)
|
|
{
|
|
//
|
|
XCSwing *swing;
|
|
swing = new XCSwing();
|
|
isInited = swing.Init(
|
|
bar,
|
|
X_POI_SWING_HIGH //
|
|
);
|
|
|
|
//
|
|
if (isInited)
|
|
{
|
|
//
|
|
Add(
|
|
swing,
|
|
mSwingHighs //
|
|
);
|
|
|
|
//
|
|
XCSwingHighObject *iObj;
|
|
bool isCreated = mDrawer.CreateSwingHigh(
|
|
swing,
|
|
iObj //
|
|
);
|
|
if (isCreated)
|
|
{
|
|
AddObjectIfNotExists(iObj);
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
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;
|
|
}
|
|
|
|
//
|
|
bool isSwing = true;
|
|
for (int i = 1; i <= range; i++)
|
|
{
|
|
//
|
|
// Prev Bar ...
|
|
XOHCL iPrevBar;
|
|
isInited = iPrevBar.Init(
|
|
symbol,
|
|
period,
|
|
barIndex + i //
|
|
);
|
|
if (!isInited)
|
|
{
|
|
//
|
|
isSwing = false;
|
|
break;
|
|
}
|
|
|
|
//
|
|
// Next Bar ...
|
|
XOHCL iNextBar;
|
|
isInited = iNextBar.Init(
|
|
symbol,
|
|
period,
|
|
barIndex - i //
|
|
);
|
|
if (!isInited)
|
|
{
|
|
//
|
|
isSwing = false;
|
|
break;
|
|
}
|
|
|
|
//
|
|
isSwing = bar.low <= iPrevBar.low &&
|
|
bar.low <= iNextBar.low;
|
|
if (!isSwing)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
if (isSwing)
|
|
{
|
|
//
|
|
XCSwing *swing;
|
|
swing = new XCSwing();
|
|
isInited = swing.Init(
|
|
bar,
|
|
X_POI_SWING_LOW //
|
|
);
|
|
|
|
//
|
|
if (isInited)
|
|
{
|
|
//
|
|
Add(
|
|
swing,
|
|
mSwingLows //
|
|
);
|
|
|
|
//
|
|
XCSwingLowObject *iObj;
|
|
bool isCreated = mDrawer.CreateSwingLow(
|
|
swing,
|
|
iObj //
|
|
);
|
|
if (isCreated)
|
|
{
|
|
AddObjectIfNotExists(iObj);
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
result = ArraySize(mSwingHighs);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Momentum Bars ...
|
|
|
|
//
|
|
// Rejection Bars ...
|
|
|
|
//
|
|
// 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 ...
|
|
|
|
//
|
|
};
|
|
|
|
// |