Files
MQL5Data/XCAEA/Classes/xcaea.x-poi.detector.class.mq5
T

1682 lines
34 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 library
#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_LL, // LowestLow
XCA_HH, // HighestHigh
XCA_KI, // KI
XCA_SWL, // SWL
XCA_SWH, // SWH
XCA_VALE, // VALE
XCA_PEAK, // PEAK
XCA_FVG_BULL, // FVGBull
XCA_FVG_BEAR, // FVGBear
XCA_RSI_COOS, // RSICOOS
XCA_RSI_CUOB, // RSICUOB
XCA_RSI_PEAK, // RSIPeak
XCA_RSI_VALE, // RSIVale
XCA_CCI_COOS, // CCICOOS
XCA_CCI_CUOB, // CCICUOB
XCA_CCI_PEAK, // CCIPeak
XCA_CCI_VALE, // CCIVale
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, // TrendBull
XCA_TREND_BEAR, // TrendBear
XCA_TKITRND_BULL, // TKITRNDBull
XCA_TKITRND_BEAR, // TKITRNDBear
};
//
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);
//
ZeroMemory(this);
}
/**
* 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_LL:
case XCA_SWL:
case XCA_VALE:
case XCA_KI_BULL:
case XCA_FVG_BULL:
case XCA_RSI_COOS:
case XCA_RSI_VALE:
case XCA_CCI_COOS:
case XCA_CCI_VALE:
case XCA_TKI_BULL:
case XCA_TREND_BULL:
case XCA_VALESWLSUP:
case XCA_TKITRND_BULL:
iDir = X_DIRECTION_BULLISH;
break;
//
case XCA_HH:
case XCA_SWH:
case XCA_PEAK:
case XCA_KI_BEAR:
case XCA_FVG_BEAR:
case XCA_RSI_CUOB:
case XCA_RSI_PEAK:
case XCA_CCI_CUOB:
case XCA_CCI_PEAK:
case XCA_TKI_BEAR:
case XCA_TREND_BEAR:
case XCA_PEAKSWHRES:
case XCA_TKITRND_BEAR:
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_FVG_BULL ||
type == XCA_FVG_BEAR)
{
//
typeStr = "XCA_FVG";
}
else if (type == XCA_RSI_COOS ||
type == XCA_RSI_CUOB)
{
//
typeStr = "XCA_RSI";
}
else if (type == XCA_CCI_COOS ||
type == XCA_CCI_CUOB)
{
//
typeStr = "XCA_CCI";
}
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";
}
else if (type == XCA_TKITRND_BULL ||
type == XCA_TKITRND_BEAR)
{
//
typeStr = "XCA_TKITRND";
}
box.type = typeStr;
//
box.upper =
isBullish
? reserve
: value;
box.lower =
isBullish
? value
: reserve;
//
result = box.IsValid();
if (!result)
{
box.Clean();
}
//
return result;
}
//
};
//
// Implementations ...
class XCXCAEAPOIDetector : public XCBase
{
//
// Public ...
public:
//
// Props ...
//
// Pivot Verifications and Max Allowed Holding Items ...
int pivotVerifications; // Pivots Verifications ...
int maxAllowedPivots; // Max Allowed Holding Pibots ...
//
// VALE Pivot Support Swing Low ...
//
XCAPivot valeSupSWLPivot;
bool detectValeSupSWLPivots;
XBoxZone valeSupSWLPivots[];
bool newValeSupSWLPivotDetected;
//
// PEAK Pivot Resistance Swing High ...
//
XCAPivot peakResSWHPivot;
bool detectPeakResSWHPivots;
XBoxZone peakResSWHPivots[];
bool newPeakResSWHPivotDetected;
//
// FVG Bullish Pivots ...
//
bool detectFVGBullishPivots;
XBoxZone fvgBullishPivots[];
bool newFVGBullishPivotDetected;
//
// FVG Bearish Pivots ...
//
bool detectFVGBearishPivots;
XBoxZone fvgBearishPivots[];
bool newFVGBearishPivotDetected;
//
// RSI Peak Pivot ...
//
XCAPivot rsiPeakPivot;
bool detectRSIPeakPivots;
XBoxZone rsiPeakPivots[];
bool newRSIPeakPivotDetected;
//
// RSI Vale Pivot ...
//
XCAPivot rsiValePivot;
bool detectRSIValePivots;
XBoxZone rsiValePivots[];
bool newRSIValePivotDetected;
//
// CCI Peak Pivot ...
//
XCAPivot cciPeakPivot;
bool detectCCIPeakPivots;
XBoxZone cciPeakPivots[];
bool newCCIPeakPivotDetected;
//
// CCI Vale Pivot ...
//
XCAPivot cciValePivot;
bool detectCCIValePivots;
XBoxZone cciValePivots[];
bool newCCIValePivotDetected;
//
// Detector Pivots State Properties ...
//
// Constructors ...
XCXCAEAPOIDetector(
XCXCAEAHelper *_helper //
)
{
//
helper = _helper;
drawer = new XCPOIDrawer();
barAnalyser = new XCBarAnalyser();
//
Default();
}
//
// De Constructors ...
~XCXCAEAPOIDetector()
{
//
rsiPeakPivot.Clean();
rsiValePivot.Clean();
cciPeakPivot.Clean();
cciValePivot.Clean();
valeSupSWLPivot.Clean();
peakResSWHPivot.Clean();
//
Clean(rsiPeakPivots);
Clean(rsiValePivots);
Clean(cciPeakPivots);
Clean(cciValePivots);
Clean(fvgBullishPivots);
Clean(fvgBearishPivots);
Clean(valeSupSWLPivots);
Clean(peakResSWHPivots);
//
ZeroMemory(helper);
ZeroMemory(drawer);
ZeroMemory(barAnalyser);
}
//
// Properties ...
//
// Tools ...
//
virtual void Default()
{
//
maxAllowedPivots = 50;
pivotVerifications = 5;
//
detectRSIPeakPivots = true;
detectRSIValePivots = true;
detectCCIPeakPivots = true;
detectCCIValePivots = true;
detectFVGBullishPivots = true;
detectFVGBearishPivots = true;
detectValeSupSWLPivots = true;
detectPeakResSWHPivots = true;
//
}
//
void Update(
int barIndex = 0,
int loopback = 400 //
)
{
//
if (barIndex < 0)
{
barIndex = 0;
}
//
loopback = NormalizeInt(loopback, 400);
//
int count = 0;
bool has = false;
//
newRSIPeakPivotDetected = false;
newRSIValePivotDetected = false;
newCCIPeakPivotDetected = false;
newCCIValePivotDetected = false;
newFVGBullishPivotDetected = false;
newFVGBearishPivotDetected = false;
newValeSupSWLPivotDetected = false;
newPeakResSWHPivotDetected = false;
//
int zIDX = 0;
int cIDX = zIDX + 1;
int pIDX = cIDX + 1;
int p2IDX = pIDX + 1;
int p3IDX = p2IDX + 1;
//
int index = barIndex;
int start = index;
int end = index + loopback;
while (start < end)
{
//
// Retrieve Conditions ...
XCAEAConditions conditions;
has = helper.GetConditions(
conditions,
start,
5 //
);
//
// Retrieve Bars ...
XOHCL zBar;
XOHCL cBar;
XOHCL pBar;
XOHCL p2Bar;
has = zBar.Init(
conditions.symbol,
conditions.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();
conditions.Clean();
//
continue;
}
//
XBoxZone fvgBox;
bool isFVG = barAnalyser.IsFVG(
cBar,
fvgBox //
);
//
bool isBullishFVG =
isFVG &&
fvgBox.IsBullish();
//
bool isBearishFVG =
isFVG &&
fvgBox.IsBearish();
//
// Provide Some Conditions ...
//
double points = GetPoints(zBar.symbol);
//
// Reading Values from Conditions and
// Create Customized Conditions if required ...
//
// Checking Pivots ...
//
// VALE Pivot Support Swing Low ...
if (detectValeSupSWLPivots)
{
//
if (conditions.isValeFinishedFromPivot)
{
//
valeSupSWLPivot.Clean();
//
valeSupSWLPivot.type = XCA_VALESWLSUP;
valeSupSWLPivot.symbol = conditions.symbol;
valeSupSWLPivot.period = conditions.period;
//
valeSupSWLPivot.to = pBar.time;
valeSupSWLPivot.from = pBar.time;
valeSupSWLPivot.value = conditions.valeBuffer[pIDX];
valeSupSWLPivot.reserve = conditions.valeGoldenBuffer[pIDX];
}
//
if (conditions.isValeIsPivot)
{
//
valeSupSWLPivot.from = pBar.time;
//
valeSupSWLPivot.reserve =
valeSupSWLPivot.reserve == 0
? conditions.valeGoldenBuffer[cIDX]
: MathMin(valeSupSWLPivot.reserve, conditions.valeGoldenBuffer[cIDX]);
}
//
if (conditions.isValeSwitchedToPivot)
{
//
has =
valeSupSWLPivot.IsValid() &&
valeSupSWLPivot.GetAge() >= pivotVerifications;
if (has)
{
//
XBoxZone iBox;
newValeSupSWLPivotDetected = valeSupSWLPivot.AsBox(iBox);
if (newValeSupSWLPivotDetected)
{
//
AddBox(
iBox,
valeSupSWLPivots,
maxAllowedPivots //
);
}
//
iBox.Clean();
}
//
valeSupSWLPivot.Clean();
}
}
//
// PEAK Pivot Resistance Swing High ...
if (detectPeakResSWHPivots)
{
}
//
// FVG Bullish ...
if (detectFVGBullishPivots)
{
}
//
// FVG Bearish ...
if (detectFVGBearishPivots)
{
}
//
// RSI Peak Pivot ...
if (detectRSIPeakPivots)
{
}
//
// RSI Vale Pivot ...
if (detectRSIValePivots)
{
}
//
// CCI Peak Pivot ...
if (detectCCIPeakPivots)
{
}
//
// CCI Vale Pivot ...
if (detectCCIValePivots)
{
}
//
start++;
//
zBar.Clean();
cBar.Clean();
pBar.Clean();
p2Bar.Clean();
fvgBox.Clean();
conditions.Clean();
}
//
}
//
void Validate(
XBoxZone &unAvailableBoxes[],
int barIndex = 0 //
)
{
//
// Do All Pivots Validation ...
//
if (barIndex < 0)
{
barIndex = 0;
}
//
XBoxZone tmp[];
bool has = false;
//
int zIDX = 0;
int cIDX = zIDX + 1;
int pIDX = cIDX + 1;
int p2IDX = pIDX + 1;
//
// Implement Validation Senarios ...
//
// VALE Pivot Support Swing Low ...
//
has = HasValeSupSWLPivots();
if (has)
{
//
// Copy Items and Cleanup Collection ...
Copy(
valeSupSWLPivots,
tmp //
);
Clean(valeSupSWLPivots);
//
// Do Validation ...
while (HasChild(tmp))
{
//
XBoxZone iBox = tmp[0];
ArrayRemove(
tmp,
0,
1 //
);
//
has = ValidateBox(
iBox,
unAvailableBoxes,
barIndex //
);
if (has)
{
//
AddRef(
iBox,
valeSupSWLPivots //
);
}
//
iBox.Clean();
}
//
Clean(tmp);
}
//
// PEAK Pivot Resistance Swing High ...
//
has = HasPeakResSWHPivots();
if (has)
{
//
// Copy Items and Cleanup Collection ...
Copy(
peakResSWHPivots,
tmp //
);
Clean(peakResSWHPivots);
//
// Do Validation ...
while (HasChild(tmp))
{
//
XBoxZone iBox = tmp[0];
ArrayRemove(
tmp,
0,
1 //
);
//
has = ValidateBox(
iBox,
unAvailableBoxes,
barIndex //
);
if (has)
{
//
AddRef(
iBox,
peakResSWHPivots //
);
}
//
iBox.Clean();
}
//
Clean(tmp);
}
//
// FVG Bullish ...
//
has = HasFVGBullishPivots();
if (has)
{
//
// Copy Items and Cleanup Collection ...
Copy(
fvgBullishPivots,
tmp //
);
Clean(fvgBullishPivots);
//
// Do Validation ...
while (HasChild(tmp))
{
//
XBoxZone iBox = tmp[0];
ArrayRemove(
tmp,
0,
1 //
);
//
has = ValidateBox(
iBox,
unAvailableBoxes,
barIndex //
);
if (has)
{
//
AddRef(
iBox,
fvgBullishPivots //
);
}
//
iBox.Clean();
}
//
Clean(tmp);
}
//
// FVG Bearish ...
//
has = HasFVGBearishPivots();
if (has)
{
//
// Copy Items and Cleanup Collection ...
Copy(
fvgBearishPivots,
tmp //
);
Clean(fvgBearishPivots);
//
// Do Validation ...
while (HasChild(tmp))
{
//
XBoxZone iBox = tmp[0];
ArrayRemove(
tmp,
0,
1 //
);
//
has = ValidateBox(
iBox,
unAvailableBoxes,
barIndex //
);
if (has)
{
//
AddRef(
iBox,
fvgBearishPivots //
);
}
//
iBox.Clean();
}
//
Clean(tmp);
}
//
// RSI Peak Pivot ...
//
has = HasRSIPeakPivots();
if (has)
{
//
// Copy Items and Cleanup Collection ...
Copy(
rsiPeakPivots,
tmp //
);
Clean(rsiPeakPivots);
//
// Do Validation ...
while (HasChild(tmp))
{
//
XBoxZone iBox = tmp[0];
ArrayRemove(
tmp,
0,
1 //
);
//
has = ValidateBox(
iBox,
unAvailableBoxes,
barIndex //
);
if (has)
{
//
AddRef(
iBox,
rsiPeakPivots //
);
}
//
iBox.Clean();
}
//
Clean(tmp);
}
//
// RSI Vale Pivot ...
//
has = HasRSIValePivots();
if (has)
{
//
// Copy Items and Cleanup Collection ...
Copy(
rsiValePivots,
tmp //
);
Clean(rsiValePivots);
//
// Do Validation ...
while (HasChild(tmp))
{
//
XBoxZone iBox = tmp[0];
ArrayRemove(
tmp,
0,
1 //
);
//
has = ValidateBox(
iBox,
unAvailableBoxes,
barIndex //
);
if (has)
{
//
AddRef(
iBox,
rsiValePivots //
);
}
//
iBox.Clean();
}
//
Clean(tmp);
}
//
// CCI Peak Pivot ...
//
has = HasCCIPeakPivots();
if (has)
{
//
// Copy Items and Cleanup Collection ...
Copy(
cciPeakPivots,
tmp //
);
Clean(cciPeakPivots);
//
// Do Validation ...
while (HasChild(tmp))
{
//
XBoxZone iBox = tmp[0];
ArrayRemove(
tmp,
0,
1 //
);
//
has = ValidateBox(
iBox,
unAvailableBoxes,
barIndex //
);
if (has)
{
//
AddRef(
iBox,
cciPeakPivots //
);
}
//
iBox.Clean();
}
//
Clean(tmp);
}
//
// CCI Vale Pivot ...
//
has = HasCCIValePivots();
if (has)
{
//
// Copy Items and Cleanup Collection ...
Copy(
cciValePivots,
tmp //
);
Clean(cciValePivots);
//
// Do Validation ...
while (HasChild(tmp))
{
//
XBoxZone iBox = tmp[0];
ArrayRemove(
tmp,
0,
1 //
);
//
has = ValidateBox(
iBox,
unAvailableBoxes,
barIndex //
);
if (has)
{
//
AddRef(
iBox,
cciValePivots //
);
}
//
iBox.Clean();
}
//
Clean(tmp);
}
//
Clean(tmp);
//
}
//
// Counters ...
//
// VALE Pivot Support Swing Low ...
//
bool HasValeSupSWLPivots()
{
return HasChild(valeSupSWLPivots);
}
//
int CountValeSupSWLPivots()
{
return ArraySize(valeSupSWLPivots);
}
//
// PEAK Pivot Resistance Swing High ...
//
bool HasPeakResSWHPivots()
{
return HasChild(peakResSWHPivots);
}
//
int CountPeakResSWHPivots()
{
return ArraySize(peakResSWHPivots);
}
//
// FVG Bullish ...
//
bool HasFVGBullishPivots()
{
return HasChild(fvgBullishPivots);
}
//
int CountFVGBullishPivots()
{
return ArraySize(fvgBullishPivots);
}
//
// FVG Bearish ...
//
bool HasFVGBearishPivots()
{
return HasChild(fvgBearishPivots);
}
//
int CountFVGBearishPivots()
{
return ArraySize(fvgBearishPivots);
}
//
// RSI Peak Pivot ...
//
bool HasRSIPeakPivots()
{
return HasChild(rsiPeakPivots);
}
//
int CountRSIPeakPivots()
{
return ArraySize(rsiPeakPivots);
}
//
// RSI Vale Pivot ...
//
bool HasRSIValePivots()
{
return HasChild(rsiValePivots);
}
//
int CountRSIValePivots()
{
return ArraySize(rsiValePivots);
}
//
// CCI Peak Pivot ...
//
bool HasCCIPeakPivots()
{
return HasChild(cciPeakPivots);
}
//
int CountCCIPeakPivots()
{
return ArraySize(cciPeakPivots);
}
//
// CCI Vale Pivot ...
//
bool HasCCIValePivots()
{
return HasChild(cciValePivots);
}
//
int CountCCIValePivots()
{
return ArraySize(cciValePivots);
}
//
// Protected ...
protected:
//
// Props ...
//
// Prrivate ...
private:
//
// Props ...
//
XCPOIDrawer *drawer;
XCXCAEAHelper *helper;
XCBarAnalyser *barAnalyser;
//
bool AddBox(
XBoxZone &box,
XBoxZone &boxes[],
int maxAllowedPivots //
)
{
//
bool result = false;
//
result = box.IsValid();
if (!result)
{
return result;
}
//
int idx = -1;
bool isExists = FindBoxIndex(
idx,
box,
boxes //
);
result = !isExists;
if (!result)
{
return result;
}
//
int before = ArraySize(boxes);
if (IsValidSize(before))
{
ArrayReverse(boxes);
}
//
AddRef(
box,
boxes //
);
int after = ArraySize(boxes);
//
result = after > before;
if (result)
{
//
ArrayReverse(boxes);
//
CleanupArray(
boxes,
maxAllowedPivots //
);
}
//
return result;
}
//
bool ValidateBox(
XBoxZone &box,
XBoxZone &unAvailableBoxes[],
int barIndex = 0 //
)
{
//
bool result = false;
//
// Normalize Bar Index ...
barIndex = NormalizeInt(barIndex, 0);
//
// Ceck Input Box is Valid ...
result = box.IsValid();
if (!result)
{
return result;
}
//
// Check Input Box is Available ...
bool canCheckUnAvailableBoxes = HasChild(unAvailableBoxes);
if (canCheckUnAvailableBoxes)
{
//
int idx = -1;
bool isUnAvailable = FindBoxIndex(
idx,
box,
unAvailableBoxes //
);
result = isUnAvailable;
if (!result)
{
return !result;
}
}
//
// Check Input Box is Breaked or not ...
//
// Check Bar Index must after Box To Index ...
int toIDX = box.ToIndex();
int fromIDX = box.FromIndex();
result = toIDX > barIndex &&
fromIDX > barIndex &&
fromIDX > toIDX;
if (!result)
{
return result;
}
//
// Detect Box Applied Boundary Price ...
// For Checking Break of Box ...
bool isBullish = box.IsBullish();
double boundary =
isBullish
? box.lower
: box.upper;
//
// for validating Box Break we have to wait At Least 3 Bars Close
// out of Box Boundary ...
int barsLength = 3;
//
// Calculate Start Checking Bar Index ...
int startCheckBreaktionBarIndex = toIDX - barsLength;
bool isBarIndexValid = startCheckBreaktionBarIndex > 0 &&
barIndex < startCheckBreaktionBarIndex;
result = isBarIndexValid;
if (!result)
{
//
// Assume Box is Valid if Bar Index not Valid for Checking ...
result = true;
return result;
}
//
// Try to Check Box Validation if Everything is OK ...
XOHCL cBar;
XOHCL pBar;
XOHCL p2Bar;
bool isValid = false;
bool isBreaked = false;
for (int i = barIndex; i < startCheckBreaktionBarIndex; i++)
{
//
// Initialize Bars ...
isValid = cBar.Init(
box.symbol,
box.period,
i + 1 //
);
isValid =
result &&
cBar.GetPreviousBar(pBar);
isValid =
result &&
pBar.GetPreviousBar(p2Bar);
if (!isValid)
{
//
cBar.Clean();
pBar.Clean();
p2Bar.Clean();
//
result = false;
//
break;
}
//
// Preparing Conditions ...
//
bool isBullishBreaked =
isBullish &&
cBar.close < boundary &&
pBar.close < boundary &&
p2Bar.close < boundary;
//
bool isBearishBreaked =
!isBullish &&
cBar.close > boundary &&
pBar.close > boundary &&
p2Bar.close > boundary;
//
// Calculate Result ...
isBreaked = isBullishBreaked ||
isBearishBreaked;
if (isBreaked)
{
//
cBar.Clean();
pBar.Clean();
p2Bar.Clean();
//
result = false;
//
break;
}
//
cBar.Clean();
pBar.Clean();
p2Bar.Clean();
}
//
result = isValid &&
!isBreaked;
//
// Cleanup Resource ...
//
cBar.Clean();
pBar.Clean();
p2Bar.Clean();
//
return result;
}
//
};
//