Files
MQL5Data/Libraries/x-saherelm.x-poi.lib.mq5
T
2025-02-11 13:13:49 +03:30

9816 lines
173 KiB
Plaintext

///////////////////////////////////////////////////////
//
// SaherElm IT Center MQL5 Seriallize Library
// ---------------------------------------
// Name: XPOILib
// Description: All models related to POIs ...
//
//
// Maintainer:
// ------------
// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com)
//
//////////////////////////////////////////////////////
//
// Global Properties ...
#property library
#property copyright "Copyright `023, SaherElm IT Center"
#property link "https://www.saherelm.ir"
#property version "1.00"
#property strict
//
// Imports ...
#include "../Classes/x-saherelm.base.class.mq5"
#include <Arrays/ArrayObj.mqh>
//
// Definitions ...
//
// Definitions ...
//
// All Available POI(s) ...
enum ENUM_XPOIS
{
//
X_POI_NONE,
//
X_POI_TICKS_ZONES, // Ticks Zone ...
//
// Trading Day ...
X_POI_TRADING_DAY, // Trading Day ...
//
// Market Session ...
X_POI_MARKET_SESSION, // Market Session ...
//
// Momentum Bar ...
X_POI_MOMENTUM_BAR, // Momentum Bar ...
//
// Rejection Bar ...
X_POI_REJECTION_BAR, // Rejection Bar ...
//
// Swings ...
X_POI_SWING_HIGH, // Simple Swing High ...
X_POI_SWING_LOW, // Simple Swing Low ...
//
// Support nad Resistance ...
X_POI_SUPPORT_ZONE, // Support Zone ...
X_POI_RESISTANCE_ZONE, // Resistance Zone ...
//
// Supply and Demand Zones ...
X_POI_SUPPLY_ZONE, // Supply Zone ...
X_POI_DEMAND_ZONE, // Demand Zone ...
//
// Order Blocks ...
X_POI_BULLISH_ORDERBLOCK, // Bullish Order Block ...
X_POI_BEARISH_ORDERBLOCK, // Bearish Order Block ...
//
// Fair Value Gaps ...
X_POI_BULLISH_FVG, // Bullish Order Block ...
X_POI_BEARISH_FVG, // Bearish Order Block ...
X_POI_CONSOLIDATION_ZONE, // Consolidation Zone ...
};
//
// Event Types ...
enum ENUM_XPOI_EVENTS
{
//
// Trading Days ...
X_TRADE_DAY_FIRST_BAR, // Trading Day First Bar ...
X_TRADE_DAY_LAST_BAR, // Trading Day Last Bar ...
//
// Session ...
X_SESSION_FIRST_BAR, // Session First Bar ...
X_SESSION_LAST_BAR, // Session Last Bar ...
//
// Momentum Bar ...
X_BULLISH_MOMENTUM_BAR_DETECTED,
X_BEARISH_MOMENTUM_BAR_DETECTED,
//
// Rejection Bar ...
X_BULLISH_REJECTION_BAR_DETECTED,
X_BEARISH_REJECTION_BAR_DETECTED,
//
// Swings ...
X_SWING_HIGH_DETECTED,
X_SWING_LOW_DETECTED,
//
// Support nad Resistance ...
X_SUPPORT_ZONE_DETECTED, // Support Zone ...
X_RESISTANCE_ZONE_DETECTED, // Resistance Zone ...
//
// Supply nad Demand ...
X_SUPPLY_ZONE_DETECTED, // Supply Zone ...
X_DEMAND_ZONE_DETECTED, // Demand Zone ...
//
// Order Blocks ...
X_BULLISH_ORDERBLOCK_DETECTED, // Bullish Order Block ...
X_BEARISH_ORDERBLOCK_DETECTED, // Bearish Order Block ...
//
// Fair Value Gaps ...
X_BULLISH_FVG_DETECTED, // Bullish Fair Value Gapّ ...
X_BEARISH_FVG_DETECTED, // Bearish Fair Value Gapّ ...
};
//
// Forext Sessions ...
enum ENUM_XSESSION
{
X_TOKYO,
X_SYDNEY,
X_LONDON,
X_NEW_YORK,
X_FRANKFORT,
};
//
// Implementation ...
//
// Base POI Model Class ...
class XCBasePOI : public XCBase
{
//
public:
//
//
// Constructor ...
void XCBasePOI()
{
//
Clean();
//
mSep = "_";
mLineSep = "\n";
}
//
// Deconstructor ...
void ~XCBasePOI()
{
Clean();
}
//
// Virtual ...
/**
* Cleanup ...
*/
virtual void Clean()
{
mType = X_POI_NONE;
}
/**
* Validate ...
*
* @return ( virtual bool )
*/
virtual bool IsValid()
{
return false;
}
/**
* Retrieve POI Type ...
*
* @return ( virtual ENUM_XPOIS member )
*/
virtual ENUM_XPOIS Type()
{
return mType;
}
/**
* Retrieve POI Type ...
*
* @return ( virtual string )
*/
virtual string TypeAsString()
{
return ToString(mType);
}
/**
* Retrieve POI Tag ...
*
* @return ( virtual string )
*/
virtual string GetTag()
{
return NULL;
}
/**
* Retrieve POI Tooltip ...
*
* @return ( virtual string )
*/
virtual string GetTooltip()
{
return NULL;
}
//
protected:
//
// Props ...
string mSep; // Separator ...
string mLineSep; // Line Separator ...
ENUM_XPOIS mType; // Type ...
//
private:
//
};
//
// Zone POI Class ...
class XCZone : public XCBasePOI
{
//
public:
//
//
// Constructor ...
void XCZone()
{
}
//
// Deconstructor ...
void ~XCZone()
{
}
//
// Tools ...
//
// Getter(s) / Setter(s) ...
/**
* Get Zone Upper Boundary ...
*
* @return ( double )
*/
double Upper()
{
return mUpper;
}
/**
* Set Zone Upper Boundary ...
*/
void Upper(double value)
{
mUpper = value;
}
/**
* Get Zone Lower Boundary ...
*
* @return ( double )
*/
double Lower()
{
return mLower;
}
/**
* Set Zone Lower Boundary ...
*/
void Lower(double value)
{
mLower = value;
}
/**
* Retrieve Zone Range ...
*
* @return ( double )
*/
double Range()
{
//
double result = 0;
//
double upper = Upper();
double lower = Lower();
//
if (upper > 0 && lower > 0 && upper > lower)
{
result = upper - lower;
}
//
return result;
}
double RangePercent()
{
//
double result = 0;
//
double range = Range();
if (range > 0)
{
result = range / 100;
}
//
return result;
}
//
// Virtuals ...
/**
* Get Zone Start Date ...
*
* @return ( virtual datetime )
*/
virtual datetime From()
{
return NULL;
}
/**
* Get Zone End Date ...
*
* @return ( virtual datetime )
*/
virtual datetime To()
{
return NULL;
}
//
// Getter(s) / Setter(s) ...
//
// Overrides ...
//
// Validators ...
/**
* Validate Upper and Lower of Zone ...
*
* @return ( bool )
*/
bool IsValidBoundary()
{
//
bool result = false;
//
result =
//
mUpper > 0 &&
mLower > 0 &&
mUpper >= mLower
//
;
//
return result;
}
/**
* Check From Date of Zone is Valid ...
*
* @return ( bool )
*/
bool IsValidFrom()
{
//
bool result = false;
//
datetime from = From();
result = IsSpecifiedValid(from);
//
return result;
}
//
protected:
//
// Props ...
double mUpper; // Zone Upper ...
double mLower; // Zone Lower ...
//
private:
//
// Props ...
//
};
//
// From To Zone ...
class XCFromToZone : public XCBasePOI
{
//
public:
//
//
// Constructor ...
void XCFromToZone()
{
}
//
// Deconstructor ...
void ~XCFromToZone()
{
}
//
// Tools ...
bool InitFromTo(
ENUM_XPOIS type,
string title,
datetime from //
)
{
//
bool result = false;
//
result = type != X_POI_NONE &&
IsSpecifiedValid(from) &&
IsSpecifiedValid(title);
//
mType = type;
mFrom = from;
mTitle = title;
mTo = TimeCurrent();
//
result = IsValid();
//
return result;
}
bool InitFromTo(
ENUM_XPOIS type,
string title,
datetime from,
datetime to //
)
{
//
bool result = false;
//
result = IsValid();
//
result = InitFromTo(
type,
title,
from //
);
if (!result)
{
return result;
}
//
to = NormalizeTime(to);
mTo = to;
//
result = IsValid();
//
return result;
}
//
// Getter(s) / Setter(s) ...
/**
* Get Zone Start Time ...
*
* @return ( datetime )
*/
datetime From()
{
return mFrom;
}
/**
* Set Zone Start Time ...
*
* @param value: Datetime
*/
void From(datetime value)
{
//
value = NormalizeTime(value);
//
mFrom = value;
}
/**
* Get Zone End Time ...
*
* @return ( datetime )
*/
datetime To()
{
return mTo;
}
/**
* Set Zone End Time ...
*
* @param value: Datetime
*/
void To(datetime value)
{
//
value = NormalizeTime(value);
//
mTo = value;
}
/**
* Get Title ...
*
* @return ( string )
*/
string Title()
{
return mTitle;
}
/**
* Set Title ...
*
* @param value: String ...
*/
// void Title(string value)
// {
// mTitle = value;
// }
//
// Overrides ...
void Clean() override
{
//
mTo = NULL;
mFrom = NULL;
mType = X_POI_NONE;
}
bool IsValid() override
{
//
bool result = false;
//
result =
//
mType != X_POI_NONE &&
IsSpecifiedValid(mTo) &&
IsSpecifiedValid(mFrom) &&
IsSpecifiedValid(mTitle)
//
;
//
return result;
}
string GetTag() override
{
//
string result = NULL;
//
if (!IsValid())
{
return result;
}
//
string hash = TypeAsString() + mSep + ToString(From()) + mSep + Title();
hash = ToMD5(hash);
//
result = TypeAsString() + "[" + Title() + "]" + mSep + hash;
//
return result;
}
//
protected:
//
//
private:
//
// Props ...
datetime mFrom; // Start Date
datetime mTo; // End Date
string mTitle; // Zone Title
//
};
//
// Bar Zone ...
class XCBarZone : public XCZone
{
//
public:
//
//
// Constructor ...
void XCBarZone()
{
}
//
// Deconstructor ...
void ~XCBarZone()
{
}
//
// Tools ...
/**
* Initialize POI ...
*
* @param bar: XOHCL instance ...
* @param type: ENUM_XPOIS member ...
* @param upperPrice: ENUM_X_PRICE member ...
* @param lowerPrice: ENUM_X_PRICE member ...
*
* @return ( bool )
*/
bool InitBarZone(
XOHCL &bar,
ENUM_XPOIS type,
ENUM_X_PRICE upperPrice,
ENUM_X_PRICE lowerPrice //
)
{
//
bool result = false;
//
result = bar.IsValid() &&
type != X_POI_NONE &&
upperPrice != lowerPrice;
if (!result)
{
return result;
}
//
mBar = bar;
mType = type;
mUpperPrice = upperPrice;
mLowerPrice = lowerPrice;
mUpper = bar.GetPrice(upperPrice);
mLower = bar.GetPrice(lowerPrice);
//
result = IsValidBarZone();
if (result)
{
//
From(bar.time);
To(TimeCurrent());
}
//
return result;
}
//
// Getter(s) / Setter(s) ...
/**
* Fill Bar as XOHCL struct ...
*
* @param bar: XOHCL instance ...
*
* @return ( bool )
*/
bool FillBar(
XOHCL &bar //
)
{
//
bool result = false;
//
result = IsValid();
if (!result)
{
return result;
}
//
bar = mBar;
result = mBar.IsValid();
//
return result;
}
/**
* Set From Date ...
*
* @param value: DateTime ...
*/
void From(datetime value)
{
//
if (!IsValidBarZone())
{
return;
}
//
value = NormalizeTime(value);
//
mFrom = value;
}
/**
* Set To Date ...
*
* @param value: DateTime ...
*/
void To(datetime value)
{
//
if (!IsValidBarZone())
{
return;
}
//
value = NormalizeTime(value);
//
mTo = value;
}
/**
* Retrieve Bar Time ...
*
* @return ( datetime )
*/
datetime BarTime()
{
return mBar.time;
}
/**
* Get Symbol ...
*
* @return ( string )
*/
string GetSymbol()
{
//
string result = NULL;
//
if (!mBar.IsValid())
{
return result;
}
//
return mBar.symbol;
//
return result;
}
/**
* Get Period ...
*
* @return ( int )
*/
ENUM_TIMEFRAMES GetPeriod()
{
//
ENUM_TIMEFRAMES result = NULL;
//
if (!mBar.IsValid())
{
return result;
}
//
return mBar.period;
//
return result;
}
/**
* Is Zone Activated ...
*
* @param forDir: ENUM_X_DIRECTION member, Specified Action Direction ...
* @param activatedBar: XOHCL instance Reference ...
* @param activatedDir: ENUM_X_DIRECTION member ...
* @param forPeriod: ENUM_TIMEFRAMES member, Specified Rejection Period ...
*
* @return ( bool )
*/
bool IsActivated(
ENUM_X_DIRECTION forDir,
XOHCL &activatedBar,
ENUM_X_DIRECTION &activatedDir,
ENUM_TIMEFRAMES forPeriod = NULL //
)
{
//
bool result = false;
//
activatedBar.Clean();
activatedDir = X_DIRECTION_NONE;
//
if (!IsSpecifiedValid(forPeriod))
{
forPeriod = GetPeriod();
}
//
result = IsValid() &&
HasDirection(forDir) &&
IsSpecifiedValid(forPeriod);
if (!result)
{
return result;
}
//
XOHCL startedBar;
ENUM_X_DIRECTION startedDir;
bool isStarted = IsStarted(
forDir,
startedBar,
startedDir,
forPeriod //
);
result = isStarted;
if (!result)
{
return result;
}
//
bool isBullish = IsBullish(forDir);
bool isBearish = IsBearish(forDir);
//
int startIndex = startedBar.Index() - 1;
//
for (int i = startIndex; i >= 0; i--)
{
//
XOHCL iBar;
bool isInited = iBar.Init(
GetSymbol(),
forPeriod,
i //
);
result = isInited;
if (!result)
{
continue;
}
//
XOHCL iPBar;
isInited = iBar.GetPreviousBar(iPBar);
result = isInited;
if (!result)
{
continue;
}
//
bool isActivedFromUpper =
//
isBullish &&
//
(
//
(iPBar.low > Upper() &&
iBar.low <= Upper())
//
)
//
;
//
bool isActivedFromLower =
//
isBearish &&
//
(
//
(iPBar.high < Lower() &&
iBar.high >= Lower())
//
)
//
;
//
bool isActivated =
isActivedFromUpper ||
isActivedFromLower;
if (isActivated)
{
//
result = isActivated;
activatedBar = iBar;
activatedDir =
isActivedFromUpper
? X_DIRECTION_BEARISH
: X_DIRECTION_BULLISH;
break;
}
}
//
result = activatedBar.IsValid() &&
HasDirection(activatedDir);
//
return result;
}
/**
* Is Zone Breaked ...
*
* @param forDir: ENUM_X_DIRECTION member, Specified Action Direction ...
* @param breakerBar: XOHCL instance Reference ...
* @param breakerDir: ENUM_X_DIRECTION member ...
* @param ignoreActivation: ignore Zone Activation and Used Start ...
* @param forPeriod: ENUM_TIMEFRAMES member, Specified Rejection Period ...
*
* @return ( bool )
*/
bool IsBreaked(
ENUM_X_DIRECTION forDir,
XOHCL &breakerBar,
ENUM_X_DIRECTION &breakerDir,
bool ignoreActivation = false,
ENUM_TIMEFRAMES forPeriod = NULL //
)
{
//
bool result = false;
//
breakerBar.Clean();
breakerDir = X_DIRECTION_NONE;
//
if (!IsSpecifiedValid(forPeriod))
{
forPeriod = GetPeriod();
}
//
result = IsValid() &&
HasDirection(forDir) &&
IsSpecifiedValid(forPeriod);
if (!result)
{
return result;
}
//
bool isBullish = IsBullish(forDir);
bool isBearish = IsBearish(forDir);
int activatedIndex = -1;
//
if (!ignoreActivation)
{
//
XOHCL activatedBar;
ENUM_X_DIRECTION activatedDir;
bool isActivated = IsActivated(
forDir,
activatedBar,
activatedDir,
forPeriod //
);
result = isActivated;
if (!result)
{
return result;
}
//
activatedIndex = activatedBar.Index();
}
else
{
//
XOHCL startedBar;
ENUM_X_DIRECTION startedDir;
bool isStarted = IsActivated(
forDir,
startedBar,
startedDir,
forPeriod //
);
result = isStarted;
if (!result)
{
return result;
}
//
activatedIndex = startedBar.Index();
}
//
result = IsValidIndex(activatedIndex);
if (!result)
{
return result;
}
//
activatedIndex--;
//
for (int i = activatedIndex; i >= 0; i--)
{
//
XOHCL iBar;
bool isInited = iBar.Init(
GetSymbol(),
forPeriod,
i //
);
result = isInited;
if (!result)
{
continue;
}
//
XOHCL iPBar;
isInited = iBar
.GetPreviousBar(iPBar);
result = isInited;
if (!result)
{
continue;
}
//
bool isBreakedFromUpper =
//
isBullish &&
//
(
//
iBar.low > Upper() ||
(iBar.low <= Upper() &&
iBar.high > Upper())
//
)
//
;
//
bool isBreakedFromLower =
//
isBearish &&
//
(
//
iBar.low < Lower() ||
(iBar.high >= Lower() &&
iBar.low < Lower())
//
)
//
;
//
bool isBreaked =
isBreakedFromUpper ||
isBreakedFromLower;
if (isBreaked)
{
//
result = isBreaked;
breakerBar = iBar;
breakerDir =
isBreakedFromUpper
? X_DIRECTION_BULLISH
: X_DIRECTION_BEARISH;
break;
}
}
//
result = breakerBar.IsValid() &&
HasDirection(breakerDir);
//
return result;
}
/**
* Is Zone Started ...
*
* @param forDir: ENUM_X_DIRECTION member, Specified Action Direction ...
* @param breakerBar: XOHCL instance Reference ...
* @param breakerDir: ENUM_X_DIRECTION member ...
* @param forPeriod: ENUM_TIMEFRAMES member, Specified Rejection Period ...
*
* @return ( bool )
*/
bool IsStarted(
ENUM_X_DIRECTION forDir,
XOHCL &startedBar,
ENUM_X_DIRECTION &startedDir,
ENUM_TIMEFRAMES forPeriod = NULL //
)
{
//
bool result = false;
//
startedBar.Clean();
startedDir = X_DIRECTION_NONE;
//
if (!IsSpecifiedValid(forPeriod))
{
forPeriod = GetPeriod();
}
//
result = IsValid() &&
HasDirection(forDir) &&
IsSpecifiedValid(forPeriod);
if (!result)
{
return result;
}
//
bool isBullish = IsBullish(forDir);
bool isBearish = IsBearish(forDir);
//
// Detect From Bar Index ...
int fromIndex = iBarShift(
GetSymbol(),
forPeriod,
From() //
);
//
for (int i = fromIndex; i >= 0; i--)
{
//
XOHCL iBar;
bool isInited = iBar.Init(
GetSymbol(),
forPeriod,
i //
);
result = isInited;
if (!result)
{
continue;
}
//
bool isBreakedFromUpper =
//
isBullish &&
//
(
//
iBar.low > Upper() ||
(iBar.low <= Upper() &&
iBar.high > Upper())
//
)
//
;
//
bool isBreakedFromLower =
//
isBearish &&
//
(
//
iBar.low < Lower() ||
(iBar.high >= Lower() &&
iBar.low < Lower())
//
)
//
;
//
bool isBreaked =
isBreakedFromUpper ||
isBreakedFromLower;
if (isBreaked)
{
//
result = isBreaked;
startedBar = iBar;
startedDir =
isBreakedFromUpper
? X_DIRECTION_BULLISH
: X_DIRECTION_BEARISH;
break;
}
}
//
result = startedBar.IsValid() &&
HasDirection(startedDir);
//
return result;
}
/**
* Is Zone Rejected/Sweeped ...
*
* @param forDir: ENUM_X_DIRECTION member, Specified Action Direction ...
* @param rejectedBar: XOHCL instance Reference ...
* @param rejectedDir: ENUM_X_DIRECTION member, Provides Rejection Direction ...
* @param from: datetime start checking optional ...
* @param forceSweep: bool, Specified Force Sweep Rejection ...
* @param forPeriod: ENUM_TIMEFRAMES member, Specified Rejection Period ...
*
* @return ( bool )
*/
bool IsRejected(
ENUM_X_DIRECTION forDir,
XOHCL &rejectedBar,
ENUM_X_DIRECTION &rejectedDir,
datetime from = NULL,
bool forceSweep = false,
ENUM_TIMEFRAMES forPeriod = NULL //
)
{
//
bool result = false;
//
rejectedBar.Clean();
rejectedDir = X_DIRECTION_NONE;
//
if (!IsSpecifiedValid(forPeriod))
{
forPeriod = GetPeriod();
}
//
if (!IsSpecifiedValid(from))
{
from = From();
}
//
result = IsValid() &&
HasDirection(forDir) &&
IsSpecifiedValid(forPeriod);
if (!result)
{
return result;
}
//
bool isBullish = IsBullish(forDir);
bool isBearish = IsBearish(forDir);
//
int fromIndex = iBarShift(
GetSymbol(),
forPeriod,
from //
);
fromIndex--;
//
for (int i = fromIndex; i >= 0; i--)
{
//
XOHCL iBar;
bool isInited = iBar.Init(
GetSymbol(),
forPeriod,
i //
);
result = isInited;
if (!result)
{
continue;
}
//
bool isRejectedFromUpper =
//
isBullish &&
//
(
//
(iBar.low <= Upper() &&
iBar.high > Upper() &&
iBar.GetUp() > Upper())
//
)
//
;
//
bool isRejectedFromLower =
//
isBearish &&
//
(
//
(iBar.high >= Lower() &&
iBar.low < Lower() &&
iBar.GetDown() < Lower())
//
)
//
;
//
bool isSweepedFromUpper =
//
isBullish &&
//
(
//
(iBar.low <= Lower() &&
iBar.high > Upper() &&
iBar.GetUp() > Upper())
//
)
//
;
//
bool isSweepedFromLower =
//
isBearish &&
//
(
//
(iBar.high >= Upper() &&
iBar.low < Lower() &&
iBar.GetDown() < Lower())
//
)
//
;
//
bool isRejected = isRejectedFromUpper ||
isRejectedFromLower;
//
bool isSweeped = isSweepedFromUpper ||
isSweepedFromLower;
//
bool fromUpper = isRejectedFromUpper ||
isSweepedFromUpper;
//
bool fromLower = isRejectedFromLower ||
isSweepedFromLower;
//
// Prepare Result ...
bool isPassed =
isSweeped ||
isRejected;
if (forceSweep)
{
isPassed = isSweeped;
}
//
if (isPassed)
{
//
result = isPassed;
rejectedBar = iBar;
rejectedDir =
fromUpper
? X_DIRECTION_BULLISH
: X_DIRECTION_BEARISH;
break;
}
}
//
result = rejectedBar.IsValid() &&
HasDirection(rejectedDir);
//
return result;
}
/**
* Check to Find Nearest Bar which Breakes Upper ...
*
* @param bar: XOHCL instance Reference, Breaker Bar ...
* @param forPeriod: ENUM_TIMEFRAMES member, Breaker Bar Detection Period, default is Zone Period ...
*
* @return ( bool )
*/
bool FindNearestInsideBarFromUpper(
XOHCL &bar,
ENUM_TIMEFRAMES forPeriod = NULL //
)
{
//
bool result = false;
//
bar.Clean();
//
if (!IsSpecifiedValid(forPeriod))
{
forPeriod = GetPeriod();
}
//
result = IsValid();
if (!result)
{
return result;
}
//
int from = 1;
int to = iBarShift(
GetSymbol(),
forPeriod,
From() //
);
//
for (int i = from; i < to; i++)
{
//
XOHCL iBar;
bool isInited = iBar.Init(
GetSymbol(),
forPeriod,
i //
);
if (!isInited)
{
break;
}
//
bool isInside = iBar.low < Upper();
if (isInside)
{
//
bar = iBar;
break;
}
}
//
result = bar.IsValid();
//
return result;
}
/**
* Check to Find Nearest Bar which Breakes Lower ...
*
* @param bar: XOHCL instance Reference, Breaker Bar ...
* @param forPeriod: ENUM_TIMEFRAMES member, Breaker Bar Detection Period, default is Zone Period ...
*
* @return ( bool )
*/
bool FindNearestInsideBarFromLower(
XOHCL &bar,
ENUM_TIMEFRAMES forPeriod = NULL //
)
{
//
bool result = false;
//
bar.Clean();
//
if (!IsSpecifiedValid(forPeriod))
{
forPeriod = GetPeriod();
}
//
result = IsValid();
if (!result)
{
return result;
}
//
int from = 1;
int to = iBarShift(
GetSymbol(),
forPeriod,
From() //
);
//
for (int i = from; i < to; i++)
{
//
XOHCL iBar;
bool isInited = iBar.Init(
GetSymbol(),
forPeriod,
i //
);
if (!isInited)
{
break;
}
//
bool isInside = iBar.high > Lower();
if (isInside)
{
//
bar = iBar;
break;
}
}
//
result = bar.IsValid();
//
return result;
}
//
// Overrides ...
void Clean() override
{
//
mBar.Clean();
mUpper = 0;
mLower = 0;
mType = X_POI_NONE;
}
datetime From() override
{
return mFrom;
}
datetime To() override
{
return mTo;
}
string GetTag() override
{
//
string result = NULL;
//
if (!IsValidBarZone())
{
return result;
}
//
string hash = ToMD5(mBar.GetTag());
//
result =
//
TypeAsString() + mSep +
ToString(mBar.period) + mSep +
hash
//
;
//
return result;
}
string GetTooltip() override
{
//
string result = NULL;
//
if (!IsValidBarZone())
{
return result;
}
//
return result;
}
//
protected:
//
// Props ...
XOHCL mBar; // Bar ...
ENUM_X_PRICE mUpperPrice; // Upper Price Selection
ENUM_X_PRICE mLowerPrice; // Lower Price Selection
/**
* Check Bar Zone Validation ...
*
* @return ( bool )
*/
bool IsValidBarZone()
{
//
bool result = false;
//
result = mBar.IsValid() &&
mType != X_POI_NONE &&
IsValidBoundary();
//
return result;
}
//
private:
//
// Props ...
datetime mFrom;
datetime mTo;
//
};
class XCTwoBarZone : public XCZone
{
//
public:
//
//
// Constructor ...
void XCTwoBarZone()
{
}
//
// Deconstructor ...
void ~XCTwoBarZone()
{
}
//
// Tools ...
/**
* Initialize POI ...
*
* @param bar: XOHCL instance ...
* @param type: ENUM_XPOIS member ...
* @param upperPrice: ENUM_X_PRICE member ...
* @param lowerPrice: ENUM_X_PRICE member ...
*
* @return ( bool )
*/
bool InitTwoBarZone(
XOHCL &startBar,
XOHCL &endBar,
ENUM_XPOIS type,
bool useStartBarForUpper,
ENUM_X_PRICE upperPrice,
ENUM_X_PRICE lowerPrice //
)
{
//
bool result = false;
//
result = startBar.IsValid() &&
endBar.IsValid() &&
startBar.symbol == endBar.symbol &&
startBar.period == endBar.period &&
startBar.time < endBar.time &&
type != X_POI_NONE;
if (!result)
{
return result;
}
//
mType = type;
mEndBar = endBar;
mStartBar = startBar;
mUpperPrice = upperPrice;
mLowerPrice = lowerPrice;
mUseStartBarForUpper = useStartBarForUpper;
mUpper =
useStartBarForUpper
? startBar.GetPrice(upperPrice)
: endBar.GetPrice(upperPrice);
mLower =
useStartBarForUpper
? endBar.GetPrice(lowerPrice)
: startBar.GetPrice(lowerPrice);
//
result = IsValidTwoBarZone();
if (result)
{
//
From(startBar.time);
To(endBar.time);
}
//
return result;
}
//
// Getter(s) / Setter(s) ...
/**
* Set From Date ...
*
* @param value: DateTime ...
*/
void From(datetime value)
{
//
if (!IsValidTwoBarZone())
{
return;
}
//
value = NormalizeTime(value);
//
mFrom = value;
}
/**
* Set To Date ...
*
* @param value: DateTime ...
*/
void To(datetime value)
{
//
if (!IsValidTwoBarZone())
{
return;
}
//
value = NormalizeTime(value);
//
mTo = value;
}
/**
* Fill Start Bar ...
*
* @param bar: XOHCL instance ...
*
* @return ( bool )
*/
bool FillStartBar(XOHCL &bar)
{
//
bool result = false;
//
result = IsValidTwoBarZone();
if (!result)
{
return result;
}
//
bar = mStartBar;
//
return result;
}
/**
* Fill End Bar ...
*
* @param bar: XOHCL instance ...
*
* @return ( bool )
*/
bool FillEndBar(XOHCL &bar)
{
//
bool result = false;
//
result = IsValidTwoBarZone();
if (!result)
{
return result;
}
//
bar = mEndBar;
//
return result;
}
/**
* Get Symbol ...
*
* @return ( string )
*/
string GetSymbol()
{
//
string result = NULL;
//
if (!mStartBar.IsValid())
{
return result;
}
//
return mStartBar.symbol;
//
return result;
}
/**
* Get Period ...
*
* @return ( int )
*/
ENUM_TIMEFRAMES GetPeriod()
{
//
ENUM_TIMEFRAMES result = NULL;
//
if (!mStartBar.IsValid())
{
return result;
}
//
return mStartBar.period;
//
return result;
}
/**
* Is Zone Activated ...
*
* @param forDir: ENUM_X_DIRECTION member, Specified Action Direction ...
* @param activatedBar: XOHCL instance Reference ...
* @param activatedDir: ENUM_X_DIRECTION member ...
* @param forPeriod: ENUM_TIMEFRAMES member, Specified Rejection Period ...
*
* @return ( bool )
*/
bool IsActivated(
ENUM_X_DIRECTION forDir,
XOHCL &activatedBar,
ENUM_X_DIRECTION &activatedDir,
ENUM_TIMEFRAMES forPeriod = NULL //
)
{
//
bool result = false;
//
activatedBar.Clean();
activatedDir = X_DIRECTION_NONE;
//
if (!IsSpecifiedValid(forPeriod))
{
forPeriod = GetPeriod();
}
//
result = IsValid() &&
HasDirection(forDir) &&
IsSpecifiedValid(forPeriod);
if (!result)
{
return result;
}
//
XOHCL startedBar;
ENUM_X_DIRECTION startedDir;
bool isStarted = IsStarted(
forDir,
startedBar,
startedDir,
forPeriod //
);
result = isStarted;
if (!result)
{
return result;
}
//
bool isBullish = IsBullish(forDir);
bool isBearish = IsBearish(forDir);
//
int startIndex = startedBar.Index() - 1;
//
for (int i = startIndex; i >= 0; i--)
{
//
XOHCL iBar;
bool isInited = iBar.Init(
GetSymbol(),
forPeriod,
i //
);
result = isInited;
if (!result)
{
continue;
}
//
XOHCL iPBar;
isInited = iBar.GetPreviousBar(iPBar);
result = isInited;
if (!result)
{
continue;
}
//
bool isActivedFromUpper =
//
isBullish &&
//
(
//
(iPBar.low > Upper() &&
iBar.low <= Upper())
//
)
//
;
//
bool isActivedFromLower =
//
isBearish &&
//
(
//
(iPBar.high < Lower() &&
iBar.high >= Lower())
//
)
//
;
//
bool isActivated =
isActivedFromUpper ||
isActivedFromLower;
if (isActivated)
{
//
result = isActivated;
activatedBar = iBar;
activatedDir =
isActivedFromUpper
? X_DIRECTION_BEARISH
: X_DIRECTION_BULLISH;
break;
}
}
//
result = activatedBar.IsValid() &&
HasDirection(activatedDir);
//
return result;
}
/**
* Is Zone Breaked ...
*
* @param forDir: ENUM_X_DIRECTION member, Specified Action Direction ...
* @param breakerBar: XOHCL instance Reference ...
* @param breakerDir: ENUM_X_DIRECTION member ...
* @param ignoreActivation: ignore Zone Activation and Used Start ...
* @param forPeriod: ENUM_TIMEFRAMES member, Specified Rejection Period ...
*
* @return ( bool )
*/
bool IsBreaked(
ENUM_X_DIRECTION forDir,
XOHCL &breakerBar,
ENUM_X_DIRECTION &breakerDir,
bool ignoreActivation = false,
ENUM_TIMEFRAMES forPeriod = NULL //
)
{
//
bool result = false;
//
breakerBar.Clean();
breakerDir = X_DIRECTION_NONE;
//
if (!IsSpecifiedValid(forPeriod))
{
forPeriod = GetPeriod();
}
//
result = IsValid() &&
HasDirection(forDir) &&
IsSpecifiedValid(forPeriod);
if (!result)
{
return result;
}
//
bool isBullish = IsBullish(forDir);
bool isBearish = IsBearish(forDir);
int activatedIndex = -1;
//
if (!ignoreActivation)
{
//
XOHCL activatedBar;
ENUM_X_DIRECTION activatedDir;
bool isActivated = IsActivated(
forDir,
activatedBar,
activatedDir,
forPeriod //
);
result = isActivated;
if (!result)
{
return result;
}
//
activatedIndex = activatedBar.Index();
}
else
{
//
XOHCL startedBar;
ENUM_X_DIRECTION startedDir;
bool isStarted = IsActivated(
forDir,
startedBar,
startedDir,
forPeriod //
);
result = isStarted;
if (!result)
{
return result;
}
//
activatedIndex = startedBar.Index();
}
//
result = IsValidIndex(activatedIndex);
if (!result)
{
return result;
}
//
activatedIndex--;
//
for (int i = activatedIndex; i >= 0; i--)
{
//
XOHCL iBar;
bool isInited = iBar.Init(
GetSymbol(),
forPeriod,
i //
);
result = isInited;
if (!result)
{
continue;
}
//
XOHCL iPBar;
isInited = iBar
.GetPreviousBar(iPBar);
result = isInited;
if (!result)
{
continue;
}
//
bool isBreakedFromUpper =
//
isBullish &&
//
(
//
iBar.low > Upper() ||
(iBar.low <= Upper() &&
iBar.high > Upper())
//
)
//
;
//
bool isBreakedFromLower =
//
isBearish &&
//
(
//
iBar.low < Lower() ||
(iBar.high >= Lower() &&
iBar.low < Lower())
//
)
//
;
//
bool isBreaked =
isBreakedFromUpper ||
isBreakedFromLower;
if (isBreaked)
{
//
result = isBreaked;
breakerBar = iBar;
breakerDir =
isBreakedFromUpper
? X_DIRECTION_BULLISH
: X_DIRECTION_BEARISH;
break;
}
}
//
result = breakerBar.IsValid() &&
HasDirection(breakerDir);
//
return result;
}
/**
* Is Zone Started ...
*
* @param forDir: ENUM_X_DIRECTION member, Specified Action Direction ...
* @param breakerBar: XOHCL instance Reference ...
* @param breakerDir: ENUM_X_DIRECTION member ...
* @param forPeriod: ENUM_TIMEFRAMES member, Specified Rejection Period ...
*
* @return ( bool )
*/
bool IsStarted(
ENUM_X_DIRECTION forDir,
XOHCL &startedBar,
ENUM_X_DIRECTION &startedDir,
ENUM_TIMEFRAMES forPeriod = NULL //
)
{
//
bool result = false;
//
startedBar.Clean();
startedDir = X_DIRECTION_NONE;
//
if (!IsSpecifiedValid(forPeriod))
{
forPeriod = GetPeriod();
}
//
result = IsValid() &&
HasDirection(forDir) &&
IsSpecifiedValid(forPeriod);
if (!result)
{
return result;
}
//
bool isBullish = IsBullish(forDir);
bool isBearish = IsBearish(forDir);
//
// Detect From Bar Index ...
int fromIndex = iBarShift(
GetSymbol(),
forPeriod,
From() //
);
//
for (int i = fromIndex; i >= 0; i--)
{
//
XOHCL iBar;
bool isInited = iBar.Init(
GetSymbol(),
forPeriod,
i //
);
result = isInited;
if (!result)
{
continue;
}
//
bool isBreakedFromUpper =
//
isBullish &&
//
(
//
iBar.low > Upper() ||
(iBar.low <= Upper() &&
iBar.high > Upper())
//
)
//
;
//
bool isBreakedFromLower =
//
isBearish &&
//
(
//
iBar.low < Lower() ||
(iBar.high >= Lower() &&
iBar.low < Lower())
//
)
//
;
//
bool isBreaked =
isBreakedFromUpper ||
isBreakedFromLower;
if (isBreaked)
{
//
result = isBreaked;
startedBar = iBar;
startedDir =
isBreakedFromUpper
? X_DIRECTION_BULLISH
: X_DIRECTION_BEARISH;
break;
}
}
//
result = startedBar.IsValid() &&
HasDirection(startedDir);
//
return result;
}
/**
* Is Zone Rejected/Sweeped ...
*
* @param forDir: ENUM_X_DIRECTION member, Specified Action Direction ...
* @param rejectedBar: XOHCL instance Reference ...
* @param rejectedDir: ENUM_X_DIRECTION member, Provides Rejection Direction ...
* @param from: datetime start checking optional ...
* @param forceSweep: bool, Specified Force Sweep Rejection ...
* @param forPeriod: ENUM_TIMEFRAMES member, Specified Rejection Period ...
*
* @return ( bool )
*/
bool IsRejected(
ENUM_X_DIRECTION forDir,
XOHCL &rejectedBar,
ENUM_X_DIRECTION &rejectedDir,
datetime from = NULL,
bool forceSweep = false,
ENUM_TIMEFRAMES forPeriod = NULL //
)
{
//
bool result = false;
//
rejectedBar.Clean();
rejectedDir = X_DIRECTION_NONE;
//
if (!IsSpecifiedValid(forPeriod))
{
forPeriod = GetPeriod();
}
//
if (!IsSpecifiedValid(from))
{
from = From();
}
//
result = IsValid() &&
HasDirection(forDir) &&
IsSpecifiedValid(forPeriod);
if (!result)
{
return result;
}
//
bool isBullish = IsBullish(forDir);
bool isBearish = IsBearish(forDir);
//
int fromIndex = iBarShift(
GetSymbol(),
forPeriod,
from //
);
fromIndex--;
//
for (int i = fromIndex; i >= 0; i--)
{
//
XOHCL iBar;
bool isInited = iBar.Init(
GetSymbol(),
forPeriod,
i //
);
result = isInited;
if (!result)
{
continue;
}
//
bool isRejectedFromUpper =
//
isBullish &&
//
(
//
(iBar.low <= Upper() &&
iBar.high > Upper() &&
iBar.GetUp() > Upper())
//
)
//
;
//
bool isRejectedFromLower =
//
isBearish &&
//
(
//
(iBar.high >= Lower() &&
iBar.low < Lower() &&
iBar.GetDown() < Lower())
//
)
//
;
//
bool isSweepedFromUpper =
//
isBullish &&
//
(
//
(iBar.low <= Lower() &&
iBar.high > Upper() &&
iBar.GetUp() > Upper())
//
)
//
;
//
bool isSweepedFromLower =
//
isBearish &&
//
(
//
(iBar.high >= Upper() &&
iBar.low < Lower() &&
iBar.GetDown() < Lower())
//
)
//
;
//
bool isRejected = isRejectedFromUpper ||
isRejectedFromLower;
//
bool isSweeped = isSweepedFromUpper ||
isSweepedFromLower;
//
bool fromUpper = isRejectedFromUpper ||
isSweepedFromUpper;
//
bool fromLower = isRejectedFromLower ||
isSweepedFromLower;
//
// Prepare Result ...
bool isPassed =
isSweeped ||
isRejected;
if (forceSweep)
{
isPassed = isSweeped;
}
//
if (isPassed)
{
//
result = isPassed;
rejectedBar = iBar;
rejectedDir =
fromUpper
? X_DIRECTION_BULLISH
: X_DIRECTION_BEARISH;
break;
}
}
//
result = rejectedBar.IsValid() &&
HasDirection(rejectedDir);
//
return result;
}
/**
* Check to Find Nearest Bar which Breakes Upper ...
*
* @param bar: XOHCL instance Reference, Breaker Bar ...
* @param forPeriod: ENUM_TIMEFRAMES member, Breaker Bar Detection Period, default is Zone Period ...
*
* @return ( bool )
*/
bool FindNearestInsideBarFromUpper(
XOHCL &bar,
ENUM_TIMEFRAMES forPeriod = NULL //
)
{
//
bool result = false;
//
bar.Clean();
//
if (!IsSpecifiedValid(forPeriod))
{
forPeriod = GetPeriod();
}
//
result = IsValid();
if (!result)
{
return result;
}
//
int from = 1;
int to = iBarShift(
GetSymbol(),
forPeriod,
From() //
);
//
for (int i = from; i < to; i++)
{
//
XOHCL iBar;
bool isInited = iBar.Init(
GetSymbol(),
forPeriod,
i //
);
if (!isInited)
{
break;
}
//
bool isInside = iBar.low < Upper();
if (isInside)
{
//
bar = iBar;
break;
}
}
//
result = bar.IsValid();
//
return result;
}
/**
* Check to Find Nearest Bar which Breakes Lower ...
*
* @param bar: XOHCL instance Reference, Breaker Bar ...
* @param forPeriod: ENUM_TIMEFRAMES member, Breaker Bar Detection Period, default is Zone Period ...
*
* @return ( bool )
*/
bool FindNearestInsideBarFromLower(
XOHCL &bar,
ENUM_TIMEFRAMES forPeriod = NULL //
)
{
//
bool result = false;
//
bar.Clean();
//
if (!IsSpecifiedValid(forPeriod))
{
forPeriod = GetPeriod();
}
//
result = IsValid();
if (!result)
{
return result;
}
//
int from = 1;
int to = iBarShift(
GetSymbol(),
forPeriod,
From() //
);
//
for (int i = from; i < to; i++)
{
//
XOHCL iBar;
bool isInited = iBar.Init(
GetSymbol(),
forPeriod,
i //
);
if (!isInited)
{
break;
}
//
bool isInside = iBar.high > Lower();
if (isInside)
{
//
bar = iBar;
break;
}
}
//
result = bar.IsValid();
//
return result;
}
//
// Overrides ...
void Clean() override
{
//
mStartBar.Clean();
mEndBar.Clean();
mUpper = 0;
mLower = 0;
mUseStartBarForUpper = false;
mType = X_POI_NONE;
}
datetime From() override
{
return mFrom;
}
datetime To() override
{
return mTo;
}
string GetTag() override
{
//
string result = NULL;
//
if (!IsValidTwoBarZone())
{
return result;
}
//
string hash = ToMD5(mStartBar.GetTag() + mSep + mEndBar.GetTag());
//
result =
//
TypeAsString() + mSep +
ToString(mStartBar.period) + mSep +
hash
//
;
//
return result;
}
string GetTooltip() override
{
//
string result = NULL;
//
if (!IsValidTwoBarZone())
{
return result;
}
//
return result;
}
//
protected:
//
// Props ...
XOHCL mStartBar; // Start (Oldest) Bar ...
XOHCL mEndBar; // End (Newest) Bar ...
bool mUseStartBarForUpper; // Use Start Bar for Upper Calculation ...
ENUM_X_PRICE mUpperPrice; // Upper Price Selection
ENUM_X_PRICE mLowerPrice; // Lower Price Selection
/**
* Check Two Bar Zone Validation ...
*
* @return ( bool )
*/
bool IsValidTwoBarZone()
{
//
bool result = false;
//
result = mStartBar.IsValid() &&
mEndBar.IsValid() &&
mStartBar.symbol == mEndBar.symbol &&
mStartBar.period == mEndBar.period &&
mStartBar.time < mEndBar.time &&
mType != X_POI_NONE &&
IsValidBoundary();
//
return result;
}
//
private:
//
// Props ...
datetime mFrom;
datetime mTo;
//
};
//
// Swing Class ...
class XCSwing : public XCBasePOI
{
//
public:
//
//
// Constructor ...
void XCSwing()
{
}
//
// Deconstructor ...
void ~XCSwing()
{
}
//
// Tools ...
/**
* Initialize POI ...
*
* @param bar: XOHCL instance ...
* @param type: ENUM_XPOIS member ...
*
* @return ( bool )
*/
bool Init(
XOHCL &bar,
ENUM_XPOIS type //
)
{
//
bool result = false;
//
result = bar.IsValid() &&
(type == X_POI_SWING_HIGH ||
type == X_POI_SWING_LOW);
if (!result)
{
return result;
}
//
mBar = bar;
mType = type;
//
result = IsValid();
//
return result;
}
//
// Getter(s) / Setter(s) ...
/**
* Fill Bar as XOHCL struct ...
*
* @param bar: XOHCL instance ...
*
* @return ( bool )
*/
bool FillBar(
XOHCL &bar //
)
{
//
bool result = false;
//
result = IsValid();
if (!result)
{
return result;
}
//
bar = mBar;
result = mBar.IsValid();
//
return result;
}
/**
* Get Time of Swing ...
*
* @return ( datetime )
*/
datetime GetTime()
{
//
datetime result = NULL;
//
if (!IsValid() || !mBar.IsValid())
{
return result;
}
//
result = mBar.time;
//
return result;
}
ENUM_TIMEFRAMES GetPeriod()
{
//
ENUM_TIMEFRAMES result = NULL;
//
XOHCL bar;
bool isFilled = FillBar(bar);
if (!isFilled)
{
return result;
}
//
result = bar.period;
//
return result;
}
/**
* Check Swing High or not ...
*
* @return ( bool )
*/
bool IsSwingHigh()
{
//
bool result = false;
//
result = IsValid();
if (!result)
{
return result;
}
//
result =
Type() == X_POI_SWING_HIGH;
//
return result;
}
/**
* Check Swing Low or not ...
*
* @return ( bool )
*/
bool IsSwingLow()
{
//
bool result = false;
//
result = IsValid();
if (!result)
{
return result;
}
//
result =
Type() == X_POI_SWING_LOW;
//
return result;
}
/**
* Get Swing Value ...
*
* @return ( double )
*/
double GetValue()
{
//
double result = 0;
//
if (!IsValid())
{
return result;
}
//
result =
IsSwingHigh()
? mBar.high
: mBar.low;
//
return result;
}
//
// Overrides ...
void Clean() override
{
//
mBar.Clean();
mType = X_POI_NONE;
}
bool IsValid() override
{
//
bool result = false;
//
result = mBar.IsValid() &&
(mType == X_POI_SWING_HIGH ||
mType == X_POI_SWING_LOW);
//
return result;
}
string GetTag() override
{
//
string result = NULL;
//
if (!IsValid())
{
return result;
}
//
string hash = ToMD5(mBar.GetTag());
//
string subType = IsSwingHigh()
? "High"
: "Low";
//
result =
//
TypeAsString() + mSep +
subType + mSep +
ToString(mBar.period) + mSep +
hash
//
;
//
return result;
}
string GetTooltip() override
{
//
string result = NULL;
//
if (!IsValid())
{
return result;
}
//
return result;
}
//
protected:
//
// Props ...
XOHCL mBar; // Swing Bar ...
//
private:
//
};
//
// Supply Zone ...
class XCSupplyZone : public XCBarZone
{
//
public:
//
//
// Constructor ...
void XCSupplyZone()
{
}
//
// Deconstructor ...
void ~XCSupplyZone()
{
}
//
// Tools ...
/**
* Initialize POI ...
*
* @param bar: XOHCL instance ...
* @param range: Integer, Detection Range ...
*
* @return ( bool )
*/
bool Init(
XOHCL &bar,
int range = 0 //
)
{
//
bool result = false;
//
result = bar.IsValid();
if (!result)
{
return result;
}
//
result = InitBarZone(
bar,
X_POI_SUPPLY_ZONE,
X_PRICE_HIGH,
X_PRICE_LOW //
);
if (!result)
{
return result;
}
//
result = IsValid();
if (result &&
range > 0)
{
//
datetime time = bar.time;
int periodSeconds = PeriodSeconds(bar.period);
//
datetime from = (datetime)((int)time - (range * periodSeconds));
datetime to = (datetime)((int)time + (range * periodSeconds));
//
From(from);
To(to);
}
//
return result;
}
//
// Getter(s) / Setter(s) ...
//
// Overrides ...
bool IsValid() override
{
//
bool result = false;
//
result = IsValidBarZone() &&
mType == X_POI_SUPPLY_ZONE;
//
return result;
}
//
protected:
//
//
private:
//
//
};
//
// Demand Zone ...
class XCDemandZone : public XCBarZone
{
//
public:
//
//
// Constructor ...
void XCDemandZone()
{
}
//
// Deconstructor ...
void ~XCDemandZone()
{
}
//
// Tools ...
/**
* Initialize POI ...
*
* @param bar: XOHCL instance ...
* @param range: Integer, Detection Range ...
*
* @return ( bool )
*/
bool Init(
XOHCL &bar,
int range = 0 //
)
{
//
bool result = false;
//
result = bar.IsValid();
if (!result)
{
return result;
}
//
result = InitBarZone(
bar,
X_POI_DEMAND_ZONE,
X_PRICE_HIGH,
X_PRICE_LOW //
);
if (!result)
{
return result;
}
//
result = IsValid();
if (result &&
range > 0)
{
//
datetime time = bar.time;
int periodSeconds = PeriodSeconds(bar.period);
//
datetime from = (datetime)((int)time - (range * periodSeconds));
datetime to = (datetime)((int)time + (range * periodSeconds));
//
From(from);
To(to);
}
//
return result;
}
//
// Getter(s) / Setter(s) ...
//
// Overrides ...
bool IsValid() override
{
//
bool result = false;
//
result = IsValidBarZone() &&
mType == X_POI_DEMAND_ZONE;
//
return result;
}
//
protected:
//
//
private:
//
//
};
//
// Support Zone ...
class XCSupportZone : public XCBarZone
{
//
public:
//
//
// Constructor ...
void XCSupportZone()
{
}
//
// Deconstructor ...
void ~XCSupportZone()
{
}
//
// Tools ...
/**
* Initialize POI ...
*
* @param bar: XOHCL instance ...
* @param range: Integer, Detection Range ...
*
* @return ( bool )
*/
bool Init(
XOHCL &bar,
int range = 0 //
)
{
//
bool result = false;
//
result = bar.IsValid();
if (!result)
{
return result;
}
//
result = InitBarZone(
bar,
X_POI_SUPPORT_ZONE,
X_PRICE_DOWN,
X_PRICE_LOW //
);
if (!result)
{
return result;
}
//
result = IsValid();
if (result &&
range > 0)
{
//
datetime time = bar.time;
int periodSeconds = PeriodSeconds(bar.period);
//
datetime from = (datetime)((int)time - (range * periodSeconds));
datetime to = (datetime)((int)time + (range * periodSeconds));
//
From(from);
To(to);
}
//
return result;
}
//
// Getter(s) / Setter(s) ...
//
// Overrides ...
bool IsValid() override
{
//
bool result = false;
//
result = IsValidBarZone() &&
mType == X_POI_SUPPORT_ZONE;
//
return result;
}
//
protected:
//
//
private:
//
//
};
//
// Resistance Zone ...
class XCResistanceZone : public XCBarZone
{
//
public:
//
//
// Constructor ...
void XCResistanceZone()
{
}
//
// Deconstructor ...
void ~XCResistanceZone()
{
}
//
// Tools ...
/**
* Initialize POI ...
*
* @param bar: XOHCL instance ...
* @param range: Integer, Detection Range ...
*
* @return ( bool )
*/
bool Init(
XOHCL &bar,
int range = 0 //
)
{
//
bool result = false;
//
result = bar.IsValid();
if (!result)
{
return result;
}
//
result = InitBarZone(
bar,
X_POI_RESISTANCE_ZONE,
X_PRICE_HIGH,
X_PRICE_UP //
);
if (!result)
{
return result;
}
//
result = IsValid();
if (result &&
range > 0)
{
//
datetime time = bar.time;
int periodSeconds = PeriodSeconds(bar.period);
//
datetime from = (datetime)((int)time - (range * periodSeconds));
datetime to = (datetime)((int)time + (range * periodSeconds));
//
From(from);
To(to);
}
//
return result;
}
//
// Getter(s) / Setter(s) ...
//
// Overrides ...
bool IsValid() override
{
//
bool result = false;
//
result = IsValidBarZone() &&
mType == X_POI_RESISTANCE_ZONE;
//
return result;
}
//
protected:
//
//
private:
//
//
};
//
// Order Block ...
class XCOrderBlock : public XCBarZone
{
//
public:
//
//
// Constructor ...
void XCOrderBlock()
{
}
//
// Deconstructor ...
void ~XCOrderBlock()
{
}
//
// Tools ...
/**
* Initialize POI ...
*
* @param bar: XOHCL instance ...
* @param dir: ENUM_X_DIRECTION member ...
*
* @return ( bool )
*/
bool Init(
XOHCL &bar,
ENUM_X_DIRECTION dir //
)
{
//
bool result = false;
//
result = bar.IsValid() &&
(dir == X_DIRECTION_BULLISH ||
dir == X_DIRECTION_BEARISH);
if (!result)
{
return result;
}
//
ENUM_XPOIS mTT =
IsSpecifiedBullish(dir)
? X_POI_BULLISH_ORDERBLOCK
: X_POI_BEARISH_ORDERBLOCK;
//
result = InitBarZone(
bar,
mTT,
X_PRICE_HIGH,
X_PRICE_LOW //
);
if (!result)
{
return result;
}
//
result = IsValid();
//
return result;
}
//
// Getter(s) / Setter(s) ...
/**
* Check is Bullish ...
*
* @return ( bool )
*/
bool IsBullish()
{
//
bool result = false;
//
result = IsValid() &&
Type() == X_POI_BULLISH_ORDERBLOCK;
//
return result;
}
/**
* Check is Bearish ...
*
* @return ( bool )
*/
bool IsBearish()
{
//
bool result = false;
//
result = IsValid() &&
Type() == X_POI_BEARISH_ORDERBLOCK;
//
return result;
}
ENUM_X_DIRECTION GetDirection()
{
//
ENUM_X_DIRECTION result = X_DIRECTION_NONE;
//
if (!IsValid())
{
return result;
}
//
result =
IsBullish()
? X_DIRECTION_BULLISH
: X_DIRECTION_BEARISH;
//
return result;
}
//
// Overrides ...
bool IsValid() override
{
//
bool result = false;
//
result = IsValidBarZone() &&
(mType == X_POI_BULLISH_ORDERBLOCK ||
mType == X_POI_BEARISH_ORDERBLOCK);
//
return result;
}
//
protected:
//
//
private:
//
//
};
//
// Rejection Bar ...
class XCRejectionBar : public XCBarZone
{
//
public:
//
//
// Constructor ...
void XCRejectionBar()
{
}
//
// Deconstructor ...
void ~XCRejectionBar()
{
}
//
// Tools ...
/**
* Initialize POI ...
*
* @param bar: XOHCL instance ...
*
* @return ( bool )
*/
bool Init(
XOHCL &bar //
)
{
//
bool result = false;
//
result = bar.IsValid();
if (!result)
{
return result;
}
//
bool isBullish =
bar.GetLowShadow() > bar.GetHighShadow();
bool isBearish =
bar.GetHighShadow() > bar.GetLowShadow();
result = isBullish ||
isBearish;
if (!result)
{
return result;
}
//
ENUM_X_PRICE upPrice = isBullish
? X_PRICE_HIGH
: X_PRICE_DOWN;
//
ENUM_X_PRICE loPrice = isBullish
? X_PRICE_UP
: X_PRICE_LOW;
//
result = InitBarZone(
bar,
X_POI_REJECTION_BAR,
upPrice,
loPrice //
);
if (!result)
{
return result;
}
//
result = IsValid();
//
return result;
}
//
// Getter(s) / Setter(s) ...
/**
* Check is Bullish ...
*
* @return ( bool )
*/
bool IsBullish()
{
//
bool result = false;
//
result = IsValid() &&
Type() == X_POI_REJECTION_BAR &&
mBar.GetLowShadow() > mBar.GetHighShadow();
//
return result;
}
/**
* Check is Bearish ...
*
* @return ( bool )
*/
bool IsBearish()
{
//
bool result = false;
//
result = IsValid() &&
Type() == X_POI_REJECTION_BAR &&
mBar.GetHighShadow() > mBar.GetLowShadow();
//
return result;
}
//
// Overrides ...
bool IsValid() override
{
//
bool result = false;
//
result = IsValidBarZone() &&
mType == X_POI_REJECTION_BAR;
//
return result;
}
//
protected:
//
//
private:
//
//
};
//
// Momentum Bar ...
class XCMomentumBar : public XCBarZone
{
//
public:
//
//
// Constructor ...
void XCMomentumBar()
{
}
//
// Deconstructor ...
void ~XCMomentumBar()
{
}
//
// Tools ...
/**
* Initialize POI ...
*
* @param bar: XOHCL instance ...
*
* @return ( bool )
*/
bool Init(
XOHCL &bar //
)
{
//
bool result = false;
//
result = bar.IsValid();
if (!result)
{
return result;
}
//
bool isBullish = bar.IsBullish();
bool isBearish = bar.IsBearish();
result = isBullish ||
isBearish;
if (!result)
{
return result;
}
//
result = InitBarZone(
bar,
X_POI_MOMENTUM_BAR,
X_PRICE_HIGH,
X_PRICE_LOW //
);
if (!result)
{
return result;
}
//
result = IsValid();
//
return result;
}
//
// Getter(s) / Setter(s) ...
/**
* Check is Bullish ...
*
* @return ( bool )
*/
bool IsBullish()
{
//
bool result = false;
//
result = IsValid() &&
mBar.IsBullish() &&
Type() == X_POI_MOMENTUM_BAR;
//
return result;
}
/**
* Check is Bearish ...
*
* @return ( bool )
*/
bool IsBearish()
{
//
bool result = false;
//
result = IsValid() &&
mBar.IsBearish() &&
Type() == X_POI_MOMENTUM_BAR;
//
return result;
}
//
// Overrides ...
bool IsValid() override
{
//
bool result = false;
//
result = IsValidBarZone() &&
mType == X_POI_MOMENTUM_BAR;
//
return result;
}
//
protected:
//
//
private:
//
//
};
//
// Fair Value Gap ...
class XCFVG : public XCTwoBarZone
{
//
public:
//
//
// Constructor ...
void XCFVG()
{
}
//
// Deconstructor ...
void ~XCFVG()
{
}
//
// Tools ...
/**
* Initialize POI ...
*
* @param startBar: XOHCL instance ...
* @param endBar: XOHCL instance ...
* @param dir: ENUM_X_DIRECTION member ...
*
* @return ( bool )
*/
bool Init(
XOHCL &startBar,
XOHCL &endBar,
ENUM_X_DIRECTION dir //
)
{
//
bool result = false;
//
result = endBar.IsValid() &&
startBar.IsValid() &&
(dir == X_DIRECTION_BULLISH ||
dir == X_DIRECTION_BEARISH);
if (!result)
{
return result;
}
//
bool isDirBullish = IsSpecifiedBullish(dir);
ENUM_XPOIS mTT =
isDirBullish
? X_POI_BULLISH_FVG
: X_POI_BEARISH_FVG;
//
bool useFistForUpper = isDirBullish
? false
: true;
ENUM_X_PRICE upPrice = isDirBullish
? X_PRICE_LOW
: X_PRICE_HIGH;
ENUM_X_PRICE loPrice = isDirBullish
? X_PRICE_HIGH
: X_PRICE_LOW;
//
result = InitTwoBarZone(
startBar,
endBar,
mTT,
useFistForUpper,
upPrice,
loPrice //
);
if (!result)
{
return result;
}
//
result = IsValid();
//
return result;
}
//
// Getter(s) / Setter(s) ...
/**
* Check is Bullish ...
*
* @return ( bool )
*/
bool IsBullish()
{
//
bool result = false;
//
result = IsValid() &&
Type() == X_POI_BULLISH_FVG;
//
return result;
}
/**
* Check is Bearish ...
*
* @return ( bool )
*/
bool IsBearish()
{
//
bool result = false;
//
result = IsValid() &&
Type() == X_POI_BEARISH_FVG;
//
return result;
}
ENUM_X_DIRECTION GetDirection()
{
//
ENUM_X_DIRECTION result = X_DIRECTION_NONE;
//
if (!IsValid())
{
return result;
}
//
result =
IsBullish()
? X_DIRECTION_BULLISH
: X_DIRECTION_BEARISH;
//
return result;
}
//
// Overrides ...
bool IsValid() override
{
//
bool result = false;
//
result = IsValidTwoBarZone() &&
(mType == X_POI_BULLISH_FVG ||
mType == X_POI_BEARISH_FVG);
//
return result;
}
//
protected:
//
//
private:
//
//
};
//
// Ticks Zones ...
//
class XCTickZone : public CObject
{
//
// Public ...
public:
//
// Props ...
string symbol;
ENUM_TIMEFRAMES period;
//
double high;
double low;
int ticks;
double percent;
//
ulong volume;
double volumePercent;
//
// Compare Two Zone With Each Other ...
virtual int Compare(
const CObject *node,
const int mode = 0 //
) const
{
//
const XCTickZone *other = (XCTickZone *)node;
//
return other.ticks - ticks;
}
//
bool IsValid()
{
//
bool result = false;
//
result = high > 0 &&
low > 0 &&
high > low &&
ticks > 0 &&
percent > 0;
//
return result;
}
//
// Protected ...
protected:
//
// Private ...
private:
//
};
//
class XCTicksZone : public XCTwoBarZone
{
//
public:
//
//
// Constructor ...
void XCTicksZone()
{
Default();
}
//
// Deconstructor ...
void ~XCTicksZone()
{
}
//
// Getter(s) / Setter(s) ...
/**
* Get Number of Ticks Levels ...
*
* @return ( int )
*/
int Levels()
{
return mLevels;
}
/**
* Set Number of Ticks Levels ...
*
* @return ( int )
*/
void Levels(int value)
{
//
if (value < 2)
{
value = 2;
}
//
mLevels = value;
}
/**
* Apply Default Config ...
*/
virtual void Default()
{
//
Levels(10);
}
//
// Tools ...
/**
* Initialize POI ...
*
* @param startBar: XOHCL instance ...
* @param endBar: XOHCL instance ...
*
* @return ( bool )
*/
bool Init(
XOHCL &startBar,
XOHCL &endBar,
ENUM_TIMEFRAMES forPeriod = NULL //
)
{
//
bool result = false;
//
result = endBar.IsValid() &&
startBar.IsValid();
if (!result)
{
return result;
}
//
if (!IsSpecifiedValid(forPeriod))
{
forPeriod = endBar.period;
}
//
// Calculate Start and End Time ...
datetime from = startBar.time;
datetime to = endBar.time;
ulong fromM = ((ulong)startBar.time * 1000);
ulong toM = ((ulong)endBar.time * 1000);
//
// Symbol and Period ...
string symbol = startBar.symbol;
ENUM_TIMEFRAMES period = startBar.period;
//
// Prepare Zones Array ...
mZones.Clear();
//
// Retrieve Ticks between Times ...
SpecificClean(mTicks);
CopyTicksRange(
symbol,
mTicks,
COPY_TICKS_ALL,
fromM,
toM //
);
//
// Ticks Volumes ...
int ticksVolumeCount = CopyTickVolume(
symbol,
forPeriod,
from,
to,
mTickVolumes //
);
if (IsValidSize(ticksVolumeCount))
{
//
mVolumes = 0;
for (int i = 0; i < ticksVolumeCount; i++)
{
mVolumes += mTickVolumes[i];
}
}
//
// Retrieve Highs ...
SpecificClean(mHighs);
CopyHigh(
symbol,
period,
from,
to,
mHighs //
);
//
// Retrieve Lows ...
SpecificClean(mLows);
CopyLow(
symbol,
period,
from,
to,
mLows //
);
//
// Find Highest Value in Range ...
int highIDX = ArrayMaximum(mHighs);
mRangeHigh = mHighs[highIDX];
//
// Find Lowest Value in Range ...
int lowIDX = ArrayMinimum(mLows);
mRangeLow = mLows[lowIDX];
//
datetime mTimes[];
CopyTime(
symbol,
period,
from,
to,
mTimes //
);
mRangeHighTime = mTimes[highIDX];
mRangeLowTime = mTimes[lowIDX];
//
double mRangeSize = mRangeHigh - mRangeLow;
//
// Create Zones ...
for (int i = 0; i < Levels(); i++)
{
//
// Instance a New Zone ...
XCTickZone *iZone = new XCTickZone();
//
iZone.symbol = symbol;
iZone.period = period;
//
// Calculate Each Zones High / Low based on Range ...
double iH = mRangeHigh - mRangeSize * i / Levels();
double iL = mRangeHigh - mRangeSize * (i + 1) / Levels();
//
// Set Zone High Low Properties ...
iZone.low = iL;
iZone.high = iH;
//
// Add Zone to Zone Array Objects ...
mZones.Add(iZone);
}
//
// Calculate Each Zone Ticks ...
int ticksCount = ArraySize(mTicks);
for (int i = 0; i < ticksCount; i++)
{
//
// Retrieve Tick ...
MqlTick iTick = mTicks[i];
//
// Loop through Zones ...
for (int j = 0; j < Levels(); j++)
{
//
// Rejrieve j indexed Zone Object ...
XCTickZone *jZone = mZones.At(j);
//
bool isInRange = IsTickInZoneRange(
iTick,
jZone //
);
if (isInRange)
{
//
jZone.ticks++;
break;
}
}
}
//
// Calculating Zone Percents ...
for (int i = 0; i < Levels(); i++)
{
//
XCTickZone *iZone = mZones.At(i);
//
double percent = CalculateZoneTickPercent(iZone);
iZone.percent = percent;
}
//
// Sort Zones Based on Percents ...
mZones.Sort();
//
mUpper = mRangeHigh;
mLower = mRangeLow;
mType = X_POI_TICKS_ZONES;
mEndBar = endBar;
mStartBar = startBar;
From(startBar.time);
To(endBar.time);
//
result = IsValid();
if (!result)
{
return result;
}
//
// Try to Find Out PERIOD_1M times in each zone ...
datetime to1M = (datetime)((int)endBar.time + PeriodSeconds(period) - 60);
int to1MIndex = iBarShift(
symbol,
forPeriod,
to1M //
);
int from1MIndex = iBarShift(
symbol,
forPeriod,
from //
);
for (int i = from1MIndex; i > to1MIndex; i--)
{
//
XOHCL iBar;
bool isInited = iBar.Init(
symbol,
forPeriod,
i //
);
if (!isInited)
{
continue;
}
ulong iVolume = iTickVolume(
symbol,
forPeriod,
i //
);
//
// Loop through Zones ...
for (int j = 0; j < Levels(); j++)
{
//
XCTickZone *jZone = mZones.At(j);
if (!jZone.IsValid())
{
continue;
}
//
// Check iBar is Inside jZone ...
bool isIBarInside =
iBar.GetUp() < jZone.high &&
iBar.GetDown() > jZone.low;
// iBar.low < jZone.high ||
// iBar.high > jZone.low;
if (isIBarInside)
{
jZone.volume += iVolume;
}
}
}
//
// Calculate Volume Percent ...
for (int i = 0; i < Levels(); i++)
{
//
XCTickZone *iZone = mZones.At(i);
//
if (mVolumes > 0)
{
iZone.volumePercent = (double)(iZone.volume * 100 / mVolumes);
}
}
//
return result;
}
//
// Getter(s) / Setter(s) ...
/**
* Retrieve Zones Count ...
*
* @return ( int )
*/
int Count()
{
return mZones.Total();
}
/**
* Retrieve Specified Sorted Zones ...
*
* @param index: Integer ...
*
* @return ( XCTickZone * )
*/
XCTickZone *GetZone(int index)
{
//
if (!IsValidIndex(index))
{
return NULL;
}
//
return mZones.At(index);
}
/**
* Calculate Liquidity Percent for Specified Direction ...
*
* @param forDirection: ENUM_X_DIRECTION member, Specified Liquidity ...
* @param price: Double, Specified Price ...
*
* @return ( double )
*/
double CalculateLiquidityPercent(
ENUM_X_DIRECTION forDirection,
double price //
)
{
//
double result = 0;
//
int count = Count();
if (price <= 0 ||
!IsValid() ||
!IsValidSize(count) ||
forDirection == X_DIRECTION_ALL ||
forDirection == X_DIRECTION_NONE)
{
return result;
}
//
bool isBullish = forDirection == X_DIRECTION_BULLISH;
//
for (int i = 0; i < count; i++)
{
//
XCTickZone *iZone = GetZone(i);
//
if (iZone.IsValid())
{
//
result += !isBullish &&
price > iZone.high
? iZone.percent
: isBullish &&
price < iZone.low
? iZone.percent
: 0;
}
}
//
return result;
}
//
// Overrides ...
bool IsValid() override
{
//
bool result = false;
//
result =
IsValidFrom() &&
IsValidTwoBarZone() &&
Levels() > 0 &&
mZones.Total() == Levels() &&
mRangeHigh > 0 &&
mRangeLow > 0;
//
return result;
}
//
protected:
//
//
private:
//
// Props ...
//
MqlTick mTicks[];
double mHighs[];
double mLows[];
ulong mVolumes;
ulong mTickVolumes[];
double mRangeHigh;
datetime mRangeHighTime;
double mRangeLow;
datetime mRangeLowTime;
//
int mLevels; // Number of Ticks Levels ...
//
CArrayObj mZones;
/**
* Check a Tick is in a Zone rage or not ...
*
* @param tick: MqlTick instance ...
* @param zone: XCTickZone instance ...
*
* @return ( bool )
*/
bool IsTickInZoneRange(
MqlTick &tick,
XCTickZone *zone //
)
{
//
bool result = false;
//
result =
//
tick.bid >= zone.low &&
tick.bid <= zone.high
//
;
//
return result;
}
/**
* Calculate Zone Tick Percent ...
*
* @param zone: XCTickZone instance ...
* @param normalizationDigits: Integer ...
*
* @return ( double )
*/
double CalculateZoneTickPercent(
XCTickZone *zone,
int normalizationDigits = 2 //
)
{
//
double result = 0;
//
if (normalizationDigits < 2 || normalizationDigits > 5)
{
normalizationDigits = 2;
}
//
int ticksCount = ArraySize(mTicks);
if (ticksCount <= 0)
{
return result;
}
//
result = (double)zone.ticks / ticksCount * 100;
result = NormalizeDouble(result, normalizationDigits);
//
return result;
}
//
};
//
// Trading Day ...
class XCDay : public XCFromToZone
{
//
public:
//
//
// Constructor ...
void XCDay()
{
}
//
// Deconstructor ...
void ~XCDay()
{
}
//
// Tools ...
/**
* Initialize POI ...
*
* @return ( bool )
*/
bool Init()
{
//
bool result = false;
//
result = IsValid();
//
return result;
}
//
// Getter(s) / Setter(s) ...
//
// Overrides ...
//
protected:
//
//
private:
//
//
};
//
// Trading Session ...
class XCSession : public XCFromToZone
{
//
public:
//
//
// Constructor ...
void XCSession()
{
}
//
// Deconstructor ...
void ~XCSession()
{
}
//
// Tools ...
/**
* Initialize POI ...
*
* @return ( bool )
*/
bool Init()
{
//
bool result = false;
//
result = IsValid();
//
return result;
}
//
// Getter(s) / Setter(s) ...
//
// Overrides ...
//
protected:
//
//
private:
//
//
};
//
//
// Model Exists Founded POIs ...
struct XPOIState
{
//
string symbol;
ENUM_TIMEFRAMES period;
datetime time;
//
XCTicksZone *ticksZone; // Ticks Zone ...
//
XCSwing *swingHighs[]; // Holds Founded Swing Highs ...
XCSwing *swingLows[]; // Holds Founded Swing Lows ...
XCMomentumBar *bullishMomentumBars[]; // Holds Founded Bullish Momentum Bars ...
XCMomentumBar *bearishMomentumBars[]; // Holds Founded Bearish Momentum Bars ...
XCRejectionBar *bullishRejectionBars[]; // Holds Founded Bullish Rejection Bars ...
XCRejectionBar *bearishRejectionBars[]; // Holds Founded Bearish Rejection Bars ...
XCSupportZone *supportZones[]; // Holds Founded Support Zones ...
XCResistanceZone *resistanceZones[]; // Holds Founded Resistance Zones ...
XCSupplyZone *supplyZones[]; // Holds Founded Supply Zones ...
XCDemandZone *demandZones[]; // Holds Founded Demand Zones ...
XCOrderBlock *bullishOrderBlocks[]; // Holds Founded Bullish Order Blocks ...
XCOrderBlock *bearishOrderBlocks[]; // Holds Founded Bearish Order Blocks ...
XCFVG *bullishFairValueGaps[]; // Holds Founded Bullish Fair Value Gaps ...
XCFVG *bearishFairValueGaps[]; // Holds Founded Bearish Fair Value Gaps ...
//
// Constructor ...
void XPOIState()
{
Clean();
}
//
// Actions ...
/**
* Cleanup all props ...
*/
void Clean()
{
//
symbol = NULL;
period = NULL;
time = NULL;
//
ticksZone = NULL;
//
Clean(swingHighs);
Clean(swingLows);
Clean(bullishMomentumBars);
Clean(bearishMomentumBars);
Clean(bullishRejectionBars);
Clean(bearishRejectionBars);
Clean(supportZones);
Clean(resistanceZones);
Clean(supplyZones);
Clean(demandZones);
Clean(bullishOrderBlocks);
Clean(bearishOrderBlocks);
Clean(bullishFairValueGaps);
Clean(bearishFairValueGaps);
//
ZeroMemory(this);
}
/**
* Validate ...
*
* @return ( bool )
*/
bool IsValid()
{
//
bool result = false;
//
result =
IsSpecifiedValid(symbol) &&
IsSpecifiedValid(period) &&
IsSpecifiedValid(time);
//
return result;
}
/**
* Check State has Childs or not ...
*
* @return ( bool )
*/
bool HasChild()
{
//
bool result = false;
//
result =
//
IsValidSize(CountSwingHighs()) ||
IsValidSize(CountSwingLows()) ||
IsValidSize(CountBullishMomentumBars()) ||
IsValidSize(CountBearishMomentumBars()) ||
IsValidSize(CountBullishRejectionBars()) ||
IsValidSize(CountBearishRejectionBars()) ||
IsValidSize(CountSupportZones()) ||
IsValidSize(CountResistanceZones()) ||
IsValidSize(CountSupplyZones()) ||
IsValidSize(CountDemandZones()) ||
IsValidSize(CountBullishOrderBlocks()) ||
IsValidSize(CountBearishOrderBlocks()) ||
IsValidSize(CountBullishFairValueGaps()) ||
IsValidSize(CountBearishFairValueGaps())
//
;
//
return result;
}
/**
* Fill Dest State by Current State's Data ...
*
* @param dest: XPOIState instance, reference to specified dest ...
*
*/
void Fill(XPOIState &dest)
{
//
if (!IsValid() ||
!HasChild())
{
return;
}
//
dest.symbol = symbol;
dest.period = period;
dest.time = time;
//
Copy(
swingHighs,
dest.swingHighs,
false //
);
Copy(
swingLows,
dest.swingLows,
false //
);
Copy(
bullishMomentumBars,
dest.bullishMomentumBars,
false //
);
Copy(
bearishMomentumBars,
dest.bearishMomentumBars,
false //
);
Copy(
bullishRejectionBars,
dest.bullishRejectionBars,
false //
);
Copy(
bearishRejectionBars,
dest.bearishRejectionBars,
false //
);
Copy(
supportZones,
dest.supportZones,
false //
);
Copy(
resistanceZones,
dest.resistanceZones,
false //
);
Copy(
supplyZones,
dest.supplyZones,
false //
);
Copy(
demandZones,
dest.demandZones,
false //
);
Copy(
bullishOrderBlocks,
dest.bullishOrderBlocks,
false //
);
Copy(
bearishOrderBlocks,
dest.bearishOrderBlocks,
false //
);
Copy(
bullishFairValueGaps,
dest.bullishFairValueGaps,
false //
);
Copy(
bearishFairValueGaps,
dest.bearishFairValueGaps,
false //
);
//
}
/**
* Calculate Liquidity Percent for Specified Direction ...
*
* @param forDirection: ENUM_X_DIRECTION member, Specified Liquidity ...
* @param price: Double, Specified Price ...
*
* @return ( double )
*/
double CalculateLiquidityPercent(
ENUM_X_DIRECTION forDirection,
double price = 0 //
)
{
//
double result = 0;
//
if (!IsValid() ||
ticksZone == NULL)
{
return result;
}
//
// Normalize Price for Actions ...
if (price <= 0)
{
//
MqlTick mTick;
bool isTickRetrieved = GetTick(
symbol,
mTick //
);
if (isTickRetrieved)
{
price = mTick.bid;
}
}
//
result = ticksZone
.CalculateLiquidityPercent(
forDirection,
price //
);
//
return result;
}
//
// Counters ...
//
int CountSwingHighs()
{
//
int result = 0;
//
if (!IsValid())
{
return result;
}
//
result = ArraySize(swingHighs);
//
return result;
}
//
bool HasSwingHighs()
{
return IsValidSize(CountSwingHighs());
}
//
int CountSwingLows()
{
//
int result = 0;
//
if (!IsValid())
{
return result;
}
//
result = ArraySize(swingLows);
//
return result;
}
//
bool HasSwingLows()
{
return IsValidSize(CountSwingLows());
}
//
int CountBullishMomentumBars()
{
//
int result = 0;
//
if (!IsValid())
{
return result;
}
//
result = ArraySize(bullishMomentumBars);
//
return result;
}
//
bool HasBullishMomentumBars()
{
return IsValidSize(CountBullishMomentumBars());
}
//
int CountBearishMomentumBars()
{
//
int result = 0;
//
if (!IsValid())
{
return result;
}
//
result = ArraySize(bearishMomentumBars);
//
return result;
}
//
bool HasBearishMomentumBars()
{
return IsValidSize(CountBearishMomentumBars());
}
//
int CountBullishRejectionBars()
{
//
int result = 0;
//
if (!IsValid())
{
return result;
}
//
result = ArraySize(bullishRejectionBars);
//
return result;
}
//
bool HasBullishRejectionBars()
{
return IsValidSize(CountBullishRejectionBars());
}
//
int CountBearishRejectionBars()
{
//
int result = 0;
//
if (!IsValid())
{
return result;
}
//
result = ArraySize(bearishRejectionBars);
//
return result;
}
//
bool HasBearishRejectionBars()
{
return IsValidSize(CountBearishRejectionBars());
}
//
int CountSupportZones()
{
//
int result = 0;
//
if (!IsValid())
{
return result;
}
//
result = ArraySize(supportZones);
//
return result;
}
//
bool HasSupportZones()
{
return IsValidSize(CountSupportZones());
}
//
int CountResistanceZones()
{
//
int result = 0;
//
if (!IsValid())
{
return result;
}
//
result = ArraySize(resistanceZones);
//
return result;
}
//
bool HasResistanceZones()
{
return IsValidSize(CountResistanceZones());
}
//
int CountSupplyZones()
{
//
int result = 0;
//
if (!IsValid())
{
return result;
}
//
result = ArraySize(supplyZones);
//
return result;
}
//
bool HasSupplyZones()
{
return IsValidSize(CountSupplyZones());
}
//
int CountDemandZones()
{
//
int result = 0;
//
if (!IsValid())
{
return result;
}
//
result = ArraySize(demandZones);
//
return result;
}
//
bool HasDemandZones()
{
return IsValidSize(CountDemandZones());
}
//
int CountBullishOrderBlocks()
{
//
int result = 0;
//
if (!IsValid())
{
return result;
}
//
result = ArraySize(bullishOrderBlocks);
//
return result;
}
//
bool HasBullishOrderBlocks()
{
return IsValidSize(CountBullishOrderBlocks());
}
//
int CountBearishOrderBlocks()
{
//
int result = 0;
//
if (!IsValid())
{
return result;
}
//
result = ArraySize(bearishOrderBlocks);
//
return result;
}
//
bool HasBearishOrderBlocks()
{
return IsValidSize(CountBearishOrderBlocks());
}
//
int CountBullishFairValueGaps()
{
//
int result = 0;
//
if (!IsValid())
{
return result;
}
//
result = ArraySize(bullishFairValueGaps);
//
return result;
}
//
bool HasBullishFairValueGaps()
{
return IsValidSize(CountBullishFairValueGaps());
}
//
int CountBearishFairValueGaps()
{
//
int result = 0;
//
if (!IsValid())
{
return result;
}
//
result = ArraySize(bearishFairValueGaps);
//
return result;
}
//
bool HasBearishFairValueGaps()
{
return IsValidSize(CountBearishFairValueGaps());
}
//
};
//
// Consolidation Zone ...
struct XConsolidationZone
{
//
// Props ...
//
string symbol; // Symbol ...
ENUM_TIMEFRAMES period; // Period ...
//
double upper; // Upper ...
double lower; // Lower ...
//
datetime initTime;
int loopback; // Loopback ...
//
ENUM_X_DIRECTION breakDir; // Break Direction ...
XOHCL breakerBar; // Breaker Bar ...
//
// Constructor ...
XConsolidationZone()
{
Clean();
}
//
// Tools ...
/**
* Initialize Zone ...
*
* @param _symbol: String ...
* @param _period: ENUM_TIMEFRAMES member ...
* @param _upper: Double ...
* @param _lower: Double ...
* @param _loopback: Integer ...
*
* @return ( bool )
*/
bool Init(
string _symbol,
ENUM_TIMEFRAMES _period,
double _upper,
double _lower,
int _loopback //
)
{
//
bool result = false;
//
_symbol = NormalizeSymbol(_symbol);
_period = NormalizePeriod(_period);
//
result =
//
_upper > 0 &&
_lower > 0 &&
_loopback > 0
//
;
if (!result)
{
return result;
}
//
upper = _upper;
lower = _lower;
symbol = _symbol;
period = _period;
loopback = _loopback;
//
result = IsValid();
if (result)
{
initTime = TimeCurrent();
}
//
return result;
}
/**
* Update Breaked State ...
*/
void Update()
{
//
if (!IsValid())
{
return;
}
//
if (IsBreaked())
{
return;
}
//
XOHCL cBar;
bool isInited = cBar.Init(
symbol,
period,
0 //
);
if (!isInited)
{
return;
}
//
XOHCL pBar;
isInited = cBar.GetPreviousBar(pBar);
if (!isInited)
{
return;
}
//
// Check Consolidation Hounts ...
bool isHountTop = cBar.high > upper &&
cBar.low < upper &&
cBar.GetUp() < upper;
bool isHountBottom = cBar.low < lower &&
cBar.high > lower &&
cBar.GetDown() > lower;
bool isHounted = isHountTop ||
isHountBottom;
if (isHounted)
{
//
if (isHountTop)
{
upper = cBar.high;
}
//
if (isHountBottom)
{
lower = cBar.low;
}
//
return;
}
//
// Check Consolidation Breaks ...
bool isBreakTop = (cBar.GetUp() > upper &&
cBar.GetDown() < upper) ||
(cBar.low > upper &&
cBar.high > upper);
bool isBreakBottom = (cBar.GetDown() < lower &&
cBar.GetUp() > lower) ||
(cBar.high < lower &&
cBar.low < lower);
bool isBreaked = isBreakTop ||
isBreakBottom;
if (!isBreaked)
{
return;
}
//
// Calculate Break Direction ...
breakerBar = cBar;
breakDir = isBreakTop
? X_DIRECTION_BULLISH
: isBreakBottom
? X_DIRECTION_BEARISH
: X_DIRECTION_NONE;
}
/**
* Cleanup ...
*/
void Clean()
{
//
upper = 0;
lower = 0;
loopback = 0;
symbol = NULL;
period = NULL;
initTime = NULL;
breakerBar.Clean();
breakDir = X_DIRECTION_NONE;
//
ZeroMemory(this);
}
/**
* Validate ...
*
* @return ( bool )
*/
bool IsValid()
{
//
bool result = false;
//
result =
//
IsValid(symbol) &&
IsValid(period) &&
upper > 0 &&
lower > 0 &&
loopback > 0
//
;
//
return result;
}
/**
* Check Zone is Breaked or not ...
*
* @return ( bool )
*/
bool IsBreaked()
{
//
bool result = false;
//
result = breakerBar.IsValid() &&
HasDirection(breakDir);
//
return result;
}
/**
* Detect Supply Zone if Exists ...
*
* @return ( bool )
*/
bool HasSupplyZone(
XCSupplyZone *&zone //
)
{
//
bool result = false;
//
result = IsBreaked() &&
breakDir == X_DIRECTION_BEARISH;
if (!result)
{
return result;
}
//
// Implment Zone Finding ...
int index = breakerBar.Index();
int hhIDX = iHighest(
symbol,
period,
MODE_HIGH,
loopback,
index //
);
result = IsValidIndex(hhIDX);
if (!result)
{
return result;
}
//
XOHCL hhBar;
result = hhBar.Init(
symbol,
period,
hhIDX //
);
if (!result)
{
return result;
}
//
zone = new XCSupplyZone();
result = zone.Init(
hhBar,
loopback //
);
//
return result;
}
/**
* Detect Demand Zone if Exists ...
*
* @return ( bool )
*/
bool HasDemandZone(
XCDemandZone *&zone //
)
{
//
bool result = false;
//
result = IsBreaked() &&
breakDir == X_DIRECTION_BULLISH;
if (!result)
{
return result;
}
//
// Implment Zone Finding ...
int index = breakerBar.Index();
int llIDX = iLowest(
symbol,
period,
MODE_LOW,
loopback,
index //
);
result = IsValidIndex(llIDX);
if (!result)
{
return result;
}
//
XOHCL llBar;
result = llBar.Init(
symbol,
period,
llIDX //
);
if (!result)
{
return result;
}
//
zone = new XCDemandZone();
result = zone.Init(
llBar,
loopback //
);
//
return result;
}
/**
* Retrieve Start Time ...
*
* @return ( datetime )
*/
datetime From()
{
//
datetime result = NULL;
//
if (!IsValid())
{
return result;
}
//
int startIndex = iBarShift(
symbol,
period,
initTime //
);
//
result = iTime(
symbol,
period,
loopback + startIndex //
);
//
return result;
}
/**
* Retrieve Unique Identifier ...
*
* @return ( string )
*/
string GetTag()
{
//
string result =
//
GetTypeName(this) + "_" +
symbol + "_" +
ToString(period) + "_" +
ToString(upper) + "_" +
ToString(lower)
//
;
//
return result;
}
//
};
struct XBoxZone
{
//
// Props ...
string symbol;
ENUM_TIMEFRAMES period;
//
double upper;
double lower;
//
datetime from;
datetime to;
//
string type;
ENUM_X_DIRECTION dir;
//
// Constructor ...
XBoxZone()
{
Clean();
}
//
// Tools ...
/**
* Cleanup Model ...
*/
void Clean()
{
//
upper = 0;
lower = 0;
to = NULL;
from = NULL;
symbol = NULL;
period = NULL;
dir = X_DIRECTION_NONE;
//
ZeroMemory(this);
}
/**
* Validate Model ...
*
* @return ( bool )
*/
bool IsValid()
{
//
bool result = false;
//
result =
//
upper > 0 &&
lower > 0 &&
from < to &&
IsValid(to) &&
upper > lower &&
IsValid(from) &&
IsValid(symbol) &&
IsValid(period)
//
;
//
return result;
}
/**
* Check Box is Same as another ...
*
* @param box: XBoxZone instance Reference ...
*
* @return ( bool )
*/
bool IsSame(XBoxZone &box)
{
//
bool result = false;
//
result = IsValid() &&
box.IsValid();
if (!result)
{
return result;
}
//
result =
//
dir == box.dir &&
from == box.from &&
type == box.type &&
upper == box.upper &&
lower == box.lower &&
symbol == box.symbol &&
period == box.period
//
;
//
return result;
}
};
//
// Extensions ...
/**
* Converts ENUM_XPOI value to String Representation ...
*
* @param value: ENUM_XPOI member ...
*
* @return ( string )
*/
string ToString(ENUM_XPOIS value)
{
//
string result = NULL;
//
switch (value)
{
//
case X_POI_TRADING_DAY:
result = "XTDAY";
break;
//
case X_POI_MARKET_SESSION:
result = "XMSESS";
break;
//
case X_POI_MOMENTUM_BAR:
result = "XMNTMB";
break;
//
case X_POI_REJECTION_BAR:
result = "XRJCTB";
break;
//
case X_POI_SWING_HIGH:
result = "XSPH";
break;
//
case X_POI_SWING_LOW:
result = "XSPL";
break;
//
case X_POI_SUPPORT_ZONE:
result = "XSUP";
break;
//
case X_POI_RESISTANCE_ZONE:
result = "XRES";
break;
//
case X_POI_SUPPLY_ZONE:
result = "XSUPPLY";
break;
//
case X_POI_DEMAND_ZONE:
result = "XDEMAND";
break;
//
case X_POI_BULLISH_ORDERBLOCK:
result = "XBULLOB";
break;
//
case X_POI_BEARISH_ORDERBLOCK:
result = "XBEAROB";
break;
//
case X_POI_BULLISH_FVG:
result = "XBULLFVG";
break;
//
case X_POI_BEARISH_FVG:
result = "XBEARFVG";
break;
//
case X_POI_TICKS_ZONES:
result = "XTKSZ";
break;
}
//
return result;
}
/**
* Converts ENUM_XSESSION value to String Representation ...
*
* @param value: ENUM_XSESSION member ...
*
* @return ( string )
*/
string ToString(ENUM_XSESSION value)
{
//
string result = NULL;
//
switch (value)
{
//
case X_SYDNEY:
result = "Sydney";
break;
//
case X_TOKYO:
result = "Tokyo";
break;
//
case X_FRANKFORT:
result = "FrankGurt";
break;
//
case X_LONDON:
result = "London";
break;
//
case X_NEW_YORK:
result = "NewYork";
break;
}
//
return result;
}
/**
* Generate General Event Messages ...
*
* @param value: ENUM_XPOI_EVENTS member ...
*
* @return ( string )
*/
string ToString(ENUM_XPOI_EVENTS value)
{
//
string result = NULL;
//
switch (value)
{
//
case X_TRADE_DAY_FIRST_BAR:
result = "First Bar of Day";
break;
//
case X_TRADE_DAY_LAST_BAR:
result = "Last Bar of Day";
break;
//
case X_SESSION_FIRST_BAR:
result = "First Bar of Session";
break;
//
case X_SESSION_LAST_BAR:
result = "Last Bar of Session";
break;
//
case X_BULLISH_MOMENTUM_BAR_DETECTED:
result = "Bullish Momentum Bar Detected";
break;
//
case X_BEARISH_MOMENTUM_BAR_DETECTED:
result = "Bearish Momentum Bar Detected";
break;
//
case X_BULLISH_REJECTION_BAR_DETECTED:
result = "Bullish Rejection Bar Detected";
break;
//
case X_BEARISH_REJECTION_BAR_DETECTED:
result = "Bearish Rejection Bar Detected";
break;
//
case X_SWING_HIGH_DETECTED:
result = "Swing High Detected";
break;
//
case X_SWING_LOW_DETECTED:
result = "Swing Low Detected";
break;
//
case X_SUPPORT_ZONE_DETECTED:
result = "Support Zone Detected";
break;
//
case X_RESISTANCE_ZONE_DETECTED:
result = "Resistance Zone Detected";
break;
//
case X_SUPPLY_ZONE_DETECTED:
result = "Supply Zone Detected";
break;
//
case X_DEMAND_ZONE_DETECTED:
result = "Demand Zone Detected";
break;
//
case X_BULLISH_ORDERBLOCK_DETECTED:
result = "Bullish Order Block Detected";
break;
//
case X_BEARISH_ORDERBLOCK_DETECTED:
result = "Bearish Orer Block Detected";
break;
//
case X_BULLISH_FVG_DETECTED:
result = "Bullish FVG Detected";
break;
//
case X_BEARISH_FVG_DETECTED:
result = "Bearish FVg Detected";
break;
}
//
return result;
}
//
//
//
/**
* Combine a Collection of States into dest ...
*
* @param dest: XPOIState instance ...
* @param source: XPOIState Collection ...
*/
void CombineStates(
XPOIState &dest,
XPOIState &source[] //
)
{
//
dest.Clean();
//
int count = ArraySize(source);
if (!IsValidSize(count))
{
return;
}
//
for (int i = 0; i < count; i++)
{
//
XPOIState iState = source[i];
//
if (dest.ticksZone == NULL)
{
dest.ticksZone = iState.ticksZone;
}
//
Copy(
iState.swingHighs,
dest.swingHighs,
false //
);
//
Copy(
iState.swingLows,
dest.swingLows,
false //
);
//
Copy(
iState.bullishMomentumBars,
dest.bullishMomentumBars,
false //
);
//
Copy(
iState.bearishMomentumBars,
dest.bearishMomentumBars,
false //
);
//
Copy(
iState.bullishRejectionBars,
dest.bullishRejectionBars,
false //
);
//
Copy(
iState.bearishRejectionBars,
dest.bearishRejectionBars,
false //
);
//
Copy(
iState.supportZones,
dest.supportZones,
false //
);
//
Copy(
iState.resistanceZones,
dest.resistanceZones,
false //
);
//
Copy(
iState.supplyZones,
dest.supplyZones,
false //
);
//
Copy(
iState.demandZones,
dest.demandZones,
false //
);
//
Copy(
iState.bullishOrderBlocks,
dest.bullishOrderBlocks,
false //
);
//
Copy(
iState.bearishOrderBlocks,
dest.bearishOrderBlocks,
false //
);
//
Copy(
iState.bullishFairValueGaps,
dest.bullishFairValueGaps,
false //
);
//
Copy(
iState.bearishFairValueGaps,
dest.bearishFairValueGaps,
false //
);
//
}
}
template <typename T>
bool ToZone(
T *&source[],
XCZone *&dest[] //
)
{
//
bool result = false;
//
Clean(dest);
//
int count = ArraySize(source);
result = IsValidSize(count);
if (!result)
{
return result;
}
//
for (int i = 0; i < count; i++)
{
//
T *item = source[i];
//
if (item != NULL)
{
//
Add(
(XCZone *)item,
dest //
);
}
}
//
int destCount = ArraySize(dest);
result = IsValidSize(destCount);
//
return result;
}
template <typename T>
bool ToBox(
T *&source[],
XBoxZone &dest[] //
)
{
//
bool result = false;
//
Clean(dest);
//
int count = ArraySize(source);
result = IsValidSize(count);
if (!result)
{
return result;
}
//
for (int i = 0; i < count; i++)
{
//
T *item = source[i];
//
if (item != NULL)
{
//
XBoxZone iBox;
bool hasBox = ToBox(
iBox,
item //
);
//
if (hasBox)
{
//
AddRef(
iBox,
dest //
);
}
}
}
//
int destCount = ArraySize(dest);
result = IsValidSize(destCount);
//
return result;
}
template <typename T>
int GetOldest(
T *&sourec[] //
)
{
//
int result = -1;
//
int count = ArraySize(source);
if (!IsValidSize(count))
{
return result;
}
//
XBoxZone boxes[];
bool isConverted = ToBox(
source,
boxes //
);
if (!isConverted)
{
return result;
}
//
int boxesCount = ArraySize(boxes);
//
if (count != boxesCount)
{
return result;
}
//
result = GetOldest(boxes);
//
Clean(boxes);
//
return result;
}
template <typename T>
int GetYoungest(
T *&source[] //
)
{
//
int result = -1;
//
int count = ArraySize(source);
if (!IsValidSize(count))
{
return result;
}
//
XBoxZone boxes[];
bool isConverted = ToBox(
source,
boxes //
);
if (!isConverted)
{
return result;
}
//
int boxesCount = ArraySize(boxes);
//
if (count != boxesCount)
{
return result;
}
//
result = GetYoungest(boxes);
//
Clean(boxes);
//
return result;
}
template <typename T>
int GetLowest(
T *&source[] //
)
{
//
int result = -1;
//
int count = ArraySize(source);
if (!IsValidSize(count))
{
return result;
}
//
XBoxZone boxes[];
bool isConverted = ToBox(
source,
boxes //
);
if (!isConverted)
{
return result;
}
//
int boxesCount = ArraySize(boxes);
//
if (count != boxesCount)
{
return result;
}
//
result = GetLowest(boxes);
//
Clean(boxes);
//
return result;
}
template <typename T>
int GetHighest(
T *&source[] //
)
{
//
int result = -1;
//
int count = ArraySize(source);
if (!IsValidSize(count))
{
return result;
}
//
XBoxZone boxes[];
bool isConverted = ToBox(
source,
boxes //
);
if (!isConverted)
{
return result;
}
//
int boxesCount = ArraySize(boxes);
//
if (count != boxesCount)
{
return result;
}
//
result = GetHighest(boxes);
//
Clean(boxes);
//
return result;
}
template <typename T>
bool IsSame(
T *source,
T *dest //
)
{
//
bool result = false;
//
XBoxZone sourceBox;
result = ToBox(
sourceBox,
source //
);
if (!result)
{
return result;
}
//
XBoxZone destBox;
result = ToBox(
destBox,
dest //
);
if (!result)
{
return result;
}
//
result = sourceBox.IsSame(destBox);
//
return result;
}
template <typename T, typename F>
bool IsSameDiff(
T *source,
F *dest //
)
{
//
bool result = false;
//
XBoxZone sourceBox;
result = ToBox(
sourceBox,
source //
);
if (!result)
{
return result;
}
//
XBoxZone destBox;
result = ToBox(
destBox,
dest //
);
if (!result)
{
return result;
}
//
result = sourceBox.IsSame(destBox);
//
return result;
}
template <typename T>
bool IsBelow(
T *source,
T *dest,
bool ignoreInside = false //
)
{
//
bool result = false;
//
XBoxZone sourceBox;
result = ToBox(
sourceBox,
source //
);
if (!result)
{
return result;
}
//
XBoxZone destBox;
result = ToBox(
destBox,
dest //
);
if (!result)
{
return result;
}
//
result = IsBoxBelow(
sourceBox,
destBox,
ignoreInside //
);
//
return result;
}
template <typename T, typename F>
bool IsBelowDiff(
T *source,
F *dest,
bool ignoreInside = false //
)
{
//
bool result = false;
//
XBoxZone sourceBox;
result = ToBox(
sourceBox,
source //
);
if (!result)
{
return result;
}
//
XBoxZone destBox;
result = ToBox(
destBox,
dest //
);
if (!result)
{
return result;
}
//
result = IsBoxBelow(
sourceBox,
destBox,
ignoreInside //
);
//
return result;
}
template <typename T>
bool IsAbove(
T *source,
T *dest,
bool ignoreInside = false //
)
{
//
bool result = false;
//
XBoxZone sourceBox;
result = ToBox(
sourceBox,
source //
);
if (!result)
{
return result;
}
//
XBoxZone destBox;
result = ToBox(
destBox,
dest //
);
if (!result)
{
return result;
}
//
result = IsBoxAbove(
sourceBox,
destBox,
ignoreInside //
);
//
return result;
}
template <typename T, typename F>
bool IsAboveDiff(
T *source,
F *dest,
bool ignoreInside = false //
)
{
//
bool result = false;
//
XBoxZone sourceBox;
result = ToBox(
sourceBox,
source //
);
if (!result)
{
return result;
}
//
XBoxZone destBox;
result = ToBox(
destBox,
dest //
);
if (!result)
{
return result;
}
//
result = IsBoxAbove(
sourceBox,
destBox,
ignoreInside //
);
//
return result;
}
template <typename T>
bool IsInside(
T *source,
T *dest //
)
{
//
bool result = false;
//
XBoxZone sourceBox;
result = ToBox(
sourceBox,
source //
);
if (!result)
{
return result;
}
//
XBoxZone destBox;
result = ToBox(
destBox,
dest //
);
if (!result)
{
return result;
}
//
result = IsBoxInside(
sourceBox,
destBox //
);
//
return result;
}
template <typename T, typename F>
bool IsInsideDiff(
T *source,
F *dest //
)
{
//
bool result = false;
//
XBoxZone sourceBox;
result = ToBox(
sourceBox,
source //
);
if (!result)
{
return result;
}
//
XBoxZone destBox;
result = ToBox(
destBox,
dest //
);
if (!result)
{
return result;
}
//
result = IsBoxInside(
sourceBox,
destBox //
);
//
return result;
}
template <typename T>
bool FindIndex(
int &index,
T *item,
T *&items[] //
)
{
//
bool result = false;
//
index = -1;
//
XBoxZone itemBox;
result = ToBox(
itemBox,
item //
);
if (!result)
{
return result;
}
//
XBoxZone itemsBox[];
result = ToBox(
items,
itemsBox //
);
if (!result)
{
return result;
}
//
result = FindBoxIndex(
index,
itemBox,
itemsBox //
);
//
return result;
}
template <typename T>
bool IsInside(
double value,
T *source //
)
{
//
bool result = false;
//
XBoxZone sourceBox;
result = ToBox(
sourceBox,
source //
);
if (!result)
{
return result;
}
//
result = IsInsideBox(
value,
sourceBox //
);
//
return result;
}
template <typename T>
bool IsAbove(
double value,
T *source //
)
{
//
bool result = false;
//
XBoxZone sourceBox;
result = ToBox(
sourceBox,
source //
);
if (!result)
{
return result;
}
//
result = IsAboveBox(
value,
sourceBox //
);
//
return result;
}
template <typename T>
bool IsBelow(
double value,
T *source //
)
{
//
bool result = false;
//
XBoxZone sourceBox;
result = ToBox(
sourceBox,
source //
);
if (!result)
{
return result;
}
//
result = IsBelowBox(
value,
sourceBox //
);
//
return result;
}
template <typename T>
bool IsReject(
ENUM_X_DIRECTION forDir,
XOHCL &bar,
T *source,
XPOIState &state,
XOHCL &swingBar,
XOHCL &rejectBar,
XOHCL &breakerBar,
XOHCL &momentumBar,
bool forceSwingRejection = true //
)
{
//
bool result = false;
//
XBoxZone sourceBox;
result = ToBox(
sourceBox,
source //
);
if (!result)
{
return result;
}
//
result = IsRejectBox(
forDir,
bar,
sourceBox,
state,
swingBar,
rejectBar,
breakerBar,
momentumBar,
forceSwingRejection //
);
//
return result;
}
template <typename T>
void UpdateTo(
T *&source[],
datetime time = NULL //
)
{
//
if (!IsValid(time))
{
time = TimeCurrent();
}
//
int count = ArraySize(source);
if (!IsValidSize(count))
{
return;
}
//
for (int i = 0; i < count; i++)
{
source[i].To(time);
}
}
/**
* Find Specified Box Index inside a Collection of Boxes ...
*
* @param box: XBoxZone instance Reference ...
* @param boxes: XBoxZone instance Reference Collection ...
*
* @return ( int )
*/
bool FindBoxIndex(
int &index,
XBoxZone &box,
XBoxZone &boxes[] //
)
{
//
bool result = false;
//
index = -1;
//
int count = ArraySize(boxes);
result = box.IsValid() &&
IsValidSize(count);
if (!result)
{
return result;
}
//
for (int i = 0; i < count; i++)
{
//
XBoxZone iBox = boxes[i];
//
bool isSame = box.IsSame(iBox);
if (isSame)
{
//
index = i;
break;
}
}
//
result = IsValidIndex(index);
//
return result;
}
/**
* Check Source Box is Below Dest ...
*
* @param source: XBoxZone instance Reference ...
* @param dest: XBoxZone instance Reference ...
* @param ignoreInside: bool ...
*
* @return ( bool )
*/
bool IsBoxBelow(
XBoxZone &source,
XBoxZone &dest,
bool ignoreInside = false //
)
{
//
bool result = false;
//
result = source.IsValid() &&
dest.IsValid() &&
!source.IsSame(dest);
if (!result)
{
return result;
}
//
if (!ignoreInside)
{
result = source.upper < dest.lower;
}
else
{
result = (source.upper < dest.lower ||
source.upper >= dest.upper) &&
source.lower < dest.lower;
}
//
return result;
}
/**
* Check Source Box is Above Dest ...
*
* @param source: XBoxZone instance Reference ...
* @param dest: XBoxZone instance Reference ...
* @param ignoreInside: bool ...
*
* @return ( bool )
*/
bool IsBoxAbove(
XBoxZone &source,
XBoxZone &dest,
bool ignoreInside = false //
)
{
//
bool result = false;
//
result = source.IsValid() &&
dest.IsValid() &&
!source.IsSame(dest);
if (!result)
{
return result;
}
//
if (!ignoreInside)
{
result = source.lower > dest.upper;
}
else
{
result = (source.lower > dest.upper ||
source.lower <= dest.upper) &&
source.upper > dest.upper;
}
//
return result;
}
/**
* Check Source Box is Inside Dest ...
*
* @param source: XBoxZone instance Reference ...
* @param dest: XBoxZone instance Reference ...
*
* @return ( bool )
*/
bool IsBoxInside(
XBoxZone &source,
XBoxZone &dest //
)
{
//
bool result = false;
//
result = source.IsValid() &&
dest.IsValid() &&
!source.IsSame(dest);
if (!result)
{
return result;
}
//
result = source.lower >= dest.lower &&
source.upper <= dest.upper;
//
return result;
}
/**
* Check Value is Inside Specified Box ...
*
* @param value: double ...
* @param box: XCBozZone instance Reference ...
*
* @return ( bool )
*/
bool IsInsideBox(
double value,
XBoxZone &box //
)
{
//
bool result = false;
//
result = value > 0 &&
box.IsValid() &&
value <= box.upper &&
value >= box.lower;
//
return result;
}
/**
* Check Value is Above Specified Box ...
*
* @param value: double ...
* @param box: XCBozZone instance Reference ...
*
* @return ( bool )
*/
bool IsAboveBox(
double value,
XBoxZone &box //
)
{
//
bool result = false;
//
result = value > 0 &&
box.IsValid() &&
value > box.upper;
//
return result;
}
/**
* Check Value is Below Specified Box ...
*
* @param value: double ...
* @param box: XCBozZone instance Reference ...
*
* @return ( bool )
*/
bool IsBelowBox(
double value,
XBoxZone &box //
)
{
//
bool result = false;
//
result = value > 0 &&
box.IsValid() &&
value < box.lower;
//
return result;
}
//
bool IsRejectBox(
ENUM_X_DIRECTION &forDir,
XOHCL &bar,
XBoxZone &box,
XPOIState &state,
XOHCL &swingBar,
XOHCL &rejectBar,
XOHCL &breakerBar,
XOHCL &momentumBar,
bool forceSwingRejection = true //
)
{
//
bool result = false;
//
swingBar.Clean();
rejectBar.Clean();
breakerBar.Clean();
momentumBar.Clean();
//
result = bar.IsValid() &&
box.IsValid() &&
state.IsValid() &&
state.HasChild() &&
HasDirection(forDir);
if (!result)
{
return result;
}
//
bool isBullish = IsBullish(forDir);
//
double appliedPrice =
isBullish
? box.upper
: box.lower;
//
// Fetch Required Bars ...
//
XOHCL cBar;
result = bar.GetPreviousBar(cBar);
if (!result)
{
return result;
}
//
XOHCL pBar;
result = cBar.GetPreviousBar(pBar);
if (!result)
{
return result;
}
//
XOHCL ppBar;
result = pBar.GetPreviousBar(ppBar);
if (!result)
{
return result;
}
//
// Check Directional Swing Type ...
ENUM_X_SWING_TYPE swingType =
isBullish
? X_SWING_LOW
: X_SWING_HIGH;
//
bool isSwingLow =
//
pBar.low < ppBar.low &&
pBar.low < cBar.low &&
bar.open > pBar.low &&
//
appliedPrice > pBar.low &&
appliedPrice < pBar.GetDown()
//
;
//
bool isSwingHigh =
//
pBar.high > ppBar.high &&
pBar.high > cBar.high &&
bar.open < pBar.high &&
//
appliedPrice < pBar.high &&
appliedPrice > pBar.GetUp()
//
;
//
// Force Rejected By Swing ...
if (forceSwingRejection)
{
//
result = swingType == X_SWING_HIGH
? isSwingHigh
: swingType == X_SWING_LOW
? isSwingLow
: false;
if (!result)
{
return result;
}
}
//
bool hasValidSwing =
isBullish
? isSwingLow
: isSwingHigh;
if (hasValidSwing)
{
swingBar = pBar;
}
//
bool isCBarBreaked = IsBarBreak(
appliedPrice,
forDir,
cBar //
);
if (isCBarBreaked)
{
breakerBar = cBar;
}
bool isPBarBreaked = IsBarBreak(
appliedPrice,
forDir,
pBar //
);
if (isPBarBreaked)
{
breakerBar = pBar;
}
bool isPPBarBreaked = IsBarBreak(
appliedPrice,
forDir,
ppBar //
);
if (isPPBarBreaked)
{
breakerBar = ppBar;
}
bool isBoxBreaked = isCBarBreaked ||
isPBarBreaked ||
isPPBarBreaked;
//
bool isCBarRejected = IsBarReject(
appliedPrice,
forDir,
cBar //
);
if (isCBarRejected)
{
rejectBar = cBar;
}
bool isPBarRejected = IsBarReject(
appliedPrice,
forDir,
pBar //
);
if (isPBarRejected)
{
rejectBar = pBar;
}
bool isPPBarRejected = IsBarReject(
appliedPrice,
forDir,
ppBar //
);
if (isPPBarRejected)
{
rejectBar = ppBar;
}
bool isBoxRejected = isCBarRejected ||
isPBarRejected ||
isPPBarRejected;
//
int count = 0;
//
bool hasRejectionBar = false;
if (isBullish)
{
//
count = state.CountBullishRejectionBars();
for (int i = 0; i < count; i++)
{
//
XCRejectionBar *iZone = state.bullishRejectionBars[i];
//
XOHCL iBar;
bool isFilled = iZone.FillBar(iBar);
if (!isFilled)
{
continue;
}
//
int iBarIndex = iBar.Index();
//
hasRejectionBar =
//
(iBarIndex == cBar.Index() ||
iBarIndex == pBar.Index())
//
;
if (hasRejectionBar)
{
//
if (!rejectBar.IsValid())
{
rejectBar = iBar;
}
//
break;
}
}
}
else
{
//
count = state.CountBearishRejectionBars();
for (int i = 0; i < count; i++)
{
//
XCRejectionBar *iZone = state.bearishRejectionBars[i];
//
XOHCL iBar;
bool isFilled = iZone.FillBar(iBar);
if (!isFilled)
{
continue;
}
//
int iBarIndex = iBar.Index();
//
hasRejectionBar =
//
(iBarIndex == cBar.Index() ||
iBarIndex == pBar.Index())
//
;
if (hasRejectionBar)
{
//
if (!rejectBar.IsValid())
{
rejectBar = iBar;
}
//
break;
}
}
}
//
bool hasMomentumBar = false;
if (isBullish)
{
//
count = state.CountBullishMomentumBars();
for (int i = 0; i < count; i++)
{
//
XCMomentumBar *iZone = state.bullishMomentumBars[i];
//
XOHCL iBar;
bool isFilled = iZone.FillBar(iBar);
if (!isFilled)
{
continue;
}
//
int iBarIndex = iBar.Index();
//
hasMomentumBar =
//
(iBarIndex == cBar.Index() ||
iBarIndex == pBar.Index())
//
;
if (hasMomentumBar)
{
//
if (!momentumBar.IsValid())
{
momentumBar = iBar;
}
//
break;
}
}
}
else
{
//
count = state.CountBearishMomentumBars();
for (int i = 0; i < count; i++)
{
//
XCMomentumBar *iZone = state.bearishMomentumBars[i];
//
XOHCL iBar;
bool isFilled = iZone.FillBar(iBar);
if (!isFilled)
{
continue;
}
//
int iBarIndex = iBar.Index();
//
hasMomentumBar =
//
(iBarIndex == cBar.Index() ||
iBarIndex == pBar.Index())
//
;
if (hasMomentumBar)
{
//
if (!momentumBar.IsValid())
{
momentumBar = iBar;
}
//
break;
}
}
}
//
bool hasSwing = false;
if (isBullish)
{
//
count = state.CountSwingLows();
for (int i = 0; i < count; i++)
{
//
XCSwing *iSwing = state.swingLows[i];
//
XOHCL iBar;
bool isFilled = iSwing.FillBar(iBar);
if (!isFilled)
{
continue;
}
//
int iBarIndex = iBar.Index();
//
hasSwing =
//
(iBarIndex == cBar.Index() ||
iBarIndex == pBar.Index())
//
;
if (hasSwing)
{
//
if (!swingBar.IsValid())
{
swingBar = iBar;
}
//
break;
}
}
}
else
{
//
count = state.CountSwingHighs();
for (int i = 0; i < count; i++)
{
//
XCSwing *iSwing = state.swingHighs[i];
//
XOHCL iBar;
bool isFilled = iSwing.FillBar(iBar);
if (!isFilled)
{
continue;
}
//
int iBarIndex = iBar.Index();
//
hasSwing =
//
(iBarIndex == cBar.Index() ||
iBarIndex == pBar.Index())
//
;
if (hasSwing)
{
//
if (!swingBar.IsValid())
{
swingBar = iBar;
}
//
break;
}
}
}
//
bool hasRequiredValidations =
//
(hasRejectionBar ||
hasMomentumBar)
//
||
//
(hasRejectionBar ||
hasSwing)
//
||
//
(hasMomentumBar ||
hasSwing)
//
;
//
result =
//
(isBoxBreaked &&
(hasRequiredValidations ||
hasValidSwing))
//
||
//
(isBoxRejected &&
(hasRequiredValidations ||
hasValidSwing))
//
;
//
return result;
}
/**
* Converts a Consolidation Zone ...
*
* @param zone: XConsolidationZone instance Reference ...
* @param dest: XCZone pointer Reference ...
*
* @return ( bool )
*/
bool ToZone(
XConsolidationZone &zone,
XCZone *&dest //
)
{
//
bool result = false;
//
dest = NULL;
//
result = zone.IsValid();
if (!result)
{
return result;
}
//
dest = new XCZone();
dest.Upper(zone.upper);
dest.Lower(zone.lower);
result = dest.IsValidBoundary();
//
return result;
}
/**
* Converts to XBoxZone ...
*
* @return ( bool )
*/
bool ToBox(
XBoxZone &box,
XCOrderBlock *item //
)
{
//
bool result = false;
//
box.Clean();
//
result = item != NULL &&
item.IsValid();
if (!result)
{
return result;
}
//
box.to = item.To();
box.from = item.From();
box.upper = item.Upper();
box.lower = item.Lower();
box.symbol = item.GetSymbol();
box.period = item.GetPeriod();
box.type = item.TypeAsString();
box.dir = item.IsBullish()
? X_DIRECTION_BULLISH
: X_DIRECTION_BEARISH;
//
result = box.IsValid();
//
return result;
}
/**
* Converts to XBoxZone ...
*
* @return ( bool )
*/
bool ToBox(
XBoxZone &box,
XCFVG *item //
)
{
//
bool result = false;
//
box.Clean();
//
result = item != NULL &&
item.IsValid();
if (!result)
{
return result;
}
//
box.to = item.To();
box.from = item.From();
box.upper = item.Upper();
box.lower = item.Lower();
box.symbol = item.GetSymbol();
box.period = item.GetPeriod();
box.type = item.TypeAsString();
box.dir = item.IsBullish()
? X_DIRECTION_BULLISH
: X_DIRECTION_BEARISH;
//
result = box.IsValid();
//
return result;
}
/**
* Converts to XBoxZone ...
*
* @return ( bool )
*/
bool ToBox(
XBoxZone &box,
XCSupportZone *item //
)
{
//
bool result = false;
//
box.Clean();
//
result = item != NULL &&
item.IsValid();
if (!result)
{
return result;
}
//
box.to = item.To();
box.from = item.From();
box.upper = item.Upper();
box.lower = item.Lower();
box.symbol = item.GetSymbol();
box.period = item.GetPeriod();
box.type = item.TypeAsString();
box.dir = X_DIRECTION_BULLISH;
//
result = box.IsValid();
//
return result;
}
/**
* Converts to XBoxZone ...
*
* @return ( bool )
*/
bool ToBox(
XBoxZone &box,
XCResistanceZone *item //
)
{
//
bool result = false;
//
box.Clean();
//
result = item != NULL &&
item.IsValid();
if (!result)
{
return result;
}
//
box.to = item.To();
box.from = item.From();
box.upper = item.Upper();
box.lower = item.Lower();
box.symbol = item.GetSymbol();
box.period = item.GetPeriod();
box.type = item.TypeAsString();
box.dir = X_DIRECTION_BEARISH;
//
result = box.IsValid();
//
return result;
}
/**
* Converts to XBoxZone ...
*
* @return ( bool )
*/
bool ToBox(
XBoxZone &box,
XCSupplyZone *item //
)
{
//
bool result = false;
//
box.Clean();
//
result = item != NULL &&
item.IsValid();
if (!result)
{
return result;
}
//
box.to = item.To();
box.from = item.From();
box.upper = item.Upper();
box.lower = item.Lower();
box.symbol = item.GetSymbol();
box.period = item.GetPeriod();
box.type = item.TypeAsString();
box.dir = X_DIRECTION_BEARISH;
//
result = box.IsValid();
//
return result;
}
/**
* Converts to XBoxZone ...
*
* @return ( bool )
*/
bool ToBox(
XBoxZone &box,
XCDemandZone *item //
)
{
//
bool result = false;
//
box.Clean();
//
result = item != NULL &&
item.IsValid();
if (!result)
{
return result;
}
//
box.to = item.To();
box.from = item.From();
box.upper = item.Upper();
box.lower = item.Lower();
box.symbol = item.GetSymbol();
box.period = item.GetPeriod();
box.type = item.TypeAsString();
box.dir = X_DIRECTION_BULLISH;
//
result = box.IsValid();
//
return result;
}
/**
* Get Oldest Zone ...
*
* @return ( int )
*/
int GetOldest(
XCZone *&source[] //
)
{
//
int result = -1;
//
int count = ArraySize(source);
if (!IsValidSize(count))
{
return result;
}
//
XCZone *oldest = NULL;
for (int i = 0; i < count; i++)
{
//
XCZone *iZone = source[i];
//
bool canSet =
oldest == NULL ||
(oldest != NULL &&
oldest.From() > iZone.From());
if (canSet)
{
//
result = i;
oldest = iZone;
}
}
//
return result;
}
/**
* Get Youngest Zone ...
*
* @return ( int )
*/
int GetYoungest(
XCZone *&source[] //
)
{
//
int result = -1;
//
int count = ArraySize(source);
if (!IsValidSize(count))
{
return result;
}
//
XCZone *youngest = NULL;
for (int i = 0; i < count; i++)
{
//
XCZone *iZone = source[i];
//
bool canSet =
youngest == NULL ||
(youngest != NULL &&
youngest.From() < iZone.From());
if (canSet)
{
//
result = i;
youngest = iZone;
}
}
//
return result;
}
/**
* Get Oldest Box Index ...
*
* @param source: XBoxZone instance Reference Collection ...
*
* @return ( int )
*/
int GetOldest(
XBoxZone &source[] //
)
{
//
int result = -1;
//
int count = ArraySize(source);
if (!IsValidSize(count))
{
return result;
}
//
XBoxZone selected;
for (int i = 0; i < count; i++)
{
//
XBoxZone iBox = source[i];
//
bool canSet =
!selected.IsValid()
? true
: selected.from > iBox.from;
if (canSet)
{
//
result = i;
selected = iBox;
}
}
//
return result;
}
/**
* Get Youngest Box Index ...
*
* @param source: XBoxZone instance Reference Collection ...
*
* @return ( int )
*/
int GetYoungest(
XBoxZone &source[] //
)
{
//
int result = -1;
//
int count = ArraySize(source);
if (!IsValidSize(count))
{
return result;
}
//
XBoxZone selected;
for (int i = 0; i < count; i++)
{
//
XBoxZone iBox = source[i];
//
bool canSet =
!selected.IsValid()
? true
: selected.from < iBox.from;
if (canSet)
{
//
result = i;
selected = iBox;
}
}
//
return result;
}
/**
* Get Highest Box Index ...
*
* @param source: XBoxZone instance Reference Collection ...
*
* @return ( int )
*/
int GetHighest(
XBoxZone &source[] //
)
{
//
int result = -1;
//
int count = ArraySize(source);
if (!IsValidSize(count))
{
return result;
}
//
XBoxZone selected;
for (int i = 0; i < count; i++)
{
//
XBoxZone iBox = source[i];
//
bool canSet =
!selected.IsValid()
? true
: selected.upper < iBox.upper;
if (canSet)
{
//
result = i;
selected = iBox;
}
}
//
return result;
}
/**
* Get Lowest Box Index ...
*
* @param source: XBoxZone instance Reference Collection ...
*
* @return ( int )
*/
int GetLowest(
XBoxZone &source[] //
)
{
//
int result = -1;
//
int count = ArraySize(source);
if (!IsValidSize(count))
{
return result;
}
//
XBoxZone selected;
for (int i = 0; i < count; i++)
{
//
XBoxZone iBox = source[i];
//
bool canSet =
!selected.IsValid()
? true
: selected.lower > iBox.lower;
if (canSet)
{
//
result = i;
selected = iBox;
}
}
//
return result;
}
template <typename T, typename F>
int FilterZones(
T *source,
F *&dest[],
bool filterDirection = true,
bool filterFrom = true,
bool filterPrice = true,
bool ignoreOutOfBox = false,
bool applySort = false,
bool ignoreInside = true //
)
{
//
int result = 0;
//
int count = ArraySize(dest);
if (source == NULL ||
!source.IsValid() ||
!IsValidSize(count))
{
return result;
}
//
XBoxZone sourceBox;
bool hasSourceBox = ToBox(
sourceBox,
source //
);
if (!hasSourceBox)
{
return result;
}
//
F *tmp[];
for (int i = 0; i < count; i++)
{
//
F *iZone = dest[i];
//
XBoxZone iBox;
bool hasBox = ToBox(
iBox,
iZone //
);
if (!hasBox)
{
continue;
}
//
ENUM_X_DIRECTION iDir = iBox.dir;
bool isIBullish = IsBullish(iDir);
//
if (filterDirection)
{
//
bool isDirectionPassed =
sourceBox.dir == iDir;
if (!isDirectionPassed)
{
continue;
}
}
//
if (filterFrom)
{
//
bool isFromPassed = iBox.from > sourceBox.from;
if (!isFromPassed)
{
continue;
}
}
//
if (filterPrice)
{
//
bool isInside = IsBoxInside(
iBox,
sourceBox //
);
//
bool isAbove = IsBoxAbove(
iBox,
sourceBox,
ignoreInside //
);
//
bool isBelow = IsBoxBelow(
iBox,
sourceBox,
ignoreInside //
);
//
bool isPricePassed =
//
isInside =
ignoreOutOfBox
? isInside
: isInside &&
(isIBullish
? isAbove
: isBelow)
//
;
if (!isPricePassed)
{
continue;
}
//
Add(
iZone,
tmp //
);
}
}
//
Clean(dest);
if (HasChild(tmp))
{
//
Copy(
tmp,
dest //
);
//
Clean(tmp);
}
//
if (applySort)
{
//
F *lastZone;
XBoxZone last;
count = ArraySize(dest);
if (HasChild(dest))
{
//
int idx = GetYoungest(dest);
if (IsValidIndex(idx))
{
//
lastZone = dest[idx];
ArrayRemove(
dest,
idx,
1 //
);
//
count = ArraySize(dest);
bool hasLastBox = ToBox(
last,
lastZone //
);
}
//
if (IsValidSize(count))
{
//
for (int i = 0; i < count; i++)
{
//
F *iZone = dest[i];
//
XBoxZone iBox;
bool hasBox = ToBox(
iBox,
iZone //
);
if (!hasBox)
{
continue;
}
//
bool isLastPassed =
last.IsValid() &&
(IsBullish(last.dir)
? IsBoxAbove(
iBox,
last,
true //
)
: IsBoxBelow(
iBox,
last,
true //
));
if (!isLastPassed)
{
continue;
}
//
lastZone = iZone;
bool hasLastBox = ToBox(
last,
lastZone //
);
Add(
iZone,
tmp //
);
}
}
else
{
//
if (last.IsValid())
{
//
AddRef(
lastZone,
tmp //
);
}
}
}
}
//
Clean(dest);
if (HasChild(tmp))
{
//
Copy(
tmp,
dest //
);
}
//
result = ArraySize(dest);
//
Clean(tmp);
//
return result;
}
int FilterBoxes(
XBoxZone &source,
XBoxZone &dest[],
bool filterDirection = true,
bool filterFrom = true,
bool filterPrice = true,
bool ignoreOutOfBox = false,
bool applySort = false,
bool ignoreInside = true //
)
{
//
int result = 0;
//
int count = ArraySize(dest);
if (!source.IsValid() ||
!IsValidSize(count))
{
return result;
}
//
XBoxZone tmp[];
for (int i = 0; i < count; i++)
{
//
XBoxZone iBox = dest[i];
ENUM_X_DIRECTION iDir = iBox.dir;
bool isIBullish = IsBullish(iDir);
//
if (filterDirection)
{
//
bool isDirectionPassed =
source.dir == iDir;
if (!isDirectionPassed)
{
continue;
}
}
//
if (filterFrom)
{
//
bool isFromPassed = iBox.from > source.from;
if (!isFromPassed)
{
continue;
}
}
//
if (filterPrice)
{
//
bool isInside = IsBoxInside(
iBox,
source //
);
//
bool isAbove = IsBoxAbove(
iBox,
source,
ignoreInside //
);
//
bool isBelow = IsBoxBelow(
iBox,
source,
ignoreInside //
);
//
bool isPricePassed =
//
ignoreOutOfBox
? isInside
: isInside &&
(isIBullish
? isAbove
: isBelow)
//
;
if (!isPricePassed)
{
continue;
}
//
AddRef(
iBox,
tmp //
);
}
}
//
if (HasChild(tmp))
{
//
Clean(dest);
//
Copy(
tmp,
dest //
);
//
Clean(tmp);
}
//
if (applySort)
{
//
XBoxZone last;
count = ArraySize(dest);
if (HasChild(dest))
{
//
int idx = GetYoungest(dest);
if (IsValidIndex(idx))
{
//
last = dest[idx];
ArrayRemove(
dest,
idx,
1 //
);
//
count = ArraySize(dest);
}
//
if (IsValidSize(count))
{
//
for (int i = 0; i < count; i++)
{
//
XBoxZone iBox = dest[i];
//
bool isLastPassed =
last.IsValid() &&
(IsBullish(last.dir)
? IsBoxAbove(
iBox,
last,
true //
)
: IsBoxBelow(
iBox,
last,
true //
));
if (!isLastPassed)
{
continue;
}
//
last = iBox;
AddRef(
iBox,
tmp //
);
}
}
else
{
//
if (last.IsValid())
{
//
AddRef(
last,
tmp //
);
}
}
}
}
//
if (HasChild(tmp))
{
//
Clean(dest);
//
Copy(
tmp,
dest //
);
}
//
result = ArraySize(dest);
//
return result;
}
//
typedef void (*TOnPOIEvent)(ENUM_XPOI_EVENTS event,
XCBasePOI *param //
);
//
//
//
/**
* Extract UnActivated Order Blocks / Fair Value Gaps ...
*
* @return ( int )
*/
template <typename T>
int ExtractUnActivatedZones(
T *&source[],
T *&dest[] //
)
{
//
int result = 0;
//
Clean(dest);
//
int count = ArraySize(source);
int hasChild = IsValidSize(count);
if (!hasChild)
{
return result;
}
//
for (int i = 0; i < count; i++)
{
//
T *iChild = source[i];
ENUM_X_DIRECTION iChildForDir = iChild.GetDirection();
//
// Validate Started Zones ...
XOHCL iChildStartedBar;
ENUM_X_DIRECTION iChildStartedDir;
bool isStarted = iChild.IsStarted(
iChildForDir,
iChildStartedBar,
iChildStartedDir //
);
if (!isStarted)
{
continue;
}
//
// Validate InActive Zone ...
XOHCL iChildActivatedBar;
ENUM_X_DIRECTION iChildActivatedDir;
bool isActivated = iChild.IsActivated(
iChildForDir,
iChildActivatedBar,
iChildActivatedDir //
);
if (isActivated)
{
continue;
}
//
// Validate Zone Iverse Breake ...
XOHCL iChildBreakedBar;
ENUM_X_DIRECTION iChildBreakedDir;
bool isBreaked = iChild.IsBreaked(
Opposit(iChildForDir),
iChildBreakedBar,
iChildBreakedDir,
true // Ignore Activation ...
);
if (isBreaked)
{
continue;
}
//
int iChildIDX = -1;
bool isIChildExists = FindIndex(
iChildIDX,
iChild,
dest //
);
if (isIChildExists)
{
continue;
}
//
Add(
iChild,
dest //
);
}
//
result = ArraySize(dest);
//
return result;
}
/**
* Extract ctivated Order Blocks / Fair Value Gaps ...
*
* @return ( int )
*/
template <typename T>
int ExtractActivatedZones(
T *&source[],
T *&dest[],
bool ignoreBreaktion = false //
)
{
//
int result = 0;
//
Clean(dest);
//
int count = ArraySize(source);
int hasChild = IsValidSize(count);
if (!hasChild)
{
return result;
}
//
for (int i = 0; i < count; i++)
{
//
T *iChild = source[i];
ENUM_X_DIRECTION iChildForDir = iChild.GetDirection();
//
// Validate Started Zones ...
XOHCL iChildStartedBar;
ENUM_X_DIRECTION iChildStartedDir;
bool isStarted = iChild.IsStarted(
iChildForDir,
iChildStartedBar,
iChildStartedDir //
);
if (!isStarted)
{
continue;
}
//
// Validate InActive Zone ...
XOHCL iChildActivatedBar;
ENUM_X_DIRECTION iChildActivatedDir;
bool isActivated = iChild.IsActivated(
iChildForDir,
iChildActivatedBar,
iChildActivatedDir //
);
if (!isActivated)
{
continue;
}
//
// Validate Zone Iverse Breake ...
if (!ignoreBreaktion)
{
//
XOHCL iChildBreakedBar;
ENUM_X_DIRECTION iChildBreakedDir;
bool isBreaked = iChild.IsBreaked(
Opposit(iChildForDir),
iChildBreakedBar,
iChildBreakedDir,
true // Ignore Activation ...
);
if (isBreaked)
{
continue;
}
//
isBreaked = iChild.IsBreaked(
iChildForDir,
iChildBreakedBar,
iChildBreakedDir,
true // Ignore Activation ...
);
if (isBreaked)
{
continue;
}
}
//
int iChildIDX = -1;
bool isIChildExists = FindIndex(
iChildIDX,
iChild,
dest //
);
if (isIChildExists)
{
continue;
}
//
Add(
iChild,
dest //
);
}
//
result = ArraySize(dest);
//
return result;
}
/**
* Extract Directinal Based Order Blocks / Fair Value Gaps ...
*
* @param forDir: ENUM_X_DIRECTION member ...
*
* @return ( int )
*/
template <typename T>
int ExtractDirectionalZones(
ENUM_X_DIRECTION forDir,
T *&source[],
T *&dest[] //
)
{
//
int result = 0;
//
Clean(dest);
//
int count = ArraySize(source);
if (!IsValidSize(count) ||
!HasDirection(forDir))
{
return result;
}
//
for (int i = 0; i < count; i++)
{
//
T *iChild = source[i];
//
ENUM_X_DIRECTION iForDir = iChild.GetDirection();
if (forDir == iForDir)
{
//
Add(
iChild,
dest //
);
}
}
//
result = ArraySize(dest);
//
return result;
}
/**
* Sort Order Blocks / Fair Value Gaps based on Place and Remove unused ...
*/
template <typename T>
void OrderedSortZones(
T *youngest,
T *&items[] //
)
{
//
int count = ArraySize(items);
if (youngest == NULL ||
!youngest.IsValid() ||
!IsValidSize(count))
{
return;
}
//
ENUM_X_DIRECTION dir = youngest.GetDirection();
bool isBullish = IsBullish(dir);
//
T *tmp[];
T *lastOB = youngest;
while (IsValidSize(count))
{
//
// Detect Youngest of Collection ...
int idx = GetYoungest(items);
T *iChild = items[idx];
ArrayRemove(
items,
idx,
1 //
);
count = ArraySize(items);
//
// Check Direction Must be Same ...
ENUM_X_DIRECTION iDir = iChild.GetDirection();
bool isSameDir = dir == iDir;
if (!isSameDir)
{
continue;
}
//
// Check Creation time Sequence ...
bool isFromPassed = lastOB.From() > iChild.From();
if (!isFromPassed)
{
continue;
}
//
// Check Order Block Place ...
bool isPlacePassed =
isBullish
? IsBelow(
iChild,
lastOB,
true // Ignore Inside ...
)
: IsAbove(
iOB,
lastOB,
true // Ignore Inside ...
);
if (!isPlacePassed)
{
continue;
}
//
// Update Last OB ...
lastOB = iChild;
Add(
iChild,
tmp //
);
//
}
//
// Update Ordered Sorted Order Blocks ...
count = ArraySize(tmp);
if (IsValidSize(count))
{
//
Copy(
tmp,
orderBlocks //
);
}
}
template <typename T>
void OrderedSortZones(
T *&items[] //
)
{
//
int count = ArraySize(items);
if (!IsValidSize(count))
{
return;
}
//
// Detect Youngest ...
int youngestIDX = GetYoungest(
items //
);
bool hasYoungest = IsValidSize(youngestIDX);
if (!hasYoungest)
{
return;
}
//
T *youngest = items[youngestIDX];
ArrayRemove(
items,
youngestIDX,
1 //
);
count = ArraySize(items);
if (!IsValidSize(count))
{
//
Add(
youngest,
items //
);
//
return;
}
//
if (youngest == NULL ||
!youngest.IsValid())
{
return;
}
//
ENUM_X_DIRECTION dir = youngest.GetDirection();
bool isBullish = IsBullish(dir);
//
T *tmp[];
T *lastOB = youngest;
while (IsValidSize(count))
{
//
// Detect Youngest of Collection ...
int idx = GetYoungest(items);
T *iChild = items[idx];
ArrayRemove(
items,
idx,
1 //
);
count = ArraySize(items);
//
// Check Direction Must be Same ...
ENUM_X_DIRECTION iDir = iChild.GetDirection();
bool isSameDir = dir == iDir;
if (!isSameDir)
{
continue;
}
//
// Check Creation time Sequence ...
bool isFromPassed = lastOB.From() > iChild.From();
if (!isFromPassed)
{
continue;
}
//
// Check Order Block Place ...
bool isPlacePassed =
isBullish
? IsBelow(
iChild,
lastOB,
true // Ignore Inside ...
)
: IsAbove(
iChild,
lastOB,
true // Ignore Inside ...
);
if (!isPlacePassed)
{
continue;
}
//
// Update Last OB ...
lastOB = iChild;
Add(
iChild,
tmp //
);
//
}
//
// Update Ordered Sorted Order Blocks ...
count = ArraySize(tmp);
if (IsValidSize(count))
{
//
Copy(
tmp,
items //
);
}
}
void OrderedSortBoxes(
XBoxZone &items[] //
)
{
//
int count = ArraySize(items);
if (!IsValidSize(count))
{
return;
}
//
// Detect Youngest ...
int youngestIDX = GetYoungest(
items //
);
bool hasYoungest = IsValidSize(youngestIDX);
if (!hasYoungest)
{
return;
}
//
XBoxZone youngest = items[youngestIDX];
ArrayRemove(
items,
youngestIDX,
1 //
);
count = ArraySize(items);
if (!IsValidSize(count))
{
//
AddRef(
youngest,
items //
);
//
return;
}
//
if (!youngest.IsValid())
{
return;
}
//
ENUM_X_DIRECTION dir = youngest.dir;
bool isBullish = IsBullish(dir);
//
XBoxZone tmp[];
XBoxZone last = youngest;
while (IsValidSize(count))
{
//
// Detect Youngest of Collection ...
int idx = GetYoungest(items);
XBoxZone iChild = items[idx];
ArrayRemove(
items,
idx,
1 //
);
count = ArraySize(items);
//
// Check Direction Must be Same ...
ENUM_X_DIRECTION iDir = iChild.dir;
bool isSameDir = dir == iDir;
if (!isSameDir)
{
continue;
}
//
// Check Creation time Sequence ...
bool isFromPassed = last.from > iChild.from;
if (!isFromPassed)
{
continue;
}
//
// Check Order Block Place ...
bool isPlacePassed =
isBullish
? IsBoxBelow(
iChild,
last,
true // Ignore Inside ...
)
: IsBoxAbove(
iChild,
last,
true // Ignore Inside ...
);
if (!isPlacePassed)
{
continue;
}
//
// Update Last OB ...
last = iChild;
AddRef(
iChild,
tmp //
);
//
}
//
// Update Ordered Sorted Order Blocks ...
count = ArraySize(tmp);
if (IsValidSize(count))
{
//
Copy(
tmp,
items //
);
}
}
/**
* Extract Order Flows Swing Points ...
*
* @param type: ENUM_X_SWING_TYPE member ...
* @param swings: double Collection ...
*
* @return ( int )
*/
int ExtractSwingPoints(
ENUM_X_SWING_TYPE type,
XCOrderBlock *&orderBlocks[],
XSwingPoint &swings[] //
)
{
//
int result = 0;
//
Clean(swings);
//
int count = ArraySize(orderBlocks);
//
if (type == X_NO_SWING ||
!IsValidSize(count))
{
return result;
}
//
bool lookingForSwingLows = type == X_SWING_LOW;
//
for (int i = 0; i < count; i++)
{
//
XCOrderBlock *iOB = orderBlocks[i];
//
string iSymbol = iOB.GetSymbol();
ENUM_TIMEFRAMES iPeriod = iOB.GetPeriod();
//
int fromIndex = iBarShift(
iSymbol,
iPeriod,
iOB.From() //
);
//
fromIndex++;
//
double iValue = 0;
datetime iVTime = NULL;
if (lookingForSwingLows)
{
//
int idx = iLowest(
iSymbol,
iPeriod,
MODE_LOW,
fromIndex //
);
//
if (IsValidIndex(idx))
{
//
iValue = iLow(
iSymbol,
iPeriod,
idx //
);
//
iVTime = iTime(
iSymbol,
iPeriod,
idx //
);
}
}
else
{
//
int idx = iHighest(
iSymbol,
iPeriod,
MODE_HIGH,
fromIndex //
);
//
if (IsValidIndex(idx))
{
//
iValue = iHigh(
iSymbol,
iPeriod,
idx //
);
//
iVTime = iTime(
iSymbol,
iPeriod,
idx //
);
}
}
//
if (iValue > 0)
{
//
XSwingPoint iSwingP;
//
iSwingP.type = type;
iSwingP.time = iVTime;
iSwingP.swing = iValue;
iSwingP.symbol = iSymbol;
iSwingP.period = iPeriod;
//
if (iSwingP.IsValid())
{
//
AddRef(
iSwingP,
swings //
);
}
//
iSwingP.Clean();
}
}
//
result = ArraySize(swings);
//
return result;
}
//