3114 lines
169 KiB
Plaintext
3114 lines
169 KiB
Plaintext
///////////////////////////////////////////////////////
|
|
//
|
|
// SaherElm IT Center MQL5 Class Library
|
|
// --------------------------------------
|
|
// Name: XCX121SMCTestStrategy
|
|
// Description: provides all based classes for use ...
|
|
//
|
|
//
|
|
// 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 "../../Helpers/x-saherelm.xchvwap.helper.mq5"
|
|
#include "../Classes/x-121.smc.base.strategy.class.mq5"
|
|
|
|
//
|
|
// Helper(s) ...
|
|
|
|
//
|
|
// XStrategy Class Implementation(s) ...
|
|
class XCX121SMCTestStrategy : public XCX121SMCBaseStrategy
|
|
{
|
|
//
|
|
// Public ...
|
|
public:
|
|
//
|
|
|
|
//
|
|
// Constructor(s) ...
|
|
void XCX121SMCTestStrategy(
|
|
//
|
|
// Base ...
|
|
string _symbol, // Trading Symbol
|
|
ENUM_TIMEFRAMES _period // Trading TimeFrame
|
|
)
|
|
: XCX121SMCBaseStrategy(_symbol, _period)
|
|
{
|
|
InitialHelpers();
|
|
}
|
|
|
|
//
|
|
// Overrides Actions ...
|
|
|
|
//
|
|
// Check Conditions For Signal ...
|
|
bool HasSignal(
|
|
XSignal &signal,
|
|
X121SMCStrategyConditions &conditions //
|
|
) override
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
signal.Clean();
|
|
conditions.Clean();
|
|
|
|
//
|
|
int pushers = 0;
|
|
|
|
//
|
|
double sl = 0;
|
|
double tp = 0;
|
|
double risk = 0;
|
|
double entry = 0;
|
|
double reward = 0;
|
|
double r2r = R2R();
|
|
double volume = Volume();
|
|
ENUM_POSITION_TYPE type = POSITION_TYPE_BUY;
|
|
ENUM_X_ORDER_MODES mode = X_ORDER_MODE_MARKET;
|
|
|
|
//
|
|
bool hasLong = false;
|
|
bool hasShort = false;
|
|
|
|
//
|
|
bool isAllowLong = AllowLong();
|
|
bool isAllowShort = AllowShort();
|
|
result = isAllowLong || isAllowShort;
|
|
if (!result)
|
|
{
|
|
return result;
|
|
;
|
|
}
|
|
|
|
//
|
|
// Start Calculations ...
|
|
|
|
//
|
|
string _symbol = GetSymbol();
|
|
ENUM_TIMEFRAMES _period = GetPeriod();
|
|
|
|
//
|
|
double points = GetPoints(_symbol);
|
|
double pip = GetPipPrice(_symbol);
|
|
double pip2 = 2 * pip;
|
|
double pip3 = 3 * pip;
|
|
|
|
//
|
|
int zIndex = 0;
|
|
int cIndex = zIndex + 1;
|
|
int pIndex = cIndex + 1;
|
|
int ppIndex = pIndex + 1;
|
|
|
|
//
|
|
// Retrieve Bars ...
|
|
|
|
//
|
|
// Zero Bar ...
|
|
XOHCL zBar;
|
|
result = zBar.Init(
|
|
_symbol,
|
|
_period,
|
|
zIndex //
|
|
);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Last Bar ...
|
|
XOHCL cBar;
|
|
result = cBar.Init(
|
|
_symbol,
|
|
_period,
|
|
cIndex //
|
|
);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Previous Bar ...
|
|
XOHCL pBar;
|
|
result = pBar.Init(
|
|
_symbol,
|
|
_period,
|
|
pIndex //
|
|
);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
bool isSpreadPassed = IsSpreadPass();
|
|
result = isSpreadPassed;
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Try to Implement SMC Based Conditions ...
|
|
|
|
// //
|
|
// ENUM_X_DIRECTION breakeType;
|
|
// bool isBreaked = IsRangeBreaked(breakeType);
|
|
|
|
// //
|
|
// if (isBreaked)
|
|
// {
|
|
// //
|
|
// // Detect Trend ...
|
|
// //
|
|
// bool d1HasBullishTrend = HasBullishTrend(_1DState);
|
|
// bool d1HasBearishTrend = HasBearishTrend(_1DState);
|
|
|
|
// //
|
|
// bool h4HasBullishTrend = HasBullishTrend(_4HState);
|
|
// bool h4HasBearishTrend = HasBearishTrend(_4HState);
|
|
|
|
// //
|
|
// bool m15HasBullishTrend = HasBullishTrend(_15MState);
|
|
// bool m15HasBearishTrend = HasBearishTrend(_15MState);
|
|
|
|
// //
|
|
// bool m5HasBullishTrend = HasBullishTrend(_5MState);
|
|
// bool m5HasBearishTrend = HasBearishTrend(_5MState);
|
|
|
|
// //
|
|
// bool m1HasBullishTrend = HasBullishTrend(_1MState);
|
|
// bool m1HasBearishTrend = HasBearishTrend(_1MState);
|
|
|
|
// //
|
|
// bool isBullishTrendValid = m15HasBullishTrend &&
|
|
// m5HasBullishTrend &&
|
|
// m1HasBullishTrend;
|
|
// //
|
|
// bool isBearishTrendValid = m15HasBearishTrend &&
|
|
// m5HasBearishTrend &&
|
|
// m1HasBearishTrend;
|
|
|
|
// //
|
|
// bool isRangeStructureDetected = DetectRangeStructure();
|
|
// if (isRangeStructureDetected)
|
|
// {
|
|
// //
|
|
// conditions.Clean();
|
|
// conditions.symbol = GetSymbol();
|
|
// conditions.period = GetPeriod();
|
|
// conditions.time = TimeCurrent();
|
|
|
|
// //
|
|
// bool isValidBreake = ValidateRangeBreake(
|
|
// breakeType,
|
|
// conditions //
|
|
// );
|
|
// if (!isValidBreake)
|
|
// {
|
|
// conditions.Clean();
|
|
// }
|
|
|
|
// //
|
|
// bool isBullish = breakeType == X_DIRECTION_BULLISH;
|
|
// bool isBearish = breakeType == X_DIRECTION_BEARISH;
|
|
|
|
// //
|
|
// hasLong =
|
|
// isBullish &&
|
|
// isValidBreake;
|
|
|
|
// //
|
|
// hasShort =
|
|
// isBearish &&
|
|
// isValidBreake;
|
|
// }
|
|
// }
|
|
|
|
//
|
|
// Reading Indicator's Conditions ...
|
|
int loopback = 7;
|
|
XCHVWAPConditions chvwapConditions;
|
|
chvwapHelper.GetConditions(
|
|
chvwapConditions,
|
|
cIndex,
|
|
loopback //
|
|
);
|
|
|
|
//
|
|
bool isRangeStructureDetected = DetectRangeStructure();
|
|
ENUM_X_DIRECTION vwapDirection = DetectVWAPDirection();
|
|
bool isVWAPBullish = IsBullish(vwapDirection) ||
|
|
(cBar.IsBullish() &&
|
|
cBar.IsStrong() &&
|
|
cBar.close > chvwapConditions.m[0] &&
|
|
cBar.close > chvwapConditions.l[0] &&
|
|
cBar.close > chvwapConditions.h[0]);
|
|
bool isVWAPBearish = IsBearish(vwapDirection) ||
|
|
(cBar.IsBearish() &&
|
|
cBar.IsStrong() &&
|
|
cBar.close < chvwapConditions.m[0] &&
|
|
cBar.close < chvwapConditions.l[0] &&
|
|
cBar.close < chvwapConditions.h[0]);
|
|
bool isValidStructure = ValidateRangeStructure(
|
|
vwapDirection,
|
|
conditions //
|
|
);
|
|
|
|
//
|
|
// Detect Trend ...
|
|
//
|
|
bool d1HasBullishTrend = HasBullishTrend(_1DState);
|
|
bool d1HasBearishTrend = HasBearishTrend(_1DState);
|
|
|
|
//
|
|
bool h4HasBullishTrend = HasBullishTrend(_4HState);
|
|
bool h4HasBearishTrend = HasBearishTrend(_4HState);
|
|
|
|
//
|
|
bool m15HasBullishTrend = HasBullishTrend(_15MState);
|
|
bool m15HasBearishTrend = HasBearishTrend(_15MState);
|
|
|
|
//
|
|
bool m5HasBullishTrend = HasBullishTrend(_5MState);
|
|
bool m5HasBearishTrend = HasBearishTrend(_5MState);
|
|
|
|
//
|
|
bool m1HasBullishTrend = HasBullishTrend(_1MState);
|
|
bool m1HasBearishTrend = HasBearishTrend(_1MState);
|
|
|
|
//
|
|
bool isBullishTrendValid = m15HasBullishTrend &&
|
|
m5HasBullishTrend &&
|
|
m1HasBullishTrend;
|
|
//
|
|
bool isBearishTrendValid = m15HasBearishTrend &&
|
|
m5HasBearishTrend &&
|
|
m1HasBearishTrend;
|
|
|
|
//
|
|
bool isBarReady =
|
|
isVWAPBullish
|
|
? cBar.IsBullish() &&
|
|
isBullishTrendValid
|
|
// &&
|
|
// (cBar.IsHammer() ||
|
|
// cBar.IsMorningStar() ||
|
|
// cBar.IsBullishEngulfing())
|
|
: isVWAPBearish
|
|
? cBar.IsBearish() &&
|
|
isBearishTrendValid
|
|
// &&
|
|
// (cBar.IsEveningStar() ||
|
|
// cBar.IsShootingStar() ||
|
|
// cBar.IsBearishEngulfing())
|
|
: false;
|
|
|
|
//
|
|
bool isRangeReady = isBarReady &&
|
|
isValidStructure &&
|
|
mVWAPRange.IsValid() &&
|
|
isRangeStructureDetected;
|
|
if (isRangeReady)
|
|
{
|
|
//
|
|
// Prepare Conditions ...
|
|
conditions.Clean();
|
|
conditions.symbol = GetSymbol();
|
|
conditions.period = GetPeriod();
|
|
conditions.time = TimeCurrent();
|
|
|
|
//
|
|
bool isTicksBullish = IsTicksBullish();
|
|
bool isTicksBearish = IsTicksBearish();
|
|
bool isTicksHasMomentum = IsTicksHasMomentum();
|
|
|
|
//
|
|
double pricateChangeRate = 0.01;
|
|
double priceChange = GetPriceChanged(
|
|
GetSymbol(),
|
|
GetPeriod(),
|
|
0,
|
|
7 //
|
|
);
|
|
bool isBullishPriceChanged = priceChange >= pricateChangeRate;
|
|
bool isBearishPriceChanged = priceChange < 0 &&
|
|
MathAbs(priceChange) >= pricateChangeRate;
|
|
|
|
//
|
|
hasLong = isAllowLong &&
|
|
isVWAPBullish &&
|
|
!isVWAPBearish &&
|
|
isTicksBullish &&
|
|
isTicksHasMomentum &&
|
|
isBullishPriceChanged;
|
|
|
|
//
|
|
hasShort = isAllowShort &&
|
|
isVWAPBearish &&
|
|
!isVWAPBullish &&
|
|
isTicksBearish &&
|
|
isTicksHasMomentum &&
|
|
isBearishPriceChanged;
|
|
}
|
|
|
|
//
|
|
bool isDetected = DetectRange();
|
|
if (isDetected)
|
|
{
|
|
//
|
|
DrawRange();
|
|
}
|
|
|
|
//
|
|
result = hasLong ||
|
|
hasShort;
|
|
if (!result)
|
|
{
|
|
conditions.Clean();
|
|
}
|
|
|
|
//
|
|
// Rmove Signal Condition ...
|
|
if (result)
|
|
{
|
|
//
|
|
// TYPE ...
|
|
type =
|
|
hasLong
|
|
? POSITION_TYPE_BUY
|
|
: POSITION_TYPE_SELL;
|
|
ENUM_X_POSITION_TYPES xType =
|
|
hasLong
|
|
? X_POSITION_TYPE_LONG
|
|
: X_POSITION_TYPE_SHORT;
|
|
|
|
//
|
|
entry = GetEntry(
|
|
conditions.symbol,
|
|
type //
|
|
);
|
|
|
|
//
|
|
// double candidates[];
|
|
// DetectSLCandidates(
|
|
// candidates,
|
|
// entry,
|
|
// conditions,
|
|
// xType //
|
|
// );
|
|
|
|
//
|
|
double slCandidates[];
|
|
Add(
|
|
chvwapConditions.m[0],
|
|
slCandidates //
|
|
);
|
|
Add(
|
|
chvwapConditions.l[0],
|
|
slCandidates //
|
|
);
|
|
Add(
|
|
chvwapConditions.h[0],
|
|
slCandidates //
|
|
);
|
|
|
|
//
|
|
double selectedSL =
|
|
hasLong
|
|
? GetMin(slCandidates)
|
|
: GetMax(slCandidates);
|
|
sl =
|
|
hasLong
|
|
? selectedSL - pip3
|
|
: selectedSL + pip3;
|
|
|
|
//
|
|
// RISK Reward ...
|
|
risk =
|
|
hasLong
|
|
? entry - sl
|
|
: sl - entry;
|
|
reward = risk * r2r;
|
|
tp =
|
|
hasLong
|
|
? entry + reward
|
|
: entry - reward;
|
|
|
|
//
|
|
ResetRange();
|
|
// ClearDraws();
|
|
|
|
//
|
|
signal.sl = sl;
|
|
signal.tp = tp;
|
|
signal.type = type;
|
|
signal.mode = mode;
|
|
signal.entry = entry;
|
|
signal.volume = volume;
|
|
signal.symbol = _symbol;
|
|
signal.pushers = pushers;
|
|
signal.provider = GetTag();
|
|
signal.time = TimeCurrent();
|
|
signal.period = _5MState.period;
|
|
|
|
//
|
|
result = PrepareSignal(signal);
|
|
|
|
//
|
|
hasLong = false;
|
|
hasShort = false;
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Customize Strategy Identifier ...
|
|
string GetTag() override
|
|
{
|
|
return X121SMCSUPDEMStrategyToken;
|
|
}
|
|
|
|
//
|
|
// Protected ...
|
|
protected:
|
|
//
|
|
|
|
//
|
|
// Props ...
|
|
|
|
//
|
|
// XCHVWAP ...
|
|
XCHVWAPInputs chvwapInputs;
|
|
XSCXCHVWAPHelper *chvwapHelper;
|
|
|
|
//
|
|
// Private ...
|
|
private:
|
|
//
|
|
// Props ...
|
|
|
|
/**
|
|
* Validate a Condition ...
|
|
*
|
|
* @param conditions: Argument 1
|
|
* @return ( bool )
|
|
*/
|
|
bool ValidateConditions(X121SMCStrategyConditions &conditions)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
result = conditions.IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
bool hasValidDemnd = conditions.ValidateDemand();
|
|
bool hasValidSupply = conditions.ValidateSupply();
|
|
result = hasValidDemnd || hasValidSupply;
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
string _symbol = GetSymbol();
|
|
ENUM_TIMEFRAMES _period = GetPeriod();
|
|
|
|
//
|
|
int zIndex = 0;
|
|
int cIndex = zIndex + 1;
|
|
int pIndex = cIndex + 1;
|
|
|
|
//
|
|
XOHCL zBar;
|
|
result = zBar.Init(
|
|
_symbol,
|
|
_period,
|
|
zIndex //
|
|
);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
XOHCL cBar;
|
|
result = cBar.Init(
|
|
_symbol,
|
|
_period,
|
|
cIndex //
|
|
);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result =
|
|
hasValidDemnd
|
|
? cBar.high < conditions.demandZone.upper &&
|
|
zBar.high < conditions.demandZone.upper &&
|
|
cBar.low > conditions.demandZone.lower &&
|
|
zBar.low > conditions.demandZone.lower
|
|
: hasValidSupply
|
|
? cBar.high < conditions.demandZone.upper &&
|
|
zBar.high < conditions.demandZone.upper &&
|
|
cBar.low > conditions.demandZone.lower &&
|
|
zBar.low > conditions.demandZone.lower
|
|
: false;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Initial Required Indicators Helper ...
|
|
*/
|
|
void InitialHelpers()
|
|
{
|
|
//
|
|
// XCHVWAP ...
|
|
|
|
//
|
|
// Short ...
|
|
ENUM_X_PERIOD_METHOD scMethod = X_PERIOD_MANUALLY; // How to Find Period
|
|
ENUM_TIMEFRAMES scPeriod = PERIOD_M15; // Time Period
|
|
|
|
//
|
|
// Medium ...
|
|
ENUM_X_PERIOD_METHOD mcMethod = X_PERIOD_MANUALLY; // How to Find Period
|
|
ENUM_TIMEFRAMES mcPeriod = PERIOD_H1; // Time Period
|
|
|
|
//
|
|
// Long ...
|
|
ENUM_X_PERIOD_METHOD lcMethod = X_PERIOD_MANUALLY; // How to Find Period
|
|
ENUM_TIMEFRAMES lcPeriod = PERIOD_H4; // Time Period
|
|
|
|
//
|
|
// Hind ...
|
|
ENUM_X_PERIOD_METHOD hcMethod = X_PERIOD_MANUALLY; // How to Find Period
|
|
ENUM_TIMEFRAMES hcPeriod = PERIOD_D1; // Time Period
|
|
|
|
//
|
|
chvwapInputs.Default();
|
|
|
|
//
|
|
chvwapInputs.scMethod = scMethod;
|
|
chvwapInputs.scPeriod = scPeriod;
|
|
chvwapInputs.mcMethod = mcMethod;
|
|
chvwapInputs.mcPeriod = mcPeriod;
|
|
chvwapInputs.lcMethod = lcMethod;
|
|
chvwapInputs.lcPeriod = lcPeriod;
|
|
chvwapInputs.hcMethod = hcMethod;
|
|
chvwapInputs.hcPeriod = hcPeriod;
|
|
|
|
//
|
|
chvwapInputs.showShort = true;
|
|
chvwapInputs.showMedium = true;
|
|
chvwapInputs.showLong = true;
|
|
chvwapInputs.showHind = true;
|
|
|
|
//
|
|
chvwapHelper = new XSCXCHVWAPHelper();
|
|
chvwapHelper.Init(
|
|
GetSymbol(),
|
|
GetPeriod(),
|
|
chvwapInputs //
|
|
);
|
|
}
|
|
|
|
//
|
|
XRange mVWAPRange;
|
|
int mVWAPRangeLongBreakeouts;
|
|
int mVWAPRangeShortBreakeouts;
|
|
XRangeStructure mVWAPRangeStructure;
|
|
|
|
/**
|
|
* Detect Range ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool DetectRange()
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
int cIndex = 1;
|
|
int loopback = 7;
|
|
int dest = cIndex + loopback;
|
|
string symbol = GetSymbol();
|
|
datetime cTime = TimeCurrent();
|
|
ENUM_TIMEFRAMES period = GetPeriod();
|
|
|
|
//
|
|
// Reading Indicator's Conditions ...
|
|
XCHVWAPConditions chvwapConditions;
|
|
chvwapHelper.GetConditions(
|
|
chvwapConditions,
|
|
cIndex,
|
|
loopback //
|
|
);
|
|
|
|
//
|
|
mVWAPRange.symbol = symbol;
|
|
mVWAPRange.period = period;
|
|
|
|
//
|
|
// Find Range Start ...
|
|
if (!mVWAPRange.IsValid())
|
|
{
|
|
//
|
|
bool hasTouchedMedium = false;
|
|
bool hasTouchedLong = false;
|
|
bool hasTouchedHind = false;
|
|
|
|
//
|
|
int count = ArraySize(chvwapConditions.h);
|
|
result = IsValidSize(count);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
for (int i = 0; i < count; i++)
|
|
{
|
|
//
|
|
ENUM_XCHVWAP_STATES mState =
|
|
chvwapHelper.ToState(chvwapConditions.mState[i]);
|
|
if (!hasTouchedMedium &&
|
|
mState == XCHVWAP_NEUTURAL_STATE)
|
|
{
|
|
hasTouchedMedium = true;
|
|
}
|
|
|
|
//
|
|
ENUM_XCHVWAP_STATES lState =
|
|
chvwapHelper.ToState(chvwapConditions.lState[i]);
|
|
if (!hasTouchedLong &&
|
|
lState == XCHVWAP_NEUTURAL_STATE)
|
|
{
|
|
hasTouchedLong = true;
|
|
}
|
|
|
|
//
|
|
ENUM_XCHVWAP_STATES hState =
|
|
chvwapHelper.ToState(chvwapConditions.hState[i]);
|
|
if (!hasTouchedHind &&
|
|
hState == XCHVWAP_NEUTURAL_STATE)
|
|
{
|
|
hasTouchedHind = true;
|
|
}
|
|
|
|
//
|
|
result =
|
|
//
|
|
hasTouchedMedium &&
|
|
hasTouchedLong &&
|
|
hasTouchedHind
|
|
//
|
|
;
|
|
if (result)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
if (result)
|
|
{
|
|
//
|
|
XOHCL sBar;
|
|
result = sBar.Init(
|
|
symbol,
|
|
period,
|
|
dest //
|
|
);
|
|
if (result)
|
|
{
|
|
//
|
|
mVWAPRange.from = sBar.time;
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
if (IsValid(mVWAPRange.from))
|
|
{
|
|
//
|
|
mVWAPRange.to = cTime;
|
|
|
|
//
|
|
int highIDX = iHighest(
|
|
symbol,
|
|
period,
|
|
MODE_HIGH,
|
|
dest,
|
|
cIndex //
|
|
);
|
|
double high = iHigh(
|
|
symbol,
|
|
period,
|
|
highIDX //
|
|
);
|
|
|
|
//
|
|
int lowIDX = iLowest(
|
|
symbol,
|
|
period,
|
|
MODE_LOW,
|
|
dest,
|
|
cIndex //
|
|
);
|
|
double low = iLow(
|
|
symbol,
|
|
period,
|
|
lowIDX //
|
|
);
|
|
|
|
//
|
|
if (mVWAPRange.upper == 0 ||
|
|
high > mVWAPRange.upper)
|
|
{
|
|
mVWAPRange.upper = high;
|
|
}
|
|
|
|
//
|
|
if (mVWAPRange.lower == 0 ||
|
|
low < mVWAPRange.lower)
|
|
{
|
|
mVWAPRange.lower = low;
|
|
}
|
|
}
|
|
|
|
//
|
|
result = mVWAPRange.IsValid();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Check Range is Breaked or not ...
|
|
*
|
|
* @param type: Argument 1
|
|
* @return ( bool )
|
|
*/
|
|
bool IsRangeBreaked(
|
|
ENUM_X_DIRECTION &type //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
type = X_DIRECTION_NONE;
|
|
|
|
//
|
|
int zIndex = 0;
|
|
int cIndex = zIndex + 1;
|
|
int pIndex = cIndex + 1;
|
|
|
|
//
|
|
int loopback = 7;
|
|
int dest = cIndex + loopback;
|
|
string symbol = GetSymbol();
|
|
datetime cTime = TimeCurrent();
|
|
ENUM_TIMEFRAMES period = GetPeriod();
|
|
|
|
//
|
|
result = mVWAPRange.IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Reading Indicator's Conditions ...
|
|
XCHVWAPConditions chvwapConditions;
|
|
chvwapHelper.GetConditions(
|
|
chvwapConditions,
|
|
cIndex,
|
|
loopback //
|
|
);
|
|
|
|
//
|
|
XOHCL zBar;
|
|
result = zBar.Init(
|
|
symbol,
|
|
period,
|
|
zIndex //
|
|
);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
XOHCL cBar;
|
|
result = cBar.Init(
|
|
symbol,
|
|
period,
|
|
cIndex //
|
|
);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
bool isBullishOrdered =
|
|
//
|
|
chvwapConditions.m[0] > chvwapConditions.l[0] &&
|
|
chvwapConditions.l[0] > chvwapConditions.h[0]
|
|
//
|
|
;
|
|
bool isBullishState =
|
|
//
|
|
chvwapHelper.IsBullish(chvwapConditions.mState[0]) &&
|
|
chvwapHelper.IsBullish(chvwapConditions.lState[0]) &&
|
|
chvwapHelper.IsBullish(chvwapConditions.hState[0])
|
|
//
|
|
;
|
|
bool isBullishBreaked = isBullishState &&
|
|
isBullishOrdered &&
|
|
cBar.IsStrong(50) &&
|
|
cBar.IsBullish() &&
|
|
zBar.low > mVWAPRange.upper &&
|
|
cBar.GetUp() > mVWAPRange.upper;
|
|
if (isBullishBreaked)
|
|
{
|
|
//
|
|
mVWAPRangeLongBreakeouts++;
|
|
type = X_DIRECTION_BULLISH;
|
|
}
|
|
|
|
//
|
|
bool isBearishOrdered =
|
|
//
|
|
chvwapConditions.m[0] < chvwapConditions.l[0] &&
|
|
chvwapConditions.l[0] < chvwapConditions.h[0]
|
|
//
|
|
;
|
|
bool isBearishState =
|
|
//
|
|
chvwapHelper.IsBearish(chvwapConditions.mState[0]) &&
|
|
chvwapHelper.IsBearish(chvwapConditions.lState[0]) &&
|
|
chvwapHelper.IsBearish(chvwapConditions.hState[0])
|
|
//
|
|
;
|
|
bool isBearishBreaked = isBearishState &&
|
|
isBearishOrdered &&
|
|
cBar.IsStrong(50) &&
|
|
cBar.IsBearish() &&
|
|
zBar.high < mVWAPRange.lower &&
|
|
cBar.GetDown() < mVWAPRange.lower;
|
|
if (isBearishBreaked)
|
|
{
|
|
//
|
|
mVWAPRangeShortBreakeouts++;
|
|
type = X_DIRECTION_BEARISH;
|
|
}
|
|
|
|
//
|
|
result = isBullishBreaked ||
|
|
isBearishBreaked;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Detect Direction of VWAP ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
ENUM_X_DIRECTION DetectVWAPDirection()
|
|
{
|
|
//
|
|
ENUM_X_DIRECTION result = X_DIRECTION_NONE;
|
|
|
|
//
|
|
int zIndex = 0;
|
|
int cIndex = zIndex + 1;
|
|
int pIndex = cIndex + 1;
|
|
|
|
//
|
|
int loopback = 7;
|
|
int dest = cIndex + loopback;
|
|
string symbol = GetSymbol();
|
|
datetime cTime = TimeCurrent();
|
|
ENUM_TIMEFRAMES period = GetPeriod();
|
|
|
|
//
|
|
bool isValid = mVWAPRange.IsValid();
|
|
if (!isValid)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Reading Indicator's Conditions ...
|
|
XCHVWAPConditions chvwapConditions;
|
|
chvwapHelper.GetConditions(
|
|
chvwapConditions,
|
|
cIndex,
|
|
loopback //
|
|
);
|
|
|
|
//
|
|
bool isBullishOrdered =
|
|
//
|
|
chvwapConditions.m[0] > chvwapConditions.l[0] &&
|
|
chvwapConditions.l[0] > chvwapConditions.h[0]
|
|
//
|
|
;
|
|
bool isBullishState =
|
|
//
|
|
chvwapHelper.IsBullish(chvwapConditions.mState[0]) &&
|
|
chvwapHelper.IsBullish(chvwapConditions.lState[0]) &&
|
|
chvwapHelper.IsBullish(chvwapConditions.hState[0])
|
|
//
|
|
;
|
|
bool isBullishDirection =
|
|
isBullishState &&
|
|
isBullishOrdered;
|
|
|
|
//
|
|
bool isBearishOrdered =
|
|
//
|
|
chvwapConditions.m[0] < chvwapConditions.l[0] &&
|
|
chvwapConditions.l[0] < chvwapConditions.h[0]
|
|
//
|
|
;
|
|
bool isBearishState =
|
|
//
|
|
chvwapHelper.IsBearish(chvwapConditions.mState[0]) &&
|
|
chvwapHelper.IsBearish(chvwapConditions.lState[0]) &&
|
|
chvwapHelper.IsBearish(chvwapConditions.hState[0])
|
|
//
|
|
;
|
|
bool isBearishDirection =
|
|
isBearishState &&
|
|
isBearishOrdered;
|
|
|
|
//
|
|
if (isBullishDirection &&
|
|
!isBearishDirection)
|
|
{
|
|
result = X_DIRECTION_BULLISH;
|
|
}
|
|
else if (
|
|
isBearishDirection &&
|
|
!isBullishDirection)
|
|
{
|
|
result = X_DIRECTION_BEARISH;
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Detect Range Structure ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool DetectRangeStructure()
|
|
{
|
|
//
|
|
mVWAPRangeStructure.Clean();
|
|
mVWAPRangeStructure.range = mVWAPRange;
|
|
|
|
//
|
|
// Supply Zones ...
|
|
int supplysCount = ArraySize(_CombineState.supplyZones);
|
|
if (IsValidSize(supplysCount))
|
|
{
|
|
//
|
|
for (int i = 0; i < supplysCount; i++)
|
|
{
|
|
//
|
|
XZone iZone = _CombineState.supplyZones[i];
|
|
|
|
//
|
|
bool isBetween = IsBetween(
|
|
iZone,
|
|
mVWAPRange //
|
|
);
|
|
if (isBetween)
|
|
{
|
|
//
|
|
iZone.to = mVWAPRange.to;
|
|
|
|
//
|
|
AddIfNotExists(
|
|
iZone,
|
|
mVWAPRangeStructure.supplyZones //
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// Demand Zones ...
|
|
int demandsCount = ArraySize(_CombineState.demandZones);
|
|
if (IsValidSize(demandsCount))
|
|
{
|
|
//
|
|
for (int i = 0; i < demandsCount; i++)
|
|
{
|
|
//
|
|
XZone iZone = _CombineState.demandZones[i];
|
|
|
|
//
|
|
bool isBetween = IsBetween(
|
|
iZone,
|
|
mVWAPRange //
|
|
);
|
|
if (isBetween)
|
|
{
|
|
//
|
|
iZone.to = mVWAPRange.to;
|
|
|
|
//
|
|
AddIfNotExists(
|
|
iZone,
|
|
mVWAPRangeStructure.demandZones //
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// Order Blocks ...
|
|
|
|
//
|
|
// Bullish OBs ...
|
|
int bullishOBsCount = ArraySize(_CombineState.bullishOrderBlocks);
|
|
if (IsValidSize(bullishOBsCount))
|
|
{
|
|
//
|
|
for (int i = 0; i < bullishOBsCount; i++)
|
|
{
|
|
//
|
|
XZone iZone = _CombineState.bullishOrderBlocks[i];
|
|
|
|
//
|
|
bool isBetween = IsBetween(
|
|
iZone,
|
|
mVWAPRange //
|
|
);
|
|
if (isBetween)
|
|
{
|
|
//
|
|
iZone.to = mVWAPRange.to;
|
|
|
|
//
|
|
AddIfNotExists(
|
|
iZone,
|
|
mVWAPRangeStructure.bullishOrderBlocks //
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// Bearish OBs ...
|
|
int bearishOBsCount = ArraySize(_CombineState.bearishOrderBlocks);
|
|
if (IsValidSize(bearishOBsCount))
|
|
{
|
|
//
|
|
for (int i = 0; i < bearishOBsCount; i++)
|
|
{
|
|
//
|
|
XZone iZone = _CombineState.bearishOrderBlocks[i];
|
|
|
|
//
|
|
bool isBetween = IsBetween(
|
|
iZone,
|
|
mVWAPRange //
|
|
);
|
|
if (isBetween)
|
|
{
|
|
//
|
|
iZone.to = mVWAPRange.to;
|
|
|
|
//
|
|
AddIfNotExists(
|
|
iZone,
|
|
mVWAPRangeStructure.bearishOrderBlocks //
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// Fair Value Gaps ...
|
|
|
|
//
|
|
// Bullish FVGs ...
|
|
int bullishFVGsCount = ArraySize(_CombineState.bullishFVGs);
|
|
if (IsValidSize(bullishFVGsCount))
|
|
{
|
|
//
|
|
for (int i = 0; i < bullishFVGsCount; i++)
|
|
{
|
|
//
|
|
XZone iZone = _CombineState.bullishFVGs[i];
|
|
|
|
//
|
|
bool isBetween = IsBetween(
|
|
iZone,
|
|
mVWAPRange //
|
|
);
|
|
if (isBetween)
|
|
{
|
|
//
|
|
iZone.to = mVWAPRange.to;
|
|
|
|
//
|
|
AddIfNotExists(
|
|
iZone,
|
|
mVWAPRangeStructure.bullishFVGs //
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// Bearish FVGs ...
|
|
int bearishFVGsCount = ArraySize(_CombineState.bearishFVGs);
|
|
if (IsValidSize(bearishFVGsCount))
|
|
{
|
|
//
|
|
for (int i = 0; i < bearishFVGsCount; i++)
|
|
{
|
|
//
|
|
XZone iZone = _CombineState.bearishFVGs[i];
|
|
|
|
//
|
|
bool isBetween = IsBetween(
|
|
iZone,
|
|
mVWAPRange //
|
|
);
|
|
if (isBetween)
|
|
{
|
|
//
|
|
iZone.to = mVWAPRange.to;
|
|
|
|
//
|
|
AddIfNotExists(
|
|
iZone,
|
|
mVWAPRangeStructure.bearishFVGs //
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// Swing Highs ...
|
|
int swingHighsCount = ArraySize(_CombineState.swingHighs);
|
|
if (IsValidSize(swingHighsCount))
|
|
{
|
|
//
|
|
for (int i = 0; i < swingHighsCount; i++)
|
|
{
|
|
//
|
|
XOHCL iBar = _CombineState.swingHighs[i];
|
|
|
|
//
|
|
bool isBetween = IsBetween(
|
|
iBar,
|
|
mVWAPRange //
|
|
);
|
|
if (isBetween)
|
|
{
|
|
//
|
|
AddIfNotExists(
|
|
iBar,
|
|
mVWAPRangeStructure.swingHighs //
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// Swing Lows ...
|
|
int swingLowsCount = ArraySize(_CombineState.swingLows);
|
|
if (IsValidSize(swingLowsCount))
|
|
{
|
|
//
|
|
for (int i = 0; i < swingLowsCount; i++)
|
|
{
|
|
//
|
|
XOHCL iBar = _CombineState.swingLows[i];
|
|
|
|
//
|
|
bool isBetween = IsBetween(
|
|
iBar,
|
|
mVWAPRange //
|
|
);
|
|
if (isBetween)
|
|
{
|
|
//
|
|
AddIfNotExists(
|
|
iBar,
|
|
mVWAPRangeStructure.swingLows //
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// Support Zones ...
|
|
int supportsCount = ArraySize(_CombineState.supportZones);
|
|
if (IsValidSize(supportsCount))
|
|
{
|
|
//
|
|
for (int i = 0; i < supportsCount; i++)
|
|
{
|
|
//
|
|
XOHCL iBar = _CombineState.supportZones[i];
|
|
|
|
//
|
|
bool isBetween = IsBetween(
|
|
iBar,
|
|
mVWAPRange //
|
|
);
|
|
if (isBetween)
|
|
{
|
|
//
|
|
AddIfNotExists(
|
|
iBar,
|
|
mVWAPRangeStructure.supports //
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// Resistance Zones ...
|
|
int resistancesCount = ArraySize(_CombineState.resistanceZones);
|
|
if (IsValidSize(resistancesCount))
|
|
{
|
|
//
|
|
for (int i = 0; i < resistancesCount; i++)
|
|
{
|
|
//
|
|
XOHCL iBar = _CombineState.resistanceZones[i];
|
|
|
|
//
|
|
bool isBetween = IsBetween(
|
|
iBar,
|
|
mVWAPRange //
|
|
);
|
|
if (isBetween)
|
|
{
|
|
//
|
|
AddIfNotExists(
|
|
iBar,
|
|
mVWAPRangeStructure.resistances //
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// Momentum Bars ...
|
|
int momentumBarCount = ArraySize(_CombineState.momentumBars);
|
|
if (IsValidSize(momentumBarCount))
|
|
{
|
|
//
|
|
for (int i = 0; i < momentumBarCount; i++)
|
|
{
|
|
//
|
|
XOHCL iBar = _CombineState.momentumBars[i];
|
|
|
|
//
|
|
bool isBetween = IsBetween(
|
|
iBar,
|
|
mVWAPRange //
|
|
);
|
|
if (isBetween)
|
|
{
|
|
//
|
|
bool isBullish = iBar.IsBullish();
|
|
|
|
//
|
|
if (isBullish)
|
|
{
|
|
//
|
|
AddIfNotExists(
|
|
iBar,
|
|
mVWAPRangeStructure.bullishMomentumBars //
|
|
);
|
|
}
|
|
else
|
|
{
|
|
//
|
|
AddIfNotExists(
|
|
iBar,
|
|
mVWAPRangeStructure.bearishMomentumBars //
|
|
);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// Rejection Bars ...
|
|
int rejectionBarCount = ArraySize(_CombineState.rejectionBars);
|
|
if (IsValidSize(rejectionBarCount))
|
|
{
|
|
//
|
|
for (int i = 0; i < rejectionBarCount; i++)
|
|
{
|
|
//
|
|
XOHCL iBar = _CombineState.rejectionBars[i];
|
|
|
|
//
|
|
bool isBetween = IsBetween(
|
|
iBar,
|
|
mVWAPRange //
|
|
);
|
|
if (isBetween)
|
|
{
|
|
//
|
|
bool isBullish = iBar.GetLowShadow() > iBar.GetHighShadow();
|
|
|
|
//
|
|
if (isBullish)
|
|
{
|
|
//
|
|
AddIfNotExists(
|
|
iBar,
|
|
mVWAPRangeStructure.bullishRejectionBars //
|
|
);
|
|
}
|
|
else
|
|
{
|
|
//
|
|
AddIfNotExists(
|
|
iBar,
|
|
mVWAPRangeStructure.bearishRejectionBars //
|
|
);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
bool result = mVWAPRangeStructure.IsValid();
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Validate Range Structure ...
|
|
*
|
|
* @param type: ENUM_X_DIRECTION member ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool ValidateRangeStructure(
|
|
ENUM_X_DIRECTION type,
|
|
X121SMCStrategyConditions &conditions //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
bool drawPOIs = true;
|
|
bool drawFVG = true;
|
|
bool drawSwing = true;
|
|
bool drawOrderBlock = true;
|
|
bool drawMomentumBar = true;
|
|
bool drawSupplyDemand = true;
|
|
bool drawRejectionBar = true;
|
|
bool drawSupportResistance = true;
|
|
|
|
//
|
|
result =
|
|
mVWAPRange.IsValid() &&
|
|
mVWAPRangeStructure.IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result = type == X_DIRECTION_BULLISH ||
|
|
type == X_DIRECTION_BEARISH;
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
bool isBullish = type == X_DIRECTION_BULLISH;
|
|
|
|
//
|
|
string symbol = GetSymbol();
|
|
ENUM_TIMEFRAMES period = GetPeriod();
|
|
|
|
//
|
|
int zIndex = 0;
|
|
int cIndex = zIndex + 1;
|
|
int pIndex = cIndex + 1;
|
|
|
|
//
|
|
XOHCL breakeBar;
|
|
result = breakeBar.Init(
|
|
symbol,
|
|
period,
|
|
cIndex //
|
|
);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
XZone fvg;
|
|
XOHCL swing;
|
|
XOHCL supRes;
|
|
XZone supDem;
|
|
XZone orderBlock;
|
|
XOHCL momentumBar;
|
|
XOHCL rejectionBar;
|
|
|
|
//
|
|
// Do this for Better Changes Later ...
|
|
XRangeStructure state = mVWAPRangeStructure;
|
|
|
|
//
|
|
// First we Have to find Supply or Demand ...
|
|
int demandsCount = ArraySize(state.demandZones);
|
|
int suppliesCount = ArraySize(state.supplyZones);
|
|
|
|
//
|
|
result = isBullish
|
|
? IsValidSize(demandsCount)
|
|
: IsValidSize(suppliesCount);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Detect Supply and Demands ...
|
|
if (isBullish)
|
|
{
|
|
//
|
|
for (int i = 0; i < demandsCount; i++)
|
|
{
|
|
//
|
|
XZone iZone = state.demandZones[i];
|
|
|
|
//
|
|
if (!supDem.IsValid() ||
|
|
supDem.lower < iZone.lower)
|
|
{
|
|
supDem = iZone;
|
|
}
|
|
|
|
//
|
|
AddRef(
|
|
iZone,
|
|
conditions.demandZones //
|
|
);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//
|
|
for (int i = 0; i < suppliesCount; i++)
|
|
{
|
|
//
|
|
XZone iZone = state.supplyZones[i];
|
|
|
|
//
|
|
if (!supDem.IsValid() ||
|
|
supDem.upper > iZone.upper)
|
|
{
|
|
supDem = iZone;
|
|
}
|
|
|
|
//
|
|
AddRef(
|
|
iZone,
|
|
conditions.supplyZones //
|
|
);
|
|
}
|
|
}
|
|
|
|
//
|
|
result = supDem.IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Detect Order Block ...
|
|
if (isBullish)
|
|
{
|
|
//
|
|
int count = ArraySize(state.bullishOrderBlocks);
|
|
if (IsValidSize(count))
|
|
{
|
|
//
|
|
for (int i = 0; i < count; i++)
|
|
{
|
|
//
|
|
XZone iZone = state.bullishOrderBlocks[i];
|
|
|
|
//
|
|
if (!orderBlock.IsValid() ||
|
|
orderBlock.lower < iZone.lower)
|
|
{
|
|
orderBlock = iZone;
|
|
}
|
|
|
|
//
|
|
AddRef(
|
|
iZone,
|
|
conditions.bullishOrderBlocks //
|
|
);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//
|
|
int count = ArraySize(state.bearishOrderBlocks);
|
|
if (IsValidSize(count))
|
|
{
|
|
//
|
|
for (int i = 0; i < count; i++)
|
|
{
|
|
//
|
|
XZone iZone = state.bearishOrderBlocks[i];
|
|
|
|
//
|
|
if (!orderBlock.IsValid() ||
|
|
orderBlock.upper > iZone.upper)
|
|
{
|
|
orderBlock = iZone;
|
|
}
|
|
|
|
//
|
|
AddRef(
|
|
iZone,
|
|
conditions.bearishOrderBlocks //
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
result = orderBlock.IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Detect Fair Value Gaps ...
|
|
if (isBullish)
|
|
{
|
|
//
|
|
int count = ArraySize(state.bullishFVGs);
|
|
if (IsValidSize(count))
|
|
{
|
|
//
|
|
for (int i = 0; i < count; i++)
|
|
{
|
|
//
|
|
XZone iZone = state.bullishFVGs[i];
|
|
|
|
//
|
|
if (!fvg.IsValid() ||
|
|
fvg.lower < iZone.lower)
|
|
{
|
|
fvg = iZone;
|
|
}
|
|
|
|
//
|
|
AddRef(
|
|
iZone,
|
|
conditions.bullishFVGs //
|
|
);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//
|
|
int count = ArraySize(state.bearishFVGs);
|
|
if (IsValidSize(count))
|
|
{
|
|
//
|
|
for (int i = 0; i < count; i++)
|
|
{
|
|
//
|
|
XZone iZone = state.bearishFVGs[i];
|
|
|
|
//
|
|
if (!fvg.IsValid() ||
|
|
fvg.upper > iZone.upper)
|
|
{
|
|
fvg = iZone;
|
|
}
|
|
|
|
//
|
|
AddRef(
|
|
iZone,
|
|
conditions.bearishFVGs //
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// Detect Swings ...
|
|
if (isBullish)
|
|
{
|
|
//
|
|
int count = ArraySize(state.swingLows);
|
|
if (IsValidSize(count))
|
|
{
|
|
//
|
|
for (int i = 0; i < count; i++)
|
|
{
|
|
//
|
|
XOHCL iBar = state.swingLows[i];
|
|
|
|
//
|
|
if (!swing.IsValid() ||
|
|
swing.low < iBar.low)
|
|
{
|
|
swing = iBar;
|
|
}
|
|
|
|
//
|
|
AddRef(
|
|
iBar,
|
|
conditions.swingLows //
|
|
);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//
|
|
int count = ArraySize(state.swingHighs);
|
|
if (IsValidSize(count))
|
|
{
|
|
//
|
|
for (int i = 0; i < count; i++)
|
|
{
|
|
//
|
|
XOHCL iBar = state.swingHighs[i];
|
|
|
|
//
|
|
if (!swing.IsValid() ||
|
|
swing.high > iBar.high)
|
|
{
|
|
swing = iBar;
|
|
}
|
|
|
|
//
|
|
AddRef(
|
|
iBar,
|
|
conditions.swingHighs //
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// Detect Momentum Bar ...
|
|
if (isBullish)
|
|
{
|
|
//
|
|
int count = ArraySize(state.bullishMomentumBars);
|
|
if (IsValidSize(count))
|
|
{
|
|
//
|
|
for (int i = 0; i < count; i++)
|
|
{
|
|
//
|
|
XOHCL iBar = state.bullishMomentumBars[i];
|
|
|
|
//
|
|
if (!momentumBar.IsValid() ||
|
|
momentumBar.low < iBar.low)
|
|
{
|
|
momentumBar = iBar;
|
|
}
|
|
|
|
//
|
|
AddRef(
|
|
iBar,
|
|
conditions.bullishMomentumBars //
|
|
);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//
|
|
int count = ArraySize(state.bearishMomentumBars);
|
|
if (IsValidSize(count))
|
|
{
|
|
//
|
|
for (int i = 0; i < count; i++)
|
|
{
|
|
//
|
|
XOHCL iBar = state.bearishMomentumBars[i];
|
|
|
|
//
|
|
if (!momentumBar.IsValid() ||
|
|
momentumBar.high > iBar.high)
|
|
{
|
|
momentumBar = iBar;
|
|
}
|
|
|
|
//
|
|
AddRef(
|
|
iBar,
|
|
conditions.bearishMomentumBars //
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
result = momentumBar.IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Detect Rejection Bar ...
|
|
if (isBullish)
|
|
{
|
|
//
|
|
int count = ArraySize(state.bullishRejectionBars);
|
|
if (IsValidSize(count))
|
|
{
|
|
//
|
|
for (int i = 0; i < count; i++)
|
|
{
|
|
//
|
|
XOHCL iBar = state.bullishRejectionBars[i];
|
|
|
|
//
|
|
if (!rejectionBar.IsValid() ||
|
|
rejectionBar.low < iBar.low)
|
|
{
|
|
rejectionBar = iBar;
|
|
}
|
|
|
|
//
|
|
AddRef(
|
|
iBar,
|
|
conditions.bullishRejectionBars //
|
|
);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//
|
|
int count = ArraySize(state.bearishRejectionBars);
|
|
if (IsValidSize(count))
|
|
{
|
|
//
|
|
for (int i = 0; i < count; i++)
|
|
{
|
|
//
|
|
XOHCL iBar = state.bearishRejectionBars[i];
|
|
|
|
//
|
|
if (!rejectionBar.IsValid() ||
|
|
rejectionBar.high > iBar.high)
|
|
{
|
|
rejectionBar = iBar;
|
|
}
|
|
|
|
//
|
|
AddRef(
|
|
iBar,
|
|
conditions.bearishRejectionBars //
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
result = rejectionBar.IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
if (drawPOIs)
|
|
{
|
|
//
|
|
bool isCreated = false;
|
|
|
|
//
|
|
if (isBullish)
|
|
{
|
|
//
|
|
// Demand ...
|
|
if (drawSupplyDemand)
|
|
{
|
|
//
|
|
XCDemandZoneObject *iObj;
|
|
isCreated = mPOIDrawer.CreateDemandZone(
|
|
supDem,
|
|
iObj //
|
|
);
|
|
if (isCreated)
|
|
{
|
|
mDrawnObjects.Add(iObj);
|
|
}
|
|
}
|
|
|
|
//
|
|
// Order Block ...
|
|
if (drawOrderBlock)
|
|
{
|
|
//
|
|
XCBullishOrderBlockObject *iObj;
|
|
isCreated = mPOIDrawer.CreateBullishOrderBlock(
|
|
orderBlock,
|
|
iObj //
|
|
);
|
|
if (isCreated)
|
|
{
|
|
mDrawnObjects.Add(iObj);
|
|
}
|
|
}
|
|
|
|
//
|
|
// Fair Value Gap ...
|
|
if (drawFVG)
|
|
{
|
|
//
|
|
XCBullishFVGObject *iObj;
|
|
isCreated = mPOIDrawer.CreateBullishFVG(
|
|
fvg,
|
|
iObj //
|
|
);
|
|
if (isCreated)
|
|
{
|
|
mDrawnObjects.Add(iObj);
|
|
}
|
|
}
|
|
|
|
//
|
|
// Support ...
|
|
if (drawSupportResistance)
|
|
{
|
|
//
|
|
XCSupportZoneObject *iObj;
|
|
isCreated = mPOIDrawer.CreateSupportZone(
|
|
supRes,
|
|
iObj //
|
|
);
|
|
if (isCreated)
|
|
{
|
|
mDrawnObjects.Add(iObj);
|
|
}
|
|
}
|
|
|
|
//
|
|
// Swing ...
|
|
if (drawSwing)
|
|
{
|
|
//
|
|
XCSwingLowObject *iObj;
|
|
isCreated = mPOIDrawer.CreateSwingLow(
|
|
swing,
|
|
iObj //
|
|
);
|
|
if (isCreated)
|
|
{
|
|
mDrawnObjects.Add(iObj);
|
|
}
|
|
}
|
|
|
|
//
|
|
// Momentum Bar ...
|
|
if (drawMomentumBar)
|
|
{
|
|
//
|
|
XCBullishMomentumBarObject *iObj;
|
|
isCreated = mPOIDrawer.CreateBullishMomentumBar(
|
|
momentumBar,
|
|
iObj //
|
|
);
|
|
if (isCreated)
|
|
{
|
|
mDrawnObjects.Add(iObj);
|
|
}
|
|
}
|
|
|
|
//
|
|
// Rejection Bar ...
|
|
if (drawRejectionBar)
|
|
{
|
|
//
|
|
XCBullishRejectionBarObject *iObj;
|
|
isCreated = mPOIDrawer.CreateBullishRejectionBar(
|
|
momentumBar,
|
|
iObj //
|
|
);
|
|
if (isCreated)
|
|
{
|
|
mDrawnObjects.Add(iObj);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// Supply ...
|
|
if (drawSupplyDemand)
|
|
{
|
|
//
|
|
XCSupplyZoneObject *iObj;
|
|
isCreated = mPOIDrawer.CreateSupplyZone(
|
|
supDem,
|
|
iObj //
|
|
);
|
|
if (isCreated)
|
|
{
|
|
mDrawnObjects.Add(iObj);
|
|
}
|
|
}
|
|
|
|
//
|
|
// Order Block ...
|
|
if (drawOrderBlock)
|
|
{
|
|
//
|
|
XCBearishOrderBlockObject *iObj;
|
|
isCreated = mPOIDrawer.CreateBearishOrderBlock(
|
|
orderBlock,
|
|
iObj //
|
|
);
|
|
if (isCreated)
|
|
{
|
|
mDrawnObjects.Add(iObj);
|
|
}
|
|
}
|
|
|
|
//
|
|
// Fair Value Gap ...
|
|
if (drawFVG)
|
|
{
|
|
//
|
|
XCBearishFVGObject *iObj;
|
|
isCreated = mPOIDrawer.CreateBearishFVG(
|
|
fvg,
|
|
iObj //
|
|
);
|
|
if (isCreated)
|
|
{
|
|
mDrawnObjects.Add(iObj);
|
|
}
|
|
}
|
|
|
|
//
|
|
// Resistance ...
|
|
if (drawSupportResistance)
|
|
{
|
|
//
|
|
XCResistanceZoneObject *iObj;
|
|
isCreated = mPOIDrawer.CreateResistanceZone(
|
|
supRes,
|
|
iObj //
|
|
);
|
|
if (isCreated)
|
|
{
|
|
mDrawnObjects.Add(iObj);
|
|
}
|
|
}
|
|
|
|
//
|
|
// Swing ...
|
|
if (drawSwing)
|
|
{
|
|
//
|
|
XCSwingHighObject *iObj;
|
|
isCreated = mPOIDrawer.CreateSwingHigh(
|
|
swing,
|
|
iObj //
|
|
);
|
|
if (isCreated)
|
|
{
|
|
mDrawnObjects.Add(iObj);
|
|
}
|
|
}
|
|
|
|
//
|
|
// Momentum Bar ...
|
|
if (drawMomentumBar)
|
|
{
|
|
//
|
|
XCBearishMomentumBarObject *iObj;
|
|
isCreated = mPOIDrawer.CreateBearishMomentumBar(
|
|
momentumBar,
|
|
iObj //
|
|
);
|
|
if (isCreated)
|
|
{
|
|
mDrawnObjects.Add(iObj);
|
|
}
|
|
}
|
|
|
|
//
|
|
// Rejection Bar ...
|
|
if (drawRejectionBar)
|
|
{
|
|
//
|
|
XCBearishRejectionBarObject *iObj;
|
|
isCreated = mPOIDrawer.CreateBearishRejectionBar(
|
|
momentumBar,
|
|
iObj //
|
|
);
|
|
if (isCreated)
|
|
{
|
|
mDrawnObjects.Add(iObj);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
if (isBullish)
|
|
{
|
|
//
|
|
conditions.bullishFVG = fvg;
|
|
conditions.support = supRes;
|
|
conditions.swingLow = swing;
|
|
conditions.demandZone = supDem;
|
|
conditions.bullishOrderBlock = orderBlock;
|
|
conditions.bullishMomentumBar = momentumBar;
|
|
conditions.bullishRejectionBar = rejectionBar;
|
|
}
|
|
else
|
|
{
|
|
//
|
|
conditions.bearishFVG = fvg;
|
|
conditions.swingHigh = swing;
|
|
conditions.resistance = supRes;
|
|
conditions.supplyZone = supDem;
|
|
conditions.bearishOrderBlock = orderBlock;
|
|
conditions.bearishMomentumBar = momentumBar;
|
|
conditions.bearishRejectionBar = rejectionBar;
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Reset Range ...
|
|
*/
|
|
void ResetRange()
|
|
{
|
|
//
|
|
mVWAPRange.Clean();
|
|
mVWAPRangeStructure.Clean();
|
|
mVWAPRangeLongBreakeouts = 0;
|
|
mVWAPRangeShortBreakeouts = 0;
|
|
}
|
|
|
|
/**
|
|
* Draw Range ...
|
|
*/
|
|
void DrawRange()
|
|
{
|
|
//
|
|
bool canDraw = mVWAPRange.IsValid();
|
|
if (!canDraw)
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
string name = mVWAPRange.GetTag();
|
|
string tooltip = mVWAPRange.GetTooltip();
|
|
|
|
//
|
|
CChartObjectRectangle *iObj;
|
|
iObj = new CChartObjectRectangle();
|
|
bool isCreated = iObj.Create(
|
|
ChartIdentification(),
|
|
name,
|
|
SubWindowIdentification(),
|
|
mVWAPRange.from,
|
|
mVWAPRange.upper,
|
|
mVWAPRange.to,
|
|
mVWAPRange.lower //
|
|
);
|
|
if (!isCreated)
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
iObj.Width(1);
|
|
iObj.Color(clrAqua);
|
|
iObj.Style(STYLE_SOLID);
|
|
iObj.Tooltip(tooltip);
|
|
|
|
//
|
|
mDrawnObjects.Add(iObj);
|
|
}
|
|
|
|
/**
|
|
* Draw Detected Market Structure ...
|
|
*
|
|
* @param direction: ENUM_X_DIRECTION member ...
|
|
*/
|
|
void DrawRangeStructure(ENUM_X_DIRECTION direction)
|
|
{
|
|
//
|
|
if (!mVWAPRangeStructure.IsValid())
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
bool canAll = direction == X_DIRECTION_ALL;
|
|
bool canBullish = direction == X_DIRECTION_BULLISH;
|
|
bool canBearish = direction == X_DIRECTION_BEARISH;
|
|
if (!canAll &&
|
|
!canBullish &&
|
|
!canBearish)
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
// Supply Zones ...
|
|
int supplysCount = ArraySize(mVWAPRangeStructure.supplyZones);
|
|
if ((canAll || canBearish) && IsValidSize(supplysCount))
|
|
{
|
|
//
|
|
for (int i = 0; i < supplysCount; i++)
|
|
{
|
|
//
|
|
XZone iZone = mVWAPRangeStructure.supplyZones[i];
|
|
|
|
//
|
|
XCSupplyZoneObject *iObj;
|
|
bool isCreated = mPOIDrawer.CreateSupplyZone(
|
|
iZone,
|
|
iObj //
|
|
);
|
|
if (isCreated)
|
|
{
|
|
//
|
|
mDrawnObjects.Add(iObj);
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// Demand Zones ...
|
|
int demandsCount = ArraySize(mVWAPRangeStructure.demandZones);
|
|
if ((canAll || canBullish) && IsValidSize(demandsCount))
|
|
{
|
|
//
|
|
for (int i = 0; i < demandsCount; i++)
|
|
{
|
|
//
|
|
XZone iZone = mVWAPRangeStructure.demandZones[i];
|
|
|
|
//
|
|
XCDemandZoneObject *iObj;
|
|
bool isCreated = mPOIDrawer.CreateDemandZone(
|
|
iZone,
|
|
iObj //
|
|
);
|
|
if (isCreated)
|
|
{
|
|
//
|
|
mDrawnObjects.Add(iObj);
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// Order Blocks ...
|
|
|
|
//
|
|
// Bullish OBs ...
|
|
int bullishOBsCount = ArraySize(mVWAPRangeStructure.bullishOrderBlocks);
|
|
if ((canAll || canBullish) && IsValidSize(bullishOBsCount))
|
|
{
|
|
//
|
|
for (int i = 0; i < bullishOBsCount; i++)
|
|
{
|
|
//
|
|
XZone iZone = mVWAPRangeStructure.bullishOrderBlocks[i];
|
|
|
|
//
|
|
XCBullishOrderBlockObject *iObj;
|
|
bool isCreated = mPOIDrawer.CreateBullishOrderBlock(
|
|
iZone,
|
|
iObj //
|
|
);
|
|
if (isCreated)
|
|
{
|
|
//
|
|
mDrawnObjects.Add(iObj);
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// Bearish OBs ...
|
|
int bearishOBsCount = ArraySize(mVWAPRangeStructure.bearishOrderBlocks);
|
|
if ((canAll || canBearish) && IsValidSize(bearishOBsCount))
|
|
{
|
|
//
|
|
for (int i = 0; i < bearishOBsCount; i++)
|
|
{
|
|
//
|
|
XZone iZone = mVWAPRangeStructure.bearishOrderBlocks[i];
|
|
|
|
//
|
|
XCBearishOrderBlockObject *iObj;
|
|
bool isCreated = mPOIDrawer.CreateBearishOrderBlock(
|
|
iZone,
|
|
iObj //
|
|
);
|
|
if (isCreated)
|
|
{
|
|
//
|
|
mDrawnObjects.Add(iObj);
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// Fair Value Gaps ...
|
|
|
|
//
|
|
// Bullish FVGs ...
|
|
int bullishFVGsCount = ArraySize(mVWAPRangeStructure.bullishFVGs);
|
|
if ((canAll || canBullish) && IsValidSize(bullishFVGsCount))
|
|
{
|
|
//
|
|
for (int i = 0; i < bullishFVGsCount; i++)
|
|
{
|
|
//
|
|
XZone iZone = mVWAPRangeStructure.bullishFVGs[i];
|
|
|
|
//
|
|
XCBullishFVGObject *iObj;
|
|
bool isCreated = mPOIDrawer.CreateBullishFVG(
|
|
iZone,
|
|
iObj //
|
|
);
|
|
if (isCreated)
|
|
{
|
|
//
|
|
mDrawnObjects.Add(iObj);
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// Bearish FVGs ...
|
|
int bearishFVGsCount = ArraySize(mVWAPRangeStructure.bearishFVGs);
|
|
if ((canAll || canBearish) && IsValidSize(bearishFVGsCount))
|
|
{
|
|
//
|
|
for (int i = 0; i < bearishFVGsCount; i++)
|
|
{
|
|
//
|
|
XZone iZone = mVWAPRangeStructure.bearishFVGs[i];
|
|
|
|
//
|
|
XCBearishFVGObject *iObj;
|
|
bool isCreated = mPOIDrawer.CreateBearishFVG(
|
|
iZone,
|
|
iObj //
|
|
);
|
|
if (isCreated)
|
|
{
|
|
//
|
|
mDrawnObjects.Add(iObj);
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// Swing Highs ...
|
|
int swingHighsCount = ArraySize(mVWAPRangeStructure.swingHighs);
|
|
if ((canAll || canBearish) && IsValidSize(swingHighsCount))
|
|
{
|
|
//
|
|
for (int i = 0; i < swingHighsCount; i++)
|
|
{
|
|
//
|
|
XOHCL iBar = mVWAPRangeStructure.swingHighs[i];
|
|
|
|
//
|
|
XCSwingHighObject *iObj;
|
|
bool isCreated = mPOIDrawer.CreateSwingHigh(
|
|
iBar,
|
|
iObj //
|
|
);
|
|
if (isCreated)
|
|
{
|
|
//
|
|
mDrawnObjects.Add(iObj);
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// Swing Lows ...
|
|
int swingLowsCount = ArraySize(mVWAPRangeStructure.swingLows);
|
|
if ((canAll || canBullish) && IsValidSize(swingLowsCount))
|
|
{
|
|
//
|
|
for (int i = 0; i < swingLowsCount; i++)
|
|
{
|
|
//
|
|
XOHCL iBar = mVWAPRangeStructure.swingLows[i];
|
|
|
|
//
|
|
XCSwingLowObject *iObj;
|
|
bool isCreated = mPOIDrawer.CreateSwingLow(
|
|
iBar,
|
|
iObj //
|
|
);
|
|
if (isCreated)
|
|
{
|
|
//
|
|
mDrawnObjects.Add(iObj);
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// Support Zones ...
|
|
int supportsCount = ArraySize(mVWAPRangeStructure.supports);
|
|
if ((canAll || canBullish) && IsValidSize(supportsCount))
|
|
{
|
|
//
|
|
for (int i = 0; i < supportsCount; i++)
|
|
{
|
|
//
|
|
XOHCL iBar = mVWAPRangeStructure.supports[i];
|
|
|
|
//
|
|
XCSupportZoneObject *iObj;
|
|
bool isCreated = mPOIDrawer.CreateSupportZone(
|
|
iBar,
|
|
iObj,
|
|
mVWAPRange.to //
|
|
);
|
|
if (isCreated)
|
|
{
|
|
//
|
|
mDrawnObjects.Add(iObj);
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// Resistance Zones ...
|
|
int resistancesCount = ArraySize(mVWAPRangeStructure.resistances);
|
|
if ((canAll || canBearish) && IsValidSize(resistancesCount))
|
|
{
|
|
//
|
|
for (int i = 0; i < resistancesCount; i++)
|
|
{
|
|
//
|
|
XOHCL iBar = mVWAPRangeStructure.resistances[i];
|
|
|
|
//
|
|
XCResistanceZoneObject *iObj;
|
|
bool isCreated = mPOIDrawer.CreateResistanceZone(
|
|
iBar,
|
|
iObj,
|
|
mVWAPRange.to //
|
|
);
|
|
if (isCreated)
|
|
{
|
|
//
|
|
mDrawnObjects.Add(iObj);
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// Momentum Bars ...
|
|
|
|
//
|
|
// Bullish Momentum Bars ...
|
|
int momentumBarCount = ArraySize(mVWAPRangeStructure.bullishMomentumBars);
|
|
if ((canAll || canBullish) && IsValidSize(momentumBarCount))
|
|
{
|
|
//
|
|
for (int i = 0; i < momentumBarCount; i++)
|
|
{
|
|
//
|
|
XOHCL iBar = mVWAPRangeStructure.bullishMomentumBars[i];
|
|
|
|
//
|
|
XCBullishMomentumBarObject *iObj;
|
|
bool isCreated = mPOIDrawer.CreateBullishMomentumBar(
|
|
iBar,
|
|
iObj //
|
|
);
|
|
if (isCreated)
|
|
{
|
|
//
|
|
mDrawnObjects.Add(iObj);
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// Bearish Momentum Bars ...
|
|
momentumBarCount = ArraySize(mVWAPRangeStructure.bearishMomentumBars);
|
|
if ((canAll || canBearish) && IsValidSize(momentumBarCount))
|
|
{
|
|
//
|
|
for (int i = 0; i < momentumBarCount; i++)
|
|
{
|
|
//
|
|
XOHCL iBar = mVWAPRangeStructure.bearishMomentumBars[i];
|
|
|
|
//
|
|
XCBearishMomentumBarObject *iObj;
|
|
bool isCreated = mPOIDrawer.CreateBearishMomentumBar(
|
|
iBar,
|
|
iObj //
|
|
);
|
|
if (isCreated)
|
|
{
|
|
//
|
|
mDrawnObjects.Add(iObj);
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// Rejection Bars ...
|
|
|
|
//
|
|
// Bullish Rejection Bars ...
|
|
int rejectionBarCount = ArraySize(mVWAPRangeStructure.bullishRejectionBars);
|
|
if ((canAll || canBullish) && IsValidSize(rejectionBarCount))
|
|
{
|
|
//
|
|
for (int i = 0; i < rejectionBarCount; i++)
|
|
{
|
|
//
|
|
XOHCL iBar = mVWAPRangeStructure.bullishRejectionBars[i];
|
|
|
|
//
|
|
XCBullishRejectionBarObject *iObj;
|
|
bool isCreated = mPOIDrawer.CreateBullishRejectionBar(
|
|
iBar,
|
|
iObj //
|
|
);
|
|
if (isCreated)
|
|
{
|
|
//
|
|
mDrawnObjects.Add(iObj);
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// Bearish Rejection Bars ...
|
|
rejectionBarCount = ArraySize(mVWAPRangeStructure.bearishRejectionBars);
|
|
if ((canAll || canBearish) && IsValidSize(rejectionBarCount))
|
|
{
|
|
//
|
|
for (int i = 0; i < rejectionBarCount; i++)
|
|
{
|
|
//
|
|
XOHCL iBar = mVWAPRangeStructure.bearishRejectionBars[i];
|
|
|
|
//
|
|
XCBearishRejectionBarObject *iObj;
|
|
bool isCreated = mPOIDrawer.CreateBearishRejectionBar(
|
|
iBar,
|
|
iObj //
|
|
);
|
|
if (isCreated)
|
|
{
|
|
//
|
|
mDrawnObjects.Add(iObj);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// Override Draw Condition ...
|
|
|
|
/**
|
|
* Draw Specific Condition ...
|
|
*
|
|
* @param conditions: X121SMCStrategyConditions instance ...
|
|
*/
|
|
void DrawConditions(
|
|
X121SMCStrategyConditions &conditions //
|
|
)
|
|
{
|
|
//
|
|
// Draw Configurations ...
|
|
|
|
//
|
|
bool drawMainDemand = true;
|
|
bool drawMainSupply = true;
|
|
|
|
//
|
|
bool drawMainBullishOrderBlock = true;
|
|
bool drawMainBearishOrderBlock = true;
|
|
|
|
//
|
|
bool drawMainBullishFVG = true;
|
|
bool drawMainBearishFVG = true;
|
|
|
|
//
|
|
bool drawOrderBlocks = false;
|
|
bool drawFVGs = false;
|
|
bool drawSupportResistances = false;
|
|
bool drawSwings = false;
|
|
bool drawMomentumBars = false;
|
|
bool drawRejectionBars = false;
|
|
|
|
//
|
|
bool renewDates = true;
|
|
|
|
//
|
|
if (!conditions.IsValid())
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
datetime time = TimeCurrent();
|
|
bool hasValidDemand = conditions.ValidateDemand();
|
|
bool hasValidSupply = conditions.ValidateSupply();
|
|
if (!hasValidDemand && !hasValidSupply)
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
// Demand Zone ...
|
|
if (hasValidDemand)
|
|
{
|
|
//
|
|
// Demand ...
|
|
if (drawMainDemand)
|
|
{
|
|
//
|
|
if (renewDates)
|
|
{
|
|
conditions.demandZone.to = time;
|
|
}
|
|
|
|
//
|
|
XCDemandZoneObject *iObj;
|
|
bool isCreated = mPOIDrawer.CreateDemandZone(
|
|
conditions.demandZone,
|
|
iObj //
|
|
);
|
|
if (isCreated)
|
|
{
|
|
mDrawnObjects.Add(iObj);
|
|
}
|
|
}
|
|
|
|
//
|
|
if (drawMainBullishOrderBlock)
|
|
{
|
|
//
|
|
if (renewDates)
|
|
{
|
|
conditions.bullishOrderBlock.to = time;
|
|
}
|
|
|
|
//
|
|
XCBullishOrderBlockObject *iObj;
|
|
bool isCreated = mPOIDrawer.CreateBullishOrderBlock(
|
|
conditions.bullishOrderBlock,
|
|
iObj //
|
|
);
|
|
if (isCreated)
|
|
{
|
|
mDrawnObjects.Add(iObj);
|
|
}
|
|
}
|
|
|
|
//
|
|
if (drawMainBullishFVG)
|
|
{
|
|
//
|
|
if (renewDates)
|
|
{
|
|
conditions.bullishFVG.to = time;
|
|
}
|
|
|
|
//
|
|
XCBullishFVGObject *iObj;
|
|
bool isCreated = mPOIDrawer.CreateBullishFVG(
|
|
conditions.bullishFVG,
|
|
iObj //
|
|
);
|
|
if (isCreated)
|
|
{
|
|
mDrawnObjects.Add(iObj);
|
|
}
|
|
}
|
|
|
|
//
|
|
// Order Blocks ...
|
|
int obsCount = ArraySize(conditions.bullishOrderBlocks);
|
|
if (drawOrderBlocks &&
|
|
IsValidSize(obsCount))
|
|
{
|
|
//
|
|
for (int i = 0; i < obsCount; i++)
|
|
{
|
|
//
|
|
XZone iZone = conditions.bullishOrderBlocks[i];
|
|
|
|
//
|
|
if (renewDates)
|
|
{
|
|
iZone.to = time;
|
|
}
|
|
|
|
//
|
|
XCBullishOrderBlockObject *iObj;
|
|
bool isCreated = mPOIDrawer.CreateBullishOrderBlock(
|
|
iZone,
|
|
iObj //
|
|
);
|
|
if (isCreated)
|
|
{
|
|
mDrawnObjects.Add(iObj);
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// Fair Value Gaps ...
|
|
int fvgsCount = ArraySize(conditions.bullishFVGs);
|
|
if (drawFVGs &&
|
|
IsValidSize(fvgsCount))
|
|
{
|
|
//
|
|
for (int i = 0; i < fvgsCount; i++)
|
|
{
|
|
//
|
|
XZone iZone = conditions.bullishFVGs[i];
|
|
|
|
//
|
|
if (renewDates)
|
|
{
|
|
iZone.to = time;
|
|
}
|
|
|
|
//
|
|
XCBullishFVGObject *iObj;
|
|
bool isCreated = mPOIDrawer.CreateBullishFVG(
|
|
iZone,
|
|
iObj //
|
|
);
|
|
if (isCreated)
|
|
{
|
|
mDrawnObjects.Add(iObj);
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// Supports ...
|
|
int supportsCount = ArraySize(conditions.supports);
|
|
if (drawSupportResistances &&
|
|
IsValidSize(supportsCount))
|
|
{
|
|
//
|
|
for (int i = 0; i < supportsCount; i++)
|
|
{
|
|
//
|
|
XOHCL iBar = conditions.supports[i];
|
|
|
|
//
|
|
XCSupportZoneObject *iObj;
|
|
bool isCreated = mPOIDrawer.CreateSupportZone(
|
|
iBar,
|
|
iObj,
|
|
time //
|
|
);
|
|
if (isCreated)
|
|
{
|
|
mDrawnObjects.Add(iObj);
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// Swings ...
|
|
int swingsCount = ArraySize(conditions.swingLows);
|
|
if (drawSwings &&
|
|
IsValidSize(swingsCount))
|
|
{
|
|
//
|
|
for (int i = 0; i < swingsCount; i++)
|
|
{
|
|
//
|
|
XOHCL iBar = conditions.swingLows[i];
|
|
|
|
//
|
|
XCSwingLowObject *iObj;
|
|
bool isCreated = mPOIDrawer.CreateSwingLow(
|
|
iBar,
|
|
iObj //
|
|
);
|
|
if (isCreated)
|
|
{
|
|
mDrawnObjects.Add(iObj);
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// Momentum Bars ...
|
|
int momentumBarsCount = ArraySize(conditions.bullishMomentumBars);
|
|
if (drawMomentumBars &&
|
|
IsValidSize(momentumBarsCount))
|
|
{
|
|
//
|
|
for (int i = 0; i < momentumBarsCount; i++)
|
|
{
|
|
//
|
|
XOHCL iBar = conditions.bullishMomentumBars[i];
|
|
|
|
//
|
|
XCBullishMomentumBarObject *iObj;
|
|
bool isCreated = mPOIDrawer.CreateBullishMomentumBar(
|
|
iBar,
|
|
iObj //
|
|
);
|
|
if (isCreated)
|
|
{
|
|
mDrawnObjects.Add(iObj);
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// Rejection Bars ...
|
|
int rejectionBarsCount = ArraySize(conditions.bullishRejectionBars);
|
|
if (drawRejectionBars &&
|
|
IsValidSize(rejectionBarsCount))
|
|
{
|
|
//
|
|
for (int i = 0; i < rejectionBarsCount; i++)
|
|
{
|
|
//
|
|
XOHCL iBar = conditions.bullishRejectionBars[i];
|
|
|
|
//
|
|
XCBullishRejectionBarObject *iObj;
|
|
bool isCreated = mPOIDrawer.CreateBullishRejectionBar(
|
|
iBar,
|
|
iObj //
|
|
);
|
|
if (isCreated)
|
|
{
|
|
mDrawnObjects.Add(iObj);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// Supply Zone ...
|
|
if (hasValidSupply)
|
|
{
|
|
//
|
|
// Supply ...
|
|
if (drawMainSupply)
|
|
{
|
|
//
|
|
if (renewDates)
|
|
{
|
|
conditions.supplyZone.to = time;
|
|
}
|
|
|
|
//
|
|
XCSupplyZoneObject *iObj;
|
|
bool isCreated = mPOIDrawer.CreateSupplyZone(
|
|
conditions.supplyZone,
|
|
iObj //
|
|
);
|
|
if (isCreated)
|
|
{
|
|
mDrawnObjects.Add(iObj);
|
|
}
|
|
}
|
|
|
|
//
|
|
if (drawMainBearishOrderBlock)
|
|
{
|
|
//
|
|
if (renewDates)
|
|
{
|
|
conditions.bearishOrderBlock.to = time;
|
|
}
|
|
|
|
//
|
|
XCBearishOrderBlockObject *iObj;
|
|
bool isCreated = mPOIDrawer.CreateBearishOrderBlock(
|
|
conditions.bearishOrderBlock,
|
|
iObj //
|
|
);
|
|
if (isCreated)
|
|
{
|
|
mDrawnObjects.Add(iObj);
|
|
}
|
|
}
|
|
|
|
//
|
|
if (drawMainBearishFVG)
|
|
{
|
|
//
|
|
if (renewDates)
|
|
{
|
|
conditions.bearishFVG.to = time;
|
|
}
|
|
|
|
//
|
|
XCBearishFVGObject *iObj;
|
|
bool isCreated = mPOIDrawer.CreateBearishFVG(
|
|
conditions.bearishFVG,
|
|
iObj //
|
|
);
|
|
if (isCreated)
|
|
{
|
|
mDrawnObjects.Add(iObj);
|
|
}
|
|
}
|
|
|
|
//
|
|
// Order Blocks ...
|
|
int obsCount = ArraySize(conditions.bearishOrderBlocks);
|
|
if (drawOrderBlocks &&
|
|
IsValidSize(obsCount))
|
|
{
|
|
//
|
|
for (int i = 0; i < obsCount; i++)
|
|
{
|
|
//
|
|
XZone iZone = conditions.bearishOrderBlocks[i];
|
|
|
|
//
|
|
if (renewDates)
|
|
{
|
|
iZone.to = time;
|
|
}
|
|
|
|
//
|
|
XCBearishOrderBlockObject *iObj;
|
|
bool isCreated = mPOIDrawer.CreateBearishOrderBlock(
|
|
iZone,
|
|
iObj //
|
|
);
|
|
if (isCreated)
|
|
{
|
|
mDrawnObjects.Add(iObj);
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// Fair Value Gaps ...
|
|
int fvgsCount = ArraySize(conditions.bearishFVGs);
|
|
if (drawFVGs &&
|
|
IsValidSize(fvgsCount))
|
|
{
|
|
//
|
|
for (int i = 0; i < fvgsCount; i++)
|
|
{
|
|
//
|
|
XZone iZone = conditions.bearishFVGs[i];
|
|
|
|
//
|
|
if (renewDates)
|
|
{
|
|
iZone.to = time;
|
|
}
|
|
|
|
//
|
|
XCBearishFVGObject *iObj;
|
|
bool isCreated = mPOIDrawer.CreateBearishFVG(
|
|
iZone,
|
|
iObj //
|
|
);
|
|
if (isCreated)
|
|
{
|
|
mDrawnObjects.Add(iObj);
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// Resistances ...
|
|
int resistancesCount = ArraySize(conditions.resistances);
|
|
if (drawSupportResistances &&
|
|
IsValidSize(resistancesCount))
|
|
{
|
|
//
|
|
for (int i = 0; i < resistancesCount; i++)
|
|
{
|
|
//
|
|
XOHCL iBar = conditions.resistances[i];
|
|
|
|
//
|
|
XCResistanceZoneObject *iObj;
|
|
bool isCreated = mPOIDrawer.CreateResistanceZone(
|
|
iBar,
|
|
iObj,
|
|
time //
|
|
);
|
|
if (isCreated)
|
|
{
|
|
mDrawnObjects.Add(iObj);
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// Swings ...
|
|
int swingsCount = ArraySize(conditions.swingHighs);
|
|
if (drawSwings &&
|
|
IsValidSize(swingsCount))
|
|
{
|
|
//
|
|
for (int i = 0; i < swingsCount; i++)
|
|
{
|
|
//
|
|
XOHCL iBar = conditions.swingHighs[i];
|
|
|
|
//
|
|
XCSwingHighObject *iObj;
|
|
bool isCreated = mPOIDrawer.CreateSwingHigh(
|
|
iBar,
|
|
iObj //
|
|
);
|
|
if (isCreated)
|
|
{
|
|
mDrawnObjects.Add(iObj);
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// Momentum Bars ...
|
|
int momentumBarsCount = ArraySize(conditions.bearishMomentumBars);
|
|
if (drawMomentumBars &&
|
|
IsValidSize(momentumBarsCount))
|
|
{
|
|
//
|
|
for (int i = 0; i < momentumBarsCount; i++)
|
|
{
|
|
//
|
|
XOHCL iBar = conditions.bearishMomentumBars[i];
|
|
|
|
//
|
|
XCBearishMomentumBarObject *iObj;
|
|
bool isCreated = mPOIDrawer.CreateBearishMomentumBar(
|
|
iBar,
|
|
iObj //
|
|
);
|
|
if (isCreated)
|
|
{
|
|
mDrawnObjects.Add(iObj);
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// Rejection Bars ...
|
|
int rejectionBarsCount = ArraySize(conditions.bearishRejectionBars);
|
|
if (drawRejectionBars &&
|
|
IsValidSize(rejectionBarsCount))
|
|
{
|
|
//
|
|
for (int i = 0; i < rejectionBarsCount; i++)
|
|
{
|
|
//
|
|
XOHCL iBar = conditions.bearishRejectionBars[i];
|
|
|
|
//
|
|
XCBearishRejectionBarObject *iObj;
|
|
bool isCreated = mPOIDrawer.CreateBearishRejectionBar(
|
|
iBar,
|
|
iObj //
|
|
);
|
|
if (isCreated)
|
|
{
|
|
mDrawnObjects.Add(iObj);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
};
|
|
|
|
// |