Files
MQL5Data/X121SMCEA/Signals/x-121.smc.xsupdemobs.signal.lib.mq5
T
2025-02-10 10:21:00 +03:30

4707 lines
112 KiB
Plaintext

///////////////////////////////////////////////////////
//
// SaherElm IT Center MQL5 X121 SMC Signal Class
// -------------------------------------------------
// Name: XSupDemOBS
// 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_XSUPDEMOBS_PRIORITY
{
X121SMC_XSUPDEMOBS_PRIORITY_NONE,
X121SMC_XSUPDEMOBS_PRIORITY_WEAK,
X121SMC_XSUPDEMOBS_PRIORITY_LOW,
X121SMC_XSUPDEMOBS_PRIORITY_REGULAR,
X121SMC_XSUPDEMOBS_PRIORITY_HIGH,
};
//
struct XOBFVG
{
//
string symbol;
ENUM_TIMEFRAMES period;
//
datetime time;
//
XCOrderBlock *ob;
XCFVG *fvg;
//
XCFVG *unActivatedFVGs[];
XCOrderBlock *unActivatedOBs[];
//
XOBFVG()
{
Clean();
}
//
void Clean()
{
//
ob = NULL;
fvg = NULL;
time = NULL;
symbol = NULL;
period = NULL;
//
Clean(unActivatedOBs);
Clean(unActivatedFVGs);
//
ZeroMemory(this);
}
//
bool IsValid()
{
//
bool result = false;
//
result =
//
ob != NULL &&
ob.IsValid() &&
fvg != NULL &&
fvg.IsValid() &&
ob.From() < fvg.From() &&
IsValid(time) &&
IsValid(symbol) &&
IsValid(period)
//
;
if (!result)
{
return result;
}
//
ENUM_X_DIRECTION mDir = GetDirection();
//
// Validate Order Block ...
//
// Validate Started Zones ...
XOHCL obStartedBar;
ENUM_X_DIRECTION obStartedDir;
bool isStarted = ob.IsStarted(
mDir,
obStartedBar,
obStartedDir //
);
result = isStarted;
if (!result)
{
return result;
}
//
// Validate InActive Zone ...
XOHCL obActivatedBar;
ENUM_X_DIRECTION obActivatedDir;
bool isActivated = ob.IsActivated(
mDir,
obActivatedBar,
obActivatedDir //
);
result = !isActivated;
if (!result)
{
return result;
}
//
// Validate Zone Iverse Breake ...
XOHCL obBreakedBar;
ENUM_X_DIRECTION obBreakedDir;
bool isBreaked = ob.IsBreaked(
Opposit(mDir),
obBreakedBar,
obBreakedDir,
true // Ignore Activation ...
);
result = !isBreaked;
if (!result)
{
return result;
}
//
// Checking Dirction(s) ...
result =
HasDirection(mDir) &&
mDir == fvg.GetDirection();
if (!result)
{
return result;
}
//
// Validate FVG From Date ...
//
// Checking FVG Place ...
//
bool isBullish = IsBullish(mDir);
//
bool isAbove = IsAboveDiff(
fvg,
ob,
true // Ignore Inside ...
);
//
bool isBelow = IsBelowDiff(
fvg,
ob,
true // Ignore Inside ...
);
//
result =
isBullish
? isAbove
: isBelow;
if (!result)
{
return result;
}
//
// Check FVG Must Be Started ...
XOHCL fvgStartedBar;
ENUM_X_DIRECTION fvgStartedDir;
isStarted = fvg.IsStarted(
mDir,
fvgStartedBar,
fvgStartedDir //
);
result = isStarted;
if (!result)
{
return result;
}
//
// Check FVg Not Breaked in Reversal Direction ...
XOHCL fvgBreakedBar;
ENUM_X_DIRECTION fvgBreakedDir;
isBreaked = fvg.IsBreaked(
Opposit(mDir),
fvgBreakedBar,
fvgBreakedDir,
true // Ignore Activation ...
);
result = !isBreaked;
if (!result)
{
return result;
}
//
return result;
}
//
ENUM_X_DIRECTION GetDirection()
{
return ob.GetDirection();
}
//
int CountUnActivatedOBs()
{
return ArraySize(unActivatedOBs);
}
//
bool HasUnActivatedOBs()
{
return IsValidSize(CountUnActivatedOBs());
}
//
bool AddUnActivatedOB(
XCOrderBlock *_ob,
XOHCL &bar //
)
{
//
bool result = false;
//
result = IsValid() &&
bar.IsValid() &&
_ob != NULL &&
_ob.IsValid();
if (!result)
{
return result;
}
//
// Check Order Block is not Same as Current OB ...
bool isSame = IsSame(
_ob,
ob //
);
result = !isSame;
if (!result)
{
return result;
}
//
ENUM_X_DIRECTION mDir = GetDirection();
bool isBullish = IsBullish(mDir);
//
// Check Bars ...
XOHCL pBar;
result = bar.GetPreviousBar(pBar);
if (!result)
{
return result;
}
//
bool isPricePassed =
isBullish
? IsAbove(
bar.low,
_ob //
) &&
IsAbove(
pBar.low,
_ob //
)
: IsBelow(
bar.high,
_ob //
) &&
IsBelow(
pBar.high,
_ob //
);
result = isPricePassed;
if (!result)
{
return result;
}
//
// Validate Order Block is Not Activated ...
//
// Validate Started Zones ...
XOHCL obStartedBar;
ENUM_X_DIRECTION obStartedDir;
bool isStarted = _ob.IsStarted(
mDir,
obStartedBar,
obStartedDir //
);
result = isStarted;
if (!result)
{
return result;
}
//
// Validate InActive Zone ...
XOHCL obActivatedBar;
ENUM_X_DIRECTION obActivatedDir;
bool isActivated = _ob.IsActivated(
mDir,
obActivatedBar,
obActivatedDir //
);
result = !isActivated;
if (!result)
{
return result;
}
//
// Validate Zone Iverse Breake ...
XOHCL obBreakedBar;
ENUM_X_DIRECTION obBreakedDir;
bool isBreaked = _ob.IsBreaked(
Opposit(mDir),
obBreakedBar,
obBreakedDir,
true // Ignore Activation ...
);
result = !isBreaked;
if (!result)
{
return result;
}
//
int idx = FindIndex(
_ob,
unActivatedOBs //
);
result = !IsValidIndex(idx);
if (!result)
{
return result;
}
//
bool isLastPassed = true;
bool isAboveLast = false;
bool isBelowLast = false;
XCOrderBlock *lastOB = NULL;
int unActivatedOBsCount = CountUnActivatedOBs();
bool hasUnActivatedOBs = HasUnActivatedOBs();
if (hasUnActivatedOBs)
{
lastOB = unActivatedOBs[unActivatedOBsCount - 1];
}
bool hasLastOB = lastOB != NULL &&
lastOB.IsValid();
if (hasLastOB)
{
//
isAboveLast = IsAbove(
_ob,
lastOB,
true // Ignore Inside ...
);
//
isBelowLast = IsBelow(
_ob,
lastOB,
true // Ignore Inside ...
);
//
isLastPassed =
isBullish
? isAboveLast
: isBelowLast;
}
result = isLastPassed;
if (!result)
{
return result;
}
//
Add(
_ob,
unActivatedOBs //
);
//
return result;
}
//
int CountUnActivatedFVGs()
{
return ArraySize(unActivatedFVGs);
}
//
bool HasUnActivatedFVGs()
{
return IsValidSize(CountUnActivatedFVGs());
}
//
bool AddUnActivatedFVG(
XCFVG *_fvg,
XOHCL &bar //
)
{
//
bool result = false;
//
result = IsValid() &&
bar.IsValid() &&
_fvg != NULL &&
_fvg.IsValid();
if (!result)
{
return result;
}
//
// Check Order Block is not Same as Current OB ...
bool isSame = IsSame(
_fvg,
fvg //
);
result = !isSame;
if (!result)
{
return result;
}
//
ENUM_X_DIRECTION mDir = GetDirection();
bool isBullish = IsBullish(mDir);
//
// Check Bars ...
XOHCL pBar;
result = bar.GetPreviousBar(pBar);
if (!result)
{
return result;
}
//
bool isPricePassed =
isBullish
? IsAbove(
bar.low,
_fvg //
) &&
IsAbove(
pBar.low,
_fvg //
)
: IsBelow(
bar.high,
_fvg //
) &&
IsBelow(
pBar.high,
_fvg //
);
result = isPricePassed;
if (!result)
{
return result;
}
//
// Validate Order Block is Not Activated ...
//
// Validate Started Zones ...
XOHCL fvgStartedBar;
ENUM_X_DIRECTION fvgStartedDir;
bool isStarted = _fvg.IsStarted(
mDir,
fvgStartedBar,
fvgStartedDir //
);
result = isStarted;
if (!result)
{
return result;
}
//
// Validate InActive Zone ...
XOHCL fvgActivatedBar;
ENUM_X_DIRECTION fvgActivatedDir;
bool isActivated = _fvg.IsActivated(
mDir,
fvgActivatedBar,
fvgActivatedDir //
);
result = !isActivated;
if (!result)
{
return result;
}
//
// Validate Zone Iverse Breake ...
XOHCL fvgBreakedBar;
ENUM_X_DIRECTION fvgBreakedDir;
bool isBreaked = _fvg.IsBreaked(
Opposit(mDir),
fvgBreakedBar,
fvgBreakedDir,
true // Ignore Activation ...
);
result = !isBreaked;
if (!result)
{
return result;
}
//
int idx = FindIndex(
_fvg,
unActivatedFVGs //
);
result = !IsValidIndex(idx);
if (!result)
{
return result;
}
//
XCFVG *lastFVG = NULL;
bool isLastPassed = true;
bool isAboveLast = false;
bool isBelowLast = false;
int unActivatedFVGsCount = CountUnActivatedFVGs();
bool hasUnActivatedFVGs = HasUnActivatedFVGs();
if (hasUnActivatedFVGs)
{
lastFVG = unActivatedFVGs[unActivatedFVGsCount - 1];
}
bool hasLastFVG = lastFVG != NULL &&
lastFVG.IsValid();
if (hasLastFVG)
{
//
isAboveLast = IsAbove(
_fvg,
lastFVG,
true // Ignore Inside ...
);
//
isBelowLast = IsBelow(
_fvg,
lastFVG,
true // Ignore Inside ...
);
//
isLastPassed =
isBullish
? isAboveLast
: isBelowLast;
}
result = isLastPassed;
if (!result)
{
return result;
}
//
Add(
_fvg,
unActivatedFVGs //
);
//
return result;
}
};
//
struct X121SMCXSupDemOBSWorkingZone
{
//
string symbol;
ENUM_TIMEFRAMES period;
//
double upper;
double lower;
//
double zoneUpper;
double zoneLower;
//
double quarter1;
double quarter2;
double quarter3;
//
datetime from;
//
X121SMCXSupDemOBSWorkingZone()
{
Clean();
}
//
void Clean()
{
//
upper = 0;
lower = 0;
quarter1 = 0;
quarter2 = 0;
quarter3 = 0;
zoneLower = 0;
zoneUpper = 0;
//
from = NULL;
symbol = NULL;
period = NULL;
//
ZeroMemory(this);
}
//
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 DetectOveralTrend(
XOHCL &touchedBar,
ENUM_X_DIRECTION &trendDir,
int barIndex = 0 //
)
{
//
bool result = false;
//
if (barIndex < 0)
{
barIndex = 0;
}
//
trendDir = X_DIRECTION_NONE;
//
result = IsValid();
if (!result)
{
return result;
}
//
int fromBarIndex = iBarShift(
symbol,
period,
from //
);
result = IsValidIndex(fromBarIndex);
if (!result)
{
return result;
}
//
XOHCL nearestUpperTouchedBar;
XOHCL nearestLowerTouchedBar;
bool hasNearestUpperTouchedBar = false;
bool hasNearestLowerTouchedBar = false;
for (int i = barIndex; i < fromBarIndex; i++)
{
//
XOHCL iBar;
bool isInited = iBar.Init(
symbol,
period,
i //
);
//
hasNearestUpperTouchedBar = nearestUpperTouchedBar.IsValid();
if (!hasNearestUpperTouchedBar)
{
//
bool isBarTouchedUpper = iBar.high > upper;
if (isBarTouchedUpper)
{
//
nearestUpperTouchedBar = iBar;
hasNearestUpperTouchedBar = true;
}
}
//
hasNearestLowerTouchedBar = nearestLowerTouchedBar.IsValid();
if (!hasNearestLowerTouchedBar)
{
//
bool isBarTouchedLower = iBar.low < lower;
if (isBarTouchedLower)
{
//
nearestLowerTouchedBar = iBar;
hasNearestLowerTouchedBar = true;
}
}
//
if (hasNearestUpperTouchedBar &&
hasNearestLowerTouchedBar)
{
break;
}
}
//
result = hasNearestUpperTouchedBar ||
hasNearestLowerTouchedBar;
if (result)
{
//
if (hasNearestUpperTouchedBar &&
!hasNearestLowerTouchedBar)
{
//
trendDir = X_DIRECTION_BEARISH;
touchedBar = nearestUpperTouchedBar;
}
else if (!hasNearestUpperTouchedBar &&
hasNearestLowerTouchedBar)
{
//
trendDir = X_DIRECTION_BULLISH;
touchedBar = nearestLowerTouchedBar;
}
else if (hasNearestUpperTouchedBar &&
hasNearestLowerTouchedBar)
{
//
trendDir =
nearestUpperTouchedBar.time < nearestLowerTouchedBar.time
? X_DIRECTION_BULLISH
: X_DIRECTION_BEARISH;
//
if (IsBullish(trendDir))
{
touchedBar = nearestLowerTouchedBar;
}
else
{
touchedBar = nearestUpperTouchedBar;
}
}
}
//
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 X121SMCStrategyXSupDemOBSSignalConditions
{
//
// Props ...
//
string symbol;
ENUM_TIMEFRAMES period;
//
double sl;
double target;
ENUM_X_DIRECTION dir;
ENUM_X_POSITION_TYPES type;
//
// Setup Props ...
//
datetime setupTime;
datetime triggerTime;
//
double pivot;
double point;
//
// Working Area ...
//
XCSupplyZone *visionHighestSupplyZone;
XCSupplyZone *consolidationHighestSupplyZone;
//
XCDemandZone *visionLowestDemandZone;
XCDemandZone *consolidationLowestDemandZone;
//
XCFVG *insideFVG;
XCOrderBlock *insideOB;
//
XCFVG *rejectedFVG;
XCOrderBlock *rejectedOB;
//
XCSupplyZone *insideSupplyZone;
XCDemandZone *insideDemandZone;
//
XOBFVG obFVGs[];
//
X121SMCXSupDemOBSWorkingZone workingZone;
//
// Constructor ...
X121SMCStrategyXSupDemOBSSignalConditions()
{
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;
//
Clean(obFVGs);
workingZone.Clean();
//
insideOB = NULL;
insideFVG = NULL;
rejectedOB = NULL;
rejectedFVG = NULL;
insideSupplyZone = NULL;
insideDemandZone = NULL;
//
visionLowestDemandZone = NULL;
visionHighestSupplyZone = NULL;
consolidationLowestDemandZone = NULL;
consolidationHighestSupplyZone = NULL;
//
ZeroMemory(visionLowestDemandZone);
ZeroMemory(visionHighestSupplyZone);
ZeroMemory(consolidationLowestDemandZone);
ZeroMemory(consolidationHighestSupplyZone);
}
//
//
//
//
bool HasVisionHighestSupplyZone()
{
//
return visionHighestSupplyZone != NULL &&
visionHighestSupplyZone.IsValid();
}
//
bool HasConsolidationHighestSupplyZone()
{
//
return consolidationHighestSupplyZone != NULL &&
consolidationHighestSupplyZone.IsValid();
}
//
bool HasVisionLowestDemandZone()
{
//
return visionLowestDemandZone != NULL &&
visionLowestDemandZone.IsValid();
}
//
bool HasConsolidationLowestDemandZone()
{
//
return consolidationLowestDemandZone != NULL &&
consolidationLowestDemandZone.IsValid();
}
//
// X_DIRECTION_BULLISH:
// Supply Zone of Consolidation Cycle appears inside
// Supply Zone of Vision Cycle ...
//
// X_DIRECTION_BEARISH:
// Demnad Zone of Consolidation Cycle appears inside
// Demnad Zone of Vision Cycle ...
bool HasHighImpactSide(ENUM_X_DIRECTION &highImpactDir)
{
//
bool result = false;
//
highImpactDir = X_DIRECTION_NONE;
//
bool isSupplyInside = false;
bool hasVisionHighestSupplyZone = HasVisionHighestSupplyZone();
bool hasConsolidationHighestSupplyZone = HasConsolidationHighestSupplyZone();
if (hasVisionHighestSupplyZone &&
hasConsolidationHighestSupplyZone)
{
isSupplyInside = IsInside(
consolidationHighestSupplyZone,
visionHighestSupplyZone //
);
}
//
bool isDemandInside = false;
bool hasVisionLowestDemandZone = HasVisionLowestDemandZone();
bool hasConsolidationLowestDemandZone = HasConsolidationLowestDemandZone();
if (hasVisionLowestDemandZone &&
hasConsolidationLowestDemandZone)
{
//
isDemandInside = IsInside(
consolidationLowestDemandZone,
visionLowestDemandZone //
);
}
//
result = isSupplyInside ||
isDemandInside;
if (result)
{
//
highImpactDir =
isSupplyInside
? X_DIRECTION_BULLISH
: X_DIRECTION_BEARISH;
}
//
return result;
}
//
datetime ExtractNearestFromDate()
{
//
datetime result = NULL;
//
bool hasVisionLowestDemandZone = HasVisionLowestDemandZone();
bool hasVisionHighestSupplyZone = HasVisionHighestSupplyZone();
bool hasConsolidationLowestDemandZone = HasConsolidationLowestDemandZone();
bool hasConsolidationHighestSupplyZone = HasConsolidationHighestSupplyZone();
if (hasVisionLowestDemandZone)
{
//
bool canSet =
!IsValid(result)
? true
: visionLowestDemandZone.From() > result;
if (canSet)
{
result = visionLowestDemandZone.From();
}
}
if (hasVisionHighestSupplyZone)
{
//
bool canSet =
!IsValid(result)
? true
: visionHighestSupplyZone.From() > result;
if (canSet)
{
result = visionHighestSupplyZone.From();
}
}
if (hasConsolidationLowestDemandZone)
{
//
bool canSet =
!IsValid(result)
? true
: consolidationLowestDemandZone.From() > result;
if (canSet)
{
result = consolidationLowestDemandZone.From();
}
}
if (hasConsolidationHighestSupplyZone)
{
//
bool canSet =
!IsValid(result)
? true
: consolidationHighestSupplyZone.From() > result;
if (canSet)
{
result = consolidationHighestSupplyZone.From();
}
}
//
return result;
}
//
datetime ExtractFarestFromDate()
{
//
datetime result = NULL;
//
bool hasVisionLowestDemandZone = HasVisionLowestDemandZone();
bool hasVisionHighestSupplyZone = HasVisionHighestSupplyZone();
bool hasConsolidationLowestDemandZone = HasConsolidationLowestDemandZone();
bool hasConsolidationHighestSupplyZone = HasConsolidationHighestSupplyZone();
if (hasVisionLowestDemandZone)
{
//
bool canSet =
!IsValid(result)
? true
: visionLowestDemandZone.From() < result;
if (canSet)
{
result = visionLowestDemandZone.From();
}
}
if (hasVisionHighestSupplyZone)
{
//
bool canSet =
!IsValid(result)
? true
: visionHighestSupplyZone.From() < result;
if (canSet)
{
result = visionHighestSupplyZone.From();
}
}
if (hasConsolidationLowestDemandZone)
{
//
bool canSet =
!IsValid(result)
? true
: consolidationLowestDemandZone.From() < result;
if (canSet)
{
result = consolidationLowestDemandZone.From();
}
}
if (hasConsolidationHighestSupplyZone)
{
//
bool canSet =
!IsValid(result)
? true
: consolidationHighestSupplyZone.From() < result;
if (canSet)
{
result = consolidationHighestSupplyZone.From();
}
}
//
return result;
}
//
int CountOBFVGs()
{
return ArraySize(obFVGs);
}
//
bool HasOBFVGs()
{
return IsValidSize(CountOBFVGs());
}
//
// Working Zone is an Area which
// we decide to trade inside it ...
bool ExtractWorkingZone(
int barIndex = 0,
ENUM_TIMEFRAMES forPeriod = NULL //
)
{
//
bool result = false;
//
if (barIndex < 0)
{
barIndex = 0;
}
//
if (!IsValid(forPeriod))
{
forPeriod = period;
}
//
result = workingZone.IsValid();
if (result)
{
return result;
}
//
XOHCL bar;
result = bar.Init(
symbol,
forPeriod,
barIndex //
);
//
double upper = 0;
double lower = 0;
double quarter1 = 0;
double quarter2 = 0;
double quarter3 = 0;
double zoneUpper = 0;
double zoneLower = 0;
//
ENUM_X_DIRECTION highImpactDir;
bool hasHighImpactSide = HasHighImpactSide(highImpactDir);
result = hasHighImpactSide;
if (!result)
{
return result;
}
//
// Select Newest Zone From time ...
datetime from = ExtractFarestFromDate();
//
bool isSupplyHighImpacted = IsBullish(highImpactDir);
bool isDemandHighImpacted = IsBearish(highImpactDir);
//
if (isSupplyHighImpacted)
{
//
upper = visionHighestSupplyZone.Lower();
if (HasConsolidationLowestDemandZone())
{
lower = consolidationLowestDemandZone.Upper();
}
else
{
lower = visionLowestDemandZone.Upper();
}
//
zoneUpper = visionHighestSupplyZone.Upper();
if (HasConsolidationLowestDemandZone())
{
zoneLower = consolidationLowestDemandZone.Lower();
}
else
{
zoneLower = visionLowestDemandZone.Lower();
}
}
else
{
//
if (HasConsolidationHighestSupplyZone())
{
upper = consolidationHighestSupplyZone.Lower();
}
else
{
upper = visionHighestSupplyZone.Lower();
}
lower = visionLowestDemandZone.Upper();
//
if (HasConsolidationHighestSupplyZone())
{
zoneUpper = consolidationHighestSupplyZone.Upper();
}
else
{
zoneUpper = visionHighestSupplyZone.Upper();
}
zoneLower = visionLowestDemandZone.Lower();
}
//
result =
lower > 0 &&
upper > 0 &&
upper > lower &&
zoneUpper > 0 &&
zoneLower > 0 &&
zoneUpper > upper &&
zoneLower < lower;
if (!result)
{
return result;
}
//
double range = (upper - lower) / 100;
double quarter = range * 25;
//
quarter1 = upper - (1 * quarter);
quarter2 = upper - (2 * quarter);
quarter3 = upper - (3 * quarter);
//
workingZone.from = from;
workingZone.upper = upper;
workingZone.lower = lower;
workingZone.symbol = symbol;
workingZone.period = period;
workingZone.quarter1 = quarter1;
workingZone.quarter2 = quarter2;
workingZone.quarter3 = quarter3;
workingZone.zoneUpper = zoneUpper;
workingZone.zoneLower = zoneLower;
//
result = workingZone.IsValid();
//
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 DetectOveralTrend(
XOHCL &touchedBar,
ENUM_X_DIRECTION &trendDir,
int barIndex = 0 //
)
{
//
bool result = false;
//
if (barIndex < 0)
{
barIndex = 0;
}
//
trendDir = X_DIRECTION_NONE;
//
result = workingZone.IsValid();
if (!result)
{
return result;
}
//
result = workingZone.DetectOveralTrend(
touchedBar,
trendDir,
barIndex //
);
//
return result;
}
//
void UpdateTo(datetime value = NULL)
{
//
value = NormalizeTime(value);
//
bool hasVisionLowestDemandZone = HasVisionLowestDemandZone();
if (hasVisionLowestDemandZone)
{
visionLowestDemandZone.To(value);
}
bool hasVisionHighestSupplyZone = HasVisionHighestSupplyZone();
if (hasVisionHighestSupplyZone)
{
visionHighestSupplyZone.To(value);
}
bool hasConsolidationLowestDemandZone = HasConsolidationLowestDemandZone();
if (hasConsolidationLowestDemandZone)
{
consolidationLowestDemandZone.To(value);
}
bool hasConsolidationHighestSupplyZone = HasConsolidationHighestSupplyZone();
if (hasConsolidationHighestSupplyZone)
{
consolidationHighestSupplyZone.To(value);
}
//
bool hasInsideOB = insideOB != NULL &&
insideOB.IsValid();
if (hasInsideOB)
{
insideOB.To(value);
}
//
bool hasInsideFVG = insideFVG != NULL &&
insideFVG.IsValid();
if (hasInsideFVG)
{
insideFVG.To(value);
}
//
bool hasOBFVGs = HasOBFVGs();
int obFVGsCount = CountOBFVGs();
if (hasOBFVGs)
{
//
for (int i = 0; i < obFVGsCount; i++)
{
//
obFVGs[i].ob.To(value);
obFVGs[i].fvg.To(value);
//
bool hasUnActivatedOBs = obFVGs[i].HasUnActivatedOBs();
int unActivatedOBsCount = obFVGs[i].CountUnActivatedOBs();
if (hasUnActivatedOBs)
{
//
for (int j = 0; j < unActivatedOBsCount; j++)
{
obFVGs[i].unActivatedOBs[j].To(value);
}
}
//
bool hasUnActivatedFVGs = obFVGs[i].HasUnActivatedFVGs();
int unActivatedFVGsCount = obFVGs[i].CountUnActivatedFVGs();
if (hasUnActivatedFVGs)
{
//
for (int j = 0; j < unActivatedFVGsCount; j++)
{
obFVGs[i].unActivatedFVGs[j].To(value);
}
}
}
}
}
//
};
//
// Signaller Data Sources ...
X121SMCStrategyXSupDemOBSSignalConditions mX121SMCXSupDemOBSConditions;
X121SMCStrategyXSupDemOBSSignalConditions mX121SMCXSupDemOBSConditionsCollection[];
CArrayObj mX121SMCXSupDemOBSObjects;
CArrayObj mX121SMCXSupDemOBSWorkingZoneObjects;
//
// Extension Functions ...
//
// Detect Setup Conditions ...
bool DetectX121SMCXSupDemOBSSignalSetup(
string _symbol,
ENUM_TIMEFRAMES _period,
//
X121SMCStrategyXSupDemOBSSignalConditions &conditions,
//
XC121SMCCycleHelper *decisionCycleHelper,
XC121SMCCycleHelper *analyseCycleHelper,
XC121SMCCycleHelper *consolidationCycleHelper,
XC121SMCCycleHelper *visionCycleHelper
//
)
{
//
bool result = false;
//
// Validate Cycle Helpers ...
result =
//
visionCycleHelper != NULL &&
analyseCycleHelper != NULL &&
decisionCycleHelper != NULL &&
consolidationCycleHelper != NULL
//
;
if (!result)
{
return result;
}
//
bool isBullish = false;
bool isBearish = false;
//
int zIndex = 0;
int cIndex = zIndex + 1;
int pIndex = cIndex + 1;
int ppIndex = pIndex + 1;
//
int loopback = 10;
//
string symbol = _symbol;
ENUM_TIMEFRAMES period = _period;
//
conditions.symbol = symbol;
conditions.period = period;
//
double ask = GetAsk(symbol);
double bid = GetBid(symbol);
datetime cTime = TimeCurrent();
double points = GetPoints(symbol);
//
// Cycles Conditions ...
//
// Decision ...
ENUM_XPOI_EVENTS decisionPoiEvents[];
ENUM_X_CYCLE_EVENTS decisionCycleEvents[];
X121SMCCycleConditions decisionConditions;
result = decisionCycleHelper.GetConditions(
decisionCycleEvents,
decisionPoiEvents,
decisionConditions,
zIndex,
loopback //
);
if (!result)
{
return result;
}
//
// Analyse ...
ENUM_XPOI_EVENTS analysePoiEvents[];
ENUM_X_CYCLE_EVENTS analyseCycleEvents[];
X121SMCCycleConditions analyseConditions;
result = analyseCycleHelper.GetConditions(
analyseCycleEvents,
analysePoiEvents,
analyseConditions,
zIndex,
loopback //
);
if (!result)
{
return result;
}
//
// Consolidation ...
ENUM_XPOI_EVENTS consolidationPoiEvents[];
ENUM_X_CYCLE_EVENTS consolidationCycleEvents[];
X121SMCCycleConditions consolidationConditions;
result = consolidationCycleHelper.GetConditions(
consolidationCycleEvents,
consolidationPoiEvents,
consolidationConditions,
zIndex,
loopback //
);
if (!result)
{
return result;
}
//
// Vision ...
ENUM_XPOI_EVENTS visionPoiEvents[];
ENUM_X_CYCLE_EVENTS visionCycleEvents[];
X121SMCCycleConditions visionConditions;
result = visionCycleHelper.GetConditions(
visionCycleEvents,
visionPoiEvents,
visionConditions,
zIndex,
loopback //
);
if (!result)
{
return result;
}
//
// Cycles POI States ...
XPOIState decisionState = decisionConditions.state;
XPOIState analyseState = analyseConditions.state;
XPOIState consolidationState = consolidationConditions.state;
XPOIState visionState = visionConditions.state;
//
// Cycle X121Conditions ...
X121Conditions decisionXConditions = decisionConditions.x121Conditions;
X121Conditions analyseXConditions = analyseConditions.x121Conditions;
X121Conditions consolidationXConditions = consolidationConditions.x121Conditions;
X121Conditions visionXConditions = visionConditions.x121Conditions;
//
// Setup Conditions ...
//
XOHCL decisionZBar;
XOHCL decisionCBar;
XOHCL decisionPBar;
double decisionCBarBullishZoneChechValue = 0;
double decisionCBarBearishZoneChechValue = 0;
//
result = decisionZBar.Init(
decisionState.symbol,
decisionState.period,
0 //
);
if (!result)
{
//
Clean(visionPoiEvents);
Clean(analysePoiEvents);
Clean(decisionPoiEvents);
Clean(visionCycleEvents);
Clean(analyseCycleEvents);
Clean(decisionCycleEvents);
Clean(consolidationPoiEvents);
Clean(consolidationCycleEvents);
//
visionState.Clean();
analyseState.Clean();
decisionZBar.Clean();
decisionCBar.Clean();
decisionPBar.Clean();
decisionState.Clean();
visionConditions.Clean();
analyseConditions.Clean();
visionXConditions.Clean();
consolidationState.Clean();
decisionConditions.Clean();
analyseXConditions.Clean();
decisionXConditions.Clean();
consolidationConditions.Clean();
consolidationXConditions.Clean();
//
return result;
}
//
result = decisionZBar
.GetPreviousBar(decisionCBar);
if (!result)
{
//
Clean(visionPoiEvents);
Clean(analysePoiEvents);
Clean(decisionPoiEvents);
Clean(visionCycleEvents);
Clean(analyseCycleEvents);
Clean(decisionCycleEvents);
Clean(consolidationPoiEvents);
Clean(consolidationCycleEvents);
//
visionState.Clean();
analyseState.Clean();
decisionZBar.Clean();
decisionCBar.Clean();
decisionPBar.Clean();
decisionState.Clean();
visionConditions.Clean();
analyseConditions.Clean();
visionXConditions.Clean();
consolidationState.Clean();
decisionConditions.Clean();
analyseXConditions.Clean();
decisionXConditions.Clean();
consolidationConditions.Clean();
consolidationXConditions.Clean();
//
return result;
}
//
result = decisionCBar
.GetPreviousBar(decisionPBar);
if (!result)
{
//
Clean(visionPoiEvents);
Clean(analysePoiEvents);
Clean(decisionPoiEvents);
Clean(visionCycleEvents);
Clean(analyseCycleEvents);
Clean(decisionCycleEvents);
Clean(consolidationPoiEvents);
Clean(consolidationCycleEvents);
//
visionState.Clean();
analyseState.Clean();
decisionZBar.Clean();
decisionCBar.Clean();
decisionPBar.Clean();
decisionState.Clean();
visionConditions.Clean();
analyseConditions.Clean();
visionXConditions.Clean();
consolidationState.Clean();
decisionConditions.Clean();
analyseXConditions.Clean();
decisionXConditions.Clean();
consolidationConditions.Clean();
consolidationXConditions.Clean();
//
return result;
}
//
decisionCBarBullishZoneChechValue = decisionCBar
.GetZoneCheckValue(X_DIRECTION_BULLISH);
decisionCBarBearishZoneChechValue = decisionCBar
.GetZoneCheckValue(X_DIRECTION_BEARISH);
//
conditions.UpdateTo();
//
// 1- Detect Valid Working Area ...
//
bool hasVisionHighestSupplyZone = conditions.HasVisionHighestSupplyZone();
bool hasConsolidationHighestSupplyZone = conditions.HasConsolidationHighestSupplyZone();
//
bool hasVisionLowestDemandZone = conditions.HasVisionLowestDemandZone();
bool hasConsolidationLowestDemandZone = conditions.HasConsolidationLowestDemandZone();
//
bool hasWorkingZone = conditions.workingZone.IsValid();
//
bool isDestroyed = false;
ENUM_X_DIRECTION destroyedDir;
//
XOHCL trendStartBar;
ENUM_X_DIRECTION trendDir;
bool hasTrend = false;
bool hasBullishTrend = false;
bool hasBearishTrend = false;
//
if (!hasVisionHighestSupplyZone)
{
//
int hasZones = visionState.HasSupplyZones();
int zonesCount = visionState.HasSupplyZones();
//
if (hasZones)
{
//
int idx = GetHighest(visionState.supplyZones);
hasVisionHighestSupplyZone = IsValidIndex(idx);
if (hasVisionHighestSupplyZone)
{
//
// Validate Zone ...
XCSupplyZone *zone = visionState.supplyZones[idx];
bool isBelow = IsBelow(
decisionCBarBearishZoneChechValue,
zone //
);
if (isBelow)
{
conditions.visionHighestSupplyZone = zone;
}
}
}
//
hasVisionHighestSupplyZone = conditions.HasVisionHighestSupplyZone();
}
//
if (!hasVisionLowestDemandZone)
{
//
int hasZones = visionState.HasDemandZones();
int zonesCount = visionState.HasDemandZones();
//
if (hasZones)
{
//
int idx = GetLowest(visionState.demandZones);
hasVisionLowestDemandZone = IsValidIndex(idx);
if (hasVisionLowestDemandZone)
{
//
// Validate Zone ...
XCDemandZone *zone = visionState.demandZones[idx];
bool isAbove = IsAbove(
decisionCBarBullishZoneChechValue,
zone //
);
if (isAbove)
{
conditions.visionLowestDemandZone = zone;
}
}
}
//
hasVisionLowestDemandZone = conditions.HasVisionLowestDemandZone();
}
//
if (!hasConsolidationHighestSupplyZone)
{
//
int hasZones = consolidationState.HasSupplyZones();
int zonesCount = consolidationState.HasSupplyZones();
//
if (hasZones)
{
//
int idx = GetHighest(consolidationState.supplyZones);
hasConsolidationHighestSupplyZone = IsValidIndex(idx);
if (hasConsolidationHighestSupplyZone)
{
//
// Validate Zone ...
XCSupplyZone *zone = consolidationState.supplyZones[idx];
bool isBelow = IsBelow(
decisionCBarBearishZoneChechValue,
zone //
);
if (isBelow)
{
//
if (conditions.workingZone.IsValid())
{
//
result = false;
conditions.Clean();
RemoveX121SMCXSupDemOBSDraws();
return result;
}
//
conditions.consolidationHighestSupplyZone = zone;
}
}
}
//
hasConsolidationHighestSupplyZone = conditions.HasConsolidationHighestSupplyZone();
}
//
if (!hasConsolidationLowestDemandZone)
{
//
int hasZones = consolidationState.HasDemandZones();
int zonesCount = consolidationState.HasDemandZones();
//
if (hasZones)
{
//
int idx = GetLowest(consolidationState.demandZones);
hasConsolidationLowestDemandZone = IsValidIndex(idx);
if (hasConsolidationLowestDemandZone)
{
//
// Validate Zone ...
XCDemandZone *zone = consolidationState.demandZones[idx];
bool isAbove = IsAbove(
decisionCBarBullishZoneChechValue,
zone //
);
if (isAbove)
{
//
if (conditions.workingZone.IsValid())
{
//
result = false;
conditions.Clean();
RemoveX121SMCXSupDemOBSDraws();
return result;
}
//
conditions.consolidationLowestDemandZone = zone;
}
}
}
//
hasConsolidationLowestDemandZone = conditions.HasConsolidationLowestDemandZone();
}
//
// 2- Detect Working Zone ...
if (!hasWorkingZone)
{
hasWorkingZone = conditions.ExtractWorkingZone();
}
//
// Here we Can Detect Price Inside SupDem Zones ...
//
bool isPriceInsideSupplyZone = false;
bool isPriceInsideDemandZone = false;
bool isPriceInsideVisionSupplyZone = false;
bool isPriceInsideVisionDemandZone = false;
bool isPriceInsideConsolidationSupplyZone = false;
bool isPriceInsideConsolidationDemandZone = false;
if (hasVisionLowestDemandZone)
{
//
double iUpper = conditions.visionLowestDemandZone.Upper();
double iLower = conditions.visionLowestDemandZone.Lower();
//
isPriceInsideVisionDemandZone =
//
decisionZBar.high < iUpper &&
decisionCBar.high < iUpper &&
//
decisionZBar.low > iLower &&
decisionCBar.low > iLower
//
;
}
if (hasVisionHighestSupplyZone)
{
//
double iUpper = conditions.visionHighestSupplyZone.Upper();
double iLower = conditions.visionHighestSupplyZone.Lower();
//
isPriceInsideVisionSupplyZone =
//
decisionZBar.high < iUpper &&
decisionCBar.high < iUpper &&
//
decisionZBar.low > iLower &&
decisionCBar.low > iLower
//
;
}
if (hasConsolidationLowestDemandZone)
{
//
double iUpper = conditions.consolidationLowestDemandZone.Upper();
double iLower = conditions.consolidationLowestDemandZone.Lower();
//
isPriceInsideConsolidationDemandZone =
//
decisionZBar.high < iUpper &&
decisionCBar.high < iUpper &&
//
decisionZBar.low > iLower &&
decisionCBar.low > iLower
//
;
}
if (hasConsolidationHighestSupplyZone)
{
//
double iUpper = conditions.consolidationHighestSupplyZone.Upper();
double iLower = conditions.consolidationHighestSupplyZone.Lower();
//
isPriceInsideConsolidationSupplyZone =
//
decisionZBar.high < iUpper &&
decisionCBar.high < iUpper &&
//
decisionZBar.low > iLower &&
decisionCBar.low > iLower
//
;
}
//
isPriceInsideSupplyZone = isPriceInsideVisionSupplyZone ||
isPriceInsideConsolidationSupplyZone;
if (isPriceInsideSupplyZone)
{
//
if (isPriceInsideVisionSupplyZone)
{
conditions.insideSupplyZone = conditions.visionHighestSupplyZone;
}
else if (isPriceInsideConsolidationSupplyZone)
{
conditions.insideSupplyZone = conditions.consolidationHighestSupplyZone;
}
}
//
isPriceInsideDemandZone = isPriceInsideVisionDemandZone ||
isPriceInsideConsolidationDemandZone;
if (isPriceInsideDemandZone)
{
//
if (isPriceInsideVisionDemandZone)
{
conditions.insideDemandZone = conditions.visionLowestDemandZone;
}
else if (isPriceInsideConsolidationDemandZone)
{
conditions.insideDemandZone = conditions.consolidationLowestDemandZone;
}
}
//
// Check Working Zone Destroy ...
isDestroyed = conditions.IsWorkingZoneDestroyed(
destroyedDir, // Direction ...
0, // Bar Index ...
decisionState.period // Period ...
);
if (isDestroyed)
{
//
Clean(visionPoiEvents);
Clean(analysePoiEvents);
Clean(decisionPoiEvents);
Clean(visionCycleEvents);
Clean(analyseCycleEvents);
Clean(decisionCycleEvents);
Clean(consolidationPoiEvents);
Clean(consolidationCycleEvents);
//
visionState.Clean();
analyseState.Clean();
decisionZBar.Clean();
decisionCBar.Clean();
decisionPBar.Clean();
decisionState.Clean();
visionConditions.Clean();
analyseConditions.Clean();
visionXConditions.Clean();
consolidationState.Clean();
decisionConditions.Clean();
analyseXConditions.Clean();
decisionXConditions.Clean();
consolidationConditions.Clean();
consolidationXConditions.Clean();
//
result = false;
conditions.Clean();
RemoveX121SMCXSupDemOBSDraws();
return result;
}
//
// 2- Detect Market Trend Based On Nearest Zone Hunting ...
hasTrend = conditions.DetectOveralTrend(
trendStartBar,
trendDir,
0 //
);
hasBullishTrend = IsBullish(trendDir);
hasBearishTrend = IsBearish(trendDir);
//
result = hasTrend;
if (!result)
{
//
Clean(visionPoiEvents);
Clean(analysePoiEvents);
Clean(decisionPoiEvents);
Clean(visionCycleEvents);
Clean(analyseCycleEvents);
Clean(decisionCycleEvents);
Clean(consolidationPoiEvents);
Clean(consolidationCycleEvents);
//
visionState.Clean();
analyseState.Clean();
decisionZBar.Clean();
decisionCBar.Clean();
decisionPBar.Clean();
decisionState.Clean();
visionConditions.Clean();
analyseConditions.Clean();
visionXConditions.Clean();
consolidationState.Clean();
decisionConditions.Clean();
analyseXConditions.Clean();
decisionXConditions.Clean();
consolidationConditions.Clean();
consolidationXConditions.Clean();
//
RemoveX121SMCXSupDemOBSDraws();
//
return result;
}
//
// Re Draw Working Zone ...
RemoveX121SMCXSupDemOBSWorkingZoneDraws();
DrawX121SMCXSupDemOBSWorkingZone(
conditions,
visionCycleHelper.mPOIDrawer //
);
//
// 3- Checking Price Inside Valid Quarters Based on Trend ...
//
// in Bullish Trend:
// -----------------------------
// - if Price Under Lower: HIGH;
// - if Price Under Quarter 3 and Above Lower: REGULAR;
// - if Price Under Quarter 2 and Above Quarter 3: LOW;
// - if Price Above Quarter 2: NONE;
//
// in Bearish Trend:
// -----------------------------
// - if Price Above Upper: HIGH;
// - if Price Above Quarter 1 and Below Upper: REGULAR;
// - if Price Above Quarter 2 and Below Quarter 1: LOW;
// - if Price Below Quarter 2: NONE;
//
ENUM_X121SMC_XSUPDEMOBS_PRIORITY bullishPriority = X121SMC_XSUPDEMOBS_PRIORITY_NONE;
ENUM_X121SMC_XSUPDEMOBS_PRIORITY bearishPriority = X121SMC_XSUPDEMOBS_PRIORITY_NONE;
//
bool isPriceAboveUpper =
//
decisionZBar.high < conditions.workingZone.zoneUpper &&
decisionCBar.high < conditions.workingZone.zoneUpper &&
//
decisionZBar.low > conditions.workingZone.upper &&
decisionCBar.low > conditions.workingZone.upper
//
;
if (isPriceAboveUpper)
{
//
bullishPriority = X121SMC_XSUPDEMOBS_PRIORITY_NONE;
bearishPriority = X121SMC_XSUPDEMOBS_PRIORITY_HIGH;
}
//
bool isPriceInQuarterOne =
//
decisionZBar.high < conditions.workingZone.upper &&
decisionCBar.high < conditions.workingZone.upper &&
//
decisionZBar.low > conditions.workingZone.quarter1 &&
decisionCBar.low > conditions.workingZone.quarter1
//
;
if (isPriceInQuarterOne)
{
//
bullishPriority = X121SMC_XSUPDEMOBS_PRIORITY_WEAK;
bearishPriority = X121SMC_XSUPDEMOBS_PRIORITY_REGULAR;
}
//
bool isPriceInQuarterTwo =
//
decisionZBar.high < conditions.workingZone.quarter1 &&
decisionCBar.high < conditions.workingZone.quarter1 &&
//
decisionZBar.low > conditions.workingZone.quarter2 &&
decisionCBar.low > conditions.workingZone.quarter2
//
;
if (isPriceInQuarterTwo)
{
//
bullishPriority = X121SMC_XSUPDEMOBS_PRIORITY_NONE;
bearishPriority = X121SMC_XSUPDEMOBS_PRIORITY_LOW;
}
//
bool isPriceInQuarterThree =
//
decisionZBar.high < conditions.workingZone.quarter2 &&
decisionCBar.high < conditions.workingZone.quarter2 &&
//
decisionZBar.low > conditions.workingZone.quarter3 &&
decisionCBar.low > conditions.workingZone.quarter3
//
;
if (isPriceInQuarterThree)
{
//
bullishPriority = X121SMC_XSUPDEMOBS_PRIORITY_LOW;
bearishPriority = X121SMC_XSUPDEMOBS_PRIORITY_NONE;
}
//
bool isPriceInQuarterFour =
//
decisionZBar.high < conditions.workingZone.quarter3 &&
decisionCBar.high < conditions.workingZone.quarter3 &&
//
decisionZBar.low > conditions.workingZone.lower &&
decisionCBar.low > conditions.workingZone.lower
//
;
if (isPriceInQuarterFour)
{
//
bullishPriority = X121SMC_XSUPDEMOBS_PRIORITY_REGULAR;
bearishPriority = X121SMC_XSUPDEMOBS_PRIORITY_WEAK;
}
//
bool isPriceBelowLower =
//
decisionZBar.high < conditions.workingZone.lower &&
decisionCBar.high < conditions.workingZone.lower &&
//
decisionZBar.low > conditions.workingZone.zoneLower &&
decisionCBar.low > conditions.workingZone.zoneLower
//
;
if (isPriceBelowLower)
{
//
bullishPriority = X121SMC_XSUPDEMOBS_PRIORITY_HIGH;
bearishPriority = X121SMC_XSUPDEMOBS_PRIORITY_NONE;
}
//
bool lookingForLong = bullishPriority != X121SMC_XSUPDEMOBS_PRIORITY_NONE;
bool lookingForShort = bearishPriority != X121SMC_XSUPDEMOBS_PRIORITY_NONE;
//
result = lookingForLong ||
lookingForShort;
if (!result)
{
//
Clean(visionPoiEvents);
Clean(analysePoiEvents);
Clean(visionCycleEvents);
Clean(decisionPoiEvents);
Clean(analyseCycleEvents);
Clean(decisionCycleEvents);
Clean(consolidationPoiEvents);
Clean(consolidationCycleEvents);
//
visionState.Clean();
analyseState.Clean();
decisionZBar.Clean();
decisionCBar.Clean();
decisionPBar.Clean();
decisionState.Clean();
visionConditions.Clean();
analyseConditions.Clean();
visionXConditions.Clean();
consolidationState.Clean();
decisionConditions.Clean();
analyseXConditions.Clean();
decisionXConditions.Clean();
consolidationConditions.Clean();
consolidationXConditions.Clean();
//
RemoveX121SMCXSupDemOBSDraws();
//
return result;
}
//
// Detect Order Blocks in Direction of Trend ...
XCOrderBlock *obs[];
Copy(
consolidationState.bullishOrderBlocks,
obs //
);
Copy(
consolidationState.bearishOrderBlocks,
obs //
);
//
// Validate OB FVG ...
XCFVG *fvgs[];
Copy(
analyseState.bullishFairValueGaps,
fvgs //
);
Copy(
analyseState.bearishFairValueGaps,
fvgs //
);
//
int obsCount = ArraySize(obs);
bool hasOBs = IsValidSize(obsCount);
//
int fvgsCount = ArraySize(fvgs);
bool hasFVGs = IsValidSize(fvgsCount);
//
bool hasOBFVGs = conditions.HasOBFVGs();
int obFVGsCount = conditions.CountOBFVGs();
//
if (hasOBs &&
hasFVGs &&
!hasOBFVGs)
{
//
for (int i = 0; i < obsCount; i++)
{
//
XCOrderBlock *iOB = obs[i];
//
// Check Ob Index inside OB FVGS ...
bool isOBFVGExists = false;
hasOBFVGs = conditions.HasOBFVGs();
obFVGsCount = conditions.CountOBFVGs();
if (hasOBFVGs)
{
//
for (int j = 0; j < obFVGsCount; j++)
{
//
bool isSame = IsSame(
conditions.obFVGs[j].ob,
iOB //
);
//
if (isSame)
{
//
isOBFVGExists = true;
break;
}
}
}
if (isOBFVGExists)
{
continue;
}
//
for (int j = 0; j < fvgsCount; j++)
{
//
XCFVG *jFVG = fvgs[j];
//
ENUM_TIMEFRAMES jPeriod = jFVG.GetPeriod();
if (jPeriod != PERIOD_M15)
{
Print(ToString(jPeriod));
}
//
XOBFVG iOBFVG;
//
iOBFVG.time = cTime;
iOBFVG.symbol = iOB.GetSymbol();
iOBFVG.period = iOB.GetPeriod();
//
iOBFVG.ob = iOB;
iOBFVG.fvg = jFVG;
//
bool isValidOBFVG = iOBFVG.IsValid();
if (isValidOBFVG)
{
//
AddRef(
iOBFVG,
conditions.obFVGs //
);
//
iOBFVG.Clean();
//
break;
}
//
iOBFVG.Clean();
}
}
//
hasOBFVGs = conditions.HasOBFVGs();
obFVGsCount = conditions.CountOBFVGs();
}
//
// Now We Have to Check OBFVGs ...
result = hasOBFVGs;
if (!result)
{
//
Clean(obs);
Clean(fvgs);
//
Clean(visionPoiEvents);
Clean(analysePoiEvents);
Clean(decisionPoiEvents);
Clean(visionCycleEvents);
Clean(analyseCycleEvents);
Clean(decisionCycleEvents);
Clean(consolidationPoiEvents);
Clean(consolidationCycleEvents);
//
visionState.Clean();
analyseState.Clean();
decisionZBar.Clean();
decisionCBar.Clean();
decisionPBar.Clean();
decisionState.Clean();
visionConditions.Clean();
analyseConditions.Clean();
visionXConditions.Clean();
consolidationState.Clean();
decisionConditions.Clean();
analyseXConditions.Clean();
decisionXConditions.Clean();
consolidationConditions.Clean();
consolidationXConditions.Clean();
//
RemoveX121SMCXSupDemOBSDraws();
//
return result;
}
//
// Detect Un Activated POI(s) ...
// including:
// - Order Blocks;
// - Fair Value Gaps;
//
bool hasUnActivatedOBs = false;
bool hasUnActivatedFVGs = false;
for (int i = 0; i < obFVGsCount; i++)
{
//
bool iHasUnActivatedOBs = conditions.obFVGs[i].HasUnActivatedOBs();
bool iHasUnActivatedFVGs = conditions.obFVGs[i].HasUnActivatedFVGs();
//
if (hasOBs)
{
//
for (int j = 0; j < obsCount; j++)
{
conditions.obFVGs[i].AddUnActivatedOB(
obs[j],
decisionZBar //
);
}
//
iHasUnActivatedOBs = conditions.obFVGs[i].HasUnActivatedOBs();
}
//
if (hasFVGs)
{
//
for (int j = 0; j < fvgsCount; j++)
{
conditions.obFVGs[i].AddUnActivatedFVG(
fvgs[j],
decisionZBar //
);
}
//
iHasUnActivatedFVGs = conditions.obFVGs[i].HasUnActivatedFVGs();
}
//
if (iHasUnActivatedOBs &&
!hasUnActivatedOBs)
{
hasUnActivatedOBs = iHasUnActivatedOBs;
}
//
if (iHasUnActivatedFVGs &&
!hasUnActivatedFVGs)
{
hasUnActivatedFVGs = iHasUnActivatedFVGs;
}
}
//
result =
(isPriceInsideSupplyZone ||
isPriceInsideDemandZone)
? true
: (hasUnActivatedOBs ||
hasUnActivatedFVGs);
if (!result)
{
//
Clean(obs);
Clean(fvgs);
//
Clean(visionPoiEvents);
Clean(analysePoiEvents);
Clean(visionCycleEvents);
Clean(decisionPoiEvents);
Clean(analyseCycleEvents);
Clean(decisionCycleEvents);
Clean(consolidationPoiEvents);
Clean(consolidationCycleEvents);
//
visionState.Clean();
analyseState.Clean();
decisionZBar.Clean();
decisionCBar.Clean();
decisionPBar.Clean();
decisionState.Clean();
visionConditions.Clean();
analyseConditions.Clean();
visionXConditions.Clean();
consolidationState.Clean();
decisionConditions.Clean();
analyseXConditions.Clean();
decisionXConditions.Clean();
consolidationConditions.Clean();
consolidationXConditions.Clean();
//
RemoveX121SMCXSupDemOBSDraws();
//
return result;
}
//
// Now We Have to Wait for Price Inside Box ...
//
XOHCL swingBar;
XOHCL rejectBar;
XOHCL breakerBar;
XOHCL momentumBar;
bool isPriceRejected = false;
XCFVG *insideFVG = conditions.insideFVG;
XCFVG *rejectedFVG = conditions.rejectedFVG;
XCOrderBlock *insideOB = conditions.insideOB;
XCOrderBlock *rejectedOB = conditions.rejectedOB;
XCSupplyZone *insideSupplyZone = conditions.insideSupplyZone;
XCDemandZone *insideDemandZone = conditions.insideDemandZone;
//
bool hasInsideOB = insideOB != NULL &&
insideOB.IsValid();
bool hasInsideFVG = insideFVG != NULL &&
insideFVG.IsValid();
bool hasInsideZone = hasInsideOB ||
hasInsideFVG;
bool hasRejectedOB = rejectedOB != NULL &&
rejectedOB.IsValid();
bool hasRejectedFVG = rejectedFVG != NULL &&
rejectedFVG.IsValid();
bool hasRejectedZone = hasRejectedOB ||
hasRejectedFVG;
bool hasInsideSupplyZone = insideSupplyZone != NULL &&
insideSupplyZone.IsValid();
bool hasInsideDemandZone = insideDemandZone != NULL &&
insideDemandZone.IsValid();
bool hasInsideSupDemZone = hasInsideSupplyZone ||
hasInsideDemandZone;
if (!hasInsideZone)
{
//
for (int i = 0; i < obFVGsCount; i++)
{
//
bool iOBFVGHasUnActivatedOBs = conditions.obFVGs[i].HasUnActivatedOBs();
int iOBFVGUnActivatedOBsCount = conditions.obFVGs[i].CountUnActivatedOBs();
//
bool iOBFVGHasUnActivatedFVGs = conditions.obFVGs[i].HasUnActivatedFVGs();
int iOBFVGUnActivatedFVGsCount = conditions.obFVGs[i].CountUnActivatedFVGs();
//
// Detect Inside Zones ...
//
if (!hasInsideOB &&
iOBFVGHasUnActivatedOBs)
{
//
int idx = -1;
for (int j = 0; j < iOBFVGUnActivatedOBsCount; j++)
{
//
ENUM_X_DIRECTION iForDir = conditions.obFVGs[i].unActivatedOBs[j].GetDirection();
bool isIBullish = IsBullish(iForDir);
//
bool isInsideFromUpper = IsInside(
decisionZBar.low,
conditions.obFVGs[i].unActivatedOBs[j] //
);
bool isInsideFromLower = IsInside(
decisionZBar.high,
conditions.obFVGs[i].unActivatedOBs[j] //
);
//
bool isInside =
isBullish
? isInsideFromUpper
: isInsideFromLower;
if (isInside)
{
//
idx = j;
insideOB = conditions.obFVGs[i].unActivatedOBs[j];
conditions.insideOB = insideOB;
break;
}
}
//
if (IsValidIndex(idx))
{
//
ArrayRemove(
conditions.obFVGs[i].unActivatedOBs,
idx,
1 //
);
}
}
//
if (insideOB == NULL &&
!hasInsideFVG &&
iOBFVGHasUnActivatedFVGs)
{
//
int idx = -1;
for (int j = 0; j < iOBFVGUnActivatedFVGsCount; j++)
{
//
ENUM_X_DIRECTION iForDir = conditions.obFVGs[i].unActivatedFVGs[j].GetDirection();
bool isIBullish = IsBullish(iForDir);
//
bool isInsideFromUpper = IsInside(
decisionZBar.low,
conditions.obFVGs[i].unActivatedFVGs[j] //
);
bool isInsideFromLower = IsInside(
decisionZBar.high,
conditions.obFVGs[i].unActivatedFVGs[j] //
);
//
bool isInside =
isBullish
? isInsideFromUpper
: isInsideFromLower;
if (isInside)
{
//
idx = j;
insideFVG = conditions.obFVGs[i].unActivatedFVGs[j];
conditions.insideFVG = insideFVG;
break;
}
}
//
if (IsValidIndex(idx))
{
//
ArrayRemove(
conditions.obFVGs[i].unActivatedFVGs,
idx,
1 //
);
}
}
}
//
hasInsideOB = insideOB != NULL &&
insideOB.IsValid();
hasInsideFVG = insideFVG != NULL &&
insideFVG.IsValid();
hasInsideZone = hasInsideOB ||
hasInsideFVG;
//
// Here Detect Inside or Rejected Zones inside Supply and Demand Zones ...
// For Using them for Positions ...
if (!hasInsideZone &&
hasInsideSupDemZone)
{
//
ENUM_X_DIRECTION forDir =
hasInsideSupplyZone
? X_DIRECTION_BEARISH
: X_DIRECTION_BULLISH;
//
bool isLookingForBullish = IsBullish(forDir);
//
XCFVG *fvgs[];
XCOrderBlock *obs[];
int obsCount = 0;
int fvgsCount = 0;
bool hasOBs = false;
bool hasFVGs = false;
//
if (isLookingForBullish)
{
//
obsCount = ExtractUnActivatedZones(
analyseState.bullishOrderBlocks,
obs //
);
hasOBs = IsValidSize(obsCount);
//
fvgsCount = ExtractUnActivatedZones(
analyseState.bullishFairValueGaps,
fvgs //
);
hasFVGs = IsValidSize(fvgsCount);
}
else
{
//
obsCount = ExtractUnActivatedZones(
analyseState.bearishOrderBlocks,
obs //
);
hasOBs = IsValidSize(obsCount);
//
fvgsCount = ExtractUnActivatedZones(
analyseState.bearishFairValueGaps,
fvgs //
);
hasFVGs = IsValidSize(fvgsCount);
}
//
OrderedSortZones(obs);
OrderedSortZones(fvgs);
//
obsCount = ArraySize(obs);
fvgsCount = ArraySize(fvgs);
//
hasOBs = IsValidSize(obsCount);
hasFVGs = IsValidSize(fvgsCount);
if (hasOBs ||
hasFVGs)
{
//
if (hasOBs)
{
//
for (int i = 0; i < obsCount; i++)
{
//
ENUM_X_DIRECTION iForDir = obs[i].GetDirection();
bool isIBullish = IsBullish(iForDir);
//
isPriceRejected = IsReject(
iForDir,
decisionZBar,
obs[i],
decisionState,
swingBar,
rejectBar,
breakerBar,
momentumBar,
false //
);
if (isPriceRejected)
{
//
rejectedOB = obs[i];
conditions.rejectedOB = rejectedOB;
}
//
bool isInsideFromUpper = IsInside(
decisionZBar.low,
obs[i] //
);
bool isInsideFromLower = IsInside(
decisionZBar.high,
obs[i] //
);
//
bool isInside =
isBullish
? isInsideFromUpper
: isInsideFromLower;
if (isInside)
{
//
insideOB = obs[i];
conditions.insideOB = obs[i];
break;
}
}
}
//
hasInsideOB = insideOB != NULL &&
insideOB.IsValid();
//
hasRejectedOB = rejectedOB != NULL &&
rejectedOB.IsValid();
//
if (hasFVGs &&
!hasInsideOB &&
!hasRejectedOB)
{
//
for (int i = 0; i < fvgsCount; i++)
{
//
ENUM_X_DIRECTION iForDir = fvgs[i].GetDirection();
bool isIBullish = IsBullish(iForDir);
//
isPriceRejected = IsReject(
iForDir,
decisionZBar,
fvgs[i],
decisionState,
swingBar,
rejectBar,
breakerBar,
momentumBar,
false //
);
if (isPriceRejected)
{
//
rejectedFVG = fvgs[i];
conditions.rejectedFVG = rejectedFVG;
}
//
bool isInsideFromUpper = IsInside(
decisionZBar.low,
fvgs[i] //
);
bool isInsideFromLower = IsInside(
decisionZBar.high,
fvgs[i] //
);
//
bool isInside =
isBullish
? isInsideFromUpper
: isInsideFromLower;
if (isInside)
{
//
insideFVG = fvgs[i];
conditions.insideFVG = fvgs[i];
break;
}
}
}
}
//
Clean(obs);
Clean(fvgs);
}
//
hasInsideOB = insideOB != NULL &&
insideOB.IsValid();
hasInsideFVG = insideFVG != NULL &&
insideFVG.IsValid();
hasInsideZone = hasInsideOB ||
hasInsideFVG;
//
hasRejectedOB = rejectedOB != NULL &&
rejectedOB.IsValid();
hasRejectedFVG = rejectedFVG != NULL &&
rejectedFVG.IsValid();
hasRejectedZone = hasRejectedOB ||
hasRejectedFVG;
}
//
if (!hasInsideZone &&
!hasRejectedZone &&
hasInsideSupDemZone)
{
//
// Check Supply and Demand Zone Rejection ...
if (hasInsideSupplyZone)
{
//
isPriceRejected = IsReject(
X_DIRECTION_BEARISH,
decisionZBar,
insideSupplyZone,
decisionState,
swingBar,
rejectBar,
breakerBar,
momentumBar,
false //
);
}
else if (hasInsideDemandZone)
{
//
isPriceRejected = IsReject(
X_DIRECTION_BULLISH,
decisionZBar,
insideDemandZone,
decisionState,
swingBar,
rejectBar,
breakerBar,
momentumBar,
false //
);
}
}
//
result = hasInsideZone ||
hasRejectedZone ||
isPriceRejected;
if (!result)
{
//
decisionZBar.Clean();
decisionCBar.Clean();
decisionPBar.Clean();
//
swingBar.Clean();
rejectBar.Clean();
breakerBar.Clean();
momentumBar.Clean();
//
Clean(obs);
Clean(fvgs);
//
Clean(visionPoiEvents);
Clean(analysePoiEvents);
Clean(visionCycleEvents);
Clean(decisionPoiEvents);
Clean(analyseCycleEvents);
Clean(decisionCycleEvents);
Clean(consolidationPoiEvents);
Clean(consolidationCycleEvents);
//
visionState.Clean();
analyseState.Clean();
decisionState.Clean();
visionConditions.Clean();
analyseConditions.Clean();
visionXConditions.Clean();
consolidationState.Clean();
decisionConditions.Clean();
analyseXConditions.Clean();
decisionXConditions.Clean();
consolidationConditions.Clean();
consolidationXConditions.Clean();
//
ZeroMemory(insideOB);
ZeroMemory(insideFVG);
ZeroMemory(rejectedOB);
ZeroMemory(rejectedFVG);
ZeroMemory(insideSupplyZone);
ZeroMemory(insideDemandZone);
//
return result;
}
//
RemoveX121SMCXSupDemOBSDraws();
DrawX121SMCXSupDemOBSConditions(
conditions,
visionCycleHelper.mPOIDrawer //
);
//
conditions.UpdateTo(cTime);
//
// Waiting for Price Breakes Inside Zone ...
//
double upper = 0;
double lower = 0;
bool isInsideZoneDirectionBullish = false;
bool isInsideZoneDirectionBearish = false;
//
if (hasInsideOB)
{
//
upper = insideOB.Upper();
lower = insideOB.Lower();
//
isInsideZoneDirectionBullish = insideOB.IsBullish();
isInsideZoneDirectionBearish = insideOB.IsBearish();
}
else if (hasInsideFVG)
{
//
upper = insideFVG.Upper();
lower = insideFVG.Lower();
//
isInsideZoneDirectionBullish = insideFVG.IsBullish();
isInsideZoneDirectionBearish = insideFVG.IsBearish();
}
else if (isPriceRejected)
{
//
bool hasRejectedOB = rejectedOB != NULL;
bool hasRejectedFVG = rejectedFVG != NULL;
//
if (hasRejectedOB)
{
//
DrawX121SMCXSupDemOBSOrderBlock(
rejectedOB,
consolidationCycleHelper.mPOIDrawer //
);
}
//
if (hasRejectedFVG)
{
//
DrawX121SMCXSupDemOBSFairValueGap(
rejectedFVG,
consolidationCycleHelper.mPOIDrawer //
);
}
// //
// if (!hasRejectedOB &&
// !hasRejectedFVG)
// {
// //
// if (hasInsideSupDemZone)
// {
// //
// double min = 0;
// double max = 0;
// bool canSetMin = false;
// bool canSetMax = false;
// //
// if (swingBar.IsValid())
// {
// //
// canSetMin =
// min == 0 || min > swingBar.low;
// if (canSetMin)
// {
// min = swingBar.low;
// }
// //
// canSetMax =
// max == 0 || max < swingBar.high;
// if (canSetMax)
// {
// max = swingBar.high;
// }
// }
// //
// if (rejectBar.IsValid())
// {
// //
// canSetMin =
// min == 0 || min > rejectBar.low;
// if (canSetMin)
// {
// min = rejectBar.low;
// }
// //
// canSetMax =
// max == 0 || max < rejectBar.high;
// if (canSetMax)
// {
// max = rejectBar.high;
// }
// }
// //
// if (breakerBar.IsValid())
// {
// //
// canSetMin =
// min == 0 || min > breakerBar.low;
// if (canSetMin)
// {
// min = breakerBar.low;
// }
// //
// canSetMax =
// max == 0 || max < breakerBar.high;
// if (canSetMax)
// {
// max = breakerBar.high;
// }
// }
// //
// if (momentumBar.IsValid())
// {
// //
// canSetMin =
// min == 0 || min > momentumBar.low;
// if (canSetMin)
// {
// min = momentumBar.low;
// }
// //
// canSetMax =
// max == 0 || max < momentumBar.high;
// if (canSetMax)
// {
// max = momentumBar.high;
// }
// }
// //
// upper = max;
// lower = min;
// //
// if (hasInsideSupplyZone)
// {
// //
// isInsideZoneDirectionBullish = false;
// isInsideZoneDirectionBearish = true;
// //
// lower = GetEntry(
// conditions.symbol,
// POSITION_TYPE_SELL //
// );
// }
// //
// if (hasInsideDemandZone)
// {
// //
// isInsideZoneDirectionBullish = true;
// isInsideZoneDirectionBearish = false;
// //
// upper = GetEntry(
// conditions.symbol,
// POSITION_TYPE_BUY //
// );
// }
// }
// }
}
//
// Cleanup Unused Objects ...
//
decisionZBar.Clean();
decisionCBar.Clean();
decisionPBar.Clean();
//
ZeroMemory(insideOB);
ZeroMemory(insideFVG);
ZeroMemory(rejectedOB);
ZeroMemory(rejectedFVG);
ZeroMemory(insideSupplyZone);
ZeroMemory(insideDemandZone);
//
Clean(visionPoiEvents);
Clean(analysePoiEvents);
Clean(visionCycleEvents);
Clean(decisionPoiEvents);
Clean(analyseCycleEvents);
Clean(decisionCycleEvents);
Clean(consolidationPoiEvents);
Clean(consolidationCycleEvents);
//
visionState.Clean();
analyseState.Clean();
decisionZBar.Clean();
decisionCBar.Clean();
decisionPBar.Clean();
decisionState.Clean();
visionConditions.Clean();
analyseConditions.Clean();
visionXConditions.Clean();
consolidationState.Clean();
decisionConditions.Clean();
analyseXConditions.Clean();
decisionXConditions.Clean();
consolidationConditions.Clean();
consolidationXConditions.Clean();
//
// Summarize Conditions ...
//
bool isCondition1Bullish =
//
hasBullishTrend &&
isInsideZoneDirectionBullish
//
;
//
bool isCondition1Bearish =
//
hasBearishTrend &&
isInsideZoneDirectionBearish
//
;
//
bool hasCondition1 = isCondition1Bullish ||
isCondition1Bearish;
if (hasCondition1)
{
//
ENUM_X_DIRECTION pzDir =
isCondition1Bullish
? X_DIRECTION_BULLISH
: X_DIRECTION_BEARISH;
//
double point = GetEntry(
conditions.symbol,
pzDir //
);
//
double longPivot = lower; // triggerXConditions.valesBuffer[1];
double shortPivot = upper; // triggerXConditions.peaksBuffer[1];
//
// Manipulate Conditions Point ...
//
conditions.point =
isCondition1Bullish
? shortPivot
: longPivot;
//
// Manipulate Conditions Pivot ...
//
conditions.pivot =
isCondition1Bullish
? longPivot
: shortPivot;
}
//
//
//
//
isBullish =
//
isCondition1Bullish
//
;
//
isBearish =
//
isCondition1Bearish
//
;
//
result = isBullish ||
isBearish;
if (!result)
{
return result;
}
//
conditions.setupTime = cTime;
conditions.dir =
isBullish
? X_DIRECTION_BULLISH
: X_DIRECTION_BEARISH;
//
RemoveX121SMCXSupDemOBSDraws();
DrawX121SMCXSupDemOBSConditions(
conditions,
visionCycleHelper.mPOIDrawer //
);
//
swingBar.Clean();
rejectBar.Clean();
breakerBar.Clean();
momentumBar.Clean();
//
return result;
}
//
// Detect Trigger Conditions ...
bool DetectX121SMCXSupDemOBSSignalTrigger(
//
X121SMCStrategyXSupDemOBSSignalConditions &conditions,
//
string _symbol,
ENUM_TIMEFRAMES _period,
//
XC121SMCCycleHelper *decisionCycleHelper,
XC121SMCCycleHelper *analyseCycleHelper,
XC121SMCCycleHelper *consolidationCycleHelper,
XC121SMCCycleHelper *visionCycleHelper,
//
int maxAllowedSetupAge = 60 //
//
)
{
//
bool result = false;
//
result =
//
visionCycleHelper != NULL &&
analyseCycleHelper != NULL &&
decisionCycleHelper != NULL &&
consolidationCycleHelper != NULL
//
;
if (!result)
{
return result;
}
//
result = conditions.IsSetuped();
if (!result)
{
return result;
}
//
datetime setupTime = conditions.setupTime;
ENUM_X_DIRECTION setupDir = conditions.dir;
//
bool isBullish = IsBullish(setupDir);
bool isBearish = IsBearish(setupDir);
//
int zIndex = 0;
int cIndex = zIndex + 1;
int pIndex = cIndex + 1;
int ppIndex = pIndex + 1;
//
int loopback = 10;
//
string symbol = _symbol;
ENUM_TIMEFRAMES period = _period;
//
XOHCL zBar;
result = decisionCycleHelper.GetBar(
zBar,
zIndex //
);
if (!result)
{
return result;
}
//
XOHCL cBar;
result = decisionCycleHelper.GetBar(
cBar,
cIndex //
);
if (!result)
{
return result;
}
//
XOHCL pBar;
result = decisionCycleHelper.GetBar(
pBar,
pIndex //
);
if (!result)
{
return result;
}
//
double ask = GetAsk(symbol);
double bid = GetBid(symbol);
datetime cTime = TimeCurrent();
double points = GetPoints(symbol);
//
int swingLoopback = 9;
double ll = cBar.FindLowest(swingLoopback, MODE_LOW);
double hh = cBar.FindHighest(swingLoopback, MODE_HIGH);
double llDown = cBar.FindLowesttDown(swingLoopback);
double hhUp = cBar.FindHighestUp(swingLoopback);
//
// Cycles Conditions ...
//
// Decision ...
ENUM_XPOI_EVENTS decisionPoiEvents[];
ENUM_X_CYCLE_EVENTS decisionCycleEvents[];
X121SMCCycleConditions decisionConditions;
result = decisionCycleHelper.GetConditions(
decisionCycleEvents,
decisionPoiEvents,
decisionConditions,
zIndex,
loopback //
);
if (!result)
{
//
// Cleanup ...
zBar.Clean();
cBar.Clean();
pBar.Clean();
//
Clean(decisionPoiEvents);
Clean(decisionCycleEvents);
//
decisionConditions.Clean();
//
return result;
}
//
// Cycles POI States ...
XPOIState decisionState = decisionConditions.state;
//
// Cycle X121Conditions ...
X121Conditions decisionXConditions = decisionConditions.x121Conditions;
//
// Trigger Conditions ...
//
// Slopes ...
//
bool isRsiSlopeBullish = decisionXConditions.isRsiSlopeBullish;
bool isStrSlopeBullish = decisionXConditions.isStrSlopeBullish;
bool isAtrUpperSlopeBullish = decisionXConditions.isAtrUpperSlopeBullish;
bool isAtrLowerSlopeBullish = decisionXConditions.isAtrLowerSlopeBullish;
bool isVwapFastSlopeBullish = decisionXConditions.isVwapFastSlopeBullish;
bool isVwapMidSlopeBullish = decisionXConditions.isVwapMidSlopeBullish;
bool isVwapSlowSlopeBullish = decisionXConditions.isVwapSlowSlopeBullish;
//
bool isRsiSlopeBearish = decisionXConditions.isRsiSlopeBearish;
bool isStrSlopeBearish = decisionXConditions.isStrSlopeBearish;
bool isAtrUpperSlopeBearish = decisionXConditions.isAtrUpperSlopeBearish;
bool isAtrLowerSlopeBearish = decisionXConditions.isAtrLowerSlopeBearish;
bool isVwapFastSlopeBearish = decisionXConditions.isVwapFastSlopeBearish;
bool isVwapMidSlopeBearish = decisionXConditions.isVwapMidSlopeBearish;
bool isVwapSlowSlopeBearish = decisionXConditions.isVwapSlowSlopeBearish;
//
bool isSlopesBullish =
isRsiSlopeBullish &&
isStrSlopeBullish &&
isAtrUpperSlopeBullish &&
isAtrLowerSlopeBullish &&
isVwapFastSlopeBullish &&
isVwapMidSlopeBullish &&
isVwapSlowSlopeBullish;
//
bool isSlopesBearish =
isRsiSlopeBearish &&
isStrSlopeBearish &&
isAtrUpperSlopeBearish &&
isAtrLowerSlopeBearish &&
isVwapFastSlopeBearish &&
isVwapMidSlopeBearish &&
isVwapSlowSlopeBearish;
//
double point = conditions.point;
bool isPointBreaked = IsBarBreak(
point,
setupDir,
cBar //
);
//
// Summary ...
//
isBullish =
//
isBullish &&
isPointBreaked
//
;
//
isBearish =
//
isBearish &&
isPointBreaked
//
;
//
result = isBullish ||
isBearish;
if (!result)
{
//
// Cleanup Setup Conditions ...
int setupAge = conditions.GetSetupAge();
if (IsValidSize(setupAge) &&
IsValidSize(maxAllowedSetupAge) &&
setupAge >= maxAllowedSetupAge)
{
conditions.Clean();
}
//
// Cleanup ...
zBar.Clean();
cBar.Clean();
pBar.Clean();
//
Clean(decisionPoiEvents);
Clean(decisionCycleEvents);
//
decisionState.Clean();
decisionConditions.Clean();
decisionXConditions.Clean();
//
return result;
}
//
// Detect Nearest Pivot Point ...
//
double entry = GetEntry(
conditions.symbol,
setupDir //
);
//
double sls[];
Add(
conditions.pivot,
sls //
);
//
double iAtr = decisionXConditions.atrBuffer[1];
iAtr *= 2;
//
double slsMin = GetMin(sls);
double slsMax = GetMax(sls);
//
double sl = isBullish
? slsMin - iAtr
: slsMax + iAtr;
double risk = MathAbs(entry - sl);
//
// Filling Conditions Props ...
conditions.sl = sl;
// conditions.target = target;
conditions.triggerTime = cTime;
conditions.type = isBullish
? X_POSITION_TYPE_LONG
: X_POSITION_TYPE_SHORT;
//
// Cleanup ...
zBar.Clean();
cBar.Clean();
pBar.Clean();
//
Clean(decisionPoiEvents);
Clean(decisionCycleEvents);
//
decisionState.Clean();
decisionConditions.Clean();
decisionXConditions.Clean();
//
return result;
}
//
// Detect Guards ...
bool DetectX121SMCXSupDemOBSGuards(
X121SMCGuard &guards[],
const XPosition &positions[],
//
XC121SMCCycleHelper *decisionCycleHelper,
XC121SMCCycleHelper *analyseCycleHelper,
XC121SMCCycleHelper *consolidationCycleHelper,
XC121SMCCycleHelper *visionCycleHelper
//
)
{
//
bool result = false;
//
result =
//
visionCycleHelper != NULL &&
analyseCycleHelper != NULL &&
decisionCycleHelper != NULL &&
consolidationCycleHelper != NULL
//
;
if (!result)
{
return result;
}
//
string provider = ToString(X_121_SMC_PROVIDER_XSUPDEMOBS);
// //
// result = DetectX121SMCGuards(
// provider,
// guards,
// positions,
// // triggerCycleHelper,
// decisionCycleHelper,
// analyseCycleHelper,
// verificationCycleHelper,
// consolidationCycleHelper,
// visionCycleHelper,
// //
// true, // CloseOnTPNear Guard ...
// true, // CloseLongsOnBearishTrend Guard ...
// true, // CloseShortsOnBullishTrend Guard ...
// true, // CloseAllWeekend Guard ...
// true, // PartialCloseOnTrendChange Guard ...
// true, // TrailStop Guard ...
// true, // TrailTarget Guard ...
// true // Hedge Guard ...
// //
// );
//
return result;
}
//
// Add Conditions to Conditions Collection ...
int AddX121SMCXSupDemOBSConditionsIfNotExists(
X121SMCStrategyXSupDemOBSSignalConditions &item,
X121SMCStrategyXSupDemOBSSignalConditions &items[],
int maxAllowed = 10 //
)
{
//
int result = 0;
//
bool isSetuped = IsValid(item.setupTime) &&
HasDirection(item.dir);
if (!isSetuped)
{
return result;
}
//
int count = ArraySize(items);
if (IsValidSize(count))
{
//
// Copy Original Items ...
X121SMCStrategyXSupDemOBSSignalConditions tmpItems[];
Copy(
items,
tmpItems //
);
//
// Prese Item Data ...
bool isBullish = IsBullish(item.dir);
//
for (int i = 0; i < count; i++)
{
//
X121SMCStrategyXSupDemOBSSignalConditions iItem = tmpItems[i];
//
bool canRemove = item.dir == iItem.dir &&
item.pivot == iItem.pivot;
if (canRemove)
{
//
ArrayRemove(
items,
i,
1 //
);
}
}
//
Clean(tmpItems);
}
//
AddRef(
item,
items //
);
//
// Remove Olds ...
CleanupArray(
items,
maxAllowed //
);
//
result = ArraySize(items);
//
return result;
}
//
// Draws ...
//
//
void RemoveX121SMCXSupDemOBSDraws()
{
mX121SMCXSupDemOBSObjects.Clear();
}
//
void DrawX121SMCXSupDemOBSOrderBlock(
XCOrderBlock *ob,
XCPOIDrawer *drawer //
)
{
//
if (ob == NULL ||
drawer == NULL)
{
return;
}
//
ENUM_X_DIRECTION forDir = ob.GetDirection();
//
color bullishColor = drawer.BarBullishColor();
color bearishColor = drawer.BarBearishColor();
color forColor = IsBullish(forDir)
? bullishColor
: bearishColor;
//
// Draw Order Block ...
XCBaseObject *obj;
bool isCreated = drawer.CreateOrderBlock(
ob,
obj //
);
if (isCreated)
{
mX121SMCXSupDemOBSObjects.Add(obj);
}
//
ulong chartID = drawer.ChartIdentification();
int subWindow = drawer.SubWindowIdentification();
//
XOHCL startedBar;
ENUM_X_DIRECTION startedDir;
bool isStarted = ob.IsStarted(
forDir,
startedBar,
startedDir //
);
if (isStarted)
{
//
datetime to = startedBar.time + (PeriodSeconds(startedBar.period));
//
XCOHCLObject *obj;
bool isCreated = drawer.CreateBar(
startedBar,
obj,
to //
);
if (isCreated)
{
//
obj.BodyColor(clrYellow);
obj.HighShadowColor(clrYellow);
obj.LowShadowColor(clrYellow);
//
obj.BodyStyle(STYLE_SOLID);
obj.HighShadowStyle(STYLE_SOLID);
obj.LowShadowStyle(STYLE_SOLID);
//
mX121SMCXSupDemOBSObjects.Add(obj);
}
//
string startVLineName = "Start_" + ob.GetTag();
//
CChartObjectVLine *startVLine;
startVLine = new CChartObjectVLine();
isCreated = startVLine.Create(
chartID,
startVLineName,
subWindow,
startedBar.time //
);
if (isCreated)
{
//
startVLine.Color(forColor);
//
mX121SMCXSupDemOBSObjects.Add(startVLine);
}
}
}
//
void DrawX121SMCXSupDemOBSFairValueGap(
XCFVG *fvg,
XCPOIDrawer *drawer //
)
{
//
if (fvg == NULL ||
drawer == NULL)
{
return;
}
//
ENUM_X_DIRECTION forDir = fvg.GetDirection();
//
color bullishColor = drawer.BarBullishColor();
color bearishColor = drawer.BarBearishColor();
color forColor = IsBullish(forDir)
? bullishColor
: bearishColor;
//
// Draw Order Block ...
XCBaseObject *obj;
bool isCreated = drawer.CreateFairValueGap(
fvg,
obj //
);
if (isCreated)
{
mX121SMCXSupDemOBSObjects.Add(obj);
}
//
ulong chartID = drawer.ChartIdentification();
int subWindow = drawer.SubWindowIdentification();
//
XOHCL startedBar;
ENUM_X_DIRECTION startedDir;
bool isStarted = fvg.IsStarted(
forDir,
startedBar,
startedDir //
);
if (isStarted)
{
//
datetime to = startedBar.time + (PeriodSeconds(startedBar.period));
//
XCOHCLObject *obj;
bool isCreated = drawer.CreateBar(
startedBar,
obj,
to //
);
if (isCreated)
{
//
obj.BodyColor(clrYellow);
obj.HighShadowColor(clrYellow);
obj.LowShadowColor(clrYellow);
//
obj.BodyStyle(STYLE_SOLID);
obj.HighShadowStyle(STYLE_SOLID);
obj.LowShadowStyle(STYLE_SOLID);
//
mX121SMCXSupDemOBSObjects.Add(obj);
}
//
string startVLineName = "Start_" + fvg.GetTag();
//
CChartObjectVLine *startVLine;
startVLine = new CChartObjectVLine();
isCreated = startVLine.Create(
chartID,
startVLineName,
subWindow,
startedBar.time //
);
if (isCreated)
{
//
startVLine.Color(forColor);
//
mX121SMCXSupDemOBSObjects.Add(startVLine);
}
}
}
//
void DrawX121SMCXSupDemOBSWorkingZone(
X121SMCStrategyXSupDemOBSSignalConditions &conditions,
XCPOIDrawer *drawer //
)
{
//
if (drawer == NULL)
{
return;
}
//
bool isCreated = false;
//
bool hasVisionHighestSupplyZone = conditions.HasVisionHighestSupplyZone();
if (hasVisionHighestSupplyZone)
{
//
XCSupplyZoneObject *ivhSupObj;
isCreated = drawer.CreateSupplyZone(
conditions.visionHighestSupplyZone,
ivhSupObj //
);
if (isCreated)
{
mX121SMCXSupDemOBSWorkingZoneObjects.Add(ivhSupObj);
}
}
//
bool hasConsolidationHighestSupplyZone = conditions.HasConsolidationHighestSupplyZone();
if (hasConsolidationHighestSupplyZone)
{
//
XCSupplyZoneObject *ichSupObj;
isCreated = drawer.CreateSupplyZone(
conditions.consolidationHighestSupplyZone,
ichSupObj //
);
if (isCreated)
{
mX121SMCXSupDemOBSWorkingZoneObjects.Add(ichSupObj);
}
}
//
bool hasVisionLowestDemandZone = conditions.HasVisionLowestDemandZone();
if (hasVisionLowestDemandZone)
{
//
XCDemandZoneObject *ivlSupObj;
isCreated = drawer.CreateDemandZone(
conditions.visionLowestDemandZone,
ivlSupObj //
);
if (isCreated)
{
mX121SMCXSupDemOBSWorkingZoneObjects.Add(ivlSupObj);
}
}
//
bool hasConsolidationLowestDemandZone = conditions.HasConsolidationLowestDemandZone();
if (hasConsolidationLowestDemandZone)
{
//
XCDemandZoneObject *iclSupObj;
isCreated = drawer.CreateDemandZone(
conditions.consolidationLowestDemandZone,
iclSupObj //
);
if (isCreated)
{
mX121SMCXSupDemOBSWorkingZoneObjects.Add(iclSupObj);
}
}
//
bool hasWorkingZone = conditions.workingZone.IsValid();
if (hasWorkingZone)
{
//
string zonePrefix = "X121_WZ_" + conditions.workingZone.symbol + "_" + ToString(conditions.workingZone.period);
string fromStr = ToFormatString(conditions.workingZone.from);
string fromMD5 = ToMD5(fromStr);
//
string upperName = zonePrefix + "_Upper_" + fromMD5;
string lowerName = zonePrefix + "_Lower_" + fromMD5;
string zoneUpperName = zonePrefix + "_ZoneUpper_" + fromMD5;
string zoneLowerName = zonePrefix + "_ZoneLower_" + fromMD5;
//
string q1Name = zonePrefix + "_Q1_" + fromMD5;
string q2Name = zonePrefix + "_Q2_" + fromMD5;
string q3Name = zonePrefix + "_Q3_" + fromMD5;
//
ulong chartID = drawer.ChartIdentification();
int subWindow = drawer.SubWindowIdentification();
//
bool isCreated = false;
//
// Lower ...
CChartObjectHLine *lowerHLine;
lowerHLine = new CChartObjectHLine();
isCreated = lowerHLine.Create(
chartID,
lowerName,
subWindow,
conditions.workingZone.lower //
);
if (isCreated)
{
//
lowerHLine.Color(clrLime);
mX121SMCXSupDemOBSWorkingZoneObjects.Add(lowerHLine);
}
//
CChartObjectHLine *upperHLine;
upperHLine = new CChartObjectHLine();
isCreated = upperHLine.Create(
chartID,
upperName,
subWindow,
conditions.workingZone.upper //
);
if (isCreated)
{
//
upperHLine.Color(clrLime);
mX121SMCXSupDemOBSWorkingZoneObjects.Add(upperHLine);
}
//
CChartObjectHLine *zoneLowerHLine;
zoneLowerHLine = new CChartObjectHLine();
isCreated = zoneLowerHLine.Create(
chartID,
zoneLowerName,
subWindow,
conditions.workingZone.zoneLower //
);
if (isCreated)
{
//
zoneLowerHLine.Color(clrRed);
mX121SMCXSupDemOBSWorkingZoneObjects.Add(zoneLowerHLine);
}
//
CChartObjectHLine *zoneUpperHLine;
zoneUpperHLine = new CChartObjectHLine();
isCreated = zoneUpperHLine.Create(
chartID,
zoneUpperName,
subWindow,
conditions.workingZone.zoneUpper //
);
if (isCreated)
{
//
zoneUpperHLine.Color(clrRed);
mX121SMCXSupDemOBSWorkingZoneObjects.Add(zoneUpperHLine);
}
//
CChartObjectHLine *quarter1HLine;
quarter1HLine = new CChartObjectHLine();
isCreated = quarter1HLine.Create(
chartID,
q1Name,
subWindow,
conditions.workingZone.quarter1 //
);
if (isCreated)
{
//
quarter1HLine.Color(clrYellow);
mX121SMCXSupDemOBSWorkingZoneObjects.Add(quarter1HLine);
}
//
CChartObjectHLine *quarter2HLine;
quarter2HLine = new CChartObjectHLine();
isCreated = quarter2HLine.Create(
chartID,
q2Name,
subWindow,
conditions.workingZone.quarter2 //
);
if (isCreated)
{
//
quarter2HLine.Color(clrYellow);
mX121SMCXSupDemOBSWorkingZoneObjects.Add(quarter2HLine);
}
//
CChartObjectHLine *quarter3HLine;
quarter3HLine = new CChartObjectHLine();
isCreated = quarter3HLine.Create(
chartID,
q3Name,
subWindow,
conditions.workingZone.quarter3 //
);
if (isCreated)
{
//
quarter3HLine.Color(clrYellow);
mX121SMCXSupDemOBSWorkingZoneObjects.Add(quarter3HLine);
}
}
}
//
void DrawX121SMCXSupDemOBSConditions(
X121SMCStrategyXSupDemOBSSignalConditions &conditions,
XCPOIDrawer *drawer,
bool forceClean = false //
)
{
//
if (drawer == NULL)
{
return;
}
//
if (forceClean)
{
mX121SMCXSupDemOBSObjects.Clear();
}
//
bool isCreated = false;
//
int obFVGsCount = ArraySize(conditions.obFVGs);
bool hasOBFVGs = IsValidSize(obFVGsCount);
if (hasOBFVGs)
{
//
for (int i = 0; i < obFVGsCount; i++)
{
//
XOBFVG iOBFVG = conditions.obFVGs[i];
//
DrawX121SMCXSupDemOBSOrderBlock(
iOBFVG.ob,
drawer //
);
//
DrawX121SMCXSupDemOBSFairValueGap(
iOBFVG.fvg,
drawer //
);
//
int hasUnActivatedOBs = iOBFVG.HasUnActivatedOBs();
int unActivatedOBsCount = iOBFVG.CountUnActivatedOBs();
if (hasUnActivatedOBs)
{
//
for (int j = 0; j < unActivatedOBsCount; j++)
{
//
DrawX121SMCXSupDemOBSOrderBlock(
iOBFVG.unActivatedOBs[j],
drawer //
);
}
}
//
int hasUnActivatedFVGs = iOBFVG.HasUnActivatedFVGs();
int unActivatedFVGsCount = iOBFVG.CountUnActivatedFVGs();
if (hasUnActivatedFVGs)
{
//
for (int j = 0; j < unActivatedFVGsCount; j++)
{
//
DrawX121SMCXSupDemOBSFairValueGap(
iOBFVG.unActivatedFVGs[j],
drawer //
);
}
}
}
}
//
int insideZoneWidth = 1;
color insideZoneColor = clrYellow;
bool hasInsideOB = conditions.insideOB != NULL &&
conditions.insideOB.IsValid();
if (hasInsideOB)
{
//
bool isBullish = conditions.insideOB.IsBullish();
//
XCBaseObject *iObj = NULL;
isCreated = false;
if (isBullish)
{
//
XCBullishOrderBlockObject *iiObj;
isCreated = drawer.CreateBullishOrderBlock(
conditions.insideOB,
iiObj //
);
//
if (isCreated)
{
//
iiObj.ZoneColor(insideZoneColor);
iiObj.ZoneWidth(insideZoneWidth);
//
iObj = (XCBaseObject *)iiObj;
}
}
else
{
//
XCBearishOrderBlockObject *iiObj;
isCreated = drawer.CreateBearishOrderBlock(
conditions.insideOB,
iiObj //
);
//
if (isCreated)
{
//
iiObj.ZoneColor(insideZoneColor);
iiObj.ZoneWidth(insideZoneWidth);
//
iObj = (XCBaseObject *)iiObj;
}
}
//
if (isCreated)
{
mX121SMCXSupDemOBSObjects.Add(iObj);
}
}
//
bool hasInsideFVG = conditions.insideFVG != NULL &&
conditions.insideFVG.IsValid();
if (hasInsideFVG)
{
//
bool isBullish = conditions.insideFVG.IsBullish();
//
XCBaseObject *iObj = NULL;
isCreated = false;
if (isBullish)
{
//
XCBullishFairValueGapObject *iiObj;
isCreated = drawer.CreateBullishFairValueGap(
conditions.insideFVG,
iiObj //
);
//
if (isCreated)
{
//
iiObj.ZoneColor(insideZoneColor);
iiObj.ZoneWidth(insideZoneWidth);
//
iObj = (XCBaseObject *)iiObj;
}
}
else
{
//
XCBearishFairValueGapObject *iiObj;
isCreated = drawer.CreateBearishFairValueGap(
conditions.insideFVG,
iiObj //
);
//
if (isCreated)
{
//
iiObj.ZoneColor(insideZoneColor);
iiObj.ZoneWidth(insideZoneWidth);
//
iObj = (XCBaseObject *)iiObj;
}
}
//
if (isCreated)
{
mX121SMCXSupDemOBSObjects.Add(iObj);
}
}
}
//
//
//
//
void RemoveX121SMCXSupDemOBSWorkingZoneDraws()
{
mX121SMCXSupDemOBSWorkingZoneObjects.Clear();
}
//
//
//
//