Files
xMQL5/BKPS/14041018/Documents/BKP/tmp.codes.mq5
T
2026-01-08 11:39:42 +03:30

7168 lines
150 KiB
Plaintext

//
int minRequiredRange = 20;
if (barIndex > maxBarIndex - minRequiredRange - 4)
{
return;
}
//
double iP2SCLL = sLLBuffer[barIndex + 2];
double iP2SCHH = sHHBuffer[barIndex + 2];
//
double iP3SCLL = sLLBuffer[barIndex + 3];
double iP3SCHH = sHHBuffer[barIndex + 3];
//
double iP4SCLL = sLLBuffer[barIndex + 4];
double iP4SCHH = sHHBuffer[barIndex + 4];
//
double iP2MCLL = mLLBuffer[barIndex + 2];
double iP2MCHH = mHHBuffer[barIndex + 2];
//
double iP3MCLL = mLLBuffer[barIndex + 3];
double iP3MCHH = mHHBuffer[barIndex + 3];
//
double iP4MCLL = mLLBuffer[barIndex + 4];
double iP4MCHH = mHHBuffer[barIndex + 4];
//
double iP2LCLL = lLLBuffer[barIndex + 2];
double iP2LCHH = lHHBuffer[barIndex + 2];
//
double iP3LCLL = lLLBuffer[barIndex + 3];
double iP3LCHH = lHHBuffer[barIndex + 3];
//
double iP4LCLL = lLLBuffer[barIndex + 4];
double iP4LCHH = lHHBuffer[barIndex + 4];
//
double iP2HCLL = hLLBuffer[barIndex + 2];
double iP2HCHH = hHHBuffer[barIndex + 2];
//
double iP3HCLL = hLLBuffer[barIndex + 3];
double iP3HCHH = hHHBuffer[barIndex + 3];
//
double iP4HCLL = hLLBuffer[barIndex + 4];
double iP4HCHH = hHHBuffer[barIndex + 4];
//
// Cycle States ...
//
// Create Conditions ...
//
bool isSCMaOverMCMa = iSCMa > iMCMa;
bool isPSCMaOverMCMa = iPSCMa > iPMCMa;
//
bool isSCMaUnderMCMa = iSCMa < iMCMa;
bool isPSCMaUnderMCMa = iPSCMa < iPMCMa;
//
bool isSCMaCrossedOverMCMa =
isSCMaOverMCMa &&
!isPSCMaOverMCMa;
//
bool isSCMaCrossedUnderMCMa =
isSCMaUnderMCMa &&
!isPSCMaUnderMCMa;
//
bool isLCMaOverHCMa = iLCMa > iHCMa;
bool isPLCMaOverHCMa = iPLCMa > iPHCMa;
//
bool isLCMaUnderHCMa = iLCMa < iHCMa;
bool isPLCMaUnderHCMa = iPLCMa < iPHCMa;
//
bool isLCMaCrossedOverHCMa =
isLCMaOverHCMa &&
!isPLCMaOverHCMa;
//
bool isLCMaCrossedUnderHCMa =
isLCMaUnderHCMa &&
!isPLCMaUnderHCMa;
//
// SC State ...
//
bool isSCMaBullish =
iSCMaState == bullishState;
bool isPSCMaBullish =
iPSCMaState == bullishState;
//
bool isSCMaBearish =
iSCMaState == bearishState;
bool isPSCMaBearish =
iPSCMaState == bearishState;
//
bool isSCMaSwitchedToBullish =
isSCMaBullish &&
!isPSCMaBullish;
//
bool isSCMaSwitchedToBearish =
isSCMaBearish &&
!isPSCMaBearish;
//
bool isSCLLOverMCLL =
iSCLL > iMCLL;
bool isPSCLLOverMCLL =
iPSCLL > iPMCLL;
bool isP2SCLLOverMCLL =
iP2SCLL > iP2MCLL;
bool isP3SCLLOverMCLL =
iP3SCLL > iP3MCLL;
bool isP4SCLLOverMCLL =
iP4SCLL > iP4MCLL;
//
bool isSCHHUnderMCHH =
iSCHH < iMCHH;
bool isPSCHHUnderMCHH =
iPSCHH < iPMCHH;
bool isP2SCHHUnderMCHH =
iP2SCHH < iP2MCHH;
bool isP3SCHHUnderMCHH =
iP3SCHH < iP3MCHH;
bool isP4SCHHUnderMCHH =
iP4SCHH < iP4MCHH;
//
bool isSCLLCrossedOverMCLL =
isSCLLOverMCLL &&
!isPSCLLOverMCLL;
bool isPSCLLCrossedOverMCLL =
isPSCLLOverMCLL &&
!isP2SCLLOverMCLL;
bool isP2SCLLCrossedOverMCLL =
isP2SCLLOverMCLL &&
!isP3SCLLOverMCLL;
bool isP3SCLLCrossedOverMCLL =
isP3SCLLOverMCLL &&
!isP4SCLLOverMCLL;
//
bool isSCHHCrossedUnderMCHH =
isSCHHUnderMCHH &&
!isPSCHHUnderMCHH;
bool isPSCHHCrossedUnderMCHH =
isPSCHHUnderMCHH &&
!isP2SCHHUnderMCHH;
bool isP2SCHHCrossedUnderMCHH =
isP2SCHHUnderMCHH &&
!isP3SCHHUnderMCHH;
bool isP3SCHHCrossedUnderMCHH =
isP3SCHHUnderMCHH &&
!isP4SCHHUnderMCHH;
//
// MC State ...
//
bool isMCMaBullish =
iMCMaState == bullishState;
bool isPMCMaBullish =
iPMCMaState == bullishState;
//
bool isMCMaBearish =
iMCMaState == bearishState;
bool isPMCMaBearish =
iPMCMaState == bearishState;
//
bool isMCMaSwitchedToBullish =
isMCMaBullish &&
!isPMCMaBullish;
//
bool isMCMaSwitchedToBearish =
isMCMaBearish &&
!isPMCMaBearish;
//
bool isMCLLOverLCLL =
iMCLL > iLCLL;
bool isPMCLLOverLCLL =
iPMCLL > iPLCLL;
bool isP2MCLLOverLCLL =
iP2MCLL > iP2LCLL;
bool isP3MCLLOverLCLL =
iP3MCLL > iP3LCLL;
bool isP4MCLLOverLCLL =
iP4MCLL > iP4LCLL;
//
bool isMCHHUnderLCHH =
iMCHH < iLCHH;
bool isPMCHHUnderLCHH =
iPMCHH < iPLCHH;
bool isP2MCHHUnderLCHH =
iP2MCHH < iP2LCHH;
bool isP3MCHHUnderLCHH =
iP3MCHH < iP3LCHH;
bool isP4MCHHUnderLCHH =
iP4MCHH < iP4LCHH;
//
bool isMCLLCrossedOverLCLL =
isMCLLOverLCLL &&
!isPMCLLOverLCLL;
bool isPMCLLCrossedOverLCLL =
isPMCLLOverLCLL &&
!isP2MCLLOverLCLL;
bool isP2MCLLCrossedOverLCLL =
isP2MCLLOverLCLL &&
!isP3MCLLOverLCLL;
bool isP3MCLLCrossedOverLCLL =
isP3MCLLOverLCLL &&
!isP4MCLLOverLCLL;
//
bool isMCHHCrossedUnderLCHH =
isMCHHUnderLCHH &&
!isPMCHHUnderLCHH;
bool isPMCHHCrossedUnderLCHH =
isPMCHHUnderLCHH &&
!isP2MCHHUnderLCHH;
bool isP2MCHHCrossedUnderLCHH =
isP2MCHHUnderLCHH &&
!isP3MCHHUnderLCHH;
bool isP3MCHHCrossedUnderLCHH =
isP3MCHHUnderLCHH &&
!isP4MCHHUnderLCHH;
//
// LC State ...
//
bool isLCMaBullish =
iLCMaState == bullishState;
bool isPLCMaBullish =
iPLCMaState == bullishState;
//
bool isLCMaBearish =
iLCMaState == bearishState;
bool isPLCMaBearish =
iPLCMaState == bearishState;
//
bool isLCMaSwitchedToBullish =
isLCMaBullish &&
!isPLCMaBullish;
//
bool isLCMaSwitchedToBearish =
isLCMaBearish &&
!isPLCMaBearish;
//
bool isLCLLOverHCLL =
iLCLL > iHCLL;
bool isPLCLLOverHCLL =
iPLCLL > iPHCLL;
bool isP2LCLLOverHCLL =
iP2LCLL > iP2HCLL;
bool isP3LCLLOverHCLL =
iP3LCLL > iP3HCLL;
bool isP4LCLLOverHCLL =
iP4LCLL > iP4HCLL;
//
bool isLCHHUnderHCHH =
iLCHH < iHCHH;
bool isPLCHHUnderHCHH =
iPLCHH < iPHCHH;
bool isP2LCHHUnderHCHH =
iP2LCHH < iP2HCHH;
bool isP3LCHHUnderHCHH =
iP3LCHH < iP3HCHH;
bool isP4LCHHUnderHCHH =
iP4LCHH < iP4HCHH;
//
bool isLCLLCrossedOverHCLL =
isLCLLOverHCLL &&
!isPLCLLOverHCLL;
bool isPLCLLCrossedOverHCLL =
isPLCLLOverHCLL &&
!isP2LCLLOverHCLL;
bool isP2LCLLCrossedOverHCLL =
isP2LCLLOverHCLL &&
!isP3LCLLOverHCLL;
bool isP3LCLLCrossedOverHCLL =
isP3LCLLOverHCLL &&
!isP4LCLLOverHCLL;
//
bool isLCHHCrossedUnderHCHH =
isLCHHUnderHCHH &&
!isPLCHHUnderHCHH;
bool isPLCHHCrossedUnderHCHH =
isPLCHHUnderHCHH &&
!isP2LCHHUnderHCHH;
bool isP2LCHHCrossedUnderHCHH =
isP2LCHHUnderHCHH &&
!isP3LCHHUnderHCHH;
bool isP3LCHHCrossedUnderHCHH =
isP3LCHHUnderHCHH &&
!isP4LCHHUnderHCHH;
//
// HC State ...
//
bool isHCMaBullish =
iHCMaState == bullishState;
bool isPHCMaBullish =
iPHCMaState == bullishState;
//
bool isHCMaBearish =
iHCMaState == bearishState;
bool isPHCMaBearish =
iPHCMaState == bearishState;
//
bool isHCMaSwitchedToBullish =
isHCMaBullish &&
!isPHCMaBullish;
//
bool isHCMaSwitchedToBearish =
isHCMaBearish &&
!isPHCMaBearish;
///////////////////////////////////////////////////////////////////////////////
//
// HK Signal Bar ...
//
double iHKSOpen = hkSBarOpenBuffer[barIndex];
double iHKSClose = hkSBarCloseBuffer[barIndex];
//
double iHKSMax = MathMax(iHKSOpen, iHKSClose);
double iHKSMin = MathMin(iHKSOpen, iHKSClose);
//
bool isHKSBullish = hkSBarOpenBuffer[barIndex] < hkSBarCloseBuffer[barIndex];
bool isPHKSBullish = hkSBarOpenBuffer[barIndex + 1] < hkSBarCloseBuffer[barIndex + 1];
//
bool isHKSBearish = hkSBarOpenBuffer[barIndex] > hkSBarCloseBuffer[barIndex];
bool isPHKSBearish = hkSBarOpenBuffer[barIndex + 1] > hkSBarCloseBuffer[barIndex + 1];
//
bool isHKSSwitchedToBullish =
isHKSBullish &&
!isPHKSBullish;
//
bool isHKSSwitchedToBearish =
isHKSBearish &&
!isPHKSBearish;
//
// TREND ...
//
double iTrend = trendBuffer[barIndex];
bool isTrendBullish = trendStateBuffer[barIndex] > 0;
bool isTrendBearish = trendStateBuffer[barIndex] < 0;
bool isTrendSwitchedToBullish =
trendStateBuffer[barIndex] > 0 &&
trendStateBuffer[barIndex + 1] <= 0;
bool isTrendSwitchedToBearish =
trendStateBuffer[barIndex] < 0 &&
trendStateBuffer[barIndex + 1] >= 0;
//
// RSI ...
//
bool isRSIOverOB = rsiBuffer[barIndex] > rsiOBLevel;
bool isPRSIOverOB = rsiBuffer[barIndex + 1] > rsiOBLevel;
//
bool isRSIUnderOB = rsiBuffer[barIndex] < rsiOBLevel;
bool isPRSIUnderOB = rsiBuffer[barIndex + 1] < rsiOBLevel;
//
bool isRSICrossedOverOB =
isRSIOverOB &&
!isPRSIOverOB;
//
bool isRSICrossedUnderOB =
isRSIUnderOB &&
!isPRSIUnderOB;
//
bool isRSIOverOS = rsiBuffer[barIndex] > rsiOSLevel;
bool isPRSIOverOS = rsiBuffer[barIndex + 1] > rsiOSLevel;
//
bool isRSIUnderOS = rsiBuffer[barIndex] < rsiOSLevel;
bool isPRSIUnderOS = rsiBuffer[barIndex + 1] < rsiOSLevel;
//
bool isRSICrossedOverOS =
isRSIOverOS &&
!isPRSIOverOS;
//
bool isRSICrossedUnderOS =
isRSIUnderOS &&
!isPRSIUnderOS;
//
// ADX ...
//
bool isADXOverThreshold = adxBuffer[barIndex] > adxThreshold;
bool isPADXOverThreshold = adxBuffer[barIndex + 1] > adxThreshold;
//
bool isADXUnderThreshold = adxBuffer[barIndex] < adxThreshold;
bool isPADXUnderThreshold = adxBuffer[barIndex + 1] < adxThreshold;
//
bool isADXCrossedOverThreshold =
isADXOverThreshold &&
!isPADXOverThreshold;
//
bool isADXCrossedUnderThreshold =
isADXUnderThreshold &&
!isPADXUnderThreshold;
//
bool isADXBullish = adxpBuffer[barIndex] > adxnBuffer[barIndex];
bool isPADXBullish = adxpBuffer[barIndex + 1] > adxnBuffer[barIndex + 1];
//
bool isADXBearish = adxpBuffer[barIndex] < adxnBuffer[barIndex];
bool isPADXBearish = adxpBuffer[barIndex + 1] < adxnBuffer[barIndex + 1];
//
bool isADXSwitchedToBullish =
isADXBullish &&
!isPADXBullish;
//
bool isADXSwitchedToBearish =
isADXBearish &&
!isPADXBearish;
//
bool isADXFullySwitchedToBullish =
isADXSwitchedToBullish &&
isADXCrossedOverThreshold;
//
bool isADXFullySwitchedToBearish =
isADXSwitchedToBearish &&
isADXCrossedUnderThreshold;
//
bool isTriggerBarOverHKS =
iBar.low > iHKSMax;
bool isTriggerBarUnderHKS =
iBar.high < iHKSMin;
//
// KI ...
//
bool isKIBullish = kiStateBuffer[barIndex] > 0;
bool isPKIBullish = kiStateBuffer[barIndex + 1] > 0;
//
bool isKIBearish = kiStateBuffer[barIndex] < 0;
bool isPKIBearish = kiStateBuffer[barIndex = 1] < 0;
// //
// bool isKIOverHKS =
// kiBuffer[barIndex] > iHKSMax;
// //
// bool isKIUnderHKS =
// kiBuffer[barIndex] < iHKSMin;
//
bool isKISwitchedToBullish =
isKIBullish &&
!isPKIBullish;
//
bool isKISwitchedToBearish =
isKIBearish &&
!isPKIBearish;
//
// Detecting Signal ...
//
// Bullish ...
isBullish =
//
false
// Conditions Validation ...
// isKIOverHKS &&
// isHKSBullish &&
// isKISwitchedToBullish
// &&
//
// Bar Validation ...
// iBar.IsBullish() &&
// iBar.close > kiBuffer[barIndex]
//
;
//
// Bearish ...
isBearish =
//
false
// Conditions Validation ...
// isKIUnderHKS &&
// isHKSBearish &&
// isKISwitchedToBearish
// &&
//
// Bar Validation ...
// iBar.IsBearish() &&
// iBar.close < kiBuffer[barIndex]
//
;
////////////////////////////////////////////////////////////////////
//
int mSameKICount = 0;
int mSameKIBullishCount = 0;
int mSameKIBearishCount = 0;
//
int mSamePeakCount = 0;
int mSameValeCount = 0;
//
double mSamePeaksGoldenMin = 0;
double mSamePeaksGoldenMax = 0;
//
double mSameValesGoldenMin = 0;
double mSameValesGoldenMax = 0;
//
int mSamePeakGoldenCount = 0;
int mSameValeGoldenCount = 0;
//
bool mDrawLiquidities = false;
bool mDrawRangeBreakes = false;
//
bool mDetectLiquidities = true;
bool mDetectRangeBreakes = true;
//
XBoxZone mBullishLiquidities[];
XBoxZone mBearishLiquidities[];
XBoxZone mBullishRangeBreakes[];
XBoxZone mBearishRangeBreakes[];
//
// POI(s) Handlers ...
//
/**
* Detect POI(s) ...
*
* @param barIndex: int, Specified Bar Index ...
* @param prevCalculated: int, Provides Previous Calculated Bars ...
* @param ratesTotal: int, Provides All Availabled Bars ...
* @param open: double Collection, Provides Open Prices Time Series ...
* @param high: double Collection, Provides High Prices Time Series ...
* @param close: double Collection, Provides Close Prices Time Series ...
* @param low: double Collection, Provides Low Prices Time Series ...
* @param tickVolume: long Collection, Provides Ticks Volume Prices Time Series ...
*/
void DetectPOIs(
int barIndex,
const int prevCalculated,
const int ratesTotal,
const double &open[],
const double &high[],
const double &close[],
const double &low[],
const long &tickVolume[] //
)
{
//
// Check Some Requirements ...
int lastBarIndex = barIndex + 1;
int maxBarIndex = startCalculationForLastBars > 0
? startCalculationForLastBars
: ratesTotal;
bool isFirstBar =
startCalculationForLastBars > 0
? barIndex == startCalculationForLastBars
: barIndex == firstBarIndex;
//
// Handle Minimum Required Bars ...
bool isPassedRequiredBars = barIndex < maxBarIndex - 3;
if (!isPassedRequiredBars)
{
return;
}
//
// Recieve Bar ...
XOHCL iBar;
XOHCL iPBar;
bool has = iBar.Init(
_Symbol,
_Period,
barIndex
//
);
has =
has &&
iBar.GetPreviousBar(iPBar);
if (!has)
{
return;
}
//
bool isBullish = false;
bool isBearish = false;
int maxAllowedPOIs = 50;
//
ENUM_X_DIRECTION iDir;
//
// Detecting Liquidity ...
if (mDetectLiquidities)
{
//
bool isLiquidity =
mBarAnalyser
.IsRejected(
iBar,
iDir,
true,
true //
);
bool isBullishLiquiditySweeped =
isLiquidity &&
IsBullish(iDir);
bool isBearishLiquiditySweeped =
isLiquidity &&
IsBearish(iDir);
if (isLiquidity)
{
//
XBoxZone iLiq;
//
iLiq.dir = iDir;
iLiq.type = "XLIQ";
iLiq.upper =
isBullishLiquiditySweeped
? iBar.GetDown()
: iBar.high;
iLiq.lower =
isBullishLiquiditySweeped
? iBar.low
: iBar.GetUp();
iLiq.at = iBar.time;
iLiq.from = iBar.time;
iLiq.symbol = _Symbol;
iLiq.period = _Period;
iLiq.to = ((datetime)((int)iBar.time + (PeriodSeconds(_Period))));
//
if (iLiq.IsValid())
{
//
if (isBullishLiquiditySweeped)
{
//
has = AddBoxIfNotExists(
iLiq,
mBullishLiquidities //
);
if (has)
{
//
SortBoxes(
mBullishLiquidities,
maxAllowedPOIs //
);
}
}
else
{
//
has = AddBoxIfNotExists(
iLiq,
mBearishLiquidities //
);
if (has)
{
//
SortBoxes(
mBearishLiquidities,
maxAllowedPOIs //
);
}
}
}
//
iLiq.Clean();
}
}
//
// Detecting Bullish and Bearish Breakes ...
//
bool isPeakSame = peakBuffer[barIndex] == peakBuffer[barIndex + 1];
bool isPPeakSame = peakBuffer[barIndex + 1] == peakBuffer[barIndex + 2];
//
bool isPeakOverLast = peakBuffer[barIndex] > peakBuffer[barIndex + 1];
bool isPPeakOverLast = peakBuffer[barIndex + 1] > peakBuffer[barIndex + 2];
//
bool isPeakUnderLast = peakBuffer[barIndex] < peakBuffer[barIndex + 1];
bool isPPeakUnderLast = peakBuffer[barIndex + 1] < peakBuffer[barIndex + 2];
//
bool isSamePeakOverLast =
isPPeakSame &&
isPeakOverLast;
bool isSamePeakUnderLast =
isPPeakSame &&
isPeakUnderLast;
//
bool isValeSame = valeBuffer[barIndex] == valeBuffer[barIndex + 1];
bool isPValeSame = valeBuffer[barIndex + 1] == valeBuffer[barIndex + 2];
//
bool isValeOverLast = valeBuffer[barIndex] > valeBuffer[barIndex + 1];
bool isPValeOverLast = valeBuffer[barIndex + 1] > valeBuffer[barIndex + 2];
//
bool isValeUnderLast = valeBuffer[barIndex] < valeBuffer[barIndex + 1];
bool isPValeUnderLast = valeBuffer[barIndex + 1] < valeBuffer[barIndex + 2];
//
bool isSameValeOverLast =
isPValeSame &&
isValeOverLast;
bool isSameValeUnderLast =
isPValeSame &&
isValeUnderLast;
//
// Detecting Range Breakes ...
if (mDetectRangeBreakes)
{
//
isBullish = isSamePeakOverLast
// || isSameValeOverLast
;
isBearish =
isSameValeUnderLast
// || isSamePeakUnderLast
;
//
bool basedOnPeak =
isSamePeakOverLast
// || isSamePeakUnderLast
;
//
bool basedOnVale =
isSameValeUnderLast
// isSameValeOverLast ||
;
//
has = isBullish ||
isBearish;
//
if (has)
{
//
XBoxZone iRNGBreak;
//
iDir =
isBullish
? X_DIRECTION_BULLISH
: isBearish
? X_DIRECTION_BEARISH
: X_DIRECTION_NONE;
//
iRNGBreak.dir = iDir;
iRNGBreak.at = iBar.time;
iRNGBreak.type = "XRNGB";
iRNGBreak.to = iBar.time;
iRNGBreak.symbol = _Symbol;
iRNGBreak.period = _Period;
//
int fromIDX =
iBar.Index() +
(basedOnPeak
? mSamePeakCount
: basedOnVale
? mSameValeCount
: 0);
datetime from = GetBarTime(
_Symbol,
_Period,
fromIDX //
);
iRNGBreak.from = from;
//
double upper =
isBullish
? basedOnPeak
? peakBuffer[barIndex]
: basedOnVale
? mSameValeGoldenCount
: 0
: isBearish
? basedOnPeak
? peakBuffer[barIndex]
: basedOnVale
? mSameValeGoldenCount
: 0
: 0;
//
double lower =
isBullish
? basedOnPeak
? mSamePeakGoldenCount
: basedOnVale
? valeBuffer[barIndex]
: 0
: isBearish
? basedOnPeak
? mSamePeakGoldenCount
: basedOnVale
? valeBuffer[barIndex]
: 0
: 0;
//
iRNGBreak.upper = upper;
iRNGBreak.lower = lower;
//
// Adding POI ...
has = iRNGBreak.IsValid();
if (has)
{
//
if (isBullish)
{
//
has = AddBoxIfNotExists(
iRNGBreak,
mBullishRangeBreakes //
);
if (has)
{
//
SortBoxes(
mBullishRangeBreakes,
maxAllowedPOIs //
);
}
}
else if (isBearish)
{
//
has = AddBoxIfNotExists(
iRNGBreak,
mBearishRangeBreakes //
);
if (has)
{
//
SortBoxes(
mBearishRangeBreakes,
maxAllowedPOIs //
);
}
}
}
}
}
//
if (isPeakSame)
{
//
mSamePeakGoldenCount =
mSamePeakGoldenCount == 0
? iBar.GetUp()
: MathMax(mSamePeakGoldenCount, iBar.GetUp());
mSamePeakCount++;
}
else
{
//
mSamePeakCount = 0;
mSamePeakGoldenCount = 0;
}
//
if (isValeSame)
{
//
mSameValeGoldenCount =
mSameValeGoldenCount == 0
? iBar.GetDown()
: MathMin(mSameValeGoldenCount, iBar.GetDown());
mSameValeCount++;
}
else
{
//
mSameValeCount = 0;
mSameValeGoldenCount = 0;
}
//
// Cleanup Resources ...
//
iBar.Clean();
iPBar.Clean();
}
/**
* Validate Detected POI(s) ...
*
* @param barIndex: int, Specified Bar Index ...
* @param prevCalculated: int, Provides Previous Calculated Bars ...
* @param ratesTotal: int, Provides All Availabled Bars ...
* @param open: double Collection, Provides Open Prices Time Series ...
* @param high: double Collection, Provides High Prices Time Series ...
* @param close: double Collection, Provides Close Prices Time Series ...
* @param low: double Collection, Provides Low Prices Time Series ...
* @param tickVolume: long Collection, Provides Ticks Volume Prices Time Series ...
*/
void ValidatePOIs(
int barIndex,
const int prevCalculated,
const int ratesTotal,
const double &open[],
const double &high[],
const double &close[],
const double &low[],
const long &tickVolume[] //
)
{
//
int count = 0;
bool has = false;
int barsLength = 3;
datetime to = GetBarTime(
_Symbol,
_Period,
barIndex //
);
//
// Liquidities ...
//
// Bullish Liquidities ...
count = ArraySize(mBullishLiquidities);
has = IsValidSize(count);
if (has)
{
//
ValidateBoxes(
mBullishLiquidities,
barIndex,
barsLength //
);
}
//
// Bearish Liquidities ...
count = ArraySize(mBearishLiquidities);
has = IsValidSize(count);
if (has)
{
//
ValidateBoxes(
mBearishLiquidities,
barIndex,
barsLength //
);
}
//
// Range Breaks ...
//
// Bullish ...
count = ArraySize(mBullishRangeBreakes);
has = IsValidSize(count);
if (has)
{
//
ValidateBoxes(
mBullishRangeBreakes,
barIndex,
barsLength //
);
}
//
// Bearish ...
count = ArraySize(mBearishRangeBreakes);
has = IsValidSize(count);
if (has)
{
//
ValidateBoxes(
mBearishRangeBreakes,
barIndex,
barsLength //
);
}
//
}
/**
* Draw Detected POI(s) ...
*
* @param barIndex: int, Specified Bar Index ...
* @param prevCalculated: int, Provides Previous Calculated Bars ...
* @param ratesTotal: int, Provides All Availabled Bars ...
* @param open: double Collection, Provides Open Prices Time Series ...
* @param high: double Collection, Provides High Prices Time Series ...
* @param close: double Collection, Provides Close Prices Time Series ...
* @param low: double Collection, Provides Low Prices Time Series ...
* @param tickVolume: long Collection, Provides Ticks Volume Prices Time Series ...
*/
void DrawPOIs(
int barIndex,
const int prevCalculated,
const int ratesTotal,
const double &open[],
const double &high[],
const double &close[],
const double &low[],
const long &tickVolume[] //
)
{
//
int count = 0;
XBoxZone iBox;
bool has = false;
datetime to = GetBarTime(
_Symbol,
_Period,
barIndex //
);
//
// Liquidities ...
if (mDrawLiquidities)
{
//
count = ArraySize(mBullishLiquidities);
has = IsValidSize(count);
if (has)
{
//
for (int i = 0; i < count; i++)
{
//
iBox = mBullishLiquidities[i];
iBox.to = to;
//
XCBoxObject *iObj;
has = mDrawer.DrawBox(
iBox,
iObj //
);
if (has)
{
mObjects.Add(iObj);
}
//
iBox.Clean();
}
}
//
count = ArraySize(mBearishLiquidities);
has = IsValidSize(count);
if (has)
{
//
for (int i = 0; i < count; i++)
{
//
iBox = mBearishLiquidities[i];
iBox.to = to;
//
XCBoxObject *iObj;
has = mDrawer.DrawBox(
iBox,
iObj //
);
if (has)
{
mObjects.Add(iObj);
}
//
iBox.Clean();
}
}
}
//
// Range Breaks ...
if (mDrawRangeBreakes)
{
//
// Bullish ...
count = ArraySize(mBullishRangeBreakes);
has = IsValidSize(count);
if (has)
{
//
for (int i = 0; i < count; i++)
{
//
iBox = mBullishRangeBreakes[i];
iBox.to = to;
//
XCBoxObject *iObj;
has = mDrawer.DrawBox(
iBox,
iObj //
);
if (has)
{
//
XPOIStyle iStyle;
iStyle.width = 1;
iStyle.clr = clrAqua;
iStyle.style = STYLE_DOT;
//
mDrawer.ApplyStyle(
iObj,
iStyle //
);
//
mObjects.Add(iObj);
}
//
iBox.Clean();
}
}
//
// Bearish ...
count = ArraySize(mBearishRangeBreakes);
has = IsValidSize(count);
if (has)
{
//
for (int i = 0; i < count; i++)
{
//
iBox = mBearishRangeBreakes[i];
iBox.to = to;
//
XCBoxObject *iObj;
has = mDrawer.DrawBox(
iBox,
iObj //
);
if (has)
{
//
XPOIStyle iStyle;
iStyle.width = 1;
iStyle.clr = clrMagenta;
iStyle.style = STYLE_DOT;
//
mDrawer.ApplyStyle(
iObj,
iStyle //
);
//
mObjects.Add(iObj);
}
//
iBox.Clean();
}
}
}
//
}
/**
* Process Custom Analysing Senarios ...
*
* @param barIndex: int, Specified Bar Index ...
* @param prevCalculated: int, Provides Previous Calculated Bars ...
* @param ratesTotal: int, Provides All Availabled Bars ...
* @param open: double Collection, Provides Open Prices Time Series ...
* @param high: double Collection, Provides High Prices Time Series ...
* @param close: double Collection, Provides Close Prices Time Series ...
* @param low: double Collection, Provides Low Prices Time Series ...
* @param tickVolume: long Collection, Provides Ticks Volume Prices Time Series ...
*/
void DoProcess(
int barIndex,
const int prevCalculated,
const int ratesTotal,
const double &open[],
const double &high[],
const double &close[],
const double &low[],
const long &tickVolume[] //
)
{
//
// Check Some Requirements ...
int lastBarIndex = barIndex + 1;
int maxBarIndex = startCalculationForLastBars > 0
? startCalculationForLastBars
: ratesTotal;
bool isFirstBar =
startCalculationForLastBars > 0
? barIndex == startCalculationForLastBars
: barIndex == firstBarIndex;
//
// Recieve Bar ...
XOHCL iBar;
XOHCL iPBar;
bool has = iBar.Init(
_Symbol,
_Period,
barIndex
//
);
has =
has &&
iBar.GetPreviousBar(iPBar);
if (!has)
{
return;
}
//
// Do Process ...
//
// Detecting Trigger Bar ...
//
bool hasSignal = false;
bool isBullish = false;
bool isBearish = false;
string namePrefix = NULL;
int triggerBarPushers = 0;
ENUM_X_DIRECTION triggerDir;
//
// Detecting Trigger Bars ...
//
bool isCond1Trigger =
mBarAnalyser
.IsValidForTrigger(
iPBar,
triggerDir,
true, // Cond 1 ...
false, // Cond 2 ...
false, // Cond 3 ...
false, // Cond 4 ...
false, // Cond 5 ...
false, // Cond 6 ...
false // Cond 7 ...
);
bool isCond1BullishTrigger =
isCond1Trigger &&
IsBullish(triggerDir);
bool isCond1BearishTrigger =
isCond1Trigger &&
IsBearish(triggerDir);
if (isCond1Trigger)
{
//
triggerBarPushers++;
namePrefix += "Cond1";
}
//
bool isCond2Trigger =
mBarAnalyser
.IsValidForTrigger(
iPBar,
triggerDir,
false, // Cond 1 ...
true, // Cond 2 ...
false, // Cond 3 ...
false, // Cond 4 ...
false, // Cond 5 ...
false, // Cond 6 ...
false // Cond 7 ...
);
bool isCond2BullishTrigger =
isCond2Trigger &&
IsBullish(triggerDir);
bool isCond2BearishTrigger =
isCond2Trigger &&
IsBearish(triggerDir);
if (isCond2Trigger)
{
//
triggerBarPushers++;
namePrefix += "Cond2";
}
//
bool isCond3Trigger =
mBarAnalyser
.IsValidForTrigger(
iPBar,
triggerDir,
false, // Cond 1 ...
false, // Cond 2 ...
true, // Cond 3 ...
false, // Cond 4 ...
false, // Cond 5 ...
false, // Cond 6 ...
false // Cond 7 ...
);
bool isCond3BullishTrigger =
isCond3Trigger &&
IsBullish(triggerDir);
bool isCond3BearishTrigger =
isCond3Trigger &&
IsBearish(triggerDir);
if (isCond3Trigger)
{
//
triggerBarPushers++;
namePrefix += "Cond3";
}
//
bool isCond4Trigger =
mBarAnalyser
.IsValidForTrigger(
iPBar,
triggerDir,
false, // Cond 1 ...
false, // Cond 2 ...
false, // Cond 3 ...
true, // Cond 4 ...
false, // Cond 5 ...
false, // Cond 6 ...
false // Cond 7 ...
);
bool isCond4BullishTrigger =
isCond4Trigger &&
IsBullish(triggerDir);
bool isCond4BearishTrigger =
isCond4Trigger &&
IsBearish(triggerDir);
if (isCond4Trigger)
{
//
triggerBarPushers++;
namePrefix += "Cond4";
}
//
bool isCond5Trigger =
mBarAnalyser
.IsValidForTrigger(
iPBar,
triggerDir,
false, // Cond 1 ...
false, // Cond 2 ...
false, // Cond 3 ...
false, // Cond 4 ...
true, // Cond 5 ...
false, // Cond 6 ...
false // Cond 7 ...
);
bool isCond5BullishTrigger =
isCond5Trigger &&
IsBullish(triggerDir);
bool isCond5BearishTrigger =
isCond5Trigger &&
IsBearish(triggerDir);
if (isCond5Trigger)
{
//
triggerBarPushers++;
namePrefix += "Cond5";
}
//
bool isCond6Trigger =
mBarAnalyser
.IsValidForTrigger(
iPBar,
triggerDir,
false, // Cond 1 ...
false, // Cond 2 ...
false, // Cond 3 ...
false, // Cond 4 ...
false, // Cond 5 ...
true, // Cond 6 ...
false // Cond 7 ...
);
bool isCond6BullishTrigger =
isCond6Trigger &&
IsBullish(triggerDir);
bool isCond6BearishTrigger =
isCond6Trigger &&
IsBearish(triggerDir);
if (isCond6Trigger)
{
//
triggerBarPushers++;
namePrefix += "Cond6";
}
//
bool isCond7Trigger =
mBarAnalyser
.IsValidForTrigger(
iPBar,
triggerDir,
false, // Cond 1 ...
false, // Cond 2 ...
false, // Cond 3 ...
false, // Cond 4 ...
false, // Cond 5 ...
false, // Cond 6 ...
true // Cond 7 ...
);
bool isCond7BullishTrigger =
isCond7Trigger &&
IsBullish(triggerDir);
bool isCond7BearishTrigger =
isCond7Trigger &&
IsBearish(triggerDir);
if (isCond7Trigger)
{
//
triggerBarPushers++;
namePrefix += "Cond7";
}
//
// Summarizing Trigger Bars ...
//
bool isBullishTriggerBar =
//
isCond1BullishTrigger ||
isCond2BullishTrigger ||
isCond3BullishTrigger ||
isCond4BullishTrigger ||
isCond5BullishTrigger ||
isCond6BullishTrigger ||
isCond7BullishTrigger
//
;
//
bool isBearishTriggerBar =
//
isCond1BearishTrigger ||
isCond2BearishTrigger ||
isCond3BearishTrigger ||
isCond4BearishTrigger ||
isCond5BearishTrigger ||
isCond6BearishTrigger ||
isCond7BearishTrigger
//
;
//
bool isTriggerBar =
//
triggerBarPushers >= 1 &&
(isBullishTriggerBar ||
isBearishTriggerBar)
//
;
//
// Reading Required Condiions ...
//
int pIndex = barIndex + 1;
int ppIndex = barIndex + 2;
//
// PV ...
//
bool isSamePeak = peakBuffer[pIndex] == peakBuffer[ppIndex];
bool isSameVale = valeBuffer[pIndex] == valeBuffer[ppIndex];
//
bool isPeakOverLast = peakBuffer[pIndex] > peakBuffer[ppIndex];
bool isPeakUnderLast = peakBuffer[pIndex] < peakBuffer[ppIndex];
//
bool isValeOverLast = valeBuffer[pIndex] > valeBuffer[ppIndex];
bool isValeUnderLast = valeBuffer[pIndex] < valeBuffer[ppIndex];
//
bool isSamePeakGolden = peakGoldenBuffer[pIndex] == peakGoldenBuffer[ppIndex];
bool isSameValeGolden = valeGoldenBuffer[pIndex] == valeGoldenBuffer[ppIndex];
//
bool isPeakGoldeOverLast = peakGoldenBuffer[pIndex] > peakGoldenBuffer[ppIndex];
bool isPeakGoldenUnderLast = peakGoldenBuffer[pIndex] < peakGoldenBuffer[ppIndex];
//
bool isValeGoldenOverLast = valeGoldenBuffer[pIndex] > valeGoldenBuffer[ppIndex];
bool isValeGoldenUnderLast = valeGoldenBuffer[pIndex] < valeGoldenBuffer[ppIndex];
//
if (isSamePeak)
{
mSamePeakCount++;
}
else
{
mSamePeakCount = 0;
}
//
if (isSameVale)
{
mSameValeCount++;
}
else
{
mSameValeCount = 0;
}
//
if (isSamePeakGolden)
{
mSamePeakGoldenCount++;
}
else
{
mSamePeakGoldenCount = 0;
}
//
if (isSameValeGolden)
{
mSameValeGoldenCount++;
}
else
{
mSameValeGoldenCount = 0;
}
//
// SAR ...
//
bool isSarBullish = sarStateBuffer[pIndex] > 0;
bool isPSarBullish = sarStateBuffer[ppIndex] > 0;
//
bool isSarBearish = sarStateBuffer[pIndex] < 0;
bool isPSarBearish = sarStateBuffer[ppIndex] < 0;
//
bool isSarSwitchedToBullish =
isSarBullish &&
!isPSarBullish;
//
bool isSarSwitchedToBearish =
isSarBearish &&
!isPSarBearish;
//
// HKS ...
//
bool isHKSBullish = hkSBarCloseBuffer[pIndex] > hkSBarOpenBuffer[pIndex];
bool isPHKSBullish = hkSBarCloseBuffer[ppIndex] > hkSBarOpenBuffer[ppIndex];
//
bool isHKSBearish = hkSBarCloseBuffer[pIndex] < hkSBarOpenBuffer[pIndex];
bool isPHKSBearish = hkSBarCloseBuffer[ppIndex] < hkSBarOpenBuffer[ppIndex];
//
bool isHKSSwitchedToBullish =
isHKSBullish &&
!isPHKSBullish;
//
bool isHKSSwitchedToBearish =
isHKSBearish &&
!isPHKSBearish;
//
// SB ...
//
bool isSBullish = sBarCloseBuffer[pIndex] > sBarOpenBuffer[pIndex];
bool isPSBullish = sBarCloseBuffer[ppIndex] > sBarOpenBuffer[ppIndex];
//
bool isSBearish = sBarCloseBuffer[pIndex] < sBarOpenBuffer[pIndex];
bool isPSBearish = sBarCloseBuffer[ppIndex] < sBarOpenBuffer[ppIndex];
//
bool isSSwitchedToBullish =
isSBullish &&
!isPSBullish;
//
bool isSSwitchedToBearish =
isSBearish &&
!isPSBearish;
//
// KI ...
//
bool isKIBullish = kiStateBuffer[pIndex] > 0;
bool isPKIBullish = kiStateBuffer[ppIndex] > 0;
//
bool isKIBearish = kiStateBuffer[pIndex] < 0;
bool isPKIBearish = kiStateBuffer[ppIndex] < 0;
//
bool isKISwitchedToBullish =
isKIBullish &&
!isPKIBullish;
//
bool isKISwitchedToBearish =
isKIBearish &&
!isPKIBearish;
//
bool isKIBullishBreaked =
iPBar.IsBreaked(
kiBuffer[pIndex],
X_DIRECTION_BULLISH,
X_FIBO_LEVEL_500,
X_BOUNDARY_PRICE_UP_DOWN //
);
//
bool isKIBearishBreaked =
iPBar.IsBreaked(
kiBuffer[pIndex],
X_DIRECTION_BEARISH,
X_FIBO_LEVEL_500,
X_BOUNDARY_PRICE_UP_DOWN //
);
//
bool isKISame = kiBuffer[pIndex] == kiBuffer[ppIndex];
bool isKIBullishSame =
isKISame &&
isKIBullish;
bool isKIBearishSame =
isKISame &&
isKIBearish;
//
if (isKISame)
{
mSameKICount++;
}
else
{
mSameKICount = 0;
}
//
if (isKIBullishSame)
{
mSameKIBullishCount++;
}
else
{
mSameKIBullishCount = 0;
}
//
if (isKIBearishSame)
{
mSameKIBearishCount++;
}
else
{
mSameKIBearishCount = 0;
}
//
// Validating Trigger Bar based on Conditions ...
if (isTriggerBar)
{
//
// TODO: Remove this if required ...
isTriggerBar = false;
isBullishTriggerBar = false;
isBearishTriggerBar = false;
}
//
// Detecting Signal ...
//
// Bullish ...
isBullish =
//
// Conditions Validation ...
isKIBullishBreaked
// isSSwitchedToBullish
// isKISwitchedToBullish
// isSarSwitchedToBullish
// isHKSSwitchedToBullish
//
// Bar Validation ...
//
;
//
// Bearish ...
isBearish =
//
// Conditions Validation ...
isKIBearishBreaked
// isSSwitchedToBearish
// isKISwitchedToBearish
// isSarSwitchedToBearish
// isHKSSwitchedToBearish
//
// Bar Validation ...
//
;
//
// Summarizing Signal ...
hasSignal =
isBullish ||
isBearish;
//
// Draw Requirements ...
//
// Draw Trigger Bar ...
if (isTriggerBar)
{
//
int triggerBullishArrowCode = 225;
int triggerBearishArrowCode = 226;
//
color triggerBarBullishColor = clrLime;
color triggerBarBearishColor = clrRed;
//
ENUM_ARROW_ANCHOR triggerBullishAnchor = ANCHOR_TOP;
ENUM_ARROW_ANCHOR triggerBearishAnchor = ANCHOR_BOTTOM;
//
int arrowWidth = 3;
int arrowCode =
isBullishTriggerBar
? triggerBullishArrowCode
: triggerBearishArrowCode;
ENUM_X_PRICE arrowPriceType =
isBullishTriggerBar
? X_PRICE_LOW
: X_PRICE_HIGH;
color arrowColor =
isBullishTriggerBar
? triggerBarBullishColor
: triggerBarBearishColor;
ENUM_ARROW_ANCHOR arrowAnchor =
isBullishTriggerBar
? triggerBullishAnchor
: triggerBearishAnchor;
//
XCBarArrowObject *iObj;
has = mDrawer.CreateBarArrow(
iBar,
iObj,
arrowPriceType,
arrowCode,
arrowColor,
arrowWidth,
arrowAnchor,
namePrefix //
);
if (has)
{
mObjects.Add(iObj);
}
//
// Converts to Box ...
XBoxZone iBox;
iBox.type = "XTRB";
iBox.to = iBar.time;
iBox.symbol = _Symbol;
iBox.period = _Period;
iBox.lower = iPBar.low;
iBox.from = iPBar.time;
iBox.upper = iPBar.high;
iBox.dir =
isBullishTriggerBar
? X_DIRECTION_BULLISH
: X_DIRECTION_BEARISH;
if (iBox.IsValid())
{
//
// XCBoxObject *iObj;
// has = mDrawer.DrawBox(
// iBox,
// iObj //
// );
// if (has)
// {
// mObjects.Add(iObj);
// }
//
XSignal iSignal;
double iRewardRatios[] = {
1,
1.5,
2 //
};
has = ToSignal(
iBox,
iSignal,
iRewardRatios,
0 // Additional SL ...
);
if (has)
{
//
XCSignalObject *iObj;
has = mDrawer.DrawSignal(
iSignal,
iObj,
4 //
);
if (has)
{
mObjects.Add(iObj);
}
}
}
//
}
//
// Draw Signal ...
if (hasSignal)
{
//
int bullishArrowCode = 225;
int bearishArrowCode = 226;
//
color bullishColor = clrLime;
color bearishColor = clrRed;
//
ENUM_ARROW_ANCHOR bullishAnchor = ANCHOR_TOP;
ENUM_ARROW_ANCHOR bearishAnchor = ANCHOR_BOTTOM;
//
int arrowWidth = 3;
int arrowCode =
isBullish
? bullishArrowCode
: bearishArrowCode;
ENUM_X_PRICE arrowPriceType =
isBullish
? X_PRICE_LOW
: X_PRICE_HIGH;
color arrowColor =
isBullish
? bullishColor
: bearishColor;
ENUM_ARROW_ANCHOR arrowAnchor =
isBullish
? bullishAnchor
: bearishAnchor;
//
XCBarArrowObject *iObj;
has = mDrawer.CreateBarArrow(
iBar,
iObj,
arrowPriceType,
arrowCode,
arrowColor,
arrowWidth,
arrowAnchor,
namePrefix //
);
if (has)
{
mObjects.Add(iObj);
}
//
// Converts to Box ...
XBoxZone iBox;
iBox.type = "XSG";
iBox.to = iBar.time;
iBox.symbol = _Symbol;
iBox.period = _Period;
iBox.lower = iPBar.low;
iBox.from = iPBar.time;
iBox.upper = iPBar.high;
iBox.dir =
isBullish
? X_DIRECTION_BULLISH
: X_DIRECTION_BEARISH;
if (iBox.IsValid())
{
//
XSignal iSignal;
double iRewardRatios[] = {
1,
1.5,
2 //
};
has = ToSignal(
iBox,
iSignal,
iRewardRatios,
0 // Additional SL ...
);
if (has)
{
//
XCSignalObject *iObj;
has = mDrawer.DrawSignal(
iSignal,
iObj,
4 //
);
if (has)
{
mObjects.Add(iObj);
}
}
}
}
//
// Cleanup Resources ...
//
iBar.Clean();
iPBar.Clean();
}
////////////////////////////////////////////////////////////////////
/**
* Analyse Market based on Specified Kind of Pivots ...
*
* @param analysis: XPivotAnalysis, reference to hold result ...
* @param barIndex: int, Bar Index ...
* @param requiredNumberOFPivots: int, Specified which Number of Pivots must be Extracted ...
* @param maxAllowedLoopbackLength: int, Specified Maximum Loopback Length for Pivot Extraction ...
* @param validationLength: int, Specified Pivots Validation Length ignore if <= 0 ...
*
* @return ( bool )
*/
bool AnalysePVPivots(
XPivotAnalysis &analysis,
int barIndex = 0,
int requiredNumberOFPivots = 50,
int maxAllowedLoopbackLength = 1500,
int validationLength = 0 //
)
{
//
bool result = false;
//
// Prepare ...
analysis.Clean();
//
// Reading Pivots ...
XPivot pivots[];
int count = fimaHelper.ExtractPVPivots(
pivots, // Result ...
barIndex, // Bar Index ...
requiredNumberOFPivots, // Required Number of Pivots ...
maxAllowedLoopbackLength, // Max Allowed Loopback ...
validationLength // Validation Length ...
);
result = IsValidSize(count);
if (!result)
{
//
SpecifiedClean(pivots);
return result;
}
//
string symbol = fimaHelper.GetSymbol();
ENUM_TIMEFRAMES period = fimaHelper.GetPeriod();
//
// Initialize Analysis ...
result = analysis.Init(
"XFIMA_XPV",
symbol,
period,
pivots //
);
//
// Cleanup Resources ...
if (!result)
{
analysis.Clean();
}
SpecifiedClean(pivots);
//
return result;
}
/**
* Analyse Market based on Specified Kind of Pivots ...
*
* @param analysis: XPivotAnalysis, reference to hold result ...
* @param barIndex: int, Bar Index ...
* @param requiredNumberOFPivots: int, Specified which Number of Pivots must be Extracted ...
* @param maxAllowedLoopbackLength: int, Specified Maximum Loopback Length for Pivot Extraction ...
* @param validationLength: int, Specified Pivots Validation Length ignore if <= 0 ...
*
* @return ( bool )
*/
bool AnalyseMAPivots(
XPivotAnalysis &analysis,
int barIndex = 0,
int requiredNumberOFPivots = 50,
int maxAllowedLoopbackLength = 1500,
int validationLength = 0 //
)
{
//
bool result = false;
//
// Prepare ...
analysis.Clean();
//
// Reading Pivots ...
XPivot pivots[];
int count = fimaHelper.ExtractMAPivots(
pivots, // Result ...
barIndex, // Bar Index ...
requiredNumberOFPivots, // Required Number of Pivots ...
maxAllowedLoopbackLength, // Max Allowed Loopback ...
validationLength // Validation Length ...
);
result = IsValidSize(count);
if (!result)
{
//
SpecifiedClean(pivots);
return result;
}
//
string symbol = fimaHelper.GetSymbol();
ENUM_TIMEFRAMES period = fimaHelper.GetPeriod();
//
// Initialize Analysis ...
result = analysis.Init(
"XFIMA_XMA",
symbol,
period,
pivots //
);
//
// Cleanup Resources ...
if (!result)
{
analysis.Clean();
}
SpecifiedClean(pivots);
//
return result;
}
/**
* Analyse Market based on Specified Kind of Pivots ...
*
* @param analysis: XPivotAnalysis, reference to hold result ...
* @param barIndex: int, Bar Index ...
* @param requiredNumberOFPivots: int, Specified which Number of Pivots must be Extracted ...
* @param maxAllowedLoopbackLength: int, Specified Maximum Loopback Length for Pivot Extraction ...
*
* @return ( bool )
*/
bool AnalyseSARPivots(
XPivotAnalysis &analysis,
int barIndex = 0,
int requiredNumberOFPivots = 50,
int maxAllowedLoopbackLength = 1500 //
)
{
//
bool result = false;
//
// Prepare ...
analysis.Clean();
//
// Reading Pivots ...
XPivot pivots[];
int count = fimaHelper.ExtractSARPivots(
pivots, // Result ...
barIndex, // Bar Index ...
requiredNumberOFPivots, // Required Number of Pivots ...
maxAllowedLoopbackLength // Max Allowed Loopback ...
);
result = IsValidSize(count);
if (!result)
{
//
SpecifiedClean(pivots);
return result;
}
//
string symbol = fimaHelper.GetSymbol();
ENUM_TIMEFRAMES period = fimaHelper.GetPeriod();
//
// Initialize Analysis ...
result = analysis.Init(
"XFIMA_XSAR",
symbol,
period,
pivots //
);
//
// Cleanup Resources ...
if (!result)
{
analysis.Clean();
}
SpecifiedClean(pivots);
//
return result;
}
/**
* Analyse Market based on Specified Kind of Pivots ...
*
* @param analysis: XPivotAnalysis, reference to hold result ...
* @param barIndex: int, Bar Index ...
* @param requiredNumberOFPivots: int, Specified which Number of Pivots must be Extracted ...
* @param maxAllowedLoopbackLength: int, Specified Maximum Loopback Length for Pivot Extraction ...
*
* @return ( bool )
*/
bool AnalyseZigZagPivots(
XPivotAnalysis &analysis,
int barIndex = 0,
int requiredNumberOFPivots = 50,
int maxAllowedLoopbackLength = 1500 //
)
{
//
bool result = false;
//
// Prepare ...
analysis.Clean();
//
// Reading Pivots ...
XPivot pivots[];
int count = fimaHelper.ExtractZigZagPivots(
pivots, // Result ...
barIndex, // Bar Index ...
requiredNumberOFPivots, // Required Number of Pivots ...
maxAllowedLoopbackLength // Max Allowed Loopback ...
);
result = IsValidSize(count);
if (!result)
{
//
SpecifiedClean(pivots);
return result;
}
//
// Initialize Analysis ...
result = analysis.Init(
"XFIMA_XZG",
symbol,
period,
pivots //
);
//
// Cleanup Resources ...
if (!result)
{
analysis.Clean();
}
SpecifiedClean(pivots);
//
return result;
}
/**
* Analyse Market based on Specified Bar ...
*
* @param structure: XFIMAMarketStructure, reference to holds result ...
* @param config: XFIMAMarketStructureConfig, reference to Configure Detector ...
* @param barIndex: int, Bar Index ...
*/
void AnalyseMarket(
XFIMAMarketStructure &structure,
XFIMAMarketStructureConfig &config,
int barIndex = 0 //
)
{
//
// Prepare ...
structure.Clean();
//
// Normalize ...
barIndex = NormalizeInt(barIndex, 0);
//
bool has = false;
//
has = structure.bar.Init(
symbol,
period,
barIndex //
);
if (!has)
{
//
structure.Clean();
return;
}
//
// Reading Bar Patterns ...
XOHCL iBar;
XPatternAnalysis iPatternAnalysis;
for (int i = barIndex; i < barIndex + config.loopback; i++)
{
//
// Cleanup ...
iBar.Clean();
iPatternAnalysis.Clean();
//
// Initialize Indexed Bar ...
//
has = structure.bar.BarAt(i, iBar);
if (!has)
{
break;
}
//
// Analyse Indexed Bar ...
has = AnalyseBarPatterns(iBar, iPatternAnalysis, config.barsAnalysisConfig);
if (has)
{
//
AddRef(
iPatternAnalysis,
structure.barsAnalysis //
);
//
if (i == barIndex)
{
structure.barAnalysis = iPatternAnalysis;
}
}
//
// Check Satisfied ...
has = ArraySize(structure.barsAnalysis) >= config.requiredPivots;
if (has)
{
break;
}
}
//
// Handle Pivot Analysis ...
//
// XPV ...
if (config.analysePVPivots)
{
//
// Reading Pivots ...
has = AnalysePVPivots(
structure.pvAnalysis,
barIndex,
config.requiredPivots,
config.loopback,
config.pvPivotsValidationLength //
);
if (!has)
{
structure.pvAnalysis.Clean();
}
}
//
// XZG ...
if (config.analyseZGPivots)
{
//
// Reading Pivots ...
has = AnalyseZigZagPivots(
structure.zgAnalysis,
barIndex,
config.requiredPivots,
config.loopback //
);
if (!has)
{
structure.zgAnalysis.Clean();
}
}
//
// Cleanup ...
iBar.Clean();
iPatternAnalysis.Clean();
}
////////////////////////////////////////////////////////////////////
/**
* Check Specified Bar has MA Cross or not ...
*
* @param dir: reference for holds cross Direction ...
* @param barIndex: int, Specified Bar Index ...
* @param validCrossDiffMultiplier: double, validate diff between MAs on Cross happens ...
*
* @return ( bool )
*/
bool HasMACross(
ENUM_X_DIRECTION &dir,
int barIndex = 0,
double validCrossDiffMultiplier = 1 //
)
{
//
bool result = false;
//
// Prepare ...
dir = X_DIRECTION_NONE;
//
// Normalize ...
barIndex = NormalizeInt(barIndex, 0);
validCrossDiffMultiplier = NormalizeDouble(validCrossDiffMultiplier, 0);
//
// Validate ...
result = IsValid();
if (!result)
{
return result;
}
//
double fast[];
int fastCount = CopyMAFast(barIndex, 2, fast);
//
double slow[];
int slowCount = CopyMASlow(barIndex, 2, slow);
//
bool isBullish = false;
bool isBearish = false;
//
// Validate Readed Values ...
int count = MathMin(fastCount, slowCount);
result = IsValidSize(count) && count >= 2;
if (result)
{
//
// Detect Direction Change ...
//
bool notEmpty =
NotEmptyZero(fast[0]) &&
NotEmptyZero(fast[1]) &&
NotEmptyZero(slow[0]) &&
NotEmptyZero(slow[1]);
//
isBullish =
notEmpty &&
fast[0] > slow[0] &&
fast[1] < slow[1];
//
isBearish =
notEmpty &&
fast[0] < slow[0] &&
fast[1] > slow[1];
//
result =
isBullish ||
isBearish;
//
// Validate Direction Change ...
if (result &&
validCrossDiffMultiplier > 0)
{
//
double _points = GetPoints(GetSymbol());
double diff = MathAbs(fast[0] - slow[0]);
//
result = diff >= (validCrossDiffMultiplier * _points);
}
}
//
if (result)
{
//
// Setting Direction ...
dir =
isBullish
? X_DIRECTION_BULLISH
: isBearish
? X_DIRECTION_BEARISH
: X_DIRECTION_NONE;
}
//
// Cleanup Resources ...
XClean(fast);
XClean(slow);
//
return result;
}
/**
* Check Specified Bar Price is In Boundary or not ...
*
* @param priceType: ENUM_X_PRICE, Specified Price type of Bar ...
* @param barIndex: int, Specified Bar Index ...
*
* @return ( bool )
*/
bool IsInBoundary(
ENUM_X_PRICE priceType = X_PRICE_CLOSE,
int barIndex = 0 //
)
{
//
bool result = false;
//
// Normalize ...
barIndex = NormalizeBarIndex(barIndex);
//
if (!IsXValid(priceType))
{
priceType = X_PRICE_CLOSE;
}
//
// Validate ...
result = IsValid();
if (!result)
{
return result;
}
//
// Retrieve Bar ...
XOHCL bar;
result = bar.Init(
mSymbol,
mPeriod,
barIndex //
);
if (!result)
{
//
bar.Clean();
return result;
}
double value = bar.GetPrice(priceType);
//
// Read Boundary Values ...
double min;
double max;
result = GetBoundaryValues(min, max, barIndex);
if (!result)
{
//
bar.Clean();
return result;
}
//
result = value < max &&
value > min;
//
// Cleanup Resources ...
bar.Clean();
//
return result;
}
/**
* Check Specified Bar Price is Over Boundary Min ...
*
* @param priceType: ENUM_X_PRICE, Specified Price type of Bar ...
* @param barIndex: int, Specified Bar Index ...
*
* @return ( bool )
*/
bool IsOverBoundaryMin(
ENUM_X_PRICE priceType = X_PRICE_CLOSE,
int barIndex = 0 //
)
{
//
bool result = false;
//
// Normalize ...
barIndex = NormalizeBarIndex(barIndex);
if (!IsXValid(priceType))
{
priceType = X_PRICE_CLOSE;
}
//
// Validate ...
result = IsValid();
if (!result)
{
return result;
}
//
// Retrieve Boundary ...
double min;
double max;
result = GetBoundaryValues(min, max, barIndex);
if (!result)
{
return result;
}
//
// Retrieve Bar ....
XOHCL bar;
result = bar.Init(
mSymbol,
mPeriod,
barIndex //
);
if (!result)
{
//
bar.Clean();
return result;
}
double value = bar.GetPrice(priceType);
//
result = value > min;
//
// Cleanup ...
bar.Clean();
//
return result;
}
/**
* Check Specified Bar Price is Under Boundary Max ...
*
* @param priceType: ENUM_X_PRICE, Specified Price type of Bar ...
* @param barIndex: int, Specified Bar Index ...
*
* @return ( bool )
*/
bool IsUnderBoundaryMax(
ENUM_X_PRICE priceType = X_PRICE_CLOSE,
int barIndex = 0 //
)
{
//
bool result = false;
//
// Normalize ...
barIndex = NormalizeBarIndex(barIndex);
if (!IsXValid(priceType))
{
priceType = X_PRICE_CLOSE;
}
//
// Validate ...
result = IsValid();
if (!result)
{
return result;
}
//
// Retrieve Boundary ...
double min;
double max;
result = GetBoundaryValues(min, max, barIndex);
if (!result)
{
return result;
}
//
// Retrieve Bar ....
XOHCL bar;
result = bar.Init(
mSymbol,
mPeriod,
barIndex //
);
if (!result)
{
//
bar.Clean();
return result;
}
double value = bar.GetPrice(priceType);
//
result = value < max;
//
// Cleanup ...
bar.Clean();
//
return result;
}
/**
* Check Boundary Fake Breaked or not ...
*
* @param dir: reference for holds cross Direction ...
* @param barIndex: int, Specified Bar Index ...
* @param overMaxPriceType: ENUM_X_PRICE, which price of Specified bar to Check ...
* @param underMinPriceType: ENUM_X_PRICE, which price of Specified bar to Check ...
*
* @return ( bool )
*/
bool IsBoundaryFakeBreaked(
ENUM_X_DIRECTION &dir,
int barIndex = 0,
ENUM_X_PRICE overMaxPriceType = X_PRICE_NONE,
ENUM_X_PRICE underMinPriceType = X_PRICE_NONE //
)
{
//
bool result = false;
//
// Prepare ...
dir = X_DIRECTION_NONE;
//
// Normalize ...
barIndex = NormalizeBarIndex(barIndex);
if (!IsXValid(overMaxPriceType))
{
overMaxPriceType = X_PRICE_CLOSE;
}
if (!IsXValid(underMinPriceType))
{
underMinPriceType = X_PRICE_CLOSE;
}
//
// Initial Bars ...
XOHCL bar;
XOHCL pBar;
double min;
double max;
double pMin;
double pMax;
double boundaryValues[];
result =
bar.Init(
mSymbol,
mPeriod,
barIndex //
) &&
bar.GetPreviousBar(pBar) &&
GetBoundaryValues(min, max, barIndex) &&
GetBoundaryValues(pMin, pMax, barIndex + 1) &&
FillBoundaryValues(boundaryValues, barIndex) > 0;
//
bool isBullish =
result &&
pBar.IsBearish() &&
bar.IsBullish() &&
pBar.GetPrice(underMinPriceType) < pMin &&
bar.GetPrice(underMinPriceType) > min &&
(bar.GetPrice(underMinPriceType) > FindLesserThan(max, boundaryValues) ||
bar.GetPrice(underMinPriceType) > FindBiggerThan(min + ((max - min) / 2), boundaryValues));
//
bool isBearish =
result &&
pBar.IsBullish() &&
bar.IsBearish() &&
pBar.GetPrice(overMaxPriceType) > pMax &&
bar.GetPrice(overMaxPriceType) < max &&
(bar.GetPrice(overMaxPriceType) < FindBiggerThan(min, boundaryValues) ||
bar.GetPrice(overMaxPriceType) < FindLesserThan(min + ((max - min) / 2), boundaryValues));
//
result = isBullish ||
isBearish;
if (!result)
{
return result;
}
//
dir =
isBullish
? X_DIRECTION_BULLISH
: X_DIRECTION_BEARISH;
//
// Cleanup ...
bar.Clean();
pBar.Clean();
//
return result;
}
/**
* Check Specified Bar's Price in Hot Place or Not ...
*
* @param dir: reference for holds cross Direction ...
* @param barIndex: int, Specified Bar Index ...
* @param overMaxPriceType: ENUM_X_PRICE, which price of Specified bar to Check ...
* @param underMinPriceType: ENUM_X_PRICE, which price of Specified bar to Check ...
*
* @return ( bool )
*/
bool IsInHotPlace(
ENUM_X_DIRECTION &dir,
int barIndex = 0,
ENUM_X_PRICE overMaxPriceType = X_PRICE_NONE,
ENUM_X_PRICE underMinPriceType = X_PRICE_NONE //
)
{
//
bool result = false;
//
// Prepare ...
dir = X_DIRECTION_NONE;
//
// Normalize ...
barIndex = NormalizeBarIndex(barIndex);
if (!IsXValid(overMaxPriceType))
{
overMaxPriceType = X_PRICE_LOW;
}
if (!IsXValid(underMinPriceType))
{
underMinPriceType = X_PRICE_HIGH;
}
//
// Validate ...
result = IsValid();
if (!result)
{
return result;
}
//
// Initialize Bar ...
XOHCL bar;
result = bar.Init(
mSymbol,
mPeriod,
barIndex);
if (!result)
{
//
bar.Clean();
return result;
}
//
double overMaxPrice = bar.GetPrice(overMaxPriceType);
double underMinPrice = bar.GetPrice(underMinPriceType);
//
// Reading Boundary Value ...
double min;
double max;
result = GetBoundaryValues(
min,
max,
barIndex //
);
if (!result)
{
//
bar.Clean();
return result;
}
//
bool isBullish = underMinPrice < min;
bool isBearish = overMaxPrice > max;
//
result = (isBullish && !isBearish) ||
(isBearish && !isBullish);
if (result)
{
//
dir =
isBullish
? X_DIRECTION_BULLISH
: X_DIRECTION_BEARISH;
}
//
// Cleanup Resources ...
bar.Clean();
//
return result;
}
/**
* Check Specified Bar price Crossed in Boundary or not ...
*
* @param dir: ENUM_X_DIRECTION, reference to hold Crossed in Dir ...
* @param priceType: ENUM_X_PRICE, Specified Price type of Bar ...
* @param barIndex: int, Specified Bar Index ...
*
* @return ( bool )
*/
bool IsCrossedInBoundary(
ENUM_X_DIRECTION &dir,
ENUM_X_PRICE priceType = X_PRICE_CLOSE,
int barIndex = 0 //
)
{
//
bool result = false;
//
// Prepare ...
dir = X_DIRECTION_NONE;
//
// Normalize ...
barIndex = NormalizeBarIndex(barIndex);
int pBarIndex = barIndex + 1;
//
if (!IsXValid(priceType))
{
priceType = X_PRICE_CLOSE;
}
//
// Validate ...
result = IsValid();
if (!result)
{
return result;
}
//
// Check PrevBar Is in Hot Place ...
result = IsInHotPlace(
dir,
pBarIndex,
X_PRICE_LOW,
X_PRICE_HIGH //
);
if (!result)
{
//
dir = X_DIRECTION_NONE;
//
return result;
}
//
bool isBullish = IsXBullish(dir);
bool isBearish = IsXBearish(dir);
//
// Current Bar must Into Boundary ...
result = IsInBoundary(priceType, barIndex);
if (!result)
{
dir = X_DIRECTION_NONE;
}
//
result = HasDirection(dir);
//
return result;
}
/**
* Check Specified Bar price Crossed out Boundary or not ...
*
* @param dir: ENUM_X_DIRECTION, reference to hold Crossed in Dir ...
* @param priceType: ENUM_X_PRICE, Specified Price type of Bar ...
* @param barIndex: int, Specified Bar Index ...
*
* @return ( bool )
*/
bool IsCrossedOutBoundary(
ENUM_X_DIRECTION &dir,
ENUM_X_PRICE priceType = X_PRICE_CLOSE,
int barIndex = 0 //
)
{
//
bool result = false;
//
// Prepare ...
dir = X_DIRECTION_NONE;
//
// Normalize ...
barIndex = NormalizeBarIndex(barIndex);
int pBarIndex = barIndex + 1;
//
if (!IsXValid(priceType))
{
priceType = X_PRICE_CLOSE;
}
//
// Validate ...
result = IsValid();
if (!result)
{
return result;
}
//
// Prev Bar Must in Boundary ...
bool isBullish = IsInBoundary(X_PRICE_LOW, pBarIndex);
bool isBearish = IsInBoundary(X_PRICE_HIGH, pBarIndex);
result = isBullish ||
isBearish;
if (!result)
{
return result;
}
//
// Current Bar must Out of Boundary ...
XOHCL bar;
result = bar.Init(
mSymbol,
mPeriod,
barIndex //
);
//
isBullish =
result &&
isBullish &&
bar.IsBullish() &&
!IsInBoundary(priceType, barIndex);
//
isBearish =
result &&
isBearish &&
bar.IsBearish() &&
!IsInBoundary(priceType, barIndex);
//
result = isBullish ||
isBearish;
if (!result)
{
//
bar.Clean();
return result;
}
//
dir = isBullish
? X_DIRECTION_BULLISH
: X_DIRECTION_BEARISH;
//
result = HasDirection(dir);
//
// Cleanup ...
bar.Clean();
//
return result;
}
/**
* Check Specified Bar has Boundary Trend or not ...
*
* @param dir: reference for holds cross Direction ...
* @param barIndex: int, Specified Bar Index ...
*
* @return ( bool )
*/
bool HasBoundaryTrend(
ENUM_X_DIRECTION &dir,
int barIndex = 0 //
)
{
//
bool result = false;
//
// Prepare ...
dir = X_DIRECTION_NONE;
//
// Normalize ...
barIndex = NormalizeBarIndex(barIndex);
//
// Validate ...
result = IsValid();
if (!result)
{
return result;
}
//
double fast = GetMAFast(barIndex);
double slow = GetMASlow(barIndex);
//
double maBandUpper = GetMABandUpper(barIndex);
double maBandLower = GetMABandLower(barIndex);
//
double pbBandUpper = GetPBBandUpper(barIndex);
double pbBandLower = GetPBBandLower(barIndex);
//
double hkBandUpper = GetHKBandUpper(barIndex);
double hkBandLower = GetHKBandLower(barIndex);
//
result =
NotEmptyZero(fast) &&
NotEmptyZero(slow) &&
NotEmptyZero(maBandUpper) &&
NotEmptyZero(maBandLower) &&
NotEmptyZero(hkBandUpper) &&
NotEmptyZero(hkBandLower) &&
NotEmptyZero(pbBandUpper) &&
NotEmptyZero(pbBandLower);
if (!result)
{
return result;
}
//
bool isBullish =
fast > hkBandLower &&
slow > hkBandLower &&
maBandUpper > hkBandLower &&
maBandLower > hkBandLower &&
pbBandUpper > hkBandLower &&
pbBandLower > hkBandLower;
bool isBearish =
fast < hkBandUpper &&
slow < hkBandUpper &&
maBandUpper < hkBandUpper &&
maBandLower < hkBandUpper &&
pbBandUpper < hkBandUpper &&
pbBandLower < hkBandUpper;
//
result = (isBullish && !isBearish) ||
(isBearish && !isBullish);
if (result)
{
//
dir =
isBullish
? X_DIRECTION_BULLISH
: X_DIRECTION_BEARISH;
}
//
return result;
}
/**
* Check Specified Bar has Boundary Trend Switched or not ...
*
* @param dir: reference for holds cross Direction ...
* @param barIndex: int, Specified Bar Index ...
*
* @return ( bool )
*/
bool HasBoundarySwitch(
ENUM_X_DIRECTION &dir,
int barIndex = 0 //
)
{
//
bool result = false;
//
// Prepare ...
dir = X_DIRECTION_NONE;
//
// Normalize ...
barIndex = NormalizeBarIndex(barIndex);
//
// Validate ...
result = IsValid();
if (!result)
{
return result;
}
//
result = HasBoundaryTrend(
dir,
barIndex //
);
if (!result)
{
return result;
}
bool isBullish = IsXBullish(dir);
bool isBearish = IsXBearish(dir);
//
result = HasBoundaryTrend(
dir,
barIndex + 1 //
);
if (!result)
{
return result;
}
bool isPBullish = IsXBullish(dir);
bool isPBearish = IsXBearish(dir);
//
bool isSwitchedToBullish =
isBullish && !isPBullish;
bool isSwitchedToBearish =
isBearish && !isPBearish;
result = isSwitchedToBullish ||
isSwitchedToBearish;
if (result)
{
//
dir = isSwitchedToBullish
? X_DIRECTION_BULLISH
: X_DIRECTION_BEARISH;
}
//
return result;
}
/**
* Check Fibo Section is Changed or not ...
*
* @param dir: reference to hold section change direction ...
* @param barIndex: int, Specified Bar Index ...
*
* @return ( bool )
*/
bool IsFiboSectionChanged(
ENUM_X_DIRECTION &dir,
int barIndex = 0 //
)
{
//
bool result = false;
//
// Prepare ...
dir = X_DIRECTION_NONE;
//
// Normalize ...
barIndex = NormalizeBarIndex(barIndex);
//
// Validate ...
result = IsValid();
if (!result)
{
return result;
}
//
bool isBullish = false;
bool isBearish = false;
//
// Reading Values ...
//
double iFiboUpper = GetFiboUpper(barIndex);
double pFiboUpper = GetFiboUpper(barIndex + 1);
//
double iFiboMiddle = GetFiboMiddle(barIndex);
double pFiboMiddle = GetFiboMiddle(barIndex + 1);
//
double iFiboLower = GetFiboLower(barIndex);
double pFiboLower = GetFiboLower(barIndex + 1);
//
isBullish = iFiboLower >= pFiboMiddle &&
iFiboMiddle >= pFiboUpper;
isBearish = iFiboUpper <= pFiboMiddle &&
iFiboMiddle <= pFiboLower;
result = (isBullish && !isBearish) ||
(isBearish && !isBullish);
if (!result)
{
return result;
}
//
dir =
isBullish
? X_DIRECTION_BULLISH
: X_DIRECTION_BEARISH;
//
return result;
}
/**
* Check for Fibo Push Exists or not ...
*
* @param dir: ENUM_X_DIRECTION, reference to hold result ...
* @param barIndex: int, Specified Bar Index ...
* @param validationLength: int, Validation Length ...
*
* @return ( bool )
*/
bool HasFiboPush(
ENUM_X_DIRECTION &dir,
int barIndex = 0,
int validationLength = 5 //
)
{
//
bool result = false;
//
// Prepare ...
dir = X_DIRECTION_NONE;
//
// Normalize ...
barIndex = NormalizeBarIndex(barIndex);
validationLength = NormalizeInt(validationLength, 3);
//
// Validate ...
result = IsValid();
if (!result)
{
return result;
}
//
// Define Requirements ...
//
XOHCL iBar;
bool isBullish = false;
bool isBearish = false;
//
double iFiboUpper = EMPTY_VALUE;
double pFiboUpper = EMPTY_VALUE;
//
double iFiboMiddle = EMPTY_VALUE;
double pFiboMiddle = EMPTY_VALUE;
//
double iFiboLower = EMPTY_VALUE;
double pFiboLower = EMPTY_VALUE;
//
// Check Zone Validation ...
int start = barIndex;
int end = start + validationLength;
for (int i = start; i < end; i++)
{
//
// Reading Values ...
//
iFiboUpper = GetFiboUpper(i);
pFiboUpper = GetFiboUpper(i + 1);
//
iFiboMiddle = GetFiboMiddle(i);
pFiboMiddle = GetFiboMiddle(i + 1);
//
iFiboLower = GetFiboLower(i);
pFiboLower = GetFiboLower(i + 1);
//
result = iFiboUpper == pFiboUpper;
if (!result)
{
break;
}
}
//
if (result)
{
//
result = iBar.Init(
mSymbol,
mPeriod,
barIndex //
);
//
if (result)
{
//
iFiboUpper = GetFiboUpper(barIndex);
iFiboMiddle = GetFiboMiddle(barIndex);
iFiboLower = GetFiboLower(barIndex);
//
isBullish = iBar.IsBullish() &&
iBar.close > iFiboLower &&
iBar.low < iFiboLower;
isBearish = iBar.IsBearish() &&
iBar.close < iFiboUpper &&
iBar.high > iFiboUpper;
result = (isBullish && !isBearish) ||
(isBearish && !isBullish);
if (result)
{
//
dir =
isBullish
? X_DIRECTION_BULLISH
: X_DIRECTION_BEARISH;
}
}
}
//
// Cleanup Resources ...
iBar.Clean();
//
return result;
}
/**
* Check Has Higher Low Based On ZigZag ...
*
* @param barIndex: int, Specified Bar Index ...
* @param forceBarValidation: bool, Force Bar Price based on Pivot ...
*
* @return ( bool )
*/
bool HasZigZagHigherLow(
int barIndex = 0,
bool forceBarValidation = false //
)
{
//
bool result = false;
//
// Normalize ...
barIndex = NormalizeBarIndex(barIndex);
//
// Validate ...
XOHCL bar;
result = IsValid() &&
bar.Init(
mSymbol,
mPeriod,
barIndex //
);
if (!result)
{
//
bar.Clean();
//
return result;
}
//
// Extract Pivots ...
XPivot pivots[];
int count = ExtractZigZagPivots(
pivots,
barIndex,
10,
200 //
);
//
// Validate Pivots and Nearest Pivot is Low ...
result = IsValidSize(count) &&
pivots[0].IsVale();
if (!result)
{
//
bar.Clean();
XClean(pivots);
//
return result;
}
//
// Extract Directional Pivots ...
XPivot vales[];
count = ExtractPivots(
vales,
pivots,
X_PIVOT_TYPE_VALE //
);
result = IsValidSize(count) &&
count >= 2;
if (!result)
{
//
bar.Clean();
XClean(vales);
XClean(pivots);
//
return result;
}
//
// Check Result ...
result =
vales[0].value > vales[1].value;
if (forceBarValidation)
{
//
result =
result &&
bar.open > vales[0].value &&
bar.close > vales[0].value;
}
//
// Cleanup ...
bar.Clean();
XClean(vales);
XClean(pivots);
//
return result;
}
/**
* Check Has Lower Low Based On ZigZag ...
*
* @param barIndex: int, Specified Bar Index ...
* @param forceBarValidation: bool, Force Bar Price based on Pivot ...
*
* @return ( bool )
*/
bool HasZigZagLowerLow(
int barIndex = 0,
bool forceBarValidation = false //
)
{
//
bool result = false;
//
// Normalize ...
barIndex = NormalizeBarIndex(barIndex);
//
// Validate ...
XOHCL bar;
result = IsValid() &&
bar.Init(
mSymbol,
mPeriod,
barIndex //
);
if (!result)
{
//
bar.Clean();
//
return result;
}
//
// Extract Pivots ...
XPivot pivots[];
int count = ExtractZigZagPivots(
pivots,
barIndex,
10,
200 //
);
//
// Validate Pivots and Nearest Pivot is Low ...
result = IsValidSize(count) &&
pivots[0].IsVale();
if (!result)
{
//
bar.Clean();
XClean(pivots);
//
return result;
}
//
// Extract Directional Pivots ...
XPivot vales[];
count = ExtractPivots(
vales,
pivots,
X_PIVOT_TYPE_VALE //
);
result = IsValidSize(count) &&
count >= 2;
if (!result)
{
//
bar.Clean();
XClean(vales);
XClean(pivots);
//
return result;
}
//
// Check Result ...
result =
vales[0].value < vales[1].value;
if (forceBarValidation)
{
//
result =
result &&
bar.open < vales[0].value &&
bar.close < vales[0].value;
}
//
// Cleanup ...
bar.Clean();
XClean(vales);
XClean(pivots);
//
return result;
}
/**
* Check Has Higher High Based On ZigZag ...
*
* @param barIndex: int, Specified Bar Index ...
* @param forceBarValidation: bool, Force Bar Price based on Pivot ...
*
* @return ( bool )
*/
bool HasZigZagHigherHigh(
int barIndex = 0,
bool forceBarValidation = false //
)
{
//
bool result = false;
//
// Normalize ...
barIndex = NormalizeBarIndex(barIndex);
//
// Validate ...
XOHCL bar;
result = IsValid() &&
bar.Init(
mSymbol,
mPeriod,
barIndex //
);
if (!result)
{
//
bar.Clean();
//
return result;
}
//
// Extract Pivots ...
XPivot pivots[];
int count = ExtractZigZagPivots(
pivots,
barIndex,
10,
200 //
);
//
// Validate Pivots and Nearest Pivot is Low ...
result = IsValidSize(count) &&
pivots[0].IsPeak();
if (!result)
{
//
bar.Clean();
XClean(pivots);
//
return result;
}
//
// Extract Directional Pivots ...
XPivot peaks[];
count = ExtractPivots(
peaks,
pivots,
X_PIVOT_TYPE_PEAK //
);
result = IsValidSize(count) &&
count >= 2;
if (!result)
{
//
bar.Clean();
XClean(peaks);
XClean(pivots);
//
return result;
}
//
// Check Result ...
result =
peaks[0].value > peaks[1].value;
if (forceBarValidation)
{
//
result =
result &&
bar.open > peaks[0].value &&
bar.close > peaks[0].value;
}
//
// Cleanup ...
bar.Clean();
XClean(peaks);
XClean(pivots);
//
return result;
}
/**
* Check Has Lower High Based On ZigZag ...
*
* @param barIndex: int, Specified Bar Index ...
* @param forceBarValidation: bool, Force Bar Price based on Pivot ...
*
* @return ( bool )
*/
bool HasZigZagLowerHigh(
int barIndex = 0,
bool forceBarValidation = false //
)
{
//
bool result = false;
//
// Normalize ...
barIndex = NormalizeBarIndex(barIndex);
//
// Validate ...
XOHCL bar;
result = IsValid() &&
bar.Init(
mSymbol,
mPeriod,
barIndex //
);
if (!result)
{
//
bar.Clean();
//
return result;
}
//
// Extract Pivots ...
XPivot pivots[];
int count = ExtractZigZagPivots(
pivots,
barIndex,
10,
200 //
);
//
// Validate Pivots and Nearest Pivot is Low ...
result = IsValidSize(count) &&
pivots[0].IsPeak();
if (!result)
{
//
bar.Clean();
XClean(pivots);
//
return result;
}
//
// Extract Directional Pivots ...
XPivot peaks[];
count = ExtractPivots(
peaks,
pivots,
X_PIVOT_TYPE_PEAK //
);
result = IsValidSize(count) &&
count >= 2;
if (!result)
{
//
bar.Clean();
XClean(peaks);
XClean(pivots);
//
return result;
}
//
// Check Result ...
result =
peaks[0].value < peaks[1].value;
if (forceBarValidation)
{
//
result =
result &&
bar.open < peaks[0].value &&
bar.close < peaks[0].value;
}
//
// Cleanup ...
bar.Clean();
XClean(peaks);
XClean(pivots);
//
return result;
}
//
// SAR ...
/**
* Check Specified Bar has SAR Switch or not ...
*
* @param dir: reference for holds cross Direction ...
* @param barIndex: int, Specified Bar Index ...
*
* @return ( bool )
*/
bool HasSARSwitch(
ENUM_X_DIRECTION &dir,
int barIndex = 0 //
)
{
//
bool result = false;
//
// Prepare ...
dir = X_DIRECTION_NONE;
//
// Normalize ...
barIndex = NormalizeInt(barIndex, 0);
//
// Validate ...
result = IsValid();
if (!result)
{
return result;
}
//
double sars[];
int count = CopySarState(barIndex, 2, sars);
//
bool isBullish = false;
bool isBearish = false;
//
// Validate Readed Values ...
result = IsValidSize(count) && count >= 2;
if (result)
{
//
// Detect Direction Change ...
//
isBullish =
sars[0] >= 1 &&
sars[1] <= -1;
//
isBearish =
sars[0] <= -1 &&
sars[1] >= 1;
//
result =
isBullish ||
isBearish;
}
//
if (result)
{
//
// Setting Direction ...
dir =
isBullish
? X_DIRECTION_BULLISH
: isBearish
? X_DIRECTION_BEARISH
: X_DIRECTION_NONE;
}
//
// Cleanup Resources ...
XClean(sars);
//
return result;
}
//
// PV ...
//
// HK ...
/**
* Check Specified Bar has HK Switch or not ...
*
* @param dir: reference for holds cross Direction ...
* @param barIndex: int, Specified Bar Index ...
*
* @return ( bool )
*/
bool HasHKSwitch(
ENUM_X_DIRECTION &dir,
int barIndex = 0 //
)
{
//
bool result = false;
//
// Prepare ...
dir = X_DIRECTION_NONE;
//
// Normalize ...
barIndex = NormalizeInt(barIndex, 0);
//
double open[];
int openCount = CopyHKOpen(barIndex, 2, open);
//
double close[];
int closeCount = CopyHKClose(barIndex, 2, close);
//
bool isBullish = false;
bool isBearish = false;
//
// Validate Readed Values ...
int count = MathMin(openCount, closeCount);
result = IsValidSize(count) && count >= 2;
if (result)
{
//
// Detect Direction Change ...
//
bool notEmpty =
NotEmptyZero(open[0]) &&
NotEmptyZero(open[1]) &&
NotEmptyZero(close[0]) &&
NotEmptyZero(close[1]);
//
isBullish =
notEmpty &&
open[0] < close[0] &&
open[1] > close[1];
//
isBearish =
notEmpty &&
open[0] > close[0] &&
open[1] < close[1];
//
result =
isBullish ||
isBearish;
}
//
if (result)
{
//
// Setting Direction ...
dir =
isBullish
? X_DIRECTION_BULLISH
: isBearish
? X_DIRECTION_BEARISH
: X_DIRECTION_NONE;
}
//
// Cleanup Resources ...
XClean(open);
XClean(close);
//
return result;
}
/**
* Check Specified Bar has HK Band Based Trend or not ...
*
* @param dir: ENUM_X_DIRECTION, reference to holds trend direction, if exists ...
* @param barIndex: int, Specified Bar Index ...
* @param validationLength: int, validation of trend ...
*
* @return ( bool )
*/
bool HasHKBasedTrend(
ENUM_X_DIRECTION &dir,
int barIndex = 0,
int validationLength = 5 //
)
{
//
bool result = false;
//
// Prepare ...
dir = X_DIRECTION_NONE;
//
// Normalize ...
barIndex = NormalizeBarIndex(barIndex);
validationLength = NormalizeInt(validationLength, 1);
//
// Validate ...
result = IsValid();
if (!result)
{
return result;
}
//
// Do ...
//
// Define Requirements ...
XOHCL iBar;
double hkUpper;
double hkLower;
bool has = false;
int bullishCount = 0;
int bearishCount = 0;
bool isBullish = false;
bool isBearish = false;
//
// Count Bullish/Bearish Directions ...
int start = barIndex + 1;
int end = start + validationLength;
for (int i = start; i < end; i++)
{
//
// Reading Requirements ...
//
// Read Indexed Bar ...
iBar.Clean();
result = iBar.Init(
mSymbol,
mPeriod,
i //
);
if (!result)
{
break;
}
//
// Reading Values ...
hkUpper = GetHKBandUpper(i);
hkLower = GetHKBandLower(i);
result = NotEmptyZero(hkUpper) &&
NotEmptyZero(hkLower);
if (!result)
{
return result;
}
//
// Check Trend ...
//
// Bullish ...
isBullish = iBar.low > hkLower;
if (isBullish)
{
bullishCount++;
}
//
// Bearish ...
isBearish = iBar.high < hkUpper;
if (isBearish)
{
bearishCount++;
}
//
iBar.Clean();
//
}
//
// Validate Results ...
isBullish =
bullishCount >= validationLength;
isBearish =
bearishCount >= validationLength;
//
result = (isBullish && !isBearish) ||
(isBearish && !isBullish);
//
// Setting Direction if Has Trend ...
if (result)
{
//
dir = isBullish
? X_DIRECTION_BULLISH
: X_DIRECTION_BEARISH;
}
//
// Cleanup ...
iBar.Clean();
//
return result;
}
/**
* Check Specified Bar has HK Band Based Trend Switch or not ...
*
* @param dir: ENUM_X_DIRECTION, reference to holds trend direction, if exists ...
* @param barIndex: int, Specified Bar Index ...
* @param validationLength: int, validation of trend ...
*
* @return ( bool )
*/
bool IsHKBasedTrendSwitch(
ENUM_X_DIRECTION &dir,
int barIndex = 0,
int validationLength = 5 //
)
{
//
bool result = false;
//
// Prepare ...
dir = X_DIRECTION_NONE;
//
// Normalize ...
barIndex = NormalizeBarIndex(barIndex);
validationLength = NormalizeInt(validationLength, 1);
//
// Validate ...
result = IsValid();
if (!result)
{
return result;
}
//
// Do ...
//
bool hasTrend = HasHKBasedTrend(
dir,
barIndex,
validationLength //
);
bool isBullish = hasTrend &&
IsXBullish(dir);
bool isBearish = hasTrend &&
IsXBearish(dir);
//
bool hasPTrend = HasHKBasedTrend(
dir,
barIndex + 1,
validationLength //
);
bool isPBullish = hasPTrend &&
IsXBullish(dir);
bool isPBearish = hasPTrend &&
IsXBearish(dir);
//
dir = X_DIRECTION_NONE;
//
// Checking Result ...
isBullish = isBullish && !isPBullish;
isBearish = isBearish && !isPBearish;
//
result =
(isBullish && !isBearish) ||
(isBearish && !isBullish);
if (result)
{
//
dir = isBullish
? X_DIRECTION_BULLISH
: X_DIRECTION_BEARISH;
}
//
// Cleanup ...
//
return result;
}
/**
* Check if Price Over HK Band Upper or not ...
*
* @param priceType: ENUM_X_PRICE, Specified Price type ...
* @param barIndex: int, Specified Bar index ...
*
* @return ( bool )
*/
bool IsOverHKBandUpper(
ENUM_X_PRICE priceType = X_PRICE_LOW,
int barIndex = 0 //
)
{
//
bool result = false;
//
// Normalize ...
barIndex = NormalizeBarIndex(barIndex);
//
// Validate ...
result = IsValid() &&
IsXValid(priceType);
if (!result)
{
return result;
}
//
// Do ...
//
XOHCL bar;
result = bar.Init(mSymbol, mPeriod, barIndex);
if (!result)
{
//
bar.Clean();
return result;
}
//
double price = bar.GetPrice(priceType);
double value = GetHKBandUpper(barIndex);
result = NotEmptyZero(price) &&
NotEmptyZero(value) &&
price > value;
//
// Cleanup ...
bar.Clean();
//
return result;
}
/**
* Check if Price Over HK Band Lower or not ...
*
* @param priceType: ENUM_X_PRICE, Specified Price type ...
* @param barIndex: int, Specified Bar index ...
*
* @return ( bool )
*/
bool IsOverHKBandLower(
ENUM_X_PRICE priceType = X_PRICE_LOW,
int barIndex = 0 //
)
{
//
bool result = false;
//
// Normalize ...
barIndex = NormalizeBarIndex(barIndex);
//
// Validate ...
result = IsValid() &&
IsXValid(priceType);
if (!result)
{
return result;
}
//
// Do ...
//
XOHCL bar;
result = bar.Init(mSymbol, mPeriod, barIndex);
if (!result)
{
//
bar.Clean();
return result;
}
//
double price = bar.GetPrice(priceType);
double value = GetHKBandLower(barIndex);
result = NotEmptyZero(price) &&
NotEmptyZero(value) &&
price > value;
//
// Cleanup ...
bar.Clean();
//
return result;
}
/**
* Check if Price Under HK Band Upper or not ...
*
* @param priceType: ENUM_X_PRICE, Specified Price type ...
* @param barIndex: int, Specified Bar index ...
*
* @return ( bool )
*/
bool IsUnderHKBandUpper(
ENUM_X_PRICE priceType = X_PRICE_HIGH,
int barIndex = 0 //
)
{
//
bool result = false;
//
// Normalize ...
barIndex = NormalizeBarIndex(barIndex);
//
// Validate ...
result = IsValid() &&
IsXValid(priceType);
if (!result)
{
return result;
}
//
// Do ...
//
XOHCL bar;
result = bar.Init(mSymbol, mPeriod, barIndex);
if (!result)
{
//
bar.Clean();
return result;
}
//
double price = bar.GetPrice(priceType);
double value = GetHKBandUpper(barIndex);
result = NotEmptyZero(price) &&
NotEmptyZero(value) &&
price < value;
//
// Cleanup ...
bar.Clean();
//
return result;
}
/**
* Check if Price Under HK Band Lower or not ...
*
* @param priceType: ENUM_X_PRICE, Specified Price type ...
* @param barIndex: int, Specified Bar index ...
*
* @return ( bool )
*/
bool IsUnderHKBandLower(
ENUM_X_PRICE priceType = X_PRICE_HIGH,
int barIndex = 0 //
)
{
//
bool result = false;
//
// Normalize ...
barIndex = NormalizeBarIndex(barIndex);
//
// Validate ...
result = IsValid() &&
IsXValid(priceType);
if (!result)
{
return result;
}
//
// Do ...
//
XOHCL bar;
result = bar.Init(mSymbol, mPeriod, barIndex);
if (!result)
{
//
bar.Clean();
return result;
}
//
double price = bar.GetPrice(priceType);
double value = GetHKBandLower(barIndex);
result = NotEmptyZero(price) &&
NotEmptyZero(value) &&
price < value;
//
// Cleanup ...
bar.Clean();
//
return result;
}
/**
* Check Price Switched Over HK Band Upper or not ...
*
* @param priceType: ENUM_X_PRICE, Specified Price type ...
* @param barIndex: int, Specified Bar index ...
*
* @return ( bool )
*/
bool IsSwitchedOverHKBandUpper(
ENUM_X_PRICE priceType = X_PRICE_HIGH,
int barIndex = 0 //
)
{
//
bool result = false;
//
// Normalize ...
barIndex = NormalizeBarIndex(barIndex);
//
// Validate ...
result = IsValid() &&
IsXValid(priceType);
if (!result)
{
return result;
}
//
// Do ...
//
int pBarIndex = barIndex + 1;
bool isBarPassed = IsOverHKBandUpper(priceType, barIndex);
bool isPBarPassed = !IsOverHKBandUpper(priceType, pBarIndex);
//
result = isBarPassed && isPBarPassed;
//
// Cleanup ...
//
return result;
}
/**
* Check Price Switched Under HK Band Upper or not ...
*
* @param priceType: ENUM_X_PRICE, Specified Price type ...
* @param barIndex: int, Specified Bar index ...
*
* @return ( bool )
*/
bool IsSwitchedUnderHKBandUpper(
ENUM_X_PRICE priceType = X_PRICE_LOW,
int barIndex = 0 //
)
{
//
bool result = false;
//
// Normalize ...
barIndex = NormalizeBarIndex(barIndex);
//
// Validate ...
result = IsValid() &&
IsXValid(priceType);
if (!result)
{
return result;
}
//
// Do ...
//
int pBarIndex = barIndex + 1;
bool isBarPassed = IsUnderHKBandUpper(priceType, barIndex);
bool isPBarPassed = !IsUnderHKBandUpper(priceType, pBarIndex);
//
result = isBarPassed && isPBarPassed;
//
// Cleanup ...
//
return result;
}
/**
* Check Price Switched Over HK Band Lower or not ...
*
* @param priceType: ENUM_X_PRICE, Specified Price type ...
* @param barIndex: int, Specified Bar index ...
*
* @return ( bool )
*/
bool IsSwitchedOverHKBandLower(
ENUM_X_PRICE priceType = X_PRICE_LOW,
int barIndex = 0 //
)
{
//
bool result = false;
//
// Normalize ...
barIndex = NormalizeBarIndex(barIndex);
//
// Validate ...
result = IsValid() &&
IsXValid(priceType);
if (!result)
{
return result;
}
//
// Do ...
//
int pBarIndex = barIndex + 1;
bool isBarPassed = IsOverHKBandLower(priceType, barIndex);
bool isPBarPassed = !IsOverHKBandLower(priceType, pBarIndex);
//
result = isBarPassed && isPBarPassed;
//
// Cleanup ...
//
return result;
}
/**
* Check Price Switched Under HK Band Lower or not ...
*
* @param priceType: ENUM_X_PRICE, Specified Price type ...
* @param barIndex: int, Specified Bar index ...
*
* @return ( bool )
*/
bool IsSwitchedUnderHKBandLower(
ENUM_X_PRICE priceType = X_PRICE_HIGH,
int barIndex = 0 //
)
{
//
bool result = false;
//
// Normalize ...
barIndex = NormalizeBarIndex(barIndex);
//
// Validate ...
result = IsValid() &&
IsXValid(priceType);
if (!result)
{
return result;
}
//
// Do ...
//
int pBarIndex = barIndex + 1;
bool isBarPassed = IsUnderHKBandLower(priceType, barIndex);
bool isPBarPassed = !IsUnderHKBandLower(priceType, pBarIndex);
//
result = isBarPassed && isPBarPassed;
//
// Cleanup ...
//
return result;
}
/**
* Detect Previous HK Band ...
*
* @param index: int, reference to holds index ...
* @param priceType: ENUM_X_PRICE, Specified Price Type ...
* @param barIndex: int, Specified Bar Index ...
* @param loopback: int, Max Allowed Loopback Length ...
*
* @return ( bool )
*/
bool FindLastOverHKBandUpper(
int &index,
ENUM_X_PRICE priceType = X_PRICE_HIGH,
int barIndex = 0,
int loopback = 500 //
)
{
//
bool result = false;
//
// Prepare ...
index = -1;
//
// Normalize ...
loopback = NormalizeInt(loopback, 50);
barIndex = NormalizeBarIndex(barIndex);
//
// Validate ...
result = IsValid() &&
IsXValid(priceType);
if (!result)
{
return result;
}
//
// Do ...
//
int idx = barIndex;
while (idx < barIndex + loopback)
{
//
idx++;
result = IsOverHKBandUpper(priceType, idx);
if (result)
{
//
index = idx - 1;
break;
}
}
//
result = IsValidIndex(index);
//
// Cleanup ...
//
return result;
}
/**
* Detect Previous HK Band ...
*
* @param index: int, reference to holds index ...
* @param priceType: ENUM_X_PRICE, Specified Price Type ...
* @param barIndex: int, Specified Bar Index ...
* @param loopback: int, Max Allowed Loopback Length ...
*
* @return ( bool )
*/
bool FindLastUnderHKBandUpper(
int &index,
ENUM_X_PRICE priceType = X_PRICE_HIGH,
int barIndex = 0,
int loopback = 500 //
)
{
//
bool result = false;
//
// Prepare ...
index = -1;
//
// Normalize ...
loopback = NormalizeInt(loopback, 50);
barIndex = NormalizeBarIndex(barIndex);
//
// Validate ...
result = IsValid() &&
IsXValid(priceType);
if (!result)
{
return result;
}
//
// Do ...
//
int idx = barIndex;
while (idx < barIndex + loopback)
{
//
idx++;
result = IsUnderHKBandUpper(priceType, idx);
if (result)
{
//
index = idx - 1;
break;
}
}
//
result = IsValidIndex(index);
//
// Cleanup ...
//
return result;
}
/**
* Detect Previous HK Band ...
*
* @param index: int, reference to holds index ...
* @param priceType: ENUM_X_PRICE, Specified Price Type ...
* @param barIndex: int, Specified Bar Index ...
* @param loopback: int, Max Allowed Loopback Length ...
*
* @return ( bool )
*/
bool FindLastOverHKBandLower(
int &index,
ENUM_X_PRICE priceType = X_PRICE_HIGH,
int barIndex = 0,
int loopback = 500 //
)
{
//
bool result = false;
//
// Prepare ...
index = -1;
//
// Normalize ...
loopback = NormalizeInt(loopback, 50);
barIndex = NormalizeBarIndex(barIndex);
//
// Validate ...
result = IsValid() &&
IsXValid(priceType);
if (!result)
{
return result;
}
//
// Do ...
//
int idx = barIndex;
while (idx < barIndex + loopback)
{
//
idx++;
result = IsOverHKBandLower(priceType, idx);
if (result)
{
//
index = idx - 1;
break;
}
}
//
result = IsValidIndex(index);
//
// Cleanup ...
//
return result;
}
/**
* Detect Previous HK Band ...
*
* @param index: int, reference to holds index ...
* @param priceType: ENUM_X_PRICE, Specified Price Type ...
* @param barIndex: int, Specified Bar Index ...
* @param loopback: int, Max Allowed Loopback Length ...
*
* @return ( bool )
*/
bool FindLastUnderHKBandLower(
int &index,
ENUM_X_PRICE priceType = X_PRICE_HIGH,
int barIndex = 0,
int loopback = 500 //
)
{
//
bool result = false;
//
// Prepare ...
index = -1;
//
// Normalize ...
loopback = NormalizeInt(loopback, 50);
barIndex = NormalizeBarIndex(barIndex);
//
// Validate ...
result = IsValid() &&
IsXValid(priceType);
if (!result)
{
return result;
}
//
// Do ...
//
int idx = barIndex;
while (idx < barIndex + loopback)
{
//
idx++;
result = IsUnderHKBandLower(priceType, idx);
if (result)
{
//
index = idx - 1;
break;
}
}
//
result = IsValidIndex(index);
//
// Cleanup ...
//
return result;
}
/**
* Detect Previous HK Band Switch ...
*
* @param index: int, reference to holds switched index ...
* @param priceType: ENUM_X_PRICE, Specified Price Type ...
* @param barIndex: int, Specified Bar Index ...
* @param loopback: int, Max Allowed Loopback Length ...
*
* @return ( bool )
*/
bool FindLastSwitchedOverHKBandUpper(
int &index,
ENUM_X_PRICE priceType = X_PRICE_HIGH,
int barIndex = 0,
int loopback = 500 //
)
{
//
bool result = false;
//
// Prepare ...
index = -1;
//
// Normalize ...
loopback = NormalizeInt(loopback, 50);
barIndex = NormalizeBarIndex(barIndex);
//
// Validate ...
result = IsValid() &&
IsXValid(priceType);
if (!result)
{
return result;
}
//
// Do ...
//
int idx = barIndex;
while (idx < barIndex + loopback)
{
//
idx++;
result = IsSwitchedOverHKBandUpper(priceType, idx);
if (result)
{
//
index = idx - 1;
break;
}
}
//
result = IsValidIndex(index);
//
// Cleanup ...
//
return result;
}
/**
* Detect Previous HK Band Switch ...
*
* @param index: int, reference to holds switched index ...
* @param priceType: ENUM_X_PRICE, Specified Price Type ...
* @param barIndex: int, Specified Bar Index ...
* @param loopback: int, Max Allowed Loopback Length ...
*
* @return ( bool )
*/
bool FindLastSwitchedUnderHKBandUpper(
int &index,
ENUM_X_PRICE priceType = X_PRICE_HIGH,
int barIndex = 0,
int loopback = 500 //
)
{
//
bool result = false;
//
// Prepare ...
index = -1;
//
// Normalize ...
loopback = NormalizeInt(loopback, 50);
barIndex = NormalizeBarIndex(barIndex);
//
// Validate ...
result = IsValid() &&
IsXValid(priceType);
if (!result)
{
return result;
}
//
// Do ...
//
int idx = barIndex;
while (idx < barIndex + loopback)
{
//
idx++;
result = IsSwitchedUnderHKBandUpper(priceType, idx);
if (result)
{
//
index = idx - 1;
break;
}
}
//
result = IsValidIndex(index);
//
// Cleanup ...
//
return result;
}
/**
* Detect Previous HK Band Switch ...
*
* @param index: int, reference to holds switched index ...
* @param priceType: ENUM_X_PRICE, Specified Price Type ...
* @param barIndex: int, Specified Bar Index ...
* @param loopback: int, Max Allowed Loopback Length ...
*
* @return ( bool )
*/
bool FindLastSwitchedOverHKBandLower(
int &index,
ENUM_X_PRICE priceType = X_PRICE_HIGH,
int barIndex = 0,
int loopback = 500 //
)
{
//
bool result = false;
//
// Prepare ...
index = -1;
//
// Normalize ...
loopback = NormalizeInt(loopback, 50);
barIndex = NormalizeBarIndex(barIndex);
//
// Validate ...
result = IsValid() &&
IsXValid(priceType);
if (!result)
{
return result;
}
//
// Do ...
//
int idx = barIndex;
while (idx < barIndex + loopback)
{
//
idx++;
result = IsSwitchedOverHKBandLower(priceType, idx);
if (result)
{
//
index = idx - 1;
break;
}
}
//
result = IsValidIndex(index);
//
// Cleanup ...
//
return result;
}
/**
* Detect Previous HK Band Switch ...
*
* @param index: int, reference to holds switched index ...
* @param priceType: ENUM_X_PRICE, Specified Price Type ...
* @param barIndex: int, Specified Bar Index ...
* @param loopback: int, Max Allowed Loopback Length ...
*
* @return ( bool )
*/
bool FindLastSwitchedUnderHKBandLower(
int &index,
ENUM_X_PRICE priceType = X_PRICE_HIGH,
int barIndex = 0,
int loopback = 500 //
)
{
//
bool result = false;
//
// Prepare ...
index = -1;
//
// Normalize ...
loopback = NormalizeInt(loopback, 50);
barIndex = NormalizeBarIndex(barIndex);
//
// Validate ...
result = IsValid() &&
IsXValid(priceType);
if (!result)
{
return result;
}
//
// Do ...
//
int idx = barIndex;
while (idx < barIndex + loopback)
{
//
idx++;
result = IsSwitchedUnderHKBandLower(priceType, idx);
if (result)
{
//
index = idx - 1;
break;
}
}
//
result = IsValidIndex(index);
//
// Cleanup ...
//
return result;
}
//
// ZigZag Pivots With Liquidity ...
/**
* Check ZigZag has Lower Low by Liquidity or Not ...
*
* @param barIndex: int, Specified Bar Index ...
* @param forceBarValidation: bool, Force Bar Price based on Pivot ...
*
* @return ( bool )
*/
bool HasZigZagLowerLowByLiquidity(
int barIndex = 0,
bool forceBarValidation = false //
)
{
//
bool result = false;
//
// Normalize ...
XOHCL bar;
barIndex = NormalizeBarIndex(barIndex);
//
// Validate ...
result = IsValid() &&
bar.Init(
mSymbol,
mPeriod,
barIndex //
);
if (!result)
{
//
bar.Clean();
return result;
}
//
// Extract Pivots ...
XPivot pivots[];
int count = ExtractZigZagPivots(
pivots,
barIndex,
10,
200 //
);
//
// Validate Pivots and Nearest Pivot is Low ...
result = IsValidSize(count) &&
pivots[0].IsVale();
if (!result)
{
//
bar.Clean();
XClean(pivots);
//
return result;
}
//
// Extract Directional Pivots ...
XPivot selected[];
count = ExtractPivots(
selected,
pivots,
X_PIVOT_TYPE_VALE //
);
result = IsValidSize(count) &&
count >= 3;
if (!result)
{
//
bar.Clean();
XClean(pivots);
XClean(selected);
//
return result;
}
//
// Do Calculations ...
result =
//
// Check Pivot ...
selected[0].value < selected[1].value &&
//
// Check Liquidity ...
selected[1].value > selected[2].value &&
//
// Check Bar Place ...
(!forceBarValidation
? true
: bar.open > selected[0].value &&
bar.close > selected[0].value);
//
// Cleanup ...
bar.Clean();
XClean(pivots);
XClean(selected);
//
return result;
}
/**
* Check ZigZag has Higher High by Liquidity or Not ...
*
* @param barIndex: int, Specified Bar Index ...
* @param forceBarValidation: bool, Force Bar Price based on Pivot ...
*
* @return ( bool )
*/
bool HasZigZagHigherHighByLiquidity(
int barIndex = 0,
bool forceBarValidation = false //
)
{
//
bool result = false;
//
// Normalize ...
XOHCL bar;
barIndex = NormalizeBarIndex(barIndex);
//
// Validate ...
result = IsValid() &&
bar.Init(
mSymbol,
mPeriod,
barIndex //
);
if (!result)
{
//
bar.Clean();
return result;
}
//
// Extract Pivots ...
XPivot pivots[];
int count = ExtractZigZagPivots(
pivots,
barIndex,
10,
200 //
);
//
// Validate Pivots and Nearest Pivot is Low ...
result = IsValidSize(count) &&
pivots[0].IsPeak();
if (!result)
{
//
bar.Clean();
XClean(pivots);
//
return result;
}
//
// Extract Directional Pivots ...
XPivot selected[];
count = ExtractPivots(
selected,
pivots,
X_PIVOT_TYPE_PEAK //
);
result = IsValidSize(count) &&
count >= 3;
if (!result)
{
//
bar.Clean();
XClean(pivots);
XClean(selected);
//
return result;
}
//
// Do Calculations ...
result =
//
// Check Pivot ...
selected[0].value > selected[1].value &&
//
// Check Liquidity ...
selected[1].value < selected[2].value &&
//
// Check Bar Place ...
(!forceBarValidation
? true
: bar.open < selected[0].value &&
bar.close < selected[0].value);
//
// Cleanup ...
bar.Clean();
XClean(pivots);
XClean(selected);
//
return result;
}
//
// Extractions ...
/**
* Extract Specified Kind of Pivots ...
*
* @param pivots: XPivot, refrence Collection to hold Extracted pivots ...
* @param barIndex: int, Specified Bar Index ...
* @param requiredNumberOFPivots: int, Specified which Number of Pivots must be Extracted ...
* @param maxAllowedLoopbackLength: int, Specified Maximum Loopback Length for Pivot Extraction ...
* @param validationLength: int, Specified Pivots Validation Length ignore if <= 0 ...
*
* @return ( int )
*/
int ExtractPVPivots(
XPivot &pivots[],
int barIndex = 0,
int requiredNumberOFPivots = 50,
int maxAllowedLoopbackLength = 1500,
int validationLength = 0 //
)
{
//
int result = 0;
//
// Prepare ...
SpecifiedClean(pivots);
//
// Normalize ...
barIndex = NormalizeInt(barIndex, 0);
validationLength = NormalizeInt(validationLength, 0);
requiredNumberOFPivots = NormalizeInt(requiredNumberOFPivots, 2);
maxAllowedLoopbackLength = NormalizeInt(maxAllowedLoopbackLength, 50);
//
// Validate ...
if (mHandler == INVALID_HANDLE)
{
return result;
}
//
bool lookupPeaks = true;
bool lookupVales = true;
//
XOHCL iBar;
XPivot iPivot;
bool has = false;
int idx = barIndex - 1;
int samePeaksCount = 0;
int sameValesCount = 0;
double tmpPeaksBuffer[];
double tmpValesBuffer[];
string symbol = GetSymbol();
double iPValue = EMPTY_VALUE;
double iVValue = EMPTY_VALUE;
double pPValue = EMPTY_VALUE;
double pVValue = EMPTY_VALUE;
ENUM_TIMEFRAMES period = GetPeriod();
ENUM_X_DIRECTION iDir = X_DIRECTION_NONE;
ENUM_X_PIVOT_TYPE iType = X_PIVOT_TYPE_NONE;
int maxAllowed = barIndex + maxAllowedLoopbackLength - 1;
while (idx < maxAllowed &&
ArraySize(pivots) < requiredNumberOFPivots)
{
//
idx++;
//
// Prepare ...
iBar.Clean();
iPivot.Clean();
SpecifiedClean(tmpPeaksBuffer);
SpecifiedClean(tmpValesBuffer);
//
// Ignore First Item ...
if (idx == barIndex)
{
continue;
}
//
// Initialize Bar ...
has = iBar.Init(
symbol,
period,
idx //
);
if (!has)
{
continue;
}
//
// Detecting ...
//
// Peak ...
if (lookupPeaks)
{
//
// Reading Buffer ...
CopyBuffer(
mHandler, // Handler ...
XFIMA_PEAK_LINE, // Handler Buffer Number ...
idx, // Bar Index ...
2, // Number of Requirements ...
tmpPeaksBuffer // Buffer ...
);
ArraySetAsSeries(tmpPeaksBuffer, true);
//
// Reading Values ...
iPValue = tmpPeaksBuffer[0];
pPValue = tmpPeaksBuffer[1];
//
// Validate Value ...
if (NotEmptyZero(iPValue))
{
//
// Check New Peak ...
has =
!NotEmptyZero(pPValue)
? true
: iPValue != pPValue;
if (has)
{
//
// Calculate and Validate Type ...
// Peaks Only Valid when Confirmed by Bar High ...
iType =
iPValue == iBar.high
? X_PIVOT_TYPE_PEAK
: X_PIVOT_TYPE_NONE;
has = IsXValid(iType);
//
// Calculate and Validate Dir ...
iDir = IsXPeak(iType)
? X_DIRECTION_BEARISH
: X_DIRECTION_NONE;
has = has &&
HasDirection(iDir);
//
// Check Validation Length ...
has =
has &&
(validationLength <= 0
? true
: samePeaksCount >= validationLength);
if (has)
{
//
// Initialize and Validate Pivot ...
has = iPivot.Init(
iPValue,
iBar.time,
symbol,
iDir,
period,
iType //
);
if (has)
{
//
iPivot.prefix = ToXString(XFIMA_PIVOT_PV);
//
// Add Pivot to Collection only if not Exists ...
AddIfNotExists(
iPivot,
pivots //
);
}
}
//
// Cleanup Resources ...
iPivot.Clean();
samePeaksCount = 0;
}
else if (iPValue == pPValue)
{
samePeaksCount++;
}
}
}
//
// Vale ...
if (lookupVales)
{
//
// Reading Buffer ...
CopyBuffer(
mHandler, // Handler ...
XFIMA_VALE_LINE, // Handler Buffer Number ...
idx, // Bar Index ...
2, // Number of Requirements ...
tmpValesBuffer // Buffer ...
);
ArraySetAsSeries(tmpValesBuffer, true);
//
// Reading Values ...
iVValue = tmpValesBuffer[0];
pVValue = tmpValesBuffer[1];
//
// Validate Value ...
if (NotEmptyZero(iVValue))
{
//
// Check New Vale ...
has =
!NotEmptyZero(pVValue)
? true
: iVValue != pVValue;
if (has)
{
//
// Calculate and Validate Type ...
// Vales Only Valid when Confirmed by Bar Low ...
iType =
iVValue == iBar.low
? X_PIVOT_TYPE_VALE
: X_PIVOT_TYPE_NONE;
has = IsXValid(iType);
//
// Calculate and Validate Dir ...
iDir = IsXVale(iType)
? X_DIRECTION_BULLISH
: X_DIRECTION_NONE;
has = has &&
HasDirection(iDir);
//
// Check Validation Length ...
has =
has &&
(validationLength <= 0
? true
: sameValesCount >= validationLength);
if (has)
{
//
// Initialize and Validate Pivot ...
has = iPivot.Init(
iVValue,
iBar.time,
symbol,
iDir,
period,
iType //
);
if (has)
{
//
iPivot.prefix = ToXString(XFIMA_PIVOT_PV);
//
// Add Pivot to Collection only if not Exists ...
AddIfNotExists(
iPivot,
pivots //
);
}
}
//
// Cleanup Resources ...
iPivot.Clean();
sameValesCount = 0;
}
else if (iVValue == pVValue)
{
sameValesCount++;
}
}
}
//
// Cleanup Resources ...
iBar.Clean();
iPivot.Clean();
SpecifiedClean(tmpPeaksBuffer);
SpecifiedClean(tmpValesBuffer);
//
// Check Moving Forward Condition ...
has =
idx < maxAllowed &&
ArraySize(pivots) < requiredNumberOFPivots;
if (!has)
{
break;
}
}
//
result = ArraySize(pivots);
//
// Cleanup Resources ...
iBar.Clean();
iPivot.Clean();
SpecifiedClean(tmpPeaksBuffer);
SpecifiedClean(tmpValesBuffer);
//
return result;
}
/**
* Extract Specified Kind of Pivots ...
*
* @param pivots: XPivot, refrence Collection to hold Extracted pivots ...
* @param barIndex: int, Specified Bar Index ...
* @param requiredNumberOFPivots: int, Specified which Number of Pivots must be Extracted ...
* @param validCrossDiffMultiplier: double, validate diff between MAs on Cross happens ...
* @param maxAllowedLoopbackLength: int, Specified Maximum Loopback Length for Pivot Extraction ...
*
* @return ( int )
*/
int ExtractMAPivots(
XPivot &pivots[],
int barIndex = 0,
int requiredNumberOFPivots = 50,
double validCrossDiffMultiplier = 1,
int maxAllowedLoopbackLength = 1500 //
)
{
//
int result = 0;
//
// Prepare ...
SpecifiedClean(pivots);
//
// Normalize ...
barIndex = NormalizeInt(barIndex, 0);
requiredNumberOFPivots = NormalizeInt(requiredNumberOFPivots, 2);
maxAllowedLoopbackLength = NormalizeInt(maxAllowedLoopbackLength, 50);
validCrossDiffMultiplier = NormalizeDouble(validCrossDiffMultiplier, 0);
//
// Validate ...
if (mHandler == INVALID_HANDLE)
{
return result;
}
//
double fast[];
double slow[];
XPivot iPivot;
int count = 0;
bool has = false;
int idx = barIndex - 1;
datetime iPivotTime = NULL;
string symbol = GetSymbol();
double iFValue = EMPTY_VALUE;
double pFValue = EMPTY_VALUE;
double iSValue = EMPTY_VALUE;
double pSValue = EMPTY_VALUE;
bool isSwitchedToBullish = false;
bool isSwitchedToBearish = false;
double iSelectedValue = EMPTY_VALUE;
ENUM_TIMEFRAMES period = GetPeriod();
ENUM_X_DIRECTION iDir = X_DIRECTION_NONE;
ENUM_X_PIVOT_TYPE iType = X_PIVOT_TYPE_NONE;
int maxAllowed = barIndex + maxAllowedLoopbackLength - 1;
while (idx < maxAllowed &&
ArraySize(pivots) < requiredNumberOFPivots)
{
//
idx++;
//
// Prepare ...
XClean(fast);
XClean(slow);
iPivot.Clean();
//
// Ignore First Item ...
if (idx == barIndex)
{
continue;
}
//
// Reading Buffer ...
int fastCount = CopyMAFast(idx, 2, fast);
int slowCount = CopyMASlow(idx, 2, slow);
count = MathMin(fastCount, slowCount);
has = IsValidSize(count);
//
// Reading Values ...
//
iFValue = fast[0];
pFValue = fast[1];
//
iSValue = slow[0];
pSValue = slow[1];
//
// Validate Value ...
has =
HasMACross(
iDir,
idx,
validCrossDiffMultiplier //
) &&
NotEmptyZero(iFValue) &&
NotEmptyZero(iSValue) &&
NotEmptyZero(pFValue) &&
NotEmptyZero(pSValue);
if (has)
{
//
// Check Direction Changed ...
isSwitchedToBullish = IsXBullish(iDir);
isSwitchedToBearish = IsXBearish(iDir);
has =
isSwitchedToBullish ||
isSwitchedToBearish;
if (has)
{
//
// Calculate and Validate Type ...
// Peaks Only Valid when Confirmed by Bar High ...
iType =
isSwitchedToBearish
? X_PIVOT_TYPE_PEAK
: isSwitchedToBullish
? X_PIVOT_TYPE_VALE
: X_PIVOT_TYPE_NONE;
has = IsXValid(iType);
//
// Calculate and Validate Dir ...
iDir = IsXPeak(iType)
? X_DIRECTION_BEARISH
: IsXVale(iType)
? X_DIRECTION_BULLISH
: X_DIRECTION_NONE;
has = has &&
HasDirection(iDir);
//
if (has)
{
//
iPivotTime = GetBarTime(
symbol,
period,
idx //
);
//
// Select Value based on Pivot Type ...
iSelectedValue = IsXPeak(iType)
? MathMax(iFValue, iSValue)
: MathMin(iFValue, iSValue);
//
// Initialize and Validate Pivot ...
has = iPivot.Init(
iSelectedValue,
iPivotTime,
symbol,
iDir,
period,
iType //
);
if (has)
{
//
iPivot.prefix = ToXString(XFIMA_PIVOT_MA_CROSS);
//
// Add Pivot to Collection only if not Exists ...
AddIfNotExists(
iPivot,
pivots //
);
}
}
//
// Cleanup Resources ...
iPivot.Clean();
}
}
//
// Cleanup Resources ...
XClean(fast);
XClean(slow);
iPivot.Clean();
//
// Check Moving Forward Condition ...
has =
idx < maxAllowed &&
ArraySize(pivots) < requiredNumberOFPivots;
if (!has)
{
break;
}
}
//
result = ArraySize(pivots);
//
// Cleanup Resources ...
XClean(fast);
XClean(slow);
iPivot.Clean();
//
return result;
}
/**
* Extract Specified Kind of Pivots ...
*
* @param pivots: XPivot, refrence Collection to hold Extracted pivots ...
* @param barIndex: int, Specified Bar Index ...
* @param requiredNumberOFPivots: int, Specified which Number of Pivots must be Extracted ...
* @param maxAllowedLoopbackLength: int, Specified Maximum Loopback Length for Pivot Extraction ...
*
* @return ( int )
*/
int ExtractHKPivots(
XPivot &pivots[],
int barIndex = 0,
int requiredNumberOFPivots = 50,
int maxAllowedLoopbackLength = 1500 //
)
{
//
int result = 0;
//
// Prepare ...
SpecifiedClean(pivots);
//
// Normalize ...
barIndex = NormalizeInt(barIndex, 0);
requiredNumberOFPivots = NormalizeInt(requiredNumberOFPivots, 2);
maxAllowedLoopbackLength = NormalizeInt(maxAllowedLoopbackLength, 50);
//
// Validate ...
if (mHandler == INVALID_HANDLE)
{
return result;
}
//
double open[];
XPivot iPivot;
int count = 0;
double close[];
bool has = false;
int idx = barIndex - 1;
datetime iPivotTime = NULL;
string symbol = GetSymbol();
bool isSwitchedToBullish = false;
bool isSwitchedToBearish = false;
double iSelectedValue = EMPTY_VALUE;
ENUM_TIMEFRAMES period = GetPeriod();
ENUM_X_DIRECTION iDir = X_DIRECTION_NONE;
ENUM_X_PIVOT_TYPE iType = X_PIVOT_TYPE_NONE;
int maxAllowed = barIndex + maxAllowedLoopbackLength - 1;
while (idx < maxAllowed &&
ArraySize(pivots) < requiredNumberOFPivots)
{
//
idx++;
//
// Prepare ...
XClean(open);
XClean(close);
iPivot.Clean();
//
// Ignore First Item ...
if (idx == barIndex)
{
continue;
}
//
// Reading Buffer ...
int openCount = CopyHKOpen(idx, 2, open);
int closeCount = CopyHKClose(idx, 2, close);
count = MathMin(openCount, closeCount);
has = IsValidSize(count);
//
// Validate Value ...
has =
HasHKSwitch(
iDir,
idx //
) &&
NotEmptyZero(open[0]) &&
NotEmptyZero(open[1]) &&
NotEmptyZero(close[0]) &&
NotEmptyZero(close[1]);
if (has)
{
//
// Check Direction Changed ...
isSwitchedToBullish = IsXBullish(iDir);
isSwitchedToBearish = IsXBearish(iDir);
has =
isSwitchedToBullish ||
isSwitchedToBearish;
if (has)
{
//
// Calculate and Validate Type ...
// Peaks Only Valid when Confirmed by Bar High ...
iType =
isSwitchedToBearish
? X_PIVOT_TYPE_PEAK
: isSwitchedToBullish
? X_PIVOT_TYPE_VALE
: X_PIVOT_TYPE_NONE;
has = IsXValid(iType);
//
// Calculate and Validate Dir ...
iDir = IsXPeak(iType)
? X_DIRECTION_BEARISH
: IsXVale(iType)
? X_DIRECTION_BULLISH
: X_DIRECTION_NONE;
has = has &&
HasDirection(iDir);
//
if (has)
{
//
iPivot.prefix = ToXString(XFIMA_PIVOT_HK);
//
iPivotTime = GetBarTime(
symbol,
period,
idx //
);
//
// Select Value based on Pivot Type ...
iSelectedValue = IsXPeak(iType)
? MathMax(open[0], close[0])
: MathMin(open[0], close[0]);
//
// Initialize and Validate Pivot ...
has = iPivot.Init(
iSelectedValue,
iPivotTime,
symbol,
iDir,
period,
iType //
);
if (has)
{
//
// Add Pivot to Collection only if not Exists ...
AddIfNotExists(
iPivot,
pivots //
);
}
}
//
// Cleanup Resources ...
iPivot.Clean();
}
}
//
// Cleanup Resources ...
XClean(open);
XClean(close);
iPivot.Clean();
//
// Check Moving Forward Condition ...
has =
idx < maxAllowed &&
ArraySize(pivots) < requiredNumberOFPivots;
if (!has)
{
break;
}
}
//
result = ArraySize(pivots);
//
// Cleanup Resources ...
XClean(open);
XClean(close);
iPivot.Clean();
//
return result;
}
/**
* Extract Specified Kind of Pivots ...
*
* @param pivots: XPivot, refrence Collection to hold Extracted pivots ...
* @param barIndex: int, Specified Bar Index ...
* @param requiredNumberOFPivots: int, Specified which Number of Pivots must be Extracted ...
* @param maxAllowedLoopbackLength: int, Specified Maximum Loopback Length for Pivot Extraction ...
*
* @return ( int )
*/
int ExtractSARPivots(
XPivot &pivots[],
int barIndex = 0,
int requiredNumberOFPivots = 50,
int maxAllowedLoopbackLength = 1500 //
)
{
//
int result = 0;
//
// Prepare ...
SpecifiedClean(pivots);
//
// Normalize ...
barIndex = NormalizeInt(barIndex, 0);
requiredNumberOFPivots = NormalizeInt(requiredNumberOFPivots, 2);
maxAllowedLoopbackLength = NormalizeInt(maxAllowedLoopbackLength, 50);
//
// Validate ...
if (mHandler == INVALID_HANDLE)
{
return result;
}
//
XOHCL iBar;
XOHCL pBar;
XPivot iPivot;
bool has = false;
double tmpSarBuffer[];
int idx = barIndex - 1;
string symbol = GetSymbol();
double iValue = EMPTY_VALUE;
double pValue = EMPTY_VALUE;
bool isSwitchedToBullish = false;
bool isSwitchedToBearish = false;
ENUM_TIMEFRAMES period = GetPeriod();
ENUM_X_DIRECTION iDir = X_DIRECTION_NONE;
ENUM_X_PIVOT_TYPE iType = X_PIVOT_TYPE_NONE;
int maxAllowed = barIndex + maxAllowedLoopbackLength - 1;
while (idx < maxAllowed &&
ArraySize(pivots) < requiredNumberOFPivots)
{
//
idx++;
//
// Prepare ...
iBar.Clean();
pBar.Clean();
iPivot.Clean();
SpecifiedClean(tmpSarBuffer);
//
// Ignore First Item ...
if (idx == barIndex)
{
continue;
}
//
// Initialize Bar ...
has = iBar.Init(
symbol,
period,
idx //
);
has =
has &&
iBar.GetPreviousBar(pBar);
if (!has)
{
continue;
}
//
// Reading Buffer ...
CopyBuffer(
mHandler, // Handler ...
XFIMA_SAR_LINE, // Handler Buffer Number ...
idx, // Bar Index ...
2, // Number of Requirements ...
tmpSarBuffer // Buffer ...
);
ArraySetAsSeries(tmpSarBuffer, true);
//
// Reading Values ...
iValue = tmpSarBuffer[0];
pValue = tmpSarBuffer[1];
//
// Validate Value ...
if (NotEmptyZero(iValue))
{
//
// Check Sar Direction Changed ...
isSwitchedToBullish = iValue < iBar.low &&
pValue > pBar.high;
isSwitchedToBearish = iValue > iBar.high &&
pValue < pBar.low;
has =
isSwitchedToBullish ||
isSwitchedToBearish;
if (has)
{
//
// Calculate and Validate Type ...
// Peaks Only Valid when Confirmed by Bar High ...
iType =
isSwitchedToBearish
? X_PIVOT_TYPE_PEAK
: isSwitchedToBullish
? X_PIVOT_TYPE_VALE
: X_PIVOT_TYPE_NONE;
has = IsXValid(iType);
//
// Calculate and Validate Dir ...
iDir = IsXPeak(iType)
? X_DIRECTION_BEARISH
: IsXVale(iType)
? X_DIRECTION_BULLISH
: X_DIRECTION_NONE;
has = has &&
HasDirection(iDir);
//
if (has)
{
//
// Initialize and Validate Pivot ...
has = iPivot.Init(
iValue,
iBar.time,
symbol,
iDir,
period,
iType //
);
if (has)
{
//
iPivot.prefix = ToXString(XFIMA_PIVOT_SAR_SWITCH);
//
// Add Pivot to Collection only if not Exists ...
AddIfNotExists(
iPivot,
pivots //
);
}
}
//
// Cleanup Resources ...
iPivot.Clean();
}
}
//
// Cleanup Resources ...
iBar.Clean();
pBar.Clean();
iPivot.Clean();
SpecifiedClean(tmpSarBuffer);
//
// Check Moving Forward Condition ...
has =
idx < maxAllowed &&
ArraySize(pivots) < requiredNumberOFPivots;
if (!has)
{
break;
}
}
//
result = ArraySize(pivots);
//
// Cleanup Resources ...
iBar.Clean();
pBar.Clean();
iPivot.Clean();
SpecifiedClean(tmpSarBuffer);
//
return result;
}
/**
* Extract Specified Kind of Pivots ...
*
* @param pivots: XPivot, refrence Collection to hold Extracted pivots ...
* @param barIndex: int, Specified Bar Index ...
* @param requiredNumberOFPivots: int, Specified which Number of Pivots must be Extracted ...
* @param maxAllowedLoopbackLength: int, Specified Maximum Loopback Length for Pivot Extraction ...
*
* @return ( int )
*/
int ExtractZigZagPivots(
XPivot &pivots[],
int barIndex = 0,
int requiredNumberOFPivots = 50,
int maxAllowedLoopbackLength = 1500 //
)
{
//
int result = 0;
//
// Prepare ...
SpecifiedClean(pivots);
//
// Normalize ...
barIndex = NormalizeInt(barIndex, 0);
requiredNumberOFPivots = NormalizeInt(requiredNumberOFPivots, 2);
maxAllowedLoopbackLength = NormalizeInt(maxAllowedLoopbackLength, 50);
//
// Validate ...
if (mHandler == INVALID_HANDLE)
{
return result;
}
//
XOHCL iBar;
XPivot iPivot;
bool has = false;
int idx = barIndex - 1;
double tmpZigZagBuffer[];
double iValue = EMPTY_VALUE;
string symbol = GetSymbol();
ENUM_TIMEFRAMES period = GetPeriod();
ENUM_X_DIRECTION iDir = X_DIRECTION_NONE;
ENUM_X_PIVOT_TYPE iType = X_PIVOT_TYPE_NONE;
int maxAllowed = barIndex + maxAllowedLoopbackLength - 1;
while (idx < maxAllowed &&
ArraySize(pivots) < requiredNumberOFPivots)
{
//
idx++;
//
// Prepare ...
iBar.Clean();
iPivot.Clean();
SpecifiedClean(tmpZigZagBuffer);
//
// Ignore First Item ...
if (idx == barIndex)
{
continue;
}
//
// Initialize Bar ...
has = iBar.Init(
symbol,
period,
idx //
);
if (!has)
{
continue;
}
//
// Reading Buffer ...
CopyBuffer(
mHandler, // Handler ...
XFIMA_ZIGZAG_LINE, // Handler Buffer Number ...
idx, // Bar Index ...
1, // Number of Requirements ...
tmpZigZagBuffer // Buffer ...
);
ArraySetAsSeries(tmpZigZagBuffer, true);
//
// Read and Validate Value ...
iValue = tmpZigZagBuffer[0];
has = NotEmptyZero(iValue);
if (!has)
{
//
iBar.Clean();
SpecifiedClean(tmpZigZagBuffer);
continue;
}
//
// Calculate and Validate Type ...
iType =
iValue == iBar.high
? X_PIVOT_TYPE_PEAK
: iValue == iBar.low
? X_PIVOT_TYPE_VALE
: X_PIVOT_TYPE_NONE;
has = IsXValid(iType);
if (!has)
{
//
iBar.Clean();
SpecifiedClean(tmpZigZagBuffer);
continue;
}
//
// Calculate and Validate Dir ...
iDir =
IsXVale(iType)
? X_DIRECTION_BULLISH
: IsXPeak(iType)
? X_DIRECTION_BEARISH
: X_DIRECTION_NONE;
has = HasDirection(iDir);
if (!has)
{
//
iBar.Clean();
SpecifiedClean(tmpZigZagBuffer);
continue;
}
//
// Initialize and Validate Pivot ...
has = iPivot.Init(
iValue,
iBar.time,
symbol,
iDir,
period,
iType //
);
if (has)
{
//
iPivot.prefix = ToXString(XFIMA_PIVOT_ZIGZAG);
//
// Add Pivot to Collection only if not Exists ...
AddIfNotExists(
iPivot,
pivots //
);
}
//
// Cleanup Resources ...
iBar.Clean();
iPivot.Clean();
SpecifiedClean(tmpZigZagBuffer);
//
// Check Moving Forward Condition ...
has =
idx < maxAllowed &&
ArraySize(pivots) < requiredNumberOFPivots;
if (!has)
{
break;
}
}
//
result = ArraySize(pivots);
//
// Cleanup Resources ...
iBar.Clean();
iPivot.Clean();
SpecifiedClean(tmpZigZagBuffer);
//
return result;
}
/**
* Extract Validated Zones ...
*
* @param zones: XBoxZone, collection reference to holds results ...
* @param barIndex: int, Specified Bar Index ...
* @param requiredNumberOFZones: int, required Number of Zones ...
* @param breakValidLength: int, Breake Validation Length of Zones ...
* @param validateFakeBreakes: bool, Validation Fake Breaked Zones ...
* @param shadowMultiplier: double a Shadow Multiplier for Validation ...
* @param validationStrength: double, Minimum Strngth Multiplier in Point to Validate ...
* @param validationLength: int, Validation Length of Zones ...
* @param maxAllowedLoopbackLength: int, max Allowed Loopback Length ...
*
* @return ( int )
*/
int ExtractHKZones(
XBoxZone &zones[],
int barIndex = 0,
int requiredNumberOFZones = 50,
int breakValidLength = 3,
bool validateFakeBreakes = true,
double shadowMultiplier = 3,
double validationStrength = 1,
int validationLength = 21,
int maxAllowedLoopbackLength = 1500 //
)
{
//
int result = 0;
//
// Prepare ...
SpecifiedClean(zones);
//
// Normalize ...
barIndex = NormalizeInt(barIndex, 0);
validationLength = NormalizeInt(validationLength, 7);
shadowMultiplier = NormalizeDouble(shadowMultiplier, 1);
validationStrength = NormalizeDouble(validationStrength, 1);
requiredNumberOFZones = NormalizeInt(requiredNumberOFZones, 5);
maxAllowedLoopbackLength = NormalizeInt(maxAllowedLoopbackLength, 100);
//
// Reading Values ...
//
string symbol = GetSymbol();
ENUM_TIMEFRAMES period = GetPeriod();
double minAllowedStrength = (validationStrength * GetPoints(symbol));
//
int count = 0;
XBoxZone zone;
bool has = false;
int start = barIndex;
bool isBullish = false;
bool isBearish = false;
double up = EMPTY_VALUE;
double low = EMPTY_VALUE;
double open = EMPTY_VALUE;
double high = EMPTY_VALUE;
double down = EMPTY_VALUE;
double body = EMPTY_VALUE;
double close = EMPTY_VALUE;
double range = EMPTY_VALUE;
bool lowShadowPassed = false;
bool highShadowPassed = false;
double lowShadow = EMPTY_VALUE;
double highShadow = EMPTY_VALUE;
double startHKLow = EMPTY_VALUE;
double startHKOpen = EMPTY_VALUE;
double startHKHigh = EMPTY_VALUE;
double startHKClose = EMPTY_VALUE;
ENUM_X_DIRECTION dir = X_DIRECTION_NONE;
int end = start + maxAllowedLoopbackLength;
for (int i = start; i < end; i++)
{
//
// Cleanup ...
zone.Clean();
dir = X_DIRECTION_NONE;
//
// Reading HK Buffesr ...
low = GetHKLow(i);
open = GetHKOpen(i);
high = GetHKHigh(i);
close = GetHKClose(i);
//
// Initialized Start Bar ...
if (i == start)
{
//
startHKLow = low;
startHKOpen = open;
startHKHigh = high;
startHKClose = close;
}
//
// Check Direction ...
isBullish = open < close;
isBearish = open > close;
dir =
(isBullish && !isBearish)
? X_DIRECTION_BULLISH
: (isBearish && !isBullish)
? X_DIRECTION_BEARISH
: X_DIRECTION_NONE;
has = HasDirection(dir);
if (!has)
{
continue;
}
//
// Calculate Requirements for Processing ...
up = isBullish
? close
: open;
down = isBullish
? open
: close;
body = MathAbs(up - down);
range = high - low;
highShadow = high - up;
lowShadow = down - low;
//
// Detecting Shadows ...
//
// Low Shadow ...
lowShadowPassed = lowShadow >= (shadowMultiplier * highShadow);
//
// High Shadow ...
highShadowPassed = highShadow >= (shadowMultiplier * lowShadow);
//
has = (lowShadowPassed && !highShadowPassed) ||
(highShadowPassed && !lowShadowPassed);
if (!has)
{
continue;
}
//
// Filling Zone ...
//
zone.symbol = symbol;
zone.period = period;
zone.from = GetBarTime(
zone.symbol,
zone.period,
i //
);
zone.dir = lowShadowPassed
? X_DIRECTION_BULLISH
: highShadowPassed
? X_DIRECTION_BEARISH
: X_DIRECTION_NONE;
//
zone.upper =
IsXBullish(zone.dir)
? down
: IsXBearish(zone.dir)
? high
: EMPTY_VALUE;
//
zone.lower =
IsXBullish(zone.dir)
? low
: IsXBearish(zone.dir)
? up
: EMPTY_VALUE;
//
zone.to = TimeCurrent();
zone.type = ToXString(XFIMA_PIVOT_HK) + "_" + (IsXBullish(zone.dir) ? "Support" : IsXBearish(zone.dir) ? "Resistance"
: "");
//
// Validate ...
has =
zone.IsValid() &&
HasDirection(zone.dir) &&
NotEmptyZero(zone.upper) &&
NotEmptyZero(zone.lower) &&
(zone.IsBullish()
? startHKLow > zone.upper
: startHKHigh < zone.lower) &&
(zone.upper - zone.lower) >= minAllowedStrength &&
ValidateHKZone(zone, validationLength, breakValidLength, validateFakeBreakes);
if (has)
{
//
AddIfNotExists(
zone,
zones //
);
}
//
// Cleanup Resources ...
zone.Clean();
//
// Validating ...
result = ArraySize(zones);
has = IsValidSize(result) &&
result >= requiredNumberOFZones;
if (has)
{
break;
}
}
//
// Cleanup Resources ...
zone.Clean();
//
return result;
}
//
// Values Retrievers ...
/**
* Filling Specified Bar index Boundary Values ...
*
* @param dest: double, reference collection to hold boundary Values ...
* @param barIndex: int, Specified Bar's Index ...
* @param containsFastSlow: bool, Contains XMA Fast / Slow ...
* @param containsMABand: bool, Contains XMA Boundary Upper / Lower ...
* @param containsHKBound: bool, Contains XHK Boundary Upper / Lower ...
* @param containsPBBand: bool, Contains XPB Boundary Upper / Lower ...
* @param containsFiboLevels: nool, Contains XFIBO Levels ...
*
* @return ( int )
*/
int FillBoundaryValues(
double &dest[],
int barIndex = 0,
bool containsFastSlow = true,
bool containsMABand = true,
bool containsHKBound = true,
bool containsPBBand = true,
bool containsFiboLevels = false //
)
{
//
int result = 0;
//
// Prepare ...
XClean(dest);
//
// Normalize ...
barIndex = NormalizeBarIndex(barIndex);
//
// Validate ...
bool has = IsValid();
if (!has)
{
return result;
}
//
// Read and Validate Values ...
//
double fast = GetMAFast(barIndex);
double slow = GetMASlow(barIndex);
//
double maBandUpper = GetMABandUpper(barIndex);
double maBandLower = GetMABandLower(barIndex);
//
double pbBandUpper = GetPBBandUpper(barIndex);
double pbBandLower = GetPBBandLower(barIndex);
//
double hkBandUpper = GetHKBandUpper(barIndex);
double hkBandLower = GetHKBandLower(barIndex);
//
double fiboUpper = GetFiboUpper(barIndex);
double fiboLower = GetFiboLower(barIndex);
double fiboMiddle = GetFiboMiddle(barIndex);
//
has =
NotEmptyZero(fast) &&
NotEmptyZero(slow) &&
NotEmptyZero(fiboLower) &&
NotEmptyZero(fiboUpper) &&
NotEmptyZero(fiboMiddle) &&
NotEmptyZero(maBandUpper) &&
NotEmptyZero(maBandLower) &&
NotEmptyZero(pbBandUpper) &&
NotEmptyZero(pbBandLower) &&
NotEmptyZero(hkBandUpper) &&
NotEmptyZero(hkBandLower);
if (!has)
{
return result;
}
//
// Fill Dest ...
//
// XMA Fast / Slow ...
if (containsFastSlow)
{
//
Add(fast, dest);
Add(slow, dest);
}
//
// XMA Bound ...
if (containsMABand)
{
//
Add(maBandUpper, dest);
Add(maBandLower, dest);
}
//
// XHK Band ...
if (containsHKBound)
{
//
Add(hkBandUpper, dest);
Add(hkBandLower, dest);
}
//
// XPB Band ...
if (containsPBBand)
{
//
Add(pbBandUpper, dest);
Add(pbBandLower, dest);
}
//
// XFIBO Zones ...
if (containsFiboLevels)
{
//
Add(fiboLower, dest);
Add(fiboUpper, dest);
Add(fiboMiddle, dest);
}
//
result = ArraySize(dest);
//
return result;
}
/**
* Retrieve Fast, Slow, MA Band Upper/Lower, HK Band Upper/Lower and PB Band Upper/Lower Min/Max ...
*
* @param min: double, minimum value ...
* @param max: double, maximum value ...
* @param barIndex: int, Specified Bar Index ...
*
* @return ( bool )
*/
bool GetBoundaryValues(
double &min,
double &max,
int barIndex = 0,
bool containsFastSlow = true,
bool containsMABand = true,
bool containsHKBound = true,
bool containsPBBand = true,
bool containsFiboLevels = false //
)
{
//
bool result = false;
//
// Prepare ...
min = EMPTY_VALUE;
max = EMPTY_VALUE;
//
// Normalize ...
barIndex = NormalizeBarIndex(barIndex);
//
// Validate ...
result = IsValid();
if (!result)
{
return result;
}
//
double fast = GetMAFast(barIndex);
double slow = GetMASlow(barIndex);
//
double maBandUpper = GetMABandUpper(barIndex);
double maBandLower = GetMABandLower(barIndex);
//
double pbBandUpper = GetPBBandUpper(barIndex);
double pbBandLower = GetPBBandLower(barIndex);
//
double hkBandUpper = GetHKBandUpper(barIndex);
double hkBandLower = GetHKBandLower(barIndex);
//
double fiboUpper = GetFiboUpper(barIndex);
double fiboLower = GetFiboLower(barIndex);
double fiboMiddle = GetFiboMiddle(barIndex);
//
result =
NotEmptyZero(fast) &&
NotEmptyZero(slow) &&
NotEmptyZero(fiboLower) &&
NotEmptyZero(fiboUpper) &&
NotEmptyZero(fiboMiddle) &&
NotEmptyZero(maBandUpper) &&
NotEmptyZero(maBandLower) &&
NotEmptyZero(pbBandUpper) &&
NotEmptyZero(pbBandLower) &&
NotEmptyZero(hkBandUpper) &&
NotEmptyZero(hkBandLower);
if (!result)
{
return result;
}
//
double values[];
//
if (containsFastSlow)
{
//
Add(fast, values);
Add(slow, values);
}
//
if (containsMABand)
{
//
Add(maBandUpper, values);
Add(maBandLower, values);
}
//
if (containsHKBound)
{
//
Add(hkBandUpper, values);
Add(hkBandLower, values);
}
//
if (containsPBBand)
{
//
Add(pbBandUpper, values);
Add(pbBandLower, values);
}
//
if (containsFiboLevels)
{
//
Add(fiboLower, values);
Add(fiboUpper, values);
Add(fiboMiddle, values);
}
//
result = HasChild(values);
if (!result)
{
return result;
}
//
min = GetMin(values);
max = GetMax(values);
//
result =
NotEmptyZero(min) &&
NotEmptyZero(max) &&
min < max;
//
return result;
}