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

3284 lines
76 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;
XConsolidationZone bullishConsolidationZone;
XConsolidationZone bearishConsolidationZone;
//
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();
//
bullishConsolidationZone.Clean();
bearishConsolidationZone.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 HasBullishConsolidationZone()
{
return bullishConsolidationZone.IsValid() &&
bullishConsolidationZone.IsBreaked() &&
IsBullish(bullishConsolidationZone.breakDir);
}
//
bool HasBearishConsolidationZone()
{
return bearishConsolidationZone.IsValid() &&
bearishConsolidationZone.IsBreaked() &&
IsBullish(bearishConsolidationZone.breakDir);
}
//
bool IsBullish()
{
//
return HasOB() &&
ob.IsBullish() &&
HasFVG() &&
fvg.IsBullish() &&
HasSupport() &&
HasDemand();
}
//
bool IsBearish()
{
//
return HasOB() &&
ob.IsBearish() &&
HasFVG() &&
fvg.IsBearish() &&
HasSupply() &&
HasResistance();
}
//
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 HasCondition(
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();
//
result = IsValid() &&
HasDirection() &&
state.IsValid() &&
state.HasChild();
if (!result)
{
//
swingBar.Clean();
breakerBar.Clean();
appliedBox.Clean();
momentumBar.Clean();
rejectionBar.Clean();
//
return result;
}
//
string symbol = ob.GetSymbol();
if (!IsValid(forPeriod))
{
forPeriod = ob.GetPeriod();
}
datetime cTime = iTime(
symbol,
forPeriod,
barIndex //
);
//
bool isInside = IsPriceInside(
barIndex,
forPeriod //
);
result = isInside;
if (!result)
{
return result;
}
//
XBoxZone box;
result = AsBox(box);
if (!result)
{
//
box.Clean();
//
swingBar.Clean();
breakerBar.Clean();
appliedBox.Clean();
momentumBar.Clean();
rejectionBar.Clean();
//
return result;
}
//
bool isBullish = IsBullish();
ENUM_X_DIRECTION forDir = box.dir;
//
int supportsCount = 0;
bool hasSupports = false;
XCSupportZone *supports[];
//
int resistancesCount = 0;
bool hasResistances = false;
XCResistanceZone *resistances[];
//
XBoxZone supResBoxes[];
int supresBoxesCount = 0;
bool hasSupResBoxes = false;
//
int count = 0;
bool has = 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,
box //
);
if (!isInside)
{
//
iBox.Clean();
continue;
}
//
Add(
iZone,
supports //
);
//
AddRef(
iBox,
supResBoxes //
);
//
iBox.Clean();
}
//
supportsCount = ArraySize(supports);
hasSupports = IsValidSize(supportsCount);
//
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,
box //
);
if (!isInside)
{
//
iBox.Clean();
continue;
}
//
Add(
iZone,
resistances //
);
//
AddRef(
iBox,
supResBoxes //
);
//
iBox.Clean();
}
//
resistancesCount = ArraySize(resistances);
hasResistances = IsValidSize(resistancesCount);
//
supresBoxesCount = ArraySize(supResBoxes);
hasSupResBoxes = IsValidSize(supresBoxesCount);
}
//
result = hasSupResBoxes;
if (!result)
{
//
box.Clean();
Clean(supports);
Clean(resistances);
Clean(supResBoxes);
//
swingBar.Clean();
breakerBar.Clean();
appliedBox.Clean();
momentumBar.Clean();
rejectionBar.Clean();
//
return result;
}
//
// Detect Bars ...
//
XOHCL zBar;
result = zBar.Init(
symbol,
forPeriod,
barIndex //
);
if (!result)
{
//
box.Clean();
zBar.Clean();
Clean(supports);
Clean(resistances);
Clean(supResBoxes);
//
swingBar.Clean();
breakerBar.Clean();
appliedBox.Clean();
momentumBar.Clean();
rejectionBar.Clean();
//
return result;
}
//
XOHCL cBar;
result = zBar.GetPreviousBar(cBar);
if (!result)
{
//
box.Clean();
zBar.Clean();
cBar.Clean();
Clean(supports);
Clean(resistances);
Clean(supResBoxes);
//
swingBar.Clean();
breakerBar.Clean();
appliedBox.Clean();
momentumBar.Clean();
rejectionBar.Clean();
//
return result;
}
//
XOHCL pBar;
result = cBar.GetPreviousBar(pBar);
if (!result)
{
//
box.Clean();
zBar.Clean();
cBar.Clean();
pBar.Clean();
Clean(supports);
Clean(resistances);
Clean(supResBoxes);
//
swingBar.Clean();
breakerBar.Clean();
appliedBox.Clean();
momentumBar.Clean();
rejectionBar.Clean();
//
return result;
}
//
XOHCL ppBar;
result = pBar.GetPreviousBar(ppBar);
if (!result)
{
//
box.Clean();
zBar.Clean();
cBar.Clean();
pBar.Clean();
ppBar.Clean();
Clean(supports);
Clean(resistances);
Clean(supResBoxes);
//
swingBar.Clean();
breakerBar.Clean();
appliedBox.Clean();
momentumBar.Clean();
rejectionBar.Clean();
//
return result;
}
//
// Check Conditions ...
//
// Detect Start Senario ...
//
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();
//
int selectedBoxIDX = -1;
for (int j = 0; j < supresBoxesCount; j++)
{
//
double appliedPrice =
isBullish
? supResBoxes[j].lower
: supResBoxes[j].upper;
//
// 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;
//
bool hasRejectionBar = false;
if (isBullish)
{
//
count = state.CountBullishRejectionBars();
for (int i = 0; i < count; i++)
{
//
XCRejectionBar *iZone = state.bullishRejectionBars[i];
//
XOHCL iBar;
bool isFilled = iZone.FillBar(iBar);
if (!isFilled)
{
continue;
}
//
int iBarIndex = iBar.Index();
//
hasRejectionBar =
//
(iBarIndex == cBar.Index() ||
iBarIndex == pBar.Index())
//
;
if (hasRejectionBar)
{
//
if (!rejectionBar.IsValid())
{
rejectionBar = iBar;
}
//
break;
}
}
}
else
{
//
count = state.CountBearishRejectionBars();
for (int i = 0; i < count; i++)
{
//
XCRejectionBar *iZone = state.bearishRejectionBars[i];
//
XOHCL iBar;
bool isFilled = iZone.FillBar(iBar);
if (!isFilled)
{
continue;
}
//
int iBarIndex = iBar.Index();
//
hasRejectionBar =
//
(iBarIndex == cBar.Index() ||
iBarIndex == pBar.Index())
//
;
if (hasRejectionBar)
{
//
if (!rejectionBar.IsValid())
{
rejectionBar = iBar;
}
//
break;
}
}
}
//
bool hasMomentumBar = false;
if (isBullish)
{
//
count = state.CountBullishMomentumBars();
for (int i = 0; i < count; i++)
{
//
XCMomentumBar *iZone = state.bullishMomentumBars[i];
//
XOHCL iBar;
bool isFilled = iZone.FillBar(iBar);
if (!isFilled)
{
continue;
}
//
int iBarIndex = iBar.Index();
//
hasMomentumBar =
//
(iBarIndex == cBar.Index() ||
iBarIndex == pBar.Index())
//
;
if (hasMomentumBar)
{
//
if (!momentumBar.IsValid())
{
momentumBar = iBar;
}
//
break;
}
}
}
else
{
//
count = state.CountBearishMomentumBars();
for (int i = 0; i < count; i++)
{
//
XCMomentumBar *iZone = state.bearishMomentumBars[i];
//
XOHCL iBar;
bool isFilled = iZone.FillBar(iBar);
if (!isFilled)
{
continue;
}
//
int iBarIndex = iBar.Index();
//
hasMomentumBar =
//
(iBarIndex == cBar.Index() ||
iBarIndex == pBar.Index())
//
;
if (hasMomentumBar)
{
//
if (!momentumBar.IsValid())
{
momentumBar = iBar;
}
//
break;
}
}
}
//
bool hasSwing = false;
if (isBullish)
{
//
count = state.CountSwingLows();
for (int i = 0; i < count; i++)
{
//
XCSwing *iSwing = state.swingLows[i];
//
XOHCL iBar;
bool isFilled = iSwing.FillBar(iBar);
if (!isFilled)
{
continue;
}
//
int iBarIndex = iBar.Index();
//
hasSwing =
//
(iBarIndex == cBar.Index() ||
iBarIndex == pBar.Index())
//
;
if (hasSwing)
{
//
if (!swingBar.IsValid())
{
swingBar = iBar;
}
//
break;
}
}
}
else
{
//
count = state.CountSwingHighs();
for (int i = 0; i < count; i++)
{
//
XCSwing *iSwing = state.swingHighs[i];
//
XOHCL iBar;
bool isFilled = iSwing.FillBar(iBar);
if (!isFilled)
{
continue;
}
//
int iBarIndex = iBar.Index();
//
hasSwing =
//
(iBarIndex == cBar.Index() ||
iBarIndex == pBar.Index())
//
;
if (hasSwing)
{
//
if (!swingBar.IsValid())
{
swingBar = iBar;
}
//
break;
}
}
}
//
bool hasRequiredValidations =
//
(hasRejectionBar ||
hasMomentumBar)
//
||
//
(hasRejectionBar ||
hasSwing)
//
||
//
(hasMomentumBar ||
hasSwing)
//
;
//
result =
//
(isBoxBreaked &&
(hasRequiredValidations ||
hasValidPressuredSwing))
//
||
//
(isBoxRejected &&
(hasRequiredValidations ||
hasValidPressuredSwing))
//
;
if (result)
{
//
selectedBoxIDX = j;
break;
}
}
//
result =
result &&
(isBullish
? zBar.open > box.upper
: zBar.open < box.lower) &&
IsValidIndex(selectedBoxIDX);
if (result)
{
appliedBox = supResBoxes[selectedBoxIDX];
}
//
box.Clean();
zBar.Clean();
cBar.Clean();
pBar.Clean();
ppBar.Clean();
Clean(supports);
Clean(resistances);
Clean(supResBoxes);
//
return result;
}
//
bool IsPriceInside(
int barIndex = 0,
ENUM_TIMEFRAMES forPeriod = NULL //
)
{
//
bool result = false;
//
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;
}
//
// Get Zone Box ...
XBoxZone box;
bool hasBox = AsBox(box);
result = hasBox;
if (!result)
{
//
box.Clean();
//
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;
}
//
result =
//
isBullish
? (
//
pBar.low > box.upper &&
cBar.low <= box.upper &&
zBar.open <= box.upper
//
)
: (
//
pBar.high < box.lower &&
cBar.high >= box.lower &&
zBar.open >= box.lower
//
)
//
;
//
box.Clean();
zBar.Clean();
cBar.Clean();
pBar.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;
//
// 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();
//
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 HasStartZone()
{
return startZone.IsValid();
}
//
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 hasStartZone = HasStartZone();
if (hasStartZone)
{
//
bool hasOB = startZone.HasOB();
if (hasOB)
{
startZone.ob.To(value);
}
//
bool hasFVG = startZone.HasFVG();
if (hasFVG)
{
startZone.fvg.To(value);
}
//
bool hasSupply = startZone.HasSupply();
if (hasSupply)
{
startZone.supply.To(value);
}
//
bool hasDemand = startZone.HasDemand();
if (hasDemand)
{
startZone.demand.To(value);
}
//
bool hasSupport = startZone.HasSupport();
if (hasSupport)
{
startZone.support.To(value);
}
//
bool hasResistance = startZone.HasResistance();
if (hasResistance)
{
startZone.resistance.To(value);
}
//
bool hasBullishCZone = startZone.HasBullishConsolidationZone();
if (hasBullishCZone)
{
// startZone.bullishConsolidationZone.to = cTime;
}
//
bool hasBearishCZone = startZone.HasBearishConsolidationZone();
if (hasBearishCZone)
{
// startZone.bearishConsolidationZone.to = cTime;
}
}
}
//
//
//
//
// 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 DetectStartZone(
ENUM_X_DIRECTION forDir,
XPOIState &state,
XC121SMCCycleHelper *cycleHelper //
)
{
//
bool result = false;
//
result = state.IsValid() &&
state.HasChild() &&
HasDirection(forDir);
if (!result)
{
return result;
}
//
bool isBullish = IsBullish(forDir);
//
int idx = -1;
int count = 0;
int has = false;
//
// Supply Zones ...
has = state.HasSupplyZones();
if (has)
{
//
idx = GetYoungest(state.supplyZones);
if (IsValidIndex(idx))
{
startZone.supply = state.supplyZones[idx];
}
}
//
// Demand Zones ...
has = state.HasDemandZones();
if (has)
{
//
idx = GetYoungest(state.demandZones);
if (IsValidIndex(idx))
{
startZone.demand = state.demandZones[idx];
}
}
//
// Support Zones ...
has = state.HasSupportZones();
if (has)
{
//
idx = GetYoungest(state.supportZones);
if (IsValidIndex(idx))
{
startZone.support = state.supportZones[idx];
}
}
//
// Resistance Zones ...
has = state.HasResistanceZones();
if (has)
{
//
idx = GetYoungest(state.resistanceZones);
if (IsValidIndex(idx))
{
startZone.resistance = state.resistanceZones[idx];
}
}
//
// Other Zones ...
if (isBullish)
{
//
// Order Block ...
has = state.HasBullishOrderBlocks();
if (has)
{
//
idx = GetYoungest(state.bullishOrderBlocks);
if (IsValidIndex(idx))
{
startZone.ob = state.bullishOrderBlocks[idx];
}
}
//
// Fair Value Gap ...
has = state.HasBullishFairValueGaps();
if (has)
{
//
idx = GetYoungest(state.bullishFairValueGaps);
if (IsValidIndex(idx))
{
startZone.fvg = state.bullishFairValueGaps[idx];
}
}
}
else
{
//
// Order Block ...
has = state.HasBearishOrderBlocks();
if (has)
{
//
idx = GetYoungest(state.bearishOrderBlocks);
if (IsValidIndex(idx))
{
startZone.ob = state.bearishOrderBlocks[idx];
}
}
//
// Fair Value Gap ...
has = state.HasBearishFairValueGaps();
if (has)
{
//
idx = GetYoungest(state.bearishFairValueGaps);
if (IsValidIndex(idx))
{
startZone.fvg = state.bearishFairValueGaps[idx];
}
}
}
//
bool hasOBFVG = startZone.HasOB() &&
startZone.HasFVG();
bool isOBStarted = false;
bool isFVGStarted = false;
bool isOBActivated = false;
bool isFVGActivated = false;
bool isOBInsideFVG = false;
bool isFVGInsideOB = false;
if (hasOBFVG)
{
//
ENUM_X_DIRECTION forDir = startZone.ob.GetDirection();
//
XOHCL startedBar;
ENUM_X_DIRECTION startedDir;
//
isOBStarted = startZone.ob.IsStarted(
forDir,
startedBar,
startedDir //
);
//
isOBActivated = startZone.ob.IsActivated(
forDir,
startedBar,
startedDir //
);
//
forDir = startZone.fvg.GetDirection();
//
isFVGStarted = startZone.fvg.IsStarted(
forDir,
startedBar,
startedDir //
);
//
isFVGActivated = startZone.fvg.IsActivated(
forDir,
startedBar,
startedDir //
);
//
isOBInsideFVG =
IsInsideDiff(
startZone.ob,
startZone.fvg //
) ||
(isBullish
? IsAboveDiff(
startZone.ob,
startZone.fvg,
true // IgnoreInside
)
: IsBelowDiff(
startZone.ob,
startZone.fvg,
true // IgnoreInside
));
//
isFVGInsideOB =
IsInsideDiff(
startZone.fvg,
startZone.ob //
) ||
(isBullish
? IsAboveDiff(
startZone.fvg,
startZone.ob,
true // IgnoreInside
)
: IsBelowDiff(
startZone.fvg,
startZone.ob,
true // IgnoreInside
));
//
startedBar.Clean();
}
//
result =
isOBStarted &&
isFVGStarted &&
!isOBActivated &&
!isFVGActivated &&
startZone.IsValid() &&
(isOBInsideFVG ||
isFVGInsideOB) &&
(isBullish
? startZone.IsBullish()
: startZone.IsBearish());
if (!result)
{
//
startZone.Clean();
//
return result;
}
//
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 HasWorkingZoneConditions(
ENUM_X_DIRECTION &conditionsDir,
XPOIState &state,
int barIndex = 0,
ENUM_TIMEFRAMES forPeriod = NULL //
)
{
//
bool result = false;
//
if (barIndex < 0)
{
barIndex = 0;
}
//
conditionsDir = X_DIRECTION_NONE;
//
result = HasWorkingZone();
if (!result)
{
return result;
}
//
XBoxZone appliedBox;
//
// Clean Condition Bars ...
workingZone.CleanConditionBars();
//
// Validate ...
result = state.IsValid() &&
state.HasChild();
if (!result)
{
//
workingZone.CleanConditionBars();
return result;
}
//
if (!IsValid(forPeriod))
{
forPeriod = period;
}
//
datetime cTime = iTime(
symbol,
forPeriod,
barIndex //
);
//
// Check Supply Zone ...
//
XBoxZone supplyBox;
bool hasSupplyBox =
supplyZone != NULL &&
supplyZone.IsValid() &&
ToBox(
supplyBox,
supplyZone //
);
if (hasSupplyBox)
{
//
result = CheckBoxForTradeConditions(
supplyBox,
appliedBox,
workingZone.swingBar,
workingZone.breakerBar,
workingZone.rejectionBar,
workingZone.momentumBar,
state,
barIndex,
forPeriod //
);
//
if (result)
{
conditionsDir = X_DIRECTION_BEARISH;
}
}
//
// Check Demand Zone ...
XBoxZone demandBox;
bool hasDemandBox = false;
if (!result)
{
//
hasDemandBox =
demandZone != NULL &&
demandZone.IsValid() &&
ToBox(
demandBox,
demandZone //
);
if (hasDemandBox)
{
//
result = CheckBoxForTradeConditions(
demandBox,
appliedBox,
workingZone.swingBar,
workingZone.breakerBar,
workingZone.rejectionBar,
workingZone.momentumBar,
state,
barIndex,
forPeriod //
);
//
if (result)
{
conditionsDir = X_DIRECTION_BULLISH;
}
}
}
//
if (!result)
{
workingZone.CleanConditionBars();
}
//
supplyBox.Clean();
demandBox.Clean();
appliedBox.Clean();
//
return result;
}
//
double GetSpread()
{
//
double result = 0;
//
if (!IsValid(symbol))
{
return result;
}
//
result = GetSpread(
symbol //
);
//
return result;
}
//
};