2996 lines
68 KiB
Plaintext
2996 lines
68 KiB
Plaintext
#include "../Signals/x-121.smc.xhkpv.signal.lib.mq5"
|
|
#include "../Signals/x-121.smc.xiobpv.signal.lib.mq5"
|
|
#include "../Signals/x-121.smc.xobpv.signal.lib.mq5"
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
|
|
bool useXHKPVSignal;
|
|
bool useXOBPVSignal;
|
|
bool useXIOBPVSignal;
|
|
|
|
Clean(mXHKPVConditionsCollection);
|
|
Clean(mXOBPVConditionsCollection);
|
|
Clean(mXIOBPVConditionsCollection);
|
|
|
|
bool hasXHKPVSignal = false;
|
|
bool hasXOBPVSignal = false;
|
|
bool hasXIOBPVSignal = false;
|
|
|
|
useXHKPVSignal = false;
|
|
useXOBPVSignal = false;
|
|
useXIOBPVSignal = false;
|
|
|
|
//
|
|
// XHKPV Signal ...
|
|
if (useXHKPVSignal && !hasSignal)
|
|
{
|
|
//
|
|
hasXHKPVSignal = DetectXHKPVSignal(conditions);
|
|
hasSignal = hasXHKPVSignal;
|
|
}
|
|
|
|
//
|
|
// XOBPV Signal ...
|
|
if (useXOBPVSignal && !hasSignal)
|
|
{
|
|
//
|
|
hasXOBPVSignal = DetectXOBPVSignal(conditions);
|
|
hasSignal = hasXOBPVSignal;
|
|
}
|
|
|
|
//
|
|
// XIOBPV Signal ...
|
|
if (useXIOBPVSignal && !hasSignal)
|
|
{
|
|
//
|
|
hasXIOBPVSignal = DetectXIOBPVSignal(conditions);
|
|
hasSignal = hasXIOBPVSignal;
|
|
}
|
|
|
|
//
|
|
// XHKPV Guard Detection ...
|
|
if (useXHKPVSignal)
|
|
{
|
|
//
|
|
bool hasGuard = DetectX121SMCXHKPVGuards(
|
|
guards,
|
|
positions,
|
|
mTriggerCycleHelper,
|
|
mDecisionCycleHelper,
|
|
mAnalyseCycleHelper,
|
|
mVerificationCycleHelper,
|
|
mConsolidationCycleHelper,
|
|
mVisionCycleHelper //
|
|
);
|
|
}
|
|
|
|
//
|
|
// XOBPV Guard Detection ...
|
|
if (useXOBPVSignal)
|
|
{
|
|
//
|
|
bool hasGuard = DetectX121SMCXOBPVGuards(
|
|
guards,
|
|
positions,
|
|
mTriggerCycleHelper,
|
|
mDecisionCycleHelper,
|
|
mAnalyseCycleHelper,
|
|
mVerificationCycleHelper,
|
|
mConsolidationCycleHelper,
|
|
mVisionCycleHelper //
|
|
);
|
|
}
|
|
|
|
//
|
|
// XIOBPV Guard Detection ...
|
|
if (useXIOBPVSignal)
|
|
{
|
|
//
|
|
bool hasGuard = DetectX121SMCXIOBPVGuards(
|
|
guards,
|
|
positions,
|
|
mTriggerCycleHelper,
|
|
mDecisionCycleHelper,
|
|
mAnalyseCycleHelper,
|
|
mVerificationCycleHelper,
|
|
mConsolidationCycleHelper,
|
|
mVisionCycleHelper //
|
|
);
|
|
}
|
|
|
|
//
|
|
// XHKPV Signal ...
|
|
bool DetectXHKPVSignal(
|
|
X121SMCStrategyConditions &conditions //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
bool isBullish = false;
|
|
bool isBearish = false;
|
|
|
|
//
|
|
int zIndex = 0;
|
|
int cIndex = zIndex + 1;
|
|
int pIndex = cIndex + 1;
|
|
int ppIndex = pIndex + 1;
|
|
|
|
//
|
|
string symbol = GetSymbol();
|
|
ENUM_TIMEFRAMES period = GetPeriod();
|
|
|
|
//
|
|
XOHCL zBar;
|
|
result = zBar.Init(
|
|
symbol,
|
|
period,
|
|
zIndex //
|
|
);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
XOHCL cBar;
|
|
result = cBar.Init(
|
|
symbol,
|
|
period,
|
|
cIndex //
|
|
);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
XOHCL pBar;
|
|
result = pBar.Init(
|
|
symbol,
|
|
period,
|
|
pIndex //
|
|
);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
double cLL = cBar.FindLowest(7, MODE_LOW);
|
|
double cHH = cBar.FindHighest(7, MODE_HIGH);
|
|
|
|
//
|
|
datetime cTime = TimeCurrent();
|
|
|
|
//
|
|
ENUM_X_121_SMC_PROVIDERS provider = X_121_SMC_PROVIDER_XHKPV;
|
|
string providerStr = ToString(provider);
|
|
|
|
//
|
|
// Detect Setup Conditions ...
|
|
datetime setupTime = mXHKPVConditions.setupTime;
|
|
bool isSetuped = mXHKPVConditions.IsSetuped();
|
|
ENUM_X_DIRECTION setupDir = mXHKPVConditions.dir;
|
|
if (!isSetuped)
|
|
{
|
|
//
|
|
// Detect Signal Setup ...
|
|
isSetuped = DetectX121SMCXHKPVSignalSetup(
|
|
symbol,
|
|
period,
|
|
mXHKPVConditions,
|
|
mTriggerCycleHelper,
|
|
mDecisionCycleHelper,
|
|
mAnalyseCycleHelper,
|
|
mVerificationCycleHelper,
|
|
mConsolidationCycleHelper,
|
|
mVisionCycleHelper //
|
|
);
|
|
|
|
//
|
|
setupDir = mXHKPVConditions.dir;
|
|
setupTime = mXHKPVConditions.setupTime;
|
|
|
|
//
|
|
if (isSetuped)
|
|
{
|
|
//
|
|
int items = AddX121SMCXHKPVConditionsIfNotExists(
|
|
mXHKPVConditions,
|
|
mXHKPVConditionsCollection //
|
|
);
|
|
|
|
//
|
|
mXHKPVConditions.Clean();
|
|
}
|
|
}
|
|
|
|
//
|
|
int conditionsCount = ArraySize(mXHKPVConditionsCollection);
|
|
result = IsValidSize(conditionsCount);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Looking For Conditions ...
|
|
int selectedIndex = 0;
|
|
X121SMCStrategyXHKPVSignalConditions mTmpConditions[];
|
|
Copy(
|
|
mXHKPVConditionsCollection,
|
|
mTmpConditions //
|
|
);
|
|
X121SMCStrategyXHKPVSignalConditions mConditions;
|
|
for (int i = 0; i < conditionsCount; i++)
|
|
{
|
|
//
|
|
// Check Triggers ...
|
|
bool canTrigger = mTmpConditions[i].CanTrigger();
|
|
datetime triggerTime = mTmpConditions[i].triggerTime;
|
|
if (!canTrigger)
|
|
{
|
|
//
|
|
// Detect Signal Trigger ...
|
|
canTrigger = DetectX121SMCXHKPVSignalTrigger(
|
|
mTmpConditions[i],
|
|
symbol,
|
|
period,
|
|
mTriggerCycleHelper,
|
|
mDecisionCycleHelper,
|
|
mAnalyseCycleHelper,
|
|
mVerificationCycleHelper,
|
|
mConsolidationCycleHelper,
|
|
mVisionCycleHelper //
|
|
);
|
|
|
|
//
|
|
result = canTrigger;
|
|
if (!result)
|
|
{
|
|
//
|
|
bool isISetuped = mTmpConditions[i].IsSetuped();
|
|
if (!isISetuped)
|
|
{
|
|
//
|
|
ArrayRemove(
|
|
mXHKPVConditionsCollection,
|
|
i,
|
|
1 //
|
|
);
|
|
}
|
|
continue;
|
|
}
|
|
|
|
//
|
|
triggerTime = mTmpConditions[i].triggerTime;
|
|
}
|
|
|
|
//
|
|
if (canTrigger)
|
|
{
|
|
//
|
|
selectedIndex = i;
|
|
mConditions = mTmpConditions[i];
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
result = IsValid(mConditions.setupTime) &&
|
|
HasDirection(mConditions.dir);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Remove Selected Index from Main Collection ...
|
|
ArrayRemove(
|
|
mXHKPVConditionsCollection,
|
|
selectedIndex,
|
|
1 //
|
|
);
|
|
|
|
//
|
|
// Check Signal Direction ...
|
|
isBullish = IsBullish(mConditions.dir);
|
|
isBearish = IsBearish(mConditions.dir);
|
|
result = isBullish ||
|
|
isBearish;
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Issues Signal on Conditions ...
|
|
conditions.sl = mConditions.sl;
|
|
conditions.provider = providerStr;
|
|
conditions.signalDir = mConditions.dir;
|
|
conditions.target = mConditions.target;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// XOBPV Signal ...
|
|
bool DetectXOBPVSignal(
|
|
X121SMCStrategyConditions &conditions //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
bool isBullish = false;
|
|
bool isBearish = false;
|
|
|
|
//
|
|
int zIndex = 0;
|
|
int cIndex = zIndex + 1;
|
|
int pIndex = cIndex + 1;
|
|
int ppIndex = pIndex + 1;
|
|
|
|
//
|
|
string symbol = GetSymbol();
|
|
ENUM_TIMEFRAMES period = GetPeriod();
|
|
|
|
//
|
|
XOHCL zBar;
|
|
result = zBar.Init(
|
|
symbol,
|
|
period,
|
|
zIndex //
|
|
);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
XOHCL cBar;
|
|
result = cBar.Init(
|
|
symbol,
|
|
period,
|
|
cIndex //
|
|
);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
XOHCL pBar;
|
|
result = pBar.Init(
|
|
symbol,
|
|
period,
|
|
pIndex //
|
|
);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
double cLL = cBar.FindLowest(7, MODE_LOW);
|
|
double cHH = cBar.FindHighest(7, MODE_HIGH);
|
|
|
|
//
|
|
datetime cTime = TimeCurrent();
|
|
|
|
//
|
|
ENUM_X_121_SMC_PROVIDERS provider = X_121_SMC_PROVIDER_XOBPV;
|
|
string providerStr = ToString(provider);
|
|
|
|
//
|
|
// Detect Setup Conditions ...
|
|
datetime setupTime = mXOBPVConditions.setupTime;
|
|
bool isSetuped = mXOBPVConditions.IsSetuped();
|
|
ENUM_X_DIRECTION setupDir = mXOBPVConditions.dir;
|
|
if (!isSetuped)
|
|
{
|
|
//
|
|
// Detect Signal Setup ...
|
|
isSetuped = DetectX121SMCXOBPVSignalSetup(
|
|
symbol,
|
|
period,
|
|
mXOBPVConditions,
|
|
mTriggerCycleHelper,
|
|
mDecisionCycleHelper,
|
|
mAnalyseCycleHelper,
|
|
mVerificationCycleHelper,
|
|
mConsolidationCycleHelper,
|
|
mVisionCycleHelper //
|
|
);
|
|
|
|
//
|
|
setupDir = mXOBPVConditions.dir;
|
|
setupTime = mXOBPVConditions.setupTime;
|
|
|
|
//
|
|
if (isSetuped)
|
|
{
|
|
//
|
|
int items = AddX121SMCXOBPVConditionsIfNotExists(
|
|
mXOBPVConditions,
|
|
mXOBPVConditionsCollection //
|
|
);
|
|
|
|
//
|
|
mXOBPVConditions.Clean();
|
|
}
|
|
}
|
|
|
|
//
|
|
int conditionsCount = ArraySize(mXOBPVConditionsCollection);
|
|
result = IsValidSize(conditionsCount);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Looking For Conditions ...
|
|
int selectedIndex = 0;
|
|
X121SMCStrategyXOBPVSignalConditions mTmpConditions[];
|
|
Copy(
|
|
mXOBPVConditionsCollection,
|
|
mTmpConditions //
|
|
);
|
|
X121SMCStrategyXOBPVSignalConditions mConditions;
|
|
for (int i = 0; i < conditionsCount; i++)
|
|
{
|
|
//
|
|
// Check Triggers ...
|
|
bool canTrigger = mTmpConditions[i].CanTrigger();
|
|
datetime triggerTime = mTmpConditions[i].triggerTime;
|
|
if (!canTrigger)
|
|
{
|
|
//
|
|
// Detect Signal Trigger ...
|
|
canTrigger = DetectX121SMCXOBPVSignalTrigger(
|
|
mTmpConditions[i],
|
|
symbol,
|
|
period,
|
|
mTriggerCycleHelper,
|
|
mDecisionCycleHelper,
|
|
mAnalyseCycleHelper,
|
|
mVerificationCycleHelper,
|
|
mConsolidationCycleHelper,
|
|
mVisionCycleHelper //
|
|
);
|
|
|
|
//
|
|
result = canTrigger;
|
|
if (!result)
|
|
{
|
|
//
|
|
bool isISetuped = mTmpConditions[i].IsSetuped();
|
|
if (!isISetuped)
|
|
{
|
|
//
|
|
ArrayRemove(
|
|
mXOBPVConditionsCollection,
|
|
i,
|
|
1 //
|
|
);
|
|
}
|
|
continue;
|
|
}
|
|
|
|
//
|
|
triggerTime = mTmpConditions[i].triggerTime;
|
|
}
|
|
|
|
//
|
|
if (canTrigger)
|
|
{
|
|
//
|
|
selectedIndex = i;
|
|
mConditions = mTmpConditions[i];
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
result = IsValid(mConditions.setupTime) &&
|
|
HasDirection(mConditions.dir);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Remove Selected Index from Main Collection ...
|
|
ArrayRemove(
|
|
mXOBPVConditionsCollection,
|
|
selectedIndex,
|
|
1 //
|
|
);
|
|
|
|
//
|
|
// Check Signal Direction ...
|
|
isBullish = IsBullish(mConditions.dir);
|
|
isBearish = IsBearish(mConditions.dir);
|
|
result = isBullish ||
|
|
isBearish;
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Issues Signal on Conditions ...
|
|
conditions.sl = mConditions.sl;
|
|
conditions.provider = providerStr;
|
|
conditions.signalDir = mConditions.dir;
|
|
conditions.target = mConditions.target;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// XIOBPV Signal ...
|
|
bool DetectXIOBPVSignal(
|
|
X121SMCStrategyConditions &conditions //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
bool isBullish = false;
|
|
bool isBearish = false;
|
|
|
|
//
|
|
int zIndex = 0;
|
|
int cIndex = zIndex + 1;
|
|
int pIndex = cIndex + 1;
|
|
int ppIndex = pIndex + 1;
|
|
|
|
//
|
|
string symbol = GetSymbol();
|
|
ENUM_TIMEFRAMES period = GetPeriod();
|
|
|
|
//
|
|
XOHCL zBar;
|
|
result = zBar.Init(
|
|
symbol,
|
|
period,
|
|
zIndex //
|
|
);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
XOHCL cBar;
|
|
result = cBar.Init(
|
|
symbol,
|
|
period,
|
|
cIndex //
|
|
);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
XOHCL pBar;
|
|
result = pBar.Init(
|
|
symbol,
|
|
period,
|
|
pIndex //
|
|
);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
double cLL = cBar.FindLowest(7, MODE_LOW);
|
|
double cHH = cBar.FindHighest(7, MODE_HIGH);
|
|
|
|
//
|
|
datetime cTime = TimeCurrent();
|
|
|
|
//
|
|
ENUM_X_121_SMC_PROVIDERS provider = X_121_SMC_PROVIDER_XIOBPV;
|
|
string providerStr = ToString(provider);
|
|
|
|
//
|
|
// Detect Setup Conditions ...
|
|
datetime setupTime = mXIOBPVConditions.setupTime;
|
|
bool isSetuped = mXIOBPVConditions.IsSetuped();
|
|
ENUM_X_DIRECTION setupDir = mXIOBPVConditions.dir;
|
|
if (!isSetuped)
|
|
{
|
|
//
|
|
// Detect Signal Setup ...
|
|
isSetuped = DetectX121SMCXIOBPVSignalSetup(
|
|
symbol,
|
|
period,
|
|
mXIOBPVConditions,
|
|
mTriggerCycleHelper,
|
|
mDecisionCycleHelper,
|
|
mAnalyseCycleHelper,
|
|
mVerificationCycleHelper,
|
|
mConsolidationCycleHelper,
|
|
mVisionCycleHelper //
|
|
);
|
|
|
|
//
|
|
setupDir = mXIOBPVConditions.dir;
|
|
setupTime = mXIOBPVConditions.setupTime;
|
|
|
|
//
|
|
if (isSetuped)
|
|
{
|
|
//
|
|
int items = AddX121SMCXIOBPVConditionsIfNotExists(
|
|
mXIOBPVConditions,
|
|
mXIOBPVConditionsCollection //
|
|
);
|
|
|
|
//
|
|
mXIOBPVConditions.Clean();
|
|
}
|
|
}
|
|
|
|
//
|
|
int conditionsCount = ArraySize(mXIOBPVConditionsCollection);
|
|
result = IsValidSize(conditionsCount);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Looking For Conditions ...
|
|
int selectedIndex = 0;
|
|
X121SMCStrategyXIOBPVSignalConditions mTmpConditions[];
|
|
Copy(
|
|
mXIOBPVConditionsCollection,
|
|
mTmpConditions //
|
|
);
|
|
X121SMCStrategyXIOBPVSignalConditions mConditions;
|
|
for (int i = 0; i < conditionsCount; i++)
|
|
{
|
|
//
|
|
// Check Triggers ...
|
|
bool canTrigger = mTmpConditions[i].CanTrigger();
|
|
datetime triggerTime = mTmpConditions[i].triggerTime;
|
|
if (!canTrigger)
|
|
{
|
|
//
|
|
// Detect Signal Trigger ...
|
|
canTrigger = DetectX121SMCXIOBPVSignalTrigger(
|
|
mTmpConditions[i],
|
|
symbol,
|
|
period,
|
|
mTriggerCycleHelper,
|
|
mDecisionCycleHelper,
|
|
mAnalyseCycleHelper,
|
|
mVerificationCycleHelper,
|
|
mConsolidationCycleHelper,
|
|
mVisionCycleHelper //
|
|
);
|
|
|
|
//
|
|
result = canTrigger;
|
|
if (!result)
|
|
{
|
|
//
|
|
bool isISetuped = mTmpConditions[i].IsSetuped();
|
|
if (!isISetuped)
|
|
{
|
|
//
|
|
ArrayRemove(
|
|
mXIOBPVConditionsCollection,
|
|
i,
|
|
1 //
|
|
);
|
|
}
|
|
continue;
|
|
}
|
|
|
|
//
|
|
triggerTime = mTmpConditions[i].triggerTime;
|
|
}
|
|
|
|
//
|
|
if (canTrigger)
|
|
{
|
|
//
|
|
selectedIndex = i;
|
|
mConditions = mTmpConditions[i];
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
result = IsValid(mConditions.setupTime) &&
|
|
HasDirection(mConditions.dir);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Remove Selected Index from Main Collection ...
|
|
ArrayRemove(
|
|
mXIOBPVConditionsCollection,
|
|
selectedIndex,
|
|
1 //
|
|
);
|
|
|
|
//
|
|
// Check Signal Direction ...
|
|
isBullish = IsBullish(mConditions.dir);
|
|
isBearish = IsBearish(mConditions.dir);
|
|
result = isBullish ||
|
|
isBearish;
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Issues Signal on Conditions ...
|
|
conditions.sl = mConditions.sl;
|
|
conditions.provider = providerStr;
|
|
conditions.signalDir = mConditions.dir;
|
|
conditions.target = mConditions.target;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
|
|
const string X121SMCXHKPVToken = "X121XHKPV";
|
|
const string X121SMCXOBPVToken = "X121XOBPV";
|
|
const string X121SMCXIOBPVToken = "X121XIOBPV";
|
|
|
|
X_121_SMC_PROVIDER_XHKPV,
|
|
X_121_SMC_PROVIDER_XOBPV,
|
|
X_121_SMC_PROVIDER_XIOBPV,
|
|
|
|
|
|
//
|
|
case X_121_SMC_PROVIDER_XHKPV:
|
|
result = X121SMCXHKPVToken;
|
|
break;
|
|
|
|
//
|
|
case X_121_SMC_PROVIDER_XOBPV:
|
|
result = X121SMCXOBPVToken;
|
|
break;
|
|
|
|
//
|
|
case X_121_SMC_PROVIDER_XIOBPV:
|
|
result = X121SMCXIOBPVToken;
|
|
break;
|
|
|
|
else if (Contains(X121SMCXHKPVToken, value))
|
|
{
|
|
result = X_121_SMC_PROVIDER_XHKPV;
|
|
}
|
|
else if (Contains(X121SMCXOBPVToken, value))
|
|
{
|
|
result = X_121_SMC_PROVIDER_XOBPV;
|
|
}
|
|
else if (Contains(X121SMCXIOBPVToken, value))
|
|
{
|
|
result = X_121_SMC_PROVIDER_XIOBPV;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
/**
|
|
* Detect Market Structure Method 2 ...
|
|
*
|
|
* @param model: XMarketStructure instance Reference ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool DetectMarketStructure(
|
|
ENUM_X_DIRECTION &dir,
|
|
int pivotsCount = 3 //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
int barIndex = 0;
|
|
|
|
//
|
|
if (pivotsCount < 3)
|
|
{
|
|
pivotsCount = 3;
|
|
}
|
|
|
|
//
|
|
dir = X_DIRECTION_NONE;
|
|
string symbol = GetSymbol();
|
|
ENUM_TIMEFRAMES period = GetPeriod();
|
|
|
|
//
|
|
int hpIndex = -1;
|
|
int hpIndexes[];
|
|
double hpValues[];
|
|
|
|
//
|
|
int lvIndex = -1;
|
|
int lvIndexes[];
|
|
double lvValues[];
|
|
|
|
//
|
|
for (int i = 0; i < pivotsCount; i++)
|
|
{
|
|
//
|
|
hpIndex = barIndex;
|
|
lvIndex = barIndex;
|
|
|
|
//
|
|
double lastHP = 0;
|
|
double lastLV = 0;
|
|
|
|
//
|
|
int hpCount = ArraySize(hpIndexes);
|
|
int lvCount = ArraySize(lvIndexes);
|
|
|
|
//
|
|
if (IsValidSize(hpCount))
|
|
{
|
|
//
|
|
lastHP = hpValues[hpCount - 1];
|
|
hpIndex = hpIndexes[hpCount - 1];
|
|
}
|
|
|
|
//
|
|
if (IsValidSize(lvCount))
|
|
{
|
|
//
|
|
lastLV = lvValues[lvCount - 1];
|
|
lvIndex = lvIndexes[lvCount - 1];
|
|
}
|
|
|
|
//
|
|
if (lastHP == 0)
|
|
{
|
|
//
|
|
lastHP = mX121Helper
|
|
.xpvHelper
|
|
.GetPeak(hpIndex);
|
|
}
|
|
|
|
//
|
|
if (lastLV == 0)
|
|
{
|
|
//
|
|
lastLV = mX121Helper
|
|
.xpvHelper
|
|
.GetVale(lvIndex);
|
|
}
|
|
|
|
//
|
|
int highestPeakIndex = -1;
|
|
double highesrPeak =
|
|
mX121Helper
|
|
.xpvHelper
|
|
.GetHigherPeak(
|
|
highestPeakIndex,
|
|
lastHP,
|
|
hpIndex //
|
|
);
|
|
if (IsValidIndex(highestPeakIndex))
|
|
{
|
|
//
|
|
Add(
|
|
highestPeakIndex,
|
|
hpIndexes //
|
|
);
|
|
|
|
//
|
|
Add(
|
|
highesrPeak,
|
|
hpValues //
|
|
);
|
|
}
|
|
|
|
//
|
|
int lowestValeIndex = -1;
|
|
double lowestVale =
|
|
mX121Helper
|
|
.xpvHelper
|
|
.GetLowerVale(
|
|
lowestValeIndex,
|
|
lastLV,
|
|
lvIndex //
|
|
);
|
|
if (IsValidIndex(lowestValeIndex))
|
|
{
|
|
//
|
|
Add(
|
|
lowestValeIndex,
|
|
lvIndexes //
|
|
);
|
|
|
|
//
|
|
Add(
|
|
lowestVale,
|
|
lvValues //
|
|
);
|
|
}
|
|
|
|
//
|
|
bool canBreak = ArraySize(hpIndexes) >= pivotsCount ||
|
|
ArraySize(lvIndexes) >= pivotsCount;
|
|
if (canBreak)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
ArrayReverse(hpValues);
|
|
ArrayReverse(hpIndexes);
|
|
int countHPs = ArraySize(hpIndexes);
|
|
|
|
//
|
|
ArrayReverse(lvValues);
|
|
ArrayReverse(lvIndexes);
|
|
int countLVs = ArraySize(lvIndexes);
|
|
|
|
//
|
|
bool isValidHPs = countHPs >= pivotsCount;
|
|
bool isValidLVs = countLVs >= pivotsCount;
|
|
|
|
//
|
|
result = isValidHPs ||
|
|
isValidLVs;
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
if (isValidHPs && isValidLVs)
|
|
{
|
|
//
|
|
hpIndex = hpIndexes[countHPs - 1];
|
|
lvIndex = lvIndexes[countLVs - 1];
|
|
}
|
|
|
|
//
|
|
dir =
|
|
!isValidHPs && isValidLVs
|
|
? X_DIRECTION_BULLISH
|
|
: !isValidLVs && isValidHPs
|
|
? X_DIRECTION_BEARISH
|
|
: hpIndex < lvIndex
|
|
? X_DIRECTION_BEARISH
|
|
: lvIndex < hpIndex
|
|
? X_DIRECTION_BULLISH
|
|
: X_DIRECTION_ALL;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Detect Order Blocks ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool DetectOrderBlocks(
|
|
XCOrderBlock *&bullishOrderBlocks[],
|
|
XCOrderBlock *&bearishOrderBlocks[] //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
Clean(bullishOrderBlocks);
|
|
Clean(bearishOrderBlocks);
|
|
|
|
//
|
|
XPOIState state;
|
|
mPOIDetector.GetState(state);
|
|
bool isValid = state.IsValid() &&
|
|
state.HasChild();
|
|
if (!isValid)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
int bullOBsCount = DetectValidOrderBlocks(
|
|
X_DIRECTION_BULLISH,
|
|
state,
|
|
bullishOrderBlocks //
|
|
);
|
|
|
|
//
|
|
int bearOBsCount = DetectValidOrderBlocks(
|
|
X_DIRECTION_BEARISH,
|
|
state,
|
|
bearishOrderBlocks //
|
|
);
|
|
|
|
//
|
|
result = IsValidSize(bullOBsCount +
|
|
bearOBsCount);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Detect Fair Value Gaps ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool DetectFairValueGaps(
|
|
XCFVG *&bullishFairValueGaps[],
|
|
XCFVG *&bearishFairValueGaps[] //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
Clean(bullishFairValueGaps);
|
|
Clean(bearishFairValueGaps);
|
|
|
|
//
|
|
XPOIState state;
|
|
mPOIDetector.GetState(state);
|
|
bool isValid = state.IsValid() &&
|
|
state.HasChild();
|
|
if (!isValid)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
int bullFVGsCount = DetectValidFairValueGaps(
|
|
X_DIRECTION_BULLISH,
|
|
state,
|
|
bullishFairValueGaps //
|
|
);
|
|
|
|
//
|
|
int bearFVGsCount = DetectValidFairValueGaps(
|
|
X_DIRECTION_BEARISH,
|
|
state,
|
|
bearishFairValueGaps //
|
|
);
|
|
|
|
//
|
|
result = IsValidSize(bullFVGsCount +
|
|
bearFVGsCount);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Detect Support Zones ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool DetectSupportZones(
|
|
XCOrderBlock *&bullishOrderBlocks[],
|
|
XCFVG *&bullishFairValueGaps[],
|
|
XCSupportZone *&supportZones[] //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
Clean(supportZones);
|
|
|
|
//
|
|
int obsCount = ArraySize(bullishOrderBlocks);
|
|
int fvgsCount = ArraySize(bullishFairValueGaps);
|
|
|
|
//
|
|
XPOIState state;
|
|
mPOIDetector.GetState(state);
|
|
bool isValid = state.IsValid() &&
|
|
state.HasChild() &&
|
|
IsValidSize(obsCount + fvgsCount);
|
|
if (!isValid)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
int supportZonesCount = DetectValidSupportZones(
|
|
state,
|
|
bullishOrderBlocks,
|
|
bullishFairValueGaps,
|
|
supportZones //
|
|
);
|
|
|
|
//
|
|
result = IsValidSize(supportZonesCount);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Detect Resistance Zones ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool DetectResistanceZones(
|
|
XCOrderBlock *&bearishOrderBlocks[],
|
|
XCFVG *&bearishFairValueGaps[],
|
|
XCResistanceZone *&resistanceZones[] //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
Clean(resistanceZones);
|
|
|
|
//
|
|
int obsCount = ArraySize(bearishOrderBlocks);
|
|
int fvgsCount = ArraySize(bearishFairValueGaps);
|
|
|
|
//
|
|
XPOIState state;
|
|
mPOIDetector.GetState(state);
|
|
bool isValid = state.IsValid() &&
|
|
state.HasChild() &&
|
|
IsValidSize(obsCount + fvgsCount);
|
|
if (!isValid)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
int resistanceZonesCount = DetectValidResistanceZones(
|
|
state,
|
|
bearishOrderBlocks,
|
|
bearishFairValueGaps,
|
|
resistanceZones //
|
|
);
|
|
|
|
//
|
|
result = IsValidSize(resistanceZonesCount);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Detect Demand Zones ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool DetectDemandZones(
|
|
XCOrderBlock *&bullishOrderBlocks[],
|
|
XCFVG *&bullishFairValueGaps[],
|
|
XCDemandZone *&demandZones[] //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
Clean(demandZones);
|
|
|
|
//
|
|
int obsCount = ArraySize(bullishOrderBlocks);
|
|
int fvgsCount = ArraySize(bullishFairValueGaps);
|
|
|
|
//
|
|
XPOIState state;
|
|
mPOIDetector.GetState(state);
|
|
bool isValid = state.IsValid() &&
|
|
state.HasChild() &&
|
|
IsValidSize(obsCount + fvgsCount);
|
|
if (!isValid)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
int demandZonesCount = DetectValidDemandZones(
|
|
state,
|
|
bullishOrderBlocks,
|
|
bullishFairValueGaps,
|
|
demandZones //
|
|
);
|
|
|
|
//
|
|
result = IsValidSize(demandZonesCount);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Detect Supply Zones ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool DetectSupplyZones(
|
|
XCOrderBlock *&bearishOrderBlocks[],
|
|
XCFVG *&bearishFairValueGaps[],
|
|
XCSupplyZone *&supplyZones[] //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
Clean(supplyZones);
|
|
|
|
//
|
|
int obsCount = ArraySize(bearishOrderBlocks);
|
|
int fvgsCount = ArraySize(bearishFairValueGaps);
|
|
|
|
//
|
|
XPOIState state;
|
|
mPOIDetector.GetState(state);
|
|
bool isValid = state.IsValid() &&
|
|
state.HasChild() &&
|
|
IsValidSize(obsCount + fvgsCount);
|
|
if (!isValid)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
int supplyZonesCount = DetectValidSupplyZones(
|
|
state,
|
|
bearishOrderBlocks,
|
|
bearishFairValueGaps,
|
|
supplyZones //
|
|
);
|
|
|
|
//
|
|
result = IsValidSize(supplyZonesCount);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Count Prev Peak Repetition ...
|
|
*
|
|
* @param barIndex: Integer ...
|
|
*
|
|
* @return ( int )
|
|
*/
|
|
int CountPrevPeakRepetition(
|
|
int barIndex = 0//
|
|
) {
|
|
//
|
|
int result = 0;
|
|
|
|
//
|
|
if (barIndex < 0) {
|
|
barIndex = 0;
|
|
}
|
|
|
|
//
|
|
int index = barIndex + 1;
|
|
double value = mX121Helper.xpvHelper.GetPeak(index);
|
|
index++;
|
|
|
|
//
|
|
bool canContinue = true;
|
|
while(canContinue) {
|
|
//
|
|
double iValue = mX121Helper.xpvHelper.GetPeak(index);
|
|
|
|
//
|
|
canContinue = iValue == value;
|
|
if (canContinue) {
|
|
//
|
|
index++;
|
|
result++;
|
|
}
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Count Prev Vale Repetition ...
|
|
*
|
|
* @param barIndex: Integer ...
|
|
*
|
|
* @return ( int )
|
|
*/
|
|
int CountPrevValeRepetition(
|
|
int barIndex = 0//
|
|
) {
|
|
//
|
|
int result = 0;
|
|
|
|
//
|
|
if (barIndex < 0) {
|
|
barIndex = 0;
|
|
}
|
|
|
|
//
|
|
int index = barIndex + 1;
|
|
double value = mX121Helper.xpvHelper.GetVale(index);
|
|
index++;
|
|
|
|
//
|
|
bool canContinue = true;
|
|
while(canContinue) {
|
|
//
|
|
double iValue = mX121Helper.xpvHelper.GetVale(index);
|
|
|
|
//
|
|
canContinue = iValue == value;
|
|
if (canContinue) {
|
|
//
|
|
index++;
|
|
result++;
|
|
}
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Get Cycle State and Update it ...
|
|
*
|
|
* @param state: X121SMCCycleState instance Reference ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool GetCycleState(X121SMCCycleState &state)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
string symbol = GetSymbol();
|
|
ENUM_TIMEFRAMES period = GetPeriod();
|
|
|
|
//
|
|
state.symbol = symbol;
|
|
state.period = period;
|
|
|
|
//
|
|
datetime cTime = TimeCurrent();
|
|
|
|
//
|
|
// Detect Order Block ...
|
|
|
|
//
|
|
bool hasBullishOBs = state.HasBullishOBs();
|
|
int bullishOBsCount = state.CountBullishOBs();
|
|
|
|
//
|
|
bool hasBearishOBs = state.HasBearishOBs();
|
|
int bearishOBsCount = state.CountBearishOBs();
|
|
|
|
//
|
|
bool hasOBs = hasBullishOBs &&
|
|
hasBearishOBs;
|
|
if (!hasOBs)
|
|
{
|
|
//
|
|
XCOrderBlock *bullishOBs[];
|
|
XCOrderBlock *bearishOBs[];
|
|
hasOBs = DetectOrderBlocks(
|
|
bullishOBs,
|
|
bearishOBs //
|
|
);
|
|
|
|
//
|
|
if (hasOBs &&
|
|
!hasBullishOBs)
|
|
{
|
|
//
|
|
Copy(
|
|
bullishOBs,
|
|
state.bullishOBs //
|
|
);
|
|
}
|
|
|
|
//
|
|
if (hasOBs &&
|
|
!hasBearishOBs)
|
|
{
|
|
//
|
|
Copy(
|
|
bearishOBs,
|
|
state.bearishOBs //
|
|
);
|
|
}
|
|
|
|
//
|
|
hasBullishOBs = state.HasBullishOBs();
|
|
bullishOBsCount = state.CountBullishOBs();
|
|
|
|
//
|
|
hasBearishOBs = state.HasBearishOBs();
|
|
bearishOBsCount = state.CountBearishOBs();
|
|
}
|
|
|
|
//
|
|
// Update Order Blocks Time ...
|
|
if (hasOBs)
|
|
{
|
|
//
|
|
if (hasBullishOBs)
|
|
{
|
|
//
|
|
for (int i = 0; i < bullishOBsCount; i++)
|
|
{
|
|
state.bullishOBs[i].To(cTime);
|
|
}
|
|
}
|
|
|
|
//
|
|
if (hasBearishOBs)
|
|
{
|
|
//
|
|
for (int i = 0; i < bearishOBsCount; i++)
|
|
{
|
|
state.bearishOBs[i].To(cTime);
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// Detect Fair Value Gap ...
|
|
|
|
//
|
|
bool hasBullishFVGs = state.HasBullishFVGs();
|
|
int bullishFVGsCount = state.CountBullishFVGs();
|
|
|
|
//
|
|
bool hasBearishFVGs = state.HasBearishFVGs();
|
|
int bearishFVGsCount = state.CountBearishFVGs();
|
|
|
|
//
|
|
bool hasFVGs = hasBullishFVGs &&
|
|
hasBearishFVGs;
|
|
if (!hasFVGs)
|
|
{
|
|
//
|
|
XCFVG *bullishFVGs[];
|
|
XCFVG *bearishFVGs[];
|
|
hasFVGs = DetectFairValueGaps(
|
|
bullishFVGs,
|
|
bearishFVGs //
|
|
);
|
|
|
|
//
|
|
if (hasFVGs &&
|
|
!hasBullishFVGs)
|
|
{
|
|
//
|
|
Copy(
|
|
bullishFVGs,
|
|
state.bullishFVGs //
|
|
);
|
|
}
|
|
|
|
//
|
|
if (hasFVGs &&
|
|
!hasBearishFVGs)
|
|
{
|
|
//
|
|
Copy(
|
|
bearishFVGs,
|
|
state.bearishFVGs //
|
|
);
|
|
}
|
|
|
|
//
|
|
hasBullishFVGs = state.HasBullishFVGs();
|
|
bullishFVGsCount = state.CountBullishFVGs();
|
|
|
|
//
|
|
hasBearishFVGs = state.HasBearishFVGs();
|
|
bearishFVGsCount = state.CountBearishFVGs();
|
|
}
|
|
|
|
//
|
|
// Update Fair Value Gaps Time ...
|
|
if (hasFVGs)
|
|
{
|
|
//
|
|
if (hasBullishFVGs)
|
|
{
|
|
//
|
|
for (int i = 0; i < bullishFVGsCount; i++)
|
|
{
|
|
state.bullishFVGs[i].To(cTime);
|
|
}
|
|
}
|
|
|
|
//
|
|
if (hasBearishFVGs)
|
|
{
|
|
//
|
|
for (int i = 0; i < bearishFVGsCount; i++)
|
|
{
|
|
state.bearishFVGs[i].To(cTime);
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// Detect Support Zones ...
|
|
|
|
//
|
|
bool hasSupportZones = state.HasSupportZones();
|
|
int supportZonesCount = state.CountSupportZones();
|
|
|
|
//
|
|
if (!hasSupportZones)
|
|
{
|
|
//
|
|
XCSupportZone *supportZones[];
|
|
hasSupportZones = DetectSupportZones(
|
|
state.bullishOBs,
|
|
state.bullishFVGs,
|
|
supportZones //
|
|
);
|
|
|
|
//
|
|
if (hasSupportZones)
|
|
{
|
|
//
|
|
Copy(
|
|
supportZones,
|
|
state.supportZones //
|
|
);
|
|
|
|
//
|
|
supportZonesCount = state.CountSupportZones();
|
|
}
|
|
}
|
|
|
|
//
|
|
// Update Support Zones Time ...
|
|
if (hasSupportZones)
|
|
{
|
|
//
|
|
for (int i = 0; i < supportZonesCount; i++)
|
|
{
|
|
state.supportZones[i].To(cTime);
|
|
}
|
|
}
|
|
|
|
//
|
|
// Detect Demand Zones ...
|
|
|
|
//
|
|
bool hasDemandZones = state.HasDemandZones();
|
|
int demandZonesCount = state.CountDemandZones();
|
|
|
|
//
|
|
if (!hasDemandZones)
|
|
{
|
|
//
|
|
XCDemandZone *demandZones[];
|
|
hasDemandZones = DetectDemandZones(
|
|
state.bullishOBs,
|
|
state.bullishFVGs,
|
|
demandZones //
|
|
);
|
|
|
|
//
|
|
if (hasDemandZones)
|
|
{
|
|
//
|
|
Copy(
|
|
demandZones,
|
|
state.demandZones //
|
|
);
|
|
|
|
//
|
|
demandZonesCount = state.CountDemandZones();
|
|
}
|
|
}
|
|
|
|
//
|
|
// Update Support Zones Time ...
|
|
if (hasDemandZones)
|
|
{
|
|
//
|
|
for (int i = 0; i < demandZonesCount; i++)
|
|
{
|
|
state.demandZones[i].To(cTime);
|
|
}
|
|
}
|
|
|
|
//
|
|
// Detect Resistance Zones ...
|
|
|
|
//
|
|
bool hasResistanceZones = state.HasResistanceZones();
|
|
int resistanceZonesCount = state.CountResistanceZones();
|
|
|
|
//
|
|
if (!hasResistanceZones)
|
|
{
|
|
//
|
|
XCResistanceZone *resistanceZones[];
|
|
hasResistanceZones = DetectResistanceZones(
|
|
state.bearishOBs,
|
|
state.bearishFVGs,
|
|
resistanceZones //
|
|
);
|
|
|
|
//
|
|
if (hasResistanceZones)
|
|
{
|
|
//
|
|
for (int i = 0; i < ArraySize(resistanceZones); i++)
|
|
{
|
|
resistanceZones[i].To(cTime);
|
|
}
|
|
|
|
//
|
|
Copy(
|
|
resistanceZones,
|
|
state.resistanceZones //
|
|
);
|
|
|
|
//
|
|
resistanceZonesCount = state.CountResistanceZones();
|
|
}
|
|
}
|
|
|
|
//
|
|
// Update Resistance Zones Time ...
|
|
if (hasResistanceZones)
|
|
{
|
|
//
|
|
for (int i = 0; i < resistanceZonesCount; i++)
|
|
{
|
|
state.resistanceZones[i].To(cTime);
|
|
}
|
|
}
|
|
|
|
//
|
|
// Detect Supply Zones ...
|
|
|
|
//
|
|
bool hasSupplyZones = state.HasSupplyZones();
|
|
int supplyZonesCount = state.CountSupplyZones();
|
|
|
|
//
|
|
if (!hasSupplyZones)
|
|
{
|
|
//
|
|
XCSupplyZone *supplyZones[];
|
|
hasSupplyZones = DetectSupplyZones(
|
|
state.bearishOBs,
|
|
state.bearishFVGs,
|
|
supplyZones //
|
|
);
|
|
|
|
//
|
|
if (hasSupplyZones)
|
|
{
|
|
//
|
|
Copy(
|
|
supplyZones,
|
|
state.supplyZones //
|
|
);
|
|
|
|
//
|
|
supplyZonesCount = state.CountSupplyZones();
|
|
}
|
|
}
|
|
|
|
//
|
|
// Update Resistance Zones Time ...
|
|
if (hasSupplyZones)
|
|
{
|
|
//
|
|
for (int i = 0; i < supplyZonesCount; i++)
|
|
{
|
|
state.supplyZones[i].To(cTime);
|
|
}
|
|
}
|
|
|
|
//
|
|
result = state.IsValid();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
|
|
//
|
|
// Model Cycle State ...
|
|
struct X121SMCCycleState
|
|
{
|
|
//
|
|
// Props ...
|
|
string symbol;
|
|
ENUM_TIMEFRAMES period;
|
|
|
|
//
|
|
// Bullish ...
|
|
XCFVG *bullishFVGs[];
|
|
XCOrderBlock *bullishOBs[];
|
|
XCDemandZone *demandZones[];
|
|
XCSupportZone *supportZones[];
|
|
|
|
//
|
|
// Bearish ...
|
|
XCFVG *bearishFVGs[];
|
|
XCOrderBlock *bearishOBs[];
|
|
XCSupplyZone *supplyZones[];
|
|
XCResistanceZone *resistanceZones[];
|
|
|
|
//
|
|
// Constructor ...
|
|
X121SMCCycleState()
|
|
{
|
|
Clean();
|
|
}
|
|
|
|
//
|
|
// Tools ...
|
|
|
|
/**
|
|
* Cleanup Model ...
|
|
*/
|
|
void Clean()
|
|
{
|
|
//
|
|
symbol = NULL;
|
|
period = NULL;
|
|
|
|
//
|
|
Clean(bullishFVGs);
|
|
Clean(bullishOBs);
|
|
Clean(demandZones);
|
|
Clean(supportZones);
|
|
|
|
//
|
|
Clean(bearishFVGs);
|
|
Clean(bearishOBs);
|
|
Clean(supplyZones);
|
|
Clean(resistanceZones);
|
|
|
|
//
|
|
ZeroMemory(this);
|
|
}
|
|
|
|
/**
|
|
* Validate Model ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool IsValid()
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
result =
|
|
//
|
|
IsValid(symbol) &&
|
|
IsValid(period) &&
|
|
(
|
|
//
|
|
(HasBullishOBs() &&
|
|
(HasBullishFVGs() ||
|
|
HasSupportZones() ||
|
|
HasDemandZones()))
|
|
//
|
|
||
|
|
(HasBearishOBs() &&
|
|
(HasSupplyZones() ||
|
|
HasBearishFVGs() ||
|
|
HasResistanceZones()))
|
|
//
|
|
)
|
|
//
|
|
;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
int CountBullishOBs()
|
|
{
|
|
return ArraySize(bullishOBs);
|
|
}
|
|
|
|
//
|
|
bool HasBullishOBs()
|
|
{
|
|
return IsValidSize(CountBullishOBs());
|
|
}
|
|
|
|
//
|
|
int CountBearishOBs()
|
|
{
|
|
return ArraySize(bearishOBs);
|
|
}
|
|
|
|
//
|
|
bool HasBearishOBs()
|
|
{
|
|
return IsValidSize(CountBearishOBs());
|
|
}
|
|
|
|
//
|
|
int CountSupportZones()
|
|
{
|
|
return ArraySize(supportZones);
|
|
}
|
|
|
|
//
|
|
bool HasSupportZones()
|
|
{
|
|
return IsValidSize(CountSupportZones());
|
|
}
|
|
|
|
//
|
|
int CountResistanceZones()
|
|
{
|
|
return ArraySize(resistanceZones);
|
|
}
|
|
|
|
//
|
|
bool HasResistanceZones()
|
|
{
|
|
return IsValidSize(CountResistanceZones());
|
|
}
|
|
|
|
//
|
|
int CountDemandZones()
|
|
{
|
|
return ArraySize(demandZones);
|
|
}
|
|
|
|
//
|
|
bool HasDemandZones()
|
|
{
|
|
return IsValidSize(CountDemandZones());
|
|
}
|
|
|
|
//
|
|
int CountSupplyZones()
|
|
{
|
|
return ArraySize(supplyZones);
|
|
}
|
|
|
|
//
|
|
bool HasSupplyZones()
|
|
{
|
|
return IsValidSize(CountSupplyZones());
|
|
}
|
|
|
|
//
|
|
int CountBullishFVGs()
|
|
{
|
|
return ArraySize(bullishFVGs);
|
|
}
|
|
|
|
//
|
|
bool HasBullishFVGs()
|
|
{
|
|
return IsValidSize(CountBullishFVGs());
|
|
}
|
|
|
|
//
|
|
int CountBearishFVGs()
|
|
{
|
|
return ArraySize(bearishFVGs);
|
|
}
|
|
|
|
//
|
|
bool HasBearishFVGs()
|
|
{
|
|
return IsValidSize(CountBearishFVGs());
|
|
}
|
|
|
|
//
|
|
bool GetOldestOB(
|
|
XCOrderBlock *&orderBlock //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
orderBlock = NULL;
|
|
|
|
//
|
|
bool hasBullishOB = HasBullishOBs();
|
|
bool hasBearishOB = HasBearishOBs();
|
|
result = hasBullishOB ||
|
|
hasBearishOB;
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
int iBullOBIDX = -1;
|
|
bool iHasBullOB = false;
|
|
XCOrderBlock *iBullOB = NULL;
|
|
if (hasBullishOB)
|
|
{
|
|
//
|
|
XCZone *iZones[];
|
|
ToZone(
|
|
bullishOBs,
|
|
iZones //
|
|
);
|
|
|
|
//
|
|
iBullOBIDX = GetOldest(
|
|
iZones //
|
|
);
|
|
|
|
//
|
|
iHasBullOB = IsValidIndex(iBullOBIDX);
|
|
if (iHasBullOB)
|
|
{
|
|
iBullOB = bullishOBs[iBullOBIDX];
|
|
}
|
|
}
|
|
|
|
//
|
|
int iBearOBIDX = -1;
|
|
bool iHasBearOB = false;
|
|
XCOrderBlock *iBearOB = NULL;
|
|
if (hasBearishOB)
|
|
{
|
|
//
|
|
XCZone *iZones[];
|
|
ToZone(
|
|
bearishOBs,
|
|
iZones //
|
|
);
|
|
|
|
//
|
|
iBearOBIDX = GetOldest(
|
|
iZones //
|
|
);
|
|
|
|
//
|
|
iHasBearOB = IsValidIndex(iBearOBIDX);
|
|
if (iHasBearOB)
|
|
{
|
|
iBearOB = bearishOBs[iBearOBIDX];
|
|
}
|
|
}
|
|
|
|
//
|
|
if (iHasBullOB)
|
|
{
|
|
orderBlock = iBullOB;
|
|
}
|
|
|
|
//
|
|
if (iHasBearOB)
|
|
{
|
|
//
|
|
bool canSet = orderBlock == NULL ||
|
|
orderBlock.From() > iBearOB.From();
|
|
if (canSet)
|
|
{
|
|
orderBlock = iBearOB;
|
|
}
|
|
}
|
|
|
|
//
|
|
result = orderBlock != NULL &&
|
|
orderBlock.IsValid();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
bool GetYoungestOB(
|
|
XCOrderBlock *&orderBlock //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
orderBlock = NULL;
|
|
|
|
//
|
|
bool hasBullishOB = HasBullishOBs();
|
|
bool hasBearishOB = HasBearishOBs();
|
|
result = hasBullishOB ||
|
|
hasBearishOB;
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
int iBullOBIDX = -1;
|
|
bool iHasBullOB = false;
|
|
XCOrderBlock *iBullOB = NULL;
|
|
if (hasBullishOB)
|
|
{
|
|
//
|
|
XCZone *iZones[];
|
|
ToZone(
|
|
bullishOBs,
|
|
iZones //
|
|
);
|
|
|
|
//
|
|
iBullOBIDX = GetYoungest(
|
|
iZones //
|
|
);
|
|
|
|
//
|
|
iHasBullOB = IsValidIndex(iBullOBIDX);
|
|
if (iHasBullOB)
|
|
{
|
|
iBullOB = bullishOBs[iBullOBIDX];
|
|
}
|
|
}
|
|
|
|
//
|
|
int iBearOBIDX = -1;
|
|
bool iHasBearOB = false;
|
|
XCOrderBlock *iBearOB = NULL;
|
|
if (hasBearishOB)
|
|
{
|
|
//
|
|
XCZone *iZones[];
|
|
ToZone(
|
|
bearishOBs,
|
|
iZones //
|
|
);
|
|
|
|
//
|
|
iBearOBIDX = GetYoungest(
|
|
iZones //
|
|
);
|
|
|
|
//
|
|
iHasBearOB = IsValidIndex(iBearOBIDX);
|
|
if (iHasBearOB)
|
|
{
|
|
iBearOB = bearishOBs[iBearOBIDX];
|
|
}
|
|
}
|
|
|
|
//
|
|
if (iHasBullOB)
|
|
{
|
|
orderBlock = iBullOB;
|
|
}
|
|
|
|
//
|
|
if (iHasBearOB)
|
|
{
|
|
//
|
|
bool canSet = orderBlock == NULL ||
|
|
orderBlock.From() < iBearOB.From();
|
|
if (canSet)
|
|
{
|
|
orderBlock = iBearOB;
|
|
}
|
|
}
|
|
|
|
//
|
|
result = orderBlock != NULL &&
|
|
orderBlock.IsValid();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
};
|
|
|
|
|
|
/**
|
|
* Detect Price inside Box ...
|
|
*
|
|
* @param box: XBoxZone instance Reference, Founded Price Inside Box ...
|
|
* @param orderBlock: XCOrderBlock pointer Reference, Founded Price Inside Order Block ...
|
|
* @param xConditions: X121Conditions instance Reference, provides Market Conditions ...
|
|
* @param state: X121SMCCycleState instance Reference ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool DetectPriceInsideBox(
|
|
XBoxZone &box, // Price Inside Bo ...
|
|
XCOrderBlock *&orderBlock, // Price Inside Order Block ...
|
|
X121Conditions &xConditions, // X121Conditions for Validation ...
|
|
X121SMCCycleState &state // Cycle State ...
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
box.Clean();
|
|
|
|
//
|
|
string symbol = state.symbol;
|
|
ENUM_TIMEFRAMES period = state.period;
|
|
|
|
//
|
|
box.symbol = symbol;
|
|
box.period = period;
|
|
|
|
//
|
|
result = state.IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Detect Price Inside Order Block ...
|
|
|
|
//
|
|
bool hasBullishOBs = state.HasBullishOBs();
|
|
int bullishOBsCount = state.CountBullishOBs();
|
|
|
|
//
|
|
bool hasBearishOBs = state.HasBearishOBs();
|
|
int bearishOBsCount = state.CountBearishOBs();
|
|
|
|
//
|
|
bool hasOBs =
|
|
//
|
|
hasBullishOBs ||
|
|
hasBearishOBs
|
|
//
|
|
;
|
|
result = hasOBs;
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
bool hasPriceInsideOB = false;
|
|
XCOrderBlock *priceInsideOB = NULL;
|
|
ENUM_X_DIRECTION boxDir = X_DIRECTION_NONE;
|
|
|
|
//
|
|
if (hasBullishOBs &&
|
|
!hasPriceInsideOB)
|
|
{
|
|
//
|
|
for (int i = 0; i < bullishOBsCount; i++)
|
|
{
|
|
//
|
|
XCOrderBlock *iOb = state.bullishOBs[i];
|
|
|
|
//
|
|
bool isInside = IsPriceInsideZone(
|
|
xConditions.valesBuffer[1],
|
|
(XCZone *)iOb //
|
|
);
|
|
if (isInside)
|
|
{
|
|
//
|
|
priceInsideOB = iOb;
|
|
hasPriceInsideOB = true;
|
|
boxDir = X_DIRECTION_BULLISH;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
if (hasBearishOBs &&
|
|
!hasPriceInsideOB)
|
|
{
|
|
//
|
|
for (int i = 0; i < bearishOBsCount; i++)
|
|
{
|
|
//
|
|
XCOrderBlock *iOb = state.bearishOBs[i];
|
|
|
|
//
|
|
bool isInside = IsPriceInsideZone(
|
|
xConditions.peaksBuffer[1],
|
|
(XCZone *)iOb //
|
|
);
|
|
if (isInside)
|
|
{
|
|
//
|
|
priceInsideOB = iOb;
|
|
hasPriceInsideOB = true;
|
|
boxDir = X_DIRECTION_BEARISH;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
if (hasPriceInsideOB)
|
|
{
|
|
//
|
|
orderBlock = priceInsideOB;
|
|
boxDir = priceInsideOB.IsBullish()
|
|
? X_DIRECTION_BULLISH
|
|
: priceInsideOB.IsBearish()
|
|
? X_DIRECTION_BEARISH
|
|
: X_DIRECTION_NONE;
|
|
}
|
|
|
|
//
|
|
bool hasBullishFVGs = state.HasBullishFVGs();
|
|
bool hasBearishFVGs = state.HasBearishFVGs();
|
|
bool hasDemandZones = state.HasDemandZones();
|
|
bool hasSupplyZones = state.HasSupplyZones();
|
|
bool hasSupportZones = state.HasSupportZones();
|
|
bool hasResistanceZones = state.HasResistanceZones();
|
|
|
|
//
|
|
bool hasBullishZones =
|
|
//
|
|
hasBullishFVGs ||
|
|
hasDemandZones ||
|
|
hasSupportZones
|
|
//
|
|
;
|
|
|
|
//
|
|
bool hasBearishZones =
|
|
//
|
|
hasBearishFVGs ||
|
|
hasSupplyZones ||
|
|
hasResistanceZones
|
|
//
|
|
;
|
|
|
|
//
|
|
bool hasPropperZones =
|
|
//
|
|
IsBullish(boxDir)
|
|
? hasBullishZones
|
|
: IsBearish(boxDir)
|
|
? hasBearishZones
|
|
: false
|
|
//
|
|
;
|
|
|
|
//
|
|
if (!hasPropperZones &&
|
|
hasPriceInsideOB)
|
|
{
|
|
//
|
|
// Use Price Inside OB as Box ...
|
|
box.dir = boxDir;
|
|
box.to = priceInsideOB.To();
|
|
box.from = priceInsideOB.From();
|
|
box.upper = priceInsideOB.Upper();
|
|
box.lower = priceInsideOB.Lower();
|
|
}
|
|
else if (hasPropperZones &&
|
|
hasPriceInsideOB)
|
|
{
|
|
//
|
|
// Detect Validate Zones ...
|
|
int count = 0;
|
|
XBoxZone boxes[];
|
|
double upper = 0;
|
|
double lower = 0;
|
|
double price = 0;
|
|
datetime to = NULL;
|
|
datetime from = NULL;
|
|
ENUM_X_DIRECTION dir = X_DIRECTION_NONE;
|
|
if (IsBullish(boxDir))
|
|
{
|
|
//
|
|
double price = xConditions.valesBuffer[1];
|
|
dir = X_DIRECTION_BULLISH;
|
|
|
|
//
|
|
// Bullish FVG ...
|
|
count = state.CountBullishFVGs();
|
|
for (int i = 0; i < count; i++)
|
|
{
|
|
//
|
|
XCFVG *iFVG = state.bullishFVGs[i];
|
|
|
|
//
|
|
to = iFVG.To();
|
|
from = iFVG.From();
|
|
upper = iFVG.Upper();
|
|
lower = iFVG.Lower();
|
|
|
|
//
|
|
bool isInside = IsPriceInsideZone(
|
|
price,
|
|
upper,
|
|
lower //
|
|
);
|
|
if (isInside)
|
|
{
|
|
//
|
|
XBoxZone iBox;
|
|
|
|
//
|
|
iBox.dir = dir;
|
|
iBox.symbol = symbol;
|
|
iBox.period = period;
|
|
|
|
//
|
|
iBox.to = to;
|
|
iBox.from = from;
|
|
iBox.upper = upper;
|
|
iBox.lower = lower;
|
|
|
|
//
|
|
if (iBox.IsValid())
|
|
{
|
|
//
|
|
AddRef(
|
|
iBox,
|
|
boxes //
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// Demand Zones ...
|
|
count = state.CountDemandZones();
|
|
for (int i = 0; i < count; i++)
|
|
{
|
|
//
|
|
XCDemandZone *iDemand = state.demandZones[i];
|
|
|
|
//
|
|
to = iDemand.To();
|
|
from = iDemand.From();
|
|
upper = iDemand.Upper();
|
|
lower = iDemand.Lower();
|
|
|
|
//
|
|
bool isInside = IsPriceInsideZone(
|
|
price,
|
|
upper,
|
|
lower //
|
|
);
|
|
if (isInside)
|
|
{
|
|
//
|
|
XBoxZone iBox;
|
|
|
|
//
|
|
iBox.dir = dir;
|
|
iBox.symbol = symbol;
|
|
iBox.period = period;
|
|
|
|
//
|
|
iBox.to = to;
|
|
iBox.from = from;
|
|
iBox.upper = upper;
|
|
iBox.lower = lower;
|
|
|
|
//
|
|
if (iBox.IsValid())
|
|
{
|
|
//
|
|
AddRef(
|
|
iBox,
|
|
boxes //
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// Support Zones ...
|
|
count = state.CountSupportZones();
|
|
for (int i = 0; i < count; i++)
|
|
{
|
|
//
|
|
XCSupportZone *iSupport = state.supportZones[i];
|
|
|
|
//
|
|
to = iSupport.To();
|
|
from = iSupport.From();
|
|
upper = iSupport.Upper();
|
|
lower = iSupport.Lower();
|
|
|
|
//
|
|
bool isInside = IsPriceInsideZone(
|
|
price,
|
|
upper,
|
|
lower //
|
|
);
|
|
if (isInside)
|
|
{
|
|
//
|
|
XBoxZone iBox;
|
|
|
|
//
|
|
iBox.dir = dir;
|
|
iBox.symbol = symbol;
|
|
iBox.period = period;
|
|
|
|
//
|
|
iBox.to = to;
|
|
iBox.from = from;
|
|
iBox.upper = upper;
|
|
iBox.lower = lower;
|
|
|
|
//
|
|
if (iBox.IsValid())
|
|
{
|
|
//
|
|
AddRef(
|
|
iBox,
|
|
boxes //
|
|
);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//
|
|
double price = xConditions.peaksBuffer[1];
|
|
dir = X_DIRECTION_BEARISH;
|
|
|
|
//
|
|
// Bearish FVG ...
|
|
count = state.CountBearishFVGs();
|
|
for (int i = 0; i < count; i++)
|
|
{
|
|
//
|
|
XCFVG *iFVG = state.bearishFVGs[i];
|
|
|
|
//
|
|
to = iFVG.To();
|
|
from = iFVG.From();
|
|
upper = iFVG.Upper();
|
|
lower = iFVG.Lower();
|
|
|
|
//
|
|
bool isInside = IsPriceInsideZone(
|
|
price,
|
|
upper,
|
|
lower //
|
|
);
|
|
if (isInside)
|
|
{
|
|
//
|
|
XBoxZone iBox;
|
|
|
|
//
|
|
iBox.dir = dir;
|
|
iBox.symbol = symbol;
|
|
iBox.period = period;
|
|
|
|
//
|
|
iBox.to = to;
|
|
iBox.from = from;
|
|
iBox.upper = upper;
|
|
iBox.lower = lower;
|
|
|
|
//
|
|
if (iBox.IsValid())
|
|
{
|
|
//
|
|
AddRef(
|
|
iBox,
|
|
boxes //
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// Supply Zones ...
|
|
count = state.CountSupplyZones();
|
|
for (int i = 0; i < count; i++)
|
|
{
|
|
//
|
|
XCSupplyZone *iSupply = state.supplyZones[i];
|
|
|
|
//
|
|
to = iSupply.To();
|
|
from = iSupply.From();
|
|
upper = iSupply.Upper();
|
|
lower = iSupply.Lower();
|
|
|
|
//
|
|
bool isInside = IsPriceInsideZone(
|
|
price,
|
|
upper,
|
|
lower //
|
|
);
|
|
if (isInside)
|
|
{
|
|
//
|
|
XBoxZone iBox;
|
|
|
|
//
|
|
iBox.dir = dir;
|
|
iBox.symbol = symbol;
|
|
iBox.period = period;
|
|
|
|
//
|
|
iBox.to = to;
|
|
iBox.from = from;
|
|
iBox.upper = upper;
|
|
iBox.lower = lower;
|
|
|
|
//
|
|
if (iBox.IsValid())
|
|
{
|
|
//
|
|
AddRef(
|
|
iBox,
|
|
boxes //
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// Demand Zones ...
|
|
count = state.CountResistanceZones();
|
|
for (int i = 0; i < count; i++)
|
|
{
|
|
//
|
|
XCResistanceZone *iResistance = state.resistanceZones[i];
|
|
|
|
//
|
|
to = iResistance.To();
|
|
from = iResistance.From();
|
|
upper = iResistance.Upper();
|
|
lower = iResistance.Lower();
|
|
|
|
//
|
|
bool isInside = IsPriceInsideZone(
|
|
price,
|
|
upper,
|
|
lower //
|
|
);
|
|
if (isInside)
|
|
{
|
|
//
|
|
XBoxZone iBox;
|
|
|
|
//
|
|
iBox.dir = dir;
|
|
iBox.symbol = symbol;
|
|
iBox.period = period;
|
|
|
|
//
|
|
iBox.to = to;
|
|
iBox.from = from;
|
|
iBox.upper = upper;
|
|
iBox.lower = lower;
|
|
|
|
//
|
|
if (iBox.IsValid())
|
|
{
|
|
//
|
|
AddRef(
|
|
iBox,
|
|
boxes //
|
|
);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
int boxesCount = ArraySize(boxes);
|
|
bool hasBoxes = IsValidSize(boxes);
|
|
if (hasBoxes)
|
|
{
|
|
//
|
|
// Filter Boxes ...
|
|
for (int i = 0; i < boxesCount; i++)
|
|
{
|
|
//
|
|
XBoxZone iBox = boxes[i];
|
|
|
|
//
|
|
// Direction ...
|
|
if (!HasDirection(box.dir) || box.dir != iBox.dir)
|
|
{
|
|
box.dir = iBox.dir;
|
|
}
|
|
|
|
//
|
|
// Upper ...
|
|
if (box.upper == 0 || box.upper < iBox.upper)
|
|
{
|
|
box.upper = iBox.upper;
|
|
}
|
|
|
|
//
|
|
// Lower ...
|
|
if (box.lower == 0 || box.lower < iBox.lower)
|
|
{
|
|
box.lower = iBox.lower;
|
|
}
|
|
|
|
//
|
|
// To ...
|
|
if (!IsValid(box.to) || box.to < iBox.to)
|
|
{
|
|
box.to = iBox.to;
|
|
}
|
|
|
|
//
|
|
// From ...
|
|
if (!IsValid(box.from) || box.from > iBox.from)
|
|
{
|
|
box.from = iBox.from;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// Use Price Inside OB as Box ...
|
|
box.dir = boxDir;
|
|
box.to = priceInsideOB.To();
|
|
box.from = priceInsideOB.From();
|
|
box.upper = priceInsideOB.Upper();
|
|
box.lower = priceInsideOB.Lower();
|
|
}
|
|
}
|
|
|
|
//
|
|
result = box.IsValid();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Draw Cycle State ...
|
|
*
|
|
* @param state: X121SMCCyleState instance Reference ...
|
|
*
|
|
* @return ( int )
|
|
*/
|
|
int DrawCycleState(
|
|
X121SMCCycleState &state,
|
|
XCBaseObject *&drawnObjects[],
|
|
bool drawOrderBlocks = true,
|
|
bool drawFairValueGaps = true,
|
|
bool drawSupplyAndDemandZones = false,
|
|
bool drawSupportAndResistanceZones = false //
|
|
)
|
|
{
|
|
//
|
|
int result = 0;
|
|
|
|
//
|
|
// Order Blocks ...
|
|
if (drawOrderBlocks)
|
|
{
|
|
//
|
|
// Bullish ...
|
|
bool hasBullishOBs = state.HasBullishOBs();
|
|
int bullishOBsCount = state.CountBullishOBs();
|
|
if (hasBullishOBs)
|
|
{
|
|
//
|
|
for (int i = 0; i < bullishOBsCount; i++)
|
|
{
|
|
//
|
|
XCOrderBlock *iOb = state.bullishOBs[i];
|
|
|
|
//
|
|
XCBullishOrderBlockObject *iObObj;
|
|
bool isCreated = mPOIDrawer
|
|
.CreateBullishOrderBlock(
|
|
iOb,
|
|
iObObj //
|
|
);
|
|
if (isCreated)
|
|
{
|
|
//
|
|
Add(
|
|
(XCBaseObject *)iObObj,
|
|
drawnObjects //
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// Bearish ...
|
|
bool hasBearishOBs = state.HasBearishOBs();
|
|
int bearishOBsCount = state.CountBearishOBs();
|
|
if (hasBearishOBs)
|
|
{
|
|
//
|
|
for (int i = 0; i < bearishOBsCount; i++)
|
|
{
|
|
//
|
|
XCOrderBlock *iOb = state.bearishOBs[i];
|
|
|
|
//
|
|
XCBearishOrderBlockObject *iObObj;
|
|
bool isCreated = mPOIDrawer
|
|
.CreateBearishOrderBlock(
|
|
iOb,
|
|
iObObj //
|
|
);
|
|
if (isCreated)
|
|
{
|
|
//
|
|
Add(
|
|
(XCBaseObject *)iObObj,
|
|
drawnObjects //
|
|
);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// Fair Value Gaps ...
|
|
if (drawFairValueGaps)
|
|
{
|
|
//
|
|
// Bullish ...
|
|
bool hasBullishFVGs = state.HasBullishFVGs();
|
|
int bullishFVGsCount = state.CountBullishFVGs();
|
|
if (hasBullishFVGs)
|
|
{
|
|
//
|
|
for (int i = 0; i < bullishFVGsCount; i++)
|
|
{
|
|
//
|
|
XCFVG *iFVG = state.bullishFVGs[i];
|
|
|
|
//
|
|
XCBullishFairValueGapObject *iFVGObj;
|
|
bool isCreated = mPOIDrawer
|
|
.CreateBullishFairValueGap(
|
|
iFVG,
|
|
iFVGObj //
|
|
);
|
|
if (isCreated)
|
|
{
|
|
//
|
|
iFVGObj.ZoneColor(clrLime);
|
|
|
|
//
|
|
Add(
|
|
(XCBaseObject *)iFVGObj,
|
|
drawnObjects //
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// Bearish ...
|
|
bool hasBearishFVGs = state.HasBearishFVGs();
|
|
int bearishFVGsCount = state.CountBearishFVGs();
|
|
if (hasBearishFVGs)
|
|
{
|
|
//
|
|
for (int i = 0; i < bearishFVGsCount; i++)
|
|
{
|
|
//
|
|
XCFVG *iFVG = state.bearishFVGs[i];
|
|
|
|
//
|
|
XCBearishFairValueGapObject *iFVGObj;
|
|
bool isCreated = mPOIDrawer
|
|
.CreateBearishFairValueGap(
|
|
iFVG,
|
|
iFVGObj //
|
|
);
|
|
if (isCreated)
|
|
{
|
|
//
|
|
iFVGObj.ZoneColor(clrRed);
|
|
|
|
//
|
|
Add(
|
|
(XCBaseObject *)iFVGObj,
|
|
drawnObjects //
|
|
);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// Support and Resistance Zones ...
|
|
if (drawSupportAndResistanceZones)
|
|
{
|
|
//
|
|
// Support Zones ...
|
|
bool hasSupportZones = state.HasSupportZones();
|
|
int supportZonesCount = state.CountSupportZones();
|
|
if (hasSupportZones)
|
|
{
|
|
//
|
|
for (int i = 0; i < supportZonesCount; i++)
|
|
{
|
|
//
|
|
XCSupportZoneObject *iObj;
|
|
bool isCreated = mPOIDrawer
|
|
.CreateSupportZone(
|
|
state.supportZones[i],
|
|
iObj //
|
|
);
|
|
|
|
//
|
|
if (isCreated)
|
|
{
|
|
//
|
|
iObj.ZoneColor(clrDarkSeaGreen);
|
|
|
|
//
|
|
Add(
|
|
(XCBaseObject *)iObj,
|
|
drawnObjects //
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// Resistance Zones ...
|
|
bool hasResistanceZones = state.HasResistanceZones();
|
|
int resistanceZonesCount = state.CountResistanceZones();
|
|
if (hasResistanceZones)
|
|
{
|
|
//
|
|
for (int i = 0; i < resistanceZonesCount; i++)
|
|
{
|
|
//
|
|
XCResistanceZoneObject *iObj;
|
|
bool isCreated = mPOIDrawer
|
|
.CreateResistanceZone(
|
|
state.resistanceZones[i],
|
|
iObj //
|
|
);
|
|
|
|
//
|
|
if (isCreated)
|
|
{
|
|
//
|
|
iObj.ZoneColor(clrSaddleBrown);
|
|
|
|
//
|
|
Add(
|
|
(XCBaseObject *)iObj,
|
|
drawnObjects //
|
|
);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// Supply and Demand Zones ...
|
|
if (drawSupplyAndDemandZones)
|
|
{
|
|
//
|
|
// Demand Zones ...
|
|
bool hasDemandZones = state.HasDemandZones();
|
|
int demandZonesCount = state.CountDemandZones();
|
|
if (hasDemandZones)
|
|
{
|
|
//
|
|
for (int i = 0; i < demandZonesCount; i++)
|
|
{
|
|
//
|
|
XCDemandZoneObject *iObj;
|
|
bool isCreated = mPOIDrawer
|
|
.CreateDemandZone(
|
|
state.demandZones[i],
|
|
iObj //
|
|
);
|
|
|
|
//
|
|
if (isCreated)
|
|
{
|
|
//
|
|
iObj.ZoneColor(clrDarkTurquoise);
|
|
|
|
//
|
|
Add(
|
|
(XCBaseObject *)iObj,
|
|
drawnObjects //
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// Supply Zones ...
|
|
bool hasSupplyZones = state.HasSupplyZones();
|
|
int supplyZonesCount = state.CountSupplyZones();
|
|
if (hasSupplyZones)
|
|
{
|
|
//
|
|
for (int i = 0; i < supplyZonesCount; i++)
|
|
{
|
|
//
|
|
XCSupplyZoneObject *iObj;
|
|
bool isCreated = mPOIDrawer
|
|
.CreateSupplyZone(
|
|
state.supplyZones[i],
|
|
iObj //
|
|
);
|
|
|
|
//
|
|
if (isCreated)
|
|
{
|
|
//
|
|
iObj.ZoneColor(clrChocolate);
|
|
|
|
//
|
|
Add(
|
|
(XCBaseObject *)iObj,
|
|
drawnObjects //
|
|
);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
result = ArraySize(drawnObjects);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
|
|
/////////////////////////////////////////////////////////////////////
|