This commit is contained in:
2026-01-04 16:00:35 +03:30
parent 3c26c9c418
commit 9fc8892c5d
5 changed files with 1181 additions and 278 deletions
@@ -1123,6 +1123,71 @@ class XCX121XKIPOIDetector : public XCMarketPatternDetector
// #endregion
// #region XDetectors ...
bool IsKIPOI(
ENUM_X_DIRECTION &dir,
int barIndex = 0 //
)
{
//
bool result = false;
//
dir = X_DIRECTION_NONE;
//
bool isBullish = IsKIBullishPOI(barIndex);
bool isBearish = IsKIBearishPOI(barIndex);
//
dir = isBullish
? X_DIRECTION_BULLISH
: isBearish
? X_DIRECTION_BEARISH
: X_DIRECTION_NONE;
//
result = HasDirection(dir);
//
return result;
}
bool IsKIBullishPOI(int barIndex = 0)
{
//
bool result = false;
//
barIndex = kiParser.NormalizeBarIndex(barIndex);
//
result =
kiParser.IsValid() &&
kiParser.IsKISlowBullish(barIndex) &&
kiParser.IsKIFastBearish(barIndex);
//
return result;
}
bool IsKIBearishPOI(int barIndex = 0)
{
//
bool result = false;
//
barIndex = kiParser.NormalizeBarIndex(barIndex);
//
result =
kiParser.IsValid() &&
kiParser.IsKISlowBearish(barIndex) &&
kiParser.IsKIFastBullish(barIndex);
//
return result;
}
bool IsKISignal(
ENUM_X_DIRECTION &dir, //
int barIndex = 0 //
@@ -1798,6 +1863,85 @@ class XCX121XKIPOIDetector : public XCMarketPatternDetector
XClean(tmpResistances);
}
void RefineStructure(
XBoxZone &supports[],
XBoxZone &resistances[],
XBoxZone &minorSupport,
XBoxZone &majorSupport,
XBoxZone &minorResistance,
XBoxZone &majorResistance,
int loopback = 500,
double breakThreshold = 5,
ENUM_X_PRICE breakBy = X_PRICE_CLOSE //
)
{
//
// Support ...
if (HasChild(supports))
{
//
for (int i = 0; i < ArraySize(supports); i++)
{
//
RefineZone(
supports[i],
loopback,
breakThreshold,
breakBy //
);
}
}
//
// Resistance ...
if (HasChild(resistances))
{
//
for (int i = 0; i < ArraySize(resistances); i++)
{
//
RefineZone(
resistances[i],
loopback,
breakThreshold,
breakBy //
);
}
}
//
RefineZone(
minorSupport,
loopback,
breakThreshold,
breakBy //
);
//
RefineZone(
majorSupport,
loopback,
breakThreshold,
breakBy //
);
//
RefineZone(
minorResistance,
loopback,
breakThreshold,
breakBy //
);
//
RefineZone(
majorResistance,
loopback,
breakThreshold,
breakBy //
);
}
int CounteZoneTouches(
XBoxZone &zone,
double threshold = 10,
@@ -1942,6 +2086,277 @@ class XCX121XKIPOIDetector : public XCMarketPatternDetector
//
return result;
}
void RefineZone(
XBoxZone &zone,
int loopback = 500,
double breakThreshold = 5,
ENUM_X_PRICE breakBy = X_PRICE_CLOSE //
)
{
//
bool has =
zone.IsValid() &&
IsXValid(breakBy);
if (!has)
{
return;
}
//
// Normalize ...
loopback = NormalizeInt(loopback, 1);
breakThreshold = NormalizeDouble(breakThreshold, 0, 50);
//
XOHCL iBar;
int start = zone.FromIndex();
int end = start + loopback;
double point = GetPoints(zone.symbol);
double breakDistance = point * breakThreshold;
for (int i = start; i < end; i++)
{
//
has = iBar.Init(zone.symbol, zone.period, i);
if (has)
{
//
// Check Rejections ...
has = zone.IsBullish()
? iBar.low < zone.upper &&
iBar.GetDown() > zone.upper
: iBar.high > zone.upper &&
iBar.GetUp() < zone.upper;
if (has)
{
//
Add(
iBar.time,
zone.tests //
);
}
//
// Check Break ...
double bPrice = iBar.GetPrice(breakBy);
has =
zone.IsBullish()
? bPrice < zone.lower - breakDistance
: bPrice > zone.upper + breakDistance;
if (has)
{
//
zone.breakAt = iBar.time;
break;
}
}
//
iBar.Clean();
}
//
has = IsXValid(zone.breakAt);
if (has)
{
//
zone.at = zone.from;
zone.from = zone.breakAt;
}
}
// #endregion
// #region VolatilitySwitchedHigh ...
bool IsVolatilitySwitchedHigh(
int barIndex = 0,
int loopback = 3 //
)
{
//
bool result = false;
//
barIndex = kiParser.NormalizeBarIndex(barIndex);
loopback = NormalizeInt(loopback, 1);
//
for (int i = barIndex; i < barIndex + loopback; i++)
{
//
result = kiParser.IsVolatilitySwitchdToHigh(i);
if (result)
{
break;
}
}
//
return result;
}
// #endregion
// #region Bar Patterns ...
bool HasRecentPatternTouched(
XBoxZone &zone,
double price,
int barIndex = 0,
int loopback = 5,
int threshold = 5,
ENUM_TIMEFRAMES forPeriod = NULL,
ENUM_X_DIRECTION forDir = X_DIRECTION_NONE //
)
{
//
bool result = false;
//
zone.Clean();
//
// Validate ...
result = NotEmptyZero(price);
if (!result)
{
return result;
}
//
// Normalize ...
loopback = NormalizeInt(loopback, 2);
barIndex = kiParser.NormalizeBarIndex(barIndex);
if (IsXValid(forPeriod))
{
forPeriod = period;
}
//
XOHCL iBar;
bool has = false;
int iBullishIDX = -1;
int iBearishIDX = -1;
bool isBullish = false;
bool isBearish = false;
XBoxZone iBullishZones[];
XBoxZone iBearishZones[];
XPatternAnalysis iAnalysis;
XPatternAnalysisConfig iConfig;
//
// Preparing Pattern Analysis Config ...
iConfig.Default();
iConfig.FullPattern();
//
for (int i = barIndex; i < barIndex + loopback; i++)
{
//
// Initialize Bar ...
has = iBar.Init(symbol, forPeriod, i);
if (!has)
{
continue;
}
//
// Analyse Patterns ...
has = AnalyseBarPatterns(iBar, iAnalysis, iConfig);
if (!has)
{
//
iBar.Clean();
continue;
}
//
// Bullish ...
has = iAnalysis.Count(X_DIRECTION_BULLISH) > 0;
if (has)
{
//
iAnalysis.GetPatterns(iBullishZones, X_DIRECTION_BULLISH);
has = HasChild(iBullishZones);
if (has)
{
//
has = HasNearZone(
iBullishIDX,
price,
threshold,
iBullishZones //
);
if (has)
{
isBullish = true;
}
}
}
//
// Bearish ...
has = iAnalysis.Count(X_DIRECTION_BEARISH) > 0;
if (has)
{
//
iAnalysis.GetPatterns(iBearishZones, X_DIRECTION_BEARISH);
has = HasChild(iBearishZones);
if (has)
{
//
has = HasNearZone(
iBearishIDX,
price,
threshold,
iBearishZones //
);
if (has)
{
isBearish = true;
}
}
}
//
// Summarizing Result ...
has =
HasDirection(forDir)
? (isBullish && !isBearish && IsXBullish(forDir)) ||
(isBearish && !isBullish && IsXBearish(forDir))
: (isBullish && !isBearish) || (isBearish && !isBullish);
if (has)
{
//
// Fill Zones ...
if (isBullish)
{
zone = iBullishZones[iBullishIDX];
}
else
{
zone = iBearishZones[iBearishIDX];
}
break;
}
//
iBar.Clean();
iAnalysis.Clean();
XClean(iBullishZones);
XClean(iBearishZones);
}
//
// Next
//
iBar.Clean();
iConfig.Clean();
iAnalysis.Clean();
XClean(iBullishZones);
XClean(iBearishZones);
//
return result;
}
// #endregion
//