Files
MQL5Data/Documents/BKP/X121XKI/tmp.zones.poi.mq5
T
saherelm 31232dffef some cleanups, refactor unnecessary requirements, implement rejected checkers and also counters ...
ass support for PV and KISuperSlow and MASuper Slow in KI Indicator and also Helper and implement them in BackTester ...
2026-01-07 04:27:38 +03:30

459 lines
12 KiB
Plaintext

int CounteZoneTouches(
XBoxZone &zone,
double threshold = 10,
int loopback = 100 //
)
{
//
int result = 0;
//
// Normalize ...
loopback = NormalizeInt(loopback, 50);
threshold = NormalizeDouble(threshold, 10);
//
if (!zone.IsValid())
{
return result;
}
//
XOHCL tmpBar;
int start = zone.ToIndex();
bool isUpperTouched = false;
bool isLowerTouched = false;
double points = GetPoints(zone.symbol);
double distance = points * threshold;
int end = MathMin(start + loopback, zone.FromIndex());
for (int i = start; i < end; i++)
{
//
if (tmpBar.Init(zone.symbol, zone.period, i))
{
//
isUpperTouched = MathAbs(tmpBar.high - zone.upper) <= distance;
isLowerTouched = MathAbs(tmpBar.low - zone.lower) <= distance;
//
if (
(zone.IsBullish() &&
(isLowerTouched ||
MathAbs(tmpBar.close - zone.lower) <= distance)) ||
(zone.IsBearish() &&
(isUpperTouched ||
MathAbs(tmpBar.close - zone.upper) <= distance)))
{
//
result++;
Add(
tmpBar.time,
zone.tests //
);
}
//
tmpBar.Clean();
}
}
//
tmpBar.Clean();
//
return result;
}
bool HasNearZone(
int &index,
double price,
double threshold,
XBoxZone &zones[] //
)
{
//
bool result = false;
//
index = -1;
//
// Validate ...
result = HasChild(zones) &&
NotEmptyZero(price) &&
NotEmptyZero(threshold) &&
price > 0 &&
threshold > 0;
if (!result)
{
return result;
}
//
double points = GetPoints(zones[0].symbol);
double distance = points * threshold;
for (int i = 0; i < ArraySize(zones); i++)
{
//
// Check Price Distance by Upper ...
result = price >= zones[i].lower - distance &&
price <= zones[i].upper + distance;
if (result)
{
//
index = i;
break;
}
}
//
result = IsValidIndex(index);
//
return result;
}
bool IsNearZone(
double price,
XBoxZone &zone,
double threshold = 0 //
)
{
//
bool result = false;
//
result =
zone.IsValid() &&
NotEmptyZero(price);
if (!result)
{
return result;
}
//
double points = GetPoints(zone.symbol);
double distance = points * threshold;
//
result = price >= zone.lower - distance &&
price <= zone.upper + distance;
//
return result;
}
/*
* Check Recently Pattern Zone is Touched or not ...
*
* @param zone: XBoxZone, Touched Zone ...
* @param patterns: ENUM_X_BAR_PATTERN, Allowed to Check Patterns ...
* @param patternsDir: ENUM_X_DIRECTION, Allowed Directions ...
* @param price: double, a Price to Check Toch or Reject ...
* @param barIndex: int, Bar Index to Start Checking ...
* @param loopback: int, Loopback for Pattern Formations ...
* @param threshold: double, threshold for Pattern touch ...
* @param forPeriod: ENUM_TIMEFRAMES, Time Frame to Check Patterns ...
* @param forDir: ENUM_X_DIRECTION, Directions for Pattern's Formation Check ...
*
* @return ( bool )
*/
bool HasRecentPatternTouched(
XBoxZone &zone,
ENUM_X_BAR_PATTERN &patterns[],
ENUM_X_DIRECTION &patternsDir[],
double price,
int barIndex = 0,
int loopback = 5,
double threshold = 5,
ENUM_TIMEFRAMES forPeriod = NULL,
ENUM_X_DIRECTION forDir = X_DIRECTION_NONE //
)
{
//
bool result = false;
//
zone.Clean();
//
// Validate ...
result =
HasChild(patterns) &&
NotEmptyZero(price) &&
HasChild(patternsDir) &&
ArraySize(patterns) == ArraySize(patternsDir);
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();
//
Copy(
patterns,
iConfig.allowedPatterns //
);
Copy(
patternsDir,
iConfig.allowedDirs //
);
//
// XAUUSD ...
iConfig.AddPattern(X_BAR_PATTERN_FVG);
iConfig.AddPattern(X_BAR_PATTERN_PIERCING);
//
// Looping Back ...
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;
}
//
// Cleanup Resource ...
iBar.Clean();
iAnalysis.Clean();
XClean(iBullishZones);
XClean(iBearishZones);
}
//
// Cleanup Resources ...
iBar.Clean();
iConfig.Clean();
iAnalysis.Clean();
XClean(iBullishZones);
XClean(iBearishZones);
//
return result;
}
void ValidateZones(
XBoxZone &zones[],
int barIndex = 0,
int minimumRetests = 2,
double retestThreshold = 10,
int retestLoopback = 100,
ENUM_X_BOUNDARY_PRICE forPriceType = X_BOUNDARY_PRICE_UP_DOWN //
)
{
//
bool has = false;
//
// Validation ...
has = HasChild(zones) &&
IsXValid(forPriceType);
if (!has)
{
return;
}
//
// Normalizetion ...
barIndex = kiParser.NormalizeBarIndex(barIndex);
minimumRetests = NormalizeInt(minimumRetests, 0);
retestLoopback = NormalizeInt(retestLoopback, 50);
retestThreshold = NormalizeDouble(retestThreshold, 5, 10);
//
XOHCL tmpBar;
XBoxZone tmp;
XBoxZone tmps[];
double tmpValue = 0;
for (int i = 0; i < ArraySize(zones); i++)
{
//
tmp = zones[i];
//
if (minimumRetests > 0)
{
//
int retests = CounteZoneTouches(tmp, retestThreshold, retestLoopback);
if (retests < minimumRetests)
{
continue;
}
}
//
// Validate Zone ...
has = false;
for (int j = barIndex; j < tmp.FromIndex(); j++)
{
//
// Initial Bar ...
if (tmpBar.Init(tmp.symbol, tmp.period, j))
{
//
tmpValue = forPriceType == X_BOUNDARY_PRICE_UP_DOWN
? tmp.IsBullish()
? tmpBar.GetDown()
: tmpBar.GetUp()
: forPriceType == X_BOUNDARY_PRICE_HIGH_LOW
? tmp.IsBullish()
? tmpBar.low
: tmpBar.high
: EMPTY_VALUE;
if (NotEmptyZero(tmpValue))
{
//
// Check Break ...
has = tmp.IsBullish()
? tmpValue < tmp.lower
: tmpValue > tmp.upper;
//
// If Breakes ...
if (has)
{
break;
}
}
//
tmpBar.Clean();
}
}
//
// Not Breaked ...
if (!has)
{
//
AddIfNotExists(
tmp,
tmps //
);
}
//
tmp.Clean();
}
//
// Update Zones ...
XClean(zones);
Copy(
tmps,
zones //
);
XClean(tmps);
}