Files
MQL5Data/Classes/x-saherelm.x-bar.analyser.class.mq5
T
2024-11-30 17:36:39 +03:30

2137 lines
42 KiB
Plaintext

///////////////////////////////////////////////////////
//
// SaherElm IT Center MQL5 Class Library
// --------------------------------------
// Name: XPOI
// Description: Bar Analysing ...
//
// Maintainer:
// ------------
// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com)
//
//////////////////////////////////////////////////////
//
// Global Properties ...
#property library
#property copyright "Copyright 2023, SaherElm IT Center"
#property link "https://www.saherelm.ir"
#property version "1.00"
#property strict
//
// Imports ...
#include "../Classes/x-saherelm.base.class.mq5"
#include "../Libraries/x-saherelm.x-poi.lib.mq5"
//
// Definitions ...
//
// Implementations ...
class XCBarAnalyser : public XCBase
{
//
public:
//
//
// Constructor(s) ...
void XCBarAnalyser()
{
}
//
// Deconstructor ...
void ~XCBarAnalyser()
{
}
//
// Getter(s) / Setter(s) ...
//
// Providers ...
//
// Actions ...
/**
* Calculate Loopback Data for Specific Bar ...
*
* @param index: Integer, Bar Current Index ...
* @param start: Integer, Start of Loopback ...
* @param end: Integer, End of Loopback ...
* @param count: Integer, Number of Calculating Bars ...
* @param bar: XOHCL instance, Specified Bar ...
* @param loopback: Integer, Loopback Length ...
* @return ( bool )
*/
bool CalculateLoopBackData(
int &index,
int &start,
int &end,
int &count,
XOHCL &bar,
int loopback = 1 //
)
{
//
bool result = false;
//
if (loopback < 1)
{
loopback = 1;
}
//
index = -1;
start = -1;
end = -1;
count = -1;
//
result = bar.IsValid();
if (!result)
{
return result;
}
//
index = bar.Index();
start = index + 1;
end = start + loopback;
count = end - start;
result = count >= 1;
if (!result)
{
return result;
}
//
return result;
}
/**
* Retrieve Loopback HH & LL Data ...
*
* @param hhIDX: Integer, HH Index ...
* @param hh: Double, HH Value ...
* @param llIDX: Integer, LL Index ...
* @param ll: Double, LL Value ...
* @param bar: XOHCL instance ...
* @param loopback: Integer, Loopback Length ...
*
* @return ( bool )
*/
bool CalculateLoopbackHLData(
int &hhIDX,
double &hh,
int &llIDX,
double &ll,
XOHCL &bar,
int loopback //
)
{
//
bool result = false;
//
if (loopback < 1)
{
loopback = 1;
}
//
int index = -1;
int start = -1;
int end = -1;
int count = -1;
result = CalculateLoopBackData(
index,
start,
end,
count,
bar,
loopback //
);
if (!result)
{
return result;
}
//
hhIDX = iHighest(
bar.symbol,
bar.period,
MODE_HIGH,
count,
start //
);
result = IsValidIndex(hhIDX);
if (!result)
{
return result;
}
//
llIDX = iLowest(
bar.symbol,
bar.period,
MODE_LOW,
count,
start //
);
result = IsValidIndex(llIDX);
if (!result)
{
return result;
}
//
hh = iHigh(
bar.symbol,
bar.period,
hhIDX //
);
ll = iLow(
bar.symbol,
bar.period,
llIDX //
);
//
return result;
}
/**
* Calculate Bar Range ...
*
* @param bar: XOHCL instance ...
*
* @return ( double )
*/
double GetBarRangePercent(XOHCL &bar)
{
//
double result = 0;
//
result = bar.GetRange() / 100;
//
return result;
}
/**
* Detect Same Bars ...
*
* @param bar: XOHCL instance, Start Bar ...
* @param dir: ENUM_X_DIRECTION member, Holds Result Direction ...
* @param index: Integer, Holds Result Index ...
* @param sameBars: Iteger, Required Same Bar ...
*
* @return ( bool )
*/
bool HasSameBars(
XOHCL &bar,
ENUM_X_DIRECTION &dir,
int &index,
int sameBars = 3 //
)
{
//
bool result = false;
//
dir = X_DIRECTION_NONE;
//
if (sameBars < 1)
{
sameBars = 1;
}
//
result = bar.IsValid();
if (!result)
{
return result;
}
//
index = bar.Index();
bool canContinue = true;
int sameBullishBarsFounded = 0;
int sameBearishBarsFounded = 0;
bool canContinueForBullish = true;
bool canContinueForBearish = true;
while (canContinue)
{
//
XOHCL iBar;
result = iBar.Init(
bar.symbol,
bar.period,
index //
);
if (!result)
{
break;
}
//
bool isBullish = iBar.IsBullish();
bool isBearish = iBar.IsBearish();
result = isBullish ||
isBearish;
if (!result)
{
break;
}
//
if (isBullish)
{
//
sameBullishBarsFounded++;
canContinueForBearish = false;
}
else
{
//
sameBearishBarsFounded++;
canContinueForBullish = false;
}
//
result = canContinueForBullish ||
canContinueForBearish;
if (!result)
{
break;
}
//
canContinueForBullish =
canContinueForBullish &&
sameBullishBarsFounded > 0;
//
canContinueForBearish =
canContinueForBearish &&
sameBearishBarsFounded > 0;
//
canContinue =
canContinueForBullish ||
canContinueForBearish;
if (canContinue)
{
index++;
}
}
//
bool hasBullishSameBars =
sameBullishBarsFounded >= sameBars;
//
bool hasBearishSameBars =
sameBearishBarsFounded >= sameBars;
//
result = hasBullishSameBars ||
hasBearishSameBars;
if (!result)
{
return result;
}
//
dir =
hasBullishSameBars
? X_DIRECTION_BULLISH
: X_DIRECTION_BEARISH;
//
return result;
}
/**
* Detect Consolidation Range ...
*
* @param index: Integer, Start Bar Index ...
* @param range: Integer, Range of Bars ...
* @param maxRange: Consolidation Price Range in Points ...
* @param symbol: String, Symbol ...
* @param period: ENUM_TIMEFRAMES member, Period ...
*
* @return ( bool )
*/
bool IsConsolidating(
int index,
int range,
double maxRange,
string symbol = NULL,
ENUM_TIMEFRAMES period = NULL //
)
{
//
bool result = false;
//
if (index < 0)
{
index = 0;
}
//
if (range < 1)
{
range = 1;
}
//
if (maxRange < 1)
{
maxRange = 1;
}
//
// Normalize ...
symbol = NormalizeSymbol(symbol);
period = NormalizePeriod(period);
//
// Point Value ...
double point = GetPoints(symbol);
//
double high = iHigh(
symbol,
period,
index //
);
double low = iLow(
symbol,
period,
index //
);
//
// Detect Range High and Low ...
for (int i = 1; i < range; i++)
{
//
double iH = iHigh(
symbol,
period,
index + i //
);
//
double iL = iLow(
symbol,
period,
index + i //
);
//
high = MathMax(high, iH);
low = MathMin(low, iL);
}
//
result = (high - low) <= (maxRange * point);
//
return result;
}
/**
* Check Bar Has Bullish Trend or not ...
*
* @param bar: XOHCL instance ...
* @param forceAll: Boolean ...
*
* @return ( bool )
*/
bool HasBullishTrend(
XOHCL &bar,
bool forceAll = false //
)
{
//
bool result = false;
//
result = bar.IsValid();
if (!result)
{
return result;
}
//
XOHCL tmpHSW[];
XOHCL tmpLSW[];
//
bool trend1 = bar.HasBullishTrend(
tmpHSW,
tmpLSW,
true //
);
//
bool trend2 = bar.HasBullishTrend(
tmpHSW,
tmpLSW,
false //
);
//
if (!forceAll)
{
//
result = trend1;
if (!result)
{
return result;
}
}
//
result =
trend1 ||
trend2;
//
return result;
}
/**
* Check Bar Has Bearish Trend or not ...
*
* @param bar: XOHCL instance ...
* @param forceAll: Boolean ...
*
* @return ( bool )
*/
bool HasBearishTrend(
XOHCL &bar,
bool forceAll = false //
)
{
//
bool result = false;
//
result = bar.IsValid();
if (!result)
{
return result;
}
//
XOHCL tmpHSW[];
XOHCL tmpLSW[];
//
bool trend1 = bar.HasBearishTrend(
tmpHSW,
tmpLSW,
true //
);
//
bool trend2 = bar.HasBearishTrend(
tmpHSW,
tmpLSW,
false //
);
//
if (!forceAll)
{
//
result = trend1;
if (!result)
{
return result;
}
}
//
result =
trend1 ||
trend2;
//
return result;
}
/**
* Check Specified Bar Has Bullish Pattern or not ...
*
* @param bar: XOHCL instance, Specified Bar ...
* @param loopback: Integer, Loopback Length for Patterns ...
* @param verifications: Integer, Number of Given Verifications ...
* @param checkHammer: Boolean, Specified Check Hammer Pattern ...
* @param checkMorningStar: Boolean, Specified Check Morning Star Pattern ...
* @param checkBullishMarubozu: Boolean, Specified Check Marubozu Pattern ...
* @param checkBullishEngulfing: Boolean, Specified Check Engulfing Pattern ...
*
* @return ( bool )
*/
bool HasBullishPattern(
XOHCL &bar,
int loopback = 0,
int verifications = 1,
bool checkHammer = true,
bool checkMorningStar = true,
bool checkBullishMarubozu = true,
bool checkBullishEngulfing = true //
)
{
//
bool result = false;
//
result = bar.IsValid();
if (!result)
{
return result;
}
//
if (verifications <= 0)
{
verifications = 1;
}
//
int founded = 0;
//
int idx = bar.Index();
for (int i = idx; i <= idx + loopback; i++)
{
//
XOHCL iBar;
result = iBar.Init(
bar.symbol,
bar.period,
i //
);
if (!result)
{
break;
}
//
bool isHammer =
!checkHammer
? false
: iBar.IsHammer();
if (isHammer)
{
founded++;
}
//
bool isMorningStar =
!checkMorningStar
? false
: iBar.IsMorningStar();
if (isMorningStar)
{
founded++;
}
//
bool isBullishMarubozu =
!checkBullishMarubozu
? false
: iBar.IsBullishMarubozu();
if (isBullishMarubozu)
{
founded++;
}
//
bool isBullishEngulfing =
!checkBullishEngulfing
? false
: iBar.IsBullishEngulfing();
if (isBullishEngulfing)
{
founded++;
}
//
}
//
result =
result &&
founded >= verifications;
//
return result;
}
/**
* Check Specified Bar Has Bearish Pattern or not ...
*
* @param bar: XOHCL instance, Specified Bar ...
* @param loopback: Integer, Loopback Length for Patterns ...
* @param verifications: Integer, Number of Given Verifications ...
* @param checkShootingStar: Boolean, Specified Check Shooting Star Pattern ...
* @param checkEveningStar: Boolean, Specified Check Evening Star Pattern ...
* @param checkBearishMarubozu: Boolean, Specified Check Marubozu Pattern ...
* @param checkBearishEngulfing: Boolean, Specified Check Engulfing Pattern ...
*
* @return ( bool )
*/
bool HasBearishPattern(
XOHCL &bar,
int loopback = 0,
int verifications = 1,
bool checkShootingStar = true,
bool checkEveningStar = true,
bool checkBearishMarubozu = true,
bool checkBearishEngulfing = true //
)
{
//
bool result = false;
//
result = bar.IsValid();
if (!result)
{
return result;
}
//
if (verifications <= 0)
{
verifications = 1;
}
//
int founded = 0;
//
int idx = bar.Index();
for (int i = idx - 1; i <= idx + loopback; i++)
{
//
XOHCL iBar;
result = iBar.Init(
bar.symbol,
bar.period,
i //
);
if (!result)
{
break;
}
//
bool isShootingStar =
!checkShootingStar
? false
: iBar.IsShootingStar();
if (isShootingStar)
{
founded++;
}
//
bool isEveningStar =
!checkEveningStar
? false
: iBar.IsEveningStar();
if (isEveningStar)
{
founded++;
}
//
bool isBearishMarubozu =
!checkBearishMarubozu
? false
: iBar.IsBearishMarubozu();
if (isBearishMarubozu)
{
founded++;
}
//
bool isBearishEngulfing =
!checkBearishEngulfing
? false
: iBar.IsBearishEngulfing();
if (isBearishEngulfing)
{
founded++;
}
//
}
//
result =
result &&
founded >= verifications;
//
return result;
}
//
// Commons ...
/**
* Check Specified Bar's Range is Extended or not ...
*
* @param bar: XOHCL instance, Specified Bar ...
* @param loopback: Integer, Loopback Length ...
*
* @return ( bool )
*/
bool HasExtendedRange(
XOHCL &bar,
int loopback = 3 //
)
{
//
bool result = false;
//
if (loopback < 3)
{
loopback = 3;
}
//
result = bar.IsValid();
if (!result)
{
return result;
}
//
int index = bar.Index();
int start = index + 1;
int end = start + loopback;
int count = end - start;
result = count >= 1;
if (!result)
{
return result;
}
//
double sum = 0;
XOHCL iBar = bar;
for (int i = start; i < end; i++)
{
//
bool isRetrieved = iBar.GetPreviousBar(iBar);
if (!isRetrieved)
{
continue;
}
//
sum += iBar.GetRange();
}
//
result = sum > 0;
if (!result)
{
return result;
}
//
double avg = sum / count;
//
result = bar.GetRange() >= avg;
//
return result;
}
/**
* Check Specified Bar's Body is Extended or not ...
*
* @param bar: XOHCL instance, Specified Bar ...
* @param loopback: Integer, Loopback Length ...
*
* @return ( bool )
*/
bool HasExtendedBody(
XOHCL &bar,
int loopback = 3 //
)
{
//
bool result = false;
//
if (loopback < 3)
{
loopback = 3;
}
//
result = bar.IsValid();
if (!result)
{
return result;
}
//
int index = bar.Index();
int start = index + 1;
int end = start + loopback;
int count = end - start;
result = count >= 1;
if (!result)
{
return result;
}
//
double sum = 0;
XOHCL iBar = bar;
for (int i = start; i < end; i++)
{
//
bool isRetrieved = iBar.GetPreviousBar(iBar);
if (!isRetrieved)
{
continue;
}
//
sum += iBar.GetBody();
}
//
result = sum > 0;
if (!result)
{
return result;
}
//
double avg = sum / count;
//
result = bar.GetBody() >= avg;
//
return result;
}
/**
* Check Specified Bar's Body and Range is Extended or not ...
*
* @param bar: XOHCL instance, Specified Bar ...
* @param loopback: Integer, Loopback Length ...
*
* @return ( bool )
*/
bool IsExtended(
XOHCL &bar,
int loopback = 3 //
)
{
//
bool result = false;
//
bool hasExtendedBody = HasExtendedBody(bar, loopback);
bool hasExtendedRange = HasExtendedRange(bar, loopback);
result = hasExtendedBody &&
hasExtendedRange;
//
return result;
}
/**
* Check Specified Bar is Swing High or not ...
*
* @param bar: XOHCL instnce ...
* @param range: Integer, Specified Range ...
*
* @return ( bool )
*/
bool IsSwingHigh(
XOHCL &bar,
int range = 2 //
)
{
//
bool result = false;
//
if (range < 1)
{
range = 1;
}
//
result = bar.IsValid();
if (!result)
{
return result;
}
//
int index = bar.Index();
result = range > 0 &&
index >= range;
if (!result)
{
return result;
}
//
string symbol = bar.symbol;
ENUM_TIMEFRAMES period = bar.period;
//
for (int i = 1; i <= range; i++)
{
//
// Prev Bar ...
XOHCL iPrevBar;
result = iPrevBar.Init(
symbol,
period,
index + i //
);
if (!result)
{
break;
}
//
// Next Bar ...
XOHCL iNextBar;
result = iNextBar.Init(
symbol,
period,
index - i //
);
if (!result)
{
break;
}
//
result = bar.high >= iPrevBar.high &&
bar.high >= iNextBar.high;
if (!result)
{
break;
}
}
//
return result;
}
/**
* Check Specified Bar is Swing Low or not ...
*
* @param bar: XOHCL instnce ...
* @param range: Integer, Specified Range ...
*
* @return ( bool )
*/
bool IsSwingLow(
XOHCL &bar,
int range = 2 //
)
{
//
bool result = false;
//
if (range < 1)
{
range = 1;
}
//
result = bar.IsValid();
if (!result)
{
return result;
}
//
int index = bar.Index();
result = range > 0 &&
index >= range;
if (!result)
{
return result;
}
//
string symbol = bar.symbol;
ENUM_TIMEFRAMES period = bar.period;
//
for (int i = 1; i <= range; i++)
{
//
// Prev Bar ...
XOHCL iPrevBar;
result = iPrevBar.Init(
symbol,
period,
index + i //
);
if (!result)
{
break;
}
//
// Next Bar ...
XOHCL iNextBar;
result = iNextBar.Init(
symbol,
period,
index - i //
);
if (!result)
{
break;
}
//
result = bar.low <= iPrevBar.low &&
bar.low <= iNextBar.low;
if (!result)
{
break;
}
}
//
return result;
}
/**
* Check a Bar is Momentum Bar or not ...
*
* @param bar: XOHCL instance ...
* @param dir: ENUM_X_DIRECTION member ...
* @param extend: Integer ...
* @param bodyPercent: Double ...
*
* @return ( bool )
*/
bool IsMomentumBar(
XOHCL &bar,
ENUM_X_DIRECTION &dir,
int extend = 1,
double bodyPercent = 70 //
)
{
//
bool result = false;
//
if (extend < 0)
{
extend = 0;
}
//
if (bodyPercent < 50)
{
bodyPercent = 50;
}
//
dir = X_DIRECTION_NONE;
//
result = bar.IsValid() &&
bar.Index() > 0;
if (!result)
{
return result;
}
//
if (extend > 0)
{
//
result = IsExtended(
bar,
extend //
);
//
if (!result)
{
return result;
}
}
//
double body = bar.GetBody();
double rp = GetBarRangePercent(bar);
//
result = body >= rp * bodyPercent;
//
if (result)
{
//
dir =
bar.IsBullish()
? X_DIRECTION_BULLISH
: X_DIRECTION_BEARISH;
}
//
return result;
}
/**
* Check a Bar is Rejection Bar or not ...
*
* @param bar: XOHCL instance ...
* @param dir: ENUM_X_DIRECTION member ...
* @param extend: Integer ...
* @param shadowPercent: Double ...
*
* @return ( bool )
*/
bool IsRejectionBar(
XOHCL &bar,
ENUM_X_DIRECTION &dir,
int extend = 1,
double shadowPercent = 60 //
)
{
//
bool result = false;
//
if (extend < 0)
{
extend = 0;
}
//
if (shadowPercent < 50)
{
shadowPercent = 50;
}
//
dir = X_DIRECTION_NONE;
//
result = bar.IsValid() &&
bar.Index() > 0;
if (!result)
{
return result;
}
//
if (extend > 0)
{
//
result = IsExtended(
bar,
extend //
);
//
if (!result)
{
return result;
}
}
//
double body = bar.GetBody();
double range = bar.GetRange();
double shadows = bar.GetShadows();
double lowShadow = bar.GetLowShadow();
double highShadow = bar.GetHighShadow();
double rp = GetBarRangePercent(bar);
//
result = shadows >= rp * shadowPercent;
//
if (result)
{
//
dir =
lowShadow > highShadow
? X_DIRECTION_BULLISH
: X_DIRECTION_BEARISH;
}
//
return result;
}
/**
* Check Specified Bar is Engulfing Bar or not ...
*
* @param bar: XOHCL instance ...
* @param dir: ENUM_X_DIRECTION member ...
* @param extend: Integer ...
* @param bodyPercent: Double ...
*
* @return ( bool )
*/
bool IsEngulfBar(
XOHCL &bar,
ENUM_X_DIRECTION &dir,
int extend = 1,
double bodyPercent = 60 //
)
{
//
bool result = false;
//
if (extend < 0)
{
extend = 0;
}
//
if (bodyPercent < 50)
{
bodyPercent = 50;
}
//
dir = X_DIRECTION_NONE;
//
result = bar.IsValid() &&
bar.Index() > 0;
if (!result)
{
return result;
}
//
// Previous Bar ...
XOHCL pBar;
result = bar.GetPreviousBar(pBar);
if (!result)
{
return result;
}
//
if (extend > 0)
{
//
result = IsExtended(
pBar,
extend //
);
//
if (!result)
{
return result;
}
}
//
// Check Engulfig ...
result =
bar.GetUp() > pBar.GetUp() &&
bar.GetDown() < pBar.GetDown();
if (!result)
{
return result;
}
//
// Check Engulfing Direction ...
bool isBullishEngulfed =
pBar.IsBearish() &&
bar.IsBullish();
bool isBearishEngulfed =
pBar.IsBullish() &&
bar.IsBearish();
//
result = isBullishEngulfed ||
isBearishEngulfed;
if (!result)
{
return result;
}
//
dir = isBullishEngulfed
? X_DIRECTION_BULLISH
: X_DIRECTION_BEARISH;
//
return result;
}
/**
* Check Specified Bar is Pin Bar or not ...
*
* @param bar: XOHCL instance ...
* @param dir: ENUM_X_DIRECTION member ...
* @param extend: Integer ...
* @param shadowPercent: Double ...
* @param bodyPercent: Double ...
*
* @return ( bool )
*/
bool IsPinBar(
XOHCL &bar,
ENUM_X_DIRECTION &dir,
int extend = 1,
double shadowPercent = 65,
double bodyPercent = 25 //
)
{
//
bool result = false;
//
dir = X_DIRECTION_NONE;
//
result = bar.IsValid() &&
bar.Index() > 0 &&
bodyPercent > 0 &&
shadowPercent > 0 &&
bodyPercent < shadowPercent;
if (!result)
{
return result;
}
//
// Chack Range Extends ...
if (extend > 0)
{
//
result = HasExtendedRange(
bar,
extend //
);
if (!result)
{
return result;
}
}
//
// Check Body ...
double rangePercent = GetBarRangePercent(bar);
//
double body = bar.GetBody();
double highShadow = bar.GetHighShadow();
double lowShadow = bar.GetLowShadow();
//
// Check Body ...
result = body / rangePercent >= bodyPercent;
if (!result)
{
return result;
}
//
bool isPassedHighShadow =
highShadow / rangePercent >= shadowPercent;
bool isPassedLowShadow =
lowShadow / rangePercent >= shadowPercent;
result =
isPassedLowShadow ||
isPassedHighShadow;
if (!result)
{
return result;
}
//
dir = isPassedLowShadow
? X_DIRECTION_BULLISH
: X_DIRECTION_BEARISH;
//
return result;
}
/**
* Decision Bar (Pin, Momentum or Rejection) ...
*
* @param bar: XOHCL instance ...
* @param dir: ENUM_X_DIRECTION member ...
* @param extend: Integer ...
* @param shadowForPinAndRejectionBarPercent: Double ...
* @param bodyForPinBarPercent: Double ...
* @param bodyForEngulfBarPercent: Double ...
* @param bodyForMomentumBarPercent: Double ...
*
* @return ( bool )
*/
bool IsDecisionBar(
XOHCL &bar,
ENUM_X_DIRECTION &dir,
int extend = 1,
double shadowForPinAndRejectionBarPercent = 65,
double bodyForPinBarPercent = 25,
double bodyForEngulfBarPercent = 65,
double bodyForMomentumBarPercent = 70 //
)
{
//
bool result = false;
//
dir = X_DIRECTION_NONE;
//
result = bar.IsValid() &&
bar.Index() > 0;
if (!result)
{
return result;
}
//
// Pin Bar ...
ENUM_X_DIRECTION pinDir;
bool isPiBar = IsPinBar(
bar,
pinDir,
extend,
shadowForPinAndRejectionBarPercent,
bodyForPinBarPercent //
);
//
// Engulfing Bar ...
ENUM_X_DIRECTION engulfDir;
bool isEngulfBar = IsEngulfBar(
bar,
engulfDir,
extend,
bodyForEngulfBarPercent //
);
//
// Momentum Bar ...
ENUM_X_DIRECTION momentumDir;
bool isMomentumBar = IsMomentumBar(
bar,
momentumDir,
extend,
bodyForMomentumBarPercent //
);
//
// Rejection Bar ...
ENUM_X_DIRECTION rejectionDir;
bool isRejectionBar = IsRejectionBar(
bar,
rejectionDir,
extend,
shadowForPinAndRejectionBarPercent //
);
//
result = isPiBar ||
isEngulfBar ||
isMomentumBar ||
isRejectionBar;
if (result)
{
//
if (isPiBar)
{
dir = pinDir;
}
else if (isEngulfBar)
{
dir = engulfDir;
}
else if (isMomentumBar)
{
dir = momentumDir;
}
else
{
dir = rejectionDir;
}
}
//
result = IsBullish(dir) ||
IsBearish(dir);
//
return result;
}
//
// Support and Resistance Zones ...
/**
* Check a Bar is Support Bar or not ...
*
* @param bar: XOHCL instance ...
* @param range: Integer, Specified Verifiation Range ...
*
* @return ( bool )
*/
bool IsSupport(
XOHCL &bar,
int range = 21 //
)
{
//
bool result = false;
//
if (range < 2)
{
range = 2;
}
//
result = bar.IsValid();
if (!result)
{
return result;
}
//
int index = bar.Index();
result = range > 0 &&
index >= range;
if (!result)
{
return result;
}
//
string symbol = bar.symbol;
ENUM_TIMEFRAMES period = bar.period;
//
for (int i = 1; i <= range; i++)
{
//
int prevIDX = index + i;
int nextIDX = index - 1;
//
// Prev Bar ...
XOHCL iPrevBar;
result = iPrevBar.Init(
symbol,
period,
prevIDX //
);
if (!result)
{
break;
}
//
// Next Bar ...
XOHCL iNextBar;
result = iNextBar.Init(
symbol,
period,
nextIDX //
);
if (!result)
{
break;
}
//
result = bar.low <= iPrevBar.low &&
bar.low <= iNextBar.low;
if (!result)
{
break;
}
}
//
return result;
}
/**
* Check a Bar is Resistance Bar or not ...
*
* @param bar: XOHCL instance ...
* @param range: Integer, Specified Verifiation Range ...
*
* @return ( bool )
*/
bool IsResistance(
XOHCL &bar,
int range = 21 //
)
{
//
bool result = false;
//
if (range < 2)
{
range = 2;
}
//
result = bar.IsValid();
if (!result)
{
return result;
}
//
int index = bar.Index();
result = range > 0 &&
index >= range;
if (!result)
{
return result;
}
//
string symbol = bar.symbol;
ENUM_TIMEFRAMES period = bar.period;
//
for (int i = 1; i <= range; i++)
{
//
int prevIDX = index + i;
int nextIDX = index - 1;
//
// Prev Bar ...
XOHCL iPrevBar;
result = iPrevBar.Init(
symbol,
period,
prevIDX //
);
if (!result)
{
break;
}
//
// Next Bar ...
XOHCL iNextBar;
result = iNextBar.Init(
symbol,
period,
nextIDX //
);
if (!result)
{
break;
}
//
result = bar.high >= iPrevBar.high &&
bar.high >= iNextBar.high;
if (!result)
{
break;
}
}
//
return result;
}
//
// Order Blocks ...
/**
* Detect an Order Block Based on Given Bar ...
*
* @param bar: XOHCL instance, Specified Start Bar ...
* @param ob: XOHCL instance, Fill it if Order Block Found ...
* @param dir: ENUM_X_DIRECTION member, Specified Founded Order Block Direction ...
* @param sameBars: Integer, Specified Min Same Bars for Detecting Order Block ...
*
* @return ( bool )
*/
bool HasOrderBlock(
XOHCL &bar,
XOHCL &ob,
ENUM_X_DIRECTION &dir,
int sameBars = 3 //
)
{
//
bool result = false;
//
ob.Clean();
dir = X_DIRECTION_NONE;
//
if (sameBars < 1)
{
sameBars = 1;
}
//
result = bar.IsValid();
if (!result)
{
return result;
}
//
int index = 0;
result = HasSameBars(
bar,
dir,
index,
sameBars //
);
if (!result)
{
return result;
}
//
int obIndex = index;
result = ob.Init(
bar.symbol,
bar.period,
obIndex //
);
if (!result)
{
return result;
}
//
return result;
}
//
// Fair Value Gaps ...
/**
* Detect a Fair Value Gap Based on Given Bar ...
*
* @param bar: XOHCL instance, Specified Start Bar ...
* @param dir: ENUM_X_DIRECTION member, Specified Founded Order Block Direction ...
* @param sameBars: Integer, Specified Min Same Bars for Detecting Order Block ...
*
* @return ( bool )
*/
bool HasFairValueGap(
XOHCL &bar,
XOHCL &prevBar,
XOHCL &nextBar,
ENUM_X_DIRECTION &dir,
int sameBars = 3 //
)
{
//
bool result = false;
//
prevBar.Clean();
nextBar.Clean();
dir = X_DIRECTION_NONE;
//
if (sameBars < 1)
{
sameBars = 1;
}
//
result = bar.IsValid();
if (!result)
{
return result;
}
//
int index = 0;
result = HasSameBars(
bar,
dir,
index,
sameBars //
);
if (!result)
{
return result;
}
//
bool isBullish = IsBullish(dir);
//
int to = bar.Index() + 1;
int from = index + 1;
for (int i = from; i > to; i--)
{
//
result = prevBar.Init(
bar.symbol,
bar.period,
i //
);
if (!result)
{
break;
}
//
result = nextBar.Init(
bar.symbol,
bar.period,
i - 2 //
);
if (!result)
{
break;
}
//
result = isBullish
? prevBar.high < nextBar.low
: prevBar.low > nextBar.high;
if (result)
{
break;
}
}
//
if (!result)
{
//
prevBar.Clean();
nextBar.Clean();
dir = X_DIRECTION_NONE;
}
//
return result;
}
//
// Bar CHOCH ...
/**
* Check Specified Bar Has PullBack or not ...
*
* @param dir: ENUM_X_DIRECTION member, Specified Direction ...
* @param bar: XOHCL instance, Speciied Bar ...
* @param loopback: Integer, loopback Length ...
* @param forceBody: Boolean, Specified Choch Happens only by Bar's Body ...
*
* @return ( bool )
*/
bool HasPullBack(
ENUM_X_DIRECTION &dir,
XOHCL &bar,
int loopback = 3,
bool forceBody = false //
)
{
//
bool result = false;
//
dir = X_DIRECTION_NONE;
//
if (loopback < 1)
{
loopback = 1;
}
//
result = bar.IsValid();
if (!result)
{
return result;
}
//
string symbol = bar.symbol;
ENUM_TIMEFRAMES period = bar.period;
//
// Calculate Loopback Data ...
int index = -1;
int start = -1;
int end = -1;
int count = -1;
result = CalculateLoopBackData(
index,
start,
end,
count,
bar,
loopback //
);
if (!result)
{
return result;
}
//
// Calculate Loopback HH and LL Data ...
int hhIDX = -1;
double hh = -1;
int llIDX = -1;
double ll = -1;
result = CalculateLoopbackHLData(
hhIDX,
hh,
llIDX,
ll,
bar,
loopback //
);
if (!result)
{
return result;
}
//
bool isBullishDirection =
bar.high > hh &&
bar.low > ll;
bool isBearishDirection =
bar.high < hh &&
bar.low < ll;
result = isBullishDirection ||
isBearishDirection;
if (!result)
{
return result;
}
//
if (forceBody)
{
//
isBullishDirection =
bar.GetUp() > hh &&
bar.GetDown() > ll;
isBearishDirection =
bar.GetUp() < hh &&
bar.GetDown() < ll;
result = isBullishDirection ||
isBearishDirection;
if (!result)
{
return result;
}
}
//
// Check Bar's Direction in related to CHOCH Direction ...
result =
isBullishDirection
? bar.IsBullish()
: bar.IsBearish();
if (!result)
{
return result;
}
//
// Set Direction ...
dir =
isBullishDirection
? X_DIRECTION_BULLISH
: X_DIRECTION_BEARISH;
//
// Check Loopback End Bar ...
XOHCL endBar;
result = endBar.Init(
symbol,
period,
end - 1 //
);
if (!result)
{
return result;
}
//
// End Bar Must be InDirect by Specified Bar ...
result =
isBullishDirection
? endBar.IsBearish()
: endBar.IsBullish();
//
// Check Loopback for Directional Bars ...
//
return result;
}
//
protected:
//
//
private:
//
//
// Props ...
//
// Actions ...
//
};
//