Files
MQL5Data/Libraries/x-saherelm.x-poi.lib.mq5
T
2024-11-04 01:36:42 +03:30

2268 lines
38 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 2023, SaherElm IT Center"
#property link "https://www.saherelm.ir"
#property version "1.00"
#property strict
//
// Imports ...
#include "../Libraries/x-saherelm.common.lib.mq5"
//
// Definitions ...
//
// Definitions ...
//
// All Available POI(s) ...
enum ENUM_XPOIS
{
//
// 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 Start ...
X_TRADE_DAY_LAST_BAR, // Trading Day End ...
//
// Session ...
X_SESSION_FIRST_BAR, // Session First Bar ...
X_SESSION_LAST_BAR, // Session Last Bar ...
//
// Momentum Bar ...
X_MOMENTUM_BAR_DETECTED, // Momentum Bar ...
//
// Rejection Bar ...
X_REJECTION_BAR_DETECTED, // Rejection Bar ...
//
// Swings ...
X_SWING_HIGH_DETECTED,
X_SWING_LOW_DETECTED,
//
// Support nad Resistance ...
X_SUPPORT_ZONE_DETECTED, // Support Zone ...
X_RESISTANCE_ZONE_DETECTED, // Resistance Zone ...
//
// Supply nad Demand ...
X_SUPPLY_ZONE_DETECTED, // Supply Zone ...
X_DEMAND_ZONE_DETECTED, // Demand Zone ...
//
// Order Blocks ...
X_BULLISH_ORDERBLOCK_DETECTED, // Bullish Order Block ...
X_BEARISH_ORDERBLOCK_DETECTED, // Bearish Order Block ...
//
// Fair Value Gaps ...
X_BULLISH_FVG_DETECTED, // Bullish Fair Value Gapّ ...
X_BEARISH_FVG_DETECTED, // Bearish Fair Value Gapّ ...
};
//
// Forext Sessions ...
enum ENUM_XSESSION
{
X_TOKYO,
X_SYDNEY,
X_LONDON,
X_NEW_YORK,
X_FRANKFORT,
};
enum ENUM_X_ZONE_EDGE
{
X_ZONE_UPPER_EDGE,
X_ZONE_LOWER_EDGE
};
//
// Represent a Session Working Time ...
struct XSession
{
//
// Props ...
ENUM_XSESSION session; // Session Identifier
string start; // Start Time
string end; // End Time
//
bool allowDraw;
color startColor;
ENUM_LINE_STYLE startStyle;
color endColor;
ENUM_LINE_STYLE endStyle;
/**
* Constructor ...
*/
void XSession()
{
Clean();
}
/**
* Clean Structure ...
*/
void Clean()
{
//
start = NULL;
end = NULL;
//
allowDraw = false;
endColor = clrAqua;
endStyle = STYLE_DOT;
startColor = clrAqua;
endStyle = STYLE_DOT;
}
/**
* Validate Structure ...
*
* @return ( bool )
*/
bool IsValid()
{
//
bool result = false;
//
result = IsValid(start) &&
IsValid(end);
//
return result;
}
/**
* Initialize Specified Session ...
*
* @param _session: ENUM_XSESSION member ...
* @param _start: String (Session Start Time) ...
* @param _end: String (Session End Time) ...
*
* @return ( bool )
*/
bool Init(
ENUM_XSESSION _session,
string _start,
string _end //
)
{
//
bool result = false;
//
result = IsValid(_start) &&
IsValid(_end);
if (!result)
{
return result;
}
//
end = _end;
start = _start;
session = _session;
//
result = IsValid();
//
return result;
}
//
};
//
struct XTradeDay
{
//
datetime from;
datetime to;
//
void XTradeDay()
{
Clean();
}
//
void Clean()
{
//
from = NULL;
to = NULL;
}
//
bool IsValid()
{
//
bool result = false;
//
result = IsValid(from) &&
IsValid(to);
//
return result;
}
//
string GetTag()
{
//
string result = NULL;
//
if (!IsValid())
{
return result;
}
//
result = ToString(X_POI_TRADING_DAY) + "_" + ToFormatString(from) + "_" + ToFormatString(to);
//
return result;
}
//
};
//
// Detected Session ...
struct XMarketSession
{
//
ENUM_XSESSION session;
datetime from;
datetime to;
//
void XMarketSession()
{
Clean();
}
//
void Clean()
{
from = NULL;
to = NULL;
}
//
bool IsValid()
{
//
bool result = false;
//
result = IsValid(from) &&
IsValid(to);
//
return result;
}
//
string GetTag()
{
//
string result = NULL;
//
if (!IsValid())
{
return result;
}
//
result =
ToString(X_POI_MARKET_SESSION) + "_" +
ToString(session) + "_" +
ToFormatString(from) +
"_" +
ToFormatString(to) + "_";
//
return result;
}
};
//
// Zone Struct ...
struct XZone
{
//
// Props ...
double upper;
double lower;
string prefix;
//
datetime from;
datetime to;
//
// Constructor ...
void XZone()
{
Clean();
}
//
bool Init(
double _upper,
double _lower,
string _prefix,
datetime _from,
datetime _to //
)
{
//
bool result = false;
//
result =
_upper > 0 &&
_lower > 0 &&
_upper > _lower &&
IsValid(_prefix) &&
IsValid(_from);
if (!result)
{
return result;
}
//
NormalizeTime(_to);
//
upper = _upper;
lower = _lower;
prefix = _prefix;
from = _from;
to = _to;
//
result = IsValid();
//
return result;
}
//
void Clean()
{
//
upper = 0;
lower = 0;
//
to = NULL;
from = NULL;
prefix = NULL;
}
//
bool IsValid()
{
//
bool result = false;
//
result = upper > 0 &&
lower > 0 &&
upper > lower &&
IsValid(to) &&
IsValid(from) &&
IsValid(prefix);
//
return result;
}
//
double GetRange()
{
//
double result = 0;
//
if (!IsValid())
{
return result;
}
//
result = upper - lower;
//
return result;
}
//
double GetMiddle()
{
//
double result = 0;
//
double range = GetRange();
if (range <= 0)
{
return result;
}
//
result = lower + (range / 2);
//
return result;
}
//
string GetTag()
{
//
string result = NULL;
//
result = prefix + "_" +
ToString(upper) + "_" +
ToString(lower);
//
return result;
}
};
//
// XOHCL Event Handler ...
typedef void (*TXOHCLEventHandler)(
ENUM_XPOI_EVENTS event,
XOHCL &bar //
);
//
// POI Event Handler ...
typedef void (*TXPOIEventHandler)(
ENUM_XPOI_EVENTS event //
);
//
// Session Event Handler ...
typedef void (*TXSessionEventHandler)(
ENUM_XSESSION session,
ENUM_XPOI_EVENTS event //
);
//
// Zone Handler ...
typedef void (*TXZoneEventHandler)(
ENUM_XPOI_EVENTS event,
XZone &zone //
);
//
// Model Exists Founded POIs ...
struct XPOIState
{
//
string symbol;
ENUM_TIMEFRAMES period;
datetime reportedAt;
//
XTradeDay tradingDays[];
XMarketSession marketSessions[];
//
XOHCL momentumBars[];
XOHCL rejectionBars[];
//
XOHCL swingHighs[];
XOHCL swingLows[];
//
XOHCL supportZones[];
XOHCL resistanceZones[];
//
XZone supplyZones[];
XZone demandZones[];
//
XZone bullishOrderBlocks[];
XZone bearishOrderBlocks[];
//
XZone bullishFVGs[];
XZone bearishFVGs[];
//
// Constructor ...
void XPOIState()
{
Clean();
}
//
// Actions ...
/**
* Cleanup all props ...
*/
void Clean()
{
//
symbol = NULL;
period = NULL;
reportedAt = NULL;
//
Clean(tradingDays);
Clean(marketSessions);
//
Clean(momentumBars);
Clean(rejectionBars);
//
Clean(swingHighs);
Clean(swingLows);
//
Clean(supportZones);
Clean(resistanceZones);
//
Clean(supplyZones);
Clean(demandZones);
//
Clean(bullishOrderBlocks);
Clean(bearishOrderBlocks);
//
Clean(bullishFVGs);
Clean(bearishFVGs);
}
/**
* Fill Trading Days ...
*
* @param source: XTradeDay instance Collection ...
* @param forceClean: Boolean ...
*
* @return ( int )
*/
int FillTradingDays(
XTradeDay &source[],
bool forceClean = true //
)
{
//
int result = 0;
//
if (forceClean)
{
Clean(tradingDays);
}
//
int count = ArraySize(source);
if (!IsValidSize(count))
{
return result;
}
//
Copy(
source,
tradingDays //
);
result = ArraySize(tradingDays);
//
return result;
}
/**
* Fill Market Sessions ...
*
* @param source: XMarketSession instance Collection ...
* @param forceClean: Boolean ...
*
* @return ( int )
*/
int FillMarketSessions(
XMarketSession &source[],
bool forceClean = true //
)
{
//
int result = 0;
//
if (forceClean)
{
Clean(marketSessions);
}
//
int count = ArraySize(source);
if (!IsValidSize(count))
{
return result;
}
//
Copy(
source,
marketSessions //
);
result = ArraySize(marketSessions);
//
return result;
}
/**
* Fill Momentum Bars ...
*
* @param source: XOHCL instance Collection ...
* @param forceClean: Boolean ...
*
* @return ( int )
*/
int FillMomentumBars(
XOHCL &source[],
bool forceClean = true //
)
{
//
int result = 0;
//
if (forceClean)
{
Clean(momentumBars);
}
//
int count = ArraySize(source);
if (!IsValidSize(count))
{
return result;
}
//
Copy(
source,
momentumBars //
);
result = ArraySize(momentumBars);
//
return result;
}
/**
* Fill Retection Bars ...
*
* @param source: XOHCL instance Collection ...
* @param forceClean: Boolean ...
*
* @return ( int )
*/
int FillRejectionBars(
XOHCL &source[],
bool forceClean = true //
)
{
//
int result = 0;
//
if (forceClean)
{
Clean(rejectionBars);
}
//
int count = ArraySize(source);
if (!IsValidSize(count))
{
return result;
}
//
Copy(
source,
rejectionBars //
);
result = ArraySize(rejectionBars);
//
return result;
}
/**
* Fill Swing Highs ...
*
* @param source: XOHCL instance Collection ...
* @param forceClean: Boolean ...
*
* @return ( int )
*/
int FillSwingHighs(
XOHCL &source[],
bool forceClean = true //
)
{
//
int result = 0;
//
if (forceClean)
{
Clean(swingHighs);
}
//
int count = ArraySize(source);
if (!IsValidSize(count))
{
return result;
}
//
Copy(
source,
swingHighs //
);
result = ArraySize(swingHighs);
//
return result;
}
/**
* Fill Swing Lows ...
*
* @param source: XOHCL instance Collection ...
* @param forceClean: Boolean ...
*
* @return ( int )
*/
int FillSwingLows(
XOHCL &source[],
bool forceClean = true //
)
{
//
int result = 0;
//
if (forceClean)
{
Clean(swingLows);
}
//
int count = ArraySize(source);
if (!IsValidSize(count))
{
return result;
}
//
Copy(
source,
swingLows //
);
result = ArraySize(swingLows);
//
return result;
}
/**
* Fill Support Zones ...
*
* @param source: XOHCL instance Collection ...
* @param forceClean: Boolean ...
*
* @return ( int )
*/
int FillSupportZones(
XOHCL &source[],
bool forceClean = true //
)
{
//
int result = 0;
//
if (forceClean)
{
Clean(supportZones);
}
//
int count = ArraySize(source);
if (!IsValidSize(count))
{
return result;
}
//
Copy(
source,
supportZones //
);
result = ArraySize(supportZones);
//
return result;
}
/**
* Fill Resistance Zones ...
*
* @param source: XOHCL instance Collection ...
* @param forceClean: Boolean ...
*
* @return ( int )
*/
int FillResistanceZones(
XOHCL &source[],
bool forceClean = true //
)
{
//
int result = 0;
//
if (forceClean)
{
Clean(resistanceZones);
}
//
int count = ArraySize(source);
if (!IsValidSize(count))
{
return result;
}
//
Copy(
source,
resistanceZones //
);
result = ArraySize(resistanceZones);
//
return result;
}
/**
* Fill Supply Zones ...
*
* @param source: XZone instance Collection ...
* @param forceClean: Boolean ...
*
* @return ( int )
*/
int FillSupplyZones(
XZone &source[],
bool forceClean = true //
)
{
//
int result = 0;
//
if (forceClean)
{
Clean(supplyZones);
}
//
int count = ArraySize(source);
if (!IsValidSize(count))
{
return result;
}
//
Copy(
source,
supplyZones //
);
result = ArraySize(supplyZones);
//
return result;
}
/**
* Fill Demand Zones ...
*
* @param source: XZone instance Collection ...
* @param forceClean: Boolean ...
*
* @return ( int )
*/
int FillDemandZones(
XZone &source[],
bool forceClean = true //
)
{
//
int result = 0;
//
if (forceClean)
{
Clean(demandZones);
}
//
int count = ArraySize(source);
if (!IsValidSize(count))
{
return result;
}
//
Copy(
source,
demandZones //
);
result = ArraySize(demandZones);
//
return result;
}
/**
* Fill Bullish Order Blockss ...
*
* @param source: XZone instance Collection ...
* @param forceClean: Boolean ...
*
* @return ( int )
*/
int FillBullishOrderBlocks(
XZone &source[],
bool forceClean = true //
)
{
//
int result = 0;
//
if (forceClean)
{
Clean(bullishOrderBlocks);
}
//
int count = ArraySize(source);
if (!IsValidSize(count))
{
return result;
}
//
Copy(
source,
bullishOrderBlocks //
);
result = ArraySize(bullishOrderBlocks);
//
return result;
}
/**
* Fill Bearish Order Blockss ...
*
* @param source: XZone instance Collection ...
* @param forceClean: Boolean ...
*
* @return ( int )
*/
int FillBearishOrderBlocks(
XZone &source[],
bool forceClean = true //
)
{
//
int result = 0;
//
if (forceClean)
{
Clean(bearishOrderBlocks);
}
//
int count = ArraySize(source);
if (!IsValidSize(count))
{
return result;
}
//
Copy(
source,
bearishOrderBlocks //
);
result = ArraySize(bearishOrderBlocks);
//
return result;
}
/**
* Fill Bullish FVGs ...
*
* @param source: XZone instance Collection ...
* @param forceClean: Boolean ...
*
* @return ( int )
*/
int FillBullishFVGs(
XZone &source[],
bool forceClean = true //
)
{
//
int result = 0;
//
if (forceClean)
{
Clean(bullishFVGs);
}
//
int count = ArraySize(source);
if (!IsValidSize(count))
{
return result;
}
//
Copy(
source,
bullishFVGs //
);
result = ArraySize(bullishFVGs);
//
return result;
}
/**
* Fill Bearish FVGs ...
*
* @param source: XZone instance Collection ...
* @param forceClean: Boolean ...
*
* @return ( int )
*/
int FillBearishFVGs(
XZone &source[],
bool forceClean = true //
)
{
//
int result = 0;
//
if (forceClean)
{
Clean(bearishFVGs);
}
//
int count = ArraySize(source);
if (!IsValidSize(count))
{
return result;
}
//
Copy(
source,
bearishFVGs //
);
result = ArraySize(bearishFVGs);
//
return result;
}
//
};
//
// Extensions ...
/**
* Converts ENUM_XPOI value to String Representation ...
*
* @param value: ENUM_XPOI member ...
*
* @return ( string )
*/
string ToString(ENUM_XPOIS value)
{
//
string result = NULL;
//
switch (value)
{
//
case X_POI_TRADING_DAY:
result = "XTDAY";
break;
//
case X_POI_MARKET_SESSION:
result = "XMSESS";
break;
//
case X_POI_MOMENTUM_BAR:
result = "XMNTMB";
break;
//
case X_POI_REJECTION_BAR:
result = "XRJCTB";
break;
//
case X_POI_SWING_HIGH:
result = "XSPH";
break;
//
case X_POI_SWING_LOW:
result = "XSPL";
break;
//
case X_POI_SUPPORT_ZONE:
result = "XSUP";
break;
//
case X_POI_RESISTANCE_ZONE:
result = "XRES";
break;
//
case X_POI_SUPPLY_ZONE:
result = "XSUPPLY";
break;
//
case X_POI_DEMAND_ZONE:
result = "XDEMAND";
break;
//
case X_POI_BULLISH_ORDERBLOCK:
result = "XBULLOB";
break;
//
case X_POI_BEARISH_ORDERBLOCK:
result = "XBEAROB";
break;
//
case X_POI_BULLISH_FVG:
result = "XBULLFVG";
break;
//
case X_POI_BEARISH_FVG:
result = "XBEARFVG";
break;
}
//
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_MOMENTUM_BAR_DETECTED:
result = "Momentum Bar Detected";
break;
//
case X_REJECTION_BAR_DETECTED:
result = "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;
}
//
// XOHCL Extensions ...
/**
* Check two Bar is Same or not ...
*
* @param source: XOHCL instance ...
* @param dest: XOHCL instance ...
* @param force: Check also it's Dates ...
*
* @return ( bool )
*/
bool IsSame(
XOHCL &source,
XOHCL &dest //
)
{
//
bool result = false;
//
result = source.IsValid() &&
dest.IsValid();
if (!result)
{
return result;
}
//
result =
source.open == dest.open &&
source.close == dest.close &&
source.high == dest.high &&
source.low == dest.low;
if (!result)
{
return result;
}
//
return result;
}
/**
* Find Specific Items Index inside a Collection ...
*
* @param source: XOHCL instance ...
* @param dest: XOHCL instance Collection ...
*
* @return ( int )
*/
int FindIndex(
XOHCL &source,
XOHCL &dest[] //
)
{
//
int result = -1;
//
if (!source.IsValid())
{
return result;
}
//
int count = ArraySize(dest);
if (!IsValidSize(count))
{
return result;
}
//
for (int i = 0; i < count; i++)
{
//
XOHCL iBar = dest[i];
//
bool isSame = IsSame(
source,
iBar //
);
if (isSame)
{
//
result = i;
break;
}
}
//
return result;
}
/**
* Add Specific Bar to List only if Not Exists ...
*
* @param source: XOHCL instance ...
* @param dest: XOHCL instance Collection ...
*
* @return ( bool )
*/
bool AddIfNotExists(
XOHCL &source,
XOHCL &dest[] //
)
{
//
bool result = false;
//
result = source.IsValid();
if (!result)
{
return result;
}
//
int idx = FindIndex(source, dest);
bool isExists = IsValidIndex(idx);
if (!isExists)
{
//
AddRef(
source,
dest //
);
//
result = isExists;
}
//
return result;
}
//
// XZone Extensions ...
/**
* Check two Zone is Same or not ...
*
* @param source: XZone instance ...
* @param dest: XZone instance ...
* @param force: Check also it's Dates ...
*
* @return ( bool )
*/
bool IsSame(
XZone &source,
XZone &dest,
bool force = false //
)
{
//
bool result = false;
//
result = source.IsValid() &&
dest.IsValid();
if (!result)
{
return result;
}
//
result =
source.upper == dest.upper &&
source.lower == dest.lower;
if (!result)
{
return result;
}
//
if (force)
{
//
result =
source.from == dest.from &&
source.to == dest.to;
}
//
return result;
}
/**
* Find Specific Items Index inside a Collection ...
*
* @param source: XZone instance ...
* @param dest: XZone instance Collection ...
*
* @return ( int )
*/
int FindIndex(
XZone &source,
XZone &dest[] //
)
{
//
int result = -1;
//
if (!source.IsValid())
{
return result;
}
//
int count = ArraySize(dest);
if (!IsValidSize(count))
{
return result;
}
//
for (int i = 0; i < count; i++)
{
//
XZone iZone = dest[i];
//
bool isSame = IsSame(
source,
iZone //
);
if (isSame)
{
//
result = i;
break;
}
}
//
return result;
}
/**
* Add Specific Zone to List only if Not Exists ...
*
* @param source: XZone instance ...
* @param dest: XZone instance Collection ...
*
* @return ( bool )
*/
bool AddIfNotExists(
XZone &source,
XZone &dest[] //
)
{
//
bool result = false;
//
result = source.IsValid();
if (!result)
{
return result;
}
//
int idx = FindIndex(source, dest);
bool isExists = IsValidIndex(idx);
if (!isExists)
{
//
AddRef(
source,
dest //
);
//
result = isExists;
}
//
return result;
}
//
/**
* Check if a Zone inside another one ...
*
* @param source: XZone instance ...
* @param dest: XZone instance ...
* @param edge: ENUM_X_ZONE_EDGE member, define inside edge of zone ...
* @param forceInside: Boolean, if set true means all edges of source must be inside dest ...
*
* @return ( bool )
*/
bool IsInside(
XZone &source,
XZone &dest,
ENUM_X_ZONE_EDGE edge,
bool forceInside = true //
)
{
//
bool result = false;
//
result = source.IsValid() &&
dest.IsValid();
if (!result)
{
return result;
}
//
bool isEdgePassed =
//
edge == X_ZONE_UPPER_EDGE
? source.upper <= dest.upper
: source.lower >= dest.lower
//
;
//
bool isForcePassed =
//
forceInside
? edge == X_ZONE_UPPER_EDGE
? source.lower >= dest.lower
: source.upper <= dest.upper
: edge == X_ZONE_UPPER_EDGE
? true
: true
//
;
//
result = isEdgePassed &&
isForcePassed;
//
return result;
}
bool IsInside(
XOHCL &source,
XZone &dest,
ENUM_X_ZONE_EDGE edge,
bool forceInside = true //
)
{
//
bool result = false;
//
result = source.IsValid() &&
dest.IsValid();
if (!result)
{
return result;
}
//
XZone iSource;
double upper =
edge == X_ZONE_UPPER_EDGE
? source.high
: source.GetUp();
double lower =
edge == X_ZONE_UPPER_EDGE
? source.GetDown()
: source.low;
result = iSource.Init(
upper,
lower,
"XOHCL",
source.time,
TimeCurrent() //
);
if (!result)
{
return result;
}
//
result = IsInside(
iSource,
dest,
edge,
forceInside //
);
//
return result;
}
/**
* Check a Zone is Between to other Zones ...
*
* @param source: XZone instance ...
* @param upper: XZone instance ...
* @param lower: XZone instance ...
*
* @return ( bool )
*/
bool IsBetween(
XZone &source,
XZone &upper,
XZone &lower //
)
{
//
bool result = false;
//
result = source.IsValid();
if (!result)
{
return result;
}
//
bool isUpperValid = upper.IsValid();
bool isLowerValid = lower.IsValid();
//
result = isUpperValid ||
isLowerValid;
if (!result)
{
return result;
}
//
if (isUpperValid)
{
//
result = source.upper < upper.lower;
if (!result)
{
return result;
}
}
//
if (isLowerValid)
{
//
result = source.lower > lower.upper;
if (!result)
{
return result;
}
}
//
return result;
}
bool IsBetween(
XOHCL &source,
XZone &upper,
XZone &lower //
)
{
//
bool result = false;
//
result = source.IsValid();
if (!result)
{
return result;
}
//
bool isUpperValid = upper.IsValid();
bool isLowerValid = lower.IsValid();
//
result = isUpperValid ||
isLowerValid;
if (!result)
{
return result;
}
//
if (isUpperValid)
{
//
result = source.high < upper.lower;
if (!result)
{
return result;
}
}
//
if (isLowerValid)
{
//
result = source.low > lower.upper;
if (!result)
{
return result;
}
}
//
return result;
}
/**
* Check Source breaked Dest from Upper ...
*
* @param source: XZone instance ...
* @param dest: XZone instance ...
*
* @return ( bool )
*/
bool IsBreakeUpper(
XZone &source,
XZone &dest //
)
{
//
bool result = false;
//
result = source.IsValid() &&
dest.IsValid();
if (!result)
{
return result;
}
//
result =
//
// Check Boundary ...
source.lower <= dest.upper &&
source.lower >= dest.lower &&
//
// Check Break ...
source.upper > dest.upper
//
;
//
return result;
}
/**
* Check Source breaked Dest from Lower ...
*
* @param source: XZone instance ...
* @param dest: XZone instance ...
*
* @return ( bool )
*/
bool IsBreakeLower(
XZone &source,
XZone &dest //
)
{
//
bool result = false;
//
result = source.IsValid() &&
dest.IsValid();
if (!result)
{
return result;
}
//
result =
//
// Check Boundary ...
source.upper <= dest.upper &&
source.upper >= dest.lower &&
//
// Check Break ...
source.lower < dest.lower
//
;
//
return result;
}
//
// State Extensions ...
/**
* Normalize and Combine States ...
*
* @param dest: XPOIState instance ...ّ
* @param states: XPOIState instance ...ّ
*/
void CombineStates(
XPOIState &dest,
XPOIState &states[] //
)
{
//
dest.Clean();
//
int count = ArraySize(states);
if (!IsValidSize(count))
{
return;
}
//
for (int i = 0; i < count; i++)
{
//
XPOIState iState = states[i];
//
dest.symbol = iState.symbol;
dest.period =
!IsValid(dest.period) ||
PeriodSeconds(dest.period) < PeriodSeconds(iState.period)
? iState.period
: dest.period;
dest.reportedAt =
!IsValid(dest.reportedAt) ||
dest.reportedAt > iState.reportedAt
? iState.reportedAt
: dest.reportedAt;
//
// Demand ...
int iCount = ArraySize(iState.demandZones);
if (IsValidSize(iCount))
{
//
Copy(
iState.demandZones,
dest.demandZones,
false //
);
}
//
// Supply ...
iCount = ArraySize(iState.supplyZones);
if (IsValidSize(iCount))
{
//
Copy(
iState.supplyZones,
dest.supplyZones,
false //
);
}
//
// Order Blocks ...
//
iCount = ArraySize(iState.bullishOrderBlocks);
if (IsValidSize(iCount))
{
//
Copy(
iState.bullishOrderBlocks,
dest.bullishOrderBlocks,
false //
);
}
//
iCount = ArraySize(iState.bearishOrderBlocks);
if (IsValidSize(iCount))
{
//
Copy(
iState.bearishOrderBlocks,
dest.bearishOrderBlocks,
false //
);
}
//
// Fair Value Gaps ...
//
iCount = ArraySize(iState.bullishFVGs);
if (IsValidSize(iCount))
{
//
Copy(
iState.bullishFVGs,
dest.bullishFVGs,
false //
);
}
//
iCount = ArraySize(iState.bearishFVGs);
if (IsValidSize(iCount))
{
//
Copy(
iState.bearishFVGs,
dest.bearishFVGs,
false //
);
}
//
// Supports ...
iCount = ArraySize(iState.supportZones);
if (IsValidSize(iCount))
{
//
Copy(
iState.supportZones,
dest.supportZones,
false //
);
}
//
// Resistances ...
iCount = ArraySize(iState.resistanceZones);
if (IsValidSize(iCount))
{
//
Copy(
iState.resistanceZones,
dest.resistanceZones,
false //
);
}
//
// Swings ...
//
// Swing Highs ...
iCount = ArraySize(iState.swingHighs);
if (IsValidSize(iCount))
{
//
Copy(
iState.swingHighs,
dest.swingHighs,
false //
);
}
//
// Swing Lows ...
iCount = ArraySize(iState.swingLows);
if (IsValidSize(iCount))
{
//
Copy(
iState.swingLows,
dest.swingLows,
false //
);
}
//
// Momentum Bars ...
iCount = ArraySize(iState.momentumBars);
if (IsValidSize(iCount))
{
//
Copy(
iState.momentumBars,
dest.momentumBars,
false //
);
}
//
// Rejection Bars ...
iCount = ArraySize(iState.rejectionBars);
if (IsValidSize(iCount))
{
//
Copy(
iState.rejectionBars,
dest.rejectionBars,
false //
);
}
}
}
/**
* Check State has Bullish Trend or not ...
*
* @param state: XPOIState instance ...
*
* @return ( bool )
*/
bool HasBullishTrend(XPOIState &state)
{
//
bool result = false;
//
// For Bullish Trends ...
int count = ArraySize(state.swingLows);
result = count >= 2;
if (!result)
{
return result;
}
//
XOHCL lastSwing = state.swingLows[count - 1];
XOHCL prevSwing = state.swingLows[count - 2];
//
result = lastSwing.low > prevSwing.low;
//
return result;
}
/**
* Check State has Bearish Trend or not ...
*
* @param state: XPOIState instance ...
*
* @return ( bool )
*/
bool HasBearishTrend(XPOIState &state)
{
//
bool result = false;
//
// For Bullish Trends ...
int count = ArraySize(state.swingHighs);
result = count >= 2;
if (!result)
{
return result;
}
//
XOHCL lastSwing = state.swingHighs[count - 1];
XOHCL prevSwing = state.swingHighs[count - 2];
//
result = lastSwing.high < prevSwing.high;
//
return result;
}
//