3489 lines
85 KiB
Plaintext
3489 lines
85 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 ...
|
|
int HasKIFastSwitch(
|
|
XDirectionShift &switches[],
|
|
int barIndex = 0,
|
|
int loopback = 10,
|
|
ENUM_X_DIRECTION forDir = X_DIRECTION_NONE //
|
|
)
|
|
{
|
|
//
|
|
int result = 0;
|
|
|
|
//
|
|
XClean(switches);
|
|
|
|
//
|
|
loopback = NormalizeInt(loopback, 2);
|
|
barIndex = kiParser.NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
bool isBullish = !HasDirection(forDir) || IsXBullish(forDir);
|
|
bool isBearish = !HasDirection(forDir) || IsXBearish(forDir);
|
|
|
|
//
|
|
bool has = false;
|
|
XDirectionShift iShift;
|
|
for (int i = barIndex; i < barIndex + loopback; i++)
|
|
{
|
|
//
|
|
// Bullish ...
|
|
bool hasBullish = kiParser.IsKIFastSwitchedToBullish(i);
|
|
has = hasBullish && isBullish;
|
|
if (has)
|
|
{
|
|
//
|
|
iShift.Clean();
|
|
has = iShift.Init(
|
|
ToXString(X121_XKI_FAST),
|
|
GetBarTime(symbol, period, i),
|
|
kiHelper.GetKIFast(i),
|
|
kiHelper.GetKIFast(i + 1),
|
|
symbol,
|
|
period,
|
|
X_DIRECTION_BULLISH //
|
|
);
|
|
if (has)
|
|
{
|
|
//
|
|
AddIfNotExists(
|
|
iShift,
|
|
switches //
|
|
);
|
|
|
|
//
|
|
iShift.Clean();
|
|
}
|
|
}
|
|
|
|
//
|
|
// Bearish ...
|
|
bool hasBearish = kiParser.IsKIFastSwitchedToBearish(i);
|
|
has = hasBearish && isBearish;
|
|
if (has)
|
|
{
|
|
//
|
|
iShift.Clean();
|
|
has = iShift.Init(
|
|
ToXString(X121_XKI_FAST),
|
|
GetBarTime(symbol, period, i),
|
|
kiHelper.GetKIFast(i),
|
|
kiHelper.GetKIFast(i + 1),
|
|
symbol,
|
|
period,
|
|
X_DIRECTION_BEARISH //
|
|
);
|
|
if (has)
|
|
{
|
|
//
|
|
AddIfNotExists(
|
|
iShift,
|
|
switches //
|
|
);
|
|
|
|
//
|
|
iShift.Clean();
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
result = ArraySize(switches);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
int HasKISlowSwitch(
|
|
XDirectionShift &switches[],
|
|
int barIndex = 0,
|
|
int loopback = 10,
|
|
ENUM_X_DIRECTION forDir = X_DIRECTION_NONE //
|
|
)
|
|
{
|
|
//
|
|
int result = 0;
|
|
|
|
//
|
|
XClean(switches);
|
|
|
|
//
|
|
loopback = NormalizeInt(loopback, 2);
|
|
barIndex = kiParser.NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
bool isBullish = !HasDirection(forDir) || IsXBullish(forDir);
|
|
bool isBearish = !HasDirection(forDir) || IsXBearish(forDir);
|
|
|
|
//
|
|
bool has = false;
|
|
XDirectionShift iShift;
|
|
for (int i = barIndex; i < barIndex + loopback; i++)
|
|
{
|
|
//
|
|
// Bullish ...
|
|
bool hasBullish = kiParser.IsKISlowSwitchedToBullish(i);
|
|
has = hasBullish && isBullish;
|
|
if (has)
|
|
{
|
|
//
|
|
iShift.Clean();
|
|
has = iShift.Init(
|
|
ToXString(X121_XKI_SLOW),
|
|
GetBarTime(symbol, period, i),
|
|
kiHelper.GetKISlow(i),
|
|
kiHelper.GetKISlow(i + 1),
|
|
symbol,
|
|
period,
|
|
X_DIRECTION_BULLISH //
|
|
);
|
|
if (has)
|
|
{
|
|
//
|
|
AddIfNotExists(
|
|
iShift,
|
|
switches //
|
|
);
|
|
|
|
//
|
|
iShift.Clean();
|
|
}
|
|
}
|
|
|
|
//
|
|
// Bearish ...
|
|
bool hasBearish = kiParser.IsKISlowSwitchedToBearish(i);
|
|
has = hasBearish && isBearish;
|
|
if (has)
|
|
{
|
|
//
|
|
iShift.Clean();
|
|
has = iShift.Init(
|
|
ToXString(X121_XKI_SLOW),
|
|
GetBarTime(symbol, period, i),
|
|
kiHelper.GetKIFast(i),
|
|
kiHelper.GetKIFast(i + 1),
|
|
symbol,
|
|
period,
|
|
X_DIRECTION_BEARISH //
|
|
);
|
|
if (has)
|
|
{
|
|
//
|
|
AddIfNotExists(
|
|
iShift,
|
|
switches //
|
|
);
|
|
|
|
//
|
|
iShift.Clean();
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
result = ArraySize(switches);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
int HasKISuperSlowSwitch(
|
|
XDirectionShift &switches[],
|
|
int barIndex = 0,
|
|
int loopback = 10,
|
|
ENUM_X_DIRECTION forDir = X_DIRECTION_NONE //
|
|
)
|
|
{
|
|
//
|
|
int result = 0;
|
|
|
|
//
|
|
XClean(switches);
|
|
|
|
//
|
|
loopback = NormalizeInt(loopback, 2);
|
|
barIndex = kiParser.NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
bool isBullish = !HasDirection(forDir) || IsXBullish(forDir);
|
|
bool isBearish = !HasDirection(forDir) || IsXBearish(forDir);
|
|
|
|
//
|
|
bool has = false;
|
|
XDirectionShift iShift;
|
|
for (int i = barIndex; i < barIndex + loopback; i++)
|
|
{
|
|
//
|
|
// Bullish ...
|
|
bool hasBullish = kiParser.IsKISuperSlowSwitchedToBullish(i);
|
|
has = hasBullish && isBullish;
|
|
if (has)
|
|
{
|
|
//
|
|
iShift.Clean();
|
|
has = iShift.Init(
|
|
ToXString(X121_XKI_SUPER_SLOW),
|
|
GetBarTime(symbol, period, i),
|
|
kiHelper.GetKISuperSlow(i),
|
|
kiHelper.GetKISuperSlow(i + 1),
|
|
symbol,
|
|
period,
|
|
X_DIRECTION_BULLISH //
|
|
);
|
|
if (has)
|
|
{
|
|
//
|
|
AddIfNotExists(
|
|
iShift,
|
|
switches //
|
|
);
|
|
|
|
//
|
|
iShift.Clean();
|
|
}
|
|
}
|
|
|
|
//
|
|
// Bearish ...
|
|
bool hasBearish = kiParser.IsKISuperSlowSwitchedToBearish(i);
|
|
has = hasBearish && isBearish;
|
|
if (has)
|
|
{
|
|
//
|
|
iShift.Clean();
|
|
has = iShift.Init(
|
|
ToXString(X121_XKI_SUPER_SLOW),
|
|
GetBarTime(symbol, period, i),
|
|
kiHelper.GetKIFast(i),
|
|
kiHelper.GetKIFast(i + 1),
|
|
symbol,
|
|
period,
|
|
X_DIRECTION_BEARISH //
|
|
);
|
|
if (has)
|
|
{
|
|
//
|
|
AddIfNotExists(
|
|
iShift,
|
|
switches //
|
|
);
|
|
|
|
//
|
|
iShift.Clean();
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
result = ArraySize(switches);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
int HasKIWaveSwitch(
|
|
XDirectionShift &switches[],
|
|
int barIndex = 0,
|
|
int loopback = 10,
|
|
ENUM_X_DIRECTION forDir = X_DIRECTION_NONE //
|
|
)
|
|
{
|
|
//
|
|
int result = 0;
|
|
|
|
//
|
|
XClean(switches);
|
|
|
|
//
|
|
loopback = NormalizeInt(loopback, 2);
|
|
barIndex = kiParser.NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
bool isBullish = !HasDirection(forDir) || IsXBullish(forDir);
|
|
bool isBearish = !HasDirection(forDir) || IsXBearish(forDir);
|
|
|
|
//
|
|
bool has = false;
|
|
XDirectionShift iShift;
|
|
for (int i = barIndex; i < barIndex + loopback; i++)
|
|
{
|
|
//
|
|
// Bullish ...
|
|
bool hasBullish = kiParser.IsKIWaveSwitchedToBullish(i);
|
|
has = hasBullish && isBullish;
|
|
if (has)
|
|
{
|
|
//
|
|
iShift.Clean();
|
|
has = iShift.Init(
|
|
ToXString(X121_XKI_WAVE),
|
|
GetBarTime(symbol, period, i),
|
|
kiHelper.GetKIWave(i),
|
|
kiHelper.GetKIWave(i + 1),
|
|
symbol,
|
|
period,
|
|
X_DIRECTION_BULLISH //
|
|
);
|
|
if (has)
|
|
{
|
|
//
|
|
AddIfNotExists(
|
|
iShift,
|
|
switches //
|
|
);
|
|
|
|
//
|
|
iShift.Clean();
|
|
}
|
|
}
|
|
|
|
//
|
|
// Bearish ...
|
|
bool hasBearish = kiParser.IsKIWaveSwitchedToBearish(i);
|
|
has = hasBearish && isBearish;
|
|
if (has)
|
|
{
|
|
//
|
|
iShift.Clean();
|
|
has = iShift.Init(
|
|
ToXString(X121_XKI_WAVE),
|
|
GetBarTime(symbol, period, i),
|
|
kiHelper.GetKIWave(i),
|
|
kiHelper.GetKIWave(i + 1),
|
|
symbol,
|
|
period,
|
|
X_DIRECTION_BEARISH //
|
|
);
|
|
if (has)
|
|
{
|
|
//
|
|
AddIfNotExists(
|
|
iShift,
|
|
switches //
|
|
);
|
|
|
|
//
|
|
iShift.Clean();
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
result = ArraySize(switches);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
int HasMAFastSwitch(
|
|
XDirectionShift &switches[],
|
|
int barIndex = 0,
|
|
int loopback = 10,
|
|
ENUM_X_DIRECTION forDir = X_DIRECTION_NONE //
|
|
)
|
|
{
|
|
//
|
|
int result = 0;
|
|
|
|
//
|
|
XClean(switches);
|
|
|
|
//
|
|
loopback = NormalizeInt(loopback, 2);
|
|
barIndex = kiParser.NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
bool isBullish = !HasDirection(forDir) || IsXBullish(forDir);
|
|
bool isBearish = !HasDirection(forDir) || IsXBearish(forDir);
|
|
|
|
//
|
|
bool has = false;
|
|
XDirectionShift iShift;
|
|
for (int i = barIndex; i < barIndex + loopback; i++)
|
|
{
|
|
//
|
|
// Bullish ...
|
|
bool hasBullish = kiParser.IsMAFastSwitchedToBullish(i);
|
|
has = hasBullish && isBullish;
|
|
if (has)
|
|
{
|
|
//
|
|
iShift.Clean();
|
|
has = iShift.Init(
|
|
ToXString(X121_XKI_MA_FAST),
|
|
GetBarTime(symbol, period, i),
|
|
kiHelper.GetMAFast(i),
|
|
kiHelper.GetMAFast(i + 1),
|
|
symbol,
|
|
period,
|
|
X_DIRECTION_BULLISH //
|
|
);
|
|
if (has)
|
|
{
|
|
//
|
|
AddIfNotExists(
|
|
iShift,
|
|
switches //
|
|
);
|
|
|
|
//
|
|
iShift.Clean();
|
|
}
|
|
}
|
|
|
|
//
|
|
// Bearish ...
|
|
bool hasBearish = kiParser.IsMAFastSwitchedToBearish(i);
|
|
has = hasBearish && isBearish;
|
|
if (has)
|
|
{
|
|
//
|
|
iShift.Clean();
|
|
has = iShift.Init(
|
|
ToXString(X121_XKI_MA_FAST),
|
|
GetBarTime(symbol, period, i),
|
|
kiHelper.GetMAFast(i),
|
|
kiHelper.GetMAFast(i + 1),
|
|
symbol,
|
|
period,
|
|
X_DIRECTION_BEARISH //
|
|
);
|
|
if (has)
|
|
{
|
|
//
|
|
AddIfNotExists(
|
|
iShift,
|
|
switches //
|
|
);
|
|
|
|
//
|
|
iShift.Clean();
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
result = ArraySize(switches);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
int HasMASlowSwitch(
|
|
XDirectionShift &switches[],
|
|
int barIndex = 0,
|
|
int loopback = 10,
|
|
ENUM_X_DIRECTION forDir = X_DIRECTION_NONE //
|
|
)
|
|
{
|
|
//
|
|
int result = 0;
|
|
|
|
//
|
|
XClean(switches);
|
|
|
|
//
|
|
loopback = NormalizeInt(loopback, 2);
|
|
barIndex = kiParser.NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
bool isBullish = !HasDirection(forDir) || IsXBullish(forDir);
|
|
bool isBearish = !HasDirection(forDir) || IsXBearish(forDir);
|
|
|
|
//
|
|
bool has = false;
|
|
XDirectionShift iShift;
|
|
for (int i = barIndex; i < barIndex + loopback; i++)
|
|
{
|
|
//
|
|
// Bullish ...
|
|
bool hasBullish = kiParser.IsMASlowSwitchedToBullish(i);
|
|
has = hasBullish && isBullish;
|
|
if (has)
|
|
{
|
|
//
|
|
iShift.Clean();
|
|
has = iShift.Init(
|
|
ToXString(X121_XKI_MA_SLOW),
|
|
GetBarTime(symbol, period, i),
|
|
kiHelper.GetMASlow(i),
|
|
kiHelper.GetMASlow(i + 1),
|
|
symbol,
|
|
period,
|
|
X_DIRECTION_BULLISH //
|
|
);
|
|
if (has)
|
|
{
|
|
//
|
|
AddIfNotExists(
|
|
iShift,
|
|
switches //
|
|
);
|
|
|
|
//
|
|
iShift.Clean();
|
|
}
|
|
}
|
|
|
|
//
|
|
// Bearish ...
|
|
bool hasBearish = kiParser.IsMASlowSwitchedToBearish(i);
|
|
has = hasBearish && isBearish;
|
|
if (has)
|
|
{
|
|
//
|
|
iShift.Clean();
|
|
has = iShift.Init(
|
|
ToXString(X121_XKI_MA_SLOW),
|
|
GetBarTime(symbol, period, i),
|
|
kiHelper.GetMAFast(i),
|
|
kiHelper.GetMAFast(i + 1),
|
|
symbol,
|
|
period,
|
|
X_DIRECTION_BEARISH //
|
|
);
|
|
if (has)
|
|
{
|
|
//
|
|
AddIfNotExists(
|
|
iShift,
|
|
switches //
|
|
);
|
|
|
|
//
|
|
iShift.Clean();
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
result = ArraySize(switches);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
int HasMASuperSlowSwitch(
|
|
XDirectionShift &switches[],
|
|
int barIndex = 0,
|
|
int loopback = 10,
|
|
ENUM_X_DIRECTION forDir = X_DIRECTION_NONE //
|
|
)
|
|
{
|
|
//
|
|
int result = 0;
|
|
|
|
//
|
|
XClean(switches);
|
|
|
|
//
|
|
loopback = NormalizeInt(loopback, 2);
|
|
barIndex = kiParser.NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
bool isBullish = !HasDirection(forDir) || IsXBullish(forDir);
|
|
bool isBearish = !HasDirection(forDir) || IsXBearish(forDir);
|
|
|
|
//
|
|
bool has = false;
|
|
XDirectionShift iShift;
|
|
for (int i = barIndex; i < barIndex + loopback; i++)
|
|
{
|
|
//
|
|
// Bullish ...
|
|
bool hasBullish = kiParser.IsMASuperSlowSwitchedToBullish(i);
|
|
has = hasBullish && isBullish;
|
|
if (has)
|
|
{
|
|
//
|
|
iShift.Clean();
|
|
has = iShift.Init(
|
|
ToXString(X121_XKI_MA_SUPER_SLOW),
|
|
GetBarTime(symbol, period, i),
|
|
kiHelper.GetMASuperSlow(i),
|
|
kiHelper.GetMASuperSlow(i + 1),
|
|
symbol,
|
|
period,
|
|
X_DIRECTION_BULLISH //
|
|
);
|
|
if (has)
|
|
{
|
|
//
|
|
AddIfNotExists(
|
|
iShift,
|
|
switches //
|
|
);
|
|
|
|
//
|
|
iShift.Clean();
|
|
}
|
|
}
|
|
|
|
//
|
|
// Bearish ...
|
|
bool hasBearish = kiParser.IsMASuperSlowSwitchedToBearish(i);
|
|
has = hasBearish && isBearish;
|
|
if (has)
|
|
{
|
|
//
|
|
iShift.Clean();
|
|
has = iShift.Init(
|
|
ToXString(X121_XKI_MA_SUPER_SLOW),
|
|
GetBarTime(symbol, period, i),
|
|
kiHelper.GetMAFast(i),
|
|
kiHelper.GetMAFast(i + 1),
|
|
symbol,
|
|
period,
|
|
X_DIRECTION_BEARISH //
|
|
);
|
|
if (has)
|
|
{
|
|
//
|
|
AddIfNotExists(
|
|
iShift,
|
|
switches //
|
|
);
|
|
|
|
//
|
|
iShift.Clean();
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
result = ArraySize(switches);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
int HasMACrossedSwitch(
|
|
XDirectionShift &switches[],
|
|
int barIndex = 0,
|
|
int loopback = 10,
|
|
ENUM_X_DIRECTION forDir = X_DIRECTION_NONE //
|
|
)
|
|
{
|
|
//
|
|
int result = 0;
|
|
|
|
//
|
|
XClean(switches);
|
|
|
|
//
|
|
loopback = NormalizeInt(loopback, 2);
|
|
barIndex = kiParser.NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
bool isBullish = !HasDirection(forDir) || IsXBullish(forDir);
|
|
bool isBearish = !HasDirection(forDir) || IsXBearish(forDir);
|
|
|
|
//
|
|
bool has = false;
|
|
XDirectionShift iShift;
|
|
for (int i = barIndex; i < barIndex + loopback; i++)
|
|
{
|
|
//
|
|
// Bullish ...
|
|
bool hasBullish = kiParser.IsMAFastCrossedOverSlow(i);
|
|
has = hasBullish && isBullish;
|
|
if (has)
|
|
{
|
|
//
|
|
iShift.Clean();
|
|
has = iShift.Init(
|
|
ToXString(X121_XKI_MA_CROSS),
|
|
GetBarTime(symbol, period, i),
|
|
MathMin(kiHelper.GetMAFast(i), kiHelper.GetMASlow(i)),
|
|
MathMin(kiHelper.GetMAFast(i + 1), kiHelper.GetMASlow(i + 1)),
|
|
symbol,
|
|
period,
|
|
X_DIRECTION_BULLISH //
|
|
);
|
|
if (has)
|
|
{
|
|
//
|
|
AddIfNotExists(
|
|
iShift,
|
|
switches //
|
|
);
|
|
|
|
//
|
|
iShift.Clean();
|
|
}
|
|
}
|
|
|
|
//
|
|
// Bearish ...
|
|
bool hasBearish = kiParser.IsMAFastCrossedUnderSlow(i);
|
|
has = hasBearish && isBearish;
|
|
if (has)
|
|
{
|
|
//
|
|
iShift.Clean();
|
|
has = iShift.Init(
|
|
ToXString(X121_XKI_MA_CROSS),
|
|
GetBarTime(symbol, period, i),
|
|
MathMin(kiHelper.GetMAFast(i), kiHelper.GetMASlow(i)),
|
|
MathMin(kiHelper.GetMAFast(i + 1), kiHelper.GetMASlow(i + 1)),
|
|
symbol,
|
|
period,
|
|
X_DIRECTION_BEARISH //
|
|
);
|
|
if (has)
|
|
{
|
|
//
|
|
AddIfNotExists(
|
|
iShift,
|
|
switches //
|
|
);
|
|
|
|
//
|
|
iShift.Clean();
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
result = ArraySize(switches);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
int HasATRVolatilitySwitch(
|
|
XDirectionShift &switches[],
|
|
int barIndex = 0,
|
|
int loopback = 10,
|
|
ENUM_X_DIRECTION forDir = X_DIRECTION_NONE //
|
|
)
|
|
{
|
|
//
|
|
int result = 0;
|
|
|
|
//
|
|
XClean(switches);
|
|
|
|
//
|
|
loopback = NormalizeInt(loopback, 2);
|
|
barIndex = kiParser.NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
bool isBullish = !HasDirection(forDir) || IsXBullish(forDir);
|
|
bool isBearish = !HasDirection(forDir) || IsXBearish(forDir);
|
|
|
|
//
|
|
bool has = false;
|
|
XDirectionShift iShift;
|
|
for (int i = barIndex; i < barIndex + loopback; i++)
|
|
{
|
|
//
|
|
// Bullish ...
|
|
bool hasBullish = kiParser.IsVolatilitySwitchdToHigh(i);
|
|
has = hasBullish && isBullish;
|
|
if (has)
|
|
{
|
|
//
|
|
iShift.Clean();
|
|
has = iShift.Init(
|
|
ToXString(X121_XKI_ATR),
|
|
GetBarTime(symbol, period, i),
|
|
kiHelper.GetATR(i),
|
|
kiHelper.GetATR(i + 1),
|
|
symbol,
|
|
period,
|
|
X_DIRECTION_BULLISH //
|
|
);
|
|
if (has)
|
|
{
|
|
//
|
|
AddIfNotExists(
|
|
iShift,
|
|
switches //
|
|
);
|
|
|
|
//
|
|
iShift.Clean();
|
|
}
|
|
}
|
|
|
|
//
|
|
// Bearish ...
|
|
bool hasBearish = kiParser.IsVolatilitySwitchdToLow(i);
|
|
has = hasBearish && isBearish;
|
|
if (has)
|
|
{
|
|
//
|
|
iShift.Clean();
|
|
has = iShift.Init(
|
|
ToXString(X121_XKI_ATR),
|
|
GetBarTime(symbol, period, i),
|
|
kiHelper.GetATR(i),
|
|
kiHelper.GetATR(i + 1),
|
|
symbol,
|
|
period,
|
|
X_DIRECTION_BEARISH //
|
|
);
|
|
if (has)
|
|
{
|
|
//
|
|
AddIfNotExists(
|
|
iShift,
|
|
switches //
|
|
);
|
|
|
|
//
|
|
iShift.Clean();
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
result = ArraySize(switches);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
// #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:
|
|
//
|
|
|
|
//
|
|
};
|
|
|
|
// |