This commit is contained in:
2026-08-14 07:49:18 +03:30
parent 9d23e2cba1
commit 4707856302
6 changed files with 3833 additions and 56 deletions
+156 -17
View File
@@ -57,8 +57,10 @@ class XCPivotDetector : public XCBase
//
// Constructor ...
XCPivotDetector(
XCAlert *_alert = NULL, //
int _maxAllowedProcessableZones = 10 //
XCAlert *_alert = NULL, // Alert instance Pointer ...
string _pivotPrefix = "XPivot", // Detected Zones Prefix ...
bool _supportInvertedZones = false, // Specified Support Inverted Zone or not ...
int _maxAllowedProcessableZones = 0 // Max Allowed Processable Zones ...
)
{
//
@@ -66,10 +68,12 @@ class XCPivotDetector : public XCBase
//
// Normalize ...
if (_maxAllowedProcessableZones <= 5)
if (_maxAllowedProcessableZones < 0)
{
_maxAllowedProcessableZones = 5;
_maxAllowedProcessableZones = 0;
}
mPivotPrefix = _pivotPrefix;
mSupportInvertedZones = _supportInvertedZones;
mMaxAllowedProcessableZones = _maxAllowedProcessableZones;
//
@@ -167,13 +171,13 @@ class XCPivotDetector : public XCBase
}
//
hasPeak = false;
hasVale = false;
hasPeak = true;
hasVale = true;
//
// Loop through Bars for Approved Side ...
int jStart = i + 1;
int jEnd = i + pivotApproved;
int jEnd = i + pivotApproved + 1;
for (int j = jStart; j < jEnd; j++)
{
//
@@ -182,8 +186,8 @@ class XCPivotDetector : public XCBase
jHigh = iHigh(iBar.symbol, iBar.period, j);
//
hasVale = iBar.low < jLow;
hasPeak = iBar.high > jHigh;
hasVale = hasVale && (iBar.low < jLow);
hasPeak = hasPeak && (iBar.high > jHigh);
has = hasVale || hasPeak;
if (!has)
{
@@ -204,7 +208,7 @@ class XCPivotDetector : public XCBase
//
// Loop through Barse for Approved Side ...
jStart = i - pivotApproved;
jEnd = i - 1;
jEnd = i;
for (int j = jStart; j < jEnd; j++)
{
//
@@ -251,7 +255,7 @@ class XCPivotDetector : public XCBase
tmpPrice = EMPTY_VALUE;
tmpZonePrice = EMPTY_VALUE;
jStart = i - pivotApproved;
jEnd = i + pivotApproved;
jEnd = i + pivotApproved + 1;
for (int j = jStart; j < jEnd; j++)
{
//
@@ -297,7 +301,7 @@ class XCPivotDetector : public XCBase
tmpPrice = EMPTY_VALUE;
tmpZonePrice = EMPTY_VALUE;
jStart = i - pivotApproved;
jEnd = i + pivotApproved;
jEnd = i + pivotApproved + 1;
for (int j = jStart; j < jEnd; j++)
{
//
@@ -341,6 +345,46 @@ class XCPivotDetector : public XCBase
}
// #endregion
}
bool HasPeaks()
{
return HasChild(peaks);
}
bool HasVales()
{
return HasChild(vales);
}
int GetYoungestPeak()
{
//
int result = -1;
//
if (HasPeaks())
{
result = GetYoungest(peaks);
}
//
return result;
}
int GetYoungestVale()
{
//
int result = -1;
//
if (HasVales())
{
result = GetYoungest(vales);
}
//
return result;
}
// #endregion
// #region Event Listener Registration ...
@@ -427,9 +471,6 @@ class XCPivotDetector : public XCBase
//
Clean(mOnPeakDetectedHandlers);
Clean(mOnValeDetectedHandlers);
//
mPivotPrefix = "XSDT";
}
/**
@@ -448,6 +489,13 @@ class XCPivotDetector : public XCBase
return;
}
//
// Validate Peak Box based on Price ...
if (!IsBoxValid(peakBox, 0, X_BOUNDARY_PRICE_UP_DOWN))
{
return;
}
//
// Update To ...
peakBox.to = TimeCurrent();
@@ -486,7 +534,7 @@ class XCPivotDetector : public XCBase
{
//
// Validate New Peak based on Youngest One ...
hasPeaks = peakBox.upper > peaks[idx].upper;
hasPeaks = peakBox.upper < peaks[idx].upper;
if (hasPeaks)
{
//
@@ -524,6 +572,13 @@ class XCPivotDetector : public XCBase
return;
}
//
// Validate Peak Box based on Price ...
if (!IsBoxValid(valeBox, 0, X_BOUNDARY_PRICE_UP_DOWN))
{
return;
}
//
// Update To ...
valeBox.to = TimeCurrent();
@@ -561,7 +616,7 @@ class XCPivotDetector : public XCBase
{
//
// Validate New Vale based on Youngest One ...
hasVales = valeBox.lower < vales[idx].lower;
hasVales = valeBox.lower > vales[idx].lower;
if (hasVales)
{
//
@@ -738,6 +793,7 @@ class XCPivotDetector : public XCBase
//
// Props ...
string mPivotPrefix; // Prefix ...
bool mSupportInvertedZones; // Support Inverted Zones ...
int mMaxAllowedProcessableZones; // Max Allowed Processable Zones ...
/**
@@ -826,6 +882,7 @@ class XCPivotDetector : public XCBase
//
Add(i, removeIDX);
NotifyPeakBreaked(peaks[i]);
HandleBreakedZone(peaks[i], cBar);
}
}
@@ -850,6 +907,7 @@ class XCPivotDetector : public XCBase
//
Add(i, removeIDX);
NotifyValeBreaked(vales[i]);
HandleBreakedZone(vales[i], cBar);
}
}
@@ -894,6 +952,87 @@ class XCPivotDetector : public XCBase
CleanupPeaks();
CleanupVales();
}
/**
* Handle Breaked Zones ...
*
* @param box: XBoxZone instance ...
* @param bar: XOHCL instance ...
*/
void HandleBreakedZone(
XBoxZone &box,
XOHCL &bar //
)
{
//
// Validate ...
if (!box.IsValid() ||
!mSupportInvertedZones //
)
{
return;
}
//
XBoxZone inverted;
int maxAllowedInversion = 1;
int count = ArraySize(box.breaks);
bool has = count < maxAllowedInversion;
if (!has)
{
return;
}
//
// Invert to Peak ...
if (box.IsBullish())
{
//
// Initialize Inverted Box ...
has = inverted.Init(
box.symbol,
box.period,
box.upper,
box.lower,
bar.time, // From ...
TimeCurrent(), // To ...
X_DIRECTION_BEARISH,
"i" + mPivotPrefix // Type ...
);
if (has)
{
//
Add(bar.time, inverted.breaks);
AddRef(inverted, peaks);
}
}
//
// Invert to Vale ...
else if (box.IsBearish())
{
//
// Initialize Inverted Box ...
has = inverted.Init(
box.symbol,
box.period,
box.upper,
box.lower,
bar.time, // From ...
TimeCurrent(), // To ...
X_DIRECTION_BULLISH,
"i" + mPivotPrefix // Type ...
);
if (has)
{
//
Add(bar.time, inverted.breaks);
AddRef(inverted, vales);
}
}
//
inverted.Clean();
}
};
//