1829 lines
30 KiB
Plaintext
1829 lines
30 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;
|
|
}
|
|
|
|
//
|
|
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.GetDown();
|
|
double lower =
|
|
edge == X_ZONE_UPPER_EDGE
|
|
? source.GetUp()
|
|
: source.low;
|
|
result = iSource.Init(
|
|
upper,
|
|
lower,
|
|
"XOHCL",
|
|
source.time,
|
|
TimeCurrent() //
|
|
);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result = IsInside(
|
|
iSource,
|
|
dest,
|
|
edge,
|
|
forceInside //
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// State Extensions ...
|
|
|
|
/**
|
|
* 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;
|
|
}
|
|
|
|
// |