Files
xMQL5/BKPS/14041018/Documents/BKP/tmp.poi.mq5
T
2026-01-08 11:39:42 +03:30

7183 lines
125 KiB
Plaintext

//
// All Available POI(s) ...
enum ENUM_XPOIS
{
//
X_POI_NONE,
//
X_POI_TICKS_ZONES, // Ticks Zone ...
//
// Trading Day ...
X_POI_TRADING_DAY, // Trading Day ...
//
// Market Session ...
X_POI_MARKET_SESSION, // Market Session ...
//
// Momentum Bar ...
X_POI_MOMENTUM_BAR, // Momentum Bar ...
//
// Rejection Bar ...
X_POI_REJECTION_BAR, // Rejection Bar ...
//
// Swings ...
X_POI_SWING_HIGH, // Simple Swing High ...
X_POI_SWING_LOW, // Simple Swing Low ...
//
// Support nad Resistance ...
X_POI_SUPPORT_ZONE, // Support Zone ...
X_POI_RESISTANCE_ZONE, // Resistance Zone ...
//
// Supply and Demand Zones ...
X_POI_SUPPLY_ZONE, // Supply Zone ...
X_POI_DEMAND_ZONE, // Demand Zone ...
//
// Order Blocks ...
X_POI_BULLISH_ORDERBLOCK, // Bullish Order Block ...
X_POI_BEARISH_ORDERBLOCK, // Bearish Order Block ...
//
// Fair Value Gaps ...
X_POI_BULLISH_FVG, // Bullish Order Block ...
X_POI_BEARISH_FVG, // Bearish Order Block ...
//
X_BULLISH_CONSOLIDATION_ZONE,
X_BEARISH_CONSOLIDATION_ZONE,
//
X_BULLISH_SHARP,
X_BEARISH_SHARP,
//
X_BULLISH_SPIKE,
X_BEARISH_SPIKE,
//
X_BULLISH_PULLBACK,
X_BEARISH_PULLBACK,
};
//
// Event Types ...
enum ENUM_XPOI_EVENTS
{
//
X_POI_EVENT_NONE,
//
// 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ّ ...
X_BULLISH_CONSOLIDATION_ZONE_DETECTED,
X_BEARISH_CONSOLIDATION_ZONE_DETECTED,
X_BULLISH_SHARP_DETECTED,
X_BEARISH_SHARP_DETECTED,
X_BULLISH_SPIKE_DETECTED,
X_BEARISH_SPIKE_DETECTED,
X_BULLISH_PULLBACK_DETECTED,
X_BEARISH_PULLBACK_DETECTED,
};
//
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,
};
/**
* 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;
//
case X_BULLISH_CONSOLIDATION_ZONE:
result = "XBULLCZ";
break;
//
case X_BEARISH_CONSOLIDATION_ZONE:
result = "XBEARCZ";
break;
//
case X_BULLISH_SPIKE:
result = "XBULLSPK";
break;
//
case X_BEARISH_SPIKE:
result = "XBEARSPK";
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;
}
//
// 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:
//
};
//
typedef void (*TOnPOIEvent)(ENUM_XPOI_EVENTS event,
XCBasePOI *param //
);
//
// 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,
ENUM_X_PRICE startPrice,
ENUM_X_PRICE endPrice //
)
{
//
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;
//
int startIndex = startBar.Index();
int endIndex = endBar.Index();
//
double mStartPrice = startBar.GetPrice(startPrice);
double mEndPrice = endBar.GetPrice(endPrice);
bool isStartOverEnd = mStartPrice > mEndPrice;
//
if (isStartOverEnd)
{
//
mUpperPrice = startPrice;
mLowerPrice = endPrice;
}
else
{
//
mUpperPrice = endPrice;
mLowerPrice = startPrice;
}
//
mUpper = MathMax(mStartPrice, mEndPrice);
mLower = MathMin(mStartPrice, mEndPrice);
//
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 useRangeAsStart = false //
)
{
//
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 =
!useRangeAsStart
? (datetime)((int)time - (range * periodSeconds))
: time;
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 useRangeAsStart = false //
)
{
//
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 =
!useRangeAsStart
? (datetime)((int)time - (range * periodSeconds))
: time;
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 useRangeAsStart = false //
)
{
//
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 =
!useRangeAsStart
? (datetime)((int)time - (range * periodSeconds))
: time;
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 useRangeAsStart = false //
)
{
//
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 =
!useRangeAsStart
? (datetime)((int)time - (range * periodSeconds))
: time;
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;
//
ENUM_X_PRICE startPrice = isDirBullish
? X_PRICE_HIGH
: X_PRICE_LOW;
ENUM_X_PRICE endPrice = isDirBullish
? X_PRICE_LOW
: X_PRICE_HIGH;
//
result = InitTwoBarZone(
startBar,
endBar,
mTT,
startPrice,
endPrice //
);
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)to * 1000);
ulong toM = ((ulong)from * 1000);
//
// Symbol and Period ...
string symbol = startBar.symbol;
ENUM_TIMEFRAMES period = startBar.period;
//
// Prepare Zones Array ...
mZones.Clear();
//
// Retrieve Ticks between Times ...
SpecificClean(mTicks);
int res = 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(endBar.time);
To(startBar.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;
}
//
bool GetMaxTickZone(XCTickZone *&zone)
{
//
bool result = false;
//
zone = NULL;
//
result = IsValid();
if (!result)
{
return result;
}
//
int count = Count();
for (int i = 0; i < count; i++)
{
//
XCTickZone *iZone = GetZone(i);
//
bool canSet =
zone == NULL
? true
: zone.ticks < iZone.ticks
? true
: false;
if (canSet)
{
zone = iZone;
}
//
ZeroMemory(iZone);
}
//
result = zone != NULL &&
zone.IsValid();
//
return result;
}
//
bool GetMinTickZone(XCTickZone *&zone)
{
//
bool result = false;
//
zone = NULL;
//
result = IsValid();
if (!result)
{
return result;
}
//
int count = Count();
for (int i = 0; i < count; i++)
{
//
XCTickZone *iZone = GetZone(i);
//
bool canSet =
zone == NULL
? true
: zone.ticks > iZone.ticks
? true
: false;
if (canSet)
{
zone = iZone;
}
//
ZeroMemory(iZone);
}
//
result = zone != NULL &&
zone.IsValid();
//
return result;
}
//
bool GetMaxVolumeZone(XCTickZone *&zone)
{
//
bool result = false;
//
zone = NULL;
//
result = IsValid();
if (!result)
{
return result;
}
//
int count = Count();
for (int i = 0; i < count; i++)
{
//
XCTickZone *iZone = GetZone(i);
//
bool canSet =
zone == NULL
? true
: zone.volume < iZone.volume
? true
: false;
if (canSet)
{
zone = iZone;
}
//
ZeroMemory(iZone);
}
//
result = zone != NULL &&
zone.IsValid();
//
return result;
}
//
bool GetMinVolumeZone(XCTickZone *&zone)
{
//
bool result = false;
//
zone = NULL;
//
result = IsValid();
if (!result)
{
return result;
}
//
int count = Count();
for (int i = 0; i < count; i++)
{
//
XCTickZone *iZone = GetZone(i);
//
bool canSet =
zone == NULL
? true
: zone.volume > iZone.volume
? true
: false;
if (canSet)
{
zone = iZone;
}
//
ZeroMemory(iZone);
}
//
result = zone != NULL &&
zone.IsValid();
//
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:
//
//
};
//
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 *&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 = 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.IsSameAs(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>
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>
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>
bool IsInsideOr(
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 = IsBoxInsideOr(
sourceBox,
destBox //
);
//
return result;
}
template <typename T>
bool FindIndex(
int &index,
T *item,
T *&items[] //
)
{
//
bool result = false;
//
index = -1;
//
XBoxZone itemBox;
result = ToBox(
itemBox,
item //
);
if (!result)
{
return result;
}
//
XBoxZone itemsBox[];
result = ToBox(
items,
itemsBox //
);
if (!result)
{
return result;
}
//
result = FindBoxIndex(
index,
itemBox,
itemsBox //
);
//
return result;
}
template <typename T>
bool IsInside(
double value,
T *source //
)
{
//
bool result = false;
//
XBoxZone sourceBox;
result = ToBox(
sourceBox,
source //
);
if (!result)
{
return result;
}
//
result = IsInsideBox(
value,
sourceBox //
);
//
return result;
}
template <typename T>
bool IsAbove(
double value,
T *source //
)
{
//
bool result = false;
//
XBoxZone sourceBox;
result = ToBox(
sourceBox,
source //
);
if (!result)
{
return result;
}
//
result = IsAboveBox(
value,
sourceBox //
);
//
return result;
}
template <typename T>
bool IsBelow(
double value,
T *source //
)
{
//
bool result = false;
//
XBoxZone sourceBox;
result = ToBox(
sourceBox,
source //
);
if (!result)
{
return result;
}
//
result = IsBelowBox(
value,
sourceBox //
);
//
return result;
}
//
//
//
//
template <typename T>
void SortZones(
T *&source[],
ENUM_X_DIRECTION forDir,
bool ignoreInside = true //
)
{
//
int idx = -1;
int count = 0;
bool has = false;
//
has = HasDirection(forDir);
if (!has)
{
return;
}
//
bool isBullish = IsBullish(forDir);
//
count = ArraySize(source);
has = IsValidSize(count);
if (!has)
{
return;
}
//
T *tmpItems[];
T *last = NULL;
bool hasLast = false;
while (HasChild(source))
{
//
if (!hasLast)
{
//
idx = GetOldest(source);
hasLast = IsValidIndex(idx);
if (hasLast)
{
//
last = source[idx];
ArrayRemove(
source,
idx,
1 //
);
//
Add(
last,
tmpItems //
);
}
//
count = ArraySize(source);
has = IsValidSize(count);
if (!has)
{
//
ZeroMemory(last);
break;
}
}
if (!hasLast)
{
//
ZeroMemory(last);
break;
}
//
T *item = NULL;
idx = GetOldest(source);
has = IsValidIndex(idx);
if (!has)
{
//
ZeroMemory(last);
ZeroMemory(item);
break;
}
item = source[idx];
ArrayRemove(
source,
idx,
1 //
);
//
bool isAbove = IsAbove(
item,
last,
ignoreInside //
);
//
bool isBelow = IsBelow(
item,
last,
ignoreInside //
);
//
has =
isBullish
? isAbove
: isBelow;
if (has)
{
//
Add(
item,
tmpItems //
);
//
last = item;
hasLast = item != NULL;
}
}
//
Clean(source);
Copy(
tmpItems,
source //
);
//
Clean(tmpItems);
}
/**
* Extract all Zones Which provided bar is Inside it ...
*
* @return ( int )
*/
template <typename T>
int ExtractInsideZones(
XOHCL &bar, // Bar ...
T *&zones[], // Source of Zones ...
T *&dest[] // Dest (all inside Zones) ...
)
{
//
int result = 0;
//
Clean(dest);
//
int count = ArraySize(zones);
bool isValid = bar.IsValid() &&
IsValidSize(count);
if (!isValid)
{
return result;
}
//
for (int i = 0; i < count; i++)
{
//
T *iZone = zones[i];
//
bool isHighInside = IsInside(
bar.high,
iZone //
);
//
bool isLowInside = IsInside(
bar.low,
iZone //
);
//
bool isInside =
isLowInside &&
isHighInside;
//
if (isInside)
{
//
Add(
iZone,
dest //
);
}
//
ZeroMemory(iZone);
}
//
result = ArraySize(dest);
//
return result;
}
/**
* Add Specific Item into a Collection Reference only if it's not Exists ...
*
* @return ( bool )
*/
template <typename T>
bool AddIfNotExists(
T *item,
T *&items[] //
)
{
//
bool result = false;
//
result = item != NULL;
if (!result)
{
return result;
}
//
int before = ArraySize(items);
//
int idx = FindIndex(
item,
items //
);
bool has = IsValidIndex(idx);
result = !has;
if (!result)
{
return result;
}
//
Add(
item,
items //
);
//
int after = ArraySize(items);
//
result = after > before;
//
return result;
}
/**
* Add items Collection reference Members into source Collection only if it's not Exists ...alignas
* @return ( int )
*/
template <typename T>
int AddIfNotExists(
T *&items[],
T *&sources[] //
)
{
//
int result = 0;
//
bool has = HasChild(items);
if (!has)
{
return result;
}
//
int before = ArraySize(sources);
//
int count = ArraySize(items);
for (int i = 0; i < count; i++)
{
//
has = AddIfNotExists(
items[i],
sources //
);
}
//
int after = ArraySize(sources);
//
result = after > before;
//
return result;
}
/**
* Update to Time of Specifiex Collection ...
*
* @param items: XOBFVG instance Collection ...
* @param value: datetime ...
*/
template <typename T>
void SpecifiedUpdateTo(
T *&items[],
datetime value = NULL //
)
{
//
value = NormalizeTime(value);
//
int count = ArraySize(items);
bool has = HasChild(items);
if (!has)
{
return;
}
//
for (int i = 0; i < count; i++)
{
items[i].To(value);
}
}
/**
* 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);
//
bool isTouched = false;
for (int i = fromIndex; i >= toIndex; i--)
{
//
XOHCL iBar;
bool isInited = iBar.Init(
box.symbol,
forPeriod,
i //
);
//
isTouched =
isInited &&
(isBullish
? iBar.low > box.upper
: iBar.high < box.lower);
if (!isTouched)
{
continue;
}
//
iBar.Clean();
break;
}
//
result = isTouched;
//
return result;
}
/**
* Validate Box ...
*
* @param box: XBoxZone instance ...
* @param barIndex: int, Current Bar Index ...
* @param forPeriod: Testing Period ...
*
* @return ( bool )
*/
bool IsBoxValid(
XBoxZone &box,
int barIndex = 0,
ENUM_TIMEFRAMES forPeriod = NULL //
)
{
//
bool result = false;
//
result = box.IsValid();
if (!result)
{
return result;
}
//
if (barIndex < 0)
{
barIndex = 0;
}
//
if (!IsValid(forPeriod))
{
forPeriod = box.period;
}
//
int toIndex = iBarShift(
box.symbol,
forPeriod,
box.to //
);
result = IsValidIndex(toIndex);
if (!result)
{
return result;
}
//
XOHCL iBar;
bool isBullish = box.IsBullish();
for (int i = barIndex; i < toIndex; i++)
{
//
result = iBar.Init(
box.symbol,
forPeriod,
i //
);
if (!result)
{
break;
}
//
result =
isBullish
? iBar.low > box.upper
: iBar.high < box.lower;
if (!result)
{
break;
}
//
iBar.Clean();
}
//
iBar.Clean();
//
return result;
}
/**
* Check Box Breaked ...
*
* @param box: XBoxZone instance ...
* @param barIndex: int, Current Bar Index ...
* @param forPeriod: Testing Period ...
*
* @return ( bool )
*/
bool IsBoxBreaked(
XBoxZone &box,
int barIndex = 0,
ENUM_TIMEFRAMES forPeriod = NULL //
)
{
//
bool result = false;
//
result = box.IsValid();
if (!result)
{
return result;
}
//
if (barIndex < 0)
{
barIndex = 0;
}
//
if (!IsValid(forPeriod))
{
forPeriod = box.period;
}
//
int toIndex = iBarShift(
box.symbol,
forPeriod,
box.to //
);
result = IsValidIndex(toIndex);
if (!result)
{
return result;
}
//
XOHCL iBar;
bool isBullish = box.IsBullish();
for (int i = barIndex; i < toIndex; i++)
{
//
result = iBar.Init(
box.symbol,
forPeriod,
i //
);
if (!result)
{
break;
}
//
result =
isBullish
? iBar.high < box.lower
: iBar.low > box.upper;
if (!result)
{
break;
}
//
iBar.Clean();
}
//
iBar.Clean();
//
return result;
}
/**
* Check a Box is Breaked or not ...
*
* @param box: XBoxZone instance Reference ...
* @param fromIndex: int ...
* @param toIndex: int
* @param forPeriod: Specified Period ...
*
* @return ( bool )
*/
bool IsBoxBreaked(
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);
//
bool isBreaked = false;
for (int i = fromIndex; i >= toIndex; i--)
{
//
XOHCL iBar;
bool isInited = iBar.Init(
box.symbol,
forPeriod,
i //
);
//
isBreaked =
isInited &&
(isBullish
? iBar.high <= box.lower
: iBar.low >= box.upper);
if (!isBreaked)
{
continue;
}
//
iBar.Clean();
break;
}
//
result = isBreaked;
//
return result;
}
/**
* Check a BaxHas Valid Place for Specified Bar ...
*
* @param bar: XOHCL instance reference, Specified Bar ...
* #param box: XBoxZone instance reference, Specified Box ...
*
* @return ( bool )
*/
bool IsBoxPlaceValidForBar(
XOHCL &bar,
XBoxZone &box //
)
{
//
bool result = false;
//
result = bar.IsValid() &&
box.IsValid();
if (!result)
{
return result;
}
//
result =
box.IsBullish()
? bar.low > box.upper
: bar.high < box.upper;
//
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.IsSameAs(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.IsSameAs(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.IsSameAs(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;
}
/**
* Detect source BoX is Inside Dest Box or Have a Side Out on it ...
*
* @param source: XBoxZone instance, source box which checks by dest ...
* @param dest: XBoxZone instance, dest Box which compares source with it ...
*
* @return ( bool )
*/
bool IsBoxInsideOr(
XBoxZone &source,
XBoxZone &dest,
bool forceInside = false //
)
{
//
bool result = false;
//
result = source.IsValid() &&
dest.IsValid() &&
!source.IsSameAs(dest);
if (!result)
{
return result;
}
//
bool isInside =
source.upper <= dest.upper &&
source.upper >= dest.lower &&
source.lower >= dest.lower &&
source.lower <= dest.upper;
bool isUpperInside =
source.upper <= dest.upper &&
source.upper >= dest.lower;
bool isLowerInside =
source.lower >= dest.lower &&
source.lower <= dest.upper;
//
result =
forceInside
? isInside
: (isInside ||
isLowerInside ||
isUpperInside);
//
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 Bar is Inside Specified Box ...
*
* @param bar: XOHCL instance reference, Specified Bar ...
* @param box: XCBozZone instance Reference ...
*
* @return ( bool )
*/
bool IsInsideBox(
XOHCL &bar,
XBoxZone &box //
)
{
//
bool result = false;
//
// Validate Args ...
result = bar.IsValid() &&
box.IsValid();
if (!result)
{
return result;
}
//
result =
bar.close <= box.upper &&
bar.close >= 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;
}
/**
* Find an Inside Box of source in a Collection ...
*
* @param index: int, Founded Index ...
* @param source: XBoxZone instance ...
* @param dest: XBoxZone instance Collection ...
*
* @return ( bool )
*/
bool HasInsideBox(
int &index,
XBoxZone &source,
XBoxZone &dest[] //
)
{
//
bool result = false;
//
index = -1;
//
result = source.IsValid() &&
HasChild(dest);
//
int count = ArraySize(dest);
for (int i = 0; i < count; i++)
{
//
XBoxZone iBox = dest[i];
//
bool isInside = !iBox.IsSameAs(source) &&
IsBoxInsideOr(
iBox,
source //
);
if (isInside)
{
//
index = i;
iBox.Clean();
//
break;
}
//
iBox.Clean();
}
//
result = IsValidIndex(index);
//
return result;
}
/////////////////////////////////////////////
//
// Analyse Bar Patterns ...
if (result && config.analyseBarPatterns)
{
//
// Try to Detect Bars Analysis ...
int fromIndex = -1;
if (!IsXValid(fromTime))
{
fromIndex = barIndex + config.loopback;
}
else
{
fromIndex = GetBarIndex(
symbol,
period,
fromTime //
);
}
result = IsValidIndex(fromIndex);
if (result)
{
//
fromIndex = MathMin(fromIndex, barIndex + config.requiredPivots);
//
for (int i = barIndex; i < fromIndex; i++)
{
//
tmpBar.Clean();
tmpBarAnalysis.Clean();
result = structure.bar.BarAt(i, tmpBar);
result = result &&
AnalyseBarPatterns(
tmpBar,
tmpBarAnalysis,
config.barsAnalysisConfig //
);
if (!result)
{
break;
}
//
AddRef(
tmpBarAnalysis,
structure.barsAnalysis //
);
}
}
}
////////////////////////////////////////////////
/**
* Draw Specified Market Structure Based on Given Configs ...
*
* @param structure: XFIMAMarketStructure, reference to Provide Specifid Market Structure ...
* @param config: XFIMAMarketStructureDrawerConfig, reference to Provide Drawing Configurations ...
*/
void DrawMarketStructure(
XFIMAMarketStructure &structure,
XFIMAMarketStructureDrawerConfig &config //
)
{
//
// Validate ...
bool has = structure.IsValid();
if (!has)
{
return;
}
//
// PV Analysis ...
if (config.drawPVAnalysis)
{
//
has = structure.pvAnalysis.IsValid();
if (has)
{
//
DrawPivotAnalysis(
structure.pvAnalysis,
config.pivotAnalysisDrawConfig //
);
}
}
//
// ZG Analysis ...
if (config.drawZGAnalysis)
{
//
has = structure.zgAnalysis.IsValid();
if (has)
{
//
DrawPivotAnalysis(
structure.zgAnalysis,
config.pivotAnalysisDrawConfig //
);
}
}
//
// Bars Analysis ...
if (config.drawBarsAnalysis)
{
//
int count = ArraySize(structure.barsAnalysis);
has = IsValidSize(count);
if (has)
{
//
for (int i = 0; i < count; i++)
{
//
DrawPatternAnalysis(
structure.barsAnalysis[i],
config.barAnalysisDrawConfig //
);
}
}
}
}