Files
MQL5Data/Libraries/x-saherelm.x-poi.lib.mq5
T
2025-02-18 21:07:05 +03:30

10309 lines
191 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 ...
};
//
// 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ّ ...
};
//
enum ENUM_XZONE_STATE
{
XZONE_STATE_NONE,
XZONE_STATE_PASSED,
XZONE_STATE_FAILED,
XZONE_STATE_IGNORED,
};
//
// 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;
}
/**
* Check Zone Started or not ...
* First Exit in Direction of Zone after From ...
*
* @param forDir: exit direction ...
* @param startedBar: specified Start Bar ...
* @param isBodyOut: specified Start Bar Close is Out of Zone or not ...
* @param forPeriod: specified Period ...
*
* @return ( bool )
*/
bool IsStarted(
ENUM_X_DIRECTION forDir,
XOHCL &startedBar,
bool &isBodyOut,
ENUM_TIMEFRAMES forPeriod = NULL //
)
{
//
bool result = false;
//
isBodyOut = false;
startedBar.Clean();
//
result = HasDirection(forDir) &&
IsValidBarZone();
if (!result)
{
return result;
}
//
bool isBullish = IsBullish(forDir);
//
if (!IsSpecifiedValid(forPeriod))
{
forPeriod = GetPeriod();
}
//
// 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)
{
//
iBar.Clean();
continue;
}
//
bool isBreakedFromUpper =
//
iBar.low > Upper() ||
(iBar.low <= Upper() &&
iBar.high > Upper() &&
iBar.close > Upper())
//
;
//
bool isBreakedFromLower =
//
iBar.low < Lower() ||
(iBar.high >= Lower() &&
iBar.low < Lower() &&
iBar.close < Lower())
//
;
//
bool isBreaked =
isBreakedFromUpper ||
isBreakedFromLower;
if (isBreaked)
{
//
result = isBreaked &&
isBullish
? isBreakedFromUpper
: isBreakedFromLower;
if (result)
{
//
startedBar = iBar;
iBar.Clean();
break;
}
}
//
iBar.Clean();
}
//
result = startedBar.IsValid();
if (result)
{
//
isBodyOut =
isBullish
? startedBar.IsBullish() &&
startedBar.GetUp() > Upper()
: startedBar.IsBearish() &&
startedBar.GetDown() < Lower();
}
//
return result;
}
/**
* Check Zone Activated or not ...
* First Enter in Opposit Direction of Zone after Start ...
*
* @param forDir: exit direction ...
* @param activatedBar: specified Activation Bar ...
* @param isBodyIn: specified Activation Bar Close is Inside of Zone or not ...
* @param forPeriod: specified Period ...
*
* @return ( bool )
*/
bool IsActivated(
ENUM_X_DIRECTION forDir,
XOHCL &activatedBar,
bool &isBodyIn,
bool forceBodyOutStarted = true,
ENUM_TIMEFRAMES forPeriod = NULL //
)
{
//
bool result = false;
//
isBodyIn = false;
activatedBar.Clean();
//
result = HasDirection(forDir) &&
IsValidBarZone();
if (!result)
{
return result;
}
//
bool isBullish = IsBullish(forDir);
//
if (!IsSpecifiedValid(forPeriod))
{
forPeriod = GetPeriod();
}
//
XOHCL startedBar;
bool isBodyOut = false;
bool isStarted = IsStarted(
forDir,
startedBar,
isBodyOut,
forPeriod //
);
result =
!forceBodyOutStarted
? isStarted
: isStarted &&
isBodyOut;
if (!result)
{
//
startedBar.Clean();
return result;
}
//
int fromIndex = startedBar.Index() - 1;
//
for (int i = fromIndex; i >= 0; i--)
{
//
XOHCL iBar;
bool isInited = iBar.Init(
GetSymbol(),
forPeriod,
i //
);
result = isInited;
if (!result)
{
//
iBar.Clean();
continue;
}
//
bool isInsideFromUpper =
//
iBar.high < Upper() ||
(iBar.high > Upper() &&
iBar.low <= Upper() &&
iBar.close <= Upper())
//
;
//
bool isInsideFromLower =
//
iBar.low > Lower() ||
(iBar.low < Lower() &&
iBar.high >= Lower() &&
iBar.close >= Lower())
//
;
//
bool isInside =
isInsideFromUpper ||
isInsideFromLower;
if (isInside)
{
//
result = isInside &&
isBullish
? isInsideFromUpper
: isInsideFromLower;
if (result)
{
//
activatedBar = iBar;
iBar.Clean();
startedBar.Clean();
break;
}
}
//
iBar.Clean();
startedBar.Clean();
}
//
result = activatedBar.IsValid();
if (result)
{
//
isBodyIn =
isBullish
? activatedBar.IsBearish() &&
activatedBar.GetDown() < Upper()
: activatedBar.IsBullish() &&
activatedBar.GetUp() > Lower();
}
//
return result;
}
/**
* Check Zone Breaked or not ...
*
* @param forDir: exit direction ...
* @param breakedBar: specified Breaked Bar ...
* @param isBodyOut: specified Breaked Bar Close is Out of Zone or not ...
* @param ignoreStart: Ignore Zone Start (Calculate from From()) ...
* @param startedBodyOut: Started Bar Body Close State, if use Start for Calculation ...
* @param forPeriod: specified Period ...
*
* @return ( bool )
*/
bool IsBreaked(
ENUM_X_DIRECTION forDir,
XOHCL &breakedBar,
bool &isBodyOut,
bool ignoreStart = false,
bool startedBodyOut = false,
ENUM_TIMEFRAMES forPeriod = NULL //
)
{
//
bool result = false;
//
isBodyOut = false;
breakedBar.Clean();
//
result = HasDirection(forDir) &&
IsValidBarZone();
if (!result)
{
return result;
}
//
bool isBullish = IsBullish(forDir);
//
if (!IsSpecifiedValid(forPeriod))
{
forPeriod = GetPeriod();
}
//
int fromIndex = -1;
if (!ignoreStart)
{
//
XOHCL startedBar;
bool isBodyOut = false;
bool isStarted = IsStarted(
forDir,
startedBar,
isBodyOut,
forPeriod //
);
//
bool isStartPassed =
!startedBodyOut
? isStarted
: isStarted &&
isBodyOut;
if (isStartPassed)
{
fromIndex = startedBar.Index() - 1;
}
//
startedBar.Clean();
}
else
{
//
fromIndex = iBarShift(
GetSymbol(),
forPeriod,
From() //
);
}
//
result = IsValidIndex(fromIndex);
if (!result)
{
return result;
}
//
for (int i = fromIndex; i >= 0; i--)
{
//
XOHCL iBar;
bool isInited = iBar.Init(
GetSymbol(),
forPeriod,
i //
);
result = isInited;
if (!result)
{
//
iBar.Clean();
continue;
}
//
bool isBreakedFromUpper =
//
iBar.low > Upper() ||
(iBar.low <= Upper() &&
iBar.high > Upper() &&
iBar.close > Upper())
//
;
//
bool isBreakedFromLower =
//
iBar.low < Lower() ||
(iBar.high >= Lower() &&
iBar.low < Lower() &&
iBar.close < Lower())
//
;
//
bool isBreaked =
isBreakedFromUpper ||
isBreakedFromLower;
if (isBreaked)
{
//
result = isBreaked &&
isBullish
? isBreakedFromLower
: isBreakedFromUpper;
if (result)
{
//
breakedBar = iBar;
iBar.Clean();
break;
}
}
//
iBar.Clean();
}
//
result = breakedBar.IsValid();
if (result)
{
//
isBodyOut =
isBullish
? breakedBar.IsBearish() &&
breakedBar.GetDown() < Lower()
: breakedBar.IsBullish() &&
breakedBar.GetUp() > Upper();
}
//
return result;
}
/**
* Check Zone Worked or not ...
*
* @param forDir: exit direction ...
* @param workedBar: specified Worked Bar ...
* @param isBodyOut: specified Worked Bar Close is Out of Zone or not ...
* @param ignoreActivation: Ignore Zone Activation (Calculate from From()) ...
* @param activationStartedOut: Specified Zone Start Bar State ...
* @param activationBodyIn: Specified Zone Activation Bar State ...
* @param forPeriod: specified Period ...
*
* @return ( bool )
*/
bool IsWorked(
ENUM_X_DIRECTION forDir,
XOHCL &workedBar,
bool &isBodyOut,
bool ignoreActivation = false,
bool activationStartedOut = false,
bool activationBodyIn = false,
ENUM_TIMEFRAMES forPeriod = NULL //
)
{
//
bool result = false;
//
isBodyOut = false;
workedBar.Clean();
//
result = HasDirection(forDir) &&
IsValidBarZone();
if (!result)
{
return result;
}
//
bool isBullish = IsBullish(forDir);
//
if (!IsSpecifiedValid(forPeriod))
{
forPeriod = GetPeriod();
}
//
int fromIndex = -1;
if (!ignoreActivation)
{
//
XOHCL activatedBar;
bool isBodyIn = false;
bool isActivated = IsActivated(
forDir,
activatedBar,
isBodyIn,
activationStartedOut,
forPeriod //
);
//
bool isActivationPassed =
!activationBodyIn
? isActivated
: isActivated &&
isBodyIn;
if (isActivationPassed)
{
fromIndex = activatedBar.Index() - 1;
}
//
activatedBar.Clean();
}
else
{
//
fromIndex = iBarShift(
GetSymbol(),
forPeriod,
From() //
);
}
//
result = IsValidIndex(fromIndex);
if (!result)
{
return result;
}
//
for (int i = fromIndex; i >= 0; i--)
{
//
XOHCL iBar;
bool isInited = iBar.Init(
GetSymbol(),
forPeriod,
i //
);
result = isInited;
if (!result)
{
//
iBar.Clean();
continue;
}
//
bool isBreakedFromUpper =
//
iBar.low > Upper() ||
(iBar.low <= Upper() &&
iBar.high > Upper() &&
iBar.close > Upper())
//
;
//
bool isBreakedFromLower =
//
iBar.low < Lower() ||
(iBar.high >= Lower() &&
iBar.low < Lower() &&
iBar.close < Lower())
//
;
//
bool isBreaked =
isBreakedFromUpper ||
isBreakedFromLower;
if (isBreaked)
{
//
result = isBreaked &&
isBullish
? isBreakedFromUpper
: isBreakedFromLower;
if (result)
{
//
workedBar = iBar;
iBar.Clean();
break;
}
}
//
iBar.Clean();
}
//
result = workedBar.IsValid();
if (result)
{
//
isBodyOut =
isBullish
? workedBar.IsBullish() &&
workedBar.GetUp() > Upper()
: workedBar.IsBearish() &&
workedBar.GetDown() < Lower();
}
//
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;
}
/**
* Check Zone Started or not ...
* First Exit in Direction of Zone after From ...
*
* @param forDir: exit direction ...
* @param startedBar: specified Start Bar ...
* @param isBodyOut: specified Start Bar Close is Out of Zone or not ...
* @param forPeriod: specified Period ...
*
* @return ( bool )
*/
bool IsStarted(
ENUM_X_DIRECTION forDir,
XOHCL &startedBar,
bool &isBodyOut,
ENUM_TIMEFRAMES forPeriod = NULL //
)
{
//
bool result = false;
//
isBodyOut = false;
startedBar.Clean();
//
result = HasDirection(forDir) &&
IsValidTwoBarZone();
if (!result)
{
return result;
}
//
bool isBullish = IsBullish(forDir);
//
if (!IsSpecifiedValid(forPeriod))
{
forPeriod = GetPeriod();
}
//
// 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)
{
//
iBar.Clean();
continue;
}
//
bool isBreakedFromUpper =
//
iBar.low > Upper() ||
(iBar.low <= Upper() &&
iBar.high > Upper() &&
iBar.close > Upper())
//
;
//
bool isBreakedFromLower =
//
iBar.low < Lower() ||
(iBar.high >= Lower() &&
iBar.low < Lower() &&
iBar.close < Lower())
//
;
//
bool isBreaked =
isBreakedFromUpper ||
isBreakedFromLower;
if (isBreaked)
{
//
result = isBreaked &&
isBullish
? isBreakedFromUpper
: isBreakedFromLower;
if (result)
{
//
startedBar = iBar;
iBar.Clean();
break;
}
}
//
iBar.Clean();
}
//
result = startedBar.IsValid();
if (result)
{
//
isBodyOut =
isBullish
? startedBar.IsBullish() &&
startedBar.GetUp() > Upper()
: startedBar.IsBearish() &&
startedBar.GetDown() < Lower();
}
//
return result;
}
/**
* Check Zone Activated or not ...
* First Enter in Opposit Direction of Zone after Start ...
*
* @param forDir: exit direction ...
* @param activatedBar: specified Activation Bar ...
* @param isBodyIn: specified Activation Bar Close is Inside of Zone or not ...
* @param forPeriod: specified Period ...
*
* @return ( bool )
*/
bool IsActivated(
ENUM_X_DIRECTION forDir,
XOHCL &activatedBar,
bool &isBodyIn,
bool forceBodyOutStarted = true,
ENUM_TIMEFRAMES forPeriod = NULL //
)
{
//
bool result = false;
//
isBodyIn = false;
activatedBar.Clean();
//
result = HasDirection(forDir) &&
IsValidTwoBarZone();
if (!result)
{
return result;
}
//
bool isBullish = IsBullish(forDir);
//
if (!IsSpecifiedValid(forPeriod))
{
forPeriod = GetPeriod();
}
//
XOHCL startedBar;
bool isBodyOut = false;
bool isStarted = IsStarted(
forDir,
startedBar,
isBodyOut,
forPeriod //
);
result =
!forceBodyOutStarted
? isStarted
: isStarted &&
isBodyOut;
if (!result)
{
//
startedBar.Clean();
return result;
}
//
int fromIndex = startedBar.Index() - 1;
//
for (int i = fromIndex; i >= 0; i--)
{
//
XOHCL iBar;
bool isInited = iBar.Init(
GetSymbol(),
forPeriod,
i //
);
result = isInited;
if (!result)
{
//
iBar.Clean();
continue;
}
//
bool isInsideFromUpper =
//
iBar.high < Upper() ||
(iBar.high > Upper() &&
iBar.low <= Upper() &&
iBar.close <= Upper())
//
;
//
bool isInsideFromLower =
//
iBar.low > Lower() ||
(iBar.low < Lower() &&
iBar.high >= Lower() &&
iBar.close >= Lower())
//
;
//
bool isInside =
isInsideFromUpper ||
isInsideFromLower;
if (isInside)
{
//
result = isInside &&
isBullish
? isInsideFromUpper
: isInsideFromLower;
if (result)
{
//
activatedBar = iBar;
iBar.Clean();
startedBar.Clean();
break;
}
}
//
iBar.Clean();
startedBar.Clean();
}
//
result = activatedBar.IsValid();
if (result)
{
//
isBodyIn =
isBullish
? activatedBar.IsBearish() &&
activatedBar.GetDown() < Upper()
: activatedBar.IsBullish() &&
activatedBar.GetUp() > Lower();
}
//
return result;
}
/**
* Check Zone reaked or not ...
*
* @param forDir: exit direction ...
* @param breakedBar: specified Breaked Bar ...
* @param isBodyOut: specified Breaked Bar Close is Out of Zone or not ...
* @param ignoreStart: Ignore Zone Start (Calculate from From()) ...
* @param startedBodyOut: Started Bar Body Close State, if use Start for Calculation ...
* @param forPeriod: specified Period ...
*
* @return ( bool )
*/
bool IsBreaked(
ENUM_X_DIRECTION forDir,
XOHCL &breakedBar,
bool &isBodyOut,
bool ignoreStart = false,
bool startedBodyOut = false,
ENUM_TIMEFRAMES forPeriod = NULL //
)
{
//
bool result = false;
//
isBodyOut = false;
breakedBar.Clean();
//
result = HasDirection(forDir) &&
IsValidTwoBarZone();
if (!result)
{
return result;
}
//
bool isBullish = IsBullish(forDir);
//
if (!IsSpecifiedValid(forPeriod))
{
forPeriod = GetPeriod();
}
//
int fromIndex = -1;
if (!ignoreStart)
{
//
XOHCL startedBar;
bool isBodyOut = false;
bool isStarted = IsStarted(
forDir,
startedBar,
isBodyOut,
forPeriod //
);
//
bool isStartPassed =
!startedBodyOut
? isStarted
: isStarted &&
isBodyOut;
if (isStartPassed)
{
fromIndex = startedBar.Index() - 1;
}
//
startedBar.Clean();
}
else
{
//
fromIndex = iBarShift(
GetSymbol(),
forPeriod,
From() //
);
}
//
result = IsValidIndex(fromIndex);
if (!result)
{
return result;
}
//
for (int i = fromIndex; i >= 0; i--)
{
//
XOHCL iBar;
bool isInited = iBar.Init(
GetSymbol(),
forPeriod,
i //
);
result = isInited;
if (!result)
{
//
iBar.Clean();
continue;
}
//
bool isBreakedFromUpper =
//
iBar.low > Upper() ||
(iBar.low <= Upper() &&
iBar.high > Upper() &&
iBar.close > Upper())
//
;
//
bool isBreakedFromLower =
//
iBar.low < Lower() ||
(iBar.high >= Lower() &&
iBar.low < Lower() &&
iBar.close < Lower())
//
;
//
bool isBreaked =
isBreakedFromUpper ||
isBreakedFromLower;
if (isBreaked)
{
//
result = isBreaked &&
isBullish
? isBreakedFromLower
: isBreakedFromUpper;
if (result)
{
//
breakedBar = iBar;
iBar.Clean();
break;
}
}
//
iBar.Clean();
}
//
result = breakedBar.IsValid();
if (result)
{
//
isBodyOut =
isBullish
? breakedBar.IsBearish() &&
breakedBar.GetDown() < Lower()
: breakedBar.IsBullish() &&
breakedBar.GetUp() > Upper();
}
//
return result;
}
/**
* Check Zone Worked or not ...
*
* @param forDir: exit direction ...
* @param workedBar: specified Worked Bar ...
* @param isBodyOut: specified Worked Bar Close is Out of Zone or not ...
* @param ignoreActivation: Ignore Zone Activation (Calculate from From()) ...
* @param activationStartedOut: Specified Zone Start Bar State ...
* @param activationBodyIn: Specified Zone Activation Bar State ...
* @param forPeriod: specified Period ...
*
* @return ( bool )
*/
bool IsWorked(
ENUM_X_DIRECTION forDir,
XOHCL &workedBar,
bool &isBodyOut,
bool ignoreActivation = false,
bool activationStartedOut = false,
bool activationBodyIn = false,
ENUM_TIMEFRAMES forPeriod = NULL //
)
{
//
bool result = false;
//
isBodyOut = false;
workedBar.Clean();
//
result = HasDirection(forDir) &&
IsValidTwoBarZone();
if (!result)
{
return result;
}
//
bool isBullish = IsBullish(forDir);
//
if (!IsSpecifiedValid(forPeriod))
{
forPeriod = GetPeriod();
}
//
int fromIndex = -1;
if (!ignoreActivation)
{
//
XOHCL activatedBar;
bool isBodyIn = false;
bool isActivated = IsActivated(
forDir,
activatedBar,
isBodyIn,
activationStartedOut,
forPeriod //
);
//
bool isActivationPassed =
!activationBodyIn
? isActivated
: isActivated &&
isBodyIn;
if (isActivationPassed)
{
fromIndex = activatedBar.Index() - 1;
}
//
activatedBar.Clean();
}
else
{
//
fromIndex = iBarShift(
GetSymbol(),
forPeriod,
From() //
);
}
//
result = IsValidIndex(fromIndex);
if (!result)
{
return result;
}
//
for (int i = fromIndex; i >= 0; i--)
{
//
XOHCL iBar;
bool isInited = iBar.Init(
GetSymbol(),
forPeriod,
i //
);
result = isInited;
if (!result)
{
//
iBar.Clean();
continue;
}
//
bool isBreakedFromUpper =
//
iBar.low > Upper() ||
(iBar.low <= Upper() &&
iBar.high > Upper() &&
iBar.close > Upper())
//
;
//
bool isBreakedFromLower =
//
iBar.low < Lower() ||
(iBar.high >= Lower() &&
iBar.low < Lower() &&
iBar.close < Lower())
//
;
//
bool isBreaked =
isBreakedFromUpper ||
isBreakedFromLower;
if (isBreaked)
{
//
result = isBreaked &&
isBullish
? isBreakedFromUpper
: isBreakedFromLower;
if (result)
{
//
workedBar = iBar;
iBar.Clean();
break;
}
}
//
iBar.Clean();
}
//
result = workedBar.IsValid();
if (result)
{
//
isBodyOut =
isBullish
? workedBar.IsBullish() &&
workedBar.GetUp() > Upper()
: workedBar.IsBearish() &&
workedBar.GetDown() < Lower();
}
//
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 =
//
"ConsolidationZone" + "_" +
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;
}
};
//
struct XOBFVG
{
//
// Props ...
XCFVG *fvg;
XCOrderBlock *ob;
//
XCSupplyZone *supplyZones[];
XCDemandZone *demandZones[];
//
XCSupportZone *supportZones[];
XCResistanceZone *resistanceZones[];
//
// Constructor ...
XOBFVG()
{
Clean();
}
//
// Tools ...
//
void Clean()
{
//
ZeroMemory(ob);
ZeroMemory(fvg);
}
//
bool IsValid()
{
return HasOB() &&
HasFVG();
}
//
bool HasOB()
{
return ob != NULL &&
ob.IsValid();
}
//
bool HasFVG()
{
return fvg != NULL &&
fvg.IsValid();
}
//
bool HasSupplyZones()
{
return HasChild(supplyZones);
}
//
int CountSupplyZones()
{
return ArraySize(supplyZones);
}
//
bool HasDemandZones()
{
return HasChild(demandZones);
}
//
int CountDemandZones()
{
return ArraySize(demandZones);
}
//
bool HasSupportZones()
{
return HasChild(supportZones);
}
//
int CountSupportZones()
{
return ArraySize(supportZones);
}
//
bool HasResistanceZones()
{
return HasChild(resistanceZones);
}
//
int CountResistanceZones()
{
return ArraySize(resistanceZones);
}
//
void UpdateTo(datetime value = NULL)
{
//
value = NormalizeTime(value);
//
int count = 0;
bool has = false;
//
if (HasOB())
{
ob.To(value);
}
//
if (HasFVG())
{
fvg.To(value);
}
//
// Supply Zones ...
has = HasSupplyZones();
if (has)
{
//
count = CountSupplyZones();
for (int i = 0; count; i++)
{
supplyZones[i].To(value);
}
}
//
// Demand Zones ...
has = HasDemandZones();
if (has)
{
//
count = CountDemandZones();
for (int i = 0; count; i++)
{
demandZones[i].To(value);
}
}
//
// Support Zones ...
has = HasSupportZones();
if (has)
{
//
count = CountSupportZones();
for (int i = 0; count; i++)
{
supportZones[i].To(value);
}
}
//
// Resistance Zones ...
has = HasResistanceZones();
if (has)
{
//
count = CountResistanceZones();
for (int i = 0; count; i++)
{
resistanceZones[i].To(value);
}
}
}
};
//
// 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 forceSideOut = 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 = IsBoxInside(
sourceBox,
destBox,
forceSideOut //
);
//
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;
}
/**
* 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 ...
* @param forceSideOut: bool, force check Box has One Side Out ...
* @param ignoreSideOut: bool, Accept if source Box one Side is out of Dest Box ...
*
* @return ( bool )
*/
bool IsBoxInside(
XBoxZone &source,
XBoxZone &dest,
bool forceSideOut = false, //
bool ignoreSideOut = true //
)
{
//
bool result = false;
//
result = source.IsValid() &&
dest.IsValid() &&
!source.IsSame(dest);
if (!result)
{
return result;
}
//
bool isBullish = IsBullish(dest.dir);
//
if (!forceSideOut)
{
//
if (ignoreSideOut)
{
//
result = source.lower >= dest.lower &&
source.upper <= dest.upper;
}
else
{
result = source.lower >= dest.lower ||
source.upper <= dest.upper;
}
}
else
{
//
bool hasSideIn =
isBullish
? source.lower >= dest.lower
: source.upper <= dest.upper;
bool hasSideOut =
isBullish
? source.upper >= dest.upper
: source.lower <= dest.lower;
result =
hasSideIn &&
hasSideOut;
}
//
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;
}
/**
* Check a Box is Used or not ...
*
* @param box: XBoxZone instance Reference ...
* @param fromIndex: int ...
* @param toIndex: int
* @param forPeriod: Specified Period ...
*
* @return ( bool )
*/
bool IsBoxUsed(
XBoxZone &box,
int fromIndex,
int toIndex = 0,
ENUM_TIMEFRAMES forPeriod = NULL //
)
{
//
bool result = false;
//
if (toIndex < 0)
{
toIndex = 0;
}
//
result =
//
box.IsValid() &&
fromIndex > 0 &&
fromIndex > toIndex
//
;
if (!result)
{
return result;
}
//
if (!IsValid(forPeriod))
{
forPeriod = box.period;
}
//
ENUM_X_DIRECTION forDir = box.dir;
bool isBullish = IsBullish(forDir);
//
for (int i = fromIndex; i >= toIndex; i--)
{
//
XOHCL iBar;
bool isInited = iBar.Init(
box.symbol,
forPeriod,
i //
);
//
bool isTouched =
isBullish
? iBar.high > box.lower
: iBar.low < box.upper;
if (!isTouched)
{
continue;
}
//
iBar.Clean();
result = false;
break;
}
//
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;
}
/**
* Converts to XBoxZone ...
*
* @return ( bool )
*/
bool ToBox(
XBoxZone &box,
XConsolidationZone &item //
)
{
//
bool result = false;
//
box.Clean();
//
result = item.IsValid();
if (!result)
{
return result;
}
//
box.upper = item.upper;
box.lower = item.lower;
box.dir = item.breakDir;
box.from = item.initTime;
box.symbol = item.symbol;
box.period = item.period;
box.to = item.breakerBar.time;
box.type = "X_CONSOLIDATION_ZONE";
//
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;
}
}
//
selected.Clean();
//
return result;
}
/**
* Extract XOBFVG Collection of Market ...
*
* @param htfState: Higher Time Frame POI State (Used For Detecting Order Blocks) ...
* @param mtfState: Medium Time Frame POI State (Used For Detecting Fair Value Gaps) ...
* @param stfState: Short Time Frame POI State (Used For Detecting Other POI(s)) ...
* @param dest: Result Collection ...
* @param forDir: Market Direction for Detecting POI(s) ...
* @param forPeriod: Time Frame which Used for Zones actions (NULL for Default) ...
* @param startState: Zones Start State ...
* @param forceStartedBodyOut: Zones Started Bar's Body State ...
* @param activeState: Zones Activation State ...
* @param forceActivatedBodyIn: Zones Activated Bar's Body State ...
* @param breakState: Zones Breaked State ...
* @param forceBreakedBodyOut: Zone Breaker Bar's Body State ...
* @param workState: Zones Worked State ...
* @param forceWorkedBodyOut: Zones Worked Bar's Body State ...
* @param applySort: Specify Applying Sorting on Collections ...
* @param applyFromFilter: Filter Sorted Zones based on Occured Date ...
* @param applyPlaceFilter: Filter Sorted Zones based on Occured Place ...
* @param ignoreInside: Ignore Inside Sides of POI(s) Zones in Related to Order Block ...
*
* @return ( int )
*/
int ExtractOBFVGZones(
XPOIState &htfState,
XPOIState &mtfState,
XPOIState &stfState,
XOBFVG &dest[],
//
ENUM_X_DIRECTION forDir,
ENUM_TIMEFRAMES forPeriod = NULL,
//
// Start ...
ENUM_XZONE_STATE startState = XZONE_STATE_PASSED,
bool forceStartedBodyOut = false,
//
// Activation ...
ENUM_XZONE_STATE activeState = XZONE_STATE_FAILED,
bool forceActivatedBodyIn = false,
//
// Breaktion ...
ENUM_XZONE_STATE breakState = XZONE_STATE_FAILED,
bool forceBreakedBodyOut = false,
//
// Works ...
ENUM_XZONE_STATE workState = XZONE_STATE_FAILED,
bool forceWorkedBodyOut = false,
//
bool applySort = true,
bool applyFromFilter = true,
bool applyPlaceFilter = true,
//
bool ignoreInside = true
//
)
{
//
int result = 0;
//
Clean(dest);
//
bool isValid =
//
htfState.HasChild() &&
mtfState.HasChild() &&
stfState.HasChild() &&
HasDirection(forDir)
//
;
if (!isValid)
{
return result;
}
//
// Implement Logic ...
//
int idx = -1;
int count = 0;
bool has = false;
XCFVG *tmpFVGs[];
XOBFVG tmpOBFVGs[];
XCOrderBlock *tmpOBs[];
XCOrderBlock *tmpWorkingOBs[];
datetime cTime = TimeCurrent();
bool isBullish = IsBullish(forDir);
//
if (isBullish)
{
//
has = htfState.HasBullishOrderBlocks();
if (has)
{
//
Copy(
htfState.bullishOrderBlocks,
tmpOBs //
);
//
has = mtfState.HasBullishFairValueGaps();
if (has)
{
//
Copy(
mtfState.bullishFairValueGaps,
tmpFVGs //
);
}
}
}
else
{
//
has = htfState.HasBearishOrderBlocks();
if (has)
{
//
Copy(
htfState.bearishOrderBlocks,
tmpOBs //
);
//
has = mtfState.HasBearishFairValueGaps();
if (has)
{
//
Copy(
mtfState.bearishFairValueGaps,
tmpFVGs //
);
}
}
}
//
count = ArraySize(tmpOBs);
has = IsValidSize(count);
if (has)
{
//
for (int i = 0; i < count; i++)
{
//
XCOrderBlock *iOB = tmpOBs[i];
//
// Check Started State ...
if (startState == XZONE_STATE_PASSED ||
startState == XZONE_STATE_FAILED)
{
//
XOHCL passedBar;
bool isBodyOut = false;
bool isStarted = iOB.IsStarted(
forDir,
passedBar,
isBodyOut,
forPeriod //
);
//
bool isPassed =
startState == XZONE_STATE_FAILED
? !isStarted
: !forceStartedBodyOut
? isStarted
: isStarted &&
isBodyOut;
//
passedBar.Clean();
if (!isPassed)
{
continue;
}
}
//
// Check Activation State ...
if (activeState == XZONE_STATE_PASSED ||
activeState == XZONE_STATE_FAILED)
{
//
XOHCL passedBar;
bool isBodyIn = false;
bool isActivated = iOB.IsActivated(
forDir,
passedBar,
isBodyIn,
forceStartedBodyOut,
forPeriod //
);
//
bool isPassed =
activeState == XZONE_STATE_FAILED
? !isActivated
: !forceActivatedBodyIn
? isActivated
: isActivated &&
isBodyIn;
//
passedBar.Clean();
if (!isPassed)
{
continue;
}
}
//
// Check Break State ...
if (breakState == XZONE_STATE_PASSED ||
breakState == XZONE_STATE_FAILED)
{
//
XOHCL passedBar;
bool isBodyOut = false;
bool isBreaked = iOB.IsBreaked(
forDir,
passedBar,
isBodyOut,
forceStartedBodyOut,
forPeriod //
);
//
bool isPassed =
breakState == XZONE_STATE_FAILED
? !isBreaked
: !forceBreakedBodyOut
? isBreaked
: isBreaked &&
isBodyOut;
//
passedBar.Clean();
if (!isPassed)
{
continue;
}
}
//
// Check Work State ...
if (workState == XZONE_STATE_PASSED ||
workState == XZONE_STATE_FAILED)
{
//
bool ignoreActivation = activeState != XZONE_STATE_PASSED;
//
XOHCL passedBar;
bool isBodyOut = false;
bool isWorked = iOB.IsWorked(
forDir,
passedBar,
isBodyOut,
ignoreActivation,
forceStartedBodyOut,
forceActivatedBodyIn,
forPeriod //
);
//
bool isPassed =
workState == XZONE_STATE_FAILED
? !isWorked
: !forceWorkedBodyOut
? isWorked
: isWorked &&
isBodyOut;
//
passedBar.Clean();
if (!isPassed)
{
continue;
}
}
//
has = FindIndex(
idx,
iOB,
tmpWorkingOBs //
);
if (has)
{
continue;
}
//
Add(
iOB,
tmpWorkingOBs //
);
}
}
//
// Clean ...
Clean(tmpOBs);
has = HasChild(tmpWorkingOBs);
if (has)
{
//
Clean(tmpOBs);
Copy(
tmpWorkingOBs,
tmpOBs //
);
//
Clean(tmpWorkingOBs);
}
//
// Sorting ...
if (applySort)
{
//
Clean(tmpWorkingOBs);
has = HasChild(tmpOBs);
count = ArraySize(tmpOBs);
//
// Sorting Applied Only when there is more than one item ...
if (has && count > 1)
{
//
bool hasLast = false;
XCOrderBlock *last = NULL;
while (HasChild(tmpOBs))
{
//
// Extract First Last Item ...
if (!hasLast)
{
//
idx =
isBullish
? GetLowest(tmpOBs)
: GetHighest(tmpOBs);
hasLast = IsValidIndex(idx);
if (hasLast)
{
//
last = tmpOBs[idx];
ArrayRemove(
tmpOBs,
idx,
1 //
);
//
Add(
last,
tmpWorkingOBs //
);
}
}
//
has = false;
XCOrderBlock *iOB = NULL;
idx =
isBullish
? GetLowest(tmpOBs)
: GetHighest(tmpOBs);
has = IsValidIndex(idx);
if (has)
{
//
iOB = tmpOBs[idx];
ArrayRemove(
tmpOBs,
idx,
1 //
);
}
//
if (!has)
{
break;
}
//
// Apply From Filter ...
if (applyFromFilter)
{
//
bool isFromPassed =
hasLast &&
last.From() < iOB.From();
if (!isFromPassed)
{
continue;
}
}
//
// Apply Place Filter ...
if (applyPlaceFilter)
{
//
bool isAbove =
hasLast &&
IsAbove(
iOB,
last,
ignoreInside //
);
//
bool isBelow =
hasLast &&
IsBelow(
iOB,
last,
ignoreInside //
);
//
bool isPlacePassed =
isBullish
? isAbove
: isBelow;
if (!isPlacePassed)
{
continue;
}
}
//
last = iOB;
Add(
iOB,
tmpWorkingOBs //
);
}
//
if (hasLast &&
!HasChild(tmpWorkingOBs))
{
//
Add(
last,
tmpWorkingOBs //
);
}
}
else
{
//
Copy(
tmpOBs,
tmpWorkingOBs //
);
}
//
if (HasChild(tmpWorkingOBs))
{
//
Copy(
tmpWorkingOBs,
tmpOBs //
);
}
//
}
//
count = ArraySize(tmpOBs);
has = IsValidSize(count);
//
// Converts to XOBFVG ...
if (has)
{
//
for (int i = 0; i < count; i++)
{
//
XOBFVG iOBFVG;
//
iOBFVG.ob = tmpOBs[i];
//
AddRef(
iOBFVG,
tmpOBFVGs //
);
}
}
//
Clean(dest);
Clean(tmpOBs);
Clean(tmpWorkingOBs);
//
// Here we Going to Complete XOBFVGs ...
has = HasChild(tmpOBFVGs);
if (has && HasChild(tmpFVGs))
{
//
count = ArraySize(tmpOBFVGs);
for (int i = 0; i < count; i++)
{
//
XOBFVG iOBFVG = tmpOBFVGs[i];
//
// Detecting FVG ...
XCFVG *tmpWorkingFVGs[];
for (int j = 0; j < ArraySize(tmpFVGs); j++)
{
//
XCFVG *jFVG = tmpFVGs[j];
//
// Check Start Date ...
bool isFromPassed = jFVG.From() > iOBFVG.ob.From();
if (!isFromPassed)
{
//
ZeroMemory(jFVG);
continue;
}
//
// Check Place ...
//
bool isAbove = IsAboveDiff(
jFVG,
iOBFVG.ob,
ignoreInside //
);
//
bool isBelow = IsBelowDiff(
jFVG,
iOBFVG.ob,
ignoreInside //
);
//
bool isInside = IsInsideDiff(
jFVG,
iOBFVG.ob,
false //
);
//
bool isPlacePassed =
isInside ||
(isBullish
? isAbove
: isBelow);
if (!isPlacePassed)
{
//
ZeroMemory(jFVG);
continue;
}
//
Add(
jFVG,
tmpWorkingFVGs //
);
}
//
int fvgsCount = ArraySize(tmpWorkingFVGs);
has = IsValidSize(fvgsCount);
if (has)
{
//
idx =
isBullish
? GetLowest(tmpWorkingFVGs)
: GetHighest(tmpWorkingFVGs);
//
if (IsValidIndex(idx))
{
//
XCFVG *selectedFVG = tmpWorkingFVGs[idx];
//
iOBFVG.fvg = selectedFVG;
//
bool isExists = FindIndex(
idx,
selectedFVG,
tmpFVGs //
);
if (isExists)
{
//
ArrayRemove(
tmpFVGs,
idx,
1 //
);
}
}
}
Clean(tmpWorkingFVGs);
//
bool isFVGPassed = iOBFVG.HasFVG();
if (!isFVGPassed)
{
//
iOBFVG.Clean();
continue;
}
//
// Validate Model ...
bool isValid = iOBFVG.IsValid();
if (!isValid)
{
//
iOBFVG.Clean();
continue;
}
//
iOBFVG.UpdateTo(cTime);
//
AddRef(
iOBFVG,
dest //
);
//
iOBFVG.Clean();
}
//
Clean(tmpOBFVGs);
}
//
// Detecting Other POI(s) ...
has = HasChild(dest);
if (has)
{
//
count = ArraySize(dest);
for (int i = 0; i < count; i++)
{
//
// Supply Zones ...
has = stfState.HasSupplyZones();
if (has)
{
//
for (int j = 0; j < stfState.CountSupplyZones(); j++)
{
//
bool isInsideOB = IsInsideDiff(
stfState.supplyZones[j],
dest[i].ob,
false //
) ||
IsInsideDiff(
stfState.supplyZones[j],
dest[i].ob,
true //
);
//
bool isInsideFVG = IsInsideDiff(
stfState.supplyZones[j],
dest[i].fvg,
false //
) ||
IsInsideDiff(
stfState.supplyZones[j],
dest[i].fvg,
true //
);
//
bool isInside = isInsideOB ||
isInsideFVG;
if (isInside)
{
//
Add(
stfState.supplyZones[j],
dest[i].supplyZones //
);
}
}
}
//
// Demand Zones ...
has = stfState.HasDemandZones();
if (has)
{
//
for (int j = 0; j < stfState.CountDemandZones(); j++)
{
//
bool isInsideOB = IsInsideDiff(
stfState.demandZones[j],
dest[i].ob,
false //
) ||
IsInsideDiff(
stfState.demandZones[j],
dest[i].ob,
true //
);
//
bool isInsideFVG = IsInsideDiff(
stfState.demandZones[j],
dest[i].fvg,
false //
) ||
IsInsideDiff(
stfState.demandZones[j],
dest[i].fvg,
true //
);
//
bool isInside = isInsideOB ||
isInsideFVG;
if (isInside)
{
//
Add(
stfState.demandZones[j],
dest[i].demandZones //
);
}
}
}
//
// Support Zones ...
has = stfState.HasSupportZones();
if (has)
{
//
for (int j = 0; j < stfState.CountSupportZones(); j++)
{
//
bool isInsideOB = IsInsideDiff(
stfState.supportZones[j],
dest[i].ob,
false //
) ||
IsInsideDiff(
stfState.supportZones[j],
dest[i].ob,
true //
);
//
bool isInsideFVG = IsInsideDiff(
stfState.supportZones[j],
dest[i].fvg,
false //
) ||
IsInsideDiff(
stfState.supportZones[j],
dest[i].fvg,
true //
);
//
bool isInside = isInsideOB ||
isInsideFVG;
if (isInside)
{
//
Add(
stfState.supportZones[j],
dest[i].supportZones //
);
}
}
}
//
// Resistance Zones ...
has = stfState.HasResistanceZones();
if (has)
{
//
for (int j = 0; j < stfState.CountResistanceZones(); j++)
{
//
bool isInsideOB = IsInsideDiff(
stfState.resistanceZones[j],
dest[i].ob,
false //
) ||
IsInsideDiff(
stfState.resistanceZones[j],
dest[i].ob,
true //
);
//
bool isInsideFVG = IsInsideDiff(
stfState.resistanceZones[j],
dest[i].fvg,
false //
) ||
IsInsideDiff(
stfState.resistanceZones[j],
dest[i].fvg,
true //
);
//
bool isInside = isInsideOB ||
isInsideFVG;
if (isInside)
{
//
Add(
stfState.resistanceZones[j],
dest[i].resistanceZones //
);
}
}
}
}
}
//
Clean(tmpOBs);
Clean(tmpFVGs);
Clean(tmpOBFVGs);
//
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;
}
/**
* Check Trading Conditions based on Specified Box ...
*
* @param box: XBoxZone instance Reference, specified Box for Checking Conditions ...
* @param appliedBox: XBoxZone instance Reference, hold's Selected Box inside Parent which trading conditions happens on it ...
* @param swingBar: XOHCL instance Reference, holds Swing Bar if Exists ...
* @param breakerBar: XOHCL instance Reference, holds Breaker Bar if Exists ...
* @param rejectionBar: XOHCL instance Reference, holds Rejection Bar if Exists ...
* @param momentumBar: XOHCL instance Reference, holds Momentum Bar if Exists ...
* @param state: XPOIState instance Reference, provides requirement zone's for check Conditions ...
* @param barIndex: int, Specified Bar Index ...
* @param forPeriod: ENUM_TIMEFRAMES member, Specified Conditions Checking Period ...
*
* @return ( bool )
*/
bool CheckBoxForTradeConditions(
XBoxZone &box,
XBoxZone &appliedBox,
XOHCL &swingBar,
XOHCL &breakerBar,
XOHCL &rejectionBar,
XOHCL &momentumBar,
XPOIState &state,
int barIndex = 0,
ENUM_TIMEFRAMES forPeriod = NULL //
)
{
//
bool result = false;
//
swingBar.Clean();
appliedBox.Clean();
breakerBar.Clean();
momentumBar.Clean();
rejectionBar.Clean();
//
if (barIndex < 0)
{
barIndex = 0;
}
//
result = box.IsValid() &&
state.IsValid() &&
state.HasChild();
if (!result)
{
return result;
}
//
if (!IsValid(forPeriod))
{
forPeriod = box.period;
}
//
string symbol = box.symbol;
datetime cTime = iTime(
symbol,
forPeriod,
barIndex //
);
//
ENUM_X_DIRECTION forDir = box.dir;
result = HasDirection(forDir);
if (!result)
{
return result;
}
//
bool isBullish = IsBullish(forDir);
//
int supportsCount = 0;
bool hasSupports = false;
XCSupportZone *supports[];
//
int resistancesCount = 0;
bool hasResistances = false;
XCResistanceZone *resistances[];
//
XBoxZone supResBoxes[];
int supresBoxesCount = 0;
bool hasSupResBoxes = false;
//
int count = 0;
bool has = false;
//
has = state.HasSupportZones();
if (has)
{
//
count = state.CountSupportZones();
for (int i = 0; i < count; i++)
{
//
XCSupportZone *iZone = state.supportZones[i];
//
iZone.To(cTime);
//
XBoxZone iBox;
bool hasBox = ToBox(
iBox,
iZone //
);
if (!hasBox)
{
//
iBox.Clean();
continue;
}
//
// Check From ...
bool isInside = IsBoxInside(
iBox,
box //
);
if (!isInside)
{
//
iBox.Clean();
continue;
}
//
Add(
iZone,
supports //
);
//
AddRef(
iBox,
supResBoxes //
);
//
iBox.Clean();
}
//
supportsCount = ArraySize(supports);
hasSupports = IsValidSize(supportsCount);
//
supresBoxesCount = ArraySize(supResBoxes);
hasSupResBoxes = IsValidSize(supresBoxesCount);
}
//
has = state.HasResistanceZones();
if (has)
{
//
count = state.CountResistanceZones();
for (int i = 0; i < count; i++)
{
//
XCResistanceZone *iZone = state.resistanceZones[i];
//
iZone.To(cTime);
//
XBoxZone iBox;
bool hasBox = ToBox(
iBox,
iZone //
);
if (!hasBox)
{
//
iBox.Clean();
continue;
}
//
// Check From ...
bool isInside = IsBoxInside(
iBox,
box //
);
if (!isInside)
{
//
iBox.Clean();
continue;
}
//
Add(
iZone,
resistances //
);
//
AddRef(
iBox,
supResBoxes //
);
//
iBox.Clean();
}
//
resistancesCount = ArraySize(resistances);
hasResistances = IsValidSize(resistancesCount);
//
supresBoxesCount = ArraySize(supResBoxes);
hasSupResBoxes = IsValidSize(supresBoxesCount);
}
//
result = hasSupResBoxes;
if (!result)
{
//
Clean(supports);
Clean(resistances);
Clean(supResBoxes);
//
return result;
}
//
// Detect Bars ...
//
XOHCL zBar;
result = zBar.Init(
symbol,
forPeriod,
barIndex //
);
if (!result)
{
//
zBar.Clean();
Clean(supports);
Clean(resistances);
Clean(supResBoxes);
//
return result;
}
//
XOHCL cBar;
result = zBar.GetPreviousBar(cBar);
if (!result)
{
//
zBar.Clean();
cBar.Clean();
Clean(supports);
Clean(resistances);
Clean(supResBoxes);
//
return result;
}
//
XOHCL pBar;
result = cBar.GetPreviousBar(pBar);
if (!result)
{
//
zBar.Clean();
cBar.Clean();
pBar.Clean();
Clean(supports);
Clean(resistances);
Clean(supResBoxes);
//
return result;
}
//
XOHCL ppBar;
result = pBar.GetPreviousBar(ppBar);
if (!result)
{
//
zBar.Clean();
cBar.Clean();
pBar.Clean();
ppBar.Clean();
Clean(supports);
Clean(resistances);
Clean(supResBoxes);
//
return result;
}
//
// Check Conditions ...
//
// Detect Start Senario ...
//
double fiboPressureLevel = GetFiboLevelValue(X_FIBO_LEVEL_382);
//
double fiboUpDown = GetFibonacciLevel(
pBar.high,
pBar.low,
X_FIBO_LEVEL_382,
X_DIRECTION_BEARISH //
);
double fiboDownUp = GetFibonacciLevel(
pBar.high,
pBar.low,
X_FIBO_LEVEL_382,
X_DIRECTION_BULLISH //
);
//
bool hasFiboToUpPressure =
fiboDownUp > 0 &&
fiboDownUp <= pBar.GetDown();
bool hasFiboToDownPressure =
fiboUpDown > 0 &&
fiboUpDown >= pBar.GetUp();
//
int selectedBoxIDX = -1;
for (int j = 0; j < supresBoxesCount; j++)
{
//
double appliedPrice =
isBullish
? supResBoxes[j].lower
: supResBoxes[j].upper;
//
// Check Swing Low ...
bool isSwingLow =
//
pBar.low < ppBar.low &&
pBar.low < cBar.low &&
zBar.open > pBar.low &&
//
appliedPrice > pBar.low &&
appliedPrice < pBar.GetDown()
//
;
bool isPressuredSwingLow =
isSwingLow &&
hasFiboToUpPressure;
bool isPressuredStrongSwingLow =
pBar.IsBullish() &&
isPressuredSwingLow;
//
bool isSwingHigh =
//
pBar.high > ppBar.high &&
pBar.high > cBar.high &&
zBar.open < pBar.high &&
//
appliedPrice < pBar.high &&
appliedPrice > pBar.GetUp()
//
;
bool isPressuredSwingHigh =
isSwingHigh &&
hasFiboToDownPressure;
bool isPressuredStrongSwingHigh =
pBar.IsBearish() &&
isPressuredSwingHigh;
//
bool hasValidSwing =
isBullish
? isSwingLow
: isSwingHigh;
bool hasValidPressuredSwing =
isBullish
? isPressuredSwingLow
: isPressuredSwingHigh;
bool hasValidPressuredStrongSwing =
isBullish
? isPressuredStrongSwingLow
: isPressuredStrongSwingHigh;
if (hasValidSwing)
{
swingBar = pBar;
}
if (hasValidPressuredSwing)
{
swingBar = pBar;
}
if (hasValidPressuredStrongSwing)
{
swingBar = pBar;
}
//
bool isCBarBreaked = IsBarBreak(
appliedPrice,
forDir,
cBar //
);
if (isCBarBreaked)
{
breakerBar = cBar;
}
bool isPBarBreaked = IsBarBreak(
appliedPrice,
forDir,
pBar //
);
if (!isCBarBreaked && isPBarBreaked)
{
breakerBar = pBar;
}
else
{
isPBarBreaked = false;
}
bool isPPBarBreaked = IsBarBreak(
appliedPrice,
forDir,
ppBar //
);
if (!isCBarBreaked &&
!isPBarBreaked &&
isPPBarBreaked)
{
breakerBar = ppBar;
}
else
{
isPPBarBreaked = false;
}
bool isBoxBreaked = isCBarBreaked ||
isPBarBreaked ||
isPPBarBreaked;
//
bool isCBarRejected = IsBarReject(
appliedPrice,
forDir,
cBar //
);
if (isCBarRejected)
{
rejectionBar = cBar;
}
bool isPBarRejected = IsBarReject(
appliedPrice,
forDir,
pBar //
);
if (!isCBarRejected && isPBarRejected)
{
rejectionBar = pBar;
}
else
{
isPBarRejected = false;
}
bool isPPBarRejected = IsBarReject(
appliedPrice,
forDir,
ppBar //
);
if (!isCBarRejected &&
!isPBarRejected &&
isPPBarRejected)
{
rejectionBar = ppBar;
}
else
{
isPPBarRejected = false;
}
bool isBoxRejected = isCBarRejected ||
isPBarRejected ||
isPPBarRejected;
//
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 (!rejectionBar.IsValid())
{
rejectionBar = 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 (!rejectionBar.IsValid())
{
rejectionBar = 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 ||
hasValidPressuredSwing))
//
||
//
(isBoxRejected &&
(hasRequiredValidations ||
hasValidPressuredSwing))
//
;
if (result)
{
//
selectedBoxIDX = j;
break;
}
}
//
result =
result &&
(isBullish
? zBar.open > box.upper
: zBar.open < box.lower) &&
IsValidIndex(selectedBoxIDX);
if (result)
{
appliedBox = supResBoxes[selectedBoxIDX];
}
//
zBar.Clean();
cBar.Clean();
pBar.Clean();
ppBar.Clean();
Clean(supports);
Clean(resistances);
Clean(supResBoxes);
//
return result;
}
//