Files
xMQL5/BKPS/14031206/Documents/BKP/x-121.smc.xwz.signal.lib.mq5
T
2025-02-24 19:20:10 +03:30

3560 lines
85 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;
//
XOHCL swingBar;
XOHCL breakerBar;
XOHCL momentumBar;
XOHCL rejectionBar;
XBoxZone appliedBox;
//
// Constructor ...
X121SMCXWZZone()
{
Clean();
}
//
// Tools ...
//
void Clean()
{
//
ZeroMemory(ob);
ZeroMemory(fvg);
ZeroMemory(supply);
ZeroMemory(demand);
ZeroMemory(support);
ZeroMemory(resistance);
//
swingBar.Clean();
breakerBar.Clean();
appliedBox.Clean();
momentumBar.Clean();
rejectionBar.Clean();
}
//
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();
}
//
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;
}
//
bool IsPriceInside(
XBoxZone &box,
int barIndex = 0,
ENUM_TIMEFRAMES forPeriod = NULL,
bool forceOB = false,
bool forceFVG = false //
)
{
//
bool result = false;
//
box.Clean();
//
if (barIndex < 0)
{
barIndex = 0;
}
//
result = IsValid() &&
HasOB() &&
HasFVG() &&
HasDirection();
if (!result)
{
return result;
}
//
string symbol = ob.GetSymbol();
if (forPeriod == NULL)
{
forPeriod = ob.GetPeriod();
}
//
ENUM_X_DIRECTION forDir = ob.GetDirection();
bool isBullish = IsBullish(forDir);
//
// Check Start Bars ...
//
XOHCL obStartedBar;
ENUM_X_DIRECTION obStartedDir;
bool isOBStarted = ob.IsStarted(
forDir,
obStartedBar,
obStartedDir //
);
result = isOBStarted;
if (!result)
{
return result;
}
//
XOHCL fvgStartedBar;
ENUM_X_DIRECTION fvgStartedDir;
bool isFVGStarted = fvg.IsStarted(
forDir,
fvgStartedBar,
fvgStartedDir //
);
result = isFVGStarted;
if (!result)
{
return result;
}
//
// Retrieve Bars ...
//
XOHCL zBar;
result = zBar.Init(
symbol,
forPeriod,
barIndex //
);
if (!result)
{
//
box.Clean();
zBar.Clean();
//
return result;
}
//
XOHCL cBar;
result = zBar.GetPreviousBar(cBar);
if (!result)
{
//
box.Clean();
zBar.Clean();
cBar.Clean();
//
return result;
}
//
XOHCL pBar;
result = cBar.GetPreviousBar(pBar);
if (!result)
{
//
box.Clean();
zBar.Clean();
cBar.Clean();
pBar.Clean();
//
return result;
}
//
bool isPriceInsideOB = X121SMCXWZCheckPriceInside(
zBar,
cBar,
ob.Upper(),
ob.Lower() //
);
//
// isBullish
// ? (
// //
// pBar.close > ob.Upper() &&
// cBar.low <= ob.Upper() &&
// cBar.close <= ob.Upper() &&
// zBar.open <= ob.Upper()
// //
// )
// : (
// //
// pBar.close < ob.Lower() &&
// cBar.high >= ob.Lower() &&
// cBar.close >= ob.Lower() &&
// zBar.open >= ob.Lower()
// //
// );
//
bool isPriceInsideFVG = X121SMCXWZCheckPriceInside(
zBar,
cBar,
fvg.Upper(),
fvg.Lower() //
);
//
// isBullish
// ? (
// //
// pBar.close > fvg.Upper() &&
// cBar.low <= fvg.Upper() &&
// cBar.close <= fvg.Upper() &&
// zBar.open <= fvg.Upper()
// //
// )
// : (
// //
// pBar.close < fvg.Lower() &&
// cBar.high >= fvg.Lower() &&
// cBar.close >= fvg.Lower() &&
// zBar.open >= fvg.Lower()
// //
// );
//
if ((forceOB && forceFVG) ||
(!forceOB && !forceFVG))
{
//
result =
isPriceInsideOB ||
isPriceInsideFVG;
}
else if (forceOB)
{
result = isPriceInsideOB;
}
else if (forceFVG)
{
result = isPriceInsideFVG;
}
//
if (result)
{
//
if (isPriceInsideOB && !isPriceInsideFVG)
{
//
result = ToBox(
box,
ob //
);
}
else if (isPriceInsideFVG && !isPriceInsideOB)
{
//
result = ToBox(
box,
fvg //
);
}
else if (isPriceInsideOB && isPriceInsideFVG)
{
result = AsBox(box);
}
}
//
zBar.Clean();
cBar.Clean();
pBar.Clean();
//
return result;
}
//
bool HasInsideConditions(
XPOIState &state,
int barIndex = 0,
ENUM_TIMEFRAMES forPeriod = NULL //
)
{
//
bool result = false;
//
if (barIndex < 0)
{
barIndex = 0;
}
//
swingBar.Clean();
breakerBar.Clean();
appliedBox.Clean();
momentumBar.Clean();
rejectionBar.Clean();
//
XBoxZone zoneBox;
bool hasBox = AsBox(zoneBox);
//
result = hasBox &&
IsValid() &&
HasDirection() &&
state.IsValid() &&
state.HasChild();
if (!result)
{
//
swingBar.Clean();
breakerBar.Clean();
appliedBox.Clean();
momentumBar.Clean();
rejectionBar.Clean();
//
return result;
}
//
string symbol = zoneBox.symbol;
if (!IsValid(forPeriod))
{
forPeriod = zoneBox.period;
}
datetime cTime = iTime(
symbol,
forPeriod,
barIndex //
);
//
ENUM_X_DIRECTION forDir = zoneBox.dir;
bool isBullish = IsBullish(forDir);
//
int count = 0;
bool has = false;
//
XBoxZone supResBoxes[];
int supresBoxesCount = 0;
bool hasSupResBoxes = false;
//
has = state.HasSupportZones();
if (has)
{
//
count = state.CountSupportZones();
for (int i = 0; i < count; i++)
{
//
XCSupportZone *iZone = state.supportZones[i];
//
iZone.To(cTime);
//
XBoxZone iBox;
bool hasBox = ToBox(
iBox,
iZone //
);
if (!hasBox)
{
//
iBox.Clean();
continue;
}
//
// Check From ...
bool isInside = IsBoxInside(
iBox,
zoneBox //
);
if (!isInside)
{
//
iBox.Clean();
continue;
}
//
AddRef(
iBox,
supResBoxes //
);
//
iBox.Clean();
ZeroMemory(iZone);
}
//
supresBoxesCount = ArraySize(supResBoxes);
hasSupResBoxes = IsValidSize(supresBoxesCount);
}
//
has = state.HasResistanceZones();
if (has)
{
//
count = state.CountResistanceZones();
for (int i = 0; i < count; i++)
{
//
XCResistanceZone *iZone = state.resistanceZones[i];
//
iZone.To(cTime);
//
XBoxZone iBox;
bool hasBox = ToBox(
iBox,
iZone //
);
if (!hasBox)
{
//
iBox.Clean();
continue;
}
//
// Check From ...
bool isInside = IsBoxInside(
iBox,
zoneBox //
);
if (!isInside)
{
//
iBox.Clean();
continue;
}
//
AddRef(
iBox,
supResBoxes //
);
//
iBox.Clean();
ZeroMemory(iZone);
}
//
supresBoxesCount = ArraySize(supResBoxes);
hasSupResBoxes = IsValidSize(supresBoxesCount);
}
//
result = hasSupResBoxes;
if (!result)
{
//
Clean(supResBoxes);
//
swingBar.Clean();
breakerBar.Clean();
appliedBox.Clean();
momentumBar.Clean();
rejectionBar.Clean();
//
return result;
}
//
for (int i = 0; i < supresBoxesCount; i++)
{
//
XBoxZone iBox = supResBoxes[i];
//
bool hasBoxConditions = HasBoxConitions(
iBox,
state,
barIndex,
forPeriod //
);
if (hasBoxConditions)
{
//
appliedBox = iBox;
result = true;
iBox.Clean();
break;
}
//
iBox.Clean();
}
//
if (!result)
{
//
swingBar.Clean();
breakerBar.Clean();
appliedBox.Clean();
momentumBar.Clean();
rejectionBar.Clean();
}
//
Clean(supResBoxes);
//
return result;
}
//
bool HasBoxConitions(
XBoxZone &box,
XPOIState &state,
int barIndex = 0,
ENUM_TIMEFRAMES forPeriod = NULL //
)
{
//
bool result = false;
//
if (barIndex < 0)
{
barIndex = 0;
}
//
result = box.IsValid() &&
IsValid() &&
HasDirection();
if (!result)
{
//
swingBar.Clean();
breakerBar.Clean();
appliedBox.Clean();
momentumBar.Clean();
rejectionBar.Clean();
//
return result;
}
//
string symbol = box.symbol;
if (forPeriod == NULL)
{
forPeriod = box.period;
}
ENUM_X_DIRECTION forDir = box.dir;
bool isBullish = IsBullish(forDir);
//
// Detect Bars ...
//
XOHCL zBar;
result = zBar.Init(
symbol,
forPeriod,
barIndex //
);
if (!result)
{
//
zBar.Clean();
//
swingBar.Clean();
breakerBar.Clean();
appliedBox.Clean();
momentumBar.Clean();
rejectionBar.Clean();
//
return result;
}
//
XOHCL cBar;
result = zBar.GetPreviousBar(cBar);
if (!result)
{
//
zBar.Clean();
cBar.Clean();
//
swingBar.Clean();
breakerBar.Clean();
appliedBox.Clean();
momentumBar.Clean();
rejectionBar.Clean();
//
return result;
}
//
XOHCL pBar;
result = cBar.GetPreviousBar(pBar);
if (!result)
{
//
zBar.Clean();
cBar.Clean();
pBar.Clean();
//
swingBar.Clean();
breakerBar.Clean();
appliedBox.Clean();
momentumBar.Clean();
rejectionBar.Clean();
//
return result;
}
//
XOHCL ppBar;
result = pBar.GetPreviousBar(ppBar);
if (!result)
{
//
zBar.Clean();
cBar.Clean();
pBar.Clean();
ppBar.Clean();
//
swingBar.Clean();
breakerBar.Clean();
appliedBox.Clean();
momentumBar.Clean();
rejectionBar.Clean();
//
return result;
}
//
double fiboPressureLevel = GetFiboLevelValue(X_FIBO_LEVEL_382);
//
double fiboUpDown = GetFibonacciLevel(
pBar.high,
pBar.low,
X_FIBO_LEVEL_382,
X_DIRECTION_BEARISH //
);
double fiboDownUp = GetFibonacciLevel(
pBar.high,
pBar.low,
X_FIBO_LEVEL_382,
X_DIRECTION_BULLISH //
);
//
bool hasFiboToUpPressure =
fiboDownUp > 0 &&
fiboDownUp <= pBar.GetDown();
bool hasFiboToDownPressure =
fiboUpDown > 0 &&
fiboUpDown >= pBar.GetUp();
//
double appliedPrice =
isBullish
? box.upper
: box.lower;
//
// Check Swing Low ...
bool isSwingLow =
//
pBar.low < ppBar.low &&
pBar.low < cBar.low &&
zBar.open > pBar.low &&
//
appliedPrice > pBar.low &&
appliedPrice < pBar.GetDown()
//
;
bool isPressuredSwingLow =
isSwingLow &&
hasFiboToUpPressure;
bool isPressuredStrongSwingLow =
pBar.IsBullish() &&
isPressuredSwingLow;
//
bool isSwingHigh =
//
pBar.high > ppBar.high &&
pBar.high > cBar.high &&
zBar.open < pBar.high &&
//
appliedPrice < pBar.high &&
appliedPrice > pBar.GetUp()
//
;
bool isPressuredSwingHigh =
isSwingHigh &&
hasFiboToDownPressure;
bool isPressuredStrongSwingHigh =
pBar.IsBearish() &&
isPressuredSwingHigh;
//
bool hasValidSwing =
isBullish
? isSwingLow
: isSwingHigh;
bool hasValidPressuredSwing =
isBullish
? isPressuredSwingLow
: isPressuredSwingHigh;
bool hasValidPressuredStrongSwing =
isBullish
? isPressuredStrongSwingLow
: isPressuredStrongSwingHigh;
if (hasValidSwing)
{
swingBar = pBar;
}
if (hasValidPressuredSwing)
{
swingBar = pBar;
}
if (hasValidPressuredStrongSwing)
{
swingBar = pBar;
}
//
bool isCBarBreaked = IsBarBreak(
appliedPrice,
forDir,
cBar //
);
if (isCBarBreaked)
{
breakerBar = cBar;
}
bool isPBarBreaked = IsBarBreak(
appliedPrice,
forDir,
pBar //
);
if (!isCBarBreaked && isPBarBreaked)
{
breakerBar = pBar;
}
else
{
isPBarBreaked = false;
}
bool isPPBarBreaked = IsBarBreak(
appliedPrice,
forDir,
ppBar //
);
if (!isCBarBreaked &&
!isPBarBreaked &&
isPPBarBreaked)
{
breakerBar = ppBar;
}
else
{
isPPBarBreaked = false;
}
bool isBoxBreaked = isCBarBreaked ||
isPBarBreaked ||
isPPBarBreaked;
//
bool isCBarRejected = IsBarReject(
appliedPrice,
forDir,
cBar //
);
if (isCBarRejected)
{
rejectionBar = cBar;
}
bool isPBarRejected = IsBarReject(
appliedPrice,
forDir,
pBar //
);
if (!isCBarRejected && isPBarRejected)
{
rejectionBar = pBar;
}
else
{
isPBarRejected = false;
}
bool isPPBarRejected = IsBarReject(
appliedPrice,
forDir,
ppBar //
);
if (!isCBarRejected &&
!isPBarRejected &&
isPPBarRejected)
{
rejectionBar = ppBar;
}
else
{
isPPBarRejected = false;
}
bool isBoxRejected = isCBarRejected ||
isPBarRejected ||
isPPBarRejected;
//
result =
//
isBoxBreaked ||
isBoxRejected ||
hasValidPressuredSwing
//
;
if (!result)
{
//
swingBar.Clean();
breakerBar.Clean();
appliedBox.Clean();
momentumBar.Clean();
rejectionBar.Clean();
}
else
{
appliedBox = box;
}
//
zBar.Clean();
cBar.Clean();
pBar.Clean();
ppBar.Clean();
//
return result;
}
//
};
//
struct X121SMCXWZWorkingZone
{
//
string symbol;
ENUM_TIMEFRAMES period;
//
double upper;
double lower;
//
double zoneUpper;
double zoneLower;
//
double quarter1;
double quarter2;
double quarter3;
//
datetime to;
datetime from;
//
XOHCL swingBar;
XOHCL breakerBar;
XOHCL momentumBar;
XOHCL rejectionBar;
XBoxZone appliedBox;
//
X121SMCXWZWorkingZone()
{
Clean();
}
//
void Clean()
{
//
upper = 0;
lower = 0;
quarter1 = 0;
quarter2 = 0;
quarter3 = 0;
zoneLower = 0;
zoneUpper = 0;
//
from = NULL;
symbol = NULL;
period = NULL;
//
CleanConditionBars();
//
ZeroMemory(this);
}
//
void CleanConditionBars()
{
//
swingBar.Clean();
breakerBar.Clean();
appliedBox.Clean();
momentumBar.Clean();
rejectionBar.Clean();
}
//
bool IsValid()
{
//
bool result = false;
//
result =
lower > 0 &&
upper > 0 &&
quarter1 > 0 &&
quarter2 > 0 &&
quarter3 > 0 &&
upper > lower &&
zoneLower > 0 &&
zoneUpper > 0 &&
IsValid(from) &&
IsValid(symbol) &&
IsValid(period) &&
zoneUpper > upper &&
zoneLower < lower;
//
return result;
}
//
bool IsDestroyed(
ENUM_X_DIRECTION &destroyedDir,
int barIndex = 0,
ENUM_TIMEFRAMES forPeriod = NULL //
)
{
//
bool result = false;
//
if (barIndex < 0)
{
barIndex = 0;
}
//
if (!IsValid(forPeriod))
{
forPeriod = period;
}
//
destroyedDir = X_DIRECTION_NONE;
//
result = IsValid();
if (!result)
{
return result;
}
//
XOHCL bar;
result = bar.Init(
symbol,
forPeriod,
barIndex //
);
if (!result)
{
return result;
}
//
bool isUpperBreaked =
bar.high > zoneUpper &&
bar.close > zoneUpper;
//
bool isLowerBreaked =
bar.low < zoneLower &&
bar.close < zoneLower;
//
result = isUpperBreaked ||
isLowerBreaked;
if (result)
{
//
destroyedDir =
isUpperBreaked
? 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;
//
// Working Zone ...
XCFVG *fairValueGap;
XCOrderBlock *orderBlock;
XCSupplyZone *supplyZone;
XCDemandZone *demandZone;
X121SMCXWZWorkingZone workingZone;
//
// X121SMCXWZZone startZone;
X121SMCXWZZone startZones[];
//
// 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;
//
ZeroMemory(supplyZone);
//
ZeroMemory(demandZone);
//
ZeroMemory(orderBlock);
//
ZeroMemory(fairValueGap);
//
// startZone.Clean();
Clean(startZones);
//
workingZone.Clean();
}
//
//
//
//
bool HasWorkingZone()
{
return workingZone.IsValid();
}
//
bool HasOrderBlock()
{
return orderBlock != NULL &&
orderBlock.IsValid();
}
//
bool HasFairValueGap()
{
return fairValueGap != NULL &&
fairValueGap.IsValid();
}
//
bool HasSupplyZone()
{
return supplyZone != NULL &&
supplyZone.IsValid();
}
//
bool HasDemandZone()
{
return demandZone != NULL &&
demandZone.IsValid();
}
//
bool HasStartZones()
{
return HasChild(startZones);
}
//
int CountStartZones()
{
return ArraySize(startZones);
}
//
void UpdateTo(datetime value = NULL)
{
//
value = NormalizeTime(value);
//
bool hasSupplyZone = HasSupplyZone();
if (hasSupplyZone)
{
supplyZone.To(value);
}
//
bool hasDemandZone = HasDemandZone();
if (hasDemandZone)
{
demandZone.To(value);
}
//
bool hasOrderBlock = HasOrderBlock();
if (hasOrderBlock)
{
orderBlock.To(value);
}
//
bool hasFairValueGap = HasFairValueGap();
if (hasFairValueGap)
{
fairValueGap.To(value);
}
//
// Working Zone ...
bool hasWorkingZone = HasWorkingZone();
if (hasWorkingZone)
{
workingZone.to = value;
}
//
// Start Zone ...
bool hasStartZones = HasStartZones();
if (hasStartZones)
{
//
int count = CountStartZones();
for (int i = 0; i < count; i++)
{
//
bool hasOB = startZones[i].HasOB();
if (hasOB)
{
startZones[i].ob.To(value);
}
//
bool hasFVG = startZones[i].HasFVG();
if (hasFVG)
{
startZones[i].fvg.To(value);
}
//
bool hasSupply = startZones[i].HasSupply();
if (hasSupply)
{
startZones[i].supply.To(value);
}
//
bool hasDemand = startZones[i].HasDemand();
if (hasDemand)
{
startZones[i].demand.To(value);
}
//
bool hasSupport = startZones[i].HasSupport();
if (hasSupport)
{
startZones[i].support.To(value);
}
//
bool hasResistance = startZones[i].HasResistance();
if (hasResistance)
{
startZones[i].resistance.To(value);
}
}
}
}
//
//
//
//
// Working Zone is an Area which
// we decide to trade inside it ...
bool ExtractWorkingZone(
XPOIState &htfState,
XPOIState &mtfState,
XPOIState &stfState,
int barIndex = 0 //
)
{
//
bool result = false;
//
if (barIndex < 0)
{
barIndex = 0;
}
int zIndex = barIndex;
//
result = !HasWorkingZone();
if (!result)
{
return result;
}
//
result = IsValid(symbol) &&
IsValid(period);
if (!result)
{
//
Clean();
return result;
}
//
datetime cTime = iTime(
symbol,
period,
zIndex //
);
//
result =
//
htfState.IsValid() &&
htfState.HasChild() &&
htfState.HasSupplyZones() &&
htfState.HasDemandZones() &&
//
mtfState.IsValid() &&
mtfState.HasChild() &&
mtfState.HasSupplyZones() &&
mtfState.HasDemandZones() &&
//
stfState.IsValid() &&
stfState.HasChild()
//
;
if (!result)
{
return result;
}
//
// Retrieve Highest Supply Zone ...
int hSupplyIDX = GetHighest(htfState.supplyZones);
int lDemandIDX = GetLowest(htfState.demandZones);
//
result =
//
IsValidIndex(hSupplyIDX) &&
IsValidIndex(lDemandIDX)
//
;
if (!result)
{
return result;
}
//
supplyZone = htfState.supplyZones[hSupplyIDX];
demandZone = htfState.demandZones[lDemandIDX];
//
result =
//
supplyZone != NULL &&
demandZone != NULL &&
supplyZone.IsValid() &&
demandZone.IsValid()
//
;
if (!result)
{
//
Clean();
return result;
}
//
// Check Validation of Supply and Demand Zones ...
lDemandIDX = GetLowest(mtfState.demandZones);
hSupplyIDX = GetHighest(mtfState.supplyZones);
result = IsValidIndex(lDemandIDX) &&
IsValidIndex(hSupplyIDX);
if (!result)
{
//
Clean();
return result;
}
//
// Validate Supply and Demand ...
bool isMTFHSupplyInside =
IsInside(
mtfState.supplyZones[hSupplyIDX],
supplyZone);
bool isMTFLDemandInside =
IsInside(
mtfState.demandZones[lDemandIDX],
demandZone //
);
if (isMTFHSupplyInside &&
!isMTFLDemandInside)
{
demandZone = mtfState.demandZones[lDemandIDX];
}
else if (!isMTFHSupplyInside &&
isMTFLDemandInside)
{
supplyZone = mtfState.supplyZones[hSupplyIDX];
}
else if (isMTFHSupplyInside &&
isMTFLDemandInside)
{
//
supplyZone = mtfState.supplyZones[hSupplyIDX];
demandZone = mtfState.demandZones[lDemandIDX];
}
//
// Check Zones Validation ...
bool hasTrend =
supplyZone != NULL &&
supplyZone.IsValid() &&
demandZone != NULL &&
demandZone.IsValid();
result = hasTrend;
if (!result)
{
//
Clean();
return result;
}
//
datetime from = MathMax(
supplyZone.From(),
demandZone.From());
//
int fromIndex = iBarShift(
symbol,
period,
from //
);
//
// Detect Trend ...
ENUM_X_DIRECTION trend = X_DIRECTION_NONE;
datetime supplyTouch = NULL;
datetime demandTouch = NULL;
for (int i = zIndex; i < fromIndex; i++)
{
//
XOHCL iBar;
bool isInited = iBar.Init(
symbol,
period,
i //
);
if (!isInited)
{
continue;
}
//
bool isTouchSupplyZone =
//
iBar.low < supplyZone.Lower() &&
iBar.GetUp() > supplyZone.Lower()
//
;
if (isTouchSupplyZone &&
!IsValid(supplyTouch))
{
supplyTouch = iBar.time;
}
//
bool isTouchDemandZone =
//
iBar.high > demandZone.Upper() &&
iBar.GetDown() < demandZone.Upper()
//
;
if (isTouchDemandZone &&
!IsValid(demandTouch))
{
demandTouch = iBar.time;
}
//
bool canBreak =
IsValid(supplyTouch) &&
IsValid(demandTouch);
//
iBar.Clean();
//
if (canBreak)
{
break;
}
}
//
hasTrend =
//
IsValid(supplyTouch) ||
IsValid(demandTouch)
//
;
if (hasTrend)
{
//
trend =
//
supplyTouch > demandTouch
? X_DIRECTION_BEARISH
: X_DIRECTION_BULLISH
//
;
}
//
// Check Trend ...
result = hasTrend;
if (!result)
{
//
Clean();
return result;
}
//
bool hasBullishTrend = IsBullish(trend);
bool hasBearishTrend = IsBearish(trend);
//
// Find Order Block and FVG for Trend Approve ...
//
bool isBullishTrendApproved = false;
bool isBearishTrendApproved = false;
//
// Now We Have to Detect at least One OrderBlock with FVG ...
// for Trend Approvement ...
bool hasOrderBlock = HasOrderBlock();
bool hasFairValueGap = HasFairValueGap();
if (!hasOrderBlock &&
!hasFairValueGap)
{
//
int count = 0;
bool has = false;
//
XCFVG *fvg = NULL;
XCOrderBlock *ob = NULL;
//
has = mtfState.HasBullishOrderBlocks();
count = mtfState.CountBullishOrderBlocks();
//
if (has)
{
//
// Check Order Block ...
for (int i = 0; i < count; i++)
{
//
XCOrderBlock *iOB = mtfState.bullishOrderBlocks[i];
//
iOB.To(cTime);
//
// Check From Passes ...
bool isFromPassed = iOB.From() > demandZone.From();
if (!isFromPassed)
{
continue;
}
//
// Must inside DemandZone ...
bool isInsideDemand = IsInsideDiff(
iOB,
demandZone //
);
if (!isInsideDemand)
{
continue;
}
//
// Check Started ...
XOHCL startedBar;
ENUM_X_DIRECTION startedDir;
bool isStarted = iOB.IsStarted(
X_DIRECTION_BULLISH,
startedBar,
startedDir //
);
if (!isStarted)
{
//
startedBar.Clean();
continue;
}
//
// Converts to Box ...
XBoxZone obBox;
bool hasOBBox = ToBox(
obBox,
iOB //
);
if (!hasOBBox)
{
//
obBox.Clean();
startedBar.Clean();
continue;
}
//
// Check Zone Must not Used before ...
bool isUsed = IsBoxUsed(
obBox,
startedBar.Index() - 1,
zIndex //
);
if (isUsed)
{
//
obBox.Clean();
startedBar.Clean();
continue;
}
//
ob = iOB;
//
obBox.Clean();
startedBar.Clean();
//
break;
}
//
// Detect Fair Value Gap ...
if (ob != NULL &&
ob.IsValid())
{
//
has = stfState.HasBullishFairValueGaps();
count = stfState.CountBullishFairValueGaps();
if (has)
{
//
// Check Fir Value Gap ...
for (int i = 0; i < count; i++)
{
//
XCFVG *iFVG = stfState.bullishFairValueGaps[i];
//
iFVG.To(cTime);
//
// Check From Passes ...
bool isFromPassed = iFVG.From() > ob.From();
if (!isFromPassed)
{
continue;
}
//
// Check Started ...
XOHCL startedBar;
ENUM_X_DIRECTION startedDir;
bool isStarted = iFVG.IsStarted(
X_DIRECTION_BULLISH,
startedBar,
startedDir //
);
if (!isStarted)
{
//
startedBar.Clean();
continue;
}
//
// Converts to Box ...
XBoxZone fvgBox;
bool hasFVGBox = ToBox(
fvgBox,
iFVG //
);
if (!hasFVGBox)
{
//
fvgBox.Clean();
startedBar.Clean();
continue;
}
//
// Check Inside Order Block ...
bool isInside = IsInsideDiff(
iFVG,
ob,
true // Force Side Out ...
);
if (!isInside)
{
continue;
}
//
fvg = iFVG;
//
fvgBox.Clean();
startedBar.Clean();
//
break;
}
}
else
{
//
ob = NULL;
}
}
//
if (ob != NULL &&
fvg != NULL)
{
//
orderBlock = ob;
fairValueGap = fvg;
}
//
hasOrderBlock = HasOrderBlock();
hasFairValueGap = HasFairValueGap();
isBullishTrendApproved = hasOrderBlock &&
hasFairValueGap;
}
//
if (!isBullishTrendApproved)
{
//
has = mtfState.HasBearishOrderBlocks();
count = mtfState.CountBearishOrderBlocks();
//
if (has)
{
//
// Check Order Block ...
for (int i = 0; i < count; i++)
{
//
XCOrderBlock *iOB = mtfState.bearishOrderBlocks[i];
//
iOB.To(cTime);
//
// Check From Passes ...
bool isFromPassed = iOB.From() > supplyZone.From();
if (!isFromPassed)
{
continue;
}
//
// Must inside DemandZone ...
bool isInsideDemand = IsInsideDiff(
iOB,
supplyZone //
);
if (!isInsideDemand)
{
continue;
}
//
// Check Started ...
XOHCL startedBar;
ENUM_X_DIRECTION startedDir;
bool isStarted = iOB.IsStarted(
X_DIRECTION_BEARISH,
startedBar,
startedDir //
);
if (!isStarted)
{
//
startedBar.Clean();
continue;
}
//
// Converts to Box ...
XBoxZone obBox;
bool hasOBBox = ToBox(
obBox,
iOB //
);
if (!hasOBBox)
{
//
obBox.Clean();
startedBar.Clean();
continue;
}
//
// Check Zone Must not Used before ...
bool isUsed = IsBoxUsed(
obBox,
startedBar.Index() - 1,
zIndex //
);
if (isUsed)
{
//
obBox.Clean();
startedBar.Clean();
continue;
}
//
ob = iOB;
//
obBox.Clean();
startedBar.Clean();
//
break;
}
//
// Detect Fair Value Gap ...
if (ob != NULL &&
ob.IsValid())
{
//
has = stfState.HasBearishFairValueGaps();
count = stfState.CountBearishFairValueGaps();
if (has)
{
//
// Check Fir Value Gap ...
for (int i = 0; i < count; i++)
{
//
XCFVG *iFVG = stfState.bearishFairValueGaps[i];
//
iFVG.To(cTime);
//
// Check From Passes ...
bool isFromPassed = iFVG.From() > ob.From();
if (!isFromPassed)
{
continue;
}
//
// Check Started ...
XOHCL startedBar;
ENUM_X_DIRECTION startedDir;
bool isStarted = iFVG.IsStarted(
X_DIRECTION_BEARISH,
startedBar,
startedDir //
);
if (!isStarted)
{
//
startedBar.Clean();
continue;
}
//
// Converts to Box ...
XBoxZone fvgBox;
bool hasFVGBox = ToBox(
fvgBox,
iFVG //
);
if (!hasFVGBox)
{
//
fvgBox.Clean();
startedBar.Clean();
continue;
}
//
// Check Inside Order Block ...
bool isInside = IsInsideDiff(
iFVG,
ob,
true // Force Side Out ...
);
if (!isInside)
{
continue;
}
//
fvg = iFVG;
//
fvgBox.Clean();
startedBar.Clean();
//
break;
}
}
else
{
//
ob = NULL;
}
}
//
if (ob != NULL &&
fvg != NULL)
{
//
orderBlock = ob;
fairValueGap = fvg;
}
//
hasOrderBlock = HasOrderBlock();
hasFairValueGap = HasFairValueGap();
isBearishTrendApproved = hasOrderBlock &&
hasFairValueGap;
}
}
}
//
// Check Trend Approved ...
bool isTrendApproved =
hasOrderBlock &&
hasFairValueGap &&
(isBullishTrendApproved ||
isBearishTrendApproved);
result = isTrendApproved;
if (!result)
{
//
Clean();
return result;
}
//
// Prepare Working Zone ...
workingZone.symbol = symbol;
workingZone.period = period;
//
workingZone.upper = supplyZone.Lower();
workingZone.zoneUpper = supplyZone.Upper();
//
workingZone.lower = demandZone.Upper();
workingZone.zoneLower = demandZone.Lower();
//
workingZone.from = from;
//
double upper = workingZone.upper;
double range =
workingZone.upper - workingZone.lower;
double ranegPercent = range / 100;
double quarterValue = ranegPercent * 25;
//
workingZone.quarter1 = upper - (quarterValue * 1);
workingZone.quarter2 = upper - (quarterValue * 2);
workingZone.quarter3 = upper - (quarterValue * 3);
//
result = workingZone.IsValid();
if (!result)
{
Clean();
}
//
return result;
}
//
bool IsWorkingZoneDestroyed(
ENUM_X_DIRECTION &destroyedDir,
int barIndex = 0,
ENUM_TIMEFRAMES forPeriod = NULL //
)
{
//
bool result = false;
//
if (barIndex < 0)
{
barIndex = 0;
}
//
if (!IsValid(forPeriod))
{
forPeriod = period;
}
//
destroyedDir = X_DIRECTION_NONE;
//
result = workingZone.IsValid();
if (!result)
{
return result;
}
//
result = workingZone.IsDestroyed(
destroyedDir,
barIndex,
forPeriod //
);
//
return result;
}
//
bool DetectTrend(
ENUM_X_DIRECTION &trend,
int barIndex = 0,
ENUM_TIMEFRAMES forPeriod = NULL //
)
{
//
bool result = false;
//
if (barIndex < 0)
{
barIndex = 0;
}
//
if (forPeriod == NULL)
{
forPeriod = period;
}
//
trend = X_DIRECTION_NONE;
//
result = HasWorkingZone();
if (!result)
{
return result;
}
//
int FromIndex = iBarShift(
symbol,
forPeriod,
workingZone.from //
);
//
datetime supplyTouch = NULL;
datetime demandTouch = NULL;
for (int i = barIndex; i < FromIndex; i++)
{
//
XOHCL iBar;
bool isInited = iBar.Init(
symbol,
forPeriod,
i //
);
if (!isInited)
{
continue;
}
//
bool isTouchSupplyZone =
//
iBar.low < supplyZone.Lower() &&
iBar.GetUp() > supplyZone.Lower()
//
;
if (isTouchSupplyZone &&
!IsValid(supplyTouch))
{
supplyTouch = iBar.time;
}
//
bool isTouchDemandZone =
//
iBar.high > demandZone.Upper() &&
iBar.GetDown() < demandZone.Upper()
//
;
if (isTouchDemandZone &&
!IsValid(demandTouch))
{
demandTouch = iBar.time;
}
//
bool canBreak =
IsValid(supplyTouch) &&
IsValid(demandTouch);
//
iBar.Clean();
//
if (canBreak)
{
break;
}
}
//
result =
//
IsValid(supplyTouch) ||
IsValid(demandTouch)
//
;
if (result)
{
//
trend =
//
supplyTouch > demandTouch
? X_DIRECTION_BEARISH
: X_DIRECTION_BULLISH
//
;
}
//
return result;
}
//
bool DetectStartZones(
ENUM_X_DIRECTION forDir,
XPOIState &obState,
XPOIState &fvgState,
XPOIState &otherState,
XC121SMCCycleHelper *cycleHelper //
)
{
//
bool result = false;
//
result = obState.IsValid() &&
obState.HasChild() &&
fvgState.IsValid() &&
fvgState.HasChild() &&
otherState.IsValid() &&
otherState.HasChild() &&
HasDirection(forDir);
if (!result)
{
return result;
}
//
bool isBullish = IsBullish(forDir);
//
int idx = -1;
int count = 0;
int has = false;
//
X121SMCXWZZone startZone;
X121SMCXWZZone lastStartZone;
bool hasLastStartZone = HasStartZones();
if (hasLastStartZone)
{
//
int startZonesCount = CountStartZones();
lastStartZone = startZones[startZonesCount - 1];
}
//
if (isBullish)
{
//
has = obState.HasBullishOrderBlocks();
if (has)
{
//
count = obState.CountBullishOrderBlocks();
for (int i = 0; i < count; i++)
{
//
XCOrderBlock *iOB = obState.bullishOrderBlocks[i];
//
bool isFromPassed =
!hasLastStartZone
? true
: iOB.From() > lastStartZone.ob.From();
if (!isFromPassed)
{
//
ZeroMemory(iOB);
continue;
}
//
XOHCL startedBar;
ENUM_X_DIRECTION startedDir;
bool isStarted = iOB.IsStarted(
forDir,
startedBar,
startedDir //
);
if (!isStarted)
{
//
ZeroMemory(iOB);
startedBar.Clean();
continue;
}
//
XOHCL activatedBar;
ENUM_X_DIRECTION activatedDir;
bool isActivated = iOB.IsActivated(
forDir,
activatedBar,
activatedDir //
);
if (isActivated)
{
//
ZeroMemory(iOB);
startedBar.Clean();
activatedBar.Clean();
continue;
}
//
bool isPlacePassed =
!IsInsideDiff(
iOB,
demandZone //
) &&
(!hasLastStartZone
? workingZone.IsValid() &&
HasOrderBlock() &&
forDir == orderBlock.GetDirection()
? IsAbove(
iOB,
orderBlock,
true // Ignore Inside ...
)
: true
: lastStartZone.HasOB() &&
IsAbove(
iOB,
lastStartZone.ob,
true // Ignore Inside ...
));
if (!isPlacePassed)
{
//
ZeroMemory(iOB);
startedBar.Clean();
activatedBar.Clean();
continue;
}
//
// Attache OB ...
startZone.ob = iOB;
//
// Now we Have to Find Specified FVG ...
has = fvgState.HasBullishFairValueGaps();
if (has)
{
//
int jCount = fvgState.CountBullishFairValueGaps();
for (int j = 0; j < jCount; j++)
{
//
XCFVG *jFVG = fvgState.bullishFairValueGaps[j];
//
startedBar.Clean();
startedDir = X_DIRECTION_NONE;
isStarted = jFVG.IsStarted(
forDir,
startedBar,
startedDir //
);
if (!isStarted)
{
//
ZeroMemory(jFVG);
startedBar.Clean();
continue;
}
//
activatedBar.Clean();
activatedDir = X_DIRECTION_NONE;
isActivated = jFVG.IsActivated(
forDir,
activatedBar,
activatedDir //
);
if (isActivated)
{
//
ZeroMemory(jFVG);
startedBar.Clean();
activatedBar.Clean();
continue;
}
//
isPlacePassed =
//
!IsInsideDiff(
jFVG,
demandZone //
) &&
IsAboveDiff(
jFVG,
iOB,
true // Ignore Inside ...
)
//
;
if (!isPlacePassed)
{
//
ZeroMemory(jFVG);
startedBar.Clean();
activatedBar.Clean();
}
//
startZone.fvg = jFVG;
}
}
//
startedBar.Clean();
activatedBar.Clean();
}
}
}
else
{
//
has = obState.HasBearishOrderBlocks();
if (has)
{
//
count = obState.CountBearishOrderBlocks();
for (int i = 0; i < count; i++)
{
//
XCOrderBlock *iOB = obState.bearishOrderBlocks[i];
//
bool isFromPassed =
!hasLastStartZone
? true
: iOB.From() > lastStartZone.ob.From();
if (!isFromPassed)
{
//
ZeroMemory(iOB);
continue;
}
//
XOHCL startedBar;
ENUM_X_DIRECTION startedDir;
bool isStarted = iOB.IsStarted(
forDir,
startedBar,
startedDir //
);
if (!isStarted)
{
//
ZeroMemory(iOB);
startedBar.Clean();
continue;
}
//
XOHCL activatedBar;
ENUM_X_DIRECTION activatedDir;
bool isActivated = iOB.IsActivated(
forDir,
activatedBar,
activatedDir //
);
if (isActivated)
{
//
ZeroMemory(iOB);
startedBar.Clean();
activatedBar.Clean();
continue;
}
//
bool isPlacePassed =
!IsInsideDiff(
iOB,
supplyZone //
) &&
(!hasLastStartZone
? workingZone.IsValid() &&
HasOrderBlock() &&
forDir == orderBlock.GetDirection()
? IsBelow(
iOB,
orderBlock,
true // Ignore Inside ...
)
: true
: lastStartZone.HasOB() &&
IsBelow(
iOB,
lastStartZone.ob,
true // Ignore Inside ...
));
if (!isPlacePassed)
{
//
ZeroMemory(iOB);
startedBar.Clean();
activatedBar.Clean();
continue;
}
//
// Attache OB ...
startZone.ob = iOB;
//
// Now we Have to Find Specified FVG ...
has = fvgState.HasBearishFairValueGaps();
if (has)
{
//
int jCount = fvgState.CountBearishFairValueGaps();
for (int j = 0; j < jCount; j++)
{
//
XCFVG *jFVG = fvgState.bearishFairValueGaps[j];
//
startedBar.Clean();
startedDir = X_DIRECTION_NONE;
isStarted = jFVG.IsStarted(
forDir,
startedBar,
startedDir //
);
if (!isStarted)
{
//
ZeroMemory(jFVG);
startedBar.Clean();
continue;
}
//
activatedBar.Clean();
activatedDir = X_DIRECTION_NONE;
isActivated = jFVG.IsActivated(
forDir,
activatedBar,
activatedDir //
);
if (isActivated)
{
//
ZeroMemory(jFVG);
startedBar.Clean();
activatedBar.Clean();
continue;
}
//
isPlacePassed =
//
!IsInsideDiff(
jFVG,
supplyZone //
) &&
IsBelowDiff(
jFVG,
iOB,
true // Ignore Inside ...
)
//
;
if (!isPlacePassed)
{
//
ZeroMemory(jFVG);
startedBar.Clean();
activatedBar.Clean();
}
//
startZone.fvg = jFVG;
}
}
//
startedBar.Clean();
activatedBar.Clean();
}
}
}
//
bool hasOBFVG = startZone.HasOB() &&
startZone.HasFVG();
result = hasOBFVG;
if (!result)
{
//
startZone.Clean();
lastStartZone.Clean();
//
return result;
}
//
XBoxZone startBox;
bool hasStartBox = startZone.AsBox(startBox);
result = hasStartBox;
if (!result)
{
//
startBox.Clean();
startZone.Clean();
lastStartZone.Clean();
//
return result;
}
//
// Detect Other Zones Inside Box ...
XBoxZone tmpBoxes[];
//
// Supply Zones ...
has = otherState.HasSupplyZones();
if (has)
{
//
count = ToBox(
otherState.supplyZones,
tmpBoxes //
);
//
has = IsValidSize(count);
if (has)
{
//
for (int i = 0; i < count; i++)
{
//
XBoxZone iBox = tmpBoxes[i];
//
bool isPlacePassed =
//
IsBoxInside(
iBox,
startBox,
false,
false //
)
//
;
if (!isPlacePassed)
{
//
iBox.Clean();
continue;
}
//
startZone.supply = otherState.supplyZones[i];
//
iBox.Clean();
break;
}
}
}
//
// Demand Zones ...
Clean(tmpBoxes);
has = otherState.HasDemandZones();
if (has)
{
//
count = ToBox(
otherState.demandZones,
tmpBoxes //
);
//
has = IsValidSize(count);
if (has)
{
//
for (int i = 0; i < count; i++)
{
//
XBoxZone iBox = tmpBoxes[i];
//
bool isPlacePassed =
//
IsBoxInside(
iBox,
startBox,
false,
false //
)
//
;
if (!isPlacePassed)
{
//
iBox.Clean();
continue;
}
//
startZone.demand = otherState.demandZones[i];
//
iBox.Clean();
break;
}
}
}
//
// Support Zones ...
Clean(tmpBoxes);
has = otherState.HasSupportZones();
if (has)
{
//
count = ToBox(
otherState.supportZones,
tmpBoxes //
);
//
has = IsValidSize(count);
if (has)
{
//
for (int i = 0; i < count; i++)
{
//
XBoxZone iBox = tmpBoxes[i];
//
bool isPlacePassed =
//
IsBoxInside(
iBox,
startBox,
false,
false //
)
//
;
if (!isPlacePassed)
{
//
iBox.Clean();
continue;
}
//
startZone.support = otherState.supportZones[i];
//
iBox.Clean();
break;
}
}
}
//
// Resistance Zones ...
Clean(tmpBoxes);
has = otherState.HasResistanceZones();
if (has)
{
//
count = ToBox(
otherState.resistanceZones,
tmpBoxes //
);
//
has = IsValidSize(count);
if (has)
{
//
for (int i = 0; i < count; i++)
{
//
XBoxZone iBox = tmpBoxes[i];
//
bool isPlacePassed =
//
IsBoxInside(
iBox,
startBox,
false,
false //
)
//
;
if (!isPlacePassed)
{
//
iBox.Clean();
continue;
}
//
startZone.resistance = otherState.resistanceZones[i];
//
iBox.Clean();
break;
}
}
}
//
result = startZone.IsValid() &&
startZone.HasDirection();
if (result)
{
//
AddRef(
startZone,
startZones //
);
}
//
Clean(tmpBoxes);
startBox.Clean();
startZone.Clean();
lastStartZone.Clean();
//
return result;
}
//
void DetectPriority(
ENUM_X121SMC_XWZ_PRIORITY &bullish,
ENUM_X121SMC_XWZ_PRIORITY &bearish,
int barIndex = 0,
ENUM_TIMEFRAMES forPeriod = NULL //
)
{
//
bullish = X121SMC_XWZ_PRIORITY_NONE;
bearish = X121SMC_XWZ_PRIORITY_NONE;
//
if (barIndex < 0)
{
barIndex = 0;
}
//
if (!IsValid(forPeriod))
{
forPeriod = period;
}
//
bool hasWorkingZone = HasWorkingZone();
if (!hasWorkingZone)
{
return;
}
//
XOHCL zBar;
bool isInited = zBar.Init(
symbol,
forPeriod,
barIndex //
);
if (!isInited)
{
//
zBar.Clean();
return;
}
//
XOHCL cBar;
isInited = zBar.GetPreviousBar(cBar);
if (!isInited)
{
//
zBar.Clean();
cBar.Clean();
return;
}
//
// ZoneUpper, Upper ...
if (cBar.low > workingZone.upper &&
cBar.high < workingZone.zoneUpper &&
zBar.low > workingZone.upper &&
zBar.high < workingZone.zoneUpper)
{
//
bullish = X121SMC_XWZ_PRIORITY_NONE;
bearish = X121SMC_XWZ_PRIORITY_STRONG_HIGH;
}
//
// Upper, Quarter1 ...
else if (cBar.low > workingZone.quarter1 &&
cBar.high < workingZone.upper &&
zBar.low > workingZone.quarter1 &&
zBar.high < workingZone.upper)
{
//
bullish = X121SMC_XWZ_PRIORITY_WEAK;
bearish = X121SMC_XWZ_PRIORITY_HIGH;
}
//
// Quarter1, Quarter2 ...
else if (cBar.low > workingZone.quarter2 &&
cBar.high < workingZone.quarter1 &&
zBar.low > workingZone.quarter2 &&
zBar.high < workingZone.quarter1)
{
//
bullish = X121SMC_XWZ_PRIORITY_LOW;
bearish = X121SMC_XWZ_PRIORITY_REGULAR;
}
//
// Quarter2, Quarter3 ...
else if (cBar.low > workingZone.quarter3 &&
cBar.high < workingZone.quarter2 &&
zBar.low > workingZone.quarter3 &&
zBar.high < workingZone.quarter2)
{
//
bullish = X121SMC_XWZ_PRIORITY_REGULAR;
bearish = X121SMC_XWZ_PRIORITY_LOW;
}
//
// Quarter3, Lower ...
else if (cBar.low > workingZone.lower &&
cBar.high < workingZone.quarter3 &&
zBar.low > workingZone.lower &&
zBar.high < workingZone.quarter3)
{
//
bullish = X121SMC_XWZ_PRIORITY_HIGH;
bearish = X121SMC_XWZ_PRIORITY_WEAK;
}
//
// Lower, ZoneLower ...
else if (cBar.low > workingZone.zoneLower &&
cBar.high < workingZone.lower &&
zBar.low > workingZone.zoneLower &&
zBar.high < workingZone.lower)
{
//
bullish = X121SMC_XWZ_PRIORITY_STRONG_HIGH;
bearish = X121SMC_XWZ_PRIORITY_NONE;
}
//
zBar.Clean();
cBar.Clean();
}
//
bool HasConditions(
double &_pivot,
double &_point,
ENUM_X_DIRECTION &conditionsDir,
XPOIState &state,
int barIndex = 0,
ENUM_TIMEFRAMES forPeriod = NULL //
)
{
//
bool result = false;
//
_pivot = 0;
_point = 0;
conditionsDir = X_DIRECTION_NONE;
//
if (barIndex < 0)
{
barIndex = 0;
}
//
if (forPeriod == NULL)
{
forPeriod = period;
}
//
result =
//
IsValid(symbol) &&
IsValid(period) &&
state.IsValid() &&
HasWorkingZone() &&
state.HasChild()
//
;
if (!result)
{
return result;
}
//
result = false;
//
// Detect Conditions Based On Start Zones ...
bool hasStartZones = HasStartZones();
if (hasStartZones)
{
//
int selectedIndex = -1;
int count = CountStartZones();
for (int i = 0; i < count; i++)
{
//
X121SMCXWZZone iStartZone = startZones[i];
//
XBoxZone selectedBox;
bool hasConditions = false;
bool isBullish = iStartZone.IsBullish();
//
// Conditions Inside Box ...
bool isPriceInside = iStartZone.IsPriceInside(
selectedBox,
barIndex,
forPeriod,
false,
false //
);
if (isPriceInside)
{
//
// hasConditions = iStartZone.HasInsideConditions(
// state,
// barIndex,
// period //
// );
//
hasConditions = true;
//
if (hasConditions)
{
//
_pivot =
//
isBullish
? selectedBox.lower
: selectedBox.upper
//
;
//
_point =
//
isBullish
? selectedBox.upper
: selectedBox.lower
//
;
//
conditionsDir = selectedBox.dir;
result = hasConditions;
iStartZone.Clean();
break;
}
}
// //
// // Order Block Rejection Conditions ...
// bool hasOBBox = ToBox(
// selectedBox,
// iStartZone.ob //
// );
// if (hasOBBox &&
// !hasConditions)
// {
// //
// hasConditions = iStartZone.HasBoxConitions(
// selectedBox,
// state,
// barIndex,
// forPeriod //
// );
// //
// if (hasConditions)
// {
// //
// _pivot =
// //
// isBullish
// ? selectedBox.lower
// : selectedBox.upper
// //
// ;
// //
// _point =
// //
// isBullish
// ? selectedBox.upper
// : selectedBox.lower
// //
// ;
// //
// conditionsDir = selectedBox.dir;
// result = hasConditions;
// iStartZone.Clean();
// break;
// }
// }
// //
// // Fair Value Gap Rejection Conditions ...
// bool hasFVGBox = ToBox(
// selectedBox,
// iStartZone.fvg //
// );
// if (hasFVGBox)
// {
// //
// hasConditions = iStartZone.HasBoxConitions(
// selectedBox,
// state,
// barIndex,
// forPeriod //
// );
// //
// if (hasConditions)
// {
// //
// _pivot =
// //
// isBullish
// ? selectedBox.lower
// : selectedBox.upper
// //
// ;
// //
// _point =
// //
// isBullish
// ? selectedBox.upper
// : selectedBox.lower
// //
// ;
// //
// conditionsDir = selectedBox.dir;
// result = hasConditions;
// iStartZone.Clean();
// break;
// }
// }
//
iStartZone.Clean();
}
//
if (result &&
IsValidIndex(selectedIndex))
{
//
ArrayRemove(
startZones,
selectedIndex,
1 //
);
}
}
//
// Detect Conditions Based On Working Zones ...
if (!result)
{
//
// Detect Result Based On WorkingZone ...
}
//
if (!result)
{
//
_point = 0;
_pivot = 0;
conditionsDir = X_DIRECTION_NONE;
//
return result;
}
//
return result;
}
//
};
//
bool X121SMCXWZCheckPriceInside(
XOHCL &zBar,
XOHCL &cBar,
double upper,
double lower //
)
{
//
bool result = false;
//
result = zBar.IsValid() &&
cBar.IsValid() &&
upper > 0 &&
lower > 0 &&
upper > lower &&
zBar.time > cBar.time;
if (!result)
{
return result;
}
//
result =
//
zBar.high < upper &&
cBar.high < upper &&
//
zBar.low > lower &&
cBar.low > lower
//
;
//
return result;
}
//