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
+388 -4
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 ...
//
@@ -2040,7 +2412,7 @@ class XCXCAEAPOIDetector : public XCBase
// Update Values ...
trendBullishPivot.value = GetMin(trendBullishPivot.values);
trendBullishPivot.reserve = GetMax(trendBullishPivot.values);
//
has =
trendBullishPivot.IsValid() &&
@@ -2151,7 +2523,7 @@ class XCXCAEAPOIDetector : public XCBase
// Update Values ...
trendBearishPivot.value = GetMax(trendBearishPivot.values);
trendBearishPivot.reserve = GetMin(trendBearishPivot.values);
//
has =
trendBearishPivot.IsValid() &&
@@ -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