3960 lines
104 KiB
Plaintext
3960 lines
104 KiB
Plaintext
///////////////////////////////////////////////////////
|
|
//
|
|
// SaherElm IT Center MQL5 X121 SMC Signal Class
|
|
// -------------------------------------------------
|
|
// Name: XWZ
|
|
// Description: provide all Signalling functions ...
|
|
//
|
|
//
|
|
// Maintainer:
|
|
// ------------
|
|
// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com)
|
|
//
|
|
//////////////////////////////////////////////////////
|
|
//
|
|
// Global Properties ...
|
|
#property library
|
|
#property copyright "Copyright 2023, SaherElm IT Center"
|
|
#property link "https://www.saherelm.ir"
|
|
#property version "1.00"
|
|
#property strict
|
|
|
|
//
|
|
// Imports ...
|
|
#include "../Classes/x-121.smc.market.cycle.helper.class.mq5"
|
|
#include "../Libraries/x-121.smc.guard.lib.mq5"
|
|
#include "../Libraries/x-121.smc.lib.mq5"
|
|
#include "./x-121.smc.xwz.signal.lib.mq5"
|
|
|
|
//
|
|
// Definition ...
|
|
class XCX121SMCXWZSignalDetector : public XCBase
|
|
{
|
|
//
|
|
public:
|
|
//
|
|
// Props ...
|
|
XOBFVG chochZone;
|
|
XOBFVG targetZone;
|
|
XOBFVG signalZone;
|
|
XOBFVG waitingZone;
|
|
X121SMCStrategyXWZWorkingZone workingZone;
|
|
X121SMCStrategyXWZSignalConditions mConditions;
|
|
X121SMCStrategyXWZSignalConditions mConditionsCollection[];
|
|
|
|
//
|
|
// Constructor(s) ...
|
|
XCX121SMCXWZSignalDetector(
|
|
string _symbol,
|
|
ENUM_TIMEFRAMES _period //
|
|
)
|
|
{
|
|
//
|
|
symbol = _symbol;
|
|
period = _period;
|
|
Init();
|
|
}
|
|
|
|
//
|
|
// Deconstructor ...
|
|
~XCX121SMCXWZSignalDetector()
|
|
{
|
|
DeInit();
|
|
}
|
|
|
|
//
|
|
//
|
|
//
|
|
|
|
//
|
|
// Detect Setup Conditions ...
|
|
bool DetectSignalSetup(
|
|
//
|
|
XC121SMCCycleHelper *decisionCycleHelper,
|
|
XC121SMCCycleHelper *analyseCycleHelper,
|
|
XC121SMCCycleHelper *consolidationCycleHelper,
|
|
XC121SMCCycleHelper *visionCycleHelper
|
|
//
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Validate Cycle Helpers ...
|
|
result =
|
|
//
|
|
visionCycleHelper != NULL &&
|
|
analyseCycleHelper != NULL &&
|
|
decisionCycleHelper != NULL &&
|
|
consolidationCycleHelper != NULL
|
|
//
|
|
;
|
|
if (!result)
|
|
{
|
|
//
|
|
mConditions.Clean();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
bool isBullish = false;
|
|
bool isBearish = false;
|
|
|
|
//
|
|
int zIndex = 0;
|
|
int cIndex = zIndex + 1;
|
|
int pIndex = cIndex + 1;
|
|
int ppIndex = pIndex + 1;
|
|
|
|
//
|
|
int loopback = 10;
|
|
|
|
//
|
|
mConditions.symbol = symbol;
|
|
mConditions.period = period;
|
|
|
|
//
|
|
double ask = GetAsk(symbol);
|
|
double bid = GetBid(symbol);
|
|
datetime cTime = TimeCurrent();
|
|
double points = GetPoints(symbol);
|
|
|
|
//
|
|
double pivot = 0;
|
|
double point = 0;
|
|
double target = 0;
|
|
double reward = 0;
|
|
double amountPercent = 0;
|
|
ENUM_X121SMC_XWZ_PRIORITY priority = X121SMC_XWZ_PRIORITY_NONE;
|
|
|
|
//
|
|
// Cycles Conditions ...
|
|
|
|
//
|
|
XOHCL consolidationZBar;
|
|
result = consolidationCycleHelper.GetBar(
|
|
consolidationZBar,
|
|
zIndex //
|
|
);
|
|
if (!result)
|
|
{
|
|
//
|
|
consolidationZBar.Clean();
|
|
return result;
|
|
}
|
|
|
|
//
|
|
bool drawBar = true;
|
|
if (drawBar)
|
|
{
|
|
//
|
|
DrawBar(
|
|
consolidationZBar,
|
|
decisionCycleHelper.mPOIDrawer //
|
|
);
|
|
}
|
|
|
|
//
|
|
// Decision ...
|
|
ENUM_XPOI_EVENTS decisionPoiEvents[];
|
|
ENUM_X_CYCLE_EVENTS decisionCycleEvents[];
|
|
X121SMCCycleConditions decisionConditions;
|
|
result = decisionCycleHelper.GetConditions(
|
|
decisionCycleEvents,
|
|
decisionPoiEvents,
|
|
decisionConditions,
|
|
zIndex,
|
|
loopback //
|
|
);
|
|
if (!result)
|
|
{
|
|
//
|
|
Clean(decisionPoiEvents);
|
|
Clean(decisionCycleEvents);
|
|
|
|
//
|
|
decisionConditions.Clean();
|
|
|
|
//
|
|
mConditions.Clean();
|
|
consolidationZBar.Clean();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Analyse ...
|
|
ENUM_XPOI_EVENTS analysePoiEvents[];
|
|
ENUM_X_CYCLE_EVENTS analyseCycleEvents[];
|
|
X121SMCCycleConditions analyseConditions;
|
|
result = analyseCycleHelper.GetConditions(
|
|
analyseCycleEvents,
|
|
analysePoiEvents,
|
|
analyseConditions,
|
|
zIndex,
|
|
loopback //
|
|
);
|
|
if (!result)
|
|
{
|
|
//
|
|
Clean(analysePoiEvents);
|
|
Clean(decisionPoiEvents);
|
|
|
|
//
|
|
Clean(analyseCycleEvents);
|
|
Clean(decisionCycleEvents);
|
|
|
|
//
|
|
analyseConditions.Clean();
|
|
decisionConditions.Clean();
|
|
|
|
//
|
|
mConditions.Clean();
|
|
consolidationZBar.Clean();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Consolidation ...
|
|
ENUM_XPOI_EVENTS consolidationPoiEvents[];
|
|
ENUM_X_CYCLE_EVENTS consolidationCycleEvents[];
|
|
X121SMCCycleConditions consolidationConditions;
|
|
result = consolidationCycleHelper.GetConditions(
|
|
consolidationCycleEvents,
|
|
consolidationPoiEvents,
|
|
consolidationConditions,
|
|
zIndex,
|
|
loopback //
|
|
);
|
|
if (!result)
|
|
{
|
|
//
|
|
Clean(analysePoiEvents);
|
|
Clean(decisionPoiEvents);
|
|
Clean(consolidationPoiEvents);
|
|
|
|
//
|
|
Clean(analyseCycleEvents);
|
|
Clean(decisionCycleEvents);
|
|
Clean(consolidationCycleEvents);
|
|
|
|
//
|
|
analyseConditions.Clean();
|
|
decisionConditions.Clean();
|
|
consolidationConditions.Clean();
|
|
|
|
//
|
|
mConditions.Clean();
|
|
consolidationZBar.Clean();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Vision ...
|
|
ENUM_XPOI_EVENTS visionPoiEvents[];
|
|
ENUM_X_CYCLE_EVENTS visionCycleEvents[];
|
|
X121SMCCycleConditions visionConditions;
|
|
result = visionCycleHelper.GetConditions(
|
|
visionCycleEvents,
|
|
visionPoiEvents,
|
|
visionConditions,
|
|
zIndex,
|
|
loopback //
|
|
);
|
|
if (!result)
|
|
{
|
|
//
|
|
Clean(visionPoiEvents);
|
|
Clean(analysePoiEvents);
|
|
Clean(decisionPoiEvents);
|
|
Clean(consolidationPoiEvents);
|
|
|
|
//
|
|
Clean(visionCycleEvents);
|
|
Clean(analyseCycleEvents);
|
|
Clean(decisionCycleEvents);
|
|
Clean(consolidationCycleEvents);
|
|
|
|
//
|
|
visionConditions.Clean();
|
|
analyseConditions.Clean();
|
|
decisionConditions.Clean();
|
|
consolidationConditions.Clean();
|
|
|
|
//
|
|
mConditions.Clean();
|
|
consolidationZBar.Clean();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Cycles POI States ...
|
|
XPOIState decisionState = decisionConditions.state;
|
|
XPOIState analyseState = analyseConditions.state;
|
|
XPOIState consolidationState = consolidationConditions.state;
|
|
XPOIState visionState = visionConditions.state;
|
|
|
|
//
|
|
// Cycle X121Conditions ...
|
|
X121Conditions decisionXConditions = decisionConditions.x121Conditions;
|
|
X121Conditions analyseXConditions = analyseConditions.x121Conditions;
|
|
X121Conditions consolidationXConditions = consolidationConditions.x121Conditions;
|
|
X121Conditions visionXConditions = visionConditions.x121Conditions;
|
|
|
|
//
|
|
// Setup Conditions ...
|
|
|
|
//
|
|
// Choch Trading Senario ...
|
|
bool hasChochBullishConditions = false;
|
|
bool hasChochBearishConditions = false;
|
|
|
|
//
|
|
// Order Flow Side Trading Senario ...
|
|
bool hasOrderFlowhBullishConditions = false;
|
|
bool hasOrderFlowhBearishConditions = false;
|
|
|
|
//
|
|
// Trend Line Trading Senario ...
|
|
bool hasTrendLineBullishConditions = false;
|
|
bool hasTrendLineBearishConditions = false;
|
|
|
|
//
|
|
// Quarter Line Trading Senario ...
|
|
bool hasBQuarterLineBullishConditions = false;
|
|
bool hasBQuarterLineBearishConditions = false;
|
|
|
|
//
|
|
// Supply and Demand Trading Senario ...
|
|
bool hasSupDemBullishConditions = false;
|
|
bool hasSupDemBearishConditions = false;
|
|
|
|
//
|
|
// Support and Resistance Trading Senario ...
|
|
bool hasSupResBullishConditions = false;
|
|
bool hasSupResBearishConditions = false;
|
|
|
|
//
|
|
ENUM_X121SMC_XWZ_PROVIDERS provider = X121SMC_XWZ_PROVIDER_NONE;
|
|
|
|
//
|
|
// Detect Working Zone ...
|
|
bool hasWorkingZone = workingZone.IsValid();
|
|
if (!hasWorkingZone)
|
|
{
|
|
hasWorkingZone = DetectWorkingZone(visionState);
|
|
}
|
|
|
|
//
|
|
// result = hasWorkingZone;
|
|
// if (!result)
|
|
// {
|
|
// //
|
|
// Clean(visionPoiEvents);
|
|
// Clean(analysePoiEvents);
|
|
// Clean(decisionPoiEvents);
|
|
// Clean(consolidationPoiEvents);
|
|
|
|
// //
|
|
// Clean(visionCycleEvents);
|
|
// Clean(analyseCycleEvents);
|
|
// Clean(decisionCycleEvents);
|
|
// Clean(consolidationCycleEvents);
|
|
|
|
// //
|
|
// visionState.Clean();
|
|
// analyseState.Clean();
|
|
// decisionState.Clean();
|
|
// consolidationState.Clean();
|
|
|
|
// //
|
|
// visionConditions.Clean();
|
|
// analyseConditions.Clean();
|
|
// decisionConditions.Clean();
|
|
// consolidationConditions.Clean();
|
|
|
|
// //
|
|
// visionXConditions.Clean();
|
|
// analyseXConditions.Clean();
|
|
// decisionXConditions.Clean();
|
|
// consolidationXConditions.Clean();
|
|
|
|
// //
|
|
// mConditions.Clean();
|
|
// consolidationZBar.Clean();
|
|
|
|
// //
|
|
// return result;
|
|
// }
|
|
|
|
//
|
|
// Supply Zones ...
|
|
bool hasSupplyZones = workingZone.HasSupplyZones();
|
|
int supplyZonesCount = workingZone.CountSupplyZones();
|
|
if (hasWorkingZone)
|
|
{
|
|
//
|
|
supplyZonesCount = workingZone
|
|
.DetectSupplyZones(consolidationState);
|
|
hasSupplyZones = IsValidSize(supplyZonesCount);
|
|
}
|
|
|
|
//
|
|
// Demand Zones ...
|
|
bool hasDemandZones = workingZone.HasDemandZones();
|
|
int demandZonesCount = workingZone.CountDemandZones();
|
|
if (hasWorkingZone)
|
|
{
|
|
//
|
|
demandZonesCount = workingZone
|
|
.DetectDemandZones(consolidationState);
|
|
hasDemandZones = IsValidSize(demandZonesCount);
|
|
}
|
|
|
|
//
|
|
// TODO: Remove this ...
|
|
UpdateTo(cTime);
|
|
|
|
//
|
|
// Detect Working Zone Destroy ...
|
|
bool isWorkingZoneDetroyed =
|
|
hasWorkingZone &&
|
|
workingZone.IsDestroyed();
|
|
if (isWorkingZoneDetroyed)
|
|
{
|
|
mWorkingZoneObjects.Clear();
|
|
}
|
|
|
|
//
|
|
// result = !isWorkingZoneDetroyed;
|
|
// if (!result)
|
|
// {
|
|
// //
|
|
// workingZone.Clean();
|
|
// mWorkingZoneObjects.Clear();
|
|
|
|
// //
|
|
// Clean(visionPoiEvents);
|
|
// Clean(analysePoiEvents);
|
|
// Clean(decisionPoiEvents);
|
|
// Clean(consolidationPoiEvents);
|
|
|
|
// //
|
|
// Clean(visionCycleEvents);
|
|
// Clean(analyseCycleEvents);
|
|
// Clean(decisionCycleEvents);
|
|
// Clean(consolidationCycleEvents);
|
|
|
|
// //
|
|
// visionState.Clean();
|
|
// analyseState.Clean();
|
|
// decisionState.Clean();
|
|
// consolidationState.Clean();
|
|
|
|
// //
|
|
// visionConditions.Clean();
|
|
// analyseConditions.Clean();
|
|
// decisionConditions.Clean();
|
|
// consolidationConditions.Clean();
|
|
|
|
// //
|
|
// visionXConditions.Clean();
|
|
// analyseXConditions.Clean();
|
|
// decisionXConditions.Clean();
|
|
// consolidationXConditions.Clean();
|
|
|
|
// //
|
|
// mConditions.Clean();
|
|
// consolidationZBar.Clean();
|
|
|
|
// //
|
|
// return result;
|
|
// }
|
|
|
|
//
|
|
// Checking Target Zone Breaked ...
|
|
bool hasTargetZone = targetZone.IsValid();
|
|
if (hasTargetZone)
|
|
{
|
|
//
|
|
XOHCL bar;
|
|
bool isInited = bar.Init(
|
|
symbol,
|
|
period,
|
|
zIndex //
|
|
);
|
|
|
|
XOHCL cBar;
|
|
isInited =
|
|
isInited &&
|
|
bar.GetPreviousBar(cBar);
|
|
|
|
//
|
|
bool isBullish = targetZone.IsBullish();
|
|
|
|
//
|
|
bool isLowerBreaked =
|
|
//
|
|
bar.high < targetZone.ob.Lower() &&
|
|
cBar.high < targetZone.ob.Lower()
|
|
//
|
|
;
|
|
|
|
//
|
|
bool isUpperBreaked =
|
|
//
|
|
bar.low > targetZone.ob.Upper() &&
|
|
cBar.low > targetZone.ob.Upper()
|
|
//
|
|
;
|
|
|
|
//
|
|
bool isBreaked = isBullish
|
|
? isLowerBreaked
|
|
: isUpperBreaked;
|
|
if (isBreaked)
|
|
{
|
|
//
|
|
mWorkingZoneObjects.Clear();
|
|
targetZone.Clean();
|
|
}
|
|
}
|
|
|
|
//
|
|
// Detect Order Flow ...
|
|
ENUM_X_DIRECTION trend = X_DIRECTION_NONE;
|
|
bool hasOrderFlow =
|
|
hasWorkingZone &&
|
|
workingZone.HasOrderFlow(trend);
|
|
if (!hasOrderFlow)
|
|
{
|
|
//
|
|
int orderFlowCount = workingZone.DetectOrderFlow(
|
|
symbol,
|
|
period,
|
|
trend,
|
|
visionState,
|
|
consolidationState,
|
|
analyseState,
|
|
decisionState //
|
|
);
|
|
hasOrderFlow = IsValidSize(orderFlowCount);
|
|
}
|
|
|
|
//
|
|
bool hasTrend = HasDirection(trend);
|
|
bool hasBllishTrend =
|
|
hasTrend &&
|
|
IsBullish(trend);
|
|
bool hasBearishTrend =
|
|
hasTrend &&
|
|
IsBearish(trend);
|
|
|
|
//
|
|
UpdateTo(cTime);
|
|
|
|
//
|
|
isBullish = IsBullish(trend);
|
|
isBearish = IsBearish(trend);
|
|
|
|
//
|
|
bool hasPriority = workingZone
|
|
.DetectPriority(
|
|
priority,
|
|
trend,
|
|
zIndex,
|
|
period //
|
|
);
|
|
|
|
//
|
|
bool hasRewardAmount = CalculateRiskReward(
|
|
priority,
|
|
reward,
|
|
amountPercent //
|
|
);
|
|
|
|
//
|
|
// Checking Order Flow Break ...
|
|
int breakedIDX = -1;
|
|
bool isOrderFlowBreaked =
|
|
hasOrderFlow &&
|
|
hasWorkingZone &&
|
|
workingZone.IsOrderFlowBreaked(
|
|
breakedIDX,
|
|
true, // Force OB Breaked
|
|
false, // Force FVG Breaked
|
|
zIndex,
|
|
period //
|
|
);
|
|
|
|
//
|
|
// Order Flow Breaked Senario ...
|
|
if (isOrderFlowBreaked)
|
|
{
|
|
//
|
|
AddRef(
|
|
workingZone.orderFlow[breakedIDX],
|
|
workingZone.brokenOrderFlow //
|
|
);
|
|
|
|
//
|
|
signalZone = workingZone.orderFlow[breakedIDX];
|
|
provider = X121SMC_XWZ_PROVIDER_ACTIVATED_CHOCH;
|
|
|
|
//
|
|
ArrayRemove(
|
|
workingZone.orderFlow,
|
|
breakedIDX,
|
|
1 //
|
|
);
|
|
Clean(workingZone.orderFlow);
|
|
|
|
//
|
|
CleanupArray(
|
|
workingZone.brokenOrderFlow,
|
|
10 //
|
|
);
|
|
}
|
|
|
|
//
|
|
// First Check Last Order Flow FVG ...
|
|
XOBFVG youngestOrderFlow;
|
|
int youngestOBFVGIDX = GetYoungest(workingZone.orderFlow);
|
|
bool hasYoungestOBFVG = IsValidIndex(youngestOBFVGIDX);
|
|
if (hasYoungestOBFVG)
|
|
{
|
|
//
|
|
youngestOrderFlow = workingZone.orderFlow[youngestOBFVGIDX];
|
|
|
|
//
|
|
XOHCL obWorkerBar;
|
|
XOHCL obActivationBar;
|
|
|
|
//
|
|
XOHCL fvgWorkerBar;
|
|
XOHCL fvgActivationBar;
|
|
|
|
//
|
|
bool isOBBodyOut = false;
|
|
bool isOBWorked = youngestOrderFlow
|
|
.ob
|
|
.IsWorked(
|
|
trend,
|
|
obWorkerBar,
|
|
isOBBodyOut,
|
|
false //
|
|
);
|
|
|
|
//
|
|
bool isOBBodyIn = false;
|
|
bool isOBActivated = youngestOrderFlow
|
|
.ob
|
|
.IsActivated(
|
|
trend,
|
|
obActivationBar,
|
|
isOBBodyIn,
|
|
false //
|
|
);
|
|
|
|
//
|
|
bool isFVGBodyOut = false;
|
|
bool isFVGWorked = youngestOrderFlow
|
|
.fvg
|
|
.IsWorked(
|
|
trend,
|
|
fvgWorkerBar,
|
|
isFVGBodyOut,
|
|
false //
|
|
);
|
|
|
|
//
|
|
bool isFVGBodyIn = false;
|
|
bool isFVGActivated = youngestOrderFlow
|
|
.fvg
|
|
.IsActivated(
|
|
trend,
|
|
fvgActivationBar,
|
|
isFVGBodyIn,
|
|
false //
|
|
);
|
|
|
|
//
|
|
if (!isFVGWorked &&
|
|
isFVGActivated)
|
|
{
|
|
//
|
|
youngestOrderFlow
|
|
.UpdateZones(decisionState);
|
|
|
|
//
|
|
signalZone = youngestOrderFlow;
|
|
youngestOrderFlow.Clean();
|
|
ArrayRemove(
|
|
workingZone.orderFlow,
|
|
youngestOBFVGIDX,
|
|
1 //
|
|
);
|
|
|
|
//
|
|
provider = X121SMC_XWZ_PROVIDER_ACTIVATED_ZONE;
|
|
}
|
|
else
|
|
{
|
|
//
|
|
bool isPriceInsideFVG =
|
|
//
|
|
IsInside(
|
|
consolidationZBar.high,
|
|
youngestOrderFlow.fvg //
|
|
)
|
|
//
|
|
&&
|
|
//
|
|
IsInside(
|
|
consolidationZBar.low,
|
|
youngestOrderFlow.fvg //
|
|
)
|
|
//
|
|
;
|
|
|
|
//
|
|
if (isPriceInsideFVG)
|
|
{
|
|
//
|
|
youngestOrderFlow
|
|
.UpdateZones(decisionState);
|
|
|
|
//
|
|
signalZone = youngestOrderFlow;
|
|
youngestOrderFlow.Clean();
|
|
ArrayRemove(
|
|
workingZone.orderFlow,
|
|
youngestOBFVGIDX,
|
|
1 //
|
|
);
|
|
|
|
//
|
|
provider = X121SMC_XWZ_PROVIDER_PRICE_INSIDE_ZONE;
|
|
}
|
|
}
|
|
|
|
//
|
|
fvgWorkerBar.Clean();
|
|
fvgActivationBar.Clean();
|
|
}
|
|
|
|
//
|
|
// Check New Order Blocks ...
|
|
bool hasNewConsolidationBullishOB = Contains(
|
|
X_BULLISH_ORDERBLOCK_DETECTED,
|
|
consolidationPoiEvents //
|
|
);
|
|
bool hasNewConsolidationBearishOB = Contains(
|
|
X_BEARISH_ORDERBLOCK_DETECTED,
|
|
consolidationPoiEvents //
|
|
);
|
|
bool hasNewOB = hasNewConsolidationBullishOB ||
|
|
hasNewConsolidationBearishOB;
|
|
|
|
//
|
|
// Check New Fair Value Gaps ...
|
|
bool hasNewConsolidationBullishFVG = Contains(
|
|
X_BULLISH_FVG_DETECTED,
|
|
consolidationPoiEvents //
|
|
);
|
|
bool hasNewConsolidationBearishFVG = Contains(
|
|
X_BEARISH_FVG_DETECTED,
|
|
consolidationPoiEvents //
|
|
);
|
|
bool hasNewFVG = hasNewConsolidationBullishFVG ||
|
|
hasNewConsolidationBearishFVG;
|
|
|
|
//
|
|
// Check New Order Blocks ...
|
|
bool hasNewAnalyseBullishOrderBlock = Contains(
|
|
X_BULLISH_ORDERBLOCK_DETECTED,
|
|
analysePoiEvents //
|
|
);
|
|
bool hasNewAnalyseBearishOrderBlock = Contains(
|
|
X_BEARISH_ORDERBLOCK_DETECTED,
|
|
analysePoiEvents //
|
|
);
|
|
bool hasNewAnalyseOB = hasNewAnalyseBullishOrderBlock ||
|
|
hasNewAnalyseBearishOrderBlock;
|
|
|
|
//
|
|
// Check New Fair Value Gaps ...
|
|
bool hasNewAnalyseBullishFVG = Contains(
|
|
X_BULLISH_FVG_DETECTED,
|
|
analysePoiEvents //
|
|
);
|
|
bool hasNewAnalyseBearishFVG = Contains(
|
|
X_BEARISH_FVG_DETECTED,
|
|
analysePoiEvents //
|
|
);
|
|
bool hasNewAnalyseFVG = hasNewAnalyseBullishFVG ||
|
|
hasNewAnalyseBearishFVG;
|
|
|
|
//
|
|
// Do Order Flow Actions when new Order Blocks
|
|
// or FVGs Formed ...
|
|
if (hasNewOB ||
|
|
hasNewFVG ||
|
|
hasNewAnalyseOB ||
|
|
hasNewAnalyseFVG)
|
|
{
|
|
//
|
|
XCFVG *newFVG = NULL;
|
|
XCOrderBlock *newOB = NULL;
|
|
XCFVG *newAnalyseFVG = NULL;
|
|
XCOrderBlock *newAnalyseOB = NULL;
|
|
|
|
//
|
|
bool isValid = false;
|
|
bool hasWaitingZone = waitingZone.IsValid();
|
|
|
|
//
|
|
int idx = -1;
|
|
if (hasNewOB)
|
|
{
|
|
//
|
|
if (hasNewConsolidationBullishOB)
|
|
{
|
|
//
|
|
idx = consolidationState.CountBullishOrderBlocks() - 1;
|
|
newOB = consolidationState.bullishOrderBlocks[idx];
|
|
}
|
|
else
|
|
{
|
|
//
|
|
idx = consolidationState.CountBearishOrderBlocks() - 1;
|
|
newOB = consolidationState.bearishOrderBlocks[idx];
|
|
}
|
|
|
|
//
|
|
if (hasWaitingZone)
|
|
{
|
|
}
|
|
else
|
|
{
|
|
//
|
|
isValid =
|
|
!waitingZone.HasOB()
|
|
? true
|
|
: !IsSame(
|
|
newOB,
|
|
waitingZone.ob //
|
|
);
|
|
if (isValid)
|
|
{
|
|
//
|
|
bool isAbove = IsAbove(
|
|
newOB,
|
|
youngestOrderFlow.ob,
|
|
true // Ignore Inside ...
|
|
);
|
|
bool isBelow = IsBelow(
|
|
newOB,
|
|
youngestOrderFlow.ob,
|
|
true // Ignore Inside ...
|
|
);
|
|
|
|
//
|
|
isValid =
|
|
isBullish
|
|
? isAbove
|
|
: isBelow;
|
|
|
|
//
|
|
if (isValid)
|
|
{
|
|
waitingZone.ob = newOB;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
if (hasNewFVG)
|
|
{
|
|
//
|
|
if (hasNewConsolidationBullishFVG)
|
|
{
|
|
//
|
|
idx = consolidationState.CountBullishFairValueGaps() - 1;
|
|
newFVG = consolidationState.bullishFairValueGaps[idx];
|
|
}
|
|
else
|
|
{
|
|
//
|
|
idx = consolidationState.CountBearishFairValueGaps() - 1;
|
|
newFVG = consolidationState.bearishFairValueGaps[idx];
|
|
}
|
|
}
|
|
|
|
//
|
|
if (hasNewAnalyseOB)
|
|
{
|
|
//
|
|
if (hasNewAnalyseBullishOrderBlock)
|
|
{
|
|
//
|
|
idx = analyseState.CountBullishOrderBlocks() - 1;
|
|
newAnalyseOB = analyseState.bullishOrderBlocks[idx];
|
|
}
|
|
else
|
|
{
|
|
//
|
|
idx = analyseState.CountBearishOrderBlocks() - 1;
|
|
newAnalyseOB = analyseState.bearishOrderBlocks[idx];
|
|
}
|
|
}
|
|
|
|
//
|
|
if (hasNewAnalyseFVG)
|
|
{
|
|
//
|
|
if (hasNewAnalyseBullishFVG)
|
|
{
|
|
//
|
|
idx = analyseState.CountBullishFairValueGaps() - 1;
|
|
newAnalyseFVG = analyseState.bullishFairValueGaps[idx];
|
|
}
|
|
else
|
|
{
|
|
//
|
|
idx = analyseState.CountBearishFairValueGaps() - 1;
|
|
newAnalyseFVG = analyseState.bearishFairValueGaps[idx];
|
|
}
|
|
|
|
//
|
|
if (hasWaitingZone)
|
|
{
|
|
}
|
|
else
|
|
{
|
|
//
|
|
if (waitingZone.HasOB())
|
|
{
|
|
//
|
|
XCFVG *tmpFVGs[];
|
|
XCFVG *tmpWorkingFVGs[];
|
|
bool isOBBullish = waitingZone.ob.IsBullish();
|
|
if (isOBBullish)
|
|
{
|
|
Copy(
|
|
analyseState.bullishFairValueGaps,
|
|
tmpFVGs //
|
|
);
|
|
}
|
|
else
|
|
{
|
|
Copy(
|
|
analyseState.bearishFairValueGaps,
|
|
tmpFVGs //
|
|
);
|
|
}
|
|
|
|
//
|
|
for (int j = 0; j < ArraySize(tmpFVGs); j++)
|
|
{
|
|
//
|
|
XCFVG *jFVG = tmpFVGs[j];
|
|
|
|
//
|
|
// Check Start Date ...
|
|
bool isFromPassed = jFVG.From() > waitingZone.ob.From();
|
|
if (!isFromPassed)
|
|
{
|
|
//
|
|
ZeroMemory(jFVG);
|
|
continue;
|
|
}
|
|
|
|
//
|
|
// Check Place ...
|
|
|
|
//
|
|
bool isAbove = IsAboveDiff(
|
|
jFVG,
|
|
waitingZone.ob,
|
|
true //
|
|
);
|
|
|
|
//
|
|
bool isBelow = IsBelowDiff(
|
|
jFVG,
|
|
waitingZone.ob,
|
|
true //
|
|
);
|
|
|
|
//
|
|
bool isInside = IsInsideDiff(
|
|
jFVG,
|
|
waitingZone.ob,
|
|
false //
|
|
);
|
|
|
|
//
|
|
bool isPlacePassed =
|
|
isInside ||
|
|
(isBullish
|
|
? isAbove
|
|
: isBelow);
|
|
if (!isPlacePassed)
|
|
{
|
|
//
|
|
ZeroMemory(jFVG);
|
|
continue;
|
|
}
|
|
|
|
//
|
|
Add(
|
|
jFVG,
|
|
tmpWorkingFVGs //
|
|
);
|
|
}
|
|
|
|
//
|
|
int fvgsCount = ArraySize(tmpWorkingFVGs);
|
|
isValid = IsValidSize(fvgsCount);
|
|
if (isValid)
|
|
{
|
|
//
|
|
idx =
|
|
isBullish
|
|
? GetLowest(tmpWorkingFVGs)
|
|
: GetHighest(tmpWorkingFVGs);
|
|
|
|
//
|
|
if (IsValidIndex(idx))
|
|
{
|
|
//
|
|
XCFVG *selectedFVG = tmpWorkingFVGs[idx];
|
|
|
|
//
|
|
waitingZone.fvg = selectedFVG;
|
|
|
|
//
|
|
bool isExists = FindIndex(
|
|
idx,
|
|
selectedFVG,
|
|
tmpFVGs //
|
|
);
|
|
if (isExists)
|
|
{
|
|
//
|
|
ArrayRemove(
|
|
tmpFVGs,
|
|
idx,
|
|
1 //
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
Clean(tmpFVGs);
|
|
Clean(tmpWorkingFVGs);
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
hasWaitingZone = waitingZone.IsValid();
|
|
if (hasWaitingZone)
|
|
{
|
|
//
|
|
bool isSameDir = waitingZone.GetDirection() == trend;
|
|
if (!isSameDir)
|
|
{
|
|
targetZone = waitingZone;
|
|
}
|
|
else
|
|
{
|
|
workingZone.AddOrderFlowItem(waitingZone);
|
|
}
|
|
|
|
//
|
|
waitingZone.Clean();
|
|
}
|
|
|
|
//
|
|
if (signalZone.IsValid() &&
|
|
provider == X121SMC_XWZ_PROVIDER_ACTIVATED_CHOCH)
|
|
{
|
|
//
|
|
ENUM_X_DIRECTION iForDir = Opposit(signalZone.GetDirection());
|
|
if (hasNewAnalyseOB &&
|
|
hasNewAnalyseFVG)
|
|
{
|
|
//
|
|
bool isSameDir =
|
|
newAnalyseOB.GetDirection() == iForDir &&
|
|
newAnalyseFVG.GetDirection() == iForDir;
|
|
bool isOneInsideAnoter =
|
|
//
|
|
(newAnalyseFVG.Upper() < newAnalyseOB.Upper() &&
|
|
newAnalyseFVG.Upper() > newAnalyseOB.Lower())
|
|
//
|
|
||
|
|
//
|
|
(newAnalyseOB.Upper() < newAnalyseFVG.Upper() &&
|
|
newAnalyseOB.Upper() > newAnalyseFVG.Lower())
|
|
//
|
|
;
|
|
|
|
//
|
|
bool isZoneDetected =
|
|
isSameDir &&
|
|
isOneInsideAnoter;
|
|
if (isZoneDetected)
|
|
{
|
|
//
|
|
XOBFVG iSignalZone;
|
|
iSignalZone.ob = newAnalyseOB;
|
|
iSignalZone.fvg = newAnalyseFVG;
|
|
|
|
//
|
|
chochZone = iSignalZone;
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
ZeroMemory(newOB);
|
|
ZeroMemory(newFVG);
|
|
ZeroMemory(newAnalyseOB);
|
|
ZeroMemory(newAnalyseFVG);
|
|
}
|
|
|
|
//
|
|
bool isPriceInsideCHOCHZone = false;
|
|
bool hasCHOCHZone = chochZone.IsValid();
|
|
if (hasCHOCHZone)
|
|
{
|
|
//
|
|
XOHCL cBar;
|
|
bool isInited = cBar.Init(
|
|
symbol,
|
|
period,
|
|
cIndex //
|
|
);
|
|
|
|
//
|
|
isPriceInsideCHOCHZone =
|
|
isInited &&
|
|
cBar.low >= chochZone.fvg.Lower() &&
|
|
cBar.high <= chochZone.fvg.Upper();
|
|
if (isPriceInsideCHOCHZone)
|
|
{
|
|
//
|
|
// Reverse Trend and ReCalculate Requirements
|
|
// For CHOCH Tradng ...
|
|
|
|
//
|
|
trend = chochZone.GetDirection();
|
|
|
|
//
|
|
isBullish = IsBullish(trend);
|
|
isBearish = IsBearish(trend);
|
|
|
|
//
|
|
bool hasPriority = workingZone
|
|
.DetectPriority(
|
|
priority,
|
|
trend,
|
|
zIndex,
|
|
period //
|
|
);
|
|
|
|
//
|
|
bool hasRewardAmount = CalculateRiskReward(
|
|
priority,
|
|
reward,
|
|
amountPercent //
|
|
);
|
|
|
|
//
|
|
provider = X121SMC_XWZ_PROVIDER_ACTIVATED_CHOCH;
|
|
}
|
|
|
|
//
|
|
cBar.Clean();
|
|
}
|
|
|
|
//
|
|
//
|
|
//
|
|
|
|
//
|
|
if (hasSupplyZones ||
|
|
hasDemandZones)
|
|
{
|
|
//
|
|
UpdateTo(cTime);
|
|
DrawWorkingZone(
|
|
visionCycleHelper.mPOIDrawer //
|
|
);
|
|
Print("CHECK ...");
|
|
}
|
|
|
|
//
|
|
// Reading Trand Line Value ...
|
|
double zValue = workingZone.GetOrderFlowTrendLinePrice(
|
|
zIndex,
|
|
period //
|
|
);
|
|
double cValue = workingZone.GetOrderFlowTrendLinePrice(
|
|
cIndex,
|
|
period //
|
|
);
|
|
double pValue = workingZone.GetOrderFlowTrendLinePrice(
|
|
pIndex,
|
|
period //
|
|
);
|
|
double ppValue = workingZone.GetOrderFlowTrendLinePrice(
|
|
ppIndex,
|
|
period //
|
|
);
|
|
|
|
//
|
|
// Implementing Signals ...
|
|
//
|
|
|
|
//
|
|
// TODO: Implement Order Flow Side Trading Senario ...
|
|
bool hasOrderFlowConditions =
|
|
hasTrend &&
|
|
hasPriority &&
|
|
hasRewardAmount &&
|
|
signalZone.IsValid() &&
|
|
provider == X121SMC_XWZ_PROVIDER_ACTIVATED_ZONE;
|
|
|
|
//
|
|
hasOrderFlowhBullishConditions =
|
|
isBullish &&
|
|
hasOrderFlowConditions &&
|
|
signalZone.IsBullish();
|
|
|
|
//
|
|
hasOrderFlowhBearishConditions =
|
|
isBearish &&
|
|
hasOrderFlowConditions &&
|
|
signalZone.IsBearish();
|
|
|
|
//
|
|
if (hasOrderFlowConditions)
|
|
{
|
|
//
|
|
mConditions.signalZone = signalZone;
|
|
|
|
//
|
|
point = hasOrderFlowhBullishConditions
|
|
? signalZone.ob.Upper()
|
|
: signalZone.ob.Lower();
|
|
|
|
//
|
|
pivot = hasOrderFlowhBullishConditions
|
|
? signalZone.ob.Lower()
|
|
: signalZone.ob.Upper();
|
|
|
|
//
|
|
signalZone.Clean();
|
|
}
|
|
|
|
//
|
|
// TODO: Implement Inside Zone Trading Senario ...
|
|
bool hasInsideZoneConditions =
|
|
hasTrend &&
|
|
hasPriority &&
|
|
hasRewardAmount &&
|
|
signalZone.IsValid() &&
|
|
provider == X121SMC_XWZ_PROVIDER_PRICE_INSIDE_ZONE;
|
|
|
|
//
|
|
bool hasInsideZoneBullishConditions =
|
|
isBullish &&
|
|
signalZone.IsBullish() &&
|
|
hasInsideZoneConditions;
|
|
|
|
//
|
|
bool hasInsideZoneBearishConditions =
|
|
isBearish &&
|
|
signalZone.IsBearish() &&
|
|
hasInsideZoneConditions;
|
|
|
|
//
|
|
if (hasInsideZoneConditions)
|
|
{
|
|
//
|
|
mConditions.signalZone = signalZone;
|
|
|
|
//
|
|
point = hasOrderFlowhBullishConditions
|
|
? signalZone.ob.Upper()
|
|
: signalZone.ob.Lower();
|
|
|
|
//
|
|
pivot = hasOrderFlowhBullishConditions
|
|
? signalZone.ob.Lower()
|
|
: signalZone.ob.Upper();
|
|
|
|
//
|
|
signalZone.Clean();
|
|
}
|
|
|
|
//
|
|
// TODO: Implement CHOCH Trading Senario ...
|
|
bool hasCHOCHConditions =
|
|
hasCHOCHZone &&
|
|
chochZone.IsValid() &&
|
|
isPriceInsideCHOCHZone &&
|
|
provider == X121SMC_XWZ_PROVIDER_ACTIVATED_CHOCH;
|
|
|
|
//
|
|
hasChochBullishConditions =
|
|
hasCHOCHConditions &&
|
|
chochZone.IsBullish();
|
|
hasChochBearishConditions =
|
|
hasCHOCHConditions &&
|
|
chochZone.IsBearish();
|
|
|
|
//
|
|
if (hasCHOCHConditions)
|
|
{
|
|
//
|
|
mConditions.signalZone = chochZone;
|
|
|
|
//
|
|
point = hasChochBullishConditions
|
|
? chochZone.ob.Upper()
|
|
: chochZone.ob.Lower();
|
|
|
|
//
|
|
pivot = hasChochBearishConditions
|
|
? chochZone.ob.Lower()
|
|
: chochZone.ob.Upper();
|
|
|
|
//
|
|
chochZone.Clean();
|
|
signalZone.Clean();
|
|
}
|
|
|
|
//
|
|
// TODO: Implement Trend Line Trading Senario ...
|
|
|
|
//
|
|
// TODO: Implement Quarter Line Trading Senario ...
|
|
|
|
//
|
|
// TODO: Implement Supply and Demand Trading Senario ...
|
|
|
|
//
|
|
// TODO: Implement Support and Resistance Trading Senario ...
|
|
|
|
//
|
|
// TODO: Implement Mitigation Blocks Trading Senario ...
|
|
|
|
//
|
|
// Summarize ...
|
|
|
|
//
|
|
bool hasBullishConditions =
|
|
//
|
|
hasChochBullishConditions ||
|
|
hasSupDemBullishConditions ||
|
|
hasSupResBullishConditions ||
|
|
hasTrendLineBullishConditions ||
|
|
hasOrderFlowhBullishConditions ||
|
|
hasInsideZoneBullishConditions ||
|
|
hasBQuarterLineBullishConditions
|
|
//
|
|
;
|
|
|
|
//
|
|
bool hasBearishConditions =
|
|
//
|
|
hasChochBearishConditions ||
|
|
hasSupDemBearishConditions ||
|
|
hasSupResBearishConditions ||
|
|
hasTrendLineBearishConditions ||
|
|
hasOrderFlowhBearishConditions ||
|
|
hasInsideZoneBearishConditions ||
|
|
hasBQuarterLineBearishConditions
|
|
//
|
|
;
|
|
|
|
//
|
|
result =
|
|
hasBullishConditions ||
|
|
hasBearishConditions;
|
|
|
|
//
|
|
if (result)
|
|
{
|
|
//
|
|
mConditions.dir = trend;
|
|
mConditions.pivot = pivot;
|
|
mConditions.point = point;
|
|
mConditions.reward = reward;
|
|
mConditions.setupTime = cTime;
|
|
mConditions.priority = priority;
|
|
mConditions.provider = provider;
|
|
mConditions.amountPercent = amountPercent;
|
|
}
|
|
|
|
//
|
|
// Cleanups ...
|
|
|
|
//
|
|
Clean(visionPoiEvents);
|
|
Clean(analysePoiEvents);
|
|
Clean(decisionPoiEvents);
|
|
Clean(consolidationPoiEvents);
|
|
|
|
//
|
|
Clean(visionCycleEvents);
|
|
Clean(analyseCycleEvents);
|
|
Clean(decisionCycleEvents);
|
|
Clean(consolidationCycleEvents);
|
|
|
|
//
|
|
visionState.Clean();
|
|
analyseState.Clean();
|
|
decisionState.Clean();
|
|
consolidationState.Clean();
|
|
|
|
//
|
|
visionConditions.Clean();
|
|
analyseConditions.Clean();
|
|
decisionConditions.Clean();
|
|
consolidationConditions.Clean();
|
|
|
|
//
|
|
visionXConditions.Clean();
|
|
analyseXConditions.Clean();
|
|
decisionXConditions.Clean();
|
|
consolidationXConditions.Clean();
|
|
|
|
//
|
|
// mConditions.Clean();
|
|
consolidationZBar.Clean();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Detect Trigger Conditions ...
|
|
bool DetectSignalTrigger(
|
|
//
|
|
X121SMCStrategyXWZSignalConditions &conditions,
|
|
//
|
|
string _symbol,
|
|
ENUM_TIMEFRAMES _period,
|
|
//
|
|
XC121SMCCycleHelper *decisionCycleHelper,
|
|
XC121SMCCycleHelper *analyseCycleHelper,
|
|
XC121SMCCycleHelper *consolidationCycleHelper,
|
|
XC121SMCCycleHelper *visionCycleHelper,
|
|
//
|
|
int maxAllowedSetupAge = 60
|
|
//
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
result =
|
|
//
|
|
visionCycleHelper != NULL &&
|
|
analyseCycleHelper != NULL &&
|
|
decisionCycleHelper != NULL &&
|
|
consolidationCycleHelper != NULL
|
|
//
|
|
;
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result = conditions.IsSetuped();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
datetime setupTime = conditions.setupTime;
|
|
ENUM_X_DIRECTION setupDir = conditions.dir;
|
|
|
|
//
|
|
bool isBullish = IsBullish(setupDir);
|
|
bool isBearish = IsBearish(setupDir);
|
|
|
|
//
|
|
int zIndex = 0;
|
|
int cIndex = zIndex + 1;
|
|
int pIndex = cIndex + 1;
|
|
int ppIndex = pIndex + 1;
|
|
|
|
//
|
|
int loopback = 10;
|
|
|
|
//
|
|
double ask = GetAsk(symbol);
|
|
double bid = GetBid(symbol);
|
|
datetime cTime = TimeCurrent();
|
|
double points = GetPoints(symbol);
|
|
|
|
//
|
|
double sls[];
|
|
|
|
//
|
|
// Cycles Conditions ...
|
|
|
|
//
|
|
// Decision ...
|
|
ENUM_XPOI_EVENTS decisionPoiEvents[];
|
|
ENUM_X_CYCLE_EVENTS decisionCycleEvents[];
|
|
X121SMCCycleConditions decisionConditions;
|
|
result = decisionCycleHelper.GetConditions(
|
|
decisionCycleEvents,
|
|
decisionPoiEvents,
|
|
decisionConditions,
|
|
zIndex,
|
|
loopback //
|
|
);
|
|
if (!result)
|
|
{
|
|
//
|
|
// Cleanup ...
|
|
|
|
//
|
|
Clean(decisionPoiEvents);
|
|
Clean(decisionCycleEvents);
|
|
|
|
//
|
|
decisionConditions.Clean();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Analyse ...
|
|
ENUM_XPOI_EVENTS analysePoiEvents[];
|
|
ENUM_X_CYCLE_EVENTS analyseCycleEvents[];
|
|
X121SMCCycleConditions analyseConditions;
|
|
result = analyseCycleHelper.GetConditions(
|
|
analyseCycleEvents,
|
|
analysePoiEvents,
|
|
analyseConditions,
|
|
zIndex,
|
|
loopback //
|
|
);
|
|
if (!result)
|
|
{
|
|
//
|
|
Clean(analysePoiEvents);
|
|
Clean(decisionPoiEvents);
|
|
|
|
//
|
|
Clean(analyseCycleEvents);
|
|
Clean(decisionCycleEvents);
|
|
|
|
//
|
|
analyseConditions.Clean();
|
|
decisionConditions.Clean();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Cycles POI States ...
|
|
XPOIState decisionState = decisionConditions.state;
|
|
XPOIState analyseState = analyseConditions.state;
|
|
|
|
//
|
|
// Cycle X121Conditions ...
|
|
X121Conditions decisionXConditions = decisionConditions.x121Conditions;
|
|
X121Conditions analyseXConditions = analyseConditions.x121Conditions;
|
|
|
|
//
|
|
// Check Signal Validation ...
|
|
|
|
//
|
|
XOHCL cBar;
|
|
bool isInited = cBar.Init(
|
|
conditions.symbol,
|
|
conditions.period,
|
|
cIndex //
|
|
);
|
|
XOHCL pBar;
|
|
isInited =
|
|
isInited &&
|
|
cBar.GetPreviousBar(pBar);
|
|
bool isLowerBreaked =
|
|
//
|
|
isInited &&
|
|
cBar.high < conditions.point &&
|
|
pBar.high >= conditions.point
|
|
//
|
|
;
|
|
bool isUpperBreaked =
|
|
//
|
|
isInited &&
|
|
cBar.low > conditions.point &&
|
|
pBar.low <= conditions.point
|
|
//
|
|
;
|
|
bool isZoneBreaked =
|
|
(isBullish &&
|
|
isLowerBreaked) ||
|
|
(isBearish &&
|
|
isUpperBreaked);
|
|
result = !isZoneBreaked;
|
|
if (!result)
|
|
{
|
|
//
|
|
cBar.Clean();
|
|
pBar.Clean();
|
|
conditions.Clean();
|
|
|
|
//
|
|
Clean(decisionPoiEvents);
|
|
Clean(decisionCycleEvents);
|
|
|
|
//
|
|
decisionState.Clean();
|
|
decisionConditions.Clean();
|
|
decisionXConditions.Clean();
|
|
|
|
//
|
|
Clean(analysePoiEvents);
|
|
Clean(analyseCycleEvents);
|
|
|
|
//
|
|
analyseState.Clean();
|
|
analyseConditions.Clean();
|
|
analyseXConditions.Clean();
|
|
}
|
|
|
|
//
|
|
cBar.Clean();
|
|
pBar.Clean();
|
|
|
|
//
|
|
double bullishScore = 0;
|
|
double bearishScore = 0;
|
|
decisionXConditions.GenerateScore(
|
|
bullishScore,
|
|
bearishScore //
|
|
);
|
|
bool isBullishScorePassed =
|
|
isBullish &&
|
|
bullishScore > (bearishScore * 1.5);
|
|
bool isBearishScorePassed =
|
|
isBearish &&
|
|
bearishScore > (bullishScore * 1.5);
|
|
bool isScorePassed = isBullishScorePassed ||
|
|
isBearishScorePassed;
|
|
|
|
//
|
|
// Base SL Used Pivot of Conditions ...
|
|
// Add(
|
|
// conditions.pivot,
|
|
// sls //
|
|
// );
|
|
|
|
//
|
|
int lowestSupportIDX = -1;
|
|
int highestResistanceIDX = -1;
|
|
bool isSupportRejected = false;
|
|
bool isResistanceRejected = false;
|
|
bool hasSignalZone = conditions.signalZone.IsValid();
|
|
if (hasSignalZone)
|
|
{
|
|
//
|
|
conditions
|
|
.signalZone
|
|
.UpdateZones(decisionState);
|
|
conditions
|
|
.signalZone
|
|
.UpdateTo(cTime);
|
|
|
|
//
|
|
XOHCL cBar;
|
|
bool isBarInited = cBar.Init(
|
|
conditions.symbol,
|
|
conditions.period,
|
|
cIndex //
|
|
);
|
|
|
|
//
|
|
lowestSupportIDX = GetLowest(conditions.signalZone.supportZones);
|
|
if (IsValidIndex(lowestSupportIDX))
|
|
{
|
|
//
|
|
isSupportRejected =
|
|
//
|
|
isBarInited &&
|
|
(
|
|
//
|
|
(cBar.low < conditions.signalZone.supportZones[lowestSupportIDX].Upper() &&
|
|
cBar.GetDown() > conditions.signalZone.supportZones[lowestSupportIDX].Upper())
|
|
//
|
|
||
|
|
//
|
|
(cBar.low < conditions.signalZone.supportZones[lowestSupportIDX].Lower() &&
|
|
cBar.GetDown() > conditions.signalZone.supportZones[lowestSupportIDX].Lower())
|
|
//
|
|
)
|
|
//
|
|
;
|
|
|
|
//
|
|
isSupportRejected =
|
|
isBullish &&
|
|
isSupportRejected;
|
|
if (isSupportRejected)
|
|
{
|
|
//
|
|
double vPivot = conditions.signalZone.supportZones[lowestSupportIDX].Lower();
|
|
bool canSetPivot = vPivot > conditions.pivot &&
|
|
vPivot < conditions.point;
|
|
if (canSetPivot)
|
|
{
|
|
//
|
|
Add(
|
|
vPivot,
|
|
sls //
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
highestResistanceIDX = GetHighest(conditions.signalZone.resistanceZones);
|
|
if (IsValidIndex(highestResistanceIDX))
|
|
{
|
|
//
|
|
isResistanceRejected =
|
|
//
|
|
isBarInited &&
|
|
(
|
|
//
|
|
(cBar.high > conditions.signalZone.resistanceZones[highestResistanceIDX].Upper() &&
|
|
cBar.GetUp() < conditions.signalZone.resistanceZones[highestResistanceIDX].Upper())
|
|
//
|
|
||
|
|
//
|
|
(cBar.high > conditions.signalZone.resistanceZones[highestResistanceIDX].Lower() &&
|
|
cBar.GetUp() < conditions.signalZone.resistanceZones[highestResistanceIDX].Lower())
|
|
//
|
|
)
|
|
//
|
|
;
|
|
|
|
//
|
|
isResistanceRejected =
|
|
isBearish &&
|
|
isResistanceRejected;
|
|
if (isResistanceRejected)
|
|
{
|
|
//
|
|
double vPivot = conditions.signalZone.resistanceZones[highestResistanceIDX].Upper();
|
|
bool canSetPivot = vPivot < conditions.pivot &&
|
|
vPivot > conditions.point;
|
|
if (canSetPivot)
|
|
{
|
|
//
|
|
Add(
|
|
vPivot,
|
|
sls //
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
cBar.Clean();
|
|
}
|
|
|
|
//
|
|
// Consolidation Zone Detection ...
|
|
|
|
//
|
|
// Detect Consolidation Zones ...
|
|
|
|
//
|
|
// Bullish Consolidation Zone ...
|
|
XConsolidationZone bullishCZones[];
|
|
bool hasBullishConsolidationZone = false;
|
|
XConsolidationZone bullishConsolidationZone;
|
|
int bullishCZonesCount = decisionCycleHelper.FillConsolidationZones(
|
|
X_DIRECTION_BULLISH,
|
|
bullishCZones //
|
|
);
|
|
bool hasBullishConsolidationZones = IsValidSize(bullishCZonesCount);
|
|
if (hasBullishConsolidationZones)
|
|
{
|
|
//
|
|
int idx = -1;
|
|
while (HasChild(bullishCZones))
|
|
{
|
|
//
|
|
idx = GetYoungest(bullishCZones);
|
|
hasBullishConsolidationZone = IsValidIndex(idx);
|
|
if (hasBullishConsolidationZone)
|
|
{
|
|
//
|
|
bullishConsolidationZone = bullishCZones[idx];
|
|
|
|
//
|
|
ArrayRemove(
|
|
bullishCZones,
|
|
idx,
|
|
1 //
|
|
);
|
|
|
|
//
|
|
// Check Zone Based On pivot, since this is the SL ...
|
|
hasBullishConsolidationZone =
|
|
isBullish &&
|
|
hasBullishConsolidationZone &&
|
|
bullishConsolidationZone.lower > conditions.pivot &&
|
|
bullishConsolidationZone.upper <= conditions.point;
|
|
if (hasBullishConsolidationZone)
|
|
{
|
|
//
|
|
Add(
|
|
bullishConsolidationZone.lower,
|
|
sls //
|
|
);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
Clean(bullishCZones);
|
|
bullishConsolidationZone.Clean();
|
|
|
|
//
|
|
// Bearish Consolidation Zone ...
|
|
XConsolidationZone bearishCZones[];
|
|
bool hasBearishConsolidationZone = false;
|
|
XConsolidationZone bearishConsolidationZone;
|
|
int bearishCZonesCount = decisionCycleHelper.FillConsolidationZones(
|
|
X_DIRECTION_BEARISH,
|
|
bearishCZones //
|
|
);
|
|
bool hasBearishConsolidationZones = IsValidSize(bearishCZones);
|
|
if (hasBearishConsolidationZones)
|
|
{
|
|
//
|
|
int idx = -1;
|
|
while (HasChild(bearishCZones))
|
|
{
|
|
//
|
|
idx = GetYoungest(bearishCZones);
|
|
hasBearishConsolidationZone = IsValidIndex(idx);
|
|
if (hasBearishConsolidationZone)
|
|
{
|
|
//
|
|
bearishConsolidationZone = bearishCZones[idx];
|
|
|
|
//
|
|
ArrayRemove(
|
|
bearishCZones,
|
|
idx,
|
|
1 //
|
|
);
|
|
|
|
//
|
|
hasBearishConsolidationZone =
|
|
isBearish &&
|
|
hasBearishConsolidationZone &&
|
|
bearishConsolidationZone.upper < conditions.pivot &&
|
|
bearishConsolidationZone.lower >= conditions.point;
|
|
if (hasBearishConsolidationZone)
|
|
{
|
|
//
|
|
Add(
|
|
bearishConsolidationZone.upper,
|
|
sls //
|
|
);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
Clean(bearishCZones);
|
|
bearishConsolidationZone.Clean();
|
|
|
|
//
|
|
// Check VWap Crossing ...
|
|
|
|
//
|
|
bool isVWapSwitchedToBullish =
|
|
//
|
|
(decisionXConditions.isVWapBullishOrdered &&
|
|
decisionXConditions.isVWapSwitchedToBullishState)
|
|
//
|
|
||
|
|
//
|
|
(decisionXConditions.isVWapBullishState &&
|
|
decisionXConditions.isVWapSwitchedToBullishOrdered)
|
|
//
|
|
;
|
|
|
|
//
|
|
isVWapSwitchedToBullish =
|
|
isBullish &&
|
|
isVWapSwitchedToBullish;
|
|
if (isVWapSwitchedToBullish)
|
|
{
|
|
//
|
|
double vPivot = decisionXConditions.vwapMin;
|
|
bool canSetPivot = vPivot > conditions.pivot &&
|
|
vPivot < conditions.point;
|
|
if (canSetPivot)
|
|
{
|
|
//
|
|
Add(
|
|
vPivot,
|
|
sls //
|
|
);
|
|
}
|
|
}
|
|
|
|
//
|
|
bool isVWapSwitchedToBearish =
|
|
//
|
|
(decisionXConditions.isVWapBearishOrdered &&
|
|
decisionXConditions.isVWapSwitchedToBearishState)
|
|
//
|
|
||
|
|
//
|
|
(decisionXConditions.isVWapBearishState &&
|
|
decisionXConditions.isVWapSwitchedToBearishOrdered)
|
|
//
|
|
;
|
|
|
|
//
|
|
isVWapSwitchedToBearish =
|
|
isBearish &&
|
|
isVWapSwitchedToBearish;
|
|
if (isVWapSwitchedToBearish)
|
|
{
|
|
//
|
|
double vPivot = decisionXConditions.vwapMax;
|
|
bool canSetPivot = vPivot < conditions.pivot &&
|
|
vPivot > conditions.point;
|
|
if (canSetPivot)
|
|
{
|
|
//
|
|
Add(
|
|
vPivot,
|
|
sls //
|
|
);
|
|
}
|
|
}
|
|
|
|
//
|
|
// Point Break ...
|
|
isInited = cBar.Init(
|
|
conditions.symbol,
|
|
conditions.period,
|
|
cIndex //
|
|
);
|
|
double point = conditions.point;
|
|
bool isPointBreaked =
|
|
isInited &&
|
|
IsBarBreak(
|
|
point,
|
|
setupDir,
|
|
cBar //
|
|
);
|
|
cBar.Clean();
|
|
|
|
//
|
|
bool isCommonsPassed =
|
|
//
|
|
(isSupportRejected ||
|
|
isResistanceRejected ||
|
|
isVWapSwitchedToBullish ||
|
|
isVWapSwitchedToBearish ||
|
|
hasBullishConsolidationZone ||
|
|
hasBearishConsolidationZone)
|
|
//
|
|
;
|
|
|
|
//
|
|
// Trigger Conditions ...
|
|
|
|
//
|
|
bool canTriggerCHOCHZone =
|
|
//
|
|
isScorePassed &&
|
|
isCommonsPassed &&
|
|
conditions.provider == X121SMC_XWZ_PROVIDER_ACTIVATED_CHOCH
|
|
//
|
|
;
|
|
|
|
//
|
|
bool canTriggerActivatedZone =
|
|
//
|
|
// isPointBreaked &&
|
|
isScorePassed &&
|
|
isCommonsPassed &&
|
|
conditions.provider == X121SMC_XWZ_PROVIDER_ACTIVATED_ZONE
|
|
//
|
|
;
|
|
|
|
//
|
|
bool canTriggerPriceInsideZone =
|
|
//
|
|
isScorePassed &&
|
|
isCommonsPassed &&
|
|
conditions.provider == X121SMC_XWZ_PROVIDER_PRICE_INSIDE_ZONE
|
|
//
|
|
;
|
|
|
|
//
|
|
bool canTrigger = (canTriggerCHOCHZone ||
|
|
canTriggerActivatedZone ||
|
|
canTriggerPriceInsideZone);
|
|
|
|
//
|
|
// Summary ...
|
|
|
|
//
|
|
isBullish =
|
|
//
|
|
isBullish &&
|
|
canTrigger
|
|
//
|
|
;
|
|
|
|
//
|
|
isBearish =
|
|
//
|
|
isBearish &&
|
|
canTrigger
|
|
//
|
|
;
|
|
|
|
//
|
|
result = isBullish ||
|
|
isBearish;
|
|
if (!result)
|
|
{
|
|
//
|
|
// Cleanup Setup Conditions ...
|
|
int setupAge = conditions.GetSetupAge();
|
|
if (IsValidSize(setupAge) &&
|
|
IsValidSize(maxAllowedSetupAge) &&
|
|
setupAge >= maxAllowedSetupAge)
|
|
{
|
|
conditions.Clean();
|
|
}
|
|
|
|
//
|
|
// Cleanup ...
|
|
|
|
//
|
|
cBar.Clean();
|
|
pBar.Clean();
|
|
|
|
//
|
|
Clean(decisionPoiEvents);
|
|
Clean(decisionCycleEvents);
|
|
|
|
//
|
|
decisionState.Clean();
|
|
decisionConditions.Clean();
|
|
decisionXConditions.Clean();
|
|
|
|
//
|
|
Clean(analysePoiEvents);
|
|
Clean(analyseCycleEvents);
|
|
|
|
//
|
|
analyseState.Clean();
|
|
analyseConditions.Clean();
|
|
analyseXConditions.Clean();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
double entry = GetEntry(
|
|
conditions.symbol,
|
|
setupDir //
|
|
);
|
|
|
|
//
|
|
// Manipulate SL Based on Consolidation Zones ...
|
|
|
|
//
|
|
double iAtr = decisionXConditions.atrBuffer[1];
|
|
iAtr *= 1.5;
|
|
|
|
//
|
|
// Since Pivot Value almost used
|
|
// as Default SL, if there isn't any Refind SL
|
|
// we use Default ...
|
|
if (!HasChild(sls))
|
|
{
|
|
//
|
|
Add(
|
|
conditions.pivot,
|
|
sls //
|
|
);
|
|
}
|
|
|
|
//
|
|
double slsMin = GetMin(sls);
|
|
double slsMax = GetMax(sls);
|
|
|
|
//
|
|
double sl = isBullish
|
|
? slsMin - iAtr
|
|
: slsMax + iAtr;
|
|
double risk = MathAbs(entry - sl);
|
|
|
|
//
|
|
// Filling Conditions Props ...
|
|
conditions.sl = sl;
|
|
conditions.triggerTime = cTime;
|
|
conditions.type = isBullish
|
|
? X_POSITION_TYPE_LONG
|
|
: X_POSITION_TYPE_SHORT;
|
|
|
|
//
|
|
// Checking Targets ...
|
|
|
|
//
|
|
ENUM_X121SMC_XWZ_PRIORITY priority = X121SMC_XWZ_PRIORITY_NONE;
|
|
bool hasPriority = workingZone
|
|
.DetectPriority(
|
|
priority,
|
|
setupDir,
|
|
zIndex,
|
|
decisionState.period //
|
|
);
|
|
|
|
//
|
|
// Order Block Targets ...
|
|
|
|
//
|
|
XCOrderBlock *bullishOBs[];
|
|
Copy(
|
|
analyseState.bullishOrderBlocks,
|
|
bullishOBs //
|
|
);
|
|
|
|
//
|
|
// Extract Available Order Blocks ...
|
|
int bullishOBsCont = FilterZones(
|
|
//
|
|
bullishOBs,
|
|
//
|
|
X_DIRECTION_BULLISH,
|
|
analyseState.period,
|
|
NULL,
|
|
//
|
|
// Start ...
|
|
XZONE_STATE_IGNORED,
|
|
false,
|
|
//
|
|
// Activation ...
|
|
XZONE_STATE_IGNORED,
|
|
false,
|
|
//
|
|
// Breake ...
|
|
XZONE_STATE_FAILED,
|
|
false,
|
|
//
|
|
// Work ...
|
|
XZONE_STATE_IGNORED,
|
|
false,
|
|
//
|
|
true, // Apply Sore ...
|
|
true // Ignore Inside ...
|
|
);
|
|
bool hasBullishOBs = HasChild(bullishOBs);
|
|
|
|
//
|
|
XCOrderBlock *bearishOBs[];
|
|
Copy(
|
|
analyseState.bearishOrderBlocks,
|
|
bearishOBs //
|
|
);
|
|
|
|
//
|
|
// Extract Available Order Blocks ...
|
|
int bearishOBsCont = FilterZones(
|
|
//
|
|
bearishOBs,
|
|
//
|
|
X_DIRECTION_BEARISH,
|
|
analyseState.period,
|
|
NULL,
|
|
//
|
|
// Start ...
|
|
XZONE_STATE_IGNORED,
|
|
false,
|
|
//
|
|
// Activation ...
|
|
XZONE_STATE_IGNORED,
|
|
false,
|
|
//
|
|
// Breake ...
|
|
XZONE_STATE_FAILED,
|
|
false,
|
|
//
|
|
// Work ...
|
|
XZONE_STATE_IGNORED,
|
|
false,
|
|
//
|
|
true, // Apply Sore ...
|
|
true // Ignore Inside ...
|
|
);
|
|
bool hasBearishOBs = HasChild(bearishOBs);
|
|
|
|
//
|
|
if (isBullish &&
|
|
hasBearishOBs)
|
|
{
|
|
//
|
|
int count = ArraySize(bearishOBs);
|
|
for (int i = 0; i < count; i++)
|
|
{
|
|
//
|
|
XCBaseObject *iObj;
|
|
bool isCreated = visionCycleHelper
|
|
.mPOIDrawer
|
|
.CreateOrderBlock(
|
|
bearishOBs[i],
|
|
iObj //
|
|
);
|
|
if (isCreated)
|
|
{
|
|
mObjects.Add(iObj);
|
|
}
|
|
|
|
//
|
|
double value = bearishOBs[i].Lower();
|
|
bool canSet = value > entry;
|
|
if (canSet)
|
|
{
|
|
//
|
|
Add(
|
|
value,
|
|
conditions.targets //
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
if (isBearish &&
|
|
hasBullishOBs)
|
|
{
|
|
//
|
|
int count = ArraySize(bullishOBs);
|
|
for (int i = 0; i < count; i++)
|
|
{
|
|
//
|
|
XCBaseObject *iObj;
|
|
bool isCreated = visionCycleHelper
|
|
.mPOIDrawer
|
|
.CreateOrderBlock(
|
|
bullishOBs[i],
|
|
iObj //
|
|
);
|
|
if (isCreated)
|
|
{
|
|
mObjects.Add(iObj);
|
|
}
|
|
|
|
//
|
|
double value = bullishOBs[i].Upper();
|
|
bool canSet = value < entry;
|
|
if (canSet)
|
|
{
|
|
//
|
|
Add(
|
|
value,
|
|
conditions.targets //
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
Clean(bullishOBs);
|
|
Clean(bearishOBs);
|
|
|
|
//
|
|
// Detect Quarter Targets ...
|
|
|
|
//
|
|
double quarterTarget = 0;
|
|
if (hasPriority)
|
|
{
|
|
//
|
|
switch (priority)
|
|
{
|
|
//
|
|
case X121SMC_XWZ_PRIORITY_WEAK:
|
|
//
|
|
quarterTarget =
|
|
isBullish
|
|
? workingZone.supplyZone.Lower()
|
|
: workingZone.demandZone.Upper();
|
|
break;
|
|
|
|
//
|
|
case X121SMC_XWZ_PRIORITY_LOW:
|
|
//
|
|
quarterTarget =
|
|
isBullish
|
|
? workingZone.quarter1
|
|
: workingZone.quarter3;
|
|
break;
|
|
|
|
//
|
|
case X121SMC_XWZ_PRIORITY_REGULAR:
|
|
//
|
|
quarterTarget =
|
|
isBullish
|
|
? workingZone.quarter2
|
|
: workingZone.quarter2;
|
|
break;
|
|
|
|
//
|
|
case X121SMC_XWZ_PRIORITY_HIGH:
|
|
//
|
|
quarterTarget =
|
|
isBullish
|
|
? workingZone.quarter3
|
|
: workingZone.quarter1;
|
|
break;
|
|
|
|
//
|
|
case X121SMC_XWZ_PRIORITY_STRONG_HIGH:
|
|
//
|
|
quarterTarget =
|
|
isBullish
|
|
? workingZone.demandZone.Upper()
|
|
: workingZone.supplyZone.Lower();
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
if (quarterTarget > 0)
|
|
{
|
|
//
|
|
Add(
|
|
quarterTarget,
|
|
conditions.targets //
|
|
);
|
|
}
|
|
|
|
//
|
|
// Cleanup ...
|
|
|
|
//
|
|
cBar.Clean();
|
|
pBar.Clean();
|
|
|
|
//
|
|
Clean(decisionPoiEvents);
|
|
Clean(decisionCycleEvents);
|
|
|
|
//
|
|
decisionState.Clean();
|
|
decisionConditions.Clean();
|
|
decisionXConditions.Clean();
|
|
|
|
//
|
|
Clean(analysePoiEvents);
|
|
Clean(analyseCycleEvents);
|
|
|
|
//
|
|
analyseState.Clean();
|
|
analyseConditions.Clean();
|
|
analyseXConditions.Clean();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Detect Guards ...
|
|
bool DetectGuards(
|
|
//
|
|
X121SMCGuard &guards[],
|
|
const XPosition &positions[],
|
|
//
|
|
XC121SMCCycleHelper *decisionCycleHelper,
|
|
XC121SMCCycleHelper *analyseCycleHelper,
|
|
XC121SMCCycleHelper *consolidationCycleHelper,
|
|
XC121SMCCycleHelper *visionCycleHelper
|
|
//
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
Clean(guards);
|
|
|
|
//
|
|
bool isCycleHelpersValid =
|
|
//
|
|
visionCycleHelper != NULL &&
|
|
analyseCycleHelper != NULL &&
|
|
decisionCycleHelper != NULL &&
|
|
consolidationCycleHelper != NULL
|
|
//
|
|
;
|
|
|
|
//
|
|
return false;
|
|
|
|
//
|
|
result = isCycleHelpersValid;
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
int count = ArraySize(positions);
|
|
result = IsValidSize(count);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
string provider = ToString(X_121_SMC_PROVIDER_XWZ);
|
|
|
|
//
|
|
XPosition ownPositions[];
|
|
XPosition ownLongPositions[];
|
|
XPosition ownShortPositions[];
|
|
for (int i = 0; i < count; i++)
|
|
{
|
|
//
|
|
XPosition iPosition = positions[i];
|
|
bool isOwn = iPosition
|
|
.IsFiltersPassed(
|
|
symbol,
|
|
provider,
|
|
NULL,
|
|
X_POSITION_TYPE_ALL,
|
|
iPosition.magic //
|
|
);
|
|
if (isOwn)
|
|
{
|
|
//
|
|
AddRef(
|
|
iPosition,
|
|
ownPositions //
|
|
);
|
|
|
|
//
|
|
bool isLong = IsLong(positions[i].type);
|
|
if (isLong)
|
|
{
|
|
//
|
|
AddRef(
|
|
iPosition,
|
|
ownLongPositions //
|
|
);
|
|
}
|
|
else
|
|
{
|
|
//
|
|
AddRef(
|
|
iPosition,
|
|
ownShortPositions //
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
count = ArraySize(ownPositions);
|
|
|
|
//
|
|
int longsCount = ArraySize(ownLongPositions);
|
|
bool hasLongs = IsValidSize(longsCount);
|
|
|
|
//
|
|
int shortsCount = ArraySize(ownShortPositions);
|
|
bool hasShorts = IsValidSize(shortsCount);
|
|
|
|
//
|
|
result = IsValidSize(count);
|
|
if (!result)
|
|
{
|
|
//
|
|
Clean(ownPositions);
|
|
Clean(ownLongPositions);
|
|
Clean(ownShortPositions);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
//
|
|
//
|
|
|
|
//
|
|
// Get Global and Common Guards ...
|
|
|
|
//
|
|
ENUM_X_121_SMC_GUARD_ACTIONS ignoreGuards[1] = {
|
|
X_121_SMC_GUARD_ACTION_TRAIL_STOP //
|
|
};
|
|
result = DetectX121SMCGuards(
|
|
provider,
|
|
guards,
|
|
positions,
|
|
decisionCycleHelper,
|
|
analyseCycleHelper,
|
|
consolidationCycleHelper,
|
|
visionCycleHelper,
|
|
//
|
|
ignoreGuards
|
|
//
|
|
);
|
|
|
|
//
|
|
//
|
|
//
|
|
|
|
//
|
|
// Get Custom Implemented Guards ...
|
|
|
|
//
|
|
// Here we Are Sure there is Positions to Guard ...
|
|
// based on Current Provider ...
|
|
|
|
//
|
|
// Detect Required Data for Analyse Market to Guard Positions ...
|
|
|
|
//
|
|
int zIndex = 0;
|
|
int cIndex = zIndex + 1;
|
|
int pIndex = cIndex + 1;
|
|
int ppIndex = pIndex + 1;
|
|
|
|
//
|
|
int loopback = 10;
|
|
|
|
//
|
|
XOHCL zBar;
|
|
result = zBar.Init(
|
|
symbol,
|
|
period,
|
|
zIndex //
|
|
);
|
|
if (!result)
|
|
{
|
|
//
|
|
result = HasChild(guards);
|
|
return result;
|
|
}
|
|
|
|
//
|
|
XOHCL cBar;
|
|
result = cBar.Init(
|
|
symbol,
|
|
period,
|
|
cIndex //
|
|
);
|
|
if (!result)
|
|
{
|
|
//
|
|
zBar.Clean();
|
|
result = HasChild(guards);
|
|
return result;
|
|
}
|
|
|
|
//
|
|
XOHCL pBar;
|
|
result = pBar.Init(
|
|
symbol,
|
|
period,
|
|
pIndex //
|
|
);
|
|
if (!result)
|
|
{
|
|
//
|
|
zBar.Clean();
|
|
cBar.Clean();
|
|
result = HasChild(guards);
|
|
return result;
|
|
}
|
|
|
|
//
|
|
XOHCL ppBar;
|
|
result = ppBar.Init(
|
|
symbol,
|
|
period,
|
|
ppIndex //
|
|
);
|
|
if (!result)
|
|
{
|
|
//
|
|
zBar.Clean();
|
|
cBar.Clean();
|
|
pBar.Clean();
|
|
result = HasChild(guards);
|
|
return result;
|
|
}
|
|
|
|
//
|
|
double ask = GetAsk(symbol);
|
|
double bid = GetBid(symbol);
|
|
datetime cTime = TimeCurrent();
|
|
double points = GetPoints(symbol);
|
|
|
|
//
|
|
|
|
//
|
|
// Cycles Conditions ...
|
|
|
|
//
|
|
// Decision ...
|
|
ENUM_XPOI_EVENTS decisionPoiEvents[];
|
|
ENUM_X_CYCLE_EVENTS decisionCycleEvents[];
|
|
X121SMCCycleConditions decisionConditions;
|
|
result = decisionCycleHelper.GetConditions(
|
|
decisionCycleEvents,
|
|
decisionPoiEvents,
|
|
decisionConditions,
|
|
zIndex,
|
|
loopback //
|
|
);
|
|
if (!result)
|
|
{
|
|
//
|
|
zBar.Clean();
|
|
cBar.Clean();
|
|
pBar.Clean();
|
|
ppBar.Clean();
|
|
result = HasChild(guards);
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Analyse ...
|
|
ENUM_XPOI_EVENTS analysePoiEvents[];
|
|
ENUM_X_CYCLE_EVENTS analyseCycleEvents[];
|
|
X121SMCCycleConditions analyseConditions;
|
|
result = analyseCycleHelper.GetConditions(
|
|
analyseCycleEvents,
|
|
analysePoiEvents,
|
|
analyseConditions,
|
|
zIndex,
|
|
loopback //
|
|
);
|
|
if (!result)
|
|
{
|
|
//
|
|
zBar.Clean();
|
|
cBar.Clean();
|
|
pBar.Clean();
|
|
ppBar.Clean();
|
|
|
|
//
|
|
Clean(decisionPoiEvents);
|
|
Clean(decisionCycleEvents);
|
|
|
|
//
|
|
decisionConditions.Clean();
|
|
|
|
//
|
|
result = HasChild(guards);
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Consolidation ...
|
|
ENUM_XPOI_EVENTS consolidationPoiEvents[];
|
|
ENUM_X_CYCLE_EVENTS consolidationCycleEvents[];
|
|
X121SMCCycleConditions consolidationConditions;
|
|
result = consolidationCycleHelper.GetConditions(
|
|
consolidationCycleEvents,
|
|
consolidationPoiEvents,
|
|
consolidationConditions,
|
|
zIndex,
|
|
loopback //
|
|
);
|
|
if (!result)
|
|
{
|
|
//
|
|
zBar.Clean();
|
|
cBar.Clean();
|
|
pBar.Clean();
|
|
ppBar.Clean();
|
|
|
|
//
|
|
Clean(decisionPoiEvents);
|
|
Clean(decisionCycleEvents);
|
|
|
|
//
|
|
decisionConditions.Clean();
|
|
|
|
//
|
|
Clean(analysePoiEvents);
|
|
Clean(analyseCycleEvents);
|
|
|
|
//
|
|
analyseConditions.Clean();
|
|
|
|
//
|
|
result = HasChild(guards);
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Vision ...
|
|
ENUM_XPOI_EVENTS visionPoiEvents[];
|
|
ENUM_X_CYCLE_EVENTS visionCycleEvents[];
|
|
X121SMCCycleConditions visionConditions;
|
|
result = visionCycleHelper.GetConditions(
|
|
visionCycleEvents,
|
|
visionPoiEvents,
|
|
visionConditions,
|
|
zIndex,
|
|
loopback //
|
|
);
|
|
if (!result)
|
|
{
|
|
//
|
|
zBar.Clean();
|
|
cBar.Clean();
|
|
pBar.Clean();
|
|
ppBar.Clean();
|
|
|
|
//
|
|
Clean(decisionPoiEvents);
|
|
Clean(decisionCycleEvents);
|
|
|
|
//
|
|
decisionConditions.Clean();
|
|
|
|
//
|
|
Clean(analysePoiEvents);
|
|
Clean(analyseCycleEvents);
|
|
|
|
//
|
|
analyseConditions.Clean();
|
|
|
|
//
|
|
Clean(consolidationPoiEvents);
|
|
Clean(consolidationCycleEvents);
|
|
|
|
//
|
|
consolidationConditions.Clean();
|
|
|
|
//
|
|
result = HasChild(guards);
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Cycles POI States ...
|
|
XPOIState decisionState = decisionConditions.state;
|
|
XPOIState analyseState = analyseConditions.state;
|
|
XPOIState consolidationState = consolidationConditions.state;
|
|
XPOIState visionState = visionConditions.state;
|
|
|
|
//
|
|
// Cycle X121Conditions ...
|
|
X121Conditions decisionXConditions = decisionConditions.x121Conditions;
|
|
X121Conditions analyseXConditions = analyseConditions.x121Conditions;
|
|
X121Conditions consolidationXConditions = consolidationConditions.x121Conditions;
|
|
X121Conditions visionXConditions = visionConditions.x121Conditions;
|
|
|
|
//
|
|
//
|
|
//
|
|
|
|
//
|
|
// Detect Consolidation Zone ...
|
|
|
|
//
|
|
// Bullish ...
|
|
XConsolidationZone bullishConsolidationZone;
|
|
bool hasBullishConsolidationZone = decisionCycleHelper
|
|
.GetLastDirectionalConsolidationZone(
|
|
X_DIRECTION_BULLISH,
|
|
bullishConsolidationZone //
|
|
);
|
|
|
|
//
|
|
// Bearish ...
|
|
XConsolidationZone bearishConsolidationZone;
|
|
bool hasBearishConsolidationZone = decisionCycleHelper
|
|
.GetLastDirectionalConsolidationZone(
|
|
X_DIRECTION_BEARISH,
|
|
bearishConsolidationZone //
|
|
);
|
|
|
|
//
|
|
// Detect High Probability Swings ...
|
|
bool isSwingLow =
|
|
//
|
|
cBar.low > pBar.low &&
|
|
ppBar.low > pBar.low &&
|
|
//
|
|
zBar.low > pBar.low
|
|
//
|
|
;
|
|
bool isSwingHigh =
|
|
//
|
|
cBar.high < pBar.high &&
|
|
ppBar.high < pBar.high &&
|
|
//
|
|
zBar.high < pBar.high
|
|
//
|
|
;
|
|
bool isStrongSwingLow =
|
|
pBar.IsBullish() &&
|
|
pBar.GetLowShadow() >= pBar.GetBody() * 2;
|
|
bool isStrongSwingHigh =
|
|
pBar.IsBearish() &&
|
|
pBar.GetHighShadow() >= pBar.GetBody() * 2;
|
|
|
|
//
|
|
// Here We Have all Requirements for Guarding Positions ...
|
|
|
|
//
|
|
// Available Guards:
|
|
// X_121_SMC_GUARD_ACTION_NONE
|
|
// X_121_SMC_GUARD_ACTION_CLOSE
|
|
// X_121_SMC_GUARD_ACTION_CLOSE_ALL
|
|
// X_121_SMC_GUARD_ACTION_CLOSE_LONGS
|
|
// X_121_SMC_GUARD_ACTION_CLOSE_SHORTS
|
|
// X_121_SMC_GUARD_ACTION_PARTIAL_CLOSE
|
|
// X_121_SMC_GUARD_ACTION_TRAIL_STOP
|
|
// X_121_SMC_GUARD_ACTION_TRAIL_TARGET
|
|
// X_121_SMC_GUARD_ACTION_HEDGE
|
|
|
|
//
|
|
// X_121_SMC_GUARD_ACTION_CLOSE:
|
|
// Close Specified Position on Specified Conditions ...
|
|
|
|
//
|
|
// X_121_SMC_GUARD_ACTION_CLOSE_ALL:
|
|
// Close All Positions on Specified Conditions ...
|
|
|
|
//
|
|
// X_121_SMC_GUARD_ACTION_CLOSE_LONGS:
|
|
// Close All Long Positions on Specified Conditions ...
|
|
|
|
//
|
|
// X_121_SMC_GUARD_ACTION_CLOSE_SHORTS:
|
|
// Close All Short Positions on Specified Conditions ...
|
|
|
|
//
|
|
// X_121_SMC_GUARD_ACTION_PARTIAL_CLOSE:
|
|
// Partial Close Specified Position on Specified Conditions ...
|
|
|
|
//
|
|
// X_121_SMC_GUARD_ACTION_TRAIL_STOP:
|
|
// Trail Stop Specified Position on Specified Conditions ...
|
|
for (int i = 0; i < count; i++)
|
|
{
|
|
//
|
|
XPosition iPosition = ownPositions[i];
|
|
|
|
//
|
|
bool isLong = IsLong(iPosition.type);
|
|
bool isInProfit = iPosition.profit > 0;
|
|
|
|
//
|
|
double sl = iPosition.sl;
|
|
double tp = iPosition.tp;
|
|
|
|
//
|
|
// Trail Stops Using Consolidation Zones ...
|
|
bool canTraiLonglUsingCZone =
|
|
//
|
|
(isLong &&
|
|
isInProfit &&
|
|
hasBullishConsolidationZone &&
|
|
bullishConsolidationZone.lower > iPosition.sl &&
|
|
bullishConsolidationZone.lower > iPosition.entry)
|
|
//
|
|
;
|
|
if (canTraiLonglUsingCZone)
|
|
{
|
|
sl = bullishConsolidationZone.lower;
|
|
}
|
|
|
|
//
|
|
bool canTraiShortlUsingCZone =
|
|
//
|
|
(!isLong &&
|
|
isInProfit &&
|
|
hasBearishConsolidationZone &&
|
|
bearishConsolidationZone.upper < iPosition.sl &&
|
|
bearishConsolidationZone.upper < iPosition.entry)
|
|
//
|
|
;
|
|
if (canTraiShortlUsingCZone)
|
|
{
|
|
sl = bearishConsolidationZone.upper;
|
|
}
|
|
|
|
//
|
|
bool canTrailUsingCZone =
|
|
canTraiLonglUsingCZone ||
|
|
canTraiShortlUsingCZone;
|
|
|
|
//
|
|
// Trail Stops Using Swings ...
|
|
|
|
//
|
|
bool canTrailLongUsingSwings =
|
|
//
|
|
isLong &&
|
|
isInProfit &&
|
|
(isSwingLow ||
|
|
isStrongSwingLow) &&
|
|
pBar.low > iPosition.sl &&
|
|
pBar.low > iPosition.entry
|
|
//
|
|
;
|
|
if (canTrailLongUsingSwings)
|
|
{
|
|
sl = pBar.low;
|
|
}
|
|
|
|
//
|
|
bool canTraiShortlUsingSwings =
|
|
//
|
|
!isLong &&
|
|
isInProfit &&
|
|
(isSwingHigh ||
|
|
isStrongSwingHigh) &&
|
|
pBar.high < iPosition.sl &&
|
|
pBar.high < iPosition.entry
|
|
//
|
|
;
|
|
if (canTraiShortlUsingSwings)
|
|
{
|
|
sl = pBar.high;
|
|
}
|
|
|
|
//
|
|
bool canTrailUsingSwings =
|
|
canTrailLongUsingSwings ||
|
|
canTraiShortlUsingSwings;
|
|
|
|
//
|
|
//
|
|
//
|
|
|
|
//
|
|
bool canTrail =
|
|
sl != iPosition.sl &&
|
|
(canTrailUsingCZone ||
|
|
canTrailUsingSwings);
|
|
if (canTrail)
|
|
{
|
|
//
|
|
X121SMCGuard iGuard;
|
|
|
|
//
|
|
iGuard.time = cTime;
|
|
iGuard.symbol = symbol;
|
|
iGuard.provider = provider;
|
|
iGuard.action = X_121_SMC_GUARD_ACTION_TRAIL_STOP;
|
|
|
|
//
|
|
iGuard.ticket = iPosition.ticket;
|
|
|
|
//
|
|
iGuard.sl = sl;
|
|
|
|
//
|
|
AddGuard(
|
|
iGuard,
|
|
guards //
|
|
);
|
|
}
|
|
}
|
|
|
|
//
|
|
// X_121_SMC_GUARD_ACTION_TRAIL_TARGET:
|
|
// Trail Target Specified Position on Specified Conditions ...
|
|
|
|
//
|
|
// X_121_SMC_GUARD_ACTION_HEDGE:
|
|
// Hedge all Positions on Specified Conditions ...
|
|
|
|
//
|
|
// Cleanup Collections ...
|
|
|
|
//
|
|
Clean(ownPositions);
|
|
Clean(ownLongPositions);
|
|
Clean(ownShortPositions);
|
|
|
|
//
|
|
zBar.Clean();
|
|
cBar.Clean();
|
|
pBar.Clean();
|
|
ppBar.Clean();
|
|
|
|
//
|
|
Clean(visionPoiEvents);
|
|
Clean(analysePoiEvents);
|
|
Clean(visionCycleEvents);
|
|
Clean(decisionPoiEvents);
|
|
Clean(analyseCycleEvents);
|
|
Clean(decisionCycleEvents);
|
|
Clean(consolidationPoiEvents);
|
|
Clean(consolidationCycleEvents);
|
|
|
|
//
|
|
visionState.Clean();
|
|
analyseState.Clean();
|
|
decisionState.Clean();
|
|
visionConditions.Clean();
|
|
analyseConditions.Clean();
|
|
visionXConditions.Clean();
|
|
decisionConditions.Clean();
|
|
consolidationState.Clean();
|
|
analyseXConditions.Clean();
|
|
decisionXConditions.Clean();
|
|
consolidationConditions.Clean();
|
|
consolidationXConditions.Clean();
|
|
|
|
//
|
|
count = ArraySize(guards);
|
|
result = IsValidSize(count);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Add Conditions to Conditions Collection ...
|
|
int AddConditionsIfNotExists(
|
|
int maxAllowed = 10 //
|
|
)
|
|
{
|
|
//
|
|
int result = 0;
|
|
|
|
//
|
|
bool isSetuped = IsValid(mConditions.setupTime) &&
|
|
HasDirection(mConditions.dir);
|
|
if (!isSetuped)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
int count = ArraySize(mConditionsCollection);
|
|
if (IsValidSize(count))
|
|
{
|
|
//
|
|
// Copy Original Items ...
|
|
X121SMCStrategyXWZSignalConditions tmpItems[];
|
|
Copy(
|
|
mConditionsCollection,
|
|
tmpItems //
|
|
);
|
|
|
|
//
|
|
// Prese Item Data ...
|
|
bool isBullish = IsBullish(mConditions.dir);
|
|
|
|
//
|
|
for (int i = 0; i < count; i++)
|
|
{
|
|
//
|
|
X121SMCStrategyXWZSignalConditions iItem = tmpItems[i];
|
|
|
|
//
|
|
bool canRemove = mConditions.dir == iItem.dir &&
|
|
mConditions.pivot == iItem.pivot;
|
|
if (canRemove)
|
|
{
|
|
//
|
|
ArrayRemove(
|
|
mConditionsCollection,
|
|
i,
|
|
1 //
|
|
);
|
|
}
|
|
}
|
|
|
|
//
|
|
Clean(tmpItems);
|
|
}
|
|
|
|
//
|
|
AddRef(
|
|
mConditions,
|
|
mConditionsCollection //
|
|
);
|
|
|
|
//
|
|
// Remove Olds ...
|
|
CleanupArray(
|
|
mConditionsCollection,
|
|
maxAllowed //
|
|
);
|
|
|
|
//
|
|
result = ArraySize(mConditionsCollection);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
bool DetectWorkingZone(
|
|
XPOIState <fState //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
result = IsValid(symbol) &&
|
|
IsValid(period);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result = !workingZone.IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
workingZone.symbol = symbol;
|
|
workingZone.period = period;
|
|
|
|
//
|
|
int idx = -1;
|
|
bool has = false;
|
|
|
|
//
|
|
has = ltfState.HasSupplyZones();
|
|
if (has)
|
|
{
|
|
//
|
|
idx = GetHighest(ltfState.supplyZones);
|
|
if (IsValidIndex(idx))
|
|
{
|
|
workingZone.supplyZone = ltfState.supplyZones[idx];
|
|
}
|
|
}
|
|
|
|
//
|
|
has = ltfState.HasDemandZones();
|
|
if (has)
|
|
{
|
|
//
|
|
idx = GetLowest(ltfState.demandZones);
|
|
if (IsValidIndex(idx))
|
|
{
|
|
workingZone.demandZone = ltfState.demandZones[idx];
|
|
}
|
|
}
|
|
|
|
//
|
|
bool hasWorkingZone = workingZone.HasSupplyZone() &&
|
|
workingZone.HasDemandZone();
|
|
if (hasWorkingZone)
|
|
{
|
|
//
|
|
double upper = workingZone.supplyZone.Lower();
|
|
double lower = workingZone.demandZone.Upper();
|
|
|
|
//
|
|
double delta = ((upper - lower) / 100) * 25;
|
|
|
|
//
|
|
workingZone.quarter1 = upper - (1 * delta);
|
|
workingZone.quarter2 = upper - (2 * delta);
|
|
workingZone.quarter3 = upper - (3 * delta);
|
|
|
|
//
|
|
hasWorkingZone = workingZone.IsValid();
|
|
}
|
|
|
|
//
|
|
result = hasWorkingZone;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Draw Functions ...
|
|
//
|
|
|
|
//
|
|
void RemoveDraws()
|
|
{
|
|
mObjects.Clear();
|
|
}
|
|
|
|
//
|
|
void DrawBar(
|
|
XOHCL &bar,
|
|
XCPOIDrawer *drawer,
|
|
bool forceClean = true //
|
|
)
|
|
{
|
|
//
|
|
if (forceClean)
|
|
{
|
|
mBarObjects.Clear();
|
|
}
|
|
|
|
//
|
|
if (drawer == NULL ||
|
|
!bar.IsValid())
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
bool isBullish = bar.IsBullish();
|
|
|
|
//
|
|
int widthBar = 2;
|
|
bool fillShadowsBar = true;
|
|
ENUM_LINE_STYLE styleBar = STYLE_SOLID;
|
|
color clrBar =
|
|
isBullish
|
|
? clrAqua
|
|
: clrMagenta;
|
|
|
|
//
|
|
datetime to = bar.NextAt();
|
|
|
|
//
|
|
XCOHCLObject *iObj;
|
|
bool isCreated = drawer
|
|
.CreateBar(
|
|
bar,
|
|
iObj,
|
|
to //
|
|
);
|
|
if (isCreated)
|
|
{
|
|
//
|
|
iObj.BarSpes(
|
|
widthBar,
|
|
clrBar,
|
|
styleBar //
|
|
);
|
|
|
|
//
|
|
iObj.LowShadowFill(fillShadowsBar);
|
|
iObj.HighShadowFill(fillShadowsBar);
|
|
|
|
//
|
|
mBarObjects.Add(iObj);
|
|
}
|
|
}
|
|
|
|
//
|
|
void DrawWorkingZone(
|
|
XCPOIDrawer *drawer,
|
|
bool drawTrendLine = true,
|
|
bool forceClean = false //
|
|
)
|
|
{
|
|
//
|
|
if (drawer == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
if (forceClean)
|
|
{
|
|
mWorkingZoneObjects.Clear();
|
|
}
|
|
|
|
//
|
|
int count = 0;
|
|
bool has = false;
|
|
bool isCreated = false;
|
|
|
|
//
|
|
ulong chartID = drawer.ChartIdentification();
|
|
int subWindow = drawer.SubWindowIdentification();
|
|
color bullishColor = drawer.BarBullishColor();
|
|
color bearishColor = drawer.BarBearishColor();
|
|
|
|
//
|
|
// Supply Zone ...
|
|
has = workingZone.HasSupplyZone();
|
|
if (has)
|
|
{
|
|
//
|
|
XCSupplyZoneObject *iObj;
|
|
isCreated = drawer.CreateSupplyZone(
|
|
workingZone.supplyZone,
|
|
iObj //
|
|
);
|
|
|
|
//
|
|
if (isCreated)
|
|
{
|
|
mWorkingZoneObjects.Add(iObj);
|
|
}
|
|
}
|
|
|
|
//
|
|
has = workingZone.HasSupplyZones();
|
|
if (has)
|
|
{
|
|
//
|
|
count = workingZone.CountSupplyZones();
|
|
for (int i = 0; i < count; i++)
|
|
{
|
|
//
|
|
XCSupplyZoneObject *iObj;
|
|
isCreated = drawer.CreateSupplyZone(
|
|
workingZone.supplyZones[i],
|
|
iObj //
|
|
);
|
|
|
|
//
|
|
if (isCreated)
|
|
{
|
|
mWorkingZoneObjects.Add(iObj);
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// Demand Zone ...
|
|
has = workingZone.HasDemandZone();
|
|
if (has)
|
|
{
|
|
//
|
|
XCDemandZoneObject *iObj;
|
|
isCreated = drawer.CreateDemandZone(
|
|
workingZone.demandZone,
|
|
iObj //
|
|
);
|
|
|
|
//
|
|
if (isCreated)
|
|
{
|
|
mWorkingZoneObjects.Add(iObj);
|
|
}
|
|
}
|
|
|
|
//
|
|
has = workingZone.HasDemandZones();
|
|
if (has)
|
|
{
|
|
//
|
|
count = workingZone.CountDemandZones();
|
|
for (int i = 0; i < count; i++)
|
|
{
|
|
//
|
|
XCDemandZoneObject *iObj;
|
|
isCreated = drawer.CreateDemandZone(
|
|
workingZone.demandZones[i],
|
|
iObj //
|
|
);
|
|
|
|
//
|
|
if (isCreated)
|
|
{
|
|
mWorkingZoneObjects.Add(iObj);
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// Quarters ...
|
|
has = workingZone.IsValid();
|
|
if (has)
|
|
{
|
|
//
|
|
double zoneUpper = workingZone.supplyZone.Upper();
|
|
double upper = workingZone.supplyZone.Lower();
|
|
|
|
//
|
|
double lower = workingZone.demandZone.Upper();
|
|
double zoneLower = workingZone.demandZone.Lower();
|
|
|
|
//
|
|
string prefix = "X121WZone_" + workingZone.symbol + "_" + ToString(workingZone.period);
|
|
|
|
//
|
|
// Zone Upper ...
|
|
CChartObjectHLine *zoneUpperLine;
|
|
zoneUpperLine = new CChartObjectHLine();
|
|
isCreated = zoneUpperLine.Create(
|
|
chartID,
|
|
prefix + "_ZoneTop",
|
|
subWindow,
|
|
zoneUpper //
|
|
);
|
|
if (isCreated)
|
|
{
|
|
//
|
|
zoneUpperLine.Color(clrRed);
|
|
|
|
//
|
|
mWorkingZoneObjects.Add(zoneUpperLine);
|
|
}
|
|
|
|
//
|
|
// Zone Lower ...
|
|
CChartObjectHLine *zoneLowerLine;
|
|
zoneLowerLine = new CChartObjectHLine();
|
|
isCreated = zoneLowerLine.Create(
|
|
chartID,
|
|
prefix + "_ZoneDown",
|
|
subWindow,
|
|
zoneLower //
|
|
);
|
|
if (isCreated)
|
|
{
|
|
//
|
|
zoneLowerLine.Color(clrRed);
|
|
|
|
//
|
|
mWorkingZoneObjects.Add(zoneLowerLine);
|
|
}
|
|
|
|
//
|
|
// Upper ...
|
|
CChartObjectHLine *upperLine;
|
|
upperLine = new CChartObjectHLine();
|
|
isCreated = upperLine.Create(
|
|
chartID,
|
|
prefix + "_Upper",
|
|
subWindow,
|
|
upper //
|
|
);
|
|
if (isCreated)
|
|
{
|
|
//
|
|
upperLine.Color(clrLime);
|
|
|
|
//
|
|
mWorkingZoneObjects.Add(upperLine);
|
|
}
|
|
|
|
//
|
|
// Lower ...
|
|
CChartObjectHLine *lowerLine;
|
|
lowerLine = new CChartObjectHLine();
|
|
isCreated = lowerLine.Create(
|
|
chartID,
|
|
prefix + "_Lower",
|
|
subWindow,
|
|
lower //
|
|
);
|
|
if (isCreated)
|
|
{
|
|
//
|
|
lowerLine.Color(clrLime);
|
|
|
|
//
|
|
mWorkingZoneObjects.Add(lowerLine);
|
|
}
|
|
|
|
//
|
|
// Quarters ...
|
|
|
|
//
|
|
// Quarter 1 ...
|
|
CChartObjectHLine *q1Line;
|
|
q1Line = new CChartObjectHLine();
|
|
isCreated = q1Line.Create(
|
|
chartID,
|
|
prefix + "_Q1",
|
|
subWindow,
|
|
workingZone.quarter1 //
|
|
);
|
|
if (isCreated)
|
|
{
|
|
//
|
|
q1Line.Color(clrYellow);
|
|
|
|
//
|
|
mWorkingZoneObjects.Add(q1Line);
|
|
}
|
|
|
|
//
|
|
// Quarter 2 ...
|
|
CChartObjectHLine *q2Line;
|
|
q2Line = new CChartObjectHLine();
|
|
isCreated = q2Line.Create(
|
|
chartID,
|
|
prefix + "_Q2",
|
|
subWindow,
|
|
workingZone.quarter2 //
|
|
);
|
|
if (isCreated)
|
|
{
|
|
//
|
|
q2Line.Color(clrYellow);
|
|
|
|
//
|
|
mWorkingZoneObjects.Add(q2Line);
|
|
}
|
|
|
|
//
|
|
// Quarter 3 ...
|
|
CChartObjectHLine *q3Line;
|
|
q3Line = new CChartObjectHLine();
|
|
isCreated = q3Line.Create(
|
|
chartID,
|
|
prefix + "_Q3",
|
|
subWindow,
|
|
workingZone.quarter3 //
|
|
);
|
|
if (isCreated)
|
|
{
|
|
//
|
|
q3Line.Color(clrYellow);
|
|
|
|
//
|
|
mWorkingZoneObjects.Add(q3Line);
|
|
}
|
|
}
|
|
|
|
//
|
|
// Draw Order Flow ...
|
|
ENUM_X_DIRECTION trend;
|
|
has = workingZone.HasOrderFlow(trend);
|
|
if (has)
|
|
{
|
|
//
|
|
bool isBullish = IsBullish(trend);
|
|
|
|
//
|
|
count = workingZone.CountOrderFlow();
|
|
for (int i = 0; i < count; i++)
|
|
{
|
|
//
|
|
XOBFVG iOBFVG = workingZone.orderFlow[i];
|
|
|
|
//
|
|
XCBaseObject *drawnObjects[];
|
|
int drawnObjectsCount = drawer
|
|
.DrawOBFVG(
|
|
//
|
|
iOBFVG,
|
|
drawnObjects,
|
|
//
|
|
true, // Draw Order Block ...
|
|
true, // Draw Fair Value Gap ...
|
|
false, // Draw Supply Zones ...
|
|
false, // Draw Demand Zones ...
|
|
false, // Draw Support Zones ...
|
|
false // Draw Resistance Zones ...
|
|
);
|
|
if (IsValidSize(drawnObjectsCount))
|
|
{
|
|
AddDrawnWorkingZoneObjects(drawnObjects);
|
|
}
|
|
}
|
|
|
|
//
|
|
// Draw Trend Line ...
|
|
if (drawTrendLine)
|
|
{
|
|
//
|
|
XOBFVGPivot pivots[];
|
|
count = workingZone.GetSwings(pivots);
|
|
has = count >= 2;
|
|
if (has)
|
|
{
|
|
//
|
|
// Get Max / Min ...
|
|
double max = 0;
|
|
double min = 0;
|
|
datetime maxAt = NULL;
|
|
datetime minAt = NULL;
|
|
for (int i = 0; i < count; i++)
|
|
{
|
|
//
|
|
XOBFVGPivot iPivot = pivots[i];
|
|
|
|
//
|
|
if (!iPivot.IsValid())
|
|
{
|
|
//
|
|
iPivot.Clean();
|
|
continue;
|
|
}
|
|
|
|
//
|
|
// Min ...
|
|
bool canSetMin =
|
|
min == 0
|
|
? true
|
|
: min > iPivot.value;
|
|
if (canSetMin)
|
|
{
|
|
//
|
|
minAt = iPivot.at;
|
|
min = iPivot.value;
|
|
}
|
|
|
|
//
|
|
// Max ...
|
|
bool canSetMax =
|
|
max == 0
|
|
? true
|
|
: max < iPivot.value;
|
|
if (canSetMax)
|
|
{
|
|
//
|
|
maxAt = iPivot.at;
|
|
max = iPivot.value;
|
|
}
|
|
|
|
//
|
|
iPivot.Clean();
|
|
}
|
|
|
|
//
|
|
double price1 =
|
|
isBullish
|
|
? min
|
|
: max;
|
|
double price2 =
|
|
isBullish
|
|
? max
|
|
: min;
|
|
datetime time1 =
|
|
isBullish
|
|
? minAt
|
|
: maxAt;
|
|
datetime time2 =
|
|
isBullish
|
|
? maxAt
|
|
: minAt;
|
|
|
|
//
|
|
color clrTrend =
|
|
isBullish
|
|
? bullishColor
|
|
: bearishColor;
|
|
|
|
//
|
|
string trendName =
|
|
ToString(trend) + "_" + "XTRNDL_" +
|
|
ToString(period) + "_" +
|
|
ToString(price1) + "_" +
|
|
ToString(price2) + "_";
|
|
// + ToMD5(ToString(time1));
|
|
|
|
//
|
|
CChartObjectTrend *mTrend;
|
|
mTrend = new CChartObjectTrend();
|
|
isCreated = mTrend.Create(
|
|
chartID,
|
|
trendName,
|
|
subWindow,
|
|
time1,
|
|
price1,
|
|
time2,
|
|
price2 //
|
|
);
|
|
|
|
//
|
|
if (isCreated)
|
|
{
|
|
//
|
|
mTrend.Width(2);
|
|
mTrend.Color(clrTrend);
|
|
mTrend.RayRight(true);
|
|
|
|
//
|
|
mWorkingZoneObjects.Add(mTrend);
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// Draw Target Zone ...
|
|
has = targetZone.IsValid();
|
|
if (has)
|
|
{
|
|
//
|
|
XCBaseObject *drawnObjects[];
|
|
int drawnObjectsCount = drawer
|
|
.DrawOBFVG(
|
|
//
|
|
targetZone,
|
|
drawnObjects,
|
|
//
|
|
true, // Draw Order Block ...
|
|
true, // Draw Fair Value Gap ...
|
|
false, // Draw Supply Zones ...
|
|
false, // Draw Demand Zones ...
|
|
false, // Draw Support Zones ...
|
|
false // Draw Resistance Zones ...
|
|
);
|
|
if (IsValidSize(drawnObjectsCount))
|
|
{
|
|
AddDrawnWorkingZoneObjects(drawnObjects);
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
}
|
|
|
|
//
|
|
void DrawConditions(
|
|
X121SMCStrategyXWZSignalConditions &conditions,
|
|
XCPOIDrawer *drawer,
|
|
bool forceClean = false //
|
|
)
|
|
{
|
|
//
|
|
if (drawer == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
if (forceClean)
|
|
{
|
|
mObjects.Clear();
|
|
}
|
|
|
|
//
|
|
bool hasSignalZone = conditions.signalZone.IsValid();
|
|
if (hasSignalZone)
|
|
{
|
|
//
|
|
XCBaseObject *iObjects[];
|
|
int iObjectsCount = drawer.DrawOBFVG(
|
|
conditions.signalZone,
|
|
iObjects //
|
|
);
|
|
AddDrawnObjects(iObjects);
|
|
}
|
|
}
|
|
|
|
//
|
|
protected:
|
|
//
|
|
|
|
//
|
|
private:
|
|
//
|
|
// Props ...
|
|
string symbol;
|
|
ENUM_TIMEFRAMES period;
|
|
CArrayObj mObjects;
|
|
CArrayObj mBarObjects;
|
|
CArrayObj mWorkingZoneObjects;
|
|
|
|
/**
|
|
* Initialize ...
|
|
*/
|
|
void Init()
|
|
{
|
|
}
|
|
|
|
/**
|
|
* DeInitialize ...
|
|
*/
|
|
void DeInit()
|
|
{
|
|
//
|
|
chochZone.Clean();
|
|
signalZone.Clean();
|
|
targetZone.Clean();
|
|
mConditions.Clean();
|
|
workingZone.Clean();
|
|
Clean(mConditionsCollection);
|
|
|
|
//
|
|
mObjects.Clear();
|
|
mBarObjects.Clear();
|
|
mWorkingZoneObjects.Clear();
|
|
}
|
|
|
|
/**
|
|
* Update To Time of Exists Components ...
|
|
*
|
|
* @param value: updated time ...
|
|
*/
|
|
void UpdateTo(
|
|
datetime value = NULL //
|
|
)
|
|
{
|
|
//
|
|
value = NormalizeTime(value);
|
|
|
|
//
|
|
chochZone.UpdateTo(value);
|
|
targetZone.UpdateTo(value);
|
|
signalZone.UpdateTo(value);
|
|
workingZone.UpdateTo(value);
|
|
mConditions.UpdateTo(value);
|
|
waitingZone.UpdateTo(value);
|
|
}
|
|
|
|
//
|
|
// Helpers ...
|
|
|
|
//
|
|
bool CalculateRiskReward(
|
|
ENUM_X121SMC_XWZ_PRIORITY priority,
|
|
double &reward,
|
|
double &amountPercent //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
reward = 0;
|
|
amountPercent = 0;
|
|
|
|
//
|
|
result = priority != X121SMC_XWZ_PRIORITY_NONE;
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
switch (priority)
|
|
{
|
|
//
|
|
case X121SMC_XWZ_PRIORITY_STRONG_HIGH:
|
|
//
|
|
reward = 6;
|
|
amountPercent = 2;
|
|
break;
|
|
|
|
//
|
|
case X121SMC_XWZ_PRIORITY_HIGH:
|
|
//
|
|
reward = 4;
|
|
amountPercent = 2;
|
|
break;
|
|
|
|
//
|
|
case X121SMC_XWZ_PRIORITY_REGULAR:
|
|
//
|
|
reward = 3;
|
|
amountPercent = 1.5;
|
|
break;
|
|
|
|
//
|
|
case X121SMC_XWZ_PRIORITY_LOW:
|
|
//
|
|
reward = 2;
|
|
amountPercent = 1;
|
|
break;
|
|
|
|
//
|
|
case X121SMC_XWZ_PRIORITY_WEAK:
|
|
//
|
|
reward = 1;
|
|
amountPercent = 0.5;
|
|
break;
|
|
}
|
|
|
|
//
|
|
result =
|
|
//
|
|
reward > 0 &&
|
|
amountPercent > 0
|
|
//
|
|
;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
void AddDrawnObjects(XCBaseObject *&objects[])
|
|
{
|
|
//
|
|
int count = ArraySize(objects);
|
|
bool has = IsValidSize(count);
|
|
if (!has)
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
for (int i = 0; i < count; i++)
|
|
{
|
|
mObjects.Add(objects[i]);
|
|
}
|
|
}
|
|
|
|
//
|
|
void AddDrawnWorkingZoneObjects(XCBaseObject *&objects[])
|
|
{
|
|
//
|
|
int count = ArraySize(objects);
|
|
bool has = IsValidSize(count);
|
|
if (!has)
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
for (int i = 0; i < count; i++)
|
|
{
|
|
mWorkingZoneObjects.Add(objects[i]);
|
|
}
|
|
}
|
|
|
|
//
|
|
};
|
|
|
|
// |