Files
MQL5Data/X121SMCEA/Signals/x-121.smc.xwz.signal.lib.mq5
T
2025-03-09 05:31:53 +03:30

3408 lines
84 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_PROVIDERS
{
X121SMC_XWZ_PROVIDER_NONE,
X121SMC_XWZ_PROVIDER_ACTIVATED_MA,
X121SMC_XWZ_PROVIDER_ACTIVATED_BOX,
X121SMC_XWZ_PROVIDER_ACTIVATED_AREA,
X121SMC_XWZ_PROVIDER_ACTIVATED_ZONE,
};
//
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,
};
//
// Definitions ...
//
struct X121SMCStrategyXWZWorkingZone
{
//
// Props ...
//
string symbol;
ENUM_TIMEFRAMES period;
//
double quarter1;
double quarter2;
double quarter3;
//
XCSupplyZone *supplyZone;
XCDemandZone *demandZone;
//
XOBFVG waitingZones[];
XOBFVG unavailableZones[];
//
XBoxZone waitingBoxes[];
XBoxZone unavailableBoxes[];
//
CArrayObj mDrawnObjects;
CArrayObj mWorkingZoneObjects;
//
// Constructor ...
X121SMCStrategyXWZWorkingZone()
{
Clean();
}
//
// Tools ...
//
void Clean()
{
//
quarter1 = 0;
quarter2 = 0;
quarter3 = 0;
//
symbol = NULL;
period = NULL;
//
Clean(waitingZones);
Clean(unavailableZones);
//
Clean(waitingBoxes);
Clean(unavailableBoxes);
//
ZeroMemory(supplyZone);
ZeroMemory(demandZone);
//
mDrawnObjects.Clear();
mWorkingZoneObjects.Clear();
}
//
bool IsValid()
{
//
bool result = false;
//
result =
//
quarter1 > 0 &&
quarter2 > 0 &&
quarter3 > 0 &&
HasSupplyZone() &&
HasDemandZone() &&
quarter1 > quarter2 &&
quarter2 > quarter3
//
;
//
return result;
}
//
bool Init(
string _symbol,
ENUM_TIMEFRAMES _period,
int barIndex,
X121SMCStrategySignalProviderData &provider //
)
{
//
bool result = false;
//
if (barIndex < 0)
{
barIndex = 0;
}
//
result =
//
IsValid(_symbol) &&
IsValid(_period) &&
//
provider.IsValid()
//
;
if (!result)
{
return result;
}
//
symbol = _symbol;
period = _period;
//
int idx = -1;
int count = 0;
bool has = false;
//
XOHCL zBar;
has = zBar.Init(
symbol,
period,
barIndex //
);
result = has;
if (!result)
{
zBar.Clean();
return result;
}
double ll5 = zBar.FindLowest(5, MODE_LOW);
double hh5 = zBar.FindHighest(5, MODE_HIGH);
zBar.Clean();
//
// Supply Zone ...
has = HasSupplyZone();
if (!has)
{
//
idx = GetHighest(provider
.consolidationState
.supplyZones //
);
has = IsValidIndex(idx);
if (has)
{
//
supplyZone = provider
.consolidationState
.supplyZones[idx];
has = hh5 < supplyZone.Lower();
if (!has)
{
supplyZone = NULL;
}
}
}
//
// Demand Zone ...
has = HasDemandZone();
if (!has)
{
//
idx = GetLowest(provider
.consolidationState
.demandZones //
);
has = IsValidIndex(idx);
if (has)
{
//
demandZone = provider
.consolidationState
.demandZones[idx];
has = ll5 > demandZone.Upper();
if (!has)
{
demandZone = NULL;
}
}
}
//
if (supplyZone != NULL &&
demandZone != NULL &&
supplyZone.IsValid() &&
demandZone.IsValid())
{
//
double upper = supplyZone.Lower();
double lower = demandZone.Upper();
//
double delta = ((upper - lower) / 100) * 25;
//
quarter1 = upper - (1 * delta);
quarter2 = upper - (2 * delta);
quarter3 = upper - (3 * delta);
}
//
result = IsValid();
if (!result)
{
Clean();
}
//
return result;
}
//
bool DetectZone(
X121SMCStrategySignalProviderData &provider //
)
{
//
bool result = false;
//
result = IsValid() &&
provider.IsValid();
if (!result)
{
return result;
}
//
int idx = -1;
int count = 0;
bool has = false;
datetime cTime = TimeCurrent();
//
XOBFVG obFVG;
XBoxZone obBox;
XBoxZone fvgBox;
XBoxZone supplyBox;
XBoxZone demandBox;
//
XCFVG *fvg = NULL;
XCOrderBlock *ob = NULL;
XCSupplyZone *supply = NULL;
XCDemandZone *demand = NULL;
//
// Check New Supply Zone Detection ...
bool hasNewSupply =
Contains(
X_SUPPLY_ZONE_DETECTED,
provider.consolidationPoiEvents //
);
if (hasNewSupply)
{
//
idx = GetYoungest(provider
.consolidationState
.supplyZones //
);
has = IsValidIndex(idx);
if (has)
{
//
supply = provider
.consolidationState
.supplyZones[idx];
has = ToBox(
supplyBox,
supply //
);
if (has)
{
//
supply.To(cTime);
supplyBox.to = cTime;
hasNewSupply = supplyBox.IsValid();
}
}
}
//
// Check New Demand Zone Detection ...
bool hasNewDemand =
Contains(
X_DEMAND_ZONE_DETECTED,
provider
.consolidationPoiEvents //
);
if (hasNewDemand)
{
//
idx = GetYoungest(provider
.consolidationState
.demandZones //
);
has = IsValidIndex(idx);
if (has)
{
//
demand = provider
.consolidationState
.demandZones[idx];
has = ToBox(
demandBox,
demand //
);
if (has)
{
//
demand.To(cTime);
demandBox.to = cTime;
hasNewDemand = demandBox.IsValid();
}
}
}
//
// Check New Fair Value Gap Detection ...
bool hasNewFairValueGap =
Contains(
X_BULLISH_FVG_DETECTED,
provider
.analysePoiEvents //
) ||
Contains(
X_BEARISH_FVG_DETECTED,
provider
.analysePoiEvents //
);
if (hasNewFairValueGap)
{
//
idx = GetYoungest(provider
.analyseState
.fairValueGaps //
);
has = IsValidIndex(idx);
if (has)
{
//
fvg = provider
.analyseState
.fairValueGaps[idx];
has = ToBox(
fvgBox,
fvg //
);
if (has)
{
//
fvg.To(cTime);
fvgBox.to = cTime;
hasNewFairValueGap = fvgBox.IsValid();
}
}
}
//
// Check New Order Block Detection ...
bool hasNewOrderBlock =
Contains(
X_BULLISH_ORDERBLOCK_DETECTED,
provider
.consolidationPoiEvents //
) ||
Contains(
X_BEARISH_ORDERBLOCK_DETECTED,
provider
.consolidationPoiEvents //
);
if (hasNewOrderBlock)
{
//
idx = GetYoungest(provider
.consolidationState
.orderBlocks //
);
has = IsValidIndex(idx);
if (has)
{
//
ob = provider
.consolidationState
.orderBlocks[idx];
has = ToBox(
obBox,
ob //
);
if (has)
{
//
ob.To(cTime);
obBox.to = cTime;
hasNewOrderBlock = obBox.IsValid();
}
}
}
//
// Detect OB FVG ...
if (hasNewOrderBlock)
{
//
XOHCL obStartedBar;
bool isOBStartedBodyOut = false;
bool isOBStarted = ob.IsStarted(
ob.GetDirection(),
obStartedBar,
isOBStartedBodyOut //
);
//
has = isOBStarted;
if (has)
{
//
obFVG.ob = ob;
//
// Select FVGs ...
count = provider
.analyseState
.CountFairValueGaps();
has = IsValidSize(count);
if (!has)
{
obFVG.Clean();
}
else
{
//
// Select FVG ...
for (int i = 0; i < count; i++)
{
//
XCFVG *iFVG = provider
.analyseState
.fairValueGaps[i];
bool isBullish = iFVG.IsBullish();
//
XOHCL iStartedBar;
bool isBodyOut = false;
bool isStarted = iFVG.IsStarted(
iFVG.GetDirection(),
iStartedBar,
isBodyOut //
);
iStartedBar.Clean();
//
bool isKindPassed = isStarted &&
isBodyOut;
bool isSameDir = iFVG.GetDirection() == ob.GetDirection();
bool isFromPassed = iFVG.From() >= obStartedBar.time;
bool isPlacePassed =
//
IsInsideOrDiff(
iFVG,
ob //
)
//
// ||
// //
// (isBullish
// ? IsAboveDiff(
// iFVG,
// ob,
// true // Ignore Inside ...
// )
// : IsBelowDiff(
// iFVG,
// ob,
// true // Ignore Inside ...
// )
// //
// )
//
;
//
has = isSameDir &&
isKindPassed &&
isFromPassed &&
isPlacePassed;
if (has)
{
obFVG.AddFVG(iFVG);
}
//
ZeroMemory(iFVG);
}
}
}
//
has = obFVG.IsValid();
if (has)
{
//
has = IsExists(obFVG);
if (!has)
{
//
// New Waiting Zone ...
AddRef(
obFVG,
waitingZones //
);
}
else
{
//
// Check Item Is not Exists ...
idx = FindIndex(
obFVG,
waitingZones //
);
has = !IsValidIndex(idx);
if (!has)
{
//
// Update Exists Waiting Zone ...
waitingZones[idx].AddFVG(fvg);
}
}
}
//
obFVG.Clean();
obStartedBar.Clean();
}
//
//
//
//
bool lookingOthers = false;
if (lookingOthers)
{
//
// Check New Order Block Detection Analyse ...
XBoxZone analyseOBBox;
XCOrderBlock *analyseOB = NULL;
bool hasNewAnalyseOrderBlock =
Contains(
X_BULLISH_ORDERBLOCK_DETECTED,
provider
.analysePoiEvents //
) ||
Contains(
X_BEARISH_ORDERBLOCK_DETECTED,
provider
.analysePoiEvents //
);
if (hasNewAnalyseOrderBlock)
{
//
idx = GetYoungest(provider
.analyseState
.orderBlocks //
);
has = IsValidIndex(idx);
if (has)
{
//
analyseOB = provider
.analyseState
.orderBlocks[idx];
has = ToBox(
analyseOBBox,
analyseOB //
);
if (has)
{
//
analyseOB.To(cTime);
analyseOBBox.to = cTime;
hasNewAnalyseOrderBlock = analyseOBBox.IsValid();
}
}
}
//
// Checking Analyse Order Block ...
if (hasNewAnalyseOrderBlock)
{
//
XOHCL obStartedBar;
bool isOBStartedBodyOut = false;
bool isOBStarted = analyseOB.IsStarted(
analyseOB.GetDirection(),
obStartedBar,
isOBStartedBodyOut //
);
//
has = isOBStarted &&
isOBStartedBodyOut;
if (has)
{
//
analyseOBBox.from =
obStartedBar.NextAt();
//
has = IsExists(analyseOBBox);
if (!has)
{
//
AddRef(
analyseOBBox,
waitingBoxes //
);
}
}
}
//
analyseOBBox.Clean();
ZeroMemory(analyseOB);
}
//
//
//
//
result = HasWaitingZones();
//
// Cleanup Resources ...
//
obFVG.Clean();
obBox.Clean();
fvgBox.Clean();
supplyBox.Clean();
demandBox.Clean();
//
ZeroMemory(ob);
ZeroMemory(fvg);
ZeroMemory(supply);
ZeroMemory(demand);
//
return result;
}
//
int ValidateWaitingZones(
int barIndex = 0 //
)
{
//
int result = 0;
//
bool has = false;
//
if (barIndex < 0)
{
barIndex = 0;
}
//
if (barIndex == 0)
{
barIndex = 1;
}
//
has = IsValid() &&
HasWaitingZones();
if (!has)
{
return result;
}
//
int removeIDX[];
result = CountWaitingZones();
for (int i = 0; i < result; i++)
{
//
has = waitingZones[i].IsValidZone(
barIndex //
);
if (!has)
{
//
Add(
i,
removeIDX //
);
//
AddRef(
waitingZones[i],
unavailableZones //
);
}
}
//
has = HasChild(removeIDX);
if (has)
{
//
CleanupArray(
removeIDX,
waitingZones //
);
}
Clean(removeIDX);
//
result = CountWaitingZones();
//
return result;
}
//
int ValidateWaitingBoxes(
int barIndex = 0 //
)
{
//
int result = 0;
//
bool has = false;
//
if (barIndex < 0)
{
barIndex = 0;
}
//
if (barIndex == 0)
{
barIndex = 1;
}
//
has = IsValid() &&
HasWaitingBoxes();
if (!has)
{
return result;
}
//
int removeIDX[];
result = CountWaitingBoxes();
for (int i = 0; i < result; i++)
{
//
has = IsValidBox(
waitingBoxes[i],
barIndex,
period //
);
if (!has)
{
//
Add(
i,
removeIDX //
);
//
AddRef(
waitingBoxes[i],
unavailableBoxes //
);
}
}
//
has = HasChild(removeIDX);
if (has)
{
//
CleanupArray(
removeIDX,
waitingBoxes //
);
}
Clean(removeIDX);
//
result = CountWaitingBoxes();
//
return result;
}
//
bool IsZoneActivated(
int &zoneIDX,
int &fvgIDX,
ENUM_X_DIRECTION &dir,
ENUM_X121SMC_XWZ_PROVIDERS &signalProvider,
X121SMCStrategySignalProviderData &provider,
int barIndex = 0 //
)
{
//
bool result = false;
//
fvgIDX = -1;
zoneIDX = -1;
dir = X_DIRECTION_NONE;
signalProvider = X121SMC_XWZ_PROVIDER_NONE;
//
// Normalize Bar Index ...
if (barIndex < 0)
{
barIndex = 0;
}
//
if (barIndex == 0)
{
barIndex = 1;
}
//
// Validate ...
result = IsValid() &&
HasWaitingZones();
if (!result)
{
return result;
}
//
XOHCL bar;
result = bar.Init(
symbol,
period,
barIndex //
);
if (!result)
{
//
bar.Clean();
//
return result;
}
//
double peak = provider.decisionXConditions.peaksBuffer[1];
double vale = provider.decisionXConditions.valesBuffer[1];
//
double analysePeak = provider.analyseXConditions.peaksBuffer[1];
double analyseVale = provider.analyseXConditions.valesBuffer[1];
//
double consolidationPeak = provider.consolidationXConditions.peaksBuffer[1];
double consolidationVale = provider.consolidationXConditions.valesBuffer[1];
//
double visionPeak = provider.visionXConditions.peaksBuffer[1];
double visionVale = provider.visionXConditions.valesBuffer[1];
//
bool isPeaksSame =
peak == analysePeak &&
analysePeak == consolidationPeak;
//
bool isValesSame =
vale == analyseVale &&
analyseVale == consolidationVale;
//
//
//
//
bool isDecisionScoreBullish =
provider.decisionBullishScore > provider.decisionBearishScore;
//
bool isDecisionScoreBearish =
provider.decisionBearishScore > provider.decisionBullishScore;
//
bool isAnalyseScoreBullish =
provider.analyseBullishScore > provider.analyseBearishScore;
//
bool isAnalyseScoreBearish =
provider.analyseBearishScore > provider.analyseBullishScore;
//
bool isConsolidationScoreBullish =
provider.consolidationBullishScore > provider.consolidationBearishScore;
//
bool isConsolidationScoreBearish =
provider.consolidationBearishScore > provider.consolidationBullishScore;
//
bool isVisionScoreBullish =
provider.visionBullishScore > provider.visionBearishScore;
//
bool isVisionScoreBearish =
provider.visionBearishScore > provider.visionBullishScore;
//
int count = CountWaitingZones();
for (int i = 0; i < count; i++)
{
//
XOBFVG iOBFVG = waitingZones[i];
//
ENUM_X_DIRECTION iDir = iOBFVG.GetDirection();
bool isBullish = iOBFVG.IsBullish();
//
int fvgsCount = iOBFVG.CountFVGs();
bool has = IsValidSize(fvgsCount);
if (has)
{
//
for (int j = 0; j < fvgsCount; j++)
{
//
XCFVG *jFVG = iOBFVG.fvgs[j];
//
XBoxZone iBox;
has = ToBox(
iBox,
jFVG //
);
if (has)
{
//
double iRange = iBox.lower + ((iBox.upper - iBox.lower) / 2);
//
// Activate Zone Using PV ...
bool isPVPassed =
isBullish
? vale <= iBox.upper &&
vale >= iBox.lower
: peak <= iBox.upper &&
peak >= iBox.lower;
bool isPV50Passed =
isBullish
? vale < iBox.upper &&
vale <= iRange &&
vale > iBox.lower
: peak < iBox.upper &&
peak >= iRange &&
peak > iBox.lower;
//
// Activate Zone using Rejection ...
bool isRejected =
isBullish
? bar.low <= iBox.upper &&
bar.GetDown() > iBox.upper
: bar.high >= iBox.lower &&
bar.GetUp() < iBox.lower;
//
// Combine Result ...
// result = isPVPassed;
// || isPVPassed
// || isPV50Passed
// || isRejected;
//
result = isPVPassed;
if (result)
{
//
fvgIDX = j;
iBox.Clean();
zoneIDX = i;
//
break;
}
}
//
if (result)
{
//
iBox.Clean();
ZeroMemory(jFVG);
//
break;
}
//
iBox.Clean();
}
}
//
if (result)
{
//
iOBFVG.Clean();
break;
}
//
iOBFVG.Clean();
}
//
result =
IsValidIndex(fvgIDX) &&
IsValidIndex(zoneIDX);
//
bar.Clean();
//
if (result)
{
bar.Clean();
}
//
return result;
}
//
bool IsBoxActivated(
XBoxZone &box,
ENUM_X_DIRECTION &dir,
ENUM_X121SMC_XWZ_PROVIDERS &signalProvider,
X121SMCStrategySignalProviderData &provider,
int barIndex = 0 //
)
{
//
bool result = false;
//
box.Clean();
dir = X_DIRECTION_NONE;
signalProvider = X121SMC_XWZ_PROVIDER_NONE;
//
if (barIndex < 0)
{
barIndex = 0;
}
//
result = IsValid() &&
HasWaitingBoxes();
if (!result)
{
return result;
}
//
XOHCL bar;
XOHCL cBar;
XOHCL pBar;
result = bar.Init(
symbol,
period,
barIndex //
);
result =
result &&
bar.GetPreviousBar(cBar);
result =
result &&
cBar.GetPreviousBar(pBar);
if (!result)
{
//
bar.Clean();
cBar.Clean();
//
return result;
}
//
// Retrieve Some Required Data ...
//
double peakZ = provider.decisionXConditions.peaksBuffer[0];
double valeZ = provider.decisionXConditions.valesBuffer[0];
double peak = provider.decisionXConditions.peaksBuffer[1];
double vale = provider.decisionXConditions.valesBuffer[1];
//
double analysePeak = provider.analyseXConditions.peaksBuffer[1];
double analyseVale = provider.analyseXConditions.valesBuffer[1];
//
double consolidationPeak = provider.consolidationXConditions.peaksBuffer[1];
double consolidationVale = provider.consolidationXConditions.valesBuffer[1];
//
double visionPeak = provider.visionXConditions.peaksBuffer[1];
double visionVale = provider.visionXConditions.valesBuffer[1];
//
bool isPeaksSame =
peak == analysePeak &&
analysePeak == consolidationPeak;
//
bool isValesSame =
vale == analyseVale &&
analyseVale == consolidationVale;
//
// Calculate Scores Conditions ...
//
bool isDecisionScoreBullish =
provider.decisionBullishScore > provider.decisionBearishScore;
//
bool isDecisionScoreBearish =
provider.decisionBearishScore > provider.decisionBullishScore;
//
bool isAnalyseScoreBullish =
provider.analyseBullishScore > provider.analyseBearishScore;
//
bool isAnalyseScoreBearish =
provider.analyseBearishScore > provider.analyseBullishScore;
//
bool isConsolidationScoreBullish =
provider.consolidationBullishScore > provider.consolidationBearishScore;
//
bool isConsolidationScoreBearish =
provider.consolidationBearishScore > provider.consolidationBullishScore;
//
bool isVisionScoreBullish =
provider.visionBullishScore > provider.visionBearishScore;
//
bool isVisionScoreBearish =
provider.visionBearishScore > provider.visionBullishScore;
//
bool isScoreBullish =
isVisionScoreBullish &&
isAnalyseScoreBullish &&
isConsolidationScoreBullish;
//
bool isScoreBearish =
isVisionScoreBearish &&
isAnalyseScoreBearish &&
isConsolidationScoreBearish;
//
// Waiting Boxes ...
int count = CountWaitingBoxes();
for (int i = 0; i < count; i++)
{
//
XBoxZone iBox = waitingBoxes[i];
bool isBullish = iBox.IsBullish();
//
// Check Score ...
//
bool isScorePassed =
isBullish
? isScoreBullish
: isScoreBearish;
//
// Check Bar Insides ...
//
bool isPBarInside =
(pBar.high <= iBox.upper &&
pBar.low >= iBox.lower) ||
(isBullish
? pBar.low < iBox.upper &&
pBar.GetDown() < iBox.upper
: pBar.high > iBox.lower &&
pBar.GetUp() > iBox.lower);
//
bool isCBarInside =
(cBar.high <= iBox.upper &&
cBar.low >= iBox.lower) ||
(isBullish
? cBar.low < iBox.upper &&
cBar.GetDown() < iBox.upper
: cBar.high > iBox.lower &&
cBar.GetUp() > iBox.lower);
//
// Checking Rejection ...
//
// Bullish ...
bool isBullishRejected =
isBullish &&
cBar.low <= iBox.upper &&
cBar.GetDown() > iBox.upper;
//
// Bearish ...
bool isBearishRejected =
!isBullish &&
cBar.high >= iBox.lower &&
cBar.GetUp() < iBox.lower;
//
// Check Breaktion ...
//
// Bullish ...
bool isBullishBreaked =
isBullish &&
cBar.high > iBox.upper &&
cBar.GetUp() > iBox.upper &&
cBar.low >= iBox.lower;
//
// Bearish ...
bool isBearishBreaked =
!isBullish &&
cBar.low < iBox.lower &&
cBar.GetDown() < iBox.lower &&
cBar.high <= iBox.upper;
//
// Checking PV Pass ...
//
bool isBullishPVPassed =
isBullish &&
vale == valeZ &&
vale > iBox.lower &&
vale < iBox.upper;
//
bool isBearishPVPassed =
!isBullish &&
peak == peakZ &&
peak > iBox.lower &&
peak < iBox.upper;
//
// Summarise ...
//
// Rejection ...
bool isRejected = isBullishRejected ||
isBearishRejected;
//
// Breaktion ...
bool isBreaked =
isPBarInside &&
(isBullishBreaked ||
isBearishBreaked);
//
bool isPVPassed =
(isBullishPVPassed ||
isBearishPVPassed);
//
// Trend Conditions ...
//
bool isX3MABullish =
provider.decisionXConditions.isX3MaFastOverMid &&
provider.decisionXConditions.x3maMidBuffer[1] > provider.decisionXConditions.x3maSlowBuffer[1];
//
bool isX3MABearish =
provider.decisionXConditions.isX3MaFastUnderMid &&
provider.decisionXConditions.x3maMidBuffer[1] < provider.decisionXConditions.x3maSlowBuffer[1];
//
bool isVWapBullish =
provider.decisionXConditions.isVWapFastOverMid &&
provider.decisionXConditions.vwapMidBuffer[1] > provider.decisionXConditions.vwapSlowBuffer[1];
//
bool isVWapBearish =
provider.decisionXConditions.isX3MaFastUnderMid &&
provider.decisionXConditions.vwapMidBuffer[1] < provider.decisionXConditions.vwapSlowBuffer[1];
//
bool isTrendBullish =
isX3MABullish &&
isVWapBullish;
//
bool isTrendBearish =
isX3MABearish &&
isVWapBearish;
//
bool isTrendPassed =
isBullish
? isTrendBullish
: isTrendBearish;
//
// Summarize Conditions ...
//
result =
//
// isBreaked ||
// isRejected ||
isPVPassed &&
isRejected &&
isTrendPassed &&
isScorePassed
//
;
//
if (result)
{
//
box = iBox;
dir = iBox.dir;
signalProvider = X121SMC_XWZ_PROVIDER_ACTIVATED_BOX;
//
iBox.Clean();
break;
}
//
iBox.Clean();
//
}
//
// MA Trends ...
if (!result)
{
//
result = provider.analyseState.HasOrderBlocks();
if (result)
{
//
//
// Trend Conditions ...
//
bool isX3MABullish =
provider.decisionXConditions.isX3MaFastCrossedOverMid;
//
bool isX3MABearish =
provider.decisionXConditions.isX3MaFastCrossedUnderMid;
//
bool isVWapBullish =
provider.decisionXConditions.isVWapFastCrossedOverMid;
//
bool isVWapBearish =
provider.decisionXConditions.isVWapFastCrossedUnderMid;
//
//
//
//
bool isTrendBullish =
(isX3MABullish ||
isVWapBullish) &&
provider.decisionXConditions.isNewPeakOverLast;
//
bool isTrendBearish =
(isX3MABearish ||
isVWapBearish) &&
provider.decisionXConditions.isNewValeUnderLast;
//
result = isTrendBullish ||
isTrendBearish;
if (result)
{
//
// Select Signal Box ...
//
bool isScorePassed =
isTrendBullish
? isScoreBullish
: isScoreBearish;
//
XBoxZone tmpBoxes[];
ToBox(
provider.analyseState.orderBlocks,
tmpBoxes //
);
Copy(
waitingBoxes,
tmpBoxes,
false //
);
int idx = -1;
// bool has = false;
while (HasChild(tmpBoxes))
{
//
if (isTrendBullish)
{
idx = GetHighest(tmpBoxes);
}
else
{
idx = GetLowest(tmpBoxes);
}
//
result = IsValidIndex(idx);
if (!result)
{
break;
}
//
XBoxZone iBox = tmpBoxes[idx];
//
ArrayRemove(
tmpBoxes,
idx,
1 //
);
//
int insideIDX = -1;
bool hasInsideBox = HasInsideBox(
insideIDX,
iBox,
tmpBoxes //
);
if (hasInsideBox)
{
//
hasInsideBox =
isTrendBullish
? iBox.lower < tmpBoxes[insideIDX].lower
: iBox.upper > tmpBoxes[insideIDX].upper;
}
//
bool isBullishPlacePassed =
// !hasInsideBox &&
isTrendBullish &&
iBox.IsBullish() &&
bar.low >= iBox.upper &&
cBar.low >= iBox.upper &&
provider.decisionXConditions.x3maMin >= iBox.lower &&
provider.decisionXConditions.vwapMin >= iBox.lower;
//
bool isBearishPlacePassed =
// !hasInsideBox &&
isTrendBearish &&
iBox.IsBearish() &&
bar.high <= iBox.lower &&
cBar.high <= iBox.lower &&
provider.decisionXConditions.x3maMax <= iBox.upper &&
provider.decisionXConditions.vwapMax <= iBox.upper;
//
result = isScorePassed &&
(isBullishPlacePassed ||
isBearishPlacePassed);
if (result)
{
//
box = iBox;
iBox.Clean();
dir =
isTrendBullish
? X_DIRECTION_BULLISH
: X_DIRECTION_BEARISH;
signalProvider = X121SMC_XWZ_PROVIDER_ACTIVATED_MA;
break;
}
//
}
Clean(tmpBoxes);
}
}
}
//
// Supply and Demand ...
if (false && !result)
{
//
int idx = -1;
bool has = false;
XBoxZone tmpBoxes[];
//
// Detecting Youngest Zones ...
//
XBoxZone bullishBox;
bool hasBullishBox = false;
if (!hasBullishBox)
{
//
XCOrderBlock *ob = NULL;
idx = GetYoungest(provider.analyseState.bullishOrderBlocks);
has = IsValidIndex(idx);
if (has)
{
//
ob = provider.analyseState.bullishOrderBlocks[idx];
//
XOHCL startedBar;
bool isBodyOut = false;
bool isStarted = ob.IsStarted(
ob.GetDirection(),
startedBar,
isBodyOut //
);
has = isStarted &&
isBodyOut;
if (has)
{
//
hasBullishBox = ToBox(
bullishBox,
ob //
);
}
}
//
if (!hasBullishBox)
{
bullishBox.Clean();
}
//
ZeroMemory(ob);
}
//
XBoxZone bearishBox;
bool hasBearishBox = false;
if (!hasBearishBox)
{
//
XCOrderBlock *ob = NULL;
idx = GetYoungest(provider.analyseState.bearishOrderBlocks);
has = IsValidIndex(idx);
if (has)
{
//
ob = provider.analyseState.bearishOrderBlocks[idx];
//
XOHCL startedBar;
bool isBodyOut = false;
bool isStarted = ob.IsStarted(
ob.GetDirection(),
startedBar,
isBodyOut //
);
has = isStarted &&
isBodyOut;
if (has)
{
//
hasBearishBox = ToBox(
bearishBox,
ob //
);
}
}
//
if (!hasBearishBox)
{
bearishBox.Clean();
}
//
ZeroMemory(ob);
}
//
XBoxZone bullishCZBox;
bool hasBullishConsolidationZone = false;
XConsolidationZone bullishConsolidationZone;
hasBullishConsolidationZone = provider.decisionState.HasBullishConsolidationZones();
if (hasBullishConsolidationZone)
{
//
idx = GetYoungest(provider.decisionState.bullishConsolidationZones);
hasBullishConsolidationZone = IsValidIndex(idx);
if (hasBullishConsolidationZone)
{
//
bullishConsolidationZone = provider.decisionState.bullishConsolidationZones[idx];
if (hasBullishConsolidationZone)
{
//
hasBullishConsolidationZone = ToBox(
bullishCZBox,
bullishConsolidationZone //
);
}
}
}
//
XBoxZone bearishCZBox;
bool hasBearishConsolidationZone = false;
XConsolidationZone bearishConsolidationZone;
hasBearishConsolidationZone = provider.decisionState.HasBearishConsolidationZones();
if (hasBearishConsolidationZone)
{
//
idx = GetYoungest(provider.decisionState.bearishConsolidationZones);
hasBearishConsolidationZone = IsValidIndex(idx);
if (hasBearishConsolidationZone)
{
//
bearishConsolidationZone = provider.decisionState.bearishConsolidationZones[idx];
if (hasBearishConsolidationZone)
{
//
hasBearishConsolidationZone = ToBox(
bearishCZBox,
bearishConsolidationZone //
);
}
}
}
//
//
//
//
// Supply Zone ...
has = provider.visionState.HasSupplyZones();
if (has)
{
//
ToBox(
provider.visionState.supplyZones,
tmpBoxes //
);
//
while (HasChild(tmpBoxes))
{
//
idx = GetYoungest(tmpBoxes);
has = IsValidIndex(idx);
if (!has)
{
break;
}
//
XBoxZone iBox = tmpBoxes[idx];
ArrayRemove(
tmpBoxes,
idx,
1 //
);
//
// Price Must Be Inside a Zonne More Than 5 Bar ...
bool isPriceInside =
//
bar.high < iBox.upper &&
bar.low > iBox.lower &&
//
cBar.high < iBox.upper &&
cBar.low > iBox.lower &&
//
pBar.high < iBox.upper &&
pBar.low > iBox.lower
//
;
//
bool isBearishBoxPassed =
hasBearishBox &&
IsBoxInside(
bearishBox,
iBox //
);
//
bool isBearishCZBoxPassed =
hasBearishConsolidationZone &&
IsBoxInside(
bearishCZBox,
iBox //
);
//
result = isPriceInside &&
(isBearishBoxPassed ||
isBearishCZBoxPassed);
if (result)
{
//
if (isBearishBoxPassed)
{
box = bearishBox;
}
else
{
box = bearishCZBox;
}
//
iBox.to = TimeCurrent();
XCBoxObject *iObj;
provider.visionCycleHelper.mPOIDrawer.DrawBox(
iBox,
iObj //
);
//
dir = X_DIRECTION_BEARISH;
signalProvider = X121SMC_XWZ_PROVIDER_ACTIVATED_AREA;
//
iBox.Clean();
//
break;
}
//
iBox.Clean();
}
//
Clean(tmpBoxes);
}
//
// Demand Zone ...
has = provider.visionState.HasDemandZones();
if (!result && has)
{
//
ToBox(
provider.visionState.demandZones,
tmpBoxes //
);
//
while (HasChild(tmpBoxes))
{
//
idx = GetYoungest(tmpBoxes);
has = IsValidIndex(idx);
if (!has)
{
break;
}
//
XBoxZone iBox = tmpBoxes[idx];
ArrayRemove(
tmpBoxes,
idx,
1 //
);
//
// Price Must Be Inside a Zonne More Than 5 Bar ...
bool isPriceInside =
//
bar.high < iBox.upper &&
bar.low > iBox.lower &&
//
cBar.high < iBox.upper &&
cBar.low > iBox.lower &&
//
pBar.high < iBox.upper &&
pBar.low > iBox.lower
//
;
//
bool isBullishBoxPassed =
hasBullishBox &&
IsBoxInside(
bullishBox,
iBox //
);
//
bool isBullishCZBoxPassed =
hasBullishConsolidationZone &&
IsBoxInside(
bullishCZBox,
iBox //
);
//
result = isPriceInside &&
(isBullishBoxPassed ||
isBullishCZBoxPassed);
if (result)
{
//
if (isBullishBoxPassed)
{
box = bullishBox;
}
else
{
box = bullishCZBox;
}
//
iBox.to = TimeCurrent();
XCBoxObject *iObj;
provider.visionCycleHelper.mPOIDrawer.DrawBox(
iBox,
iObj //
);
//
dir = X_DIRECTION_BULLISH;
signalProvider = X121SMC_XWZ_PROVIDER_ACTIVATED_AREA;
//
iBox.Clean();
//
break;
}
//
iBox.Clean();
}
//
Clean(tmpBoxes);
}
//
Clean(tmpBoxes);
//
bullishBox.Clean();
bearishBox.Clean();
bullishCZBox.Clean();
bearishCZBox.Clean();
bullishConsolidationZone.Clean();
bearishConsolidationZone.Clean();
//
}
//
bar.Clean();
cBar.Clean();
pBar.Clean();
//
return result;
}
//
bool DetectSignalConditions(
XBoxZone &box,
ENUM_X_DIRECTION &dir,
ENUM_X121SMC_XWZ_PROVIDERS &signalProvider,
X121SMCStrategySignalProviderData &provider,
int barIndex = 0 //
)
{
//
bool result = false;
//
// Normalize Bars ...
//
box.Clean();
dir = X_DIRECTION_NONE;
signalProvider = X121SMC_XWZ_PROVIDER_NONE;
//
if (barIndex < 0)
{
barIndex = 0;
}
//
result = IsValid();
if (!result)
{
return result;
}
//
int zIDX = barIndex;
int cIDX = zIDX + 1;
int pIDX = cIDX + 1;
//
bool isBullish = false;
bool isBearish = false;
//
XOHCL zBar;
XOHCL cBar;
XOHCL pBar;
//
// Initial Bars ...
result = zBar.Init(
symbol,
period,
barIndex //
);
result =
result &&
zBar.GetPreviousBar(cBar);
result =
result &&
cBar.GetPreviousBar(pBar);
if (!result)
{
//
zBar.Clean();
cBar.Clean();
pBar.Clean();
//
return result;
}
//
// Detecting Signal Conditions ...
X121SMCStrategyConditionParser decisionParser;
decisionParser.Parse(provider.decisionXConditions);
//
// Senario 1:
// ----------
//
// Senario 1 Bullish Conditions ...
bool isSenario1Bullish =
//
// X3Ma / XVwap Switched To Bulish ...
(
//
// X3Ma Switched To Bulish ...
(
//
(provider.decisionXConditions.isX3MaFastCrossedOverMid &&
decisionParser.isX3MaBullishStateUnderValesGoldenZone)
//
)
//
||
//
// XVWap Switched To Bulish ...
(
//
(provider.decisionXConditions.isVWapFastCrossedOverMid &&
decisionParser.isVWapBullishStateUnderValesGoldenZone)
//
)
//
)
//
&&
//
// Checking other Conditions ...
(
//
// XSTR ...
provider.decisionXConditions.isStrBullish &&
//
// XCHE ...
provider.decisionXConditions.isCheBullish &&
provider.decisionXConditions.le1Buffer[cIDX] < cBar.low &&
provider.decisionXConditions.le2Buffer[cIDX] < cBar.low
//
)
//
;
//
// Senario 1 Bearish Conditions ...
bool isSenario1Bearish =
//
// X3Ma / XVwap Switched To Bearish ...
(
//
// X3Ma Switched To Bearish ...
(
//
(provider.decisionXConditions.isX3MaFastCrossedUnderMid &&
decisionParser.isX3MaBearishStateOverPeaksGoldenZone)
//
)
//
||
//
// XVWap Switched To Bearish ...
(
//
(provider.decisionXConditions.isVWapFastCrossedUnderMid &&
decisionParser.isVWapBearishStateOverPeaksGoldenZone)
//
)
//
)
//
&&
//
// Checking other Conditions ...
(
//
// XSTR ...
provider.decisionXConditions.isStrBearish &&
//
// XCHE ...
provider.decisionXConditions.isCheBearish &&
provider.decisionXConditions.se1Buffer[cIDX] > cBar.high &&
provider.decisionXConditions.se2Buffer[cIDX] > cBar.high
//
)
//
;
//
// Filling Requirements using Senario 1 ...
bool isSenari1Happend =
isSenario1Bullish ||
isSenario1Bearish;
if (isSenari1Happend)
{
//
dir =
isSenario1Bullish
? X_DIRECTION_BULLISH
: X_DIRECTION_BEARISH;
//
box.dir = dir;
box.to = TimeCurrent();
box.symbol = provider
.decisionXConditions
.symbol;
box.period = provider
.decisionXConditions
.period;
//
int fromIDX = -1;
if (isSenario1Bullish)
{
//
double vale = provider
.decisionXConditions
.valesBuffer[cIDX];
//
box.lower = vale;
//
box.upper = provider
.decisionXConditions
.valesGoldenBuffer[cIDX];
//
int lowerValeIDX = -1;
double lowerVale = provider
.decisionCycleHelper
.mX121Helper
.xpvHelper
.GetLowerVale(
lowerValeIDX,
vale,
cBar.Index() //
);
//
int higherValeIDX = -1;
double higherVale = provider
.decisionCycleHelper
.mX121Helper
.xpvHelper
.GetHigherVale(
higherValeIDX,
vale,
cBar.Index() //
);
//
if (IsValidIndex(lowerValeIDX) &&
IsValidIndex(higherValeIDX))
{
//
fromIDX =
lowerValeIDX < higherValeIDX
? lowerValeIDX
: higherValeIDX;
}
else if (IsValidIndex(lowerValeIDX) &&
!IsValidIndex(higherValeIDX))
{
//
fromIDX = lowerValeIDX;
}
else if (!IsValidIndex(lowerValeIDX) &&
IsValidIndex(higherValeIDX))
{
//
fromIDX = higherValeIDX;
}
}
else
{
//
double peak = provider
.decisionXConditions
.peaksBuffer[cIDX];
//
box.upper = peak;
//
box.lower = provider
.decisionXConditions
.peaksGoldenBuffer[cIDX];
//
int lowerPeakIDX = -1;
double lowerPeak = provider
.decisionCycleHelper
.mX121Helper
.xpvHelper
.GetLowerPeak(
lowerPeakIDX,
peak,
cBar.Index() //
);
//
int higherPeakIDX = -1;
double higherPeak = provider
.decisionCycleHelper
.mX121Helper
.xpvHelper
.GetHigherPeak(
higherPeakIDX,
peak,
cBar.Index() //
);
//
if (IsValidIndex(lowerPeakIDX) &&
IsValidIndex(higherPeakIDX))
{
//
fromIDX =
lowerPeakIDX < higherPeakIDX
? lowerPeakIDX
: higherPeakIDX;
}
else if (IsValidIndex(lowerPeakIDX) &&
!IsValidIndex(higherPeakIDX))
{
//
fromIDX = lowerPeakIDX;
}
else if (!IsValidIndex(lowerPeakIDX) &&
IsValidIndex(higherPeakIDX))
{
//
fromIDX = higherPeakIDX;
}
}
//
if (IsValidIndex(fromIDX))
{
//
box.from = iTime(
zBar.symbol,
zBar.period,
fromIDX //
);
}
else
{
box.from = pBar.time;
}
//
signalProvider = X121SMC_XWZ_PROVIDER_ACTIVATED_BOX;
}
//
// Summarize All Senario(s) Conditions ...
//
isBullish =
//
isSenario1Bullish
//
;
//
isBearish =
//
isSenario1Bearish
//
;
//
// Check All Conditions ...
result =
box.IsValid() &&
HasDirection(dir) &&
(isBullish ||
isBearish);
//
// Cleanup Resources ...
//
zBar.Clean();
cBar.Clean();
pBar.Clean();
//
return result;
}
//
bool IsExists(XOBFVG &zone)
{
//
bool result = false;
//
// Check Validation ...
result = zone.IsValid() &&
(HasWaitingZones() ||
HasUnavailableZones());
if (!result)
{
return result;
}
//
int idx = -1;
//
// Check Index in Waiting Zones ...
idx = FindIndex(
zone,
waitingZones //
);
result = IsValidIndex(idx);
if (result)
{
return result;
}
//
// Check Index in Unavailable Zones ...
idx = FindIndex(
zone,
unavailableZones //
);
result = IsValidIndex(idx);
if (result)
{
return result;
}
//
return result;
}
//
bool IsExists(XBoxZone &box)
{
//
bool result = false;
//
// Check Validation ...
result = box.IsValid() &&
(HasWaitingBoxes() ||
HasUnavailableBoxes());
if (!result)
{
return result;
}
//
int idx = -1;
//
// Check Index in Waiting Zones ...
idx = FindIndex(
box,
waitingBoxes //
);
result = IsValidIndex(idx);
if (result)
{
return result;
}
//
// Check Index in Unavailable Zones ...
idx = FindIndex(
box,
unavailableBoxes //
);
result = IsValidIndex(idx);
if (result)
{
return result;
}
//
return result;
}
//
bool IsDestroyed(
int barIndex = 0,
ENUM_TIMEFRAMES forPeriod = NULL //
)
{
//
bool result = false;
//
if (barIndex < 0)
{
barIndex = 0;
}
//
if (!IsValid(forPeriod))
{
forPeriod = period;
}
//
result = IsValid();
if (!result)
{
return result;
}
//
XOHCL bar;
result = bar.Init(
symbol,
period,
barIndex //
);
if (!result)
{
//
bar.Clean();
return result;
}
//
XOHCL cBar;
result = bar.GetPreviousBar(cBar);
if (!result)
{
//
bar.Clean();
cBar.Clean();
//
return result;
}
//
bool isSupplyZoneBreaked =
//
bar.low > supplyZone.Upper() &&
cBar.low > supplyZone.Upper()
//
;
//
bool isDemandZoneBreaked =
//
bar.high < demandZone.Lower() &&
cBar.high < demandZone.Lower()
//
;
//
bar.Clean();
cBar.Clean();
//
result = isSupplyZoneBreaked ||
isDemandZoneBreaked;
//
return result;
}
//
bool DetectPriority(
ENUM_X121SMC_XWZ_PRIORITY &priority,
ENUM_X_DIRECTION forDir,
int barIndex = 0,
ENUM_TIMEFRAMES forPeriod = NULL //
)
{
//
bool result = false;
//
priority = X121SMC_XWZ_PRIORITY_NONE;
//
if (barIndex < 0)
{
barIndex = 0;
}
//
if (!IsValid(forPeriod))
{
forPeriod = period;
}
//
result = IsValid() &&
HasDirection(forDir);
if (!result)
{
return result;
}
//
bool isBullish = IsBullish(forDir);
//
XOHCL bar;
result = bar.Init(
symbol,
forPeriod,
barIndex //
);
if (!result)
{
//
bar.Clean();
return result;
}
//
if (bar.high < supplyZone.Upper() &&
bar.low > supplyZone.Lower())
{
//
priority =
isBullish
? X121SMC_XWZ_PRIORITY_NONE
: X121SMC_XWZ_PRIORITY_STRONG_HIGH;
}
else if (bar.high < supplyZone.Lower() &&
bar.low > quarter1)
{
//
priority =
isBullish
? X121SMC_XWZ_PRIORITY_WEAK
: X121SMC_XWZ_PRIORITY_HIGH;
}
else if (bar.high < quarter1 &&
bar.low > quarter2)
{
//
priority =
isBullish
? X121SMC_XWZ_PRIORITY_LOW
: X121SMC_XWZ_PRIORITY_REGULAR;
}
else if (bar.high < quarter2 &&
bar.low > quarter3)
{
//
priority =
isBullish
? X121SMC_XWZ_PRIORITY_REGULAR
: X121SMC_XWZ_PRIORITY_LOW;
}
else if (bar.high < quarter3 &&
bar.low > demandZone.Upper())
{
//
priority =
isBullish
? X121SMC_XWZ_PRIORITY_HIGH
: X121SMC_XWZ_PRIORITY_WEAK;
}
else if (bar.high < demandZone.Upper() &&
bar.low > demandZone.Lower())
{
//
priority =
isBullish
? X121SMC_XWZ_PRIORITY_STRONG_HIGH
: X121SMC_XWZ_PRIORITY_NONE;
}
//
result = priority != X121SMC_XWZ_PRIORITY_NONE &&
priority != X121SMC_XWZ_PRIORITY_WEAK;
//
bar.Clean();
//
return result;
}
//
bool DetectOveralDirection(
ENUM_X_DIRECTION &dir //
)
{
//
bool result = false;
//
dir = X_DIRECTION_NONE;
//
result = IsValid() &&
HasSupplyZone() &&
HasDemandZone();
if (!result)
{
return result;
}
//
XBoxZone demBox;
XBoxZone supBox;
result = ToBox(
demBox,
demandZone //
);
if (!result)
{
//
supBox.Clean();
demBox.Clean();
//
return result;
}
result = ToBox(
supBox,
supplyZone //
);
if (!result)
{
//
supBox.Clean();
demBox.Clean();
//
return result;
}
//
XOHCL supPriceOutBar;
XOHCL demPriceOutBar;
result = DetectBoxNearestPriceOut(
supBox,
supPriceOutBar,
period //
);
if (!result)
{
//
demBox.Clean();
supBox.Clean();
supPriceOutBar.Clean();
demPriceOutBar.Clean();
//
return result;
}
result = DetectBoxNearestPriceOut(
demBox,
demPriceOutBar,
period //
);
if (!result)
{
//
demBox.Clean();
supBox.Clean();
supPriceOutBar.Clean();
demPriceOutBar.Clean();
//
return result;
}
//
// Specified Direction ...
dir =
(supPriceOutBar.IsValid() &&
demPriceOutBar.IsValid())
? supPriceOutBar.time > demPriceOutBar.time
? X_DIRECTION_BEARISH
: demPriceOutBar.time > supPriceOutBar.time
? X_DIRECTION_BULLISH
: X_DIRECTION_NONE
: X_DIRECTION_NONE;
//
result = HasDirection(dir);
//
// Clean Up Resources ...
//
demBox.Clean();
supBox.Clean();
supPriceOutBar.Clean();
demPriceOutBar.Clean();
//
return result;
}
//
void UpdateTo(datetime value = NULL)
{
//
value = NormalizeTime(value);
//
int count = 0;
bool has = false;
//
has = HasSupplyZone();
if (has)
{
supplyZone.To(value);
}
//
has = HasDemandZone();
if (has)
{
demandZone.To(value);
}
//
has = HasWaitingZones();
if (has)
{
//
count = CountWaitingZones();
for (int i = 0; i < count; i++)
{
waitingZones[i].UpdateTo(value);
}
}
//
has = HasWaitingBoxes();
if (has)
{
//
count = CountWaitingBoxes();
for (int i = 0; i < count; i++)
{
waitingBoxes[i].to = value;
}
}
//
}
//
void Draw(
XCPOIDrawer *drawer,
bool drawSupplyZone = false,
bool drawDemandZone = false,
bool drawWaitingZones = false)
{
//
if (drawer == NULL)
{
return;
}
//
int count = 0;
bool has = false;
bool isCreated = false;
//
ulong chartID = drawer.ChartIdentification();
int subWindow = drawer.SubWindowIdentification();
color bullishColor = drawer.BarBullishColor();
color bearishColor = drawer.BarBearishColor();
//
// Supply Zone ...
if (drawSupplyZone)
{
//
has = HasSupplyZone();
if (has)
{
//
XCSupplyZoneObject *iObj;
isCreated = drawer.CreateSupplyZone(
supplyZone,
iObj //
);
//
if (isCreated)
{
mWorkingZoneObjects.Add(iObj);
}
}
}
//
// Demand Zone ...
if (drawDemandZone)
{
//
has = HasDemandZone();
if (has)
{
//
XCDemandZoneObject *iObj;
isCreated = drawer.CreateDemandZone(
demandZone,
iObj //
);
//
if (isCreated)
{
mWorkingZoneObjects.Add(iObj);
}
}
}
//
//
//
//
// Quarters ...
has = IsValid();
if (has)
{
//
double zoneUpper = supplyZone.Upper();
double upper = supplyZone.Lower();
//
double lower = demandZone.Upper();
double zoneLower = demandZone.Lower();
//
string prefix = "X121WZone_" + symbol + "_" + ToString(period);
//
// Zone Upper ...
CChartObjectHLine *zoneUpperLine;
zoneUpperLine = new CChartObjectHLine();
isCreated = zoneUpperLine.Create(
chartID,
prefix + "_ZoneTop",
subWindow,
zoneUpper //
);
if (isCreated)
{
//
zoneUpperLine.Color(clrRed);
//
mWorkingZoneObjects.Add(zoneUpperLine);
}
//
// Zone Lower ...
CChartObjectHLine *zoneLowerLine;
zoneLowerLine = new CChartObjectHLine();
isCreated = zoneLowerLine.Create(
chartID,
prefix + "_ZoneDown",
subWindow,
zoneLower //
);
if (isCreated)
{
//
zoneLowerLine.Color(clrRed);
//
mWorkingZoneObjects.Add(zoneLowerLine);
}
//
// Upper ...
CChartObjectHLine *upperLine;
upperLine = new CChartObjectHLine();
isCreated = upperLine.Create(
chartID,
prefix + "_Upper",
subWindow,
upper //
);
if (isCreated)
{
//
upperLine.Color(clrLime);
//
mWorkingZoneObjects.Add(upperLine);
}
//
// Lower ...
CChartObjectHLine *lowerLine;
lowerLine = new CChartObjectHLine();
isCreated = lowerLine.Create(
chartID,
prefix + "_Lower",
subWindow,
lower //
);
if (isCreated)
{
//
lowerLine.Color(clrLime);
//
mWorkingZoneObjects.Add(lowerLine);
}
//
// Quarters ...
//
// Quarter 1 ...
CChartObjectHLine *q1Line;
q1Line = new CChartObjectHLine();
isCreated = q1Line.Create(
chartID,
prefix + "_Q1",
subWindow,
quarter1 //
);
if (isCreated)
{
//
q1Line.Color(clrYellow);
//
mWorkingZoneObjects.Add(q1Line);
}
//
// Quarter 2 ...
CChartObjectHLine *q2Line;
q2Line = new CChartObjectHLine();
isCreated = q2Line.Create(
chartID,
prefix + "_Q2",
subWindow,
quarter2 //
);
if (isCreated)
{
//
q2Line.Color(clrYellow);
//
mWorkingZoneObjects.Add(q2Line);
}
//
// Quarter 3 ...
CChartObjectHLine *q3Line;
q3Line = new CChartObjectHLine();
isCreated = q3Line.Create(
chartID,
prefix + "_Q3",
subWindow,
quarter3 //
);
if (isCreated)
{
//
q3Line.Color(clrYellow);
//
mWorkingZoneObjects.Add(q3Line);
}
}
//
// Waiting Zones ...
if (drawWaitingZones)
{
//
has = HasWaitingZones();
if (has)
{
//
count = CountWaitingZones();
for (int i = 0; i < count; i++)
{
//
XCBaseObject *iObjects[];
int iObjectsCount = drawer.DrawOBFVG(
waitingZones[i],
iObjects,
true, // Draw Order Block ...
true, // Draw Fair Value Gaps ...
true, // Draw All Fair Value Gaps ...
//
true, // Draw OB StartedBar ...
true, // Draw OB ActivatedBar ...
true, // Draw OB BreakedBar ...
true, // Draw OB WorkedBar ...
//
true, // Draw FVG StartedBar ...
true, // Draw FVG ActivatedBar ...
true, // Draw FVG BreakedBar ...
true // Draw FVG WorkedBar ...
//
);
has = IsValidSize(iObjectsCount);
if (has)
{
//
for (int j = 0; j < iObjectsCount; j++)
{
mDrawnObjects.Add(iObjects[j]);
}
}
//
// if (drawWaitingZonesBoxArea)
// {
// //
// XBoxZone iBox;
// has = waitingZones[i].ToZone(
// iBox //
// );
// if (has)
// {
// //
// XCBoxObject *iBoxObj;
// has = drawer.DrawBox(
// iBox,
// iBoxObj //
// );
// if (has)
// {
// mDrawnObjects.Add(iBoxObj);
// }
// }
// //
// iBox.Clean();
// }
}
}
//
has = HasWaitingBoxes();
if (has)
{
//
count = CountWaitingBoxes();
for (int i = 0; i < count; i++)
{
//
XCBoxObject *iBoxObj;
has = drawer.DrawBox(
waitingBoxes[i],
iBoxObj //
);
if (has)
{
mDrawnObjects.Add(iBoxObj);
}
//
ZeroMemory(iBoxObj);
}
}
}
//
}
//
//
//
//
bool HasSupplyZone()
{
return supplyZone != NULL &&
supplyZone.IsValid();
}
//
bool HasDemandZone()
{
return demandZone != NULL &&
demandZone.IsValid();
}
//
bool HasWaitingZones()
{
return HasChild(waitingZones);
}
//
int CountWaitingZones()
{
return ArraySize(waitingZones);
}
//
bool HasUnavailableZones()
{
return HasChild(unavailableZones);
}
//
int CounUnavailableZones()
{
return ArraySize(unavailableZones);
}
//
bool HasWaitingBoxes()
{
return HasChild(waitingBoxes);
}
//
int CountWaitingBoxes()
{
return ArraySize(waitingBoxes);
}
//
bool HasUnavailableBoxes()
{
return HasChild(unavailableBoxes);
}
//
int CountUnavailableBoxes()
{
return ArraySize(unavailableBoxes);
}
//
};
//
struct X121SMCStrategyXWZSignalConditions
{
//
// Props ...
//
string symbol;
ENUM_TIMEFRAMES period;
//
double sl;
double reward;
double amountPercent;
ENUM_X_DIRECTION dir;
ENUM_X_POSITION_TYPES type;
//
// Setup Props ...
//
datetime setupTime;
datetime triggerTime;
//
double pivot;
double point;
double sls[];
double targets[];
//
XBoxZone signalBox;
//
ENUM_X121SMC_XWZ_PRIORITY priority;
ENUM_X121SMC_XWZ_PROVIDERS provider;
//
// Constructor ...
X121SMCStrategyXWZSignalConditions()
{
Clean();
}
//
// Tools ...
/**
* Cleaning Up ...
*/
void Clean()
{
//
sl = 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;
//
reward = 0;
amountPercent = 0;
//
Clean(sls);
Clean(targets);
signalBox.Clean();
//
provider = X121SMC_XWZ_PROVIDER_NONE;
}
//
//
//
//
void UpdateTo(datetime value = NULL)
{
//
value = NormalizeTime(value);
//
int count = 0;
bool has = false;
}
//
};
//
// Extension Functions ...
//