Files
MQL5Data/X121XKIEA/Classes/x-saherelm.x121.xki.x-poi.detector.class.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

2645 lines
63 KiB
Plaintext

///////////////////////////////////////////////////////
//
// SaherElm IT Center MQL5 Class
// -------------------------------------------------
// Name: XCX121XKIPoiDetector ...
// Description: X121XKI POI Detector Class ...
//
//
// Maintainer:
// ------------
// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com)
//
//////////////////////////////////////////////////////
//
// Global Properties ...
#property library
#property copyright "Copyright 2023, SaherElm IT Center"
#property link "https://saherelm.ir"
#property version "1.00"
#property description "SaherElm X121XKI POI Detector Class"
#property strict
//
// Imports ...
#include "../../Classes/x-saherelm.base.class.mq5"
#include "../../Classes/x-saherelm.x-bar.analyser.class.mq5"
#include "../../Classes/x-saherelm.x-market.pattern.class.mq5"
#include "../../Helpers/x-saherelm.x121.xki.helper.mq5"
#include "../Classes/x-saherelm.x121.xki.parser.class.mq5"
//
// Definitions ...
//
// Implementation ...
class XCX121XKIPOIDetector : public XCMarketPatternDetector
{
//
// Public ...
public:
//
// Props ...
//
string symbol;
ENUM_TIMEFRAMES period;
//
XCBarAnalyser *barAnalyser; // Bar Analyser ...
XCX121XKIHelper *kiHelper; // X121XKI Helper ...
XCX121XKIHelperParser *kiParser; // X121XKI Helper Parser ...
//
// Constructor ...
XCX121XKIPOIDetector(
XCX121XKIHelper *_kiHelper,
XCX121XKIHelperParser *_kiParser //
) : XCMarketPatternDetector()
{
//
barAnalyser = new XCBarAnalyser();
kiHelper = _kiHelper;
kiParser = _kiParser;
//
symbol = kiHelper.GetSymbol();
period = kiHelper.GetPeriod();
}
//
// Deconstructor ...
~XCX121XKIPOIDetector()
{
Destroy();
}
//
// Actions and Tools ...
// #region Zone Detectors ...
int DetectSupports(
XBoxZone &zones[],
int barIndex,
int loopback = 50,
bool forceValidation = true,
int validationLength = 7,
string forSymbol = NULL,
ENUM_TIMEFRAMES forPeriod = NULL //
)
{
//
int result = 0;
//
XClean(zones);
//
// Normalize ...
//
if (barIndex < 0)
{
barIndex = 0;
}
//
if (!IsXValid(forSymbol))
{
forSymbol = symbol;
}
//
if (!IsXValid(forPeriod))
{
forPeriod = period;
}
//
if (loopback < 2)
{
loopback = 2;
}
//
if (validationLength < 2)
{
validationLength = 2;
}
//
// Preparing Loops ...
XOHCL tmpBar;
bool has = false;
double upper = 0;
double lower = 0;
XBoxZone tmpZone;
string type = NULL;
double tmpValue = 0;
datetime from = NULL;
int start = barIndex;
int end = barIndex + loopback;
datetime to = GetBarTime(forSymbol, forPeriod, barIndex);
for (int i = start; i < end; i++)
{
//
// Initialize Bar ...
if (tmpBar.Init(forSymbol, forPeriod, i))
{
//
// Check Has Shadow ...
has = tmpBar.GetHighShadow() > 0 ||
tmpBar.GetLowShadow() > 0;
if (has)
{
//
// Check Support or Resistance ...
//
// Support ...
tmpValue = tmpBar.FindLowest(validationLength, MODE_LOW);
has = NotEmptyZero(tmpValue) &&
tmpValue == tmpBar.low;
//
if (has)
{
//
tmpZone.Clean();
lower = tmpValue;
from = tmpBar.time;
upper = tmpBar.GetDown();
type = ToXString(X_BAR_PATTERN_SUPPORT);
has = tmpZone.Init(
forSymbol,
forPeriod,
upper,
lower,
from,
to,
X_DIRECTION_BULLISH,
type //
);
if (has)
{
//
AddRef(
tmpZone,
zones //
);
//
tmpZone.Clean();
}
}
}
//
tmpBar.Clean();
}
}
//
// Validate ...
if (HasChild(zones) && forceValidation)
{
//
ValidateZones(
zones,
barIndex //
);
}
//
result = ArraySize(zones);
//
return result;
}
int DetectResistances(
XBoxZone &zones[],
int barIndex,
int loopback = 50,
bool forceValidation = true,
int validationLength = 7,
string forSymbol = NULL,
ENUM_TIMEFRAMES forPeriod = NULL //
)
{
//
int result = 0;
//
XClean(zones);
//
// Normalize ...
//
if (barIndex < 0)
{
barIndex = 0;
}
//
if (!IsXValid(forSymbol))
{
forSymbol = symbol;
}
//
if (!IsXValid(forPeriod))
{
forPeriod = period;
}
//
if (loopback < 2)
{
loopback = 2;
}
//
if (validationLength < 2)
{
validationLength = 2;
}
//
// Preparing Loops ...
XOHCL tmpBar;
bool has = false;
double upper = 0;
double lower = 0;
XBoxZone tmpZone;
string type = NULL;
double tmpValue = 0;
datetime from = NULL;
int start = barIndex;
int end = barIndex + loopback;
datetime to = GetBarTime(forSymbol, forPeriod, barIndex);
for (int i = start; i < end; i++)
{
//
// Initialize Bar ...
if (tmpBar.Init(forSymbol, forPeriod, i))
{
//
// Check Has Shadow ...
has = tmpBar.GetHighShadow() > 0 ||
tmpBar.GetLowShadow() > 0;
if (has)
{
//
// Check Support or Resistance ...
//
// Resistance ...
tmpValue = tmpBar.FindHighest(validationLength, MODE_HIGH);
has = NotEmptyZero(tmpValue) &&
tmpValue == tmpBar.high;
if (has)
{
//
tmpZone.Clean();
upper = tmpValue;
from = tmpBar.time;
lower = tmpBar.GetUp();
type = ToXString(X_BAR_PATTERN_RESISTANCE);
has = tmpZone.Init(
forSymbol,
forPeriod,
upper,
lower,
from,
to,
X_DIRECTION_BEARISH,
type //
);
if (has)
{
//
AddRef(
tmpZone,
zones //
);
//
tmpZone.Clean();
}
}
}
//
tmpBar.Clean();
}
}
//
// Validate ...
if (HasChild(zones) && forceValidation)
{
//
ValidateZones(
zones,
barIndex //
);
}
//
result = ArraySize(zones);
//
return result;
}
void ValidateZones(
XBoxZone &zones[],
int barIndex = 0,
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);
//
XOHCL tmpBar;
XBoxZone tmp;
XBoxZone tmps[];
double tmpValue = 0;
for (int i = 0; i < ArraySize(zones); i++)
{
//
tmp = zones[i];
//
// 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);
}
void GetCurrentStructure(
XBoxZone &supports[],
XBoxZone &resistances[],
XBoxZone &minorSupport,
XBoxZone &majorSupport,
XBoxZone &minorResistance,
XBoxZone &majorResistance,
int barIndex = 0,
string forSymbol = NULL,
ENUM_TIMEFRAMES forMinorPeriod = NULL,
ENUM_TIMEFRAMES forMajorPeriod = NULL,
int loopback = 50,
int minorValidation = 7,
int majorValidation = 14 //
)
{
//
bool has = false;
//
XClean(supports);
XClean(resistances);
minorSupport.Clean();
majorSupport.Clean();
minorResistance.Clean();
majorResistance.Clean();
//
// Normalize ...
barIndex = kiParser.NormalizeBarIndex(barIndex);
if (!IsXValid(forSymbol))
{
forSymbol = symbol;
}
if (!IsXValid(forMinorPeriod))
{
forMinorPeriod = period;
}
if (!IsXValid(forMajorPeriod))
{
forMajorPeriod = period;
}
//
int tmpIDX = -1;
int supportsCount = 0;
XBoxZone tmpSupports[];
int resistancesCount = 0;
XBoxZone tmpResistances[];
//
// Detect Minors ...
//
supportsCount = DetectSupports(
tmpSupports,
barIndex,
loopback,
true, // Force Validation ...
minorValidation,
forSymbol,
forMinorPeriod //
);
if (IsValidSize(supportsCount))
{
//
FillNotExists(
supports,
tmpSupports //
);
//
tmpIDX = GetYoungest(tmpSupports);
if (IsValidIndex(tmpIDX))
{
minorSupport = tmpSupports[tmpIDX];
}
}
//
resistancesCount = DetectResistances(
tmpResistances,
barIndex,
loopback,
true, // Force Validation ...
minorValidation,
forSymbol,
forMinorPeriod //
);
if (IsValidSize(resistancesCount))
{
//
FillNotExists(
resistances,
tmpResistances //
);
//
tmpIDX = GetYoungest(tmpResistances);
if (IsValidIndex(tmpIDX))
{
minorResistance = tmpResistances[tmpIDX];
}
}
//
XClean(tmpSupports);
XClean(tmpResistances);
//
// Detect Majors ...
//
supportsCount = DetectSupports(
tmpSupports,
barIndex,
loopback,
true, // Force Validation ...
majorValidation,
forSymbol,
forMajorPeriod //
);
if (IsValidSize(supportsCount))
{
//
UpdateToTime(tmpSupports);
//
FillNotExists(
supports,
tmpSupports //
);
//
tmpIDX = GetLowest(tmpSupports);
if (IsValidIndex(tmpIDX))
{
majorSupport = tmpSupports[tmpIDX];
}
}
//
resistancesCount = DetectResistances(
tmpResistances,
barIndex,
loopback,
true, // Force Validation ...
majorValidation,
forSymbol,
forMajorPeriod //
);
if (IsValidSize(resistancesCount))
{
//
UpdateToTime(tmpResistances);
//
FillNotExists(
resistances,
tmpResistances //
);
//
tmpIDX = GetHighest(tmpResistances);
if (IsValidIndex(tmpIDX))
{
majorResistance = tmpResistances[tmpIDX];
}
}
//
XClean(tmpSupports);
XClean(tmpResistances);
}
bool HasStructure(
int barIndex = 0,
string forSymbol = NULL,
ENUM_TIMEFRAMES forMinorPeriod = NULL,
ENUM_TIMEFRAMES forMajorPeriod = NULL,
int loopback = 50,
int minorValidation = 7,
int majorValidation = 14 //
)
{
//
XBoxZone supports[];
XBoxZone resistances[];
XBoxZone minorSupport;
XBoxZone majorSupport;
XBoxZone minorResistance;
XBoxZone majorResistance;
//
GetCurrentStructure(
supports,
resistances,
minorSupport,
majorSupport,
minorResistance,
majorResistance,
barIndex,
forSymbol,
forMinorPeriod,
forMajorPeriod,
loopback,
minorValidation,
majorValidation //
);
//
bool result =
majorSupport.IsValid() &&
majorResistance.IsValid();
//
XClean(supports);
XClean(resistances);
minorSupport.Clean();
majorSupport.Clean();
minorResistance.Clean();
majorResistance.Clean();
//
return result;
}
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 //
);
}
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;
}
}
bool DetectRecentSwings(
XBoxZone &swingHigh,
XBoxZone &swingLow,
int barIndex = 0,
int swingsValidationLength = 50,
int loopback = 500,
ENUM_TIMEFRAMES forPeriod = NULL,
bool forceRefineZones = true //
)
{
//
swingLow.Clean();
swingHigh.Clean();
//
loopback = NormalizeInt(loopback, 5);
barIndex = kiParser.NormalizeBarIndex(barIndex);
swingsValidationLength = NormalizeInt(swingsValidationLength, 5);
if (!IsXValid(forPeriod))
{
forPeriod = period;
}
//
XOHCL iBar;
int iIDX = -1;
double low = 0;
double high = 0;
int lowIDX = -1;
int highIDX = -1;
bool has = false;
double iValue = 0;
datetime lowAt = NULL;
datetime highAt = NULL;
for (int i = barIndex; i < barIndex + loopback; i++)
{
//
has = iBar.Init(symbol, forPeriod, i);
if (!has)
{
continue;
}
//
iIDX = iBar.FindLowestIndex(swingsValidationLength, MODE_LOW);
has = IsValidIndex(iIDX);
if (has)
{
//
iValue = iLow(iBar.symbol, iBar.period, iIDX);
//
// Check Can Set Low ...
has = (!NotEmptyZero(low) ||
(NotEmptyZero(low) && iValue < low)) &&
IsValidSwing(
iValue,
iIDX,
barIndex,
iBar.symbol,
iBar.period,
X_SWING_LOW //
);
if (has)
{
//
low = iValue;
lowIDX = iIDX;
lowAt = iBar.time;
}
}
//
iIDX = iBar.FindHighestIndex(swingsValidationLength, MODE_HIGH);
has = IsValidIndex(iIDX);
if (has)
{
//
iValue = iHigh(iBar.symbol, iBar.period, iIDX);
//
// Check Can Set High ...
has = (!NotEmptyZero(high) ||
(NotEmptyZero(high) && iValue > high)) &&
IsValidSwing(
iValue,
iIDX,
barIndex,
iBar.symbol,
iBar.period,
X_SWING_HIGH //
);
if (has)
{
//
high = iValue;
highIDX = iIDX;
highAt = iBar.time;
}
}
//
iBar.Clean();
}
//
// Recent Low Swing ...
has =
IsXValid(lowAt) &&
NotEmptyZero(low) &&
IsValidIndex(lowIDX);
if (has)
{
//
has = iBar.Init(symbol, forPeriod, lowIDX);
has = has &&
swingLow.Init(
iBar.symbol,
iBar.period,
iBar.GetDown(),
low,
GetBarTime(iBar.symbol, iBar.period, lowIDX + swingsValidationLength - 1),
GetBarTime(iBar.symbol, iBar.period, barIndex),
X_DIRECTION_BULLISH,
ToXString(X_BAR_PATTERN_LOW),
lowAt //
);
if (has && forceRefineZones)
{
RefineZone(swingLow, 500, 5, X_PRICE_CLOSE);
}
}
//
// Recent High Swing ...
has =
IsXValid(highAt) &&
NotEmptyZero(high) &&
IsValidIndex(highIDX);
if (has)
{
//
has = iBar.Init(symbol, forPeriod, highIDX);
has = has &&
swingHigh.Init(
iBar.symbol,
iBar.period,
high,
iBar.GetUp(),
GetBarTime(iBar.symbol, iBar.period, lowIDX + swingsValidationLength - 1),
GetBarTime(iBar.symbol, iBar.period, barIndex),
X_DIRECTION_BEARISH,
ToXString(X_BAR_PATTERN_HIGH),
highAt //
);
if (has && forceRefineZones)
{
RefineZone(swingHigh, 500, 5, X_PRICE_CLOSE);
}
}
//
bool result = swingLow.IsValid() &&
swingHigh.IsValid();
//
return result;
}
bool HasOrderFlow(
XBoxZone &flow[],
int barIndex = 0,
int flowValidationLength = 5,
ENUM_X_DIRECTION flowDir = X_DIRECTION_NONE,
int loopback = 50,
string forSymbol = NULL,
ENUM_TIMEFRAMES forPeriod = NULL,
ENUM_X_BOUNDARY_PRICE priceType = X_BOUNDARY_PRICE_HIGH_LOW //
)
{
//
bool result = false;
//
XClean(flow);
//
// Validate ...
result =
IsXValid(priceType);
if (!result)
{
return result;
}
//
// Normalizing Data ...
if (!IsXValid(forSymbol))
{
forSymbol = symbol;
}
if (!IsXValid(forPeriod))
{
forPeriod = period;
}
loopback = NormalizeInt(loopback, 5);
barIndex = kiParser.NormalizeBarIndex(barIndex);
flowValidationLength = NormalizeInt(flowValidationLength, 2);
//
// Handle Works ...
//
XOHCL iBar;
int iIndex = -1;
bool has = false;
XBoxZone tmpZone;
double iPrice = 0;
ENUM_X_PRICE iPriceType;
bool isBullish = !HasDirection(flowDir) || IsXBullish(flowDir);
bool isBearish = !HasDirection(flowDir) || IsXBearish(flowDir);
//
// Looping Reversal ...
int start = barIndex + loopback;
int end = barIndex;
for (int i = start; i > end; i--)
{
//
has = iBar.Init(forSymbol, forPeriod, i);
if (!has)
{
continue;
}
//
// Check iBar is Low Swing ...
if (isBullish)
{
//
iPriceType = priceType == X_BOUNDARY_PRICE_HIGH_LOW
? X_PRICE_LOW
: X_PRICE_DOWN;
iPrice = iBar.GetPrice(iPriceType);
has = iPrice == iBar.FindLowest(iIndex, flowValidationLength, iPriceType);
has = has &&
IsValidSwing(
iPrice,
iBar.Index(),
barIndex,
iBar.symbol,
iBar.period,
X_SWING_LOW //
);
if (has)
{
//
// Flow Detected ...
tmpZone.Clean();
iPriceType = priceType == X_BOUNDARY_PRICE_HIGH_LOW
? X_PRICE_DOWN
: X_PRICE_UP;
has = tmpZone.Init(
iBar.symbol,
iBar.period,
iBar.GetPrice(iPriceType),
iPrice,
iBar.time,
GetBarTime(iBar.symbol, iBar.period, barIndex),
X_DIRECTION_BULLISH,
ToXString(X_BAR_PATTERN_LOW) //
);
if (has)
{
//
AddIfNotExists(
tmpZone,
flow //
);
//
tmpZone.Clean();
}
}
}
//
// Check iBar is High Swing ...
if (isBearish)
{
//
iPriceType = priceType == X_BOUNDARY_PRICE_HIGH_LOW
? X_PRICE_HIGH
: X_PRICE_UP;
iPrice = iBar.GetPrice(iPriceType);
has = iPrice == iBar.FindHighest(iIndex, flowValidationLength, iPriceType);
has = has &&
IsValidSwing(
iPrice,
iBar.Index(),
barIndex,
iBar.symbol,
iBar.period,
X_SWING_HIGH //
);
if (has)
{
//
// Flow Detected ...
tmpZone.Clean();
iPriceType = priceType == X_BOUNDARY_PRICE_HIGH_LOW
? X_PRICE_UP
: X_PRICE_DOWN;
has = tmpZone.Init(
iBar.symbol,
iBar.period,
iPrice,
iBar.GetPrice(iPriceType),
iBar.time,
GetBarTime(iBar.symbol, iBar.period, barIndex),
X_DIRECTION_BEARISH,
ToXString(X_BAR_PATTERN_HIGH) //
);
if (has)
{
//
AddIfNotExists(
tmpZone,
flow //
);
//
tmpZone.Clean();
}
}
}
//
iBar.Clean();
tmpZone.Clean();
}
//
result = HasChild(flow);
if (result)
{
Sort(flow);
}
//
return result;
}
bool IsValidSwing(
double price,
int swingIDX,
int barIndex = 0,
string forSymbol = NULL,
ENUM_TIMEFRAMES forPeriod = NULL,
ENUM_X_SWING_TYPE swingType = X_SWING_NONE //
)
{
//
bool result = false;
//
result =
NotEmptyZero(price) &&
IsXValid(swingType) &&
IsValidIndex(swingIDX) &&
swingIDX >= barIndex;
if (!result)
{
return result;
}
//
if (!IsXValid(forSymbol))
{
forSymbol = symbol;
}
if (!IsXValid(forPeriod))
{
forPeriod = period;
}
barIndex = kiParser.NormalizeBarIndex(barIndex);
//
XOHCL iBar;
bool has = false;
for (int i = barIndex; i <= (swingIDX - barIndex); i++)
{
//
has = iBar.Init(forSymbol, forPeriod, i);
if (!has)
{
continue;
}
//
// Check Price Break ...
has =
(swingType == X_SWING_LOW &&
iBar.low < price) ||
(swingType == X_SWING_HIGH &&
iBar.high > price);
if (has)
{
break;
}
//
iBar.Clean();
}
//
result = !has && !iBar.IsValid();
//
iBar.Clean();
//
return result;
}
// #endregion
// #region Hasers ...
bool HasVolatilitySwitchedHigh(
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 ...
void FillStrategy1Patterns(
ENUM_X_BAR_PATTERN &patterns[],
ENUM_X_DIRECTION &dirs[],
ENUM_X_DIRECTION forDir = X_DIRECTION_NONE,
string forSymbol = NULL,
ENUM_TIMEFRAMES forPeriod = NULL //
)
{
//
XClean(dirs);
XClean(patterns);
//
if (!IsXValid(forSymbol))
{
forSymbol = symbol;
}
if (!IsXValid(forPeriod))
{
forPeriod = period;
}
//
GetAllBarPatters(patterns, dirs);
//
// Add(X_BAR_PATTERN_FVG, patterns);
// Add(forDir, dirs);
}
void RefactorStrategy1OperationalZone(XBoxZone &zone)
{
//
if (!zone.IsValid())
{
return;
}
//
// Refine Zone ...
RefineZone(zone);
//
// SL Refactoring ...
//
XOHCL toBar;
if (zone.ToBar(toBar))
{
//
int to = zone.ToIndex();
int from = zone.FromIndex();
int length = from - to;
double iValue =
zone.IsBullish()
? toBar.FindLowest(length, MODE_LOW)
: zone.IsBearish()
? toBar.FindHighest(length, MODE_HIGH)
: EMPTY_VALUE;
if (NotEmptyZero(iValue))
{
//
if (zone.IsBullish())
{
zone.lower = MathMin(zone.lower, iValue);
}
//
if (zone.IsBearish())
{
zone.upper = MathMax(zone.upper, iValue);
}
}
}
toBar.Clean();
}
/*
* Check Recently Pattern Zone is Rejected 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 forPeriod: ENUM_TIMEFRAMES, Time Frame to Check Patterns ...
* @param forDir: ENUM_X_DIRECTION, Directions for Pattern's Formation Check ...
*
* @return ( bool )
*/
bool HasRecentPatternRejected(
XBoxZone &zone,
ENUM_X_BAR_PATTERN &patterns[],
ENUM_X_DIRECTION &patternsDir[],
int barIndex = 0,
int loopback = 5,
ENUM_TIMEFRAMES forPeriod = NULL,
ENUM_X_DIRECTION forDir = X_DIRECTION_NONE //
)
{
//
bool result = false;
//
zone.Clean();
//
// Validate ...
result =
HasChild(patterns) &&
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 bar;
result = bar.Init(symbol, forPeriod, barIndex);
if (!result)
{
return result;
}
//
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 //
);
//
// 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);
isBullish =
HasChild(iBullishZones) &&
HasRejected(iBullishIDX, bar, iBullishZones);
}
//
// Bearish ...
has = iAnalysis.Count(X_DIRECTION_BEARISH) > 0;
if (has)
{
//
iAnalysis.GetPatterns(iBearishZones, X_DIRECTION_BEARISH);
isBearish =
HasChild(iBearishZones) &&
HasRejected(iBearishIDX, bar, iBearishZones);
}
//
// 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 ...
bar.Clean();
iBar.Clean();
iConfig.Clean();
iAnalysis.Clean();
XClean(iBullishZones);
XClean(iBearishZones);
//
result = zone.IsValid();
//
return result;
}
// #endregion
// #region Switches ...
// TODO: Implement Switches Checkers in Loopback ...
// #endregion
// #region Peak and Vale ...
// TODO: Implement Root of Changes when IsPeakOverLast or IsValeUnderLast Happens ...
// #endregion
// #region Rejecteds ...
bool IsKIFastRejected(
ENUM_X_DIRECTION &dir,
int barIndex = 0,
string forSymbol = NULL,
ENUM_TIMEFRAMES forPeriod = NULL //
)
{
//
bool result = false;
//
dir = X_DIRECTION_NONE;
if (!IsXValid(forSymbol))
{
forSymbol = symbol;
}
if (!IsXValid(forPeriod))
{
forPeriod = period;
}
barIndex = kiParser.NormalizeBarIndex(barIndex);
//
XOHCL bar;
result =
kiParser.IsValid() &&
bar.Init(forSymbol, forPeriod, barIndex);
if (!result)
{
return result;
}
//
double iValue = kiHelper.GetKIFast(barIndex);
//
bool isBullish = bar.IsRejected(iValue, X_DIRECTION_BULLISH, false, false);
bool isBearish = bar.IsRejected(iValue, X_DIRECTION_BEARISH, false, false);
//
dir =
isBullish
? X_DIRECTION_BULLISH
: isBearish
? X_DIRECTION_BEARISH
: X_DIRECTION_NONE;
//
result = HasDirection(dir);
//
bar.Clean();
//
return result;
}
bool IsKISlowRejected(
ENUM_X_DIRECTION &dir,
int barIndex = 0,
string forSymbol = NULL,
ENUM_TIMEFRAMES forPeriod = NULL //
)
{
//
bool result = false;
//
dir = X_DIRECTION_NONE;
if (!IsXValid(forSymbol))
{
forSymbol = symbol;
}
if (!IsXValid(forPeriod))
{
forPeriod = period;
}
barIndex = kiParser.NormalizeBarIndex(barIndex);
//
XOHCL bar;
result =
kiParser.IsValid() &&
bar.Init(forSymbol, forPeriod, barIndex);
if (!result)
{
return result;
}
//
double iValue = kiHelper.GetKISlow(barIndex);
//
bool isBullish = bar.IsRejected(iValue, X_DIRECTION_BULLISH, false, false);
bool isBearish = bar.IsRejected(iValue, X_DIRECTION_BEARISH, false, false);
//
dir =
isBullish
? X_DIRECTION_BULLISH
: isBearish
? X_DIRECTION_BEARISH
: X_DIRECTION_NONE;
//
result = HasDirection(dir);
//
bar.Clean();
//
return result;
}
bool IsKISuperSlowRejected(
ENUM_X_DIRECTION &dir,
int barIndex = 0,
string forSymbol = NULL,
ENUM_TIMEFRAMES forPeriod = NULL //
)
{
//
bool result = false;
//
dir = X_DIRECTION_NONE;
if (!IsXValid(forSymbol))
{
forSymbol = symbol;
}
if (!IsXValid(forPeriod))
{
forPeriod = period;
}
barIndex = kiParser.NormalizeBarIndex(barIndex);
//
XOHCL bar;
result =
kiParser.IsValid() &&
bar.Init(forSymbol, forPeriod, barIndex);
if (!result)
{
return result;
}
//
double iValue = kiHelper.GetKISuperSlow(barIndex);
//
bool isBullish = bar.IsRejected(iValue, X_DIRECTION_BULLISH, false, false);
bool isBearish = bar.IsRejected(iValue, X_DIRECTION_BEARISH, false, false);
//
dir =
isBullish
? X_DIRECTION_BULLISH
: isBearish
? X_DIRECTION_BEARISH
: X_DIRECTION_NONE;
//
result = HasDirection(dir);
//
bar.Clean();
//
return result;
}
bool IsKIUpperRejected(
ENUM_X_DIRECTION &dir,
int barIndex = 0,
string forSymbol = NULL,
ENUM_TIMEFRAMES forPeriod = NULL //
)
{
//
bool result = false;
//
dir = X_DIRECTION_NONE;
if (!IsXValid(forSymbol))
{
forSymbol = symbol;
}
if (!IsXValid(forPeriod))
{
forPeriod = period;
}
barIndex = kiParser.NormalizeBarIndex(barIndex);
//
XOHCL bar;
result =
kiParser.IsValid() &&
bar.Init(forSymbol, forPeriod, barIndex);
if (!result)
{
return result;
}
//
double iValue = kiHelper.GetKIUpper(barIndex);
//
bool isBullish = bar.IsRejected(iValue, X_DIRECTION_BULLISH, false, false);
bool isBearish = bar.IsRejected(iValue, X_DIRECTION_BEARISH, false, false);
//
dir =
isBullish
? X_DIRECTION_BULLISH
: isBearish
? X_DIRECTION_BEARISH
: X_DIRECTION_NONE;
//
result = HasDirection(dir);
//
bar.Clean();
//
return result;
}
bool IsKILowerRejected(
ENUM_X_DIRECTION &dir,
int barIndex = 0,
string forSymbol = NULL,
ENUM_TIMEFRAMES forPeriod = NULL //
)
{
//
bool result = false;
//
dir = X_DIRECTION_NONE;
if (!IsXValid(forSymbol))
{
forSymbol = symbol;
}
if (!IsXValid(forPeriod))
{
forPeriod = period;
}
barIndex = kiParser.NormalizeBarIndex(barIndex);
//
XOHCL bar;
result =
kiParser.IsValid() &&
bar.Init(forSymbol, forPeriod, barIndex);
if (!result)
{
return result;
}
//
double iValue = kiHelper.GetKILower(barIndex);
//
bool isBullish = bar.IsRejected(iValue, X_DIRECTION_BULLISH, false, false);
bool isBearish = bar.IsRejected(iValue, X_DIRECTION_BEARISH, false, false);
//
dir =
isBullish
? X_DIRECTION_BULLISH
: isBearish
? X_DIRECTION_BEARISH
: X_DIRECTION_NONE;
//
result = HasDirection(dir);
//
bar.Clean();
//
return result;
}
bool IsMAFastRejected(
ENUM_X_DIRECTION &dir,
int barIndex = 0,
string forSymbol = NULL,
ENUM_TIMEFRAMES forPeriod = NULL //
)
{
//
bool result = false;
//
dir = X_DIRECTION_NONE;
if (!IsXValid(forSymbol))
{
forSymbol = symbol;
}
if (!IsXValid(forPeriod))
{
forPeriod = period;
}
barIndex = kiParser.NormalizeBarIndex(barIndex);
//
XOHCL bar;
result =
kiParser.IsValid() &&
bar.Init(forSymbol, forPeriod, barIndex);
if (!result)
{
return result;
}
//
double iValue = kiHelper.GetMAFast(barIndex);
//
bool isBullish = bar.IsRejected(iValue, X_DIRECTION_BULLISH, false, false);
bool isBearish = bar.IsRejected(iValue, X_DIRECTION_BEARISH, false, false);
//
dir =
isBullish
? X_DIRECTION_BULLISH
: isBearish
? X_DIRECTION_BEARISH
: X_DIRECTION_NONE;
//
result = HasDirection(dir);
//
bar.Clean();
//
return result;
}
bool IsMASlowRejected(
ENUM_X_DIRECTION &dir,
int barIndex = 0,
string forSymbol = NULL,
ENUM_TIMEFRAMES forPeriod = NULL //
)
{
//
bool result = false;
//
dir = X_DIRECTION_NONE;
if (!IsXValid(forSymbol))
{
forSymbol = symbol;
}
if (!IsXValid(forPeriod))
{
forPeriod = period;
}
barIndex = kiParser.NormalizeBarIndex(barIndex);
//
XOHCL bar;
result =
kiParser.IsValid() &&
bar.Init(forSymbol, forPeriod, barIndex);
if (!result)
{
return result;
}
//
double iValue = kiHelper.GetMASlow(barIndex);
//
bool isBullish = bar.IsRejected(iValue, X_DIRECTION_BULLISH, false, false);
bool isBearish = bar.IsRejected(iValue, X_DIRECTION_BEARISH, false, false);
//
dir =
isBullish
? X_DIRECTION_BULLISH
: isBearish
? X_DIRECTION_BEARISH
: X_DIRECTION_NONE;
//
result = HasDirection(dir);
//
bar.Clean();
//
return result;
}
bool IsMASuperSlowRejected(
ENUM_X_DIRECTION &dir,
int barIndex = 0,
string forSymbol = NULL,
ENUM_TIMEFRAMES forPeriod = NULL //
)
{
//
bool result = false;
//
dir = X_DIRECTION_NONE;
if (!IsXValid(forSymbol))
{
forSymbol = symbol;
}
if (!IsXValid(forPeriod))
{
forPeriod = period;
}
barIndex = kiParser.NormalizeBarIndex(barIndex);
//
XOHCL bar;
result =
kiParser.IsValid() &&
bar.Init(forSymbol, forPeriod, barIndex);
if (!result)
{
return result;
}
//
double iValue = kiHelper.GetMASuperSlow(barIndex);
//
bool isBullish = bar.IsRejected(iValue, X_DIRECTION_BULLISH, false, false);
bool isBearish = bar.IsRejected(iValue, X_DIRECTION_BEARISH, false, false);
//
dir =
isBullish
? X_DIRECTION_BULLISH
: isBearish
? X_DIRECTION_BEARISH
: X_DIRECTION_NONE;
//
result = HasDirection(dir);
//
bar.Clean();
//
return result;
}
bool IsPrevPeakRejected(
ENUM_X_DIRECTION &dir,
int barIndex = 0,
string forSymbol = NULL,
ENUM_TIMEFRAMES forPeriod = NULL //
)
{
//
bool result = false;
//
dir = X_DIRECTION_NONE;
if (!IsXValid(forSymbol))
{
forSymbol = symbol;
}
if (!IsXValid(forPeriod))
{
forPeriod = period;
}
barIndex = kiParser.NormalizeBarIndex(barIndex);
//
XOHCL bar;
result =
kiParser.IsValid() &&
bar.Init(forSymbol, forPeriod, barIndex);
if (!result)
{
return result;
}
//
double iValue = kiHelper.GetPeak(barIndex + 1);
//
bool isBullish = bar.IsRejected(iValue, X_DIRECTION_BULLISH, false, false);
bool isBearish = bar.IsRejected(iValue, X_DIRECTION_BEARISH, false, false);
//
dir =
isBullish
? X_DIRECTION_BULLISH
: isBearish
? X_DIRECTION_BEARISH
: X_DIRECTION_NONE;
//
result = HasDirection(dir);
//
bar.Clean();
//
return result;
}
bool IsPrevValeRejected(
ENUM_X_DIRECTION &dir,
int barIndex = 0,
string forSymbol = NULL,
ENUM_TIMEFRAMES forPeriod = NULL //
)
{
//
bool result = false;
//
dir = X_DIRECTION_NONE;
if (!IsXValid(forSymbol))
{
forSymbol = symbol;
}
if (!IsXValid(forPeriod))
{
forPeriod = period;
}
barIndex = kiParser.NormalizeBarIndex(barIndex);
//
XOHCL bar;
result =
kiParser.IsValid() &&
bar.Init(forSymbol, forPeriod, barIndex);
if (!result)
{
return result;
}
//
double iValue = kiHelper.GetVale(barIndex + 1);
//
bool isBullish = bar.IsRejected(iValue, X_DIRECTION_BULLISH, false, false);
bool isBearish = bar.IsRejected(iValue, X_DIRECTION_BEARISH, false, false);
//
dir =
isBullish
? X_DIRECTION_BULLISH
: isBearish
? X_DIRECTION_BEARISH
: X_DIRECTION_NONE;
//
result = HasDirection(dir);
//
bar.Clean();
//
return result;
}
// #endregion
// #region Counters ...
int CountKIFastRejects(
int barIndex = 0,
int loopback = 10,
ENUM_X_DIRECTION forDir = X_DIRECTION_NONE,
string forSymbol = NULL,
ENUM_TIMEFRAMES forPeriod = NULL //
)
{
//
int result = 0;
//
loopback = NormalizeInt(loopback, 2);
barIndex = kiParser.NormalizeBarIndex(barIndex);
//
bool isBullish = !HasDirection(forDir) || IsXBullish(forDir);
bool isBearish = !HasDirection(forDir) || IsXBearish(forDir);
//
bool is = false;
bool hasBullish = false;
bool hasBearish = false;
ENUM_X_DIRECTION tmpDir;
for (int i = barIndex; i < barIndex + loopback; i++)
{
//
is = IsKIFastRejected(
tmpDir,
i,
forSymbol,
forPeriod //
);
hasBullish = is && IsXBullish(tmpDir);
hasBearish = is && IsXBearish(tmpDir);
//
if ((isBullish && hasBullish) ||
(isBearish && hasBearish))
{
result++;
}
}
//
return result;
}
int CountKISlowRejects(
int barIndex = 0,
int loopback = 10,
ENUM_X_DIRECTION forDir = X_DIRECTION_NONE,
string forSymbol = NULL,
ENUM_TIMEFRAMES forPeriod = NULL //
)
{
//
int result = 0;
//
loopback = NormalizeInt(loopback, 2);
barIndex = kiParser.NormalizeBarIndex(barIndex);
//
bool isBullish = !HasDirection(forDir) || IsXBullish(forDir);
bool isBearish = !HasDirection(forDir) || IsXBearish(forDir);
//
bool is = false;
bool hasBullish = false;
bool hasBearish = false;
ENUM_X_DIRECTION tmpDir;
for (int i = barIndex; i < barIndex + loopback; i++)
{
//
is = IsKISlowRejected(
tmpDir,
i,
forSymbol,
forPeriod //
);
hasBullish = is && IsXBullish(tmpDir);
hasBearish = is && IsXBearish(tmpDir);
//
if ((isBullish && hasBullish) ||
(isBearish && hasBearish))
{
result++;
}
}
//
return result;
}
int CountKISuperSlowRejects(
int barIndex = 0,
int loopback = 10,
ENUM_X_DIRECTION forDir = X_DIRECTION_NONE,
string forSymbol = NULL,
ENUM_TIMEFRAMES forPeriod = NULL //
)
{
//
int result = 0;
//
loopback = NormalizeInt(loopback, 2);
barIndex = kiParser.NormalizeBarIndex(barIndex);
//
bool isBullish = !HasDirection(forDir) || IsXBullish(forDir);
bool isBearish = !HasDirection(forDir) || IsXBearish(forDir);
//
bool is = false;
bool hasBullish = false;
bool hasBearish = false;
ENUM_X_DIRECTION tmpDir;
for (int i = barIndex; i < barIndex + loopback; i++)
{
//
is = IsKISuperSlowRejected(
tmpDir,
i,
forSymbol,
forPeriod //
);
hasBullish = is && IsXBullish(tmpDir);
hasBearish = is && IsXBearish(tmpDir);
//
if ((isBullish && hasBullish) ||
(isBearish && hasBearish))
{
result++;
}
}
//
return result;
}
int CountKIUpperRejects(
int barIndex = 0,
int loopback = 10,
ENUM_X_DIRECTION forDir = X_DIRECTION_NONE,
string forSymbol = NULL,
ENUM_TIMEFRAMES forPeriod = NULL //
)
{
//
int result = 0;
//
loopback = NormalizeInt(loopback, 2);
barIndex = kiParser.NormalizeBarIndex(barIndex);
//
bool isBullish = !HasDirection(forDir) || IsXBullish(forDir);
bool isBearish = !HasDirection(forDir) || IsXBearish(forDir);
//
bool is = false;
bool hasBullish = false;
bool hasBearish = false;
ENUM_X_DIRECTION tmpDir;
for (int i = barIndex; i < barIndex + loopback; i++)
{
//
is = IsKIUpperRejected(
tmpDir,
i,
forSymbol,
forPeriod //
);
hasBullish = is && IsXBullish(tmpDir);
hasBearish = is && IsXBearish(tmpDir);
//
if ((isBullish && hasBullish) ||
(isBearish && hasBearish))
{
result++;
}
}
//
return result;
}
int CountKILowerRejects(
int barIndex = 0,
int loopback = 10,
ENUM_X_DIRECTION forDir = X_DIRECTION_NONE,
string forSymbol = NULL,
ENUM_TIMEFRAMES forPeriod = NULL //
)
{
//
int result = 0;
//
loopback = NormalizeInt(loopback, 2);
barIndex = kiParser.NormalizeBarIndex(barIndex);
//
bool isBullish = !HasDirection(forDir) || IsXBullish(forDir);
bool isBearish = !HasDirection(forDir) || IsXBearish(forDir);
//
bool is = false;
bool hasBullish = false;
bool hasBearish = false;
ENUM_X_DIRECTION tmpDir;
for (int i = barIndex; i < barIndex + loopback; i++)
{
//
is = IsKILowerRejected(
tmpDir,
i,
forSymbol,
forPeriod //
);
hasBullish = is && IsXBullish(tmpDir);
hasBearish = is && IsXBearish(tmpDir);
//
if ((isBullish && hasBullish) ||
(isBearish && hasBearish))
{
result++;
}
}
//
return result;
}
int CountMAFastRejects(
int barIndex = 0,
int loopback = 10,
ENUM_X_DIRECTION forDir = X_DIRECTION_NONE,
string forSymbol = NULL,
ENUM_TIMEFRAMES forPeriod = NULL //
)
{
//
int result = 0;
//
loopback = NormalizeInt(loopback, 2);
barIndex = kiParser.NormalizeBarIndex(barIndex);
//
bool isBullish = !HasDirection(forDir) || IsXBullish(forDir);
bool isBearish = !HasDirection(forDir) || IsXBearish(forDir);
//
bool is = false;
bool hasBullish = false;
bool hasBearish = false;
ENUM_X_DIRECTION tmpDir;
for (int i = barIndex; i < barIndex + loopback; i++)
{
//
is = IsMAFastRejected(
tmpDir,
i,
forSymbol,
forPeriod //
);
hasBullish = is && IsXBullish(tmpDir);
hasBearish = is && IsXBearish(tmpDir);
//
if ((isBullish && hasBullish) ||
(isBearish && hasBearish))
{
result++;
}
}
//
return result;
}
int CountMASlowRejects(
int barIndex = 0,
int loopback = 10,
ENUM_X_DIRECTION forDir = X_DIRECTION_NONE,
string forSymbol = NULL,
ENUM_TIMEFRAMES forPeriod = NULL //
)
{
//
int result = 0;
//
loopback = NormalizeInt(loopback, 2);
barIndex = kiParser.NormalizeBarIndex(barIndex);
//
bool isBullish = !HasDirection(forDir) || IsXBullish(forDir);
bool isBearish = !HasDirection(forDir) || IsXBearish(forDir);
//
bool is = false;
bool hasBullish = false;
bool hasBearish = false;
ENUM_X_DIRECTION tmpDir;
for (int i = barIndex; i < barIndex + loopback; i++)
{
//
is = IsMASlowRejected(
tmpDir,
i,
forSymbol,
forPeriod //
);
hasBullish = is && IsXBullish(tmpDir);
hasBearish = is && IsXBearish(tmpDir);
//
if ((isBullish && hasBullish) ||
(isBearish && hasBearish))
{
result++;
}
}
//
return result;
}
int CountMASuperSlowRejects(
int barIndex = 0,
int loopback = 10,
ENUM_X_DIRECTION forDir = X_DIRECTION_NONE,
string forSymbol = NULL,
ENUM_TIMEFRAMES forPeriod = NULL //
)
{
//
int result = 0;
//
loopback = NormalizeInt(loopback, 2);
barIndex = kiParser.NormalizeBarIndex(barIndex);
//
bool isBullish = !HasDirection(forDir) || IsXBullish(forDir);
bool isBearish = !HasDirection(forDir) || IsXBearish(forDir);
//
bool is = false;
bool hasBullish = false;
bool hasBearish = false;
ENUM_X_DIRECTION tmpDir;
for (int i = barIndex; i < barIndex + loopback; i++)
{
//
is = IsMASuperSlowRejected(
tmpDir,
i,
forSymbol,
forPeriod //
);
hasBullish = is && IsXBullish(tmpDir);
hasBearish = is && IsXBearish(tmpDir);
//
if ((isBullish && hasBullish) ||
(isBearish && hasBearish))
{
result++;
}
}
//
return result;
}
int CountPrevPeakRejects(
int barIndex = 0,
int loopback = 10,
ENUM_X_DIRECTION forDir = X_DIRECTION_NONE,
string forSymbol = NULL,
ENUM_TIMEFRAMES forPeriod = NULL //
)
{
//
int result = 0;
//
loopback = NormalizeInt(loopback, 2);
barIndex = kiParser.NormalizeBarIndex(barIndex);
//
bool isBullish = !HasDirection(forDir) || IsXBullish(forDir);
bool isBearish = !HasDirection(forDir) || IsXBearish(forDir);
//
bool is = false;
bool hasBullish = false;
bool hasBearish = false;
ENUM_X_DIRECTION tmpDir;
for (int i = barIndex; i < barIndex + loopback; i++)
{
//
is = IsPrevPeakRejected(
tmpDir,
i,
forSymbol,
forPeriod //
);
hasBullish = is && IsXBullish(tmpDir);
hasBearish = is && IsXBearish(tmpDir);
//
if ((isBullish && hasBullish) ||
(isBearish && hasBearish))
{
result++;
}
}
//
return result;
}
int CountPrevValeRejects(
int barIndex = 0,
int loopback = 10,
ENUM_X_DIRECTION forDir = X_DIRECTION_NONE,
string forSymbol = NULL,
ENUM_TIMEFRAMES forPeriod = NULL //
)
{
//
int result = 0;
//
loopback = NormalizeInt(loopback, 2);
barIndex = kiParser.NormalizeBarIndex(barIndex);
//
bool isBullish = !HasDirection(forDir) || IsXBullish(forDir);
bool isBearish = !HasDirection(forDir) || IsXBearish(forDir);
//
bool is = false;
bool hasBullish = false;
bool hasBearish = false;
ENUM_X_DIRECTION tmpDir;
for (int i = barIndex; i < barIndex + loopback; i++)
{
//
is = IsPrevValeRejected(
tmpDir,
i,
forSymbol,
forPeriod //
);
hasBullish = is && IsXBullish(tmpDir);
hasBearish = is && IsXBearish(tmpDir);
//
if ((isBullish && hasBullish) ||
(isBearish && hasBearish))
{
result++;
}
}
//
return result;
}
// #endregion
//
// Others ...
/**
* Destroy ...
*/
void Destroy()
{
//
delete barAnalyser;
ZeroMemory(barAnalyser);
//
ZeroMemory(kiHelper);
ZeroMemory(kiParser);
}
//
// Testers ...
//
// Protected ...
protected:
//
// Props ...
//
// Private ...
private:
//
//
};
//