Finish Order Blocks Detection ...

This commit is contained in:
2024-11-14 00:31:40 +03:30
parent a4fb541557
commit 849fc73ee2
4 changed files with 1048 additions and 95 deletions
+242
View File
@@ -223,6 +223,97 @@ class XCBarAnalyser : public XCBase
return result; return result;
} }
/**
* Detect Consolidation Range ...
*
* @param index: Integer, Start Bar Index ...
* @param range: Integer, Range of Bars ...
* @param maxRange: Consolidation Price Range in Points ...
* @param symbol: String, Symbol ...
* @param period: ENUM_TIMEFRAMES member, Period ...
*
* @return ( bool )
*/
bool IsConsolidating(
int index,
int range,
double maxRange,
string symbol = NULL,
ENUM_TIMEFRAMES period = NULL //
)
{
//
bool result = false;
//
if (index < 0)
{
index = 0;
}
//
if (range < 1)
{
range = 1;
}
//
if (maxRange < 1)
{
maxRange = 1;
}
//
// Normalize ...
symbol = NormalizeSymbol(symbol);
period = NormalizePeriod(period);
//
// Point Value ...
double point = GetPoints(symbol);
//
double high = iHigh(
symbol,
period,
index //
);
double low = iLow(
symbol,
period,
index //
);
//
// Detect Range High and Low ...
for (int i = 1; i < range; i++)
{
//
double iH = iHigh(
symbol,
period,
index + i //
);
//
double iL = iLow(
symbol,
period,
index + i //
);
//
high = MathMax(high, iH);
low = MathMin(low, iL);
}
//
result = (high - low) <= (maxRange * point);
//
return result;
}
// //
// Commons ... // Commons ...
@@ -909,6 +1000,157 @@ class XCBarAnalyser : public XCBase
return result; return result;
} }
//
// Order Blocks ...
/**
* Detect an Order Block Based on Given Bar ...
*
* @param bar: XOHCL instance, Specified Start Bar ...
* @param ob: XOHCL instance, Fill it if Order Block Found ...
* @param dir: ENUM_X_DIRECTION member, Specified Founded Order Block Direction ...
* @param sameBars: Integer, Specified Min Same Bars for Detecting Order Block ...
*
* @return ( bool )
*/
bool HasOrderBlock(
XOHCL &bar,
XOHCL &ob,
ENUM_X_DIRECTION &dir,
int sameBars = 3 //
)
{
//
bool result = false;
//
ob.Clean();
dir = X_DIRECTION_NONE;
//
if (sameBars < 1)
{
sameBars = 1;
}
//
result = bar.IsValid();
if (!result)
{
return result;
}
//
int index = bar.Index();
bool canContinue = true;
int sameBullishBarsFounded = 0;
int sameBearishBarsFounded = 0;
bool canContinueForBullish = true;
bool canContinueForBearish = true;
while (canContinue)
{
//
XOHCL iBar;
result = iBar.Init(
bar.symbol,
bar.period,
index //
);
if (!result)
{
break;
}
//
bool isBullish = iBar.IsBullish();
bool isBearish = iBar.IsBearish();
result = isBullish ||
isBearish;
if (!result)
{
break;
}
//
if (isBullish)
{
//
sameBullishBarsFounded++;
canContinueForBearish = false;
}
else
{
//
sameBearishBarsFounded++;
canContinueForBullish = false;
}
//
result = canContinueForBullish ||
canContinueForBearish;
if (!result)
{
break;
}
//
canContinueForBullish =
canContinueForBullish &&
sameBullishBarsFounded > 0;
//
canContinueForBearish =
canContinueForBearish &&
sameBearishBarsFounded > 0;
//
canContinue =
canContinueForBullish ||
canContinueForBearish;
if (canContinue)
{
index++;
}
}
//
bool hasBullishOB =
sameBullishBarsFounded >= sameBars;
//
bool hasBearishOB =
sameBearishBarsFounded >= sameBars;
//
result = hasBullishOB ||
hasBearishOB;
if (!result)
{
return result;
}
//
int obIndex = index;
result = ob.Init(
bar.symbol,
bar.period,
obIndex //
);
if (!result)
{
return result;
}
//
dir =
hasBullishOB
? X_DIRECTION_BULLISH
: X_DIRECTION_BEARISH;
//
return result;
}
// //
protected: protected:
// //
+137 -3
View File
@@ -1136,7 +1136,8 @@ class XCResistanceZoneObject : public XCZoneObject
// //
// Supply Zone ... // Supply Zone ...
class XCSupplyZoneObject : public XCZoneObject { class XCSupplyZoneObject : public XCZoneObject
{
// //
public: public:
// //
@@ -1200,7 +1201,8 @@ class XCSupplyZoneObject : public XCZoneObject {
// //
// Demand Zone ... // Demand Zone ...
class XCDemandZoneObject : public XCZoneObject { class XCDemandZoneObject : public XCZoneObject
{
// //
public: public:
// //
@@ -1258,7 +1260,139 @@ class XCDemandZoneObject : public XCZoneObject {
*/ */
virtual ENUM_XCHARTOBJECTS Type() virtual ENUM_XCHARTOBJECTS Type()
{ {
return X_SUPPLY_ZONE_OBJ; return X_DEMAND_ZONE_OBJ;
}
};
//
// Bullish Order Block ...
class XCBullishOrderBlockObject : public XCZoneObject
{
//
public:
//
/**
* Creator ...
*
* @param chart_id: Long, Specified Chart ID ...
* @param window: Integer, Specified Chart Window ID ...
* @param zone: XCOrderBlock instance ...
* @param prefix: String ...
*
* @return ( bool )
*/
bool Create(
long chart_id,
int window,
XCOrderBlock &zone,
string prefix = NULL //
)
{
//
bool result = false;
//
result = zone.IsValid() &&
zone.IsBullish();
if (!result)
{
return result;
}
//
string name = zone.GetTag();
//
result = CreateByZone(
chart_id,
name,
window,
zone,
prefix //
);
//
return result;
}
//
// Virtual ...
/**
* Retrieve Object Type ...
*
* @return ( ENUM_XCHARTOBJECTS )
*/
virtual ENUM_XCHARTOBJECTS Type()
{
return X_BULLISH_ORDERBLOCK_OBJ;
}
};
//
// Bearish Order Block ...
class XCBearishOrderBlockObject : public XCZoneObject
{
//
public:
//
/**
* Creator ...
*
* @param chart_id: Long, Specified Chart ID ...
* @param window: Integer, Specified Chart Window ID ...
* @param zone: XCOrderBlock instance ...
* @param prefix: String ...
*
* @return ( bool )
*/
bool Create(
long chart_id,
int window,
XCOrderBlock &zone,
string prefix = NULL //
)
{
//
bool result = false;
//
result = zone.IsValid() &&
zone.IsBearish();
if (!result)
{
return result;
}
//
string name = zone.GetTag();
//
result = CreateByZone(
chart_id,
name,
window,
zone,
prefix //
);
//
return result;
}
//
// Virtual ...
/**
* Retrieve Object Type ...
*
* @return ( ENUM_XCHARTOBJECTS )
*/
virtual ENUM_XCHARTOBJECTS Type()
{
return X_BULLISH_ORDERBLOCK_OBJ;
} }
}; };
+444
View File
@@ -377,6 +377,36 @@ class XCPOIDetector : public XCBaseAlert
mSupplyAndDemandRange = value; mSupplyAndDemandRange = value;
} }
//
// Order Blocks ...
/**
* Get Order Blocks Detection Bars ...
*
* @return ( int )
*/
int OrderBlocksSameBars()
{
return mOrderBlocksSameBars;
}
/**
* Set Order Blocks Detection Bars ...
*
* @param value: Argument 1
*/
void OrderBlocksSameBars(int value)
{
//
if (value < 0)
{
value = 0;
}
//
mOrderBlocksSameBars = value;
}
// //
// Actions ... // Actions ...
@@ -768,6 +798,68 @@ class XCPOIDetector : public XCBaseAlert
} }
} }
//
// Order Blocks ...
int obSameBars = OrderBlocksSameBars();
if (obSameBars > 0)
{
//
// Bullish Order Block ...
isDetected = DetectBullishOrderBlock(cBar);
if (isDetected)
{
//
ENUM_XPOI_EVENTS event = X_BULLISH_ORDERBLOCK_DETECTED;
XCOrderBlock *param;
bool hasItem = GetLastItem(
param,
mBullishOrderBlocks //
);
if (hasItem)
{
//
NotifyEventListeners(
event,
param //
);
}
//
Add(
event,
state //
);
}
//
// Bearish Order Block ...
isDetected = DetectBearishOrderBlock(cBar);
if (isDetected)
{
//
ENUM_XPOI_EVENTS event = X_BEARISH_ORDERBLOCK_DETECTED;
XCOrderBlock *param;
bool hasItem = GetLastItem(
param,
mBearishOrderBlocks //
);
if (hasItem)
{
//
NotifyEventListeners(
event,
param //
);
}
//
Add(
event,
state //
);
}
}
// //
ValidatePOIs(cBar); ValidatePOIs(cBar);
@@ -863,6 +955,10 @@ class XCPOIDetector : public XCBaseAlert
// //
Clean(mSupplyZones); Clean(mSupplyZones);
Clean(mDemandZones); Clean(mDemandZones);
//
Clean(mBullishOrderBlocks);
Clean(mBearishOrderBlocks);
} }
/** /**
@@ -911,6 +1007,9 @@ class XCPOIDetector : public XCBaseAlert
// //
SupplyAndDemandRange(144); SupplyAndDemandRange(144);
//
OrderBlocksSameBars(3);
} }
// //
@@ -983,6 +1082,10 @@ class XCPOIDetector : public XCBaseAlert
int supplyZonesCount = 0; int supplyZonesCount = 0;
int demandZonesCount = 0; int demandZonesCount = 0;
//
int bullishOrderBlocksCount = 0;
int bearishOrderBlocksCount = 0;
// //
bool canContinue = true; bool canContinue = true;
@@ -1067,6 +1170,28 @@ class XCPOIDetector : public XCBaseAlert
ArrayReverse(mDemandZones); ArrayReverse(mDemandZones);
} }
//
// Oder Blocks ...
int obSameBars = OrderBlocksSameBars();
if (obSameBars > 0)
{
//
// Bullish Order Blocks ...
bullishOrderBlocksCount = DetectRequiredBullishOrderBlocks(barIndex);
if (bullishOrderBlocksCount == requiredPOIs)
{
ArrayReverse(mBullishOrderBlocks);
}
//
// Bearish Order Blocks ...
bearishOrderBlocksCount = DetectRequiredBearishOrderBlocks(barIndex);
if (bearishOrderBlocksCount == requiredPOIs)
{
ArrayReverse(mBearishOrderBlocks);
}
}
// //
canContinue = canContinue =
// //
@@ -1118,6 +1243,16 @@ class XCPOIDetector : public XCBaseAlert
// Demand Zones ... // Demand Zones ...
demandZonesCount < requiredPOIs demandZonesCount < requiredPOIs
// //
||
//
// Bullish Order Blocks ...
bullishOrderBlocksCount < requiredPOIs
//
||
//
// Bearish Order Blocks ...
bearishOrderBlocksCount < requiredPOIs
//
; ;
if (canContinue) if (canContinue)
{ {
@@ -2986,12 +3121,321 @@ class XCPOIDetector : public XCBaseAlert
// //
// Order Blocks ... // Order Blocks ...
int mOrderBlocksSameBars; // Order Blocks Detection Bars ...
// //
// Bullish OB ... // Bullish OB ...
XCOrderBlock *mBullishOrderBlocks[];
/**
* Detect Bullish Order Block ...
*
* @param bar: XOHCL instance ...
*
* @return ( bool )
*/
bool DetectBullishOrderBlock(XOHCL &bar)
{
//
bool result = false;
//
result = bar.IsValid();
if (!result)
{
return result;
}
//
int sameBars = OrderBlocksSameBars();
if (sameBars < 0)
{
return result;
}
//
XOHCL obBar;
ENUM_X_DIRECTION dir;
result = mBarAnalyser
.HasOrderBlock(
bar,
obBar,
dir,
sameBars //
);
result =
result &&
dir == X_DIRECTION_BULLISH;
if (!result)
{
return result;
}
//
if (result)
{
//
XCOrderBlock *ob;
ob = new XCOrderBlock();
result = ob.Init(
obBar,
dir //
);
//
if (result)
{
//
datetime cTime = TimeCurrent();
ob.To(cTime);
//
Add(
ob,
mBullishOrderBlocks //
);
// //
// XCBullishOrderBlockObject *iObj;
// bool isCreated = mDrawer.CreateBullishOrderBlock(
// ob,
// iObj //
// );
// if (isCreated)
// {
// AddObjectIfNotExists(iObj);
// }
}
}
//
return result;
}
/**
* Detect Required Bullish Order Blocks ...
*
* @param barIndex: Integer Start bar index ...
* 0 is Default ...
*
* @return ( int )
*/
int DetectRequiredBullishOrderBlocks(int barIndex)
{
//
int result = 0;
//
if (barIndex < 0)
{
barIndex = 0;
}
//
int required = MaxNumberOfRequiredPOIs();
if (required <= 0)
{
return result;
}
//
int count = ArraySize(mBullishOrderBlocks);
if (count >= required)
{
//
result = count;
return result;
}
//
int sameBars = OrderBlocksSameBars();
if (sameBars < 0)
{
return result;
}
//
string symbol = GetSymbol();
ENUM_TIMEFRAMES period = GetPeriod();
//
XOHCL bar;
bool isInited = bar.Init(
symbol,
period,
barIndex //
);
if (!isInited)
{
return result;
}
//
DetectBullishOrderBlock(bar);
//
result = ArraySize(mBullishOrderBlocks);
//
return result;
}
// //
// Bearish OB ... // Bearish OB ...
XCOrderBlock *mBearishOrderBlocks[];
/**
* Detect Bearish Order Block ...
*
* @param bar: XOHCL instance ...
*
* @return ( bool )
*/
bool DetectBearishOrderBlock(XOHCL &bar)
{
//
bool result = false;
//
result = bar.IsValid();
if (!result)
{
return result;
}
//
int sameBars = OrderBlocksSameBars();
if (sameBars < 0)
{
return result;
}
//
XOHCL obBar;
ENUM_X_DIRECTION dir;
result = mBarAnalyser
.HasOrderBlock(
bar,
obBar,
dir,
sameBars //
);
result =
result &&
dir == X_DIRECTION_BEARISH;
if (!result)
{
return result;
}
//
if (result)
{
//
XCOrderBlock *ob;
ob = new XCOrderBlock();
result = ob.Init(
obBar,
dir //
);
//
if (result)
{
//
datetime cTime = TimeCurrent();
ob.To(cTime);
//
Add(
ob,
mBearishOrderBlocks //
);
// //
// XCBearishOrderBlockObject *iObj;
// bool isCreated = mDrawer.CreateBearishOrderBlock(
// ob,
// iObj //
// );
// if (isCreated)
// {
// AddObjectIfNotExists(iObj);
// }
}
}
//
return result;
}
/**
* Detect Required Bearish Order Blocks ...
*
* @param barIndex: Integer Start bar index ...
* 0 is Default ...
*
* @return ( int )
*/
int DetectRequiredBearishOrderBlocks(int barIndex)
{
//
int result = 0;
//
if (barIndex < 0)
{
barIndex = 0;
}
//
int required = MaxNumberOfRequiredPOIs();
if (required <= 0)
{
return result;
}
//
int count = ArraySize(mBearishOrderBlocks);
if (count >= required)
{
//
result = count;
return result;
}
//
int sameBars = OrderBlocksSameBars();
if (sameBars < 0)
{
return result;
}
//
string symbol = GetSymbol();
ENUM_TIMEFRAMES period = GetPeriod();
//
XOHCL bar;
bool isInited = bar.Init(
symbol,
period,
barIndex //
);
if (!isInited)
{
return result;
}
//
DetectBearishOrderBlock(bar);
//
result = ArraySize(mBearishOrderBlocks);
//
return result;
}
// //
// Fair Value Gaps ... // Fair Value Gaps ...
+225 -92
View File
@@ -1269,6 +1269,103 @@ class XCPOIDrawer : public XCBase
mBearishFVGStyle = value; mBearishFVGStyle = value;
} }
//
// Virtuals ...
/**
* Apply Default Configurations ...
*/
virtual void Default()
{
//
// Apply Default Props ...
//
Prefix(NULL);
ChartIdentification(0);
SubWindowIdentification(0);
//
SwingLowWidth(3);
SwingLowArrow(108);
SwingLowColor(clrAqua);
//
SwingHighWidth(3);
SwingHighArrow(108);
SwingHighColor(clrMagenta);
//
BullishMomentumBarWidth(3);
BullishMomentumBarArrow(225);
BullishMomentumBarColor(clrAqua);
//
BearishMomentumBarWidth(3);
BearishMomentumBarArrow(226);
BearishMomentumBarColor(clrMagenta);
//
BullishRejectionBarWidth(3);
BullishRejectionBarArrow(217);
BullishRejectionBarColor(clrAqua);
//
BearishRejectionBarWidth(3);
BearishRejectionBarArrow(218);
BearishRejectionBarColor(clrMagenta);
//
SupportZoneFill(false);
SupportZoneWidth(1);
SupportZoneStyle(STYLE_DOT);
SupportZoneColor(clrLime);
//
ResistanceZoneFill(false);
ResistanceZoneWidth(1);
ResistanceZoneStyle(STYLE_DOT);
ResistanceZoneColor(clrRed);
//
SupplyZoneFill(false);
SupplyZoneWidth(1);
SupplyZoneStyle(STYLE_DOT);
SupplyZoneColor(clrRed);
//
DemandZoneFill(false);
DemandZoneWidth(1);
DemandZoneStyle(STYLE_DOT);
DemandZoneColor(clrGreen);
//
BullishOrderBlockFill(false);
BullishOrderBlockWidth(1);
BullishOrderBlockStyle(STYLE_DASHDOT);
BullishOrderBlockColor(clrLime);
//
BearishOrderBlockFill(false);
BearishOrderBlockWidth(1);
BearishOrderBlockStyle(STYLE_DASHDOT);
BearishOrderBlockColor(clrRed);
//
BullishFVGFill(true);
BullishFVGWidth(1);
BullishFVGStyle(STYLE_DOT);
BullishFVGColor(clrLime);
//
BearishFVGFill(true);
BearishFVGWidth(1);
BearishFVGStyle(STYLE_DOT);
BearishFVGColor(clrRed);
//
}
// //
// Object Creators ... // Object Creators ...
@@ -1917,102 +2014,138 @@ class XCPOIDrawer : public XCBase
return result; return result;
} }
/**
* Create Bullish Order Block Object ...
*
* @param zone: XCOrderBlock instance ...
* @param object: XCBullishOrderBlockObject pointer ...
*
* @return ( bool )
*/
bool CreateBullishOrderBlock(
XCOrderBlock &zone,
XCBullishOrderBlockObject *&object //
)
{
//
bool result = false;
//
object = NULL;
//
result =
zone.IsValid() &&
zone.IsBullish();
if (!result)
{
return result;
}
//
string prefix = Prefix();
long chartID = ChartIdentification();
int window = SubWindowIdentification();
//
bool fill = BullishOrderBlockFill();
int width = BullishOrderBlockWidth();
color crl = BullishOrderBlockColor();
ENUM_LINE_STYLE style = BullishOrderBlockStyle();
//
object = new XCBullishOrderBlockObject();
result = object.Create(
chartID,
window,
zone,
prefix //
);
//
if (!result)
{
return result;
}
//
object.ZoneFill(fill);
object.ZoneColor(crl);
object.ZoneWidth(width);
object.ZoneStyle(style);
//
return result;
}
/**
* Create Bearish Order Block Object ...
*
* @param zone: XCOrderBlock instance ...
* @param object: XCBearishOrderBlockObject pointer ...
*
* @return ( bool )
*/
bool CreateBearishOrderBlock(
XCOrderBlock &zone,
XCBearishOrderBlockObject *&object //
)
{
//
bool result = false;
//
object = NULL;
//
result =
zone.IsValid() &&
zone.IsBearish();
if (!result)
{
return result;
}
//
string prefix = Prefix();
long chartID = ChartIdentification();
int window = SubWindowIdentification();
//
bool fill = BearishOrderBlockFill();
int width = BearishOrderBlockWidth();
color crl = BearishOrderBlockColor();
ENUM_LINE_STYLE style = BearishOrderBlockStyle();
//
object = new XCBearishOrderBlockObject();
result = object.Create(
chartID,
window,
zone,
prefix //
);
//
if (!result)
{
return result;
}
//
object.ZoneFill(fill);
object.ZoneColor(crl);
object.ZoneWidth(width);
object.ZoneStyle(style);
//
return result;
}
// //
protected: protected:
// //
//
void Default()
{
//
// Apply Default Props ...
//
Prefix(NULL);
ChartIdentification(0);
SubWindowIdentification(0);
//
SwingLowWidth(3);
SwingLowArrow(108);
SwingLowColor(clrAqua);
//
SwingHighWidth(3);
SwingHighArrow(108);
SwingHighColor(clrMagenta);
//
BullishMomentumBarWidth(3);
BullishMomentumBarArrow(225);
BullishMomentumBarColor(clrAqua);
//
BearishMomentumBarWidth(3);
BearishMomentumBarArrow(226);
BearishMomentumBarColor(clrMagenta);
//
BullishRejectionBarWidth(3);
BullishRejectionBarArrow(217);
BullishRejectionBarColor(clrAqua);
//
BearishRejectionBarWidth(3);
BearishRejectionBarArrow(218);
BearishRejectionBarColor(clrMagenta);
//
SupportZoneFill(false);
SupportZoneWidth(1);
SupportZoneStyle(STYLE_DOT);
SupportZoneColor(clrLime);
//
ResistanceZoneFill(false);
ResistanceZoneWidth(1);
ResistanceZoneStyle(STYLE_DOT);
ResistanceZoneColor(clrRed);
//
SupplyZoneFill(false);
SupplyZoneWidth(1);
SupplyZoneStyle(STYLE_DOT);
SupplyZoneColor(clrRed);
//
DemandZoneFill(false);
DemandZoneWidth(1);
DemandZoneStyle(STYLE_DOT);
DemandZoneColor(clrGreen);
//
BullishOrderBlockFill(true);
BullishOrderBlockWidth(1);
BullishOrderBlockStyle(STYLE_DOT);
BullishOrderBlockColor(clrLime);
//
BearishOrderBlockFill(true);
BearishOrderBlockWidth(1);
BearishOrderBlockStyle(STYLE_DOT);
BearishOrderBlockColor(clrRed);
//
BullishFVGFill(true);
BullishFVGWidth(1);
BullishFVGStyle(STYLE_DOT);
BullishFVGColor(clrLime);
//
BearishFVGFill(true);
BearishFVGWidth(1);
BearishFVGStyle(STYLE_DOT);
BearishFVGColor(clrRed);
//
}
// //
private: private:
// //