This commit is contained in:
2025-10-05 13:47:57 +03:30
parent 8298759c8d
commit 03d215c9fa
2 changed files with 617 additions and 29 deletions
+552 -14
View File
@@ -1525,10 +1525,24 @@ class XCXFIMAHelper : public XCBaseHelper
return result; return result;
} }
/**
* Retrieve Fast, Slow, MA Bond Upper/Lower, HK Bond Upper/Lower and PB Bond Upper/Lower Min/Max ...
*
* @param min: double, minimum value ...
* @param max: double, maximum value ...
* @param barIndex: int, Specified Bar Index ...
*
* @return ( bool )
*/
bool GetBoundaryValues( bool GetBoundaryValues(
double &min, double &min,
double &max, double &max,
int barIndex = 0 // int barIndex = 0,
bool containsFastSlow = true,
bool containsMABond = true,
bool containsHKBound = true,
bool containsPBBond = true,
bool containsFiboLevels = false //
) )
{ {
// //
@@ -1591,19 +1605,57 @@ class XCXFIMAHelper : public XCBaseHelper
} }
// //
double values[11] = { double values[];
fast,
slow, //
fiboLower, if (containsFastSlow)
fiboUpper, {
fiboMiddle, //
maBondUpper, Add(fast, values);
maBondLower, Add(slow, values);
pbBondUpper, }
pbBondLower,
hkBondUpper, //
hkBondLower // if (containsMABond)
}; {
//
Add(maBondUpper, values);
Add(maBondLower, values);
}
//
if (containsHKBound)
{
//
Add(hkBondUpper, values);
Add(hkBondLower, values);
}
//
if (containsPBBond)
{
//
Add(pbBondUpper, values);
Add(pbBondLower, values);
}
//
if (containsFiboLevels)
{
//
Add(fiboLower, values);
Add(fiboUpper, values);
Add(fiboMiddle, values);
}
//
result = HasChild(values);
if (!result)
{
return result;
}
//
min = GetMin(values); min = GetMin(values);
max = GetMax(values); max = GetMax(values);
@@ -3841,6 +3893,492 @@ class XCXFIMAHelper : public XCBaseHelper
return result; return result;
} }
/**
* Detect XFIMA Based POI Bars ...
*
* @param bars: XOHCL, reference collection to holds detected bars ...
* @param dirs: ENUM_X_DIRECTION, reference collection to holds detected bars Direction ...
* @param barIndex: int, Specified Bar Index ...
* @param forDir: ENUM_X_DIRECTION, specified which Direction of potential bars looking for ...
* @param requiredNumberOfBars: int, Specified how many bars looking for ...
* @param maxAllowedLoopbackLength: int, Specified Max Allowed Looping back trhough Bars for Detection ...
* @return ( int )
*/
int DetectXFIMAPOIBars(
XOHCL &bars[],
ENUM_X_DIRECTION &dirs[],
int barIndex = 0,
ENUM_X_DIRECTION forDir = X_DIRECTION_NONE,
int requiredNumberOfBars = 300,
int maxAllowedLoopbackLength = 1500 //
)
{
//
int result = 0;
//
// Prepare ...
XClean(bars);
XClean(dirs);
//
// Normalize ...
barIndex = NormalizeBarIndex(barIndex);
requiredNumberOfBars = NormalizeInt(requiredNumberOfBars, 5);
maxAllowedLoopbackLength = NormalizeInt(maxAllowedLoopbackLength, 50);
//
// Validate ...
bool has = IsValid();
if (!has)
{
return result;
}
//
XOHCL iBar;
int idx = barIndex - 1;
int start = barIndex;
bool isBullish = false;
bool isBearish = false;
double iMin = EMPTY_VALUE;
double iMax = EMPTY_VALUE;
ENUM_X_DIRECTION iDir = X_DIRECTION_NONE;
int end = start + maxAllowedLoopbackLength;
while (ArraySize(bars) < requiredNumberOfBars ||
idx < maxAllowedLoopbackLength)
{
//
idx++;
has = iBar.Init(
mSymbol,
mPeriod,
idx //
);
if (!has)
{
continue;
}
//
has = GetBoundaryValues(
iMin,
iMax,
idx //
);
if (!has)
{
continue;
}
//
isBullish = iBar.low < iMin;
isBearish = iBar.high > iMax;
has =
!HasDirection(forDir)
? ((isBullish && !isBearish) ||
(isBearish && !isBullish))
: IsXBullish(forDir)
? (isBullish && !isBearish)
: (isBearish && !isBullish);
if (has)
{
//
iDir = isBullish
? X_DIRECTION_BULLISH
: X_DIRECTION_BEARISH;
//
AddRef(
iBar,
bars //
);
//
Add(
iDir,
dirs //
);
}
}
//
result = ArraySize(bars);
//
// Cleanup Resources ...
iBar.Clean();
//
return result;
}
int DetectXFIMAReversalPOIBars(
XOHCL &bars[],
ENUM_X_DIRECTION &dirs[],
int barIndex = 0,
bool forceTouchBoundary = false,
ENUM_X_DIRECTION forDir = X_DIRECTION_NONE,
int requiredNumberOfBars = 300,
int maxAllowedLoopbackLength = 1500 //
)
{
//
int result = 0;
//
// Prepare ...
XClean(bars);
XClean(dirs);
//
// Normalize ...
barIndex = NormalizeBarIndex(barIndex);
requiredNumberOfBars = NormalizeInt(requiredNumberOfBars, 5);
maxAllowedLoopbackLength = NormalizeInt(maxAllowedLoopbackLength, 50);
//
// Validate ...
bool has = IsValid();
if (!has)
{
return result;
}
//
// Detect POI Bars ...
XOHCL decisionBars[];
ENUM_X_DIRECTION decisionBarDirs[];
int decisionBarsCount = DetectXFIMAPOIBars(
decisionBars,
decisionBarDirs,
barIndex,
forDir,
requiredNumberOfBars,
maxAllowedLoopbackLength //
);
has = IsValidSize(decisionBarsCount);
if (!has)
{
//
XClean(decisionBars);
XClean(decisionBarDirs);
//
return result;
}
//
bool isBullish = false;
bool isBearish = false;
double iMin = EMPTY_VALUE;
double iMax = EMPTY_VALUE;
ENUM_X_DIRECTION iDir = X_DIRECTION_NONE;
for (int i = 0; i < decisionBarsCount; i++)
{
//
// Read Boundary Values ...
has = GetBoundaryValues(iMin, iMax, i);
if (!has)
{
continue;
}
//
// Check Bar Decision Direction ...
isBullish = IsXBullish(decisionBarDirs[i]);
isBearish = IsXBearish(decisionBarDirs[i]);
//
// Validate ...
//
isBullish =
isBullish &&
decisionBars[i].IsBullish();
//
isBearish =
isBearish &&
decisionBars[i].IsBearish();
//
if (forceTouchBoundary)
{
//
isBullish =
isBullish &&
(decisionBars[i].high > iMin ||
decisionBars[i].GetUp() > iMin);
//
isBearish =
isBearish &&
(decisionBars[i].low < iMax ||
decisionBars[i].GetDown() < iMax);
}
//
has = (isBullish && !isBearish) ||
(isBearish && !isBullish);
if (!has)
{
continue;
}
//
iDir =
isBullish
? X_DIRECTION_BULLISH
: X_DIRECTION_BEARISH;
//
// Validate For Dir ...
has = !HasDirection(forDir)
? HasDirection(iDir)
: iDir == forDir;
if (has)
{
//
AddRef(
decisionBars[i],
bars //
);
//
Add(
iDir,
dirs //
);
}
}
//
result = ArraySize(bars);
//
// Cleanup Resources ...
XClean(decisionBars);
XClean(decisionBarDirs);
//
return result;
}
int DetectXFIMAContinuationalPOIBars(
XOHCL &bars[],
ENUM_X_DIRECTION &dirs[],
int barIndex = 0,
bool forceTouchBoundary = false,
ENUM_X_DIRECTION forDir = X_DIRECTION_NONE,
int requiredNumberOfBars = 300,
int maxAllowedLoopbackLength = 1500 //
)
{
//
int result = 0;
//
// Prepare ...
XClean(bars);
XClean(dirs);
//
// Normalize ...
barIndex = NormalizeBarIndex(barIndex);
requiredNumberOfBars = NormalizeInt(requiredNumberOfBars, 5);
maxAllowedLoopbackLength = NormalizeInt(maxAllowedLoopbackLength, 50);
//
// Validate ...
bool has = IsValid();
if (!has)
{
return result;
}
//
// Detect POI Bars ...
XOHCL decisionBars[];
ENUM_X_DIRECTION decisionBarDirs[];
int decisionBarsCount = DetectXFIMAPOIBars(
decisionBars,
decisionBarDirs,
barIndex,
forDir,
requiredNumberOfBars,
maxAllowedLoopbackLength //
);
has = IsValidSize(decisionBarsCount);
if (!has)
{
//
XClean(decisionBars);
XClean(decisionBarDirs);
//
return result;
}
//
bool isBullish = false;
bool isBearish = false;
double iMin = EMPTY_VALUE;
double iMax = EMPTY_VALUE;
ENUM_X_DIRECTION iDir = X_DIRECTION_NONE;
for (int i = 0; i < decisionBarsCount; i++)
{
//
// Read Boundary Values ...
has = GetBoundaryValues(iMin, iMax, i);
if (!has)
{
continue;
}
//
// Validate ...
//
isBullish =
decisionBars[i].high > iMax &&
IsXBearish(decisionBarDirs[i]);
// &&
// decisionBars[i].IsBullish();
//
isBearish =
decisionBars[i].low < iMin &&
IsXBullish(decisionBarDirs[i]);
// &&
// decisionBars[i].IsBearish();
//
// Check Direction ...
has =
isBullish ||
!isBearish;
// has = (isBullish && !isBearish) ||
// (isBearish && !isBullish);
if (!has)
{
continue;
}
//
iDir = isBullish
? X_DIRECTION_BULLISH
: X_DIRECTION_BEARISH;
//
// Validate For Dir ...
has = !HasDirection(forDir)
? HasDirection(iDir)
: iDir == forDir;
if (has)
{
//
AddRef(
decisionBars[i],
bars //
);
//
Add(
iDir,
dirs //
);
}
// //
// isBullish =
// (decisionBars[i].low > iMax ||
// decisionBars[i].GetDown() > iMax) &&
// IsXBearish(decisionBarDirs[i]) &&
// decisionBars[i].IsBullish();
// //
// isBearish =
// (decisionBars[i].high < iMin ||
// decisionBars[i].GetUp() < iMin) &&
// IsXBullish(decisionBarDirs[i]) &&
// decisionBars[i].IsBearish();
// //
// if (forceTouchBoundary)
// {
// //
// isBullish =
// isBullish &&
// decisionBars[i].low < iMax &&
// decisionBars[i].GetUp() > iMax;
// //
// isBearish =
// isBearish &&
// decisionBars[i].high > iMin &&
// decisionBars[i].GetDown() < iMin;
// }
// //
// has = (isBullish && !isBearish) ||
// (isBearish && !isBullish);
// if (!has)
// {
// continue;
// }
// //
// iDir =
// isBullish
// ? X_DIRECTION_BULLISH
// : X_DIRECTION_BEARISH;
// //
// // Validate For Dir ...
// has = !HasDirection(forDir)
// ? HasDirection(iDir)
// : iDir == forDir;
// if (has)
// {
// //
// AddRef(
// decisionBars[i],
// bars //
// );
// //
// Add(
// iDir,
// dirs //
// );
// }
//
AddRef(
decisionBars[i],
bars //
);
//
Add(
decisionBarDirs[i],
dirs //
);
}
//
result = ArraySize(bars);
//
// Cleanup Resources ...
XClean(decisionBars);
XClean(decisionBarDirs);
//
return result;
}
// //
// Values Retrievers ... // Values Retrievers ...
@@ -450,6 +450,7 @@ class XCXFIMAStrategy1Signaller : public XCXFIMABaseSignaller
public: public:
// //
// Props ... // Props ...
CArrayObj barObjects;
CArrayObj zoneObjects; CArrayObj zoneObjects;
CArrayObj pivotObjects; CArrayObj pivotObjects;
XFIMAPatternDetectorConfig analyserConfig; XFIMAPatternDetectorConfig analyserConfig;
@@ -670,14 +671,14 @@ class XCXFIMAStrategy1Signaller : public XCXFIMABaseSignaller
// ); // );
// //
XPivot fimaPivots[]; // XPivot fimaPivots[];
int fimaPivotsCount = fimaHelper.DetecteXFIMAPivots( // int fimaPivotsCount = fimaHelper.DetecteXFIMAPivots(
fimaPivots, // fimaPivots,
iBar.Index(), // iBar.Index(),
50, // Number of Pivots ... // 50, // Number of Pivots ...
7, // Validation Length ... // 7, // Validation Length ...
500 // Loopback ... // 500 // Loopback ...
); // );
// // // //
// has = IsValidSize(fimaZonesCount); // has = IsValidSize(fimaZonesCount);
@@ -702,22 +703,71 @@ class XCXFIMAStrategy1Signaller : public XCXFIMABaseSignaller
// } // }
// } // }
// //
// has = IsValidSize(fimaPivotsCount);
// if (has)
// {
// //
// // Draw Detected Pivots ...
// for (int i = 0; i < fimaPivotsCount; i++)
// {
// //
// XCBarArrowObject *iObj;
// has = poiDrawer.DrawPivot(
// fimaPivots[i],
// iObj);
// if (has)
// {
// pivotObjects.Add(iObj);
// }
// }
// }
// //
has = IsValidSize(fimaPivotsCount); // Detect DecisionBars ...
XOHCL decisionBars[];
ENUM_X_DIRECTION decisionBarDirs[];
int decisionBarsCount = fimaHelper.DetectXFIMAContinuationalPOIBars(
decisionBars,
decisionBarDirs,
iBar.Index(),
true,
X_DIRECTION_ALL, // For Dir ...
300 // Required Number of Bars ...
);
// int decisionBarsCount = fimaHelper.DetectXFIMAPOIBars(
// decisionBars,
// decisionBarDirs,
// iBar.Index(),
// true,
// X_DIRECTION_ALL, // For Dir ...
// 300 // Required Number of Bars ...
// );
//
has = IsValidSize(decisionBarsCount);
if (has) if (has)
{ {
// //
// Draw Detected Pivots ... for (int i = 0; i < decisionBarsCount; i++)
for (int i = 0; i < fimaPivotsCount; i++)
{ {
// //
XCBarArrowObject *iObj; XCBarArrowObject *iObj;
has = poiDrawer.DrawPivot( has = poiDrawer.DrawBarArrow(
fimaPivots[i], decisionBars[i],
iObj); iObj,
IsXBullish(decisionBarDirs[i]) ? X_PRICE_LOW : X_PRICE_HIGH,
159,
IsXBullish(decisionBarDirs[i]) ? clrYellow : clrDarkOrange,
5,
IsXBullish(decisionBarDirs[i]) ? ANCHOR_BOTTOM : ANCHOR_TOP,
"XOHCL_" + ToXString(TimeToSeconds(decisionBars[i].time)),
true, // Ignore Bar Tag ...
5 // Threshold ...
);
if (has) if (has)
{ {
pivotObjects.Add(iObj); barObjects.Add(iObj);
} }
} }
} }