Files
MQL5Data/XCAEA/Classes/xcaea.x-poi.detector.class.mq5
T
2025-04-18 09:26:32 +03:30

1927 lines
49 KiB
Plaintext

///////////////////////////////////////////////////////
//
// SaherElm IT Center MQL5 Indicator
// -------------------------------------------------
// Name: XCXCAEAPOIDetector ...
// Description: Class for XCAEA POI Detector ...
//
//
// Maintainer:
// ------------
// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com)
//
//////////////////////////////////////////////////////
//
// Global Properties ...
#property copyright "Copyright 2023, SaherElm IT Center"
#property link "https://saherelm.ir"
#property version "1.00"
#property description "SaherElm Class for XCAEA POI Detector"
#property strict
//
// Imports ...
#include "../../Classes/x-saherelm.x-bar.analyser.class.mq5"
#include "../../Classes/x-saherelm.x-poi.drawer.class.mq5"
#include "../Helpers/xcaea.helper.mq5"
//
// Definitions ...
//
enum ENUM_XCA_PIVOTS
{
XCA_NONE, // None
XCA_SWL, // SWL
XCA_SWH, // SWH
XCA_VALE, // VALE
XCA_PEAK, // PEAK
XCA_KI_BULL, // KIBull
XCA_KI_BEAR, // KIBear
XCA_TKI_BULL, // TKIBull
XCA_TKI_BEAR, // TKIBear
XCA_PEAKSWHRES, // PeakSWHRes
XCA_VALESWLSUP, // ValeSWLSup
XCA_TREND_BULL, // Trend Bullish
XCA_TREND_BEAR, // Trend Bearish
};
//
bool IsValid(ENUM_XCA_PIVOTS value)
{
//
bool result = false;
//
result = value != XCA_NONE;
//
return result;
}
//
string ToString(ENUM_XCA_PIVOTS value)
{
//
string result = NULL;
//
result = EnumToString(value);
//
return result;
}
//
struct XCAPivot
{
//
// Props ...
datetime to;
double value;
string symbol;
datetime from;
double reserve;
ENUM_XCA_PIVOTS type;
ENUM_TIMEFRAMES period;
//
double values[];
//
// Constructor ...
XCAPivot()
{
Clean();
}
//
// Tools ...
/**
* Cleanup ...
*/
void Clean()
{
//
value = 0;
to = NULL;
reserve = 0;
from = NULL;
symbol = NULL;
period = NULL;
type = XCA_NONE;
//
Clean(values);
}
/**
* Validate ...
*
* @return ( bool )
*/
bool IsValid()
{
//
bool result = false;
//
result =
from < to &&
value != 0 &&
IsValid(to) &&
IsValid(from) &&
IsValid(type) &&
IsValid(symbol) &&
IsValid(period);
//
return result;
}
/**
* Check a Model is Same as this or not ...
*
* @param pivot: XCAPivot ...
*
* @return ( bool )
*/
bool IsSameAs(XCAPivot &pivot)
{
//
bool result = false;
//
result =
IsValid() &&
pivot.IsValid();
if (!result)
{
return result;
}
//
result =
to == pivot.to &&
from == pivot.from &&
type == pivot.type &&
value == pivot.value &&
symbol == pivot.symbol &&
period == pivot.period;
//
return result;
}
/**
* Retrieve To Index ...
*
* @param forPeriod: ENUM_TIMEFRAMES, Specified Period ...
*
* @return ( int )
*/
int ToIndex(
ENUM_TIMEFRAMES forPeriod = NULL //
)
{
//
int result = -1;
//
if (!IsValid())
{
return result;
}
//
if (!IsValid(forPeriod))
{
forPeriod = period;
}
//
result = GetBarIndex(
symbol,
forPeriod,
to //
);
//
return result;
}
/**
* Retrieve From Index ...
*
* @param forPeriod: ENUM_TIMEFRAMES, Specified Period ...
*
* @return ( int )
*/
int FromIndex(
ENUM_TIMEFRAMES forPeriod = NULL //
)
{
//
int result = -1;
//
if (!IsValid())
{
return result;
}
//
if (!IsValid(forPeriod))
{
forPeriod = period;
}
//
result = GetBarIndex(
symbol,
forPeriod,
from //
);
//
return result;
}
/**
* Retrieve Age of Pivot ...
*
* @param forPeriod: ENUM_TIMEFRAMES, Specified Period ...
*
* @return ( int )
*/
int GetAge(
ENUM_TIMEFRAMES forPeriod = NULL //
)
{
//
int result = 0;
//
if (!IsValid())
{
return result;
}
//
if (!IsValid(forPeriod))
{
forPeriod = period;
}
//
int toIDX = ToIndex(forPeriod);
int fromIDX = FromIndex(forPeriod);
//
result = fromIDX - toIDX;
//
return result;
}
/**
* Converts Pivot to Box ...
*
* @param box: XBoxZone instance reference ...
*
* @return ( bool )
*/
bool AsBox(
XBoxZone &box //
)
{
//
bool result = false;
//
box.Clean();
//
result = IsValid();
if (!result)
{
return result;
}
//
ENUM_X_DIRECTION iDir = X_DIRECTION_NONE;
switch (type)
{
//
case XCA_SWL:
case XCA_VALE:
case XCA_KI_BULL:
case XCA_TKI_BULL:
case XCA_TREND_BULL:
case XCA_VALESWLSUP:
iDir = X_DIRECTION_BULLISH;
break;
//
case XCA_SWH:
case XCA_PEAK:
case XCA_KI_BEAR:
case XCA_TKI_BEAR:
case XCA_TREND_BEAR:
case XCA_PEAKSWHRES:
iDir = X_DIRECTION_BEARISH;
break;
}
//
result = HasDirection(iDir);
if (!result)
{
return result;
}
//
bool isBullish =
IsBullish(iDir) &&
value < reserve;
//
bool isBearish =
IsBearish(iDir) &&
value > reserve;
//
result = isBullish ||
isBearish;
if (!result)
{
return result;
}
//
box.to = to;
box.dir = iDir;
box.from = from;
box.symbol = symbol;
box.period = period;
//
string typeStr = ToString(type);
if (type == XCA_KI_BULL ||
type == XCA_KI_BEAR)
{
//
typeStr = "XCA_KI";
}
else if (type == XCA_TKI_BULL ||
type == XCA_TKI_BEAR)
{
//
typeStr = "XCA_TKI";
}
else if (type == XCA_TREND_BULL ||
type == XCA_TREND_BEAR)
{
//
typeStr = "XCA_TREND";
}
box.type = typeStr;
//
box.upper =
isBullish
? reserve
: value;
box.lower =
isBullish
? value
: reserve;
//
result = box.IsValid();
if (!result)
{
box.Clean();
}
//
return result;
}
//
};
/**
* Find Specified Pivot Index inside a Collection of Pivots ...
*
* @param pivot: XCAPivot instance Reference ...
* @param pivots: XCAPivot instance Reference Collection ...
*
* @return ( int )
*/
bool FindPivotIndex(
int &index,
XCAPivot &pivot,
XCAPivot &pivots[] //
)
{
//
bool result = false;
//
index = -1;
//
int count = ArraySize(pivots);
result = pivot.IsValid() &&
IsValidSize(count);
if (!result)
{
return result;
}
//
for (int i = 0; i < count; i++)
{
//
XCAPivot iPivot = pivots[i];
//
bool isSame = pivot.IsSameAs(iPivot);
if (isSame)
{
//
index = i;
break;
}
}
//
result = IsValidIndex(index);
//
return result;
}
//
// Implementations ...
class XCXCAEAPOIDetector : public XCBase
{
//
// Public ...
public:
//
// Props ...
XCAPivot swhPivots[];
XCAPivot swlPivots[];
XCAPivot peakPivots[];
XCAPivot valePivots[];
XCAPivot kiBullishPivots[];
XCAPivot kiBearishPivots[];
XCAPivot tkiBullishPivots[];
XCAPivot tkiBearishPivots[];
XCAPivot peakSWHResPivots[];
XCAPivot valeSWLSupPivots[];
XCAPivot trendBullishPivots[];
XCAPivot trendBearishPivots[];
//
// Constructors ...
XCXCAEAPOIDetector(
XCXCAEAHelper *_helper //
)
{
//
helper = _helper;
drawer = new XCPOIDrawer();
barAnalyser = new XCBarAnalyser();
//
Default();
}
//
// De Constructors ...
~XCXCAEAPOIDetector()
{
//
peakPivot.Clean();
Clean(peakPivots);
//
valePivot.Clean();
Clean(valePivots);
//
peakSWHResPivot.Clean();
Clean(peakSWHResPivots);
//
valeSWLSupPivot.Clean();
Clean(valeSWLSupPivots);
//
ZeroMemory(helper);
ZeroMemory(drawer);
ZeroMemory(barAnalyser);
}
//
// Properties ...
//
// Tools ...
virtual void Default()
{
//
maxAllowedPivots = 50;
pivotVerifications = 5;
}
//
void Update(
int barIndex = 0,
int loopback = 400 //
)
{
//
if (barIndex < 0)
{
barIndex = 0;
}
//
loopback = NormalizeInt(loopback, 400);
//
int count = 0;
bool has = false;
//
int zIDX = 0;
int cIDX = zIDX + 1;
int pIDX = cIDX + 1;
int p2IDX = pIDX + 1;
//
int index = barIndex;
int start = index;
int end = index + loopback;
while (start < end)
{
//
// Retrieve Conditions ...
XCAEAConditions iConditions;
has = helper.GetConditions(
iConditions,
start,
5 //
);
//
// Retrieve Bars ...
XOHCL zBar;
XOHCL cBar;
XOHCL pBar;
XOHCL p2Bar;
has = zBar.Init(
iConditions.symbol,
iConditions.period,
start //
);
has =
has &&
zBar.GetPreviousBar(cBar);
has =
has &&
cBar.GetPreviousBar(pBar);
has =
has &&
pBar.GetPreviousBar(p2Bar);
if (!has)
{
//
zBar.Clean();
cBar.Clean();
pBar.Clean();
p2Bar.Clean();
iConditions.Clean();
//
continue;
}
//
// Provide Some Conditions ...
//
double points = GetPoints(zBar.symbol);
//
// PEAK ...
//
double cPeak = iConditions.peakBuffer[cIDX];
double pPeak = iConditions.peakBuffer[pIDX];
double p2Peak = iConditions.peakBuffer[p2IDX];
//
bool isPeakStartSameLast =
cPeak == pPeak &&
pPeak != p2Peak;
//
bool isPeakFinishedSameLast =
cPeak != pPeak &&
pPeak == p2Peak;
//
// VALE ...
//
double cVale = iConditions.valeBuffer[cIDX];
double pVale = iConditions.valeBuffer[pIDX];
double p2Vale = iConditions.valeBuffer[p2IDX];
//
bool isValeStartSameLast =
cVale == pVale &&
pVale != p2Vale;
//
bool isValeFinishedSameLast =
cVale != pVale &&
pVale == p2Vale;
//
// SWH ...
//
double cSWH = iConditions.swingHighBuffer[cIDX];
double pSWH = iConditions.swingHighBuffer[pIDX];
double p2SWH = iConditions.swingHighBuffer[p2IDX];
//
bool isSWHStartSameLast =
cSWH == pSWH &&
pSWH != p2SWH;
//
bool isSWHFinishedSameLast =
cSWH != pSWH &&
pSWH == p2SWH;
//
// SWL ...
//
double pSWL = iConditions.swingLowBuffer[pIDX];
double cSWL = iConditions.swingLowBuffer[cIDX];
double p2SWL = iConditions.swingLowBuffer[p2IDX];
//
bool isSWLStartSameLast =
cSWL == pSWL &&
pSWL != p2SWL;
//
bool isSWLFinishedSameLast =
cSWL != pSWL &&
pSWL == p2SWL;
//
// SUPPORT ...
//
double cSupport = iConditions.supportBuffer[cIDX];
double pSupport = iConditions.supportBuffer[pIDX];
double p2Support = iConditions.supportBuffer[p2IDX];
//
bool isSupportStartSameLast =
cSupport == pSupport &&
pSupport != p2Support;
//
bool isSupportFinishedSameLast =
cSupport != pSupport &&
pSupport == p2Support;
//
// RESISTANCE ...
//
double pResistance = iConditions.resistanceBuffer[pIDX];
double cResistance = iConditions.resistanceBuffer[cIDX];
double p2Resistance = iConditions.resistanceBuffer[p2IDX];
//
bool isResistanceStartSameLast =
cResistance == pResistance &&
pResistance != p2Resistance;
//
bool isResistanceFinishedSameLast =
cResistance != pResistance &&
pResistance == p2Resistance;
//
// Checking Pivots ...
//
bool detectSWHPivot = true;
bool detectSWLPivot = true;
bool detectPeakPivot = true;
bool detectValePivot = true;
bool detectKIBullishPivot = true;
bool detectKIBearishPivot = true;
bool detectTKIBullishPivot = true;
bool detectTKIBearishPivot = true;
bool detectPeakSWHResPivot = true;
bool detectValeSWLSupPivot = true;
bool detectTrendBullishPivot = true;
bool detectTrendBearishPivot = true;
//
// Peak Pivot ...
if (detectPeakPivot)
{
//
if (!peakPivot.IsValid())
{
//
peakPivot.type = XCA_PEAK;
peakPivot.symbol = iConditions.symbol;
peakPivot.period = iConditions.period;
//
if (isPeakFinishedSameLast)
{
//
peakPivot.Clean();
//
peakPivot.type = XCA_PEAK;
peakPivot.symbol = iConditions.symbol;
peakPivot.period = iConditions.period;
//
peakPivot.to = pBar.time;
peakPivot.from = pBar.time;
peakPivot.value = iConditions.peakBuffer[pIDX];
peakPivot.reserve = iConditions.peakGoldenBuffer[pIDX];
}
}
//
if (iConditions.isPeakSameLast)
{
//
peakPivot.from = pBar.time;
//
peakPivot.reserve =
peakPivot.reserve == 0
? iConditions.peakGoldenBuffer[cIDX]
: MathMax(peakPivot.reserve, iConditions.peakGoldenBuffer[cIDX]);
}
//
if (isPeakStartSameLast)
{
//
has =
peakPivot.IsValid() &&
peakPivot.GetAge() >= pivotVerifications;
if (has)
{
//
AddPivot(
peakPivot,
peakPivots //
);
}
//
peakPivot.Clean();
}
}
//
// Vale Pivot ...
if (detectValePivot)
{
//
if (!valePivot.IsValid())
{
//
valePivot.type = XCA_VALE;
valePivot.symbol = iConditions.symbol;
valePivot.period = iConditions.period;
//
if (isValeFinishedSameLast)
{
//
valePivot.Clean();
//
valePivot.type = XCA_VALE;
valePivot.symbol = iConditions.symbol;
valePivot.period = iConditions.period;
//
valePivot.to = pBar.time;
valePivot.from = pBar.time;
valePivot.value = iConditions.valeBuffer[pIDX];
valePivot.reserve = iConditions.valeGoldenBuffer[pIDX];
}
}
//
if (iConditions.isValeSameLast)
{
//
valePivot.from = pBar.time;
//
valePivot.reserve =
valePivot.reserve == 0
? iConditions.valeGoldenBuffer[cIDX]
: MathMin(valePivot.reserve, iConditions.valeGoldenBuffer[cIDX]);
}
//
if (isValeStartSameLast)
{
//
has = valePivot.IsValid() &&
valePivot.GetAge() >= pivotVerifications;
if (has)
{
//
AddPivot(
valePivot,
valePivots //
);
}
//
valePivot.Clean();
}
}
//
// SWH Pivot ...
if (detectSWHPivot)
{
//
if (!swhPivot.IsValid())
{
//
swhPivot.type = XCA_SWH;
swhPivot.symbol = iConditions.symbol;
swhPivot.period = iConditions.period;
//
if (isSWHFinishedSameLast)
{
//
swhPivot.Clean();
//
swhPivot.type = XCA_SWH;
swhPivot.symbol = iConditions.symbol;
swhPivot.period = iConditions.period;
//
swhPivot.to = pBar.time;
swhPivot.from = pBar.time;
swhPivot.value = iConditions.swingHighBuffer[pIDX];
}
}
//
if (iConditions.isSwingHighSameLast)
{
//
swhPivot.from = pBar.time;
//
double reserve = swhPivot.reserve;
if (pBar.high == pSWH)
{
//
reserve =
reserve == 0
? pBar.GetUp()
: MathMin(reserve, pBar.GetUp());
}
swhPivot.reserve = reserve;
}
//
if (isSWHStartSameLast)
{
//
double reserve = swhPivot.reserve;
if (cBar.high == cSWH)
{
//
reserve =
reserve == 0
? cBar.GetUp()
: MathMin(reserve, cBar.GetUp());
}
if (pBar.high == pSWH)
{
//
reserve =
reserve == 0
? pBar.GetUp()
: MathMin(reserve, pBar.GetUp());
}
if (reserve == 0 || reserve == swhPivot.value)
{
reserve = swhPivot.value - (5 * points);
}
swhPivot.reserve = reserve;
//
has =
swhPivot.IsValid() &&
swhPivot.GetAge() >= pivotVerifications;
if (has)
{
//
AddPivot(
swhPivot,
swhPivots //
);
}
//
swhPivot.Clean();
}
}
//
// SWL Pivot ...
if (detectSWLPivot)
{
//
if (!swlPivot.IsValid())
{
//
swlPivot.type = XCA_SWL;
swlPivot.symbol = iConditions.symbol;
swlPivot.period = iConditions.period;
//
if (isSWLFinishedSameLast)
{
//
swlPivot.Clean();
//
swlPivot.type = XCA_SWL;
swlPivot.symbol = iConditions.symbol;
swlPivot.period = iConditions.period;
//
swlPivot.to = cBar.time;
swlPivot.from = pBar.time;
swlPivot.value = iConditions.swingLowBuffer[cIDX];
}
}
//
if (iConditions.isSwingLowSameLast)
{
//
swlPivot.from = pBar.time;
//
double reserve = swlPivot.reserve;
if (pBar.low == pSWL)
{
//
reserve =
reserve == 0
? pBar.GetDown()
: MathMax(reserve, pBar.GetDown());
}
swlPivot.reserve = reserve;
}
//
if (isSWLStartSameLast)
{
//
double reserve = swlPivot.reserve;
if (cBar.low == cSWL)
{
//
reserve =
reserve == 0
? cBar.GetDown()
: MathMax(reserve, cBar.GetDown());
}
if (pBar.low == pSWL)
{
//
reserve =
reserve == 0
? pBar.GetDown()
: MathMax(reserve, pBar.GetDown());
}
if (reserve == 0 || reserve == swlPivot.value)
{
reserve = swlPivot.value + (5 * points);
}
swlPivot.reserve = reserve;
//
has =
swlPivot.IsValid() &&
swlPivot.GetAge() >= pivotVerifications;
if (has)
{
//
AddPivot(
swlPivot,
swlPivots //
);
}
//
swlPivot.Clean();
}
}
//
// Peak SWH Res Pivot ...
if (detectPeakSWHResPivot)
{
//
if (!peakSWHResPivot.IsValid())
{
//
peakSWHResPivot.type = XCA_PEAKSWHRES;
peakSWHResPivot.symbol = iConditions.symbol;
peakSWHResPivot.period = iConditions.period;
//
if (iConditions.isPeakIsPivot && iConditions.isPeakSameLast)
{
//
peakSWHResPivot.to = cBar.time;
peakSWHResPivot.from = pBar.time;
peakSWHResPivot.value = iConditions.peakBuffer[cIDX];
}
}
//
if (iConditions.isPeakIsPivot && iConditions.isPeakSameLast)
{
//
peakSWHResPivot.from = pBar.time;
peakSWHResPivot.reserve =
peakSWHResPivot.reserve == 0
? iConditions.peakGoldenBuffer[cIDX]
: MathMax(peakSWHResPivot.reserve, iConditions.peakGoldenBuffer[cIDX]);
}
//
if (!(iConditions.isPeakIsPivot && iConditions.isPeakSameLast))
{
//
has = peakSWHResPivot.IsValid() &&
peakSWHResPivot.GetAge() >= pivotVerifications;
if (has)
{
//
AddPivot(
peakSWHResPivot,
peakSWHResPivots //
);
}
//
peakSWHResPivot.Clean();
}
}
//
// Vale SWL Sup Pivot ...
if (detectValeSWLSupPivot)
{
//
if (!valeSWLSupPivot.IsValid())
{
//
valeSWLSupPivot.type = XCA_VALESWLSUP;
valeSWLSupPivot.symbol = iConditions.symbol;
valeSWLSupPivot.period = iConditions.period;
//
if (iConditions.isValeIsPivot && iConditions.isValeSameLast)
{
//
valeSWLSupPivot.to = cBar.time;
valeSWLSupPivot.from = pBar.time;
valeSWLSupPivot.value = iConditions.valeBuffer[cIDX];
}
}
//
if (iConditions.isValeIsPivot && iConditions.isValeSameLast)
{
//
valeSWLSupPivot.from = pBar.time;
valeSWLSupPivot.reserve =
valeSWLSupPivot.reserve == 0
? iConditions.valeGoldenBuffer[cIDX]
: MathMin(valeSWLSupPivot.reserve, iConditions.valeGoldenBuffer[cIDX]);
}
//
if (!(iConditions.isValeIsPivot && iConditions.isValeSameLast))
{
//
has = valeSWLSupPivot.IsValid() &&
valeSWLSupPivot.GetAge() >= pivotVerifications;
if (has)
{
//
AddPivot(
valeSWLSupPivot,
valeSWLSupPivots //
);
}
//
valeSWLSupPivot.Clean();
}
}
//
// KI Bullish ...
if (detectKIBullishPivot)
{
//
if (!kiBullishPivot.IsValid())
{
//
kiBullishPivot.type = XCA_KI_BULL;
kiBullishPivot.symbol = iConditions.symbol;
kiBullishPivot.period = iConditions.period;
//
if (iConditions.isKISwitchedToBearish)
{
//
kiBullishPivot.Clean();
//
kiBullishPivot.type = XCA_KI_BULL;
kiBullishPivot.symbol = iConditions.symbol;
kiBullishPivot.period = iConditions.period;
//
kiBullishPivot.to = pBar.time;
kiBullishPivot.from = pBar.time;
kiBullishPivot.value = iConditions.kiBuffer[pIDX];
kiBullishPivot.reserve = iConditions.kiBuffer[pIDX];
}
}
//
if (iConditions.isKIBullish)
{
//
kiBullishPivot.from = cBar.time;
//
Add(
iConditions.kiBuffer[cIDX],
kiBullishPivot.values //
);
//
kiBullishPivot.value =
kiBullishPivot.value == 0
? iConditions.kiBuffer[cIDX]
: MathMin(iConditions.kiBuffer[cIDX], kiBullishPivot.value);
//
kiBullishPivot.reserve =
kiBullishPivot.reserve == 0
? iConditions.kiBuffer[cIDX]
: MathMax(iConditions.kiBuffer[cIDX], kiBullishPivot.reserve);
}
//
if (iConditions.isKISwitchedToBullish)
{
//
has =
kiBullishPivot.IsValid() &&
kiBullishPivot.GetAge() >= pivotVerifications;
if (has)
{
//
AddPivot(
kiBullishPivot,
kiBullishPivots //
);
}
//
kiBullishPivot.Clean();
}
}
//
// KI Bearish ...
if (detectKIBearishPivot)
{
//
if (!kiBearishPivot.IsValid())
{
//
kiBearishPivot.type = XCA_KI_BEAR;
kiBearishPivot.symbol = iConditions.symbol;
kiBearishPivot.period = iConditions.period;
//
if (iConditions.isKISwitchedToBullish)
{
//
kiBearishPivot.Clean();
//
kiBearishPivot.type = XCA_KI_BEAR;
kiBearishPivot.symbol = iConditions.symbol;
kiBearishPivot.period = iConditions.period;
//
kiBearishPivot.to = pBar.time;
kiBearishPivot.from = pBar.time;
kiBearishPivot.value = iConditions.kiBuffer[pIDX];
kiBearishPivot.reserve = iConditions.kiBuffer[pIDX];
}
}
//
if (iConditions.isKIBearish)
{
//
kiBearishPivot.from = cBar.time;
//
Add(
iConditions.kiBuffer[cIDX],
kiBearishPivot.values //
);
//
kiBearishPivot.value =
kiBearishPivot.value == 0
? iConditions.kiBuffer[cIDX]
: MathMax(iConditions.kiBuffer[cIDX], kiBearishPivot.value);
//
kiBearishPivot.reserve =
kiBearishPivot.reserve == 0
? iConditions.kiBuffer[cIDX]
: MathMin(iConditions.kiBuffer[cIDX], kiBearishPivot.reserve);
}
//
if (iConditions.isKISwitchedToBearish)
{
//
has =
kiBearishPivot.IsValid() &&
kiBearishPivot.GetAge() >= pivotVerifications;
if (has)
{
//
AddPivot(
kiBearishPivot,
kiBearishPivots //
);
}
//
kiBearishPivot.Clean();
}
}
//
// TKI Bullish ...
if (detectTKIBullishPivot)
{
//
if (!tkiBullishPivot.IsValid())
{
//
tkiBullishPivot.type = XCA_TKI_BULL;
tkiBullishPivot.symbol = iConditions.symbol;
tkiBullishPivot.period = iConditions.period;
//
if (iConditions.isTKISwitchedToBearish)
{
//
tkiBullishPivot.Clean();
//
tkiBullishPivot.type = XCA_TKI_BULL;
tkiBullishPivot.symbol = iConditions.symbol;
tkiBullishPivot.period = iConditions.period;
//
tkiBullishPivot.to = pBar.time;
tkiBullishPivot.from = pBar.time;
tkiBullishPivot.value = iConditions.tkiBuffer[pIDX];
tkiBullishPivot.reserve = iConditions.tkiBuffer[pIDX];
}
}
//
if (iConditions.isTKIBullish)
{
//
tkiBullishPivot.from = cBar.time;
//
Add(
iConditions.tkiBuffer[cIDX],
tkiBullishPivot.values //
);
//
tkiBullishPivot.value =
tkiBullishPivot.value == 0
? iConditions.tkiBuffer[cIDX]
: MathMin(iConditions.tkiBuffer[cIDX], tkiBullishPivot.value);
//
tkiBullishPivot.reserve =
tkiBullishPivot.reserve == 0
? iConditions.tkiBuffer[cIDX]
: MathMax(iConditions.tkiBuffer[cIDX], tkiBullishPivot.reserve);
}
//
if (iConditions.isTKISwitchedToBullish)
{
//
has =
tkiBullishPivot.IsValid() &&
tkiBullishPivot.GetAge() >= pivotVerifications;
if (has)
{
//
AddPivot(
tkiBullishPivot,
tkiBullishPivots //
);
}
//
tkiBullishPivot.Clean();
}
}
//
// TKI Bearish ...
if (detectTKIBearishPivot)
{
//
if (!tkiBearishPivot.IsValid())
{
//
tkiBearishPivot.type = XCA_TKI_BEAR;
tkiBearishPivot.symbol = iConditions.symbol;
tkiBearishPivot.period = iConditions.period;
//
if (iConditions.isTKISwitchedToBullish)
{
//
tkiBearishPivot.Clean();
//
tkiBearishPivot.type = XCA_TKI_BEAR;
tkiBearishPivot.symbol = iConditions.symbol;
tkiBearishPivot.period = iConditions.period;
//
tkiBearishPivot.to = pBar.time;
tkiBearishPivot.from = pBar.time;
tkiBearishPivot.value = iConditions.tkiBuffer[pIDX];
tkiBearishPivot.reserve = iConditions.tkiBuffer[pIDX];
}
}
//
if (iConditions.isTKIBearish)
{
//
tkiBearishPivot.from = cBar.time;
//
Add(
iConditions.tkiBuffer[cIDX],
tkiBearishPivot.values //
);
//
tkiBearishPivot.value =
tkiBearishPivot.value == 0
? iConditions.tkiBuffer[cIDX]
: MathMax(iConditions.tkiBuffer[cIDX], tkiBearishPivot.value);
//
tkiBearishPivot.reserve =
tkiBearishPivot.reserve == 0
? iConditions.tkiBuffer[cIDX]
: MathMin(iConditions.tkiBuffer[cIDX], tkiBearishPivot.reserve);
}
//
if (iConditions.isTKISwitchedToBearish)
{
//
has =
tkiBearishPivot.IsValid() &&
tkiBearishPivot.GetAge() >= pivotVerifications;
if (has)
{
//
AddPivot(
tkiBearishPivot,
tkiBearishPivots //
);
}
//
tkiBearishPivot.Clean();
}
}
//
// TREND Bullish ...
if (detectTrendBullishPivot)
{
//
if (!trendBullishPivot.IsValid())
{
//
trendBullishPivot.type = XCA_TREND_BULL;
trendBullishPivot.symbol = iConditions.symbol;
trendBullishPivot.period = iConditions.period;
//
if (iConditions.isTrendSwitchedToBearish)
{
//
trendBullishPivot.Clean();
//
trendBullishPivot.type = XCA_TREND_BULL;
trendBullishPivot.symbol = iConditions.symbol;
trendBullishPivot.period = iConditions.period;
//
trendBullishPivot.to = pBar.time;
trendBullishPivot.from = pBar.time;
trendBullishPivot.value = iConditions.trendBuffer[pIDX];
trendBullishPivot.reserve = iConditions.trendBuffer[pIDX];
}
}
//
if (iConditions.isTrendBullish)
{
//
trendBullishPivot.from = cBar.time;
//
Add(
iConditions.trendBuffer[cIDX],
trendBullishPivot.values //
);
//
trendBullishPivot.value =
trendBullishPivot.value == 0
? iConditions.trendBuffer[cIDX]
: MathMin(iConditions.trendBuffer[cIDX], trendBullishPivot.value);
//
trendBullishPivot.reserve =
trendBullishPivot.reserve == 0
? iConditions.trendBuffer[cIDX]
: MathMax(iConditions.trendBuffer[cIDX], trendBullishPivot.reserve);
}
//
if (iConditions.isTrendSwitchedToBullish)
{
//
has =
trendBullishPivot.IsValid() &&
trendBullishPivot.GetAge() >= pivotVerifications;
if (has)
{
//
AddPivot(
trendBullishPivot,
trendBullishPivots //
);
}
//
trendBullishPivot.Clean();
}
}
//
// TREND Bearish ...
if (detectTrendBearishPivot)
{
//
if (!trendBearishPivot.IsValid())
{
//
trendBearishPivot.type = XCA_TREND_BEAR;
trendBearishPivot.symbol = iConditions.symbol;
trendBearishPivot.period = iConditions.period;
//
if (iConditions.isTrendSwitchedToBullish)
{
//
trendBearishPivot.Clean();
//
trendBearishPivot.type = XCA_TREND_BEAR;
trendBearishPivot.symbol = iConditions.symbol;
trendBearishPivot.period = iConditions.period;
//
trendBearishPivot.to = pBar.time;
trendBearishPivot.from = pBar.time;
trendBearishPivot.value = iConditions.trendBuffer[pIDX];
trendBearishPivot.reserve = iConditions.trendBuffer[pIDX];
}
}
//
if (iConditions.isTrendBearish)
{
//
trendBearishPivot.from = cBar.time;
//
Add(
iConditions.trendBuffer[cIDX],
trendBearishPivot.values //
);
//
trendBearishPivot.value =
trendBearishPivot.value == 0
? iConditions.trendBuffer[cIDX]
: MathMax(iConditions.trendBuffer[cIDX], trendBearishPivot.value);
//
trendBearishPivot.reserve =
trendBearishPivot.reserve == 0
? iConditions.trendBuffer[cIDX]
: MathMin(iConditions.trendBuffer[cIDX], trendBearishPivot.reserve);
}
//
if (iConditions.isTrendSwitchedToBearish)
{
//
has =
trendBearishPivot.IsValid() &&
trendBearishPivot.GetAge() >= pivotVerifications;
if (has)
{
//
AddPivot(
trendBearishPivot,
trendBearishPivots //
);
}
//
trendBearishPivot.Clean();
}
}
//
start++;
//
zBar.Clean();
cBar.Clean();
pBar.Clean();
p2Bar.Clean();
iConditions.Clean();
}
//
}
//
// POI Handlers ...
//
// Peaks ...
//
bool HasPeakPivots()
{
return HasChild(peakPivots);
}
//
int CountPeakPivots()
{
return ArraySize(peakPivots);
}
//
// Peak SWH Res ...
//
bool HasPeakSWHResPivots()
{
return HasChild(peakSWHResPivots);
}
//
int CountPeakSWHResPivots()
{
return ArraySize(peakSWHResPivots);
}
//
// Vale ...
//
bool HasValePivots()
{
return HasChild(valePivots);
}
//
int CountValePivots()
{
return ArraySize(valePivots);
}
//
// ValeSWLSup ...
//
bool HasValeSWLSupPivots()
{
return HasChild(valeSWLSupPivots);
}
//
int CountValeSWLSupPivots()
{
return ArraySize(valeSWLSupPivots);
}
//
// Swing High ...
//
bool HasSWHPivots()
{
return HasChild(swhPivots);
}
//
int CountSWHPivots()
{
return ArraySize(swhPivots);
}
//
// Swing Low ...
//
bool HasSWLPivots()
{
return HasChild(swlPivots);
}
//
int CountSWLPivots()
{
return ArraySize(swlPivots);
}
//
// KI ...
//
bool HasKIBullishPivots()
{
return HasChild(kiBullishPivots);
}
//
int CountKIBullishPivots()
{
return ArraySize(kiBullishPivots);
}
//
bool HasKIBearishPivots()
{
return HasChild(kiBearishPivots);
}
//
int CountKIBearishPivots()
{
return ArraySize(kiBearishPivots);
}
//
// TKI ...
//
bool HasTKIBullishPivots()
{
return HasChild(tkiBullishPivots);
}
//
int CountTKIBullishPivots()
{
return ArraySize(tkiBullishPivots);
}
//
bool HasTKIBearishPivots()
{
return HasChild(tkiBearishPivots);
}
//
int CountTKIBearishPivots()
{
return ArraySize(tkiBearishPivots);
}
//
// TREND ...
//
bool HasTrendBullishPivots()
{
return HasChild(trendBullishPivots);
}
//
int CountTrendBullishPivots()
{
return ArraySize(trendBullishPivots);
}
//
bool HasTrendBearishPivots()
{
return HasChild(trendBearishPivots);
}
//
int CountTrendBearishPivots()
{
return ArraySize(trendBearishPivots);
}
//
// Protected ...
protected:
//
// Props ...
//
// Prrivate ...
private:
//
// Props ...
int pivotVerifications; // Pivots Verifications ...
int maxAllowedPivots; // Max Allowed Holding Pibots ...
//
XCAPivot swhPivot;
XCAPivot swlPivot;
XCAPivot peakPivot;
XCAPivot valePivot;
XCAPivot kiBullishPivot;
XCAPivot kiBearishPivot;
XCAPivot tkiBullishPivot;
XCAPivot tkiBearishPivot;
XCAPivot peakSWHResPivot;
XCAPivot valeSWLSupPivot;
XCAPivot trendBullishPivot;
XCAPivot trendBearishPivot;
//
XCPOIDrawer *drawer;
XCXCAEAHelper *helper;
XCBarAnalyser *barAnalyser;
//
void AddPivot(
XCAPivot &pivot,
XCAPivot &pivots[] //
)
{
//
bool has = pivot.IsValid();
if (!has)
{
return;
}
//
int idx = -1;
has = FindPivotIndex(
idx,
pivot,
pivots //
);
if (has)
{
return;
}
//
int updateIDX = -1;
int count = ArraySize(pivots);
for (int i = 0; i < count; i++)
{
//
XCAPivot iPivot = pivots[i];
//
has =
iPivot.to > pivot.to &&
iPivot.from == pivot.from &&
iPivot.value == pivot.value &&
iPivot.symbol == pivot.symbol &&
iPivot.period == pivot.period;
if (has)
{
//
updateIDX = i;
break;
}
}
//
has = IsValidIndex(updateIDX);
if (!has)
{
//
AddRef(
pivot,
pivots //
);
}
else
{
pivots[updateIDX].to = pivot.to;
}
//
// Apply Max Allowed ...
CleanupArray(
pivots,
maxAllowedPivots //
);
}
//
};
//