This commit is contained in:
2025-04-27 02:16:59 +03:30
parent a34ca8272a
commit 86846de1d1
4 changed files with 1795 additions and 614 deletions
+386 -2
View File
@@ -33,6 +33,8 @@
enum ENUM_XCA_PIVOTS
{
XCA_NONE, // None
XCA_TICK, // Tick
XCA_VOLUME, // Volume
XCA_FVG_BULL, // FVGBull
XCA_FVG_BEAR, // FVGBear
XCA_RSI_COOS, // RSICOOS
@@ -121,6 +123,8 @@ string GetBoxType(ENUM_XCA_PIVOTS value)
switch (value)
{
//
case XCA_TICK:
case XCA_VOLUME:
case XCA_RSI_COOS:
case XCA_RSI_VALE:
case XCA_CCI_COOS:
@@ -150,6 +154,163 @@ string GetBoxType(ENUM_XCA_PIVOTS value)
return result;
}
//
ENUM_XCA_PIVOTS GetPivotType(XBoxZone &value)
{
//
ENUM_XCA_PIVOTS result = XCA_NONE;
//
bool has = value.IsValid();
if (!has)
{
return result;
}
//
bool isTick = value.type == GetBoxType(XCA_TICK);
bool isVolume = value.type == GetBoxType(XCA_VOLUME);
bool isFVGBull = value.type == GetBoxType(XCA_FVG_BULL) &&
value.dir == GetDirection(XCA_FVG_BULL);
bool isFVGBear = value.type == GetBoxType(XCA_FVG_BEAR) &&
value.dir == GetDirection(XCA_FVG_BEAR);
bool isRSIPeak = value.type == GetBoxType(XCA_RSI_PEAK) &&
value.dir == GetDirection(XCA_RSI_PEAK);
bool isRSIVale = value.type == GetBoxType(XCA_RSI_VALE) &&
value.dir == GetDirection(XCA_RSI_VALE);
bool isCCIPeak = value.type == GetBoxType(XCA_CCI_PEAK) &&
value.dir == GetDirection(XCA_CCI_PEAK);
bool isCCIVale = value.type == GetBoxType(XCA_CCI_VALE) &&
value.dir == GetDirection(XCA_CCI_VALE);
bool isRSICrossedOverOS = value.type == GetBoxType(XCA_RSI_COOS) &&
value.dir == GetDirection(XCA_RSI_COOS);
bool isRSICrossedUnderOB = value.type == GetBoxType(XCA_RSI_CUOB) &&
value.dir == GetDirection(XCA_RSI_CUOB);
bool isCCICrossedOverOS = value.type == GetBoxType(XCA_CCI_COOS) &&
value.dir == GetDirection(XCA_CCI_COOS);
bool isCCICrossedUnderOB = value.type == GetBoxType(XCA_CCI_CUOB) &&
value.dir == GetDirection(XCA_CCI_CUOB);
bool isTrendBullish = value.type == GetBoxType(XCA_TREND_BULL) &&
value.dir == GetDirection(XCA_TREND_BULL);
bool isTrendBearish = value.type == GetBoxType(XCA_TREND_BEAR) &&
value.dir == GetDirection(XCA_TREND_BEAR);
//
if (isTick)
{
result = XCA_TICK;
}
else if (isVolume)
{
result = XCA_VOLUME;
}
else if (isFVGBull)
{
result = XCA_FVG_BULL;
}
else if (isFVGBear)
{
result = XCA_FVG_BEAR;
}
else if (isRSIPeak)
{
result = XCA_RSI_PEAK;
}
else if (isRSIVale)
{
result = XCA_RSI_VALE;
}
else if (isCCIPeak)
{
result = XCA_CCI_PEAK;
}
else if (isCCIVale)
{
result = XCA_CCI_VALE;
}
else if (isRSICrossedOverOS)
{
result = XCA_RSI_COOS;
}
else if (isRSICrossedUnderOB)
{
result = XCA_RSI_CUOB;
}
else if (isCCICrossedOverOS)
{
result = XCA_CCI_COOS;
}
else if (isCCICrossedUnderOB)
{
result = XCA_CCI_CUOB;
}
else if (isTrendBullish)
{
result = XCA_TREND_BULL;
}
else if (isTrendBearish)
{
result = XCA_TREND_BEAR;
}
//
return result;
}
//
int ExtractPivots(
XBoxZone &extracted[],
ENUM_XCA_PIVOTS type,
XBoxZone &source[] //
)
{
//
int result = 0;
//
Clean(extracted);
//
bool has =
IsValid(type) &&
HasChild(source);
if (!has)
{
return result;
}
//
int count = ArraySize(source);
for (int i = 0; i < count; i++)
{
//
XBoxZone iBox = source[i];
//
ENUM_XCA_PIVOTS iType = GetPivotType(iBox);
//
has = iType == type;
if (has)
{
//
AddRef(
iBox,
extracted //
);
}
//
iBox.Clean();
}
//
result = ArraySize(extracted);
//
return result;
}
//
struct XCAPivot
{
@@ -580,6 +741,217 @@ struct XCATRENDFVG
//
};
//
int ExtractTrendFVGs(
XBoxZone &extracteds[],
XBoxZone &trend,
XBoxZone &fvgs[] //
)
{
//
int result = 0;
//
Clean(extracteds);
//
bool has = HasChild(fvgs) &&
trend.IsValid();
if (!has)
{
return result;
}
//
// Check Trend Box Pivot is Valid Trend ...
ENUM_XCA_PIVOTS iType = GetPivotType(trend);
has = iType == XCA_TREND_BULL ||
iType == XCA_TREND_BEAR;
if (!has)
{
return result;
}
//
int count = ArraySize(fvgs);
for (int i = 0; i < count; i++)
{
//
XBoxZone iFVG = fvgs[i];
//
bool isDirPassed = iFVG.dir == trend.dir;
bool isPricePassed = iFVG.upper <= trend.upper &&
iFVG.lower >= trend.lower;
bool isFromPassed = iFVG.from > trend.from;
has =
isDirPassed &&
isFromPassed &&
isPricePassed;
if (has)
{
//
AddRef(
iFVG,
extracteds //
);
}
//
iFVG.Clean();
}
//
result = ArraySize(extracteds);
//
return result;
}
//
int ExtractTrendPivots(
XCATRENDFVG &items[],
XBoxZone &boxes[] //
)
{
//
int result = 0;
//
Clean(items);
//
bool has = HasChild(boxes);
if (!has)
{
return result;
}
//
// Extract Trend Boxes ...
XBoxZone tmp[];
XBoxZone trendBoxes[];
ExtractPivots(
tmp,
XCA_TREND_BULL,
boxes //
);
Copy(
tmp,
trendBoxes,
false //
);
Clean(tmp);
ExtractPivots(
tmp,
XCA_TREND_BEAR,
boxes //
);
Copy(
tmp,
trendBoxes,
false //
);
Clean(tmp);
//
// Check Trend Boxes Exists ...
has = HasChild(trendBoxes);
if (!has)
{
//
Clean(trendBoxes);
return result;
}
//
// Extract FVG Boxes ...
XBoxZone fvgBoxes[];
//
ExtractPivots(
tmp,
XCA_FVG_BULL,
boxes //
);
Copy(
tmp,
fvgBoxes,
false //
);
Clean(tmp);
ExtractPivots(
tmp,
XCA_FVG_BEAR,
boxes //
);
Copy(
tmp,
fvgBoxes,
false //
);
Clean(tmp);
bool hasFVGs = HasChild(fvgBoxes);
int fvgsCount = ArraySize(fvgBoxes);
//
// Loop through Trend Boxes to Extract XCATRENDFVG Models ...
int count = ArraySize(trendBoxes);
for (int i = 0; i < count; i++)
{
//
XBoxZone iTrendBox = trendBoxes[i];
//
XCATRENDFVG iTrendFVG;
iTrendFVG.trend = iTrendBox;
//
XBoxZone fvgs[];
if (hasFVGs)
{
//
int fvgsCount = ExtractTrendFVGs(
fvgs,
iTrendBox,
fvgBoxes //
);
//
Copy(
fvgs,
iTrendFVG.fvgs //
);
}
//
has = iTrendFVG.IsValid();
if (has)
{
//
AddRef(
iTrendFVG,
items //
);
}
//
iTrendBox.Clean();
iTrendFVG.Clean();
}
//
Clean(tmp);
Clean(fvgBoxes);
Clean(trendBoxes);
//
result = ArraySize(items);
//
return result;
}
//
int GetOldest(XCATRENDFVG &items[])
{
@@ -1382,7 +1754,7 @@ class XCXCAEAPOIDetector : public XCBase
iBox.upper = iZone.high;
iBox.symbol = iZone.symbol;
iBox.period = iZone.period;
iBox.type = "XCA_MAX_TICK";
iBox.type = GetBoxType(XCA_TICK);
iBox.dir = X_DIRECTION_BULLISH; // Temparory ...
//
@@ -1425,7 +1797,7 @@ class XCXCAEAPOIDetector : public XCBase
iBox.upper = iZone.high;
iBox.symbol = iZone.symbol;
iBox.period = iZone.period;
iBox.type = "XCA_MAX_VOLUME";
iBox.type = GetBoxType(XCA_VOLUME);
iBox.dir = X_DIRECTION_BULLISH; // Temparory ...
//
@@ -2877,6 +3249,12 @@ class XCXCAEAPOIDetector : public XCBase
count = CountTrendBullishPivots();
for (int i = 0; i < count; i++)
{
//
AddRef(
trendBullishPivots[i].trend,
pivots //
);
//
XBoxZone iBox;
has = trendBullishPivots[i].GetSelectedFVG(iBox);
@@ -2949,6 +3327,12 @@ class XCXCAEAPOIDetector : public XCBase
count = CountTrendBearishPivots();
for (int i = 0; i < count; i++)
{
//
AddRef(
trendBearishPivots[i].trend,
pivots //
);
//
XBoxZone iBox;
has = trendBearishPivots[i].GetSelectedFVG(iBox);
File diff suppressed because it is too large Load Diff
+126
View File
@@ -26,6 +26,7 @@
#include "../../Libraries/x-saherelm.x-poi.lib.mq5"
#include "../../Libraries/x-saherelm.x-trade.lib.mq5"
#include "../Classes/xcaea.x-poi.detector.class.mq5"
#include "../Classes/xcaea.x-poi.drawer.class.mq5"
#include "../Helpers/xcaea.helper.mq5"
//
@@ -421,6 +422,7 @@ int AddGuard(
//
bool DetectXCAEAConditions(
XCXCAEAPOIDrawer *drawer,
ENUM_X_DIRECTION trend,
XBoxZone &pivots[],
XCAEAConditions &conditions,
@@ -761,6 +763,23 @@ bool DetectXCAEAConditions(
//
// Parsing Pivots ...
//
// Select Inside Boxes ...
XBoxZone insidePivots[];
int insidePivotsCount = SelectInsideBoxes(
insidePivots,
pivots,
zBar,
cBar,
pBar,
p2Bar //
);
bool hasInsidePivots = IsValidSize(insidePivotsCount);
if (hasInsidePivots) {
//
drawer.DrawBoxes(insidePivots, TimeCurrent());
}
//
// Detect Selected Pivot ...
XBoxZone rejectedPivot;
@@ -986,6 +1005,113 @@ bool DetectXCAEAConditions(
return result;
}
//
// Select Inside Boxes ...
int SelectInsideBoxes(
XBoxZone &insideBoxes[],
XBoxZone &boxes[],
XOHCL &zBar,
XOHCL &cBar,
XOHCL &pBar,
XOHCL &p2Bar //
)
{
//
int result = 0;
//
Clean(insideBoxes);
//
bool has =
zBar.IsValid() &&
cBar.IsValid() &&
pBar.IsValid() &&
p2Bar.IsValid() &&
HasChild(boxes);
if (!has)
{
return result;
}
//
int count = ArraySize(boxes);
for (int i = 0; i < count; i++)
{
//
XBoxZone iBox = boxes[i];
//
// Check Box Type ...
bool isTypePassed =
//
iBox.type == GetBoxType(XCA_TREND_BULL) ||
iBox.type == GetBoxType(XCA_TREND_BEAR)
//
;
if (!isTypePassed)
{
//
iBox.Clean();
//
continue;
}
//
bool isBullish = iBox.IsBullish();
bool isBearish = iBox.IsBearish();
//
// Check Inside Conditions ...
//
bool isBullishInside =
//
isBullish &&
//
((cBar.low < iBox.upper &&
cBar.low > iBox.lower) ||
(cBar.GetDown() < iBox.upper &&
cBar.GetDown() > iBox.lower))
//
;
//
bool isBearishInside =
//
isBearish &&
//
((cBar.high > iBox.lower &&
cBar.high < iBox.upper) ||
(cBar.GetUp() > iBox.lower &&
cBar.GetUp() < iBox.upper))
//
;
//
has = isBullishInside ||
isBearishInside;
if (has)
{
//
AddRef(
iBox,
insideBoxes //
);
}
//
iBox.Clean();
}
//
result = ArraySize(insideBoxes);
//
return result;
}
//
bool SelectRejectedBox(
XBoxZone &box,
+2 -1
View File
@@ -206,7 +206,7 @@ class XCXCAEASignaller : XCBase
//
// Draw Founded Pivots ...
drawer.Draw(cTime);
// drawer.Draw(cTime);
//
// Retrieve Valid Pviots ...
@@ -259,6 +259,7 @@ class XCXCAEASignaller : XCBase
//
// Detect Sinal Box ...
hasSignalBox = DetectXCAEAConditions(
drawer,
trend,
pivots,
conditions,