661 lines
12 KiB
Plaintext
661 lines
12 KiB
Plaintext
///////////////////////////////////////////////////////
|
|
//
|
|
// SaherElm IT Center MQL5 X121 SMC Signal Class
|
|
// -------------------------------------------------
|
|
// Name: XWZ
|
|
// Description: provide all Signalling functions ...
|
|
//
|
|
//
|
|
// 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-trade.lib"
|
|
#include "../Classes/x-121.smc.market.cycle.helper.class.mq5"
|
|
#include "../Libraries/x-121.smc.guard.lib.mq5"
|
|
#include "../Libraries/x-121.smc.lib.mq5"
|
|
|
|
//
|
|
enum ENUM_X121SMC_XWZ_PRIORITY
|
|
{
|
|
X121SMC_XWZ_PRIORITY_NONE,
|
|
X121SMC_XWZ_PRIORITY_WEAK,
|
|
X121SMC_XWZ_PRIORITY_LOW,
|
|
X121SMC_XWZ_PRIORITY_REGULAR,
|
|
X121SMC_XWZ_PRIORITY_HIGH,
|
|
X121SMC_XWZ_PRIORITY_STRONG_HIGH,
|
|
};
|
|
|
|
//
|
|
struct X121SMCXWZZone
|
|
{
|
|
//
|
|
// Props ...
|
|
XCFVG *fvg;
|
|
XCOrderBlock *ob;
|
|
XCSupplyZone *supply;
|
|
XCDemandZone *demand;
|
|
XCSupportZone *support;
|
|
XCResistanceZone *resistance;
|
|
|
|
//
|
|
// Constructor ...
|
|
X121SMCXWZZone()
|
|
{
|
|
Clean();
|
|
}
|
|
|
|
//
|
|
// Tools ...
|
|
|
|
//
|
|
void Clean()
|
|
{
|
|
//
|
|
ZeroMemory(ob);
|
|
ZeroMemory(fvg);
|
|
ZeroMemory(supply);
|
|
ZeroMemory(demand);
|
|
ZeroMemory(support);
|
|
ZeroMemory(resistance);
|
|
}
|
|
|
|
//
|
|
bool IsValid()
|
|
{
|
|
//
|
|
return HasOB() &&
|
|
HasFVG() &&
|
|
HasDirection();
|
|
}
|
|
|
|
//
|
|
bool AsBox(XBoxZone &box)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
box.Clean();
|
|
|
|
//
|
|
result = IsValid() &&
|
|
HasDirection();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
XBoxZone obBox;
|
|
bool hasOBBox = ToBox(
|
|
obBox,
|
|
ob //
|
|
);
|
|
result = hasOBBox;
|
|
if (!result)
|
|
{
|
|
//
|
|
box.Clean();
|
|
obBox.Clean();
|
|
return result;
|
|
}
|
|
|
|
//
|
|
box = obBox;
|
|
|
|
//
|
|
obBox.Clean();
|
|
|
|
//
|
|
bool hasOB = HasOB();
|
|
bool hasFVG = HasFVG();
|
|
bool hasSupply = HasSupply();
|
|
bool hasDemand = HasDemand();
|
|
bool hasSupport = HasSupport();
|
|
bool hasResistance = HasResistance();
|
|
|
|
//
|
|
// OB Compared since box used obBox ...
|
|
|
|
//
|
|
if (hasFVG)
|
|
{
|
|
//
|
|
if (fvg.Upper() > box.upper)
|
|
{
|
|
box.upper = fvg.Upper();
|
|
}
|
|
|
|
//
|
|
if (fvg.Lower() < box.lower)
|
|
{
|
|
box.lower = fvg.Lower();
|
|
}
|
|
}
|
|
|
|
//
|
|
result = box.IsValid();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
bool HasOB()
|
|
{
|
|
return ob != NULL &&
|
|
ob.IsValid();
|
|
}
|
|
|
|
//
|
|
bool HasFVG()
|
|
{
|
|
return fvg != NULL &&
|
|
fvg.IsValid();
|
|
}
|
|
|
|
//
|
|
bool HasSupply()
|
|
{
|
|
return supply != NULL &&
|
|
supply.IsValid();
|
|
}
|
|
|
|
//
|
|
bool HasDemand()
|
|
{
|
|
return demand != NULL &&
|
|
demand.IsValid();
|
|
}
|
|
|
|
//
|
|
bool HasSupport()
|
|
{
|
|
return support != NULL &&
|
|
support.IsValid();
|
|
}
|
|
|
|
//
|
|
bool HasResistance()
|
|
{
|
|
return resistance != NULL &&
|
|
resistance.IsValid();
|
|
}
|
|
|
|
//
|
|
bool IsBullish()
|
|
{
|
|
//
|
|
return HasOB() &&
|
|
ob.IsBullish() &&
|
|
HasFVG() &&
|
|
fvg.IsBullish();
|
|
}
|
|
|
|
//
|
|
bool IsBearish()
|
|
{
|
|
//
|
|
return HasOB() &&
|
|
ob.IsBearish() &&
|
|
HasFVG() &&
|
|
fvg.IsBearish();
|
|
}
|
|
|
|
//
|
|
bool HasDirection()
|
|
{
|
|
return IsBullish() ||
|
|
IsBearish();
|
|
}
|
|
|
|
//
|
|
bool ValidateZone(
|
|
int barIndex = 0,
|
|
ENUM_TIMEFRAMES forPeriod = NULL,
|
|
bool forceOB = false,
|
|
bool forceFVG = false //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
if (barIndex < 0)
|
|
{
|
|
barIndex = 0;
|
|
}
|
|
|
|
//
|
|
result = IsValid() &&
|
|
HasDirection();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
string symbol = ob.GetSymbol();
|
|
if (forPeriod == NULL)
|
|
{
|
|
forPeriod = ob.GetPeriod();
|
|
}
|
|
ENUM_X_DIRECTION forDir = GetDirection();
|
|
|
|
//
|
|
XOHCL cBar;
|
|
result = cBar.Init(
|
|
symbol,
|
|
forPeriod,
|
|
barIndex + 1 //
|
|
);
|
|
if (!result)
|
|
{
|
|
//
|
|
cBar.Clean();
|
|
return result;
|
|
}
|
|
|
|
//
|
|
bool isObBreaked =
|
|
IsBullish(forDir)
|
|
? cBar.close < ob.Lower()
|
|
: cBar.close > ob.Upper();
|
|
|
|
//
|
|
bool isFVGBreaked =
|
|
IsBullish(forDir)
|
|
? cBar.close < fvg.Lower()
|
|
: cBar.close > fvg.Upper();
|
|
|
|
//
|
|
bool isBreaked = true;
|
|
if ((forceOB && forceFVG) ||
|
|
(!forceOB && !forceFVG))
|
|
{
|
|
isBreaked =
|
|
isObBreaked ||
|
|
isFVGBreaked;
|
|
}
|
|
else if (forceFVG)
|
|
{
|
|
isBreaked = isFVGBreaked;
|
|
}
|
|
else if (forceOB)
|
|
{
|
|
isBreaked = isObBreaked;
|
|
}
|
|
|
|
//
|
|
result = !isBreaked;
|
|
|
|
//
|
|
cBar.Clean();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
ENUM_X_DIRECTION GetDirection()
|
|
{
|
|
//
|
|
ENUM_X_DIRECTION result = X_DIRECTION_NONE;
|
|
|
|
//
|
|
bool hasDirection = HasDirection();
|
|
if (!hasDirection)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
bool isBullish = IsBullish();
|
|
|
|
//
|
|
result =
|
|
isBullish
|
|
? X_DIRECTION_BULLISH
|
|
: X_DIRECTION_BEARISH;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
};
|
|
|
|
//
|
|
// Definitions ...
|
|
struct X121SMCStrategyXWZSignalConditions
|
|
{
|
|
//
|
|
// Props ...
|
|
|
|
//
|
|
string symbol;
|
|
ENUM_TIMEFRAMES period;
|
|
|
|
//
|
|
double sl;
|
|
double target;
|
|
double reward;
|
|
double amountPercent;
|
|
ENUM_X_DIRECTION dir;
|
|
ENUM_X_POSITION_TYPES type;
|
|
|
|
//
|
|
// Setup Props ...
|
|
|
|
//
|
|
datetime setupTime;
|
|
datetime triggerTime;
|
|
|
|
//
|
|
double pivot;
|
|
double point;
|
|
|
|
//
|
|
ENUM_X121SMC_XWZ_PRIORITY priority;
|
|
|
|
//
|
|
// X121SMCXWZZone startZone;
|
|
X121SMCXWZZone bullishFlow[];
|
|
X121SMCXWZZone bearishFlow[];
|
|
|
|
//
|
|
// Constructor ...
|
|
X121SMCStrategyXWZSignalConditions()
|
|
{
|
|
Clean();
|
|
}
|
|
|
|
//
|
|
// Tools ...
|
|
|
|
/**
|
|
* Cleaning Up ...
|
|
*/
|
|
void Clean()
|
|
{
|
|
//
|
|
sl = 0;
|
|
target = 0;
|
|
|
|
//
|
|
dir = X_DIRECTION_NONE;
|
|
type = X_POSITION_TYPE_NONE;
|
|
|
|
//
|
|
symbol = NULL;
|
|
period = NULL;
|
|
setupTime = NULL;
|
|
triggerTime = NULL;
|
|
|
|
//
|
|
ExtensionClean();
|
|
|
|
//
|
|
ZeroMemory(this);
|
|
}
|
|
|
|
/**
|
|
* Check Condition is Setting Up ...
|
|
*
|
|
* @param dir: ENUM_X_DIRECTION member, Setting Up Direction ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool IsSetuped()
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
result = IsValid(setupTime) &&
|
|
HasDirection(dir);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Calculate Setup Age ...
|
|
*
|
|
* @return ( int )
|
|
*/
|
|
int GetSetupAge()
|
|
{
|
|
//
|
|
int result = 0;
|
|
|
|
//
|
|
if (!IsSetuped())
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result = (int)(TimeCurrent() - setupTime) / PeriodSeconds(period);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Detect How we Can Trigger Signal ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool CanTrigger()
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
result =
|
|
//
|
|
sl > 0 &&
|
|
IsValid(symbol) &&
|
|
IsValid(period) &&
|
|
IsValid(triggerTime) &&
|
|
type != X_POSITION_TYPE_ALL &&
|
|
type != X_POSITION_TYPE_NONE
|
|
//
|
|
;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Extensions ...
|
|
|
|
/**
|
|
* Clean Additional Properties ...
|
|
*/
|
|
void ExtensionClean()
|
|
{
|
|
//
|
|
pivot = 0;
|
|
point = 0;
|
|
|
|
//
|
|
target = 0;
|
|
reward = 0;
|
|
amountPercent = 0;
|
|
|
|
//
|
|
// startZone.Clean();
|
|
Clean(bullishFlow);
|
|
Clean(bearishFlow);
|
|
}
|
|
|
|
//
|
|
//
|
|
//
|
|
|
|
//
|
|
bool HasBullishFlow()
|
|
{
|
|
return HasChild(bullishFlow);
|
|
}
|
|
|
|
//
|
|
int CountBullishFlow()
|
|
{
|
|
return ArraySize(bullishFlow);
|
|
}
|
|
|
|
//
|
|
bool HasBearishFlow()
|
|
{
|
|
return HasChild(bearishFlow);
|
|
}
|
|
|
|
//
|
|
int CountBearishFlow()
|
|
{
|
|
return ArraySize(bearishFlow);
|
|
}
|
|
|
|
//
|
|
void UpdateTo(datetime value = NULL)
|
|
{
|
|
//
|
|
value = NormalizeTime(value);
|
|
|
|
//
|
|
}
|
|
|
|
//
|
|
//
|
|
//
|
|
|
|
//
|
|
int DetectOrderFlow(
|
|
ENUM_X_DIRECTION forDir,
|
|
XPOIState &htfState,
|
|
XPOIState &mtfState,
|
|
int barIndex = 0,
|
|
ENUM_TIMEFRAMES forPeriod = NULL,
|
|
XCPOIDrawer *drawer = NULL //
|
|
)
|
|
{
|
|
//
|
|
int result = 0;
|
|
|
|
//
|
|
bool isValid =
|
|
//
|
|
IsValid(symbol) &&
|
|
IsValid(period) &&
|
|
htfState.HasChild() &&
|
|
mtfState.HasChild() &&
|
|
HasDirection(forDir)
|
|
//
|
|
;
|
|
if (!isValid)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
if (forPeriod == NULL)
|
|
{
|
|
forPeriod = period;
|
|
}
|
|
|
|
//
|
|
bool isBullish = IsBullish(forDir);
|
|
|
|
//
|
|
int idx = -1;
|
|
int count = 0;
|
|
bool has = false;
|
|
|
|
//
|
|
XOBFVG tmpOBFVGs[];
|
|
count = ExtractOBFVGZones(
|
|
htfState,
|
|
mtfState,
|
|
mtfState,
|
|
tmpOBFVGs,
|
|
forDir,
|
|
NULL, // For Period ...
|
|
//
|
|
// Start ...
|
|
XZONE_STATE_PASSED,
|
|
true, // Force Body Out ...
|
|
//
|
|
// Activation ...
|
|
XZONE_STATE_PASSED,
|
|
true, // Force Body In ...
|
|
//
|
|
// Breaktion ...
|
|
XZONE_STATE_FAILED,
|
|
false, // Force Body In ...
|
|
//
|
|
// Works ...
|
|
XZONE_STATE_PASSED,
|
|
true, // Force Body Out ...
|
|
//
|
|
true, // Apply Sort ...
|
|
true, // From Filter ...
|
|
true, // Place Filter ...
|
|
//
|
|
true // Ignore Inside in Place Filter ...
|
|
);
|
|
has = IsValidSize(count);
|
|
if (has)
|
|
{
|
|
//
|
|
for (int i = 0; i < count; i++)
|
|
{
|
|
//
|
|
XOBFVG iOBFVG = tmpOBFVGs[i];
|
|
|
|
//
|
|
XCBaseObject *iOBObjs[];
|
|
int drawnCount = drawer.DrawOrderBlock(
|
|
iOBFVG.ob,
|
|
iOBObjs //
|
|
);
|
|
|
|
//
|
|
XCBaseObject *iFVGObjs[];
|
|
drawnCount = drawer.DrawFairValueGap(
|
|
iOBFVG.fvg,
|
|
iFVGObjs //
|
|
);
|
|
}
|
|
}
|
|
|
|
//
|
|
has = IsValidSize(count);
|
|
result = count;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
};
|
|
|
|
// |