Files
MQL5Data/XCAEA/Classes/xcaea.x-poi.detector.class.mq5
T
2025-04-27 02:16:59 +03:30

4593 lines
104 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_TICK, // Tick
XCA_VOLUME, // Volume
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_PEAKSWHRES, // PeakSWHRes
XCA_VALESWLSUP, // ValeSWLSup
XCA_TREND_BULL, // TrendBull
XCA_TREND_BEAR, // TrendBear
};
//
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;
}
//
ENUM_X_DIRECTION GetDirection(ENUM_XCA_PIVOTS value)
{
//
ENUM_X_DIRECTION result = X_DIRECTION_NONE;
//
switch (value)
{
//
case XCA_FVG_BULL:
case XCA_RSI_COOS:
case XCA_RSI_VALE:
case XCA_CCI_COOS:
case XCA_CCI_VALE:
case XCA_TREND_BULL:
case XCA_VALESWLSUP:
result = X_DIRECTION_BULLISH;
break;
//
case XCA_FVG_BEAR:
case XCA_RSI_CUOB:
case XCA_RSI_PEAK:
case XCA_CCI_CUOB:
case XCA_CCI_PEAK:
case XCA_TREND_BEAR:
case XCA_PEAKSWHRES:
result = X_DIRECTION_BEARISH;
break;
}
//
return result;
}
//
string GetBoxType(ENUM_XCA_PIVOTS value)
{
//
string result = NULL;
//
switch (value)
{
//
case XCA_TICK:
case XCA_VOLUME:
case XCA_RSI_COOS:
case XCA_RSI_VALE:
case XCA_CCI_COOS:
case XCA_CCI_VALE:
case XCA_RSI_CUOB:
case XCA_RSI_PEAK:
case XCA_CCI_CUOB:
case XCA_CCI_PEAK:
case XCA_VALESWLSUP:
case XCA_PEAKSWHRES:
result = ToString(value);
break;
//
case XCA_FVG_BULL:
case XCA_FVG_BEAR:
result = "XCA_FVG";
break;
//
case XCA_TREND_BULL:
case XCA_TREND_BEAR:
result = "XCA_TREND";
break;
}
//
return result;
}
//
ENUM_XCA_PIVOTS GetPivotType(XBoxZone &value)
{
//
ENUM_XCA_PIVOTS result = XCA_NONE;
//
bool has = value.IsValid();
if (!has)
{
return result;
}
//
bool isTick = value.type == GetBoxType(XCA_TICK);
bool isVolume = value.type == GetBoxType(XCA_VOLUME);
bool isFVGBull = value.type == GetBoxType(XCA_FVG_BULL) &&
value.dir == GetDirection(XCA_FVG_BULL);
bool isFVGBear = value.type == GetBoxType(XCA_FVG_BEAR) &&
value.dir == GetDirection(XCA_FVG_BEAR);
bool isRSIPeak = value.type == GetBoxType(XCA_RSI_PEAK) &&
value.dir == GetDirection(XCA_RSI_PEAK);
bool isRSIVale = value.type == GetBoxType(XCA_RSI_VALE) &&
value.dir == GetDirection(XCA_RSI_VALE);
bool isCCIPeak = value.type == GetBoxType(XCA_CCI_PEAK) &&
value.dir == GetDirection(XCA_CCI_PEAK);
bool isCCIVale = value.type == GetBoxType(XCA_CCI_VALE) &&
value.dir == GetDirection(XCA_CCI_VALE);
bool isRSICrossedOverOS = value.type == GetBoxType(XCA_RSI_COOS) &&
value.dir == GetDirection(XCA_RSI_COOS);
bool isRSICrossedUnderOB = value.type == GetBoxType(XCA_RSI_CUOB) &&
value.dir == GetDirection(XCA_RSI_CUOB);
bool isCCICrossedOverOS = value.type == GetBoxType(XCA_CCI_COOS) &&
value.dir == GetDirection(XCA_CCI_COOS);
bool isCCICrossedUnderOB = value.type == GetBoxType(XCA_CCI_CUOB) &&
value.dir == GetDirection(XCA_CCI_CUOB);
bool isTrendBullish = value.type == GetBoxType(XCA_TREND_BULL) &&
value.dir == GetDirection(XCA_TREND_BULL);
bool isTrendBearish = value.type == GetBoxType(XCA_TREND_BEAR) &&
value.dir == GetDirection(XCA_TREND_BEAR);
//
if (isTick)
{
result = XCA_TICK;
}
else if (isVolume)
{
result = XCA_VOLUME;
}
else if (isFVGBull)
{
result = XCA_FVG_BULL;
}
else if (isFVGBear)
{
result = XCA_FVG_BEAR;
}
else if (isRSIPeak)
{
result = XCA_RSI_PEAK;
}
else if (isRSIVale)
{
result = XCA_RSI_VALE;
}
else if (isCCIPeak)
{
result = XCA_CCI_PEAK;
}
else if (isCCIVale)
{
result = XCA_CCI_VALE;
}
else if (isRSICrossedOverOS)
{
result = XCA_RSI_COOS;
}
else if (isRSICrossedUnderOB)
{
result = XCA_RSI_CUOB;
}
else if (isCCICrossedOverOS)
{
result = XCA_CCI_COOS;
}
else if (isCCICrossedUnderOB)
{
result = XCA_CCI_CUOB;
}
else if (isTrendBullish)
{
result = XCA_TREND_BULL;
}
else if (isTrendBearish)
{
result = XCA_TREND_BEAR;
}
//
return result;
}
//
int ExtractPivots(
XBoxZone &extracted[],
ENUM_XCA_PIVOTS type,
XBoxZone &source[] //
)
{
//
int result = 0;
//
Clean(extracted);
//
bool has =
IsValid(type) &&
HasChild(source);
if (!has)
{
return result;
}
//
int count = ArraySize(source);
for (int i = 0; i < count; i++)
{
//
XBoxZone iBox = source[i];
//
ENUM_XCA_PIVOTS iType = GetPivotType(iBox);
//
has = iType == type;
if (has)
{
//
AddRef(
iBox,
extracted //
);
}
//
iBox.Clean();
}
//
result = ArraySize(extracted);
//
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 = GetDirection(type);
//
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 = GetBoxType(type);
box.type = typeStr;
//
box.upper =
isBullish
? reserve
: value;
box.lower =
isBullish
? value
: reserve;
//
result = box.IsValid();
if (!result)
{
box.Clean();
}
//
return result;
}
//
};
//
struct XCATRENDFVG
{
//
XBoxZone trend;
XBoxZone fvgs[];
//
XCATRENDFVG()
{
Clean();
}
//
// Tools ...
//
void Clean()
{
//
Clean(fvgs);
trend.Clean();
}
//
bool IsValid()
{
//
bool result = false;
//
result = trend.IsValid();
//
return result;
}
//
void AddFVG(XBoxZone &fvg)
{
//
bool has = trend.IsValid() &&
fvg.IsValid() &&
fvg.dir == trend.dir;
if (!has)
{
return;
}
//
int idx = -1;
has = FindBoxIndex(
idx,
fvg,
fvgs //
);
if (has)
{
return;
}
//
AddRef(
fvg,
fvgs //
);
}
//
bool IsBullish()
{
return IsValid() &&
trend.IsBullish();
}
//
bool IsBearish()
{
return IsValid() &&
trend.IsBearish();
}
//
bool GetSelectedFVG(XBoxZone &fvg)
{
//
bool result = false;
//
fvg.Clean();
//
result = IsValid();
if (!result)
{
return result;
}
//
int idx = -1;
if (IsBullish())
{
idx = GetLowest(fvgs);
}
else if (IsBearish())
{
idx = GetHighest(fvgs);
}
result = IsValidIndex(idx);
if (!result)
{
return result;
}
//
fvg = fvgs[idx];
//
result = fvg.IsValid();
//
return result;
}
//
};
//
int ExtractTrendFVGs(
XBoxZone &extracteds[],
XBoxZone &trend,
XBoxZone &fvgs[] //
)
{
//
int result = 0;
//
Clean(extracteds);
//
bool has = HasChild(fvgs) &&
trend.IsValid();
if (!has)
{
return result;
}
//
// Check Trend Box Pivot is Valid Trend ...
ENUM_XCA_PIVOTS iType = GetPivotType(trend);
has = iType == XCA_TREND_BULL ||
iType == XCA_TREND_BEAR;
if (!has)
{
return result;
}
//
int count = ArraySize(fvgs);
for (int i = 0; i < count; i++)
{
//
XBoxZone iFVG = fvgs[i];
//
bool isDirPassed = iFVG.dir == trend.dir;
bool isPricePassed = iFVG.upper <= trend.upper &&
iFVG.lower >= trend.lower;
bool isFromPassed = iFVG.from > trend.from;
has =
isDirPassed &&
isFromPassed &&
isPricePassed;
if (has)
{
//
AddRef(
iFVG,
extracteds //
);
}
//
iFVG.Clean();
}
//
result = ArraySize(extracteds);
//
return result;
}
//
int ExtractTrendPivots(
XCATRENDFVG &items[],
XBoxZone &boxes[] //
)
{
//
int result = 0;
//
Clean(items);
//
bool has = HasChild(boxes);
if (!has)
{
return result;
}
//
// Extract Trend Boxes ...
XBoxZone tmp[];
XBoxZone trendBoxes[];
ExtractPivots(
tmp,
XCA_TREND_BULL,
boxes //
);
Copy(
tmp,
trendBoxes,
false //
);
Clean(tmp);
ExtractPivots(
tmp,
XCA_TREND_BEAR,
boxes //
);
Copy(
tmp,
trendBoxes,
false //
);
Clean(tmp);
//
// Check Trend Boxes Exists ...
has = HasChild(trendBoxes);
if (!has)
{
//
Clean(trendBoxes);
return result;
}
//
// Extract FVG Boxes ...
XBoxZone fvgBoxes[];
//
ExtractPivots(
tmp,
XCA_FVG_BULL,
boxes //
);
Copy(
tmp,
fvgBoxes,
false //
);
Clean(tmp);
ExtractPivots(
tmp,
XCA_FVG_BEAR,
boxes //
);
Copy(
tmp,
fvgBoxes,
false //
);
Clean(tmp);
bool hasFVGs = HasChild(fvgBoxes);
int fvgsCount = ArraySize(fvgBoxes);
//
// Loop through Trend Boxes to Extract XCATRENDFVG Models ...
int count = ArraySize(trendBoxes);
for (int i = 0; i < count; i++)
{
//
XBoxZone iTrendBox = trendBoxes[i];
//
XCATRENDFVG iTrendFVG;
iTrendFVG.trend = iTrendBox;
//
XBoxZone fvgs[];
if (hasFVGs)
{
//
int fvgsCount = ExtractTrendFVGs(
fvgs,
iTrendBox,
fvgBoxes //
);
//
Copy(
fvgs,
iTrendFVG.fvgs //
);
}
//
has = iTrendFVG.IsValid();
if (has)
{
//
AddRef(
iTrendFVG,
items //
);
}
//
iTrendBox.Clean();
iTrendFVG.Clean();
}
//
Clean(tmp);
Clean(fvgBoxes);
Clean(trendBoxes);
//
result = ArraySize(items);
//
return result;
}
//
int GetOldest(XCATRENDFVG &items[])
{
//
int result = -1;
//
bool has = HasChild(items);
if (!has)
{
return result;
}
//
XCATRENDFVG item;
int count = ArraySize(items);
for (int i = 0; i < count; i++)
{
//
XCATRENDFVG iTrendFVG = items[i];
//
bool canSet =
!item.IsValid()
? true
: item.trend.from > iTrendFVG.trend.from;
if (canSet)
{
//
result = i;
item = iTrendFVG;
}
//
iTrendFVG.Clean();
}
//
has = IsValidIndex(result);
item.Clean();
//
return result;
}
//
// Implementations ...
class XCXCAEAPOIDetector : public XCBase
{
//
// Public ...
public:
//
// Props ...
//
// Pivot Verifications and Max Allowed Holding Items ...
int maxAllowedPivots; // Max Allowed Holding Pibots ...
int pivotVerifications; // Pivots Verifications ...
int pivotDetectionLoopbac; // Pivots Detection Loopback ...
double ticksDividerInPoints; // Ticks and Volume Detection Divider in Point ...
ENUM_TIMEFRAMES ticksDetectionPerid; // Ticks and Volume Detection Loopback ...
//
// TREND ...
XBoxZone trendPivotP; // Prev Pivot of Market Trend ...
XBoxZone trendPivotC; // Current Pivot of Market Trend ...
ENUM_X_DIRECTION trendDir; // Trend Direction ...
//
// Breaked Pivots ...
XBoxZone invalidPivots[];
//
// TICK Pivots ...
//
bool detectTickPivots;
XBoxZone tickPivots[];
//
// VOLUME Pivots ...
//
bool detectVolumePivots;
XBoxZone volumePivots[];
//
// RSI Peak Pivot ...
//
bool detectRSIPeakPivots;
XBoxZone rsiPeakPivots[];
bool newRSIPeakPivotDetected;
//
// RSI Vale Pivot ...
//
bool detectRSIValePivots;
XBoxZone rsiValePivots[];
bool newRSIValePivotDetected;
//
// CCI Peak Pivot ...
//
bool detectCCIPeakPivots;
XBoxZone cciPeakPivots[];
bool newCCIPeakPivotDetected;
//
// CCI Vale Pivot ...
//
bool detectCCIValePivots;
XBoxZone cciValePivots[];
bool newCCIValePivotDetected;
//
// FVG Bullish Pivots ...
//
bool detectFVGBullishPivots;
XBoxZone fvgBullishPivots[];
bool newFVGBullishPivotDetected;
//
// FVG Bearish Pivots ...
//
bool detectFVGBearishPivots;
XBoxZone fvgBearishPivots[];
bool newFVGBearishPivotDetected;
//
// 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;
//
// TREND Bullish ...
//
XCAPivot trendBullishPivot;
XBoxZone trendBullishFVGs[];
bool detectTrendBullishPivots;
XCATRENDFVG trendBullishPivots[];
bool newTrendBullishPivotDetected;
//
// TREND Bearish ...
//
XCAPivot trendBearishPivot;
XBoxZone trendBearishFVGs[];
bool detectTrendBearishPivots;
XCATRENDFVG trendBearishPivots[];
bool newTrendBearishPivotDetected;
//
// RSI Crossed Over OS Pivot ...
//
bool detectRSICrossedOverOSPivots;
XBoxZone rsiCrossedOverOSPivots[];
bool newRSICrossedOverOSPivotDetected;
//
// RSI Crossed Under OB Pivot ...
//
bool detectRSICrossedUnderOBPivots;
XBoxZone rsiCrossedUnderOBPivots[];
bool newRSICrossedUnderOBPivotDetected;
//
// CCI Crossed Over OS Pivot ...
//
bool detectCCICrossedOverOSPivots;
XBoxZone cciCrossedOverOSPivots[];
bool newCCICrossedOverOSPivotDetected;
//
// CCI Crossed Under OB Pivot ...
//
bool detectCCICrossedUnderOBPivots;
XBoxZone cciCrossedUnderOBPivots[];
bool newCCICrossedUnderOBPivotDetected;
//
// Constructors ...
XCXCAEAPOIDetector(
XCXCAEAHelper *_helper //
)
{
//
helper = _helper;
drawer = new XCPOIDrawer();
barAnalyser = new XCBarAnalyser();
//
Default();
}
//
// De Constructors ...
~XCXCAEAPOIDetector()
{
//
valeSupSWLPivot.Clean();
peakResSWHPivot.Clean();
//
Clean(trendBullishFVGs);
trendBullishPivot.Clean();
//
Clean(trendBearishFVGs);
trendBearishPivot.Clean();
//
trendPivotP.Clean();
trendPivotC.Clean();
trendDir = X_DIRECTION_NONE;
//
CleanPivots();
//
ZeroMemory(helper);
ZeroMemory(drawer);
ZeroMemory(barAnalyser);
}
//
// Properties ...
//
// Tools ...
//
virtual void Default()
{
//
maxAllowedPivots = 50;
pivotVerifications = 5;
ticksDividerInPoints = 15;
pivotDetectionLoopbac = 100;
ticksDetectionPerid = PERIOD_D1;
//
detectTickPivots = true;
detectVolumePivots = true;
detectRSIPeakPivots = true;
detectRSIValePivots = true;
detectCCIPeakPivots = true;
detectCCIValePivots = true;
detectFVGBullishPivots = true;
detectFVGBearishPivots = true;
detectValeSupSWLPivots = true;
detectPeakResSWHPivots = true;
detectTrendBullishPivots = true;
detectTrendBearishPivots = true;
detectRSICrossedOverOSPivots = true;
detectRSICrossedUnderOBPivots = true;
detectCCICrossedOverOSPivots = true;
detectCCICrossedUnderOBPivots = true;
//
trendDir = X_DIRECTION_NONE;
}
//
void Update(
int barIndex = 0 //
)
{
//
if (barIndex < 0)
{
barIndex = 0;
}
//
int loopback = pivotDetectionLoopbac;
loopback = NormalizeInt(loopback, 50);
//
int idx = -1;
int count = 0;
bool has = false;
//
newRSIPeakPivotDetected = false;
newRSIValePivotDetected = false;
newCCIPeakPivotDetected = false;
newCCIValePivotDetected = false;
newFVGBullishPivotDetected = false;
newFVGBearishPivotDetected = false;
newValeSupSWLPivotDetected = false;
newPeakResSWHPivotDetected = false;
newTrendBullishPivotDetected = false;
newTrendBearishPivotDetected = false;
newRSICrossedOverOSPivotDetected = false;
newRSICrossedUnderOBPivotDetected = false;
newCCICrossedOverOSPivotDetected = false;
newCCICrossedUnderOBPivotDetected = 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 //
);
if (!has)
{
conditions.Clean();
continue;
}
//
// 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;
}
//
// Bars Conditions ...
//
// Bars Conditions ...
//
ENUM_X_DIRECTION cBarDir;
//
// Hammer ...
bool isCBarHammer = helper
.barAnalyser
.IsHammer(
cBar,
cBarDir //
);
bool isCBarBullishHammer =
isCBarHammer &&
IsBullish(cBarDir);
bool isCBarBearishHammer =
isCBarHammer &&
IsBearish(cBarDir);
//
// Rejected ...
bool isCBarRejected = helper
.barAnalyser
.IsRejected(
cBar,
cBarDir,
false, // Force Type ...
true // Force Fibo Pressure ...
);
bool isCBarBullishRejected =
isCBarRejected &&
IsBullish(cBarDir);
bool isCBarBearishRejected =
isCBarRejected &&
IsBearish(cBarDir);
//
// Engulfed ...
bool isCBarEngulfed = helper
.barAnalyser
.IsEngulfed(
cBar,
cBarDir //
);
bool isCBarBullishEngulfed =
isCBarEngulfed &&
IsBullish(cBarDir);
bool isCBarBearishEngulfed =
isCBarEngulfed &&
IsBearish(cBarDir);
//
// Momentum ...
bool isCBarMomentum = helper
.barAnalyser
.IsMomentum(
cBar,
cBarDir,
1 //
);
bool isCBarBullishMomentum =
isCBarMomentum &&
IsBullish(cBarDir);
bool isCBarBearishMomentum =
isCBarMomentum &&
IsBearish(cBarDir);
//
// FVG ...
//
XBoxZone fvgBox;
bool isFVG = barAnalyser.IsFVG(
cBar,
fvgBox //
);
bool isBullishFVG =
isFVG &&
fvgBox.IsBullish();
bool isBearishFVG =
isFVG &&
fvgBox.IsBearish();
//
bool isCBarHasBullishPower = isBullishFVG ||
isCBarBullishRejected ||
isCBarBullishEngulfed ||
isCBarBullishMomentum;
//
bool isCBarHasBearishPower = isBearishFVG ||
isCBarBearishRejected ||
isCBarBearishEngulfed ||
isCBarBearishMomentum;
//
// Reading Values from Conditions and
// Create Customized Conditions if required ...
//
// PEAK ...
double zPeak = conditions.peakBuffer[zIDX];
double cPeak = conditions.peakBuffer[cIDX];
double pPeak = conditions.peakBuffer[pIDX];
double p2Peak = conditions.peakBuffer[p2IDX];
//
// VALE ...
double zVale = conditions.valeBuffer[zIDX];
double cVale = conditions.valeBuffer[cIDX];
double pVale = conditions.valeBuffer[pIDX];
double p2Vale = conditions.valeBuffer[p2IDX];
//
// RSI ...
//
double zRSI = conditions.rsiBuffer[zIDX];
double cRSI = conditions.rsiBuffer[cIDX];
double pRSI = conditions.rsiBuffer[pIDX];
double p2RSI = conditions.rsiBuffer[p2IDX];
//
bool isRSIPeak =
pRSI > cRSI &&
pRSI > p2RSI &&
pRSI > zRSI;
//
bool isRSIVale =
pRSI < cRSI &&
pRSI < p2RSI &&
pRSI < zRSI;
//
// CCI ...
//
double zCCI = conditions.cciBuffer[zIDX];
double cCCI = conditions.cciBuffer[cIDX];
double pCCI = conditions.cciBuffer[pIDX];
double p2CCI = conditions.cciBuffer[p2IDX];
//
bool isCCIPeak =
pCCI > cCCI &&
pCCI > p2CCI &&
pCCI > zCCI;
//
bool isCCIVale =
pCCI < cCCI &&
pCCI < p2CCI &&
pCCI < zCCI;
//
// Extracting Required Data about Trending ...
//
double zFast = conditions.fastBuffer[zIDX];
double cFast = conditions.fastBuffer[cIDX];
double pFast = conditions.fastBuffer[pIDX];
double p2Fast = conditions.fastBuffer[p2IDX];
//
double zMedium = conditions.mediumBuffer[zIDX];
double cMedium = conditions.mediumBuffer[cIDX];
double pMedium = conditions.mediumBuffer[pIDX];
double p2Medium = conditions.mediumBuffer[p2IDX];
//
double zSlow = conditions.slowBuffer[zIDX];
double cSlow = conditions.slowBuffer[cIDX];
double pSlow = conditions.slowBuffer[pIDX];
double p2Slow = conditions.slowBuffer[p2IDX];
//
double z3Mas[] = {
zFast,
zMedium,
zSlow,
};
double z3MasMin = GetMin(z3Mas);
double z3MasMax = GetMax(z3Mas);
//
double c3Mas[] = {
cFast,
cMedium,
cSlow,
};
double c3MasMin = GetMin(c3Mas);
double c3MasMax = GetMax(c3Mas);
//
double p3Mas[] = {
pFast,
pMedium,
pSlow,
};
double p3MasMin = GetMin(p3Mas);
double p3MasMax = GetMax(p3Mas);
//
double p23Mas[] = {
p2Fast,
p2Medium,
p2Slow,
};
double p23MasMin = GetMin(p23Mas);
double p23MasMax = GetMax(p23Mas);
//
// Try to Custom Mechanism for Trend Detection ...
//
bool is3MaBullish =
cFast > cSlow &&
cMedium > cSlow;
bool is3MaBullishPrev =
pFast > pSlow &&
pMedium > pSlow;
//
bool is3MaBearish =
cFast < cSlow &&
cMedium < cSlow;
bool is3MaBearishPrev =
pFast < pSlow &&
pMedium < pSlow;
//
bool is3MaSwitchedToBullish = is3MaBullish &&
!is3MaBullishPrev;
bool is3MaSwitchedToBearish = is3MaBearish &&
!is3MaBearishPrev;
//
bool is3MaFinishedFromBullish = !is3MaBullish &&
is3MaBullishPrev;
bool is3MaFinishedFromBearish = !is3MaBearish &&
is3MaBearishPrev;
//
// TREND BULLISH Conditions ...
//
bool trendBullishStartPivotCondition =
//
// One ...
// conditions.is3MaFinishedFromBullish
// //
// ||
//
// Two ...
is3MaFinishedFromBullish
//
;
//
bool trendBullishPivotContinuationCondition =
//
// One ...
// conditions.is3MaBullish
// //
// ||
//
// Two ...
is3MaBullish
//
;
//
bool trendBullisPivothFinishedCondition =
//
// One ...
// conditions.is3MaSwitchedToBullish
// //
// ||
//
// Two ...
is3MaSwitchedToBullish
//
;
//
// TREND BEARISH Conditions ...
//
bool trendBearishStartPivotCondition =
//
// One ...
// conditions.is3MaFinishedFromBearish
// //
// ||
//
// Two ...
is3MaFinishedFromBearish
//
;
//
bool trendBearishPivotContinuationCondition =
//
// One ...
// conditions.is3MaBearish
// //
// ||
//
// Two ...
is3MaBearish
//
;
//
bool trendBearishivothFinishedCondition =
//
// One ...
// conditions.is3MaSwitchedToBearish
// //
// ||
//
// Two ...
is3MaSwitchedToBearish
//
;
//
// Checking Pivots ...
//
// Detect TICK and VOLUME Pivots ...
if (detectTickPivots || detectVolumePivots)
{
//
XOHCL ticksToBar;
XOHCL ticksFromBar;
XCTicksZone *ticksZone = NULL;
//
datetime ticksTo = GetPeriodStartTime(
zBar.symbol,
ticksDetectionPerid,
zBar.time //
);
bool isTicksBarInited = ticksToBar.Init(
zBar.symbol,
zBar.period,
ticksTo //
);
datetime ticksFrom = ticksTo - PeriodSeconds(ticksDetectionPerid);
isTicksBarInited = isTicksBarInited &&
ticksFromBar.Init(
zBar.symbol,
zBar.period,
ticksFrom //
);
bool hasValidTicksTimeRange = IsValid(ticksTo) &&
isTicksBarInited &&
IsValid(ticksFrom) &&
ticksFrom < ticksTo;
//
bool isTickPivotExists =
hasValidTicksTimeRange &&
IsExistsTickPivot(
ticksTo,
ticksFrom //
);
//
bool isVolumePivotExists =
hasValidTicksTimeRange &&
IsExistsVolumePivot(
ticksTo,
ticksFrom //
);
//
bool isInitializedZone = !isTickPivotExists ||
!isVolumePivotExists;
if (isInitializedZone)
{
//
isInitializedZone = InitializeTicksZone(
ticksZone,
ticksToBar,
ticksFromBar //
);
}
//
// TICK Pivots ...
if (detectTickPivots)
{
//
// Check Current Zone Exists or Not ...
if (isInitializedZone && !isTickPivotExists)
{
//
XBoxZone iBox;
XCTickZone *iZone;
has = ticksZone.GetMaxTickZone(iZone);
if (has)
{
//
// Try to Converts a Tick Zone to XBoxZone ...
iBox.to = ticksTo;
iBox.from = ticksFrom;
iBox.lower = iZone.low;
iBox.upper = iZone.high;
iBox.symbol = iZone.symbol;
iBox.period = iZone.period;
iBox.type = GetBoxType(XCA_TICK);
iBox.dir = X_DIRECTION_BULLISH; // Temparory ...
//
has = iBox.IsValid();
if (has)
{
//
AddBox(
iBox,
tickPivots //
);
}
}
//
iBox.Clean();
ZeroMemory(iZone);
}
}
//
// VOLUME Pivots ...
if (detectVolumePivots)
{
//
// Check Current Zone Exists or Not ...
if (isInitializedZone && !isVolumePivotExists)
{
//
XBoxZone iBox;
XCTickZone *iZone;
has = ticksZone.GetMaxVolumeZone(iZone);
if (has)
{
//
// Try to Converts a Tick Zone to XBoxZone ...
iBox.to = ticksTo;
iBox.from = ticksFrom;
iBox.lower = iZone.low;
iBox.upper = iZone.high;
iBox.symbol = iZone.symbol;
iBox.period = iZone.period;
iBox.type = GetBoxType(XCA_VOLUME);
iBox.dir = X_DIRECTION_BULLISH; // Temparory ...
//
has = iBox.IsValid();
if (has)
{
//
AddBox(
iBox,
volumePivots //
);
}
}
//
iBox.Clean();
ZeroMemory(iZone);
}
}
//
ticksToBar.Clean();
ticksFromBar.Clean();
ZeroMemory(ticksZone);
//
}
//
// RSI Peak Pivot ...
if (detectRSIPeakPivots)
{
//
bool checkingCondition =
isRSIPeak &&
isCBarHasBearishPower // &&
// conditions.isRSICrossedUnderOB
;
//
if (checkingCondition)
{
//
XCAPivot iPivot;
//
iPivot.to = cBar.time;
iPivot.from = p2Bar.time;
iPivot.value = pBar.high;
iPivot.type = XCA_RSI_PEAK;
iPivot.symbol = cBar.symbol;
iPivot.period = cBar.period;
//
Add(
cBar.high,
iPivot.values //
);
Add(
pBar.high,
iPivot.values //
);
Add(
p2Bar.high,
iPivot.values //
);
Add(
cBar.close,
iPivot.values //
);
Add(
pBar.close,
iPivot.values //
);
Add(
p2Bar.close,
iPivot.values //
);
//
iPivot.reserve = GetMin(iPivot.values);
//
XBoxZone iBox;
has = iPivot.IsValid();
if (has)
{
//
has = iPivot.AsBox(iBox);
if (has)
{
//
newRSIPeakPivotDetected = AddBox(
iBox,
rsiPeakPivots //
);
}
}
//
iBox.Clean();
iPivot.Clean();
}
}
//
// RSI Vale Pivot ...
if (detectRSIValePivots)
{
//
bool checkingCondition =
isRSIVale &&
isCBarHasBullishPower // &&
// conditions.isRSICrossedOverOS
;
//
if (checkingCondition)
{
//
XCAPivot iPivot;
//
iPivot.to = cBar.time;
iPivot.from = p2Bar.time;
iPivot.value = pBar.low;
iPivot.type = XCA_RSI_VALE;
iPivot.symbol = cBar.symbol;
iPivot.period = cBar.period;
//
Add(
cBar.low,
iPivot.values //
);
Add(
pBar.low,
iPivot.values //
);
Add(
p2Bar.low,
iPivot.values //
);
Add(
cBar.close,
iPivot.values //
);
Add(
pBar.close,
iPivot.values //
);
Add(
p2Bar.close,
iPivot.values //
);
//
iPivot.reserve = GetMax(iPivot.values);
//
XBoxZone iBox;
has = iPivot.IsValid();
if (has)
{
//
has = iPivot.AsBox(iBox);
if (has)
{
//
newRSIValePivotDetected = AddBox(
iBox,
rsiValePivots //
);
}
}
//
iBox.Clean();
iPivot.Clean();
}
}
//
// CCI Peak Pivot ...
if (detectCCIPeakPivots)
{
//
bool checkingCondition =
isCCIPeak &&
isCBarHasBearishPower // &&
// conditions.isCCICrossedUnderOB
;
//
if (checkingCondition)
{
//
XCAPivot iPivot;
//
iPivot.to = cBar.time;
iPivot.from = p2Bar.time;
iPivot.value = pBar.high;
iPivot.type = XCA_CCI_PEAK;
iPivot.symbol = cBar.symbol;
iPivot.period = cBar.period;
//
Add(
cBar.high,
iPivot.values //
);
Add(
pBar.high,
iPivot.values //
);
Add(
p2Bar.high,
iPivot.values //
);
Add(
cBar.close,
iPivot.values //
);
Add(
pBar.close,
iPivot.values //
);
Add(
p2Bar.close,
iPivot.values //
);
//
iPivot.reserve = GetMin(iPivot.values);
//
XBoxZone iBox;
has = iPivot.IsValid();
if (has)
{
//
has = iPivot.AsBox(iBox);
if (has)
{
//
newCCIPeakPivotDetected = AddBox(
iBox,
cciPeakPivots //
);
}
}
//
iBox.Clean();
iPivot.Clean();
}
}
//
// CCI Vale Pivot ...
if (detectCCIValePivots)
{
//
bool checkingCondition =
isCCIVale &&
isCBarHasBullishPower // &&
// conditions.isCCICrossedOverOS
;
//
if (checkingCondition)
{
//
XCAPivot iPivot;
//
iPivot.to = cBar.time;
iPivot.from = p2Bar.time;
iPivot.value = pBar.low;
iPivot.type = XCA_CCI_VALE;
iPivot.symbol = cBar.symbol;
iPivot.period = cBar.period;
//
Add(
cBar.low,
iPivot.values //
);
Add(
pBar.low,
iPivot.values //
);
Add(
p2Bar.low,
iPivot.values //
);
Add(
cBar.close,
iPivot.values //
);
Add(
pBar.close,
iPivot.values //
);
Add(
p2Bar.close,
iPivot.values //
);
//
iPivot.reserve = GetMax(iPivot.values);
//
XBoxZone iBox;
has = iPivot.IsValid();
if (has)
{
//
has = iPivot.AsBox(iBox);
if (has)
{
//
newCCIValePivotDetected = AddBox(
iBox,
cciValePivots //
);
}
}
//
iBox.Clean();
iPivot.Clean();
}
}
//
// FVG Bullish ...
if (detectFVGBullishPivots)
{
//
if (isBullishFVG)
{
//
XBoxZone iBox;
XCAPivot iPivot;
//
iPivot.to = fvgBox.to;
iPivot.from = fvgBox.from;
iPivot.type = XCA_FVG_BULL;
iPivot.value = fvgBox.lower;
iPivot.reserve = fvgBox.upper;
iPivot.symbol = fvgBox.symbol;
iPivot.period = fvgBox.period;
//
has = iPivot.IsValid();
if (has)
{
//
has = iPivot.AsBox(iBox);
if (has)
{
//
newFVGBullishPivotDetected = AddBox(
iBox,
fvgBullishPivots //
);
}
}
//
iBox.Clean();
iPivot.Clean();
}
}
//
// FVG Bearish ...
if (detectFVGBearishPivots)
{
//
if (isBearishFVG)
{
//
XBoxZone iBox;
XCAPivot iPivot;
//
iPivot.to = fvgBox.to;
iPivot.from = fvgBox.from;
iPivot.type = XCA_FVG_BEAR;
iPivot.value = fvgBox.upper;
iPivot.reserve = fvgBox.lower;
iPivot.symbol = fvgBox.symbol;
iPivot.period = fvgBox.period;
//
has = iPivot.IsValid();
if (has)
{
//
has = iPivot.AsBox(iBox);
if (has)
{
//
newFVGBearishPivotDetected = AddBox(
iBox,
fvgBearishPivots //
);
}
}
//
iBox.Clean();
iPivot.Clean();
}
}
//
// 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;
has = valeSupSWLPivot.AsBox(iBox);
if (has)
{
//
newValeSupSWLPivotDetected = AddBox(
iBox,
valeSupSWLPivots //
);
}
//
iBox.Clean();
}
//
valeSupSWLPivot.Clean();
}
}
//
// PEAK Pivot Resistance Swing High ...
if (detectPeakResSWHPivots)
{
//
if (conditions.isPeakFinishedFromPivot)
{
//
peakResSWHPivot.Clean();
//
peakResSWHPivot.type = XCA_PEAKSWHRES;
peakResSWHPivot.symbol = conditions.symbol;
peakResSWHPivot.period = conditions.period;
//
peakResSWHPivot.to = pBar.time;
peakResSWHPivot.from = pBar.time;
peakResSWHPivot.value = conditions.peakBuffer[pIDX];
peakResSWHPivot.reserve = conditions.peakGoldenBuffer[pIDX];
}
//
if (conditions.isPeakIsPivot)
{
//
peakResSWHPivot.from = pBar.time;
//
peakResSWHPivot.reserve =
peakResSWHPivot.reserve == 0
? conditions.peakGoldenBuffer[cIDX]
: MathMax(peakResSWHPivot.reserve, conditions.peakGoldenBuffer[cIDX]);
}
//
if (conditions.isPeakSwitchedToPivot)
{
//
has =
peakResSWHPivot.IsValid() &&
peakResSWHPivot.GetAge() >= pivotVerifications;
if (has)
{
//
XBoxZone iBox;
has = peakResSWHPivot.AsBox(iBox);
if (has)
{
//
newPeakResSWHPivotDetected = AddBox(
iBox,
peakResSWHPivots //
);
}
//
iBox.Clean();
}
//
peakResSWHPivot.Clean();
}
}
//
// TREND Bullish ...
if (detectTrendBullishPivots)
{
//
if (trendBullishStartPivotCondition)
{
//
Clean(trendBullishFVGs);
trendBullishPivot.Clean();
//
trendBullishPivot.type = XCA_TREND_BULL;
trendBullishPivot.symbol = conditions.symbol;
trendBullishPivot.period = conditions.period;
//
trendBullishPivot.to = pBar.time;
trendBullishPivot.from = pBar.time;
trendBullishPivot.value = p3MasMin;
trendBullishPivot.reserve = p3MasMax;
}
//
if (trendBullishPivotContinuationCondition)
{
//
trendBullishPivot.from = pBar.time;
//
Add(
p3MasMin,
trendBullishPivot.values //
);
Add(
p3MasMax,
trendBullishPivot.values //
);
//
trendBullishPivot.reserve =
trendBullishPivot.reserve == 0
? p3MasMax
: MathMax(trendBullishPivot.reserve, p3MasMax);
//
// Handling FVGs Here ...
if (isBullishFVG)
{
//
AddBox(
fvgBox,
trendBullishFVGs //
);
}
}
//
if (trendBullisPivothFinishedCondition)
{
//
// Update Values ...
trendBullishPivot.value = GetMin(trendBullishPivot.values);
trendBullishPivot.reserve = GetMax(trendBullishPivot.values);
//
has =
trendBullishPivot.IsValid() &&
trendBullishPivot.GetAge() >= pivotVerifications;
if (has)
{
//
XBoxZone iBox;
has = trendBullishPivot.AsBox(iBox);
if (has)
{
//
XCATRENDFVG iTrendFVG;
//
iTrendFVG.trend = iBox;
Copy(
trendBullishFVGs,
iTrendFVG.fvgs //
);
//
newTrendBullishPivotDetected = iTrendFVG.IsValid();
if (newTrendBullishPivotDetected)
{
//
AddRef(
iTrendFVG,
trendBullishPivots //
);
}
//
iTrendFVG.Clean();
}
//
iBox.Clean();
}
//
Clean(trendBullishFVGs);
trendBullishPivot.Clean();
}
}
//
// TREND Bearish ...
if (detectTrendBearishPivots)
{
//
if (trendBearishStartPivotCondition)
{
//
Clean(trendBearishFVGs);
trendBearishPivot.Clean();
//
trendBearishPivot.type = XCA_TREND_BEAR;
trendBearishPivot.symbol = conditions.symbol;
trendBearishPivot.period = conditions.period;
//
trendBearishPivot.to = pBar.time;
trendBearishPivot.from = pBar.time;
trendBearishPivot.value = p3MasMax;
trendBearishPivot.reserve = p3MasMin;
}
//
if (trendBearishPivotContinuationCondition)
{
//
trendBearishPivot.from = pBar.time;
//
Add(
p3MasMin,
trendBearishPivot.values //
);
Add(
p3MasMax,
trendBearishPivot.values //
);
//
trendBearishPivot.reserve =
trendBearishPivot.reserve == 0
? p3MasMin
: MathMin(trendBearishPivot.reserve, p3MasMin);
//
// Handling FVGs Here ...
if (isBearishFVG)
{
//
AddBox(
fvgBox,
trendBearishFVGs //
);
}
}
//
if (trendBearishivothFinishedCondition)
{
//
// Update Values ...
trendBearishPivot.value = GetMax(trendBearishPivot.values);
trendBearishPivot.reserve = GetMin(trendBearishPivot.values);
//
has =
trendBearishPivot.IsValid() &&
trendBearishPivot.GetAge() >= pivotVerifications;
if (has)
{
//
XBoxZone iBox;
has = trendBearishPivot.AsBox(iBox);
if (has)
{
//
XCATRENDFVG iTrendFVG;
//
iTrendFVG.trend = iBox;
Copy(
trendBearishFVGs,
iTrendFVG.fvgs //
);
//
newTrendBearishPivotDetected = iTrendFVG.IsValid();
if (newTrendBearishPivotDetected)
{
//
AddRef(
iTrendFVG,
trendBearishPivots //
);
}
//
iTrendFVG.Clean();
}
//
iBox.Clean();
}
//
Clean(trendBearishFVGs);
trendBearishPivot.Clean();
}
}
//
// RSI Crossed Over OS ...
if (detectRSICrossedOverOSPivots)
{
//
bool checkingCondition =
// isRSIVale &&
// isCBarHasBullishPower &&
conditions.isRSICrossedOverOS;
//
if (checkingCondition)
{
//
XCAPivot iPivot;
//
iPivot.to = cBar.time;
iPivot.value = pBar.low;
iPivot.from = p2Bar.time;
iPivot.type = XCA_RSI_COOS;
iPivot.symbol = cBar.symbol;
iPivot.period = cBar.period;
//
Add(
cBar.high,
iPivot.values //
);
Add(
pBar.high,
iPivot.values //
);
Add(
p2Bar.high,
iPivot.values //
);
Add(
cBar.low,
iPivot.values //
);
Add(
pBar.low,
iPivot.values //
);
Add(
p2Bar.low,
iPivot.values //
);
//
iPivot.value = GetMin(iPivot.values);
iPivot.reserve = GetMax(iPivot.values);
//
XBoxZone iBox;
has = iPivot.IsValid();
if (has)
{
//
has = iPivot.AsBox(iBox);
if (has)
{
//
newRSICrossedOverOSPivotDetected = AddBox(
iBox,
rsiCrossedOverOSPivots //
);
}
}
//
iBox.Clean();
iPivot.Clean();
}
}
//
// RSI Crossed Under OB ...
if (detectRSICrossedUnderOBPivots)
{
//
bool checkingCondition =
// isRSIPeak &&
// isCBarHasBearishPower &&
conditions.isRSICrossedUnderOB;
//
if (checkingCondition)
{
//
XCAPivot iPivot;
//
iPivot.to = cBar.time;
iPivot.from = p2Bar.time;
iPivot.value = pBar.high;
iPivot.type = XCA_RSI_CUOB;
iPivot.symbol = cBar.symbol;
iPivot.period = cBar.period;
//
Add(
cBar.high,
iPivot.values //
);
Add(
pBar.high,
iPivot.values //
);
Add(
p2Bar.high,
iPivot.values //
);
Add(
cBar.low,
iPivot.values //
);
Add(
pBar.low,
iPivot.values //
);
Add(
p2Bar.low,
iPivot.values //
);
//
iPivot.value = GetMax(iPivot.values);
iPivot.reserve = GetMin(iPivot.values);
//
XBoxZone iBox;
has = iPivot.IsValid();
if (has)
{
//
has = iPivot.AsBox(iBox);
if (has)
{
//
newRSICrossedUnderOBPivotDetected = AddBox(
iBox,
rsiCrossedUnderOBPivots //
);
}
}
//
iBox.Clean();
iPivot.Clean();
}
}
//
// CCI Crossed Over OS ...
if (detectCCICrossedOverOSPivots)
{
//
bool checkingCondition =
isCCIVale &&
// isCBarHasBullishPower &&
conditions.isCCICrossedOverOS;
//
if (checkingCondition)
{
//
XCAPivot iPivot;
//
iPivot.to = cBar.time;
iPivot.value = pBar.low;
iPivot.from = p2Bar.time;
iPivot.type = XCA_CCI_COOS;
iPivot.symbol = cBar.symbol;
iPivot.period = cBar.period;
//
Add(
cBar.high,
iPivot.values //
);
Add(
pBar.high,
iPivot.values //
);
Add(
p2Bar.high,
iPivot.values //
);
Add(
cBar.low,
iPivot.values //
);
Add(
pBar.low,
iPivot.values //
);
Add(
p2Bar.low,
iPivot.values //
);
//
iPivot.value = GetMin(iPivot.values);
iPivot.reserve = GetMax(iPivot.values);
//
XBoxZone iBox;
has = iPivot.IsValid();
if (has)
{
//
has = iPivot.AsBox(iBox);
if (has)
{
//
newCCICrossedOverOSPivotDetected = AddBox(
iBox,
cciCrossedOverOSPivots //
);
}
}
//
iBox.Clean();
iPivot.Clean();
}
}
//
// CCI Crossed Under OB ...
if (detectCCICrossedUnderOBPivots)
{
//
bool checkingCondition =
isCCIPeak &&
// isCBarHasBearishPower &&
conditions.isCCICrossedUnderOB;
//
if (checkingCondition)
{
//
XCAPivot iPivot;
//
iPivot.to = cBar.time;
iPivot.from = p2Bar.time;
iPivot.value = pBar.high;
iPivot.type = XCA_CCI_CUOB;
iPivot.symbol = cBar.symbol;
iPivot.period = cBar.period;
//
Add(
cBar.high,
iPivot.values //
);
Add(
pBar.high,
iPivot.values //
);
Add(
p2Bar.high,
iPivot.values //
);
Add(
cBar.low,
iPivot.values //
);
Add(
pBar.low,
iPivot.values //
);
Add(
p2Bar.low,
iPivot.values //
);
//
iPivot.value = GetMax(iPivot.values);
iPivot.reserve = GetMin(iPivot.values);
//
XBoxZone iBox;
has = iPivot.IsValid();
if (has)
{
//
has = iPivot.AsBox(iBox);
if (has)
{
//
newCCICrossedUnderOBPivotDetected = AddBox(
iBox,
cciCrossedUnderOBPivots //
);
}
}
//
iBox.Clean();
iPivot.Clean();
}
}
//
start++;
//
Clean(z3Mas);
Clean(c3Mas);
Clean(p3Mas);
Clean(p23Mas);
//
zBar.Clean();
cBar.Clean();
pBar.Clean();
p2Bar.Clean();
fvgBox.Clean();
conditions.Clean();
}
//
SortPivots();
}
//
void Validate(
XBoxZone &unAvailableBoxes[],
int barIndex = 0 //
)
{
//
// Do All Pivots Validation ...
//
if (barIndex < 0)
{
barIndex = 0;
}
//
bool has = false;
//
int zIDX = 0;
int cIDX = zIDX + 1;
int pIDX = cIDX + 1;
int p2IDX = pIDX + 1;
//
// Implement Validation Senarios ...
//
// TICK Pivots ...
//
// TODO: Complete this ...
has = HasTickPivots();
if (has)
{
//
}
//
// VOLUME Pivots ...
//
// TODO: Complete this ...
has = HasVolumePivots();
if (has)
{
//
}
//
// RSI Peak Pivot ...
//
has = HasRSIPeakPivots();
if (has)
{
//
ApplyValidationOnBox(
rsiPeakPivots,
unAvailableBoxes,
barIndex //
);
}
//
// RSI Vale Pivot ...
//
has = HasRSIValePivots();
if (has)
{
//
ApplyValidationOnBox(
rsiValePivots,
unAvailableBoxes,
barIndex //
);
}
//
// CCI Peak Pivot ...
//
has = HasCCIPeakPivots();
if (has)
{
//
ApplyValidationOnBox(
cciPeakPivots,
unAvailableBoxes,
barIndex //
);
}
//
// CCI Vale Pivot ...
//
has = HasCCIValePivots();
if (has)
{
//
ApplyValidationOnBox(
cciValePivots,
unAvailableBoxes,
barIndex //
);
}
//
// FVG Bullish ...
//
has = HasFVGBullishPivots();
if (has)
{
//
ApplyValidationOnBox(
fvgBullishPivots,
unAvailableBoxes,
barIndex //
);
}
//
// FVG Bearish ...
//
has = HasFVGBearishPivots();
if (has)
{
//
ApplyValidationOnBox(
fvgBearishPivots,
unAvailableBoxes,
barIndex //
);
}
//
// VALE Pivot Support Swing Low ...
//
has = HasValeSupSWLPivots();
if (has)
{
//
ApplyValidationOnBox(
valeSupSWLPivots,
unAvailableBoxes,
barIndex //
);
}
//
// PEAK Pivot Resistance Swing High ...
//
has = HasPeakResSWHPivots();
if (has)
{
//
ApplyValidationOnBox(
peakResSWHPivots,
unAvailableBoxes,
barIndex //
);
}
//
// TREND Bullish ...
//
has = HasTrendBullishPivots();
if (has)
{
//
ApplyValidationOnTrendFVG(
trendBullishPivots,
unAvailableBoxes,
barIndex //
);
}
//
// TREND Bearish ...
//
has = HasTrendBearishPivots();
if (has)
{
//
ApplyValidationOnTrendFVG(
trendBearishPivots,
unAvailableBoxes,
barIndex //
);
}
//
// RSI Crossed Over OS ...
//
has = HasRSICrossedOverOSPivots();
if (has)
{
//
ApplyValidationOnBox(
rsiCrossedOverOSPivots,
unAvailableBoxes,
barIndex //
);
}
//
// RSI Crossed Under OB ...
//
has = HasRSICrossedUnderOBPivots();
if (has)
{
//
ApplyValidationOnBox(
rsiCrossedUnderOBPivots,
unAvailableBoxes,
barIndex //
);
}
//
// CCI Crossed Over OS ...
//
has = HasCCICrossedOverOSPivots();
if (has)
{
//
ApplyValidationOnBox(
cciCrossedOverOSPivots,
unAvailableBoxes,
barIndex //
);
}
//
// CCI Crossed Under OB ...
//
has = HasCCICrossedUnderOBPivots();
if (has)
{
//
ApplyValidationOnBox(
cciCrossedUnderOBPivots,
unAvailableBoxes,
barIndex //
);
}
//
SortPivots();
}
//
int FillPivots(
XBoxZone &pivots[],
ENUM_X_DIRECTION forDir = X_DIRECTION_ALL //
)
{
//
int result = 0;
//
Clean(pivots);
//
if (forDir == X_DIRECTION_NONE)
{
return result;
}
//
int count = 0;
bool has = false;
//
bool canFillBullish =
forDir == X_DIRECTION_ALL ||
forDir == X_DIRECTION_BULLISH;
//
bool canFillBearish =
forDir == X_DIRECTION_ALL ||
forDir == X_DIRECTION_BEARISH;
//
// Bullish ...
if (canFillBullish)
{
//
Copy(
rsiValePivots,
pivots,
false //
);
//
Copy(
cciValePivots,
pivots,
false //
);
//
Copy(
fvgBullishPivots,
pivots,
false //
);
//
Copy(
valeSupSWLPivots,
pivots,
false //
);
//
Copy(
rsiCrossedOverOSPivots,
pivots,
false //
);
//
Copy(
cciCrossedOverOSPivots,
pivots,
false //
);
//
has = HasTrendBullishPivots();
if (has)
{
//
count = CountTrendBullishPivots();
for (int i = 0; i < count; i++)
{
//
AddRef(
trendBullishPivots[i].trend,
pivots //
);
//
XBoxZone iBox;
has = trendBullishPivots[i].GetSelectedFVG(iBox);
if (has)
{
//
AddRef(
iBox,
pivots //
);
}
//
iBox.Clean();
}
}
}
//
// Bearish ...
if (canFillBearish)
{
//
Copy(
rsiPeakPivots,
pivots,
false //
);
//
Copy(
cciPeakPivots,
pivots,
false //
);
//
Copy(
fvgBearishPivots,
pivots,
false //
);
//
Copy(
peakResSWHPivots,
pivots,
false //
);
//
Copy(
rsiCrossedUnderOBPivots,
pivots,
false //
);
//
Copy(
cciCrossedUnderOBPivots,
pivots,
false //
);
//
has = HasTrendBearishPivots();
if (has)
{
//
count = CountTrendBearishPivots();
for (int i = 0; i < count; i++)
{
//
AddRef(
trendBearishPivots[i].trend,
pivots //
);
//
XBoxZone iBox;
has = trendBearishPivots[i].GetSelectedFVG(iBox);
if (has)
{
//
AddRef(
iBox,
pivots //
);
}
//
iBox.Clean();
}
}
}
//
result = ArraySize(pivots);
//
return result;
}
//
bool MarketTrend(ENUM_X_DIRECTION &trend)
{
//
bool result = false;
//
// Update Market Trend ...
DetectMarketTrend();
//
trend = trendDir;
result = HasDirection(trend);
//
return result;
}
//
// Counters ...
//
// INVALID Pivots ...
//
bool HasInvalidPivots()
{
return HasChild(invalidPivots);
}
//
int CountInvalidPivots()
{
return ArraySize(invalidPivots);
}
//
// TICK Pivot ...
//
bool HasTickPivots()
{
return HasChild(tickPivots);
}
//
int CountTickPivots()
{
return ArraySize(tickPivots);
}
//
// VOLUME Pivots ...
//
bool HasVolumePivots()
{
return HasChild(volumePivots);
}
//
int CountVolumePivots()
{
return ArraySize(volumePivots);
}
//
// 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);
}
//
// FVG Bullish ...
//
bool HasFVGBullishPivots()
{
return HasChild(fvgBullishPivots);
}
//
int CountFVGBullishPivots()
{
return ArraySize(fvgBullishPivots);
}
//
// FVG Bearish ...
//
bool HasFVGBearishPivots()
{
return HasChild(fvgBearishPivots);
}
//
int CountFVGBearishPivots()
{
return ArraySize(fvgBearishPivots);
}
//
// 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);
}
//
// TREND Bullish ...
//
bool HasTrendBullishPivots()
{
return HasChild(trendBullishPivots);
}
//
int CountTrendBullishPivots()
{
return ArraySize(trendBullishPivots);
}
//
// TREND Bearish ...
//
bool HasTrendBearishPivots()
{
return HasChild(trendBearishPivots);
}
//
int CountTrendBearishPivots()
{
return ArraySize(trendBearishPivots);
}
//
// RSI Crossed Over OS Pivots ...
//
bool HasRSICrossedOverOSPivots()
{
return HasChild(rsiCrossedOverOSPivots);
}
//
int CountRSICrossedOverOSPivots()
{
return ArraySize(rsiCrossedOverOSPivots);
}
//
// RSI Crossed Under OB Pivots ...
//
bool HasRSICrossedUnderOBPivots()
{
return HasChild(rsiCrossedUnderOBPivots);
}
//
int CountRSICrossedUnderOBPivots()
{
return ArraySize(rsiCrossedUnderOBPivots);
}
//
// CCI Crossed Over OS Pivots ...
//
bool HasCCICrossedOverOSPivots()
{
return HasChild(cciCrossedOverOSPivots);
}
//
int CountCCICrossedOverOSPivots()
{
return ArraySize(rsiCrossedOverOSPivots);
}
//
// CCI Crossed Under OB Pivots ...
//
bool HasCCICrossedUnderOBPivots()
{
return HasChild(cciCrossedUnderOBPivots);
}
//
int CountCCICrossedUnderOBPivots()
{
return ArraySize(cciCrossedUnderOBPivots);
}
//
// Protected ...
protected:
//
// Props ...
//
// Prrivate ...
private:
//
// Props ...
//
XCPOIDrawer *drawer;
XCXCAEAHelper *helper;
XCBarAnalyser *barAnalyser;
//
bool AddBox(
XBoxZone &box,
XBoxZone &boxes[] //
)
{
//
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);
//
AddRef(
box,
boxes //
);
//
int after = ArraySize(boxes);
//
result = after > before;
//
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;
}
//
void CleanPivots()
{
//
Clean(invalidPivots);
//
Clean(tickPivots);
Clean(volumePivots);
Clean(rsiPeakPivots);
Clean(rsiValePivots);
Clean(cciPeakPivots);
Clean(cciValePivots);
Clean(fvgBullishPivots);
Clean(fvgBearishPivots);
Clean(valeSupSWLPivots);
Clean(peakResSWHPivots);
Clean(trendBullishPivots);
Clean(trendBearishPivots);
Clean(rsiCrossedOverOSPivots);
Clean(rsiCrossedUnderOBPivots);
Clean(cciCrossedOverOSPivots);
Clean(cciCrossedUnderOBPivots);
}
//
void SortPivots()
{
//
bool has = false;
//
// RSI Peak ...
has = HasRSIPeakPivots();
if (has)
{
ApplySortOnBox(rsiPeakPivots);
}
//
// RSI Vale ...
has = HasRSIValePivots();
if (has)
{
ApplySortOnBox(rsiValePivots);
}
//
// CCI Peak ...
has = HasCCIPeakPivots();
if (has)
{
ApplySortOnBox(cciPeakPivots);
}
//
// CCI Vale ...
has = HasCCIValePivots();
if (has)
{
ApplySortOnBox(cciValePivots);
}
//
// FVG Bullish ...
has = HasFVGBullishPivots();
if (has)
{
ApplySortOnBox(fvgBullishPivots);
}
//
// FVG Bearish ...
has = HasFVGBearishPivots();
if (has)
{
ApplySortOnBox(fvgBearishPivots);
}
//
// VALE SUP SWL ...
has = HasValeSupSWLPivots();
if (has)
{
ApplySortOnBox(valeSupSWLPivots);
}
//
// PEAK REs SWH ...
has = HasPeakResSWHPivots();
if (has)
{
ApplySortOnBox(peakResSWHPivots);
}
//
// PVFVG Bullish ...
has = HasTrendBullishPivots();
if (has)
{
ApplySortOnTrendFVG(trendBullishPivots);
}
//
// PVFVG Bearish ...
has = HasTrendBearishPivots();
if (has)
{
ApplySortOnTrendFVG(trendBearishPivots);
}
//
// RSI Crossed Over OS ...
has = HasRSICrossedOverOSPivots();
if (has)
{
ApplySortOnBox(rsiCrossedOverOSPivots);
}
//
// RSI Crossed Under OB ...
has = HasRSICrossedUnderOBPivots();
if (has)
{
ApplySortOnBox(rsiCrossedUnderOBPivots);
}
//
// CCI Crossed Over OS ...
has = HasCCICrossedOverOSPivots();
if (has)
{
ApplySortOnBox(cciCrossedOverOSPivots);
}
//
// CCI Crossed Under OB ...
has = HasCCICrossedUnderOBPivots();
if (has)
{
ApplySortOnBox(cciCrossedUnderOBPivots);
}
//
// INVALID Pivots ...
has = HasInvalidPivots();
if (has)
{
ApplySortOnBox(invalidPivots);
}
}
//
void ApplyValidationOnBox(
XBoxZone &items[],
XBoxZone &unAvailableItems[],
int barIndex = 0 //
)
{
//
bool has = false;
//
has = HasChild(items);
if (!has)
{
return;
}
//
XBoxZone tmp[];
Copy(
items,
tmp //
);
Clean(items);
while (HasChild(tmp))
{
//
XBoxZone iBox = tmp[0];
ArrayRemove(
tmp,
0,
1 //
);
//
has = ValidateBox(
iBox,
unAvailableItems,
barIndex //
);
if (has)
{
//
AddRef(
iBox,
items //
);
}
//
iBox.Clean();
//
}
//
Clean(tmp);
}
//
void ApplyValidationOnTrendFVG(
XCATRENDFVG &items[],
XBoxZone &unAvailableItems[],
int barIndex = 0 //
)
{
//
bool has = false;
//
has = HasChild(items);
if (!has)
{
return;
}
//
XCATRENDFVG tmp[];
Copy(
items,
tmp //
);
Clean(items);
while (HasChild(tmp))
{
//
XCATRENDFVG iTrendFVG = tmp[0];
ArrayRemove(
tmp,
0,
1 //
);
//
// Validate TMP Trend Box ...
has = ValidateBox(
iTrendFVG.trend,
unAvailableItems,
barIndex //
);
if (has)
{
//
// Now we Have to Validate FVGS ...
ApplyValidationOnBox(
iTrendFVG.fvgs,
unAvailableItems,
barIndex //
);
//
has = iTrendFVG.IsValid();
if (has)
{
//
AddRef(
iTrendFVG,
items //
);
}
}
//
iTrendFVG.Clean();
}
//
Clean(tmp);
}
//
void ApplySortOnBox(
XBoxZone &items[] //
)
{
//
int idx = -1;
bool has = false;
//
has = HasChild(items);
if (!has)
{
return;
}
//
XBoxZone tmp[];
Copy(
items,
tmp //
);
Clean(items);
//
while (HasChild(tmp))
{
//
idx = GetOldest(tmp);
has = IsValidIndex(idx);
if (!has)
{
break;
}
//
XBoxZone iBox = tmp[idx];
ArrayRemove(
tmp,
idx,
1 //
);
//
AddRef(
iBox,
items //
);
}
//
CleanupArray(
items,
maxAllowedPivots //
);
//
Clean(tmp);
}
//
void ApplySortOnTrendFVG(
XCATRENDFVG &items[] //
)
{
//
int idx = -1;
bool has = false;
//
has = HasChild(items);
if (!has)
{
return;
}
//
XCATRENDFVG tmp[];
Copy(
items,
tmp //
);
Clean(items);
//
while (HasChild(tmp))
{
//
idx = GetOldest(tmp);
has = IsValidIndex(idx);
if (!has)
{
break;
}
//
XCATRENDFVG iTrendFVG = tmp[idx];
ArrayRemove(
tmp,
idx,
1 //
);
//
AddRef(
iTrendFVG,
items //
);
}
//
CleanupArray(
items,
maxAllowedPivots //
);
//
Clean(tmp);
}
//
//
bool IsExistsTickPivot(
datetime to,
datetime from //
)
{
//
bool result = false;
//
// Validate Args ...
result = IsValid(to) &&
IsValid(from) &&
to > from;
if (!result)
{
return result;
}
//
result = HasTickPivots();
if (!result)
{
return result;
}
//
int idx = -1;
int count = CountTickPivots();
for (int i = 0; i < count; i++)
{
//
XBoxZone iBox = tickPivots[i];
//
result = iBox.to == to &&
iBox.from == from;
if (result)
{
//
idx = i;
iBox.Clean();
//
break;
}
//
iBox.Clean();
}
//
result = IsValidIndex(idx);
//
return result;
}
//
bool IsExistsVolumePivot(
datetime to,
datetime from //
)
{
//
bool result = false;
//
// Validate Args ...
result = IsValid(to) &&
IsValid(from) &&
to > from;
if (!result)
{
return result;
}
//
result = HasVolumePivots();
if (!result)
{
return result;
}
//
int idx = -1;
int count = CountVolumePivots();
for (int i = 0; i < count; i++)
{
//
XBoxZone iBox = volumePivots[i];
//
result = iBox.to == to &&
iBox.from == from;
if (result)
{
//
idx = i;
iBox.Clean();
//
break;
}
//
iBox.Clean();
}
//
result = IsValidIndex(idx);
//
return result;
}
//
bool InitializeTicksZone(
XCTicksZone *&zone,
XOHCL &toBar,
XOHCL &fromBar //
)
{
//
bool result = false;
//
result = zone == NULL;
if (!result)
{
return result;
}
//
int toIDX = toBar.Index();
int fromIDX = fromBar.Index();
int rangeLength = fromIDX - toIDX;
double rangeDivider = ticksDividerInPoints * GetPoints(toBar.symbol);
double rangeL = toBar.FindLowest(rangeLength, MODE_LOW);
double rangeH = toBar.FindHighest(rangeLength, MODE_HIGH);
double rangeDiff = (rangeH - rangeL);
int zoneLevels = (int)(rangeDiff / rangeDivider);
//
zone = new XCTicksZone();
zone.Levels(zoneLevels);
//
result = zone.Init(
fromBar,
toBar //
);
if (!result)
{
ZeroMemory(zone);
}
//
return result;
}
//
void DetectMarketTrend()
{
//
int idx = -1;
int count = 0;
bool has = false;
//
XBoxZone tmp[];
has = HasPeakResSWHPivots();
if (has)
{
//
Copy(
peakResSWHPivots,
tmp,
false //
);
}
has = HasValeSupSWLPivots();
if (has)
{
//
Copy(
valeSupSWLPivots,
tmp,
false //
);
}
count = ArraySize(tmp);
has = HasChild(tmp);
if (!has)
{
return;
}
//
has = HasDirection(trendDir);
if (!has)
{
//
trendPivotC.Clean();
trendPivotP.Clean();
}
//
XBoxZone cPivot;
XBoxZone pPivot;
ENUM_X_DIRECTION dir = X_DIRECTION_NONE;
while (HasChild(tmp))
{
//
XBoxZone iPivot;
idx = GetYoungest(tmp);
has = IsValidIndex(idx);
if (!has)
{
//
iPivot.Clean();
break;
}
//
iPivot = tmp[idx];
ArrayRemove(
tmp,
idx,
1 //
);
//
// Check Can Set CPivot ...
bool canSetCPivot =
!cPivot.IsValid()
? true
: iPivot.from > cPivot.from;
if (canSetCPivot)
{
//
if (cPivot.IsValid())
{
pPivot = cPivot;
}
//
cPivot = iPivot;
}
//
// Check Can Set PPivot ...
bool canSetPPivot =
!cPivot.IsValid()
? false
: iPivot.from < cPivot.from
? !pPivot.IsValid()
? true
: iPivot.from > pPivot.from
: false;
if (canSetPPivot)
{
pPivot = iPivot;
}
//
has = cPivot.IsValid() &&
pPivot.IsValid();
if (has)
{
//
iPivot.Clean();
break;
}
//
iPivot.Clean();
}
//
// Check Resources for Detecting Conditions ...
bool hasTrend =
//
cPivot.IsValid() &&
pPivot.IsValid() &&
cPivot.dir == pPivot.dir &&
cPivot.from > pPivot.from &&
(IsBullish(cPivot.dir)
? cPivot.lower > pPivot.lower
: cPivot.upper < pPivot.upper);
//
;
if (hasTrend)
{
//
trendPivotC = cPivot;
trendPivotP = pPivot;
trendDir = cPivot.dir;
}
//
Clean(tmp);
cPivot.Clean();
pPivot.Clean();
//
}
//
};
//