Add support for Draw Trend Line for Order Flow ...
This commit is contained in:
@@ -4332,6 +4332,7 @@ class XCPOIDrawer : public XCBase
|
|||||||
|
|
||||||
//
|
//
|
||||||
int DrawOBFVG(
|
int DrawOBFVG(
|
||||||
|
//
|
||||||
XOBFVG &item,
|
XOBFVG &item,
|
||||||
XCBaseObject *&objects[],
|
XCBaseObject *&objects[],
|
||||||
//
|
//
|
||||||
|
|||||||
@@ -6067,6 +6067,51 @@ struct XBoxZone
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//
|
||||||
|
struct XOBFVGPivot
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Props ...
|
||||||
|
double value;
|
||||||
|
datetime at;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Constructor ...
|
||||||
|
XOBFVGPivot()
|
||||||
|
{
|
||||||
|
Clean();
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Tools ...
|
||||||
|
|
||||||
|
//
|
||||||
|
void Clean()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
value = 0;
|
||||||
|
at = NULL;
|
||||||
|
|
||||||
|
//
|
||||||
|
ZeroMemory(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
bool IsValid()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
bool result = false;
|
||||||
|
|
||||||
|
//
|
||||||
|
result =
|
||||||
|
value > 0 &&
|
||||||
|
IsValid(at);
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
//
|
//
|
||||||
struct XOBFVG
|
struct XOBFVG
|
||||||
{
|
{
|
||||||
@@ -6105,6 +6150,9 @@ struct XOBFVG
|
|||||||
Clean(demandZones);
|
Clean(demandZones);
|
||||||
Clean(supportZones);
|
Clean(supportZones);
|
||||||
Clean(resistanceZones);
|
Clean(resistanceZones);
|
||||||
|
|
||||||
|
//
|
||||||
|
ZeroMemory(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
@@ -6176,6 +6224,166 @@ struct XOBFVG
|
|||||||
return ArraySize(resistanceZones);
|
return ArraySize(resistanceZones);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
ENUM_X_DIRECTION GetDirection()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
ENUM_X_DIRECTION result = X_DIRECTION_NONE;
|
||||||
|
|
||||||
|
//
|
||||||
|
bool isValid = IsValid();
|
||||||
|
if (!isValid)
|
||||||
|
{
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
result = ob.GetDirection();
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
bool IsBullish()
|
||||||
|
{
|
||||||
|
return IsBullish(GetDirection());
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
bool IsBearish()
|
||||||
|
{
|
||||||
|
return IsBearish(GetDirection());
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
int GetSwings(
|
||||||
|
XOBFVGPivot &pivots[] //
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
int result = 0;
|
||||||
|
|
||||||
|
//
|
||||||
|
Clean(pivots);
|
||||||
|
|
||||||
|
//
|
||||||
|
if (!IsValid())
|
||||||
|
{
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
ENUM_X_DIRECTION forDir = GetDirection();
|
||||||
|
bool isBullish = IsBullish(forDir);
|
||||||
|
|
||||||
|
//
|
||||||
|
XOHCL passedBar;
|
||||||
|
XOBFVGPivot iPivot;
|
||||||
|
bool isPassed = false;
|
||||||
|
double appliedPrice = 0;
|
||||||
|
bool isBodyState = false;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Start ...
|
||||||
|
isPassed = ob.IsStarted(
|
||||||
|
forDir,
|
||||||
|
passedBar,
|
||||||
|
isBodyState //
|
||||||
|
);
|
||||||
|
if (isPassed)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
appliedPrice =
|
||||||
|
isBullish
|
||||||
|
? passedBar.low
|
||||||
|
: passedBar.high;
|
||||||
|
|
||||||
|
//
|
||||||
|
iPivot.Clean();
|
||||||
|
iPivot.value = appliedPrice;
|
||||||
|
iPivot.at = passedBar.time;
|
||||||
|
|
||||||
|
//
|
||||||
|
AddRef(
|
||||||
|
iPivot,
|
||||||
|
pivots //
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
iPivot.Clean();
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Activation ...
|
||||||
|
isPassed = ob.IsActivated(
|
||||||
|
forDir,
|
||||||
|
passedBar,
|
||||||
|
isBodyState //
|
||||||
|
);
|
||||||
|
if (isPassed)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
appliedPrice =
|
||||||
|
isBullish
|
||||||
|
? passedBar.low
|
||||||
|
: passedBar.high;
|
||||||
|
|
||||||
|
//
|
||||||
|
iPivot.Clean();
|
||||||
|
iPivot.value = appliedPrice;
|
||||||
|
iPivot.at = passedBar.time;
|
||||||
|
|
||||||
|
//
|
||||||
|
AddRef(
|
||||||
|
iPivot,
|
||||||
|
pivots //
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
iPivot.Clean();
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Worked ...
|
||||||
|
isPassed = ob.IsWorked(
|
||||||
|
forDir,
|
||||||
|
passedBar,
|
||||||
|
isBodyState //
|
||||||
|
);
|
||||||
|
if (isPassed)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
appliedPrice =
|
||||||
|
isBullish
|
||||||
|
? passedBar.low
|
||||||
|
: passedBar.high;
|
||||||
|
|
||||||
|
//
|
||||||
|
iPivot.Clean();
|
||||||
|
iPivot.value = appliedPrice;
|
||||||
|
iPivot.at = passedBar.time;
|
||||||
|
|
||||||
|
//
|
||||||
|
AddRef(
|
||||||
|
iPivot,
|
||||||
|
pivots //
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
iPivot.Clean();
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
passedBar.Clean();
|
||||||
|
|
||||||
|
//
|
||||||
|
result = ArraySize(pivots);
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
void UpdateTo(datetime value = NULL)
|
void UpdateTo(datetime value = NULL)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -232,26 +232,47 @@ class XCX121SMCXWZSignalDetector : public XCBase
|
|||||||
// Setup Conditions ...
|
// Setup Conditions ...
|
||||||
|
|
||||||
//
|
//
|
||||||
int bullishFlowCount = mConditions.DetectOrderFlow(
|
ENUM_X_DIRECTION trend = X_DIRECTION_NONE;
|
||||||
X_DIRECTION_BULLISH,
|
bool hasOrderFlow = mConditions.HasOrderFlow(trend);
|
||||||
consolidationState,
|
if (!hasOrderFlow)
|
||||||
analyseState,
|
{
|
||||||
decisionState,
|
//
|
||||||
zIndex,
|
int orderFlowCount = mConditions.DetectOrderFlow(
|
||||||
period,
|
trend,
|
||||||
|
consolidationState,
|
||||||
|
analyseState,
|
||||||
|
decisionState //
|
||||||
|
);
|
||||||
|
hasOrderFlow = IsValidSize(orderFlowCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
result = hasOrderFlow;
|
||||||
|
if (!result)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// TODO: Implement Clean ...
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
isBullish = IsBullish(trend);
|
||||||
|
isBearish = IsBearish(trend);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Has Order Flow ...
|
||||||
|
|
||||||
|
//
|
||||||
|
// TODO: Remove this ...
|
||||||
|
DrawConditions(
|
||||||
|
mConditions,
|
||||||
visionCycleHelper.mPOIDrawer //
|
visionCycleHelper.mPOIDrawer //
|
||||||
);
|
);
|
||||||
|
|
||||||
//
|
//
|
||||||
int bearishFlowCount = mConditions.DetectOrderFlow(
|
|
||||||
X_DIRECTION_BEARISH,
|
|
||||||
consolidationState,
|
|
||||||
analyseState,
|
|
||||||
decisionState,
|
|
||||||
zIndex,
|
|
||||||
period,
|
|
||||||
visionCycleHelper.mPOIDrawer //
|
|
||||||
);
|
|
||||||
|
|
||||||
//
|
//
|
||||||
return false;
|
return false;
|
||||||
@@ -1535,6 +1556,7 @@ class XCX121SMCXWZSignalDetector : public XCBase
|
|||||||
void DrawConditions(
|
void DrawConditions(
|
||||||
X121SMCStrategyXWZSignalConditions &conditions,
|
X121SMCStrategyXWZSignalConditions &conditions,
|
||||||
XCPOIDrawer *drawer,
|
XCPOIDrawer *drawer,
|
||||||
|
bool drawTrendLine = true,
|
||||||
bool forceClean = false //
|
bool forceClean = false //
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
@@ -1551,6 +1573,8 @@ class XCX121SMCXWZSignalDetector : public XCBase
|
|||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
int count = 0;
|
||||||
|
bool has = false;
|
||||||
bool isCreated = false;
|
bool isCreated = false;
|
||||||
|
|
||||||
//
|
//
|
||||||
@@ -1558,6 +1582,160 @@ class XCX121SMCXWZSignalDetector : public XCBase
|
|||||||
int subWindow = drawer.SubWindowIdentification();
|
int subWindow = drawer.SubWindowIdentification();
|
||||||
color bullishColor = drawer.BarBullishColor();
|
color bullishColor = drawer.BarBullishColor();
|
||||||
color bearishColor = drawer.BarBearishColor();
|
color bearishColor = drawer.BarBearishColor();
|
||||||
|
|
||||||
|
//
|
||||||
|
ENUM_X_DIRECTION trend;
|
||||||
|
has = conditions.HasOrderFlow(trend);
|
||||||
|
if (has)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
bool isBullish = IsBullish(trend);
|
||||||
|
|
||||||
|
//
|
||||||
|
count = conditions.CountOrderFlow();
|
||||||
|
for (int i = 0; i < count; i++)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
XOBFVG iOBFVG = conditions.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))
|
||||||
|
{
|
||||||
|
AddDrawnObjects(drawnObjects);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
if (drawTrendLine)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
XOBFVGPivot pivots[];
|
||||||
|
count = conditions.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(conditions.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);
|
||||||
|
|
||||||
|
//
|
||||||
|
mObjects.Add(mTrend);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
@@ -1663,6 +1841,24 @@ class XCX121SMCXWZSignalDetector : public XCBase
|
|||||||
return result;
|
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]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -37,306 +37,6 @@ enum ENUM_X121SMC_XWZ_PRIORITY
|
|||||||
X121SMC_XWZ_PRIORITY_STRONG_HIGH,
|
X121SMC_XWZ_PRIORITY_STRONG_HIGH,
|
||||||
};
|
};
|
||||||
|
|
||||||
//
|
|
||||||
struct X121SMCXWZZone
|
|
||||||
{
|
|
||||||
//
|
|
||||||
// Props ...
|
|
||||||
XCFVG *fvg;
|
|
||||||
XCOrderBlock *ob;
|
|
||||||
XCSupplyZone *supply;
|
|
||||||
XCDemandZone *demand;
|
|
||||||
XCSupportZone *support;
|
|
||||||
XCResistanceZone *resistance;
|
|
||||||
|
|
||||||
//
|
|
||||||
// Constructor ...
|
|
||||||
X121SMCXWZZone()
|
|
||||||
{
|
|
||||||
Clean();
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Tools ...
|
|
||||||
|
|
||||||
//
|
|
||||||
void Clean()
|
|
||||||
{
|
|
||||||
//
|
|
||||||
ZeroMemory(ob);
|
|
||||||
ZeroMemory(fvg);
|
|
||||||
ZeroMemory(supply);
|
|
||||||
ZeroMemory(demand);
|
|
||||||
ZeroMemory(support);
|
|
||||||
ZeroMemory(resistance);
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
bool IsValid()
|
|
||||||
{
|
|
||||||
//
|
|
||||||
return HasOB() &&
|
|
||||||
HasFVG() &&
|
|
||||||
HasDirection();
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
bool AsBox(XBoxZone &box)
|
|
||||||
{
|
|
||||||
//
|
|
||||||
bool result = false;
|
|
||||||
|
|
||||||
//
|
|
||||||
box.Clean();
|
|
||||||
|
|
||||||
//
|
|
||||||
result = IsValid() &&
|
|
||||||
HasDirection();
|
|
||||||
if (!result)
|
|
||||||
{
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
XBoxZone obBox;
|
|
||||||
bool hasOBBox = ToBox(
|
|
||||||
obBox,
|
|
||||||
ob //
|
|
||||||
);
|
|
||||||
result = hasOBBox;
|
|
||||||
if (!result)
|
|
||||||
{
|
|
||||||
//
|
|
||||||
box.Clean();
|
|
||||||
obBox.Clean();
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
box = obBox;
|
|
||||||
|
|
||||||
//
|
|
||||||
obBox.Clean();
|
|
||||||
|
|
||||||
//
|
|
||||||
bool hasOB = HasOB();
|
|
||||||
bool hasFVG = HasFVG();
|
|
||||||
bool hasSupply = HasSupply();
|
|
||||||
bool hasDemand = HasDemand();
|
|
||||||
bool hasSupport = HasSupport();
|
|
||||||
bool hasResistance = HasResistance();
|
|
||||||
|
|
||||||
//
|
|
||||||
// OB Compared since box used obBox ...
|
|
||||||
|
|
||||||
//
|
|
||||||
if (hasFVG)
|
|
||||||
{
|
|
||||||
//
|
|
||||||
if (fvg.Upper() > box.upper)
|
|
||||||
{
|
|
||||||
box.upper = fvg.Upper();
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
if (fvg.Lower() < box.lower)
|
|
||||||
{
|
|
||||||
box.lower = fvg.Lower();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
result = box.IsValid();
|
|
||||||
|
|
||||||
//
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
bool HasOB()
|
|
||||||
{
|
|
||||||
return ob != NULL &&
|
|
||||||
ob.IsValid();
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
bool HasFVG()
|
|
||||||
{
|
|
||||||
return fvg != NULL &&
|
|
||||||
fvg.IsValid();
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
bool HasSupply()
|
|
||||||
{
|
|
||||||
return supply != NULL &&
|
|
||||||
supply.IsValid();
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
bool HasDemand()
|
|
||||||
{
|
|
||||||
return demand != NULL &&
|
|
||||||
demand.IsValid();
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
bool HasSupport()
|
|
||||||
{
|
|
||||||
return support != NULL &&
|
|
||||||
support.IsValid();
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
bool HasResistance()
|
|
||||||
{
|
|
||||||
return resistance != NULL &&
|
|
||||||
resistance.IsValid();
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
bool IsBullish()
|
|
||||||
{
|
|
||||||
//
|
|
||||||
return HasOB() &&
|
|
||||||
ob.IsBullish() &&
|
|
||||||
HasFVG() &&
|
|
||||||
fvg.IsBullish();
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
bool IsBearish()
|
|
||||||
{
|
|
||||||
//
|
|
||||||
return HasOB() &&
|
|
||||||
ob.IsBearish() &&
|
|
||||||
HasFVG() &&
|
|
||||||
fvg.IsBearish();
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
bool HasDirection()
|
|
||||||
{
|
|
||||||
return IsBullish() ||
|
|
||||||
IsBearish();
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
bool ValidateZone(
|
|
||||||
int barIndex = 0,
|
|
||||||
ENUM_TIMEFRAMES forPeriod = NULL,
|
|
||||||
bool forceOB = false,
|
|
||||||
bool forceFVG = false //
|
|
||||||
)
|
|
||||||
{
|
|
||||||
//
|
|
||||||
bool result = false;
|
|
||||||
|
|
||||||
//
|
|
||||||
if (barIndex < 0)
|
|
||||||
{
|
|
||||||
barIndex = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
result = IsValid() &&
|
|
||||||
HasDirection();
|
|
||||||
if (!result)
|
|
||||||
{
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
string symbol = ob.GetSymbol();
|
|
||||||
if (forPeriod == NULL)
|
|
||||||
{
|
|
||||||
forPeriod = ob.GetPeriod();
|
|
||||||
}
|
|
||||||
ENUM_X_DIRECTION forDir = GetDirection();
|
|
||||||
|
|
||||||
//
|
|
||||||
XOHCL cBar;
|
|
||||||
result = cBar.Init(
|
|
||||||
symbol,
|
|
||||||
forPeriod,
|
|
||||||
barIndex + 1 //
|
|
||||||
);
|
|
||||||
if (!result)
|
|
||||||
{
|
|
||||||
//
|
|
||||||
cBar.Clean();
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
bool isObBreaked =
|
|
||||||
IsBullish(forDir)
|
|
||||||
? cBar.close < ob.Lower()
|
|
||||||
: cBar.close > ob.Upper();
|
|
||||||
|
|
||||||
//
|
|
||||||
bool isFVGBreaked =
|
|
||||||
IsBullish(forDir)
|
|
||||||
? cBar.close < fvg.Lower()
|
|
||||||
: cBar.close > fvg.Upper();
|
|
||||||
|
|
||||||
//
|
|
||||||
bool isBreaked = true;
|
|
||||||
if ((forceOB && forceFVG) ||
|
|
||||||
(!forceOB && !forceFVG))
|
|
||||||
{
|
|
||||||
isBreaked =
|
|
||||||
isObBreaked ||
|
|
||||||
isFVGBreaked;
|
|
||||||
}
|
|
||||||
else if (forceFVG)
|
|
||||||
{
|
|
||||||
isBreaked = isFVGBreaked;
|
|
||||||
}
|
|
||||||
else if (forceOB)
|
|
||||||
{
|
|
||||||
isBreaked = isObBreaked;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
result = !isBreaked;
|
|
||||||
|
|
||||||
//
|
|
||||||
cBar.Clean();
|
|
||||||
|
|
||||||
//
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
ENUM_X_DIRECTION GetDirection()
|
|
||||||
{
|
|
||||||
//
|
|
||||||
ENUM_X_DIRECTION result = X_DIRECTION_NONE;
|
|
||||||
|
|
||||||
//
|
|
||||||
bool hasDirection = HasDirection();
|
|
||||||
if (!hasDirection)
|
|
||||||
{
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
bool isBullish = IsBullish();
|
|
||||||
|
|
||||||
//
|
|
||||||
result =
|
|
||||||
isBullish
|
|
||||||
? X_DIRECTION_BULLISH
|
|
||||||
: X_DIRECTION_BEARISH;
|
|
||||||
|
|
||||||
//
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
};
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Definitions ...
|
// Definitions ...
|
||||||
struct X121SMCStrategyXWZSignalConditions
|
struct X121SMCStrategyXWZSignalConditions
|
||||||
@@ -371,9 +71,7 @@ struct X121SMCStrategyXWZSignalConditions
|
|||||||
ENUM_X121SMC_XWZ_PRIORITY priority;
|
ENUM_X121SMC_XWZ_PRIORITY priority;
|
||||||
|
|
||||||
//
|
//
|
||||||
// X121SMCXWZZone startZone;
|
XOBFVG orderFlow[];
|
||||||
X121SMCXWZZone bullishFlow[];
|
|
||||||
X121SMCXWZZone bearishFlow[];
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Constructor ...
|
// Constructor ...
|
||||||
@@ -503,8 +201,7 @@ struct X121SMCStrategyXWZSignalConditions
|
|||||||
|
|
||||||
//
|
//
|
||||||
// startZone.Clean();
|
// startZone.Clean();
|
||||||
Clean(bullishFlow);
|
Clean(orderFlow);
|
||||||
Clean(bearishFlow);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
@@ -512,27 +209,93 @@ struct X121SMCStrategyXWZSignalConditions
|
|||||||
//
|
//
|
||||||
|
|
||||||
//
|
//
|
||||||
bool HasBullishFlow()
|
bool HasOrderFlow()
|
||||||
{
|
{
|
||||||
return HasChild(bullishFlow);
|
//
|
||||||
|
bool result = false;
|
||||||
|
|
||||||
|
//
|
||||||
|
result = HasChild(orderFlow);
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
int CountBullishFlow()
|
bool HasOrderFlow(
|
||||||
|
ENUM_X_DIRECTION &orderFlowDir //
|
||||||
|
)
|
||||||
{
|
{
|
||||||
return ArraySize(bullishFlow);
|
//
|
||||||
|
bool result = false;
|
||||||
|
|
||||||
|
//
|
||||||
|
result = HasChild(orderFlow);
|
||||||
|
if (result)
|
||||||
|
{
|
||||||
|
orderFlowDir = orderFlow[0].GetDirection();
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
bool HasBearishFlow()
|
int CountOrderFlow()
|
||||||
{
|
{
|
||||||
return HasChild(bearishFlow);
|
return ArraySize(orderFlow);
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
int CountBearishFlow()
|
int GetSwings(
|
||||||
|
XOBFVGPivot &pivots[] //
|
||||||
|
)
|
||||||
{
|
{
|
||||||
return ArraySize(bearishFlow);
|
//
|
||||||
|
int result = 0;
|
||||||
|
|
||||||
|
//
|
||||||
|
Clean(pivots);
|
||||||
|
|
||||||
|
//
|
||||||
|
int count = 0;
|
||||||
|
bool has = false;
|
||||||
|
|
||||||
|
//
|
||||||
|
has = HasOrderFlow();
|
||||||
|
if (!has)
|
||||||
|
{
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
count = CountOrderFlow();
|
||||||
|
for (int i = 0; i < count; i++)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
XOBFVGPivot iPivots[];
|
||||||
|
int iPivotsCount = orderFlow[i]
|
||||||
|
.GetSwings(iPivots);
|
||||||
|
bool hasPivots = IsValidSize(iPivotsCount);
|
||||||
|
if (hasPivots)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
Copy(
|
||||||
|
iPivots,
|
||||||
|
pivots,
|
||||||
|
false //
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
Clean(iPivots);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
result = ArraySize(pivots);
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
@@ -542,6 +305,22 @@ struct X121SMCStrategyXWZSignalConditions
|
|||||||
value = NormalizeTime(value);
|
value = NormalizeTime(value);
|
||||||
|
|
||||||
//
|
//
|
||||||
|
int count = 0;
|
||||||
|
bool has = false;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Order Flow ...
|
||||||
|
ENUM_X_DIRECTION orderFlowDir;
|
||||||
|
has = HasOrderFlow(orderFlowDir);
|
||||||
|
if (has)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
count = CountOrderFlow();
|
||||||
|
for (int i = 0; i < count; i++)
|
||||||
|
{
|
||||||
|
orderFlow[i].UpdateTo(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
@@ -550,18 +329,19 @@ struct X121SMCStrategyXWZSignalConditions
|
|||||||
|
|
||||||
//
|
//
|
||||||
int DetectOrderFlow(
|
int DetectOrderFlow(
|
||||||
ENUM_X_DIRECTION forDir,
|
ENUM_X_DIRECTION &orderFlowDir,
|
||||||
XPOIState &htfState,
|
XPOIState &htfState,
|
||||||
XPOIState &mtfState,
|
XPOIState &mtfState,
|
||||||
XPOIState &stfState,
|
XPOIState &stfState //
|
||||||
int barIndex = 0,
|
|
||||||
ENUM_TIMEFRAMES forPeriod = NULL,
|
|
||||||
XCPOIDrawer *drawer = NULL //
|
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
//
|
//
|
||||||
int result = 0;
|
int result = 0;
|
||||||
|
|
||||||
|
//
|
||||||
|
Clean(orderFlow);
|
||||||
|
orderFlowDir = X_DIRECTION_NONE;
|
||||||
|
|
||||||
//
|
//
|
||||||
bool isValid =
|
bool isValid =
|
||||||
//
|
//
|
||||||
@@ -569,8 +349,7 @@ struct X121SMCStrategyXWZSignalConditions
|
|||||||
IsValid(period) &&
|
IsValid(period) &&
|
||||||
htfState.HasChild() &&
|
htfState.HasChild() &&
|
||||||
mtfState.HasChild() &&
|
mtfState.HasChild() &&
|
||||||
stfState.HasChild() &&
|
stfState.HasChild()
|
||||||
HasDirection(forDir)
|
|
||||||
//
|
//
|
||||||
;
|
;
|
||||||
if (!isValid)
|
if (!isValid)
|
||||||
@@ -579,27 +358,14 @@ struct X121SMCStrategyXWZSignalConditions
|
|||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
if (forPeriod == NULL)
|
// Bullish OBFVGs ...
|
||||||
{
|
XOBFVG bullOBFVGs[];
|
||||||
forPeriod = period;
|
int bullOBFVGsCount = ExtractOBFVGZones(
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
bool isBullish = IsBullish(forDir);
|
|
||||||
|
|
||||||
//
|
|
||||||
int idx = -1;
|
|
||||||
int count = 0;
|
|
||||||
bool has = false;
|
|
||||||
|
|
||||||
//
|
|
||||||
XOBFVG tmpOBFVGs[];
|
|
||||||
count = ExtractOBFVGZones(
|
|
||||||
htfState,
|
htfState,
|
||||||
mtfState,
|
mtfState,
|
||||||
stfState,
|
stfState,
|
||||||
tmpOBFVGs,
|
bullOBFVGs,
|
||||||
forDir,
|
X_DIRECTION_BULLISH,
|
||||||
NULL, // For Period ...
|
NULL, // For Period ...
|
||||||
//
|
//
|
||||||
// Start ...
|
// Start ...
|
||||||
@@ -624,169 +390,107 @@ struct X121SMCStrategyXWZSignalConditions
|
|||||||
//
|
//
|
||||||
true, // Ignore Inside in Place Filter ...
|
true, // Ignore Inside in Place Filter ...
|
||||||
//
|
//
|
||||||
true, // Detect Inside OB POI(s) ...
|
true, // Detect Inside OB POI(s) ...
|
||||||
false, // Detect Inside FVG POI(s) ...
|
true, // Detect Inside FVG POI(s) ...
|
||||||
true // Apply From Filter to Selected POI(s) ...
|
true // Apply From Filter to Selected POI(s) ...
|
||||||
);
|
);
|
||||||
has = IsValidSize(count);
|
bool hasBullOBFVGs = IsValidSize(bullOBFVGsCount);
|
||||||
if (has)
|
|
||||||
|
//
|
||||||
|
// Bearish OBFVGs ...
|
||||||
|
XOBFVG bearOBFVGs[];
|
||||||
|
int bearOBFVGsCount = ExtractOBFVGZones(
|
||||||
|
htfState,
|
||||||
|
mtfState,
|
||||||
|
stfState,
|
||||||
|
bearOBFVGs,
|
||||||
|
X_DIRECTION_BEARISH,
|
||||||
|
NULL, // For Period ...
|
||||||
|
//
|
||||||
|
// Start ...
|
||||||
|
XZONE_STATE_PASSED,
|
||||||
|
true, // Force Body Out ...
|
||||||
|
//
|
||||||
|
// Activation ...
|
||||||
|
XZONE_STATE_PASSED,
|
||||||
|
true, // Force Body In ...
|
||||||
|
//
|
||||||
|
// Breaktion ...
|
||||||
|
XZONE_STATE_FAILED,
|
||||||
|
false, // Force Body In ...
|
||||||
|
//
|
||||||
|
// Works ...
|
||||||
|
XZONE_STATE_PASSED,
|
||||||
|
true, // Force Body Out ...
|
||||||
|
//
|
||||||
|
true, // Apply Sort ...
|
||||||
|
true, // From Filter ...
|
||||||
|
true, // Place Filter ...
|
||||||
|
//
|
||||||
|
true, // Ignore Inside in Place Filter ...
|
||||||
|
//
|
||||||
|
true, // Detect Inside OB POI(s) ...
|
||||||
|
true, // Detect Inside FVG POI(s) ...
|
||||||
|
true // Apply From Filter to Selected POI(s) ...
|
||||||
|
);
|
||||||
|
bool hasBearOBFVGs = IsValidSize(bearOBFVGsCount);
|
||||||
|
|
||||||
|
//
|
||||||
|
bool hasOrderBlow = hasBearOBFVGs ||
|
||||||
|
hasBullOBFVGs;
|
||||||
|
if (hasOrderBlow)
|
||||||
{
|
{
|
||||||
//
|
//
|
||||||
for (int i = 0; i < count; i++)
|
// Vlidate ...
|
||||||
|
bool isValid =
|
||||||
|
//
|
||||||
|
(hasBullOBFVGs &&
|
||||||
|
!hasBearOBFVGs &&
|
||||||
|
bullOBFVGsCount > 1)
|
||||||
|
//
|
||||||
|
||
|
||||||
|
//
|
||||||
|
(hasBearOBFVGs &&
|
||||||
|
!hasBullOBFVGs &&
|
||||||
|
bearOBFVGsCount > 1)
|
||||||
|
//
|
||||||
|
;
|
||||||
|
|
||||||
|
//
|
||||||
|
if (isValid)
|
||||||
{
|
{
|
||||||
//
|
//
|
||||||
XOBFVG iOBFVG = tmpOBFVGs[i];
|
if (hasBullOBFVGs)
|
||||||
iOBFVG.UpdateTo(NULL);
|
{
|
||||||
|
|
||||||
// //
|
|
||||||
// if (iOBFVG.HasOB())
|
|
||||||
// {
|
|
||||||
// //
|
|
||||||
// XCBaseObject *iObj;
|
|
||||||
// drawer.CreateOrderBlock(
|
|
||||||
// iOBFVG.ob,
|
|
||||||
// iObj //
|
|
||||||
// );
|
|
||||||
|
|
||||||
// //
|
|
||||||
// if (stfState.HasSupplyZones())
|
|
||||||
// {
|
|
||||||
// //
|
|
||||||
// for (int j = 0; j < stfState.CountSupplyZones(); j++)
|
|
||||||
// {
|
|
||||||
// //
|
|
||||||
// XCSupplyZone *jZone = stfState.supplyZones[j];
|
|
||||||
|
|
||||||
// //
|
|
||||||
// bool isInside = IsInsideDiff(
|
|
||||||
// jZone,
|
|
||||||
// iOBFVG.ob,
|
|
||||||
// false //
|
|
||||||
// );
|
|
||||||
|
|
||||||
// //
|
|
||||||
// if (isInside)
|
|
||||||
// {
|
|
||||||
// //
|
|
||||||
// XCSupplyZoneObject *iObj;
|
|
||||||
// drawer.CreateSupplyZone(
|
|
||||||
// jZone,
|
|
||||||
// iObj //
|
|
||||||
// );
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// //
|
|
||||||
// if (stfState.HasDemandZones())
|
|
||||||
// {
|
|
||||||
// //
|
|
||||||
// for (int j = 0; j < stfState.CountDemandZones(); j++)
|
|
||||||
// {
|
|
||||||
// //
|
|
||||||
// XCDemandZone *jZone = stfState.demandZones[j];
|
|
||||||
|
|
||||||
// //
|
|
||||||
// bool isInside = IsInsideDiff(
|
|
||||||
// jZone,
|
|
||||||
// iOBFVG.ob,
|
|
||||||
// false //
|
|
||||||
// );
|
|
||||||
|
|
||||||
// //
|
|
||||||
// if (isInside)
|
|
||||||
// {
|
|
||||||
// //
|
|
||||||
// XCDemandZoneObject *iObj;
|
|
||||||
// drawer.CreateDemandZone(
|
|
||||||
// jZone,
|
|
||||||
// iObj //
|
|
||||||
// );
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// //
|
|
||||||
// if (stfState.HasSupportZones())
|
|
||||||
// {
|
|
||||||
// //
|
|
||||||
// for (int j = 0; j < stfState.CountSupportZones(); j++)
|
|
||||||
// {
|
|
||||||
// //
|
|
||||||
// XCSupportZone *jZone = stfState.supportZones[j];
|
|
||||||
|
|
||||||
// //
|
|
||||||
// bool isInside = IsInsideDiff(
|
|
||||||
// jZone,
|
|
||||||
// iOBFVG.ob,
|
|
||||||
// false //
|
|
||||||
// );
|
|
||||||
|
|
||||||
// //
|
|
||||||
// if (isInside)
|
|
||||||
// {
|
|
||||||
// //
|
|
||||||
// XCSupportZoneObject *iObj;
|
|
||||||
// drawer.CreateSupportZone(
|
|
||||||
// jZone,
|
|
||||||
// iObj //
|
|
||||||
// );
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// //
|
|
||||||
// if (stfState.HasResistanceZones())
|
|
||||||
// {
|
|
||||||
// //
|
|
||||||
// for (int j = 0; j < stfState.CountResistanceZones(); j++)
|
|
||||||
// {
|
|
||||||
// //
|
|
||||||
// XCResistanceZone *jZone = stfState.resistanceZones[j];
|
|
||||||
|
|
||||||
// //
|
|
||||||
// bool isInside = IsInsideDiff(
|
|
||||||
// jZone,
|
|
||||||
// iOBFVG.ob,
|
|
||||||
// false //
|
|
||||||
// );
|
|
||||||
|
|
||||||
// //
|
|
||||||
// if (isInside)
|
|
||||||
// {
|
|
||||||
// //
|
|
||||||
// XCResistanceZoneObject *iObj;
|
|
||||||
// drawer.CreateResistanceZone(
|
|
||||||
// jZone,
|
|
||||||
// iObj //
|
|
||||||
// );
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
//
|
|
||||||
XCBaseObject *drawnObjects[];
|
|
||||||
int drawnObjectsCount = drawer.DrawOBFVG(
|
|
||||||
iOBFVG,
|
|
||||||
drawnObjects,
|
|
||||||
//
|
//
|
||||||
true, // Draw Order Block ...
|
Copy(
|
||||||
true, // Draw Fair Value Gap ...
|
bullOBFVGs,
|
||||||
false, // Draw Supply Zones ...
|
orderFlow //
|
||||||
false, // Draw Demand Zones ...
|
);
|
||||||
false, // Draw Support Zones ...
|
}
|
||||||
false // Draw Resistance Zones ...
|
else if (hasBearOBFVGs)
|
||||||
);
|
{
|
||||||
|
//
|
||||||
|
Copy(
|
||||||
|
bearOBFVGs,
|
||||||
|
orderFlow //
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
iOBFVG.Clean();
|
orderFlowDir =
|
||||||
|
hasBullOBFVGs
|
||||||
|
? X_DIRECTION_BULLISH
|
||||||
|
: X_DIRECTION_BEARISH;
|
||||||
|
|
||||||
|
//
|
||||||
|
result = ArraySize(orderFlow);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
has = IsValidSize(count);
|
Clean(bullOBFVGs);
|
||||||
result = count;
|
Clean(bearOBFVGs);
|
||||||
|
|
||||||
//
|
//
|
||||||
return result;
|
return result;
|
||||||
|
|||||||
Reference in New Issue
Block a user