Files
MQL5Data/Documents/BKP/tmp.bar.anal.mq5
T

5210 lines
104 KiB
Plaintext

/**
* Detect Price Consolidation ...
*
* @param bar: XOHCL instance Reference, Start Bar ...
* @param loopback: Integer, Consolidation Length Finder ...
* @param consolidationRange: Integer, Consolidation Range Finder ...
* @param upper: Double Reference ...
* @param lower: Double Reference ...
* @param upperAppliedTo: ENUM_APPLIED_PRICE member, Upper Price ...
* @param lowerAppliedTo: ENUM_APPLIED_PRICE member, Lower Price ...
*
* @return ( bool )
*/
bool IsConsolidate(
XOHCL &bar,
double &upper,
double &lower,
int loopback = 30,
int consolidationRange = 50,
ENUM_APPLIED_PRICE upperAppliedTo = PRICE_HIGH,
ENUM_APPLIED_PRICE lowerAppliedTo = PRICE_LOW //
)
{
//
bool result = false;
//
upper = 0;
lower = 0;
//
if (loopback < 7)
{
loopback = 7;
}
//
result = bar.IsValid();
if (!result)
{
return result;
}
//
double points = GetPoints(bar.symbol);
int index = bar.Index();
//
double upperPrice[];
int upperPriceCount = FillPrice(
upperPrice,
upperAppliedTo,
bar.symbol,
bar.period,
index,
loopback //
);
//
double lowerPrice[];
int lowerPriceCount = FillPrice(
lowerPrice,
lowerAppliedTo,
bar.symbol,
bar.period,
index,
loopback //
);
//
result = upperPriceCount == lowerPriceCount &&
lowerPriceCount == loopback;
if (!result)
{
return result;
}
//
upper = upperPrice[ArrayMaximum(upperPrice)];
lower = lowerPrice[ArrayMinimum(lowerPrice)];
//
double range = upper - lower;
result = range <= consolidationRange * points;
//
return result;
}
bool HasConsolidationZone(
XOHCL &bar,
XConsolidationZone &zone,
int minLoopback = 3,
double range = 50,
ENUM_APPLIED_PRICE upperAppliedTo = PRICE_HIGH,
ENUM_APPLIED_PRICE lowerAppliedTo = PRICE_LOW //
)
{
//
bool result = false;
//
zone.Clean();
//
result = bar.IsValid() &&
minLoopback > 0 &&
range > 0;
if (!result)
{
return result;
}
//
double points = GetPoints(bar.symbol);
int index = bar.Index() + 1;
int length = minLoopback;
//
double upperPrice[];
int upperPriceCount = FillPrice(
upperPrice,
upperAppliedTo,
bar.symbol,
bar.period,
index,
length //
);
//
double lowerPrice[];
int lowerPriceCount = FillPrice(
lowerPrice,
lowerAppliedTo,
bar.symbol,
bar.period,
index,
length //
);
//
result = upperPriceCount == lowerPriceCount &&
lowerPriceCount == length;
if (!result)
{
//
Clean(upperPrice);
Clean(lowerPrice);
//
return result;
}
//
double upper = upperPrice[ArrayMaximum(upperPrice)];
double lower = lowerPrice[ArrayMinimum(lowerPrice)];
//
bool isBullishBreake =
bar.low > lower &&
bar.high > upper &&
bar.GetUp() > upper;
bool isBearishBreake =
bar.high < upper &&
bar.low < lower &&
bar.GetDown() < lower;
result = isBullishBreake ||
isBearishBreake;
if (!result)
{
//
Clean(upperPrice);
Clean(lowerPrice);
//
return result;
}
//
double delta = upper - lower;
result = delta <= range * points;
if (!result)
{
//
Clean(upperPrice);
Clean(lowerPrice);
//
return result;
}
//
while (delta <= range * points)
{
//
length++;
//
upperPriceCount = FillPrice(
upperPrice,
upperAppliedTo,
bar.symbol,
bar.period,
index,
length //
);
//
lowerPriceCount = FillPrice(
lowerPrice,
lowerAppliedTo,
bar.symbol,
bar.period,
index,
length //
);
//
bool isValid = upperPriceCount == lowerPriceCount &&
lowerPriceCount == length;
if (!isValid)
{
break;
}
//
double iUpper = upperPrice[ArrayMaximum(upperPrice)];
double iLower = lowerPrice[ArrayMinimum(lowerPrice)];
//
delta = iUpper - iLower;
if (delta <= range * points)
{
//
upper = iUpper;
lower = iLower;
}
}
//
Clean(upperPrice);
Clean(lowerPrice);
//
// Filling Zone ...
zone.upper = upper;
zone.lower = lower;
zone.symbol = bar.symbol;
zone.period = bar.period;
zone.to = iTime(
bar.symbol,
bar.period,
bar.Index() + 1 //
);
zone.from = iTime(
bar.symbol,
bar.period,
bar.Index() + length //
);
zone.dir = isBullishBreake
? X_DIRECTION_BULLISH
: X_DIRECTION_BEARISH;
//
result = zone.IsValid();
if (!result)
{
zone.Clean();
}
//
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 Specified Bar is Swing or not ...
*
* @param bar: XOHCL instnce ...
* @param dir: ENUM_X_DIRECTION member ...
* @param range: Integer, Specified Range ...
*
* @return ( bool )
*/
bool IsSwing(
XOHCL &bar,
ENUM_X_DIRECTION &dir,
int range = 2 //
)
{
//
bool result = false;
//
dir = X_DIRECTION_NONE;
//
bool isSwingLow = IsSwingLow(bar, range);
bool isSwingHigh = IsSwingHigh(bar, range);
//
result = isSwingLow ||
isSwingHigh;
if (result)
{
//
if (isSwingLow)
{
dir = X_DIRECTION_BULLISH;
}
else
{
dir = X_DIRECTION_BEARISH;
}
}
//
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);
result = rangePercent > 0;
if (!result)
{
return result;
}
//
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 Has Support or not ...
*
* @param bar: XOHCL instance ...
* @param supportBar: XOHCL instance Specified Support Bar ...
* @param rage: int,
* @return ( bool )
*/
bool HasSupport(
XOHCL &bar,
XOHCL &supportBar,
int range = 21 //
)
{
//
bool result = false;
//
result = bar.IsValid();
if (!result)
{
return result;
}
//
int barIndex = bar.Index() + range;
result = IsValidIndex(barIndex);
if (!result)
{
//
supportBar.Clean();
return result;
}
result = supportBar.Init(
bar.symbol,
bar.period,
barIndex //
);
//
result = supportBar.low < supportBar.GetDown();
if (!result)
{
//
supportBar.Clean();
return result;
}
//
double selectedValue = supportBar.GetDown();
//
int llIDX = bar.FindLowestIndex(range - 1, MODE_LOW);
result = IsValidIndex(llIDX);
if (!result)
{
//
supportBar.Clean();
return result;
}
//
double llValue = iLow(
bar.symbol,
bar.period,
llIDX //
);
//
result = llValue >= selectedValue;
if (!result)
{
//
supportBar.Clean();
return result;
}
//
result = supportBar.IsValid();
//
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;
}
/**
* Check a Bar Has Resistance or not ...
*
* @param bar: XOHCL instance ...
* @param resistanceBar: XOHCL instance Specified Resistance Bar ...
* @param rage: int,
* @return ( bool )
*/
bool HasResistance(
XOHCL &bar,
XOHCL &resistanceBar,
int range = 21 //
)
{
//
bool result = false;
//
result = bar.IsValid();
if (!result)
{
return result;
}
//
int barIndex = bar.Index() + range;
result = IsValidIndex(barIndex);
if (!result)
{
//
resistanceBar.Clean();
return result;
}
result = resistanceBar.Init(
bar.symbol,
bar.period,
barIndex //
);
//
result = resistanceBar.low < resistanceBar.GetDown();
if (!result)
{
//
resistanceBar.Clean();
return result;
}
//
double selectedValue = resistanceBar.GetUp();
//
int hhIDX = bar.FindHighestIndex(range - 1, MODE_HIGH);
result = IsValidIndex(hhIDX);
if (!result)
{
//
resistanceBar.Clean();
return result;
}
//
double hhValue = iHigh(
bar.symbol,
bar.period,
hhIDX //
);
//
result = hhValue >= selectedValue;
if (!result)
{
//
resistanceBar.Clean();
return result;
}
//
result = resistanceBar.IsValid();
//
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 + 1;
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();
int from =
index > (to + sameBars)
? to + sameBars
: index;
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;
}
//
// Tools ...
//
bool IsStrong(
XOHCL &bar,
double percent = 50 // Percent of Body
)
{
//
bool result = false;
//
result = bar.IsValid() &&
bar.Index() > 0;
if (!result)
{
return result;
}
//
result =
(bar.GetRange() * percent) / 100 <= bar.GetBody();
//
return result;
}
//
bool HasStrongLowShadow(
XOHCL &bar,
double percent = 50, // Percent of Body
int __loopback = 2,
double _sharpRatio = 2.5 //
)
{
//
bool result = false;
//
result = bar.IsValid() &&
bar.Index() > 0;
if (!result)
{
return result;
}
//
result =
(bar.GetRange() * percent) / 100 <= bar.GetLowShadow();
if (!result)
{
return result;
}
//
if (__loopback < 0)
{
__loopback = 2;
}
//
if (_sharpRatio < 0)
{
_sharpRatio = 2.5;
}
//
result = bar.Index() > __loopback;
if (!result)
{
return result;
}
//
// Get Highest High and Lowest Low in loopback Range ...
int startIndex = bar.Index() - __loopback;
int endIndex = bar.Index() + __loopback;
int requiredBars = MathAbs(endIndex - startIndex);
//
// Highs ...
double highs[];
int copiedHighs = CopyHigh(
bar.symbol,
bar.period,
startIndex,
requiredBars,
highs //
);
//
result = copiedHighs == requiredBars;
if (!result)
{
return result;
}
//
int highestHighIDX = ArrayMaximum(highs);
result = IsValidIndex(highestHighIDX);
if (!result)
{
return result;
}
//
double highestHigh = highs[highestHighIDX];
//
// Lows ...
double lows[];
int copiedLows = CopyLow(
bar.symbol,
bar.period,
startIndex,
requiredBars,
lows //
);
//
result = copiedLows == requiredBars;
if (!result)
{
return result;
}
//
int lowestLowIDX = ArrayMinimum(lows);
result = IsValidIndex(lowestLowIDX);
if (!result)
{
return result;
}
//
double lowestLow = lows[lowestLowIDX];
//
result = bar.low == lowestLow &&
highestHigh > bar.high;
if (!result)
{
return result;
}
//
// Try to Validate Sharp Ratio ...
//
Clean(highs);
Clean(lows);
//
// Left Side ...
startIndex = bar.Index() + 1;
endIndex = startIndex + (__loopback / 2) - 1;
requiredBars = MathAbs(endIndex - startIndex);
//
copiedHighs = CopyHigh(
bar.symbol,
bar.period,
startIndex,
requiredBars,
highs //
);
result = copiedHighs == requiredBars;
if (!result)
{
return result;
}
//
highestHighIDX = ArrayMaximum(highs);
result = IsValidIndex(highestHighIDX);
if (!result)
{
return result;
}
//
highestHigh = highs[highestHighIDX];
//
copiedLows = CopyLow(
bar.symbol,
bar.period,
startIndex,
requiredBars,
lows //
);
result = copiedLows == requiredBars;
if (!result)
{
return result;
}
//
lowestLowIDX = ArrayMinimum(lows);
result = IsValidIndex(lowestLowIDX);
if (!result)
{
return result;
}
//
lowestLow = lows[lowestLowIDX];
//
double leftDiff = highestHigh - lowestLow;
//
Clean(highs);
Clean(lows);
//
// Right Side ...
startIndex = bar.Index() - 1;
endIndex = startIndex - (__loopback / 2) + 1;
requiredBars = MathAbs(endIndex - startIndex);
//
copiedHighs = CopyHigh(
bar.symbol,
bar.period,
startIndex,
requiredBars,
highs //
);
result = copiedHighs == requiredBars;
if (!result)
{
return result;
}
//
highestHighIDX = ArrayMaximum(highs);
result = IsValidIndex(highestHighIDX);
if (!result)
{
return result;
}
//
highestHigh = highs[highestHighIDX];
//
copiedLows = CopyLow(
bar.symbol,
bar.period,
startIndex,
requiredBars,
lows //
);
result = copiedLows == requiredBars;
if (!result)
{
return result;
}
//
lowestLowIDX = ArrayMinimum(lows);
result = IsValidIndex(lowestLowIDX);
if (!result)
{
return result;
}
//
lowestLow = lows[lowestLowIDX];
//
double rightDiff = highestHigh - lowestLow;
double diff = MathMax(leftDiff, rightDiff);
result = bar.GetLowShadow() >= (diff / 100) * _sharpRatio;
//
return result;
}
//
bool HasStrongHighShadow(
XOHCL &bar,
double percent = 50, // Percent of Body
int __loopback = 2,
double _sharpRatio = 2.5 //
)
{
//
bool result = false;
//
result = bar.IsValid() && bar.Index() > 0;
if (!result)
{
return result;
}
//
result =
(bar.GetRange() * percent) / 100 <= bar.GetHighShadow();
if (!result)
{
return result;
}
//
if (__loopback < 0)
{
__loopback = 2;
}
//
if (_sharpRatio < 0)
{
_sharpRatio = 2.5;
}
//
result = bar.Index() > __loopback;
if (!result)
{
return result;
}
//
// Get Highest High and Lowest Low in loopback Range ...
int startIndex = bar.Index() - __loopback;
int endIndex = bar.Index() + __loopback;
int requiredBars = MathAbs(endIndex - startIndex);
//
// Highs ...
double highs[];
int copiedHighs = CopyHigh(
bar.symbol,
bar.period,
startIndex,
requiredBars,
highs //
);
//
result = copiedHighs == requiredBars;
if (!result)
{
return result;
}
//
int highestHighIDX = ArrayMaximum(highs);
result = IsValidIndex(highestHighIDX);
if (!result)
{
return result;
}
//
double highestHigh = highs[highestHighIDX];
//
// Lows ...
double lows[];
int copiedLows = CopyLow(
bar.symbol,
bar.period,
startIndex,
requiredBars,
lows //
);
//
result = copiedLows == requiredBars;
if (!result)
{
return result;
}
//
int lowestLowIDX = ArrayMinimum(lows);
result = IsValidIndex(lowestLowIDX);
if (!result)
{
return result;
}
//
double lowestLow = lows[lowestLowIDX];
//
result = bar.high == highestHigh &&
lowestLow < bar.low;
if (!result)
{
return result;
}
//
// Try to Validate Sharp Ratio ...
//
Clean(highs);
Clean(lows);
//
// Left Side ...
startIndex = bar.Index() + 1;
endIndex = startIndex + (__loopback / 2) - 1;
requiredBars = MathAbs(endIndex - startIndex);
//
copiedHighs = CopyHigh(
bar.symbol,
bar.period,
startIndex,
requiredBars,
highs //
);
result = copiedHighs == requiredBars;
if (!result)
{
return result;
}
//
highestHighIDX = ArrayMaximum(highs);
result = IsValidIndex(highestHighIDX);
if (!result)
{
return result;
}
//
highestHigh = highs[highestHighIDX];
//
copiedLows = CopyLow(
bar.symbol,
bar.period,
startIndex,
requiredBars,
lows //
);
result = copiedLows == requiredBars;
if (!result)
{
return result;
}
//
lowestLowIDX = ArrayMinimum(lows);
result = IsValidIndex(lowestLowIDX);
if (!result)
{
return result;
}
//
lowestLow = lows[lowestLowIDX];
//
double leftDiff = highestHigh - lowestLow;
//
Clean(highs);
Clean(lows);
//
// Right Side ...
startIndex = bar.Index() - 1;
endIndex = startIndex - (__loopback / 2) + 1;
requiredBars = MathAbs(endIndex - startIndex);
//
copiedHighs = CopyHigh(
bar.symbol,
bar.period,
startIndex,
requiredBars,
highs //
);
result = copiedHighs == requiredBars;
if (!result)
{
return result;
}
//
highestHighIDX = ArrayMaximum(highs);
result = IsValidIndex(highestHighIDX);
if (!result)
{
return result;
}
//
highestHigh = highs[highestHighIDX];
//
copiedLows = CopyLow(
bar.symbol,
bar.period,
startIndex,
requiredBars,
lows //
);
result = copiedLows == requiredBars;
if (!result)
{
return result;
}
//
lowestLowIDX = ArrayMinimum(lows);
result = IsValidIndex(lowestLowIDX);
if (!result)
{
return result;
}
//
lowestLow = lows[lowestLowIDX];
//
double rightDiff = highestHigh - lowestLow;
double diff = MathMax(leftDiff, rightDiff);
result = bar.GetHighShadow() >= (diff / 100) * _sharpRatio;
//
return result;
}
//
bool IsStrongBullish(
XOHCL &bar,
double percent = 50 // Percent of Body
)
{
//
bool result = false;
//
result =
bar.IsValid() &&
bar.IsBullish() &&
IsStrong(bar, percent);
//
return result;
}
//
bool IsStrongBearish(
XOHCL &bar,
double percent = 50 // Percent of Body
)
{
//
bool result = false;
//
result =
bar.IsValid() &&
bar.IsBearish() &&
IsStrong(bar, percent);
//
return result;
}
//
bool IsSharpBullish(
XOHCL &bar,
int __loopback = 2,
double _sharpRatio = 2.5 //
)
{
//
bool result = false;
//
result = bar.IsValid();
if (!result)
{
return result;
}
//
if (__loopback < 0)
{
__loopback = 2;
}
//
if (_sharpRatio < 0)
{
_sharpRatio = 2.5;
}
//
int hIDX = bar.FindHighestIndex(
__loopback,
MODE_HIGH //
);
int lIDX = bar.FindLowestIndex(
__loopback,
MODE_LOW //
);
//
result =
//
hIDX >= 0 &&
lIDX >= 0 &&
MathAbs(hIDX - bar.Index()) < 2
//
;
//
if (!result)
{
return result;
}
//
XOHCL hBar;
result = hBar.Init(
bar.symbol,
bar.period,
hIDX //
);
if (!result)
{
return result;
}
//
XOHCL lBar;
result = lBar.Init(
bar.symbol,
bar.period,
lIDX //
);
if (!result)
{
return result;
}
//
double lhDif = hBar.high - lBar.low;
//
int hhIDX = hBar.FindHighestIndex(
__loopback,
MODE_HIGH //
);
//
int llIDX = lBar.FindLowestIndex(
__loopback,
MODE_LOW //
);
//
XOHCL hhBar;
result = hhBar.Init(
bar.symbol,
bar.period,
hhIDX + hIDX //
);
if (!result)
{
return result;
}
//
XOHCL llBar;
result = llBar.Init(
bar.symbol,
bar.period,
llIDX + lIDX //
);
if (!result)
{
return result;
}
//
double llhhDif = hhBar.high - llBar.low;
//
result =
//
lBar.low > llBar.low &&
hBar.high > hhBar.high &&
lhDif >= llhhDif * _sharpRatio
//
;
//
return result;
}
//
bool IsSharpBearish(
XOHCL &bar,
int __loopback = 2,
double _sharpRatio = 2.5 //
)
{
//
bool result = false;
//
result = bar.IsValid();
if (!result)
{
return result;
}
//
if (__loopback < 0)
{
__loopback = 2;
}
//
if (_sharpRatio < 0)
{
_sharpRatio = 2.5;
}
//
int hIDX = bar.FindHighestIndex(
__loopback,
MODE_HIGH //
);
int lIDX = bar.FindLowestIndex(
__loopback,
MODE_LOW //
);
//
result =
//
hIDX >= 0 &&
lIDX >= 0 &&
MathAbs(hIDX - bar.Index()) < 2
//
;
//
if (!result)
{
return result;
}
//
XOHCL hBar;
result = hBar.Init(
bar.symbol,
bar.period,
hIDX //
);
if (!result)
{
return result;
}
//
XOHCL lBar;
result = lBar.Init(
bar.symbol,
bar.period,
lIDX //
);
if (!result)
{
return result;
}
//
double lhDif = hBar.high - lBar.low;
//
int hhIDX = hBar.FindHighestIndex(
__loopback,
MODE_HIGH //
);
//
int llIDX = lBar.FindLowestIndex(
__loopback,
MODE_LOW //
);
//
XOHCL hhBar;
result = hhBar.Init(
bar.symbol,
bar.period,
hhIDX + hIDX //
);
if (!result)
{
return result;
}
//
XOHCL llBar;
result = llBar.Init(
bar.symbol,
bar.period,
llIDX + lIDX //
);
if (!result)
{
return result;
}
//
double llhhDif = hhBar.high - llBar.low;
//
result =
//
lBar.low < llBar.low &&
hBar.high < hhBar.high &&
lhDif >= llhhDif * _sharpRatio
//
;
//
return result;
}
//
//
//
//
// Retrieve Bullish Pressure ...
double GetBullishPressure(
XOHCL &bar,
int __loopback = 7 //
)
{
//
double result = 0;
//
if (!bar.IsValid())
{
return result;
}
//
XOHCL bars[];
int barsCount = GetBars(
bars,
bar.symbol,
bar.period,
bar.Index(),
__loopback //
);
if (!IsValidSize(barsCount))
{
return result;
}
//
for (int i = 0; i < barsCount; i++)
{
result += bars[i].GetLowShadow();
}
//
return result;
}
//
// Retrieve Bearish Pressure ...
double GetBearishPressure(
XOHCL &bar,
int __loopback = 7 //
)
{
//
double result = 0;
//
if (!bar.IsValid())
{
return result;
}
//
XOHCL bars[];
int barsCount = GetBars(
bars,
bar.symbol,
bar.period,
bar.Index(),
__loopback //
);
if (!IsValidSize(barsCount))
{
return result;
}
//
for (int i = 0; i < barsCount; i++)
{
result += bars[i].GetHighShadow();
}
//
return result;
}
//
bool HasBullishPressure(
XOHCL &bar,
int __loopback = 7 //
)
{
//
bool result = false;
//
if (__loopback < 0)
{
__loopback = 7;
}
//
result = bar.IsValid();
if (!result)
{
return result;
}
//
double bullishPressure = GetBullishPressure(bar, __loopback);
double bearishPressure = GetBearishPressure(bar, __loopback);
//
result =
//
bullishPressure > 0 &&
bearishPressure >= 0 &&
bullishPressure > bearishPressure
//
;
//
return result;
}
//
bool HasBearishPressure(
XOHCL &bar,
int __loopback = 7 //
)
{
//
bool result = false;
//
if (__loopback < 0)
{
__loopback = 7;
}
//
result = bar.IsValid();
if (!result)
{
return result;
}
//
double bullishPressure = GetBullishPressure(bar, __loopback);
double bearishPressure = GetBearishPressure(bar, __loopback);
//
result =
//
bearishPressure > 0 &&
bullishPressure >= 0 &&
bearishPressure > bullishPressure
//
;
//
return result;
}
//
// Retrieve Bullish Power ...
double GetBullishPower(
XOHCL &bar,
int __loopback = 7 //
)
{
//
double result = 0;
//
if (!bar.IsValid())
{
return result;
}
//
XOHCL bars[];
int barsCount = GetBars(
bars,
bar.symbol,
bar.period,
bar.Index(),
__loopback //
);
if (!IsValidSize(barsCount))
{
return result;
}
//
for (int i = 0; i < barsCount; i++)
{
//
if (bars[i].IsBullish())
{
result += bars[i].GetBody();
}
}
//
return result;
}
//
// Retrieve Bearish Pressure ...
double GetBearishPower(
XOHCL &bar,
int __loopback = 7 //
)
{
//
double result = 0;
//
if (!bar.IsValid())
{
return result;
}
//
XOHCL bars[];
int barsCount = GetBars(
bars,
bar.symbol,
bar.period,
bar.Index(),
__loopback //
);
if (!IsValidSize(barsCount))
{
return result;
}
//
for (int i = 0; i < barsCount; i++)
{
//
if (bars[i].IsBearish())
{
result += bars[i].GetBody();
}
}
//
return result;
}
//
bool HasBullishPower(
XOHCL &bar,
int __loopback = 7 //
)
{
//
bool result = false;
//
if (__loopback < 0)
{
__loopback = 7;
}
//
result = bar.IsValid();
if (!result)
{
return result;
}
//
double bullishPressure = GetBullishPower(bar, __loopback);
double bearishPressure = GetBearishPower(bar, __loopback);
//
result =
//
bullishPressure > 0 &&
bearishPressure >= 0 &&
bullishPressure > bearishPressure
//
;
//
return result;
}
//
bool HasBearishPower(
XOHCL &bar,
int __loopback = 7 //
)
{
//
bool result = false;
//
if (__loopback < 0)
{
__loopback = 7;
}
//
result = bar.IsValid();
if (!result)
{
return result;
}
//
double bullishPressure = GetBullishPower(bar, __loopback);
double bearishPressure = GetBearishPower(bar, __loopback);
//
result =
//
bearishPressure > 0 &&
bullishPressure >= 0 &&
bearishPressure > bullishPressure
//
;
//
return result;
}
//
// Decisions ...
//
// Candlestic Patterns ...
//
// Check Doji ...
bool IsDoji(
XOHCL &bar //
)
{
//
bool result = false;
//
// Validate Content and Ignore 0 Bar
// since it is not Completed ...
result = bar.IsValid() && bar.Index() > 0;
if (!result)
{
return result;
}
//
result = bar.open == bar.close;
//
return result;
}
//
// Check Hammer ...
bool IsHammer(
XOHCL &bar,
double _upShadowFactor = 0.1,
double _downShadowFactor = 0.6,
bool applyFib382Check = true,
bool applyPrevShadowCheck = true //
)
{
//
bool result = false;
//
// Validate Content and Ignore 0 Bar
// since it is not Completed ...
result = bar.IsValid() && bar.Index() > 0;
if (!result)
{
return result;
}
//
if (_upShadowFactor < 0)
{
_upShadowFactor = 0.1;
}
//
if (_downShadowFactor < 0)
{
_upShadowFactor = 0.6;
}
//
double range = bar.GetRange();
//
// Check Upper Shadow Must be 0 or Under 10% ...
double upShadow = bar.GetHighShadow();
result = upShadow < range * _upShadowFactor;
if (!result)
{
return result;
}
//
// Check Down Shadow Must at least 60% ...
double downShadow = bar.GetLowShadow();
result = downShadow > range * _downShadowFactor;
if (!result)
{
return result;
}
//
// Check Fib 382 ...
if (result && applyFib382Check)
{
//
double fib382 = GetFibonacciLevel(
bar.high,
bar.low,
0.382,
-1 //
);
result = bar.GetDown() > fib382;
}
//
// Check Shadow Based on Prev Bar ...
if (result && applyPrevShadowCheck)
{
//
XOHCL pBar;
result = bar.GetPreviousBar(pBar);
if (!result)
{
return result;
}
//
result = bar.low < pBar.low;
}
//
return result;
}
//
// Check Sgooting Star ...
// Reversal Hammer ...
bool IsShootingStar(
XOHCL &bar,
double _upShadowFactor = 0.6,
double _downShadowFactor = 0.1,
bool applyFib382Check = true,
bool applyPrevShadowCheck = true //
)
{
//
bool result = false;
//
// Validate Content and Ignore 0 Bar
// since it is not Completed ...
result = bar.IsValid() && bar.Index() > 0;
if (!result)
{
return result;
}
//
if (_upShadowFactor < 0)
{
_upShadowFactor = 0.6;
}
//
if (_downShadowFactor < 0)
{
_upShadowFactor = 0.1;
}
//
double range = bar.GetRange();
//
// Check Upper Shadow Must be 0 or Under 10% ...
double upShadow = bar.GetHighShadow();
result = upShadow > range * _upShadowFactor;
if (!result)
{
return result;
}
//
// Check Down Shadow Must at least 60% ...
double downShadow = bar.GetLowShadow();
result = downShadow < range * _downShadowFactor;
if (!result)
{
return result;
}
//
// Check Fib 382 ...
if (result && applyFib382Check)
{
//
double fib382 = GetFibonacciLevel(
bar.high,
bar.low,
0.382,
1 //
);
result = bar.GetUp() < fib382;
}
//
// Check Shadow Based on Prev Bar ...
if (result && applyPrevShadowCheck)
{
//
XOHCL pBar;
result = bar.GetPreviousBar(pBar);
if (!result)
{
return result;
}
//
result = bar.high > pBar.high;
}
//
return result;
}
//
// Check Bullish Engulfing ...
bool IsBullishEngulfing(
XOHCL &bar,
double _engulfBarBodyFactor = 0.7 //
)
{
//
bool result = false;
//
// Validate Content and Ignore 0 Bar
// since it is not Completed ...
result = bar.IsValid() && bar.Index() > 0;
if (!result)
{
return result;
}
//
if (_engulfBarBodyFactor < 0)
{
_engulfBarBodyFactor = 0.7;
}
//
// Check Bar Is Bullish ...
result = bar.IsBullish();
if (!result)
{
return result;
}
//
// Retrieve Previous Bar ...
XOHCL pBar;
result = bar.GetPreviousBar(pBar);
if (!result)
{
return result;
}
//
double range = bar.GetRange();
double body = bar.GetBody();
//
// Check Prev Bar Must Bearish ...
result = pBar.IsBearish();
if (!result)
{
return result;
}
//
// Check Shadows Engulf Prev Bar ...
result =
//
bar.high > pBar.high &&
bar.low <= pBar.low
//
;
if (!result)
{
return result;
}
//
// Check Engulfed Bar Must Inside Engulfer Body ...
result =
//
bar.GetUp() > pBar.GetUp() &&
bar.GetDown() < pBar.GetDown()
//
;
if (!result)
{
return result;
}
//
// Check Body of Engulfing Bar ...
if (result && _engulfBarBodyFactor > 0)
{
result = body >= range * _engulfBarBodyFactor;
}
//
return result;
}
//
// Check Bearish Engulfing ...
bool IsBearishEngulfing(
XOHCL &bar,
double _engulfBarBodyFactor = 0.7 //
)
{
//
bool result = false;
//
// Validate Content and Ignore 0 Bar
// since it is not Completed ...
result = bar.IsValid() && bar.Index() > 0;
if (!result)
{
return result;
}
//
if (_engulfBarBodyFactor < 0)
{
_engulfBarBodyFactor = 0.7;
}
//
// Check Bar Is Bearish ...
result = bar.IsBearish();
if (!result)
{
return result;
}
//
// Retrieve Previous Bar ...
XOHCL pBar;
result = bar.GetPreviousBar(pBar);
if (!result)
{
return result;
}
//
double range = bar.GetRange();
double body = bar.GetBody();
//
// Check Prev Bar Must Bullish ...
result = pBar.IsBullish();
if (!result)
{
return result;
}
//
// Check Shadows Engulf Prev Bar ...
result = bar.high >= pBar.high &&
bar.low < pBar.low;
if (!result)
{
return result;
}
//
// Check Engulfed Bar Must Inside Engulfer Body ...
result =
//
bar.GetUp() > pBar.GetUp() &&
bar.GetDown() < pBar.GetDown()
//
;
if (!result)
{
return result;
}
//
// Check Body of Engulfing Bar ...
if (result && _engulfBarBodyFactor > 0)
{
result = body >= range * _engulfBarBodyFactor;
}
//
return result;
}
//
// Check Morning Star Pattern ...
bool IsMorningStar(
XOHCL &bar,
double _middleRangeFactor = 0.3,
double _startBodyFactor = 0.6,
bool forceCheckMiddleBarDirection = true,
bool forceCheckStartBody = true //
)
{
//
bool result = false;
//
// Validate Content and Ignore 0 Bar
// since it is not Completed ...
result = bar.IsValid() && bar.Index() > 0;
if (!result)
{
return result;
}
//
if (_middleRangeFactor < 0)
{
_middleRangeFactor = 0.3;
}
//
if (_startBodyFactor < 0)
{
_startBodyFactor = 0.6;
}
//
// Current Bar Must be Bullish ...
result = bar.IsBullish();
if (!result)
{
return result;
}
//
// Retrieve Previous Bar ...
XOHCL pBar;
result = bar.GetPreviousBar(pBar);
if (!result)
{
return result;
}
//
// Prev Bar must be Bearish ...
if (result && forceCheckMiddleBarDirection)
{
//
result = pBar.IsBearish();
if (!result)
{
return result;
}
}
//
// Retrieve Previous Bar of Prev Bar ...
XOHCL ppBar;
result = pBar.GetPreviousBar(ppBar);
if (!result)
{
return result;
}
//
// Prev Of Prev Bar Must be Bearish ...
result = ppBar.IsBearish();
if (!result)
{
return result;
}
//
double range = bar.GetRange();
double pRange = pBar.GetRange();
double ppRange = ppBar.GetRange();
//
// Middle Bar must be Smaller than Ratio of other ...
result =
//
pRange < range * _middleRangeFactor &&
pRange < ppRange * _middleRangeFactor
//
;
if (!result)
{
return result;
}
//
if (result && forceCheckStartBody)
{
//
result = ppBar.GetBody() > ppRange * _startBodyFactor;
if (!result)
{
return result;
}
}
//
return result;
}
//
// Check Evening Star Pattern ...
bool IsEveningStar(
XOHCL &bar,
double _middleRangeFactor = 0.3,
double _startBodyFactor = 0.6,
bool forceCheckMiddleBarDirection = true,
bool forceCheckStartBody = true //
)
{
//
bool result = false;
//
// Validate Content and Ignore 0 Bar
// since it is not Completed ...
result = bar.IsValid() && bar.Index() > 0;
if (!result)
{
return result;
}
//
if (_middleRangeFactor < 0)
{
_middleRangeFactor = 0.3;
}
//
if (_startBodyFactor < 0)
{
_startBodyFactor = 0.6;
}
//
// Current Bar Must be Bearish ...
result = bar.IsBearish();
if (!result)
{
return result;
}
//
// Retrieve Previous Bar ...
XOHCL pBar;
result = bar.GetPreviousBar(pBar);
if (!result)
{
return result;
}
//
// Prev Bar must be Bullish ...
if (result && forceCheckMiddleBarDirection)
{
//
result = pBar.IsBullish();
if (!result)
{
return result;
}
}
//
// Retrieve Previous Bar of Prev Bar ...
XOHCL ppBar;
result = pBar.GetPreviousBar(ppBar);
if (!result)
{
return result;
}
//
// Prev Of Prev Bar Must be Bullish ...
result = ppBar.IsBullish();
if (!result)
{
return result;
}
//
double range = bar.GetRange();
double pRange = pBar.GetRange();
double ppRange = ppBar.GetRange();
//
// Middle Bar must be Smaller than Ratio of other ...
result =
//
pRange < range * _middleRangeFactor &&
pRange < ppRange * _middleRangeFactor
//
;
if (!result)
{
return result;
}
//
if (result && forceCheckStartBody)
{
//
result = ppBar.GetBody() > ppRange * _startBodyFactor;
if (!result)
{
return result;
}
}
//
return result;
}
//
// Bullish Marubozu ...
bool IsBullishMarubozu(XOHCL &bar)
{
//
bool result = false;
//
result = bar.IsValid() && bar.Index() > 0;
if (!result)
{
return result;
}
//
result = bar.IsBullish();
if (!result)
{
return result;
}
//
result =
//
bar.GetUp() == bar.high &&
bar.GetDown() == bar.low
//
;
//
return result;
}
//
// Bearish Marubozu ...
bool IsBearishMarubozu(XOHCL &bar)
{
//
bool result = false;
//
result = bar.IsValid() && bar.Index() > 0;
if (!result)
{
return result;
}
//
result = bar.IsBearish();
if (!result)
{
return result;
}
//
result =
//
bar.GetUp() == bar.high &&
bar.GetDown() == bar.low
//
;
//
return result;
}
//
// Contextual Patterns ...
//
// Check Swing High ...
bool IsBarSwingHigh(XOHCL &bar)
{
//
bool result = false;
//
// Validate Content and Ignore 0 Bar
// since it is not Completed ...
result = bar.IsValid() && bar.Index() > 0;
if (!result)
{
return result;
}
//
// Current Bar Must be Bearish ...
result = bar.IsBearish();
if (!result)
{
return result;
}
//
// Retrieve Prev Bar ...
XOHCL pBar;
result = bar.GetPreviousBar(pBar);
if (!result)
{
return result;
}
//
// Prev Bar Must be Bullish ...
result = pBar.IsBullish();
if (!result)
{
return result;
}
//
// Retrieve Prev of Prev Bar ...
XOHCL ppBar;
result = pBar.GetPreviousBar(ppBar);
if (!result)
{
return result;
}
//
// Prev of Prev Bar Must be Bullish ...
result = ppBar.IsBullish();
if (!result)
{
return result;
}
//
// Check All Highs ...
result =
//
bar.high < pBar.high &&
pBar.high > ppBar.high
//
;
//
return result;
}
//
// Find Simple 3 Candle Based Swing High ...
bool IsSimpleSwingHigh(
XOHCL &bar,
double thresholdInPoint = 1 //
)
{
//
bool result = false;
//
int index = bar.Index();
result = index > 0;
if (!result)
{
return result;
}
//
XOHCL nextBar;
result = bar.GetNextBar(nextBar);
if (!result)
{
return result;
}
//
XOHCL prevBar;
result = bar.GetPreviousBar(prevBar);
if (!result)
{
return result;
}
//
double point = GetPoints(bar.symbol);
double requiredOffset = point * thresholdInPoint;
//
result =
bar.high > nextBar.high &&
bar.high > prevBar.high &&
(thresholdInPoint <= 0
? true
: MathAbs(
MathMax(
nextBar.high,
prevBar.high) -
bar.high) >= requiredOffset);
//
return result;
}
//
// Find Last Swing High ...
bool FindLastSwingHigh(
XOHCL &bar,
XOHCL &swing //
)
{
//
bool result = false;
//
swing.Clean();
//
result = bar.IsValid();
if (!result)
{
return result;
}
//
int totalBars = iBars(
bar.symbol,
bar.period //
);
int maxAllowed = MathMin(100, (totalBars / 100));
//
int idx = bar.Index();
for (int i = idx; i <= idx + maxAllowed; i++)
{
//
swing.Clean();
result = swing.Init(
bar.symbol,
bar.period,
i //
);
if (!result)
{
//
swing.Clean();
break;
}
//
result = IsBarSwingHigh(swing);
if (result)
{
break;
}
}
//
return result;
}
//
// Check Swing Low ...
bool IsBarSwingLow(XOHCL &bar)
{
//
bool result = false;
//
// Validate Content and Ignore 0 Bar
// since it is not Completed ...
result = bar.IsValid() && bar.Index() > 0;
if (!result)
{
return result;
}
//
// Current Bar Must be Bullish ...
result = bar.IsBullish();
if (!result)
{
return result;
}
//
// Retrieve Prev Bar ...
XOHCL pBar;
result = bar.GetPreviousBar(pBar);
if (!result)
{
return result;
}
//
// Prev Bar Must be Bearish ...
result = pBar.IsBearish();
if (!result)
{
return result;
}
//
// Retrieve Prev of Prev Bar ...
XOHCL ppBar;
result = pBar.GetPreviousBar(ppBar);
if (!result)
{
return result;
}
//
// Prev of Prev Bar Must be Bearish ...
result = ppBar.IsBearish();
if (!result)
{
return result;
}
//
// Check All Lows ...
result =
//
bar.low > pBar.low &&
pBar.low < ppBar.low
//
;
//
return result;
}
//
// Find Simple 3 Candle Based Swing Low ...
bool IsSimpleSwingLow(
XOHCL &bar,
double thresholdInPoint = 1 //
)
{
//
bool result = false;
//
int index = bar.Index();
result = index > 0;
if (!result)
{
return result;
}
//
XOHCL nextBar;
result = bar.GetNextBar(nextBar);
if (!result)
{
return result;
}
//
XOHCL prevBar;
result = bar.GetPreviousBar(prevBar);
if (!result)
{
return result;
}
//
double point = GetPoints(bar.symbol);
double requiredOffset = point * thresholdInPoint;
//
result =
bar.low < nextBar.low &&
bar.low < prevBar.low &&
(thresholdInPoint <= 0
? true
: MathAbs(
MathMax(
nextBar.low,
prevBar.low) -
bar.low) >= requiredOffset);
//
return result;
}
//
// Find Last Swing Low ...
bool FindLastSwingLow(
XOHCL &bar,
XOHCL &swing //
)
{
//
bool result = false;
//
swing.Clean();
//
result = bar.IsValid();
if (!result)
{
return result;
}
//
int totalBars = iBars(
bar.symbol,
bar.period //
);
int maxAllowed = MathMin(100, (totalBars / 100));
//
int idx = bar.Index();
for (int i = idx; i <= idx + maxAllowed; i++)
{
//
swing.Clean();
result = swing.Init(
bar.symbol,
bar.period,
i //
);
if (!result)
{
//
swing.Clean();
break;
}
//
result = IsBarSwingLow(swing);
if (result)
{
break;
}
}
//
return result;
}
//
// Check Bullish FVG ...
bool HasBullishFVG(
XOHCL &bar,
double &upper,
double &lower,
datetime &start,
datetime &end,
bool forceMiddleBarCheck = true,
bool forceCheckLastBarDirection = false //
)
{
//
bool result = false;
//
upper = 0;
lower = 0;
//
end = NULL;
start = NULL;
//
// Validate Content and Ignore 0 Bar
// since it is not Completed ...
result = bar.IsValid() && bar.Index() > 0;
if (!result)
{
return result;
}
//
// Current Bar Must be Bullish ...
result =
!forceCheckLastBarDirection
? true
: bar.IsBullish();
if (!result)
{
return result;
}
//
// Retrieve Prev Bar ...
XOHCL pBar;
result = bar.GetPreviousBar(pBar);
if (!result)
{
return result;
}
//
// Prev Bar Must be Bullish ...
result = pBar.IsBullish();
if (!result)
{
return result;
}
//
// Retrieve Prev of Prev Bar ...
XOHCL ppBar;
result = pBar.GetPreviousBar(ppBar);
if (!result)
{
return result;
}
//
// Prev of Prev Bar Must be Bullish ...
result = ppBar.IsBullish();
if (!result)
{
return result;
}
//
// Other Conditions ...
result =
//
bar.low > ppBar.high
//
;
//
// Check Middle Bar Range ...
if (result && forceMiddleBarCheck)
{
//
result =
//
pBar.high > bar.low &&
pBar.low < ppBar.high
//
;
//
if (!result)
{
return result;
}
}
//
if (result)
{
//
end = bar.time;
upper = bar.low;
lower = ppBar.high;
start = ppBar.time;
}
//
return result;
}
//
// Check Bearish FVG ...
bool HasBearishFVG(
XOHCL &bar,
double &upper,
double &lower,
datetime &start,
datetime &end,
bool forceMiddleBarCheck = true,
bool forceCheckLastBarDirection = false //
)
{
//
bool result = false;
//
upper = 0;
lower = 0;
//
end = NULL;
start = NULL;
//
// Validate Content and Ignore 0 Bar
// since it is not Completed ...
result = bar.IsValid() && bar.Index() > 0;
if (!result)
{
return result;
}
//
// Current Bar Must be Bearish ...
result =
!forceCheckLastBarDirection
? true
: bar.IsBullish();
if (!result)
{
return result;
}
//
// Retrieve Prev Bar ...
XOHCL pBar;
result = bar.GetPreviousBar(pBar);
if (!result)
{
return result;
}
//
// Prev Bar Must be Bearish ...
result = pBar.IsBearish();
if (!result)
{
return result;
}
//
// Retrieve Prev of Prev Bar ...
XOHCL ppBar;
result = pBar.GetPreviousBar(ppBar);
if (!result)
{
return result;
}
//
// Prev of Prev Bar Must be Bearish ...
result = ppBar.IsBearish();
if (!result)
{
return result;
}
//
// Other Conditions ...
result =
//
bar.high < ppBar.low
//
;
//
// Check Middle Bar Range ...
if (result && forceMiddleBarCheck)
{
//
result =
//
pBar.high > bar.low &&
pBar.low < ppBar.high
//
;
//
if (!result)
{
return result;
}
}
//
if (result)
{
//
end = bar.time;
lower = bar.high;
upper = ppBar.low;
start = ppBar.time;
}
//
return result;
}
//
// Find Support ...
bool HasSupport(
XOHCL &bar,
XOHCL &dest,
ENUM_X_PRICE type = X_PRICE_CLOSE,
int _loopback = 21,
int tries = 100 //
)
{
//
bool result = false;
//
dest.Clean();
//
if (_loopback < 0)
{
_loopback = 21;
}
//
if (tries < 0)
{
tries = 100;
}
//
result = bar.IsValid();
if (!result)
{
return result;
}
//
double price = bar.GetPrice(type);
//
for (int i = 1; i < tries; i++)
{
//
int _length = _loopback * i;
//
int lowestIDX = bar.FindLowestIndex(
_length,
MODE_LOW //
);
result = IsValidIndex(lowestIDX);
if (!result)
{
break;
}
//
XOHCL iLBar;
result = iLBar.Init(
bar.symbol,
bar.period,
lowestIDX //
);
if (!result)
{
break;
}
//
result =
//
price > iLBar.high
//
;
if (result)
{
//
dest = iLBar;
break;
}
}
//
result = dest.IsValid();
//
return result;
}
//
// Find Resistance ...
bool HasResistance(
XOHCL &bar,
XOHCL &dest,
ENUM_X_PRICE type = X_PRICE_CLOSE,
int _loopback = 21,
int tries = 100 //
)
{
//
bool result = false;
//
dest.Clean();
//
if (_loopback < 0)
{
_loopback = 21;
}
//
if (tries < 0)
{
tries = 100;
}
//
result = bar.IsValid();
if (!result)
{
return result;
}
//
double price = bar.GetPrice(type);
//
for (int i = 1; i < tries; i++)
{
//
int _length = _loopback * i;
//
int highestIDX = bar.FindHighestIndex(
_length,
MODE_LOW //
);
result = IsValidIndex(highestIDX);
if (!result)
{
break;
}
//
XOHCL iHBar;
result = iHBar.Init(
bar.symbol,
bar.period,
highestIDX //
);
if (!result)
{
break;
}
//
result =
//
price < iHBar.high
//
;
if (result)
{
//
dest = iHBar;
break;
}
}
//
result = dest.IsValid();
//
return result;
}
//
// Trend Detection ...
//
// Find Bullish Trend ...
bool HasBullishTrend(
XOHCL &bar,
XOHCL &highSwingBars[],
XOHCL &lowSwingBars[],
bool forceMethod2 = false,
int _loopback = 3,
int tries = 3,
ENUM_X_PRICE type = X_PRICE_CLOSE //
)
{
//
bool result = false;
//
Clean(lowSwingBars);
Clean(highSwingBars);
//
result = bar.IsValid();
if (!result)
{
return result;
}
//
double price = bar.GetPrice(type);
//
int lastIDX = bar.Index();
double lastH = 0;
double lastL = 0;
for (int i = 1; i < tries + 1; i++)
{
//
// Use Regular Method ...
if (!forceMethod2)
{
//
int iHIDX = FindSwing(
bar.symbol,
bar.period,
X_SWING_HIGH,
_loopback,
lastIDX //
);
result = IsValidIndex(iHIDX);
if (!result)
{
break;
}
//
XOHCL iHBar;
result = iHBar.Init(
bar.symbol,
bar.period,
iHIDX //
);
if (!result)
{
break;
}
//
double iH = iHBar.high;
bool isIHAccepted =
//
iH > 0 &&
(
//
lastH == 0
? true
: iH < lastH
//
)
//
;
if (isIHAccepted)
{
//
AddRef(
iHBar,
highSwingBars //
);
//
lastH = iH;
lastIDX = iHIDX;
}
//
int iLIDX = FindSwing(
bar.symbol,
bar.period,
X_SWING_LOW,
_loopback,
lastIDX //
);
result = IsValidIndex(iLIDX);
if (!result)
{
break;
}
//
XOHCL iLBar;
result = iLBar.Init(
bar.symbol,
bar.period,
iLIDX //
);
if (!result)
{
break;
}
//
double iL = iLBar.low;
bool isILAccepted =
//
iL > 0 &&
(
//
lastL == 0
? true
: iL < lastL
//
)
//
;
if (isILAccepted)
{
//
AddRef(
iLBar,
lowSwingBars //
);
//
lastL = iL;
lastIDX = iLIDX;
}
}
//
// Use Other MEthod ...
else
{
//
int _length = i * _loopback;
int start =
//
i == 1
? 1
: _length - _loopback
//
;
//
int iHIDX = iHighest(
bar.symbol,
bar.period,
MODE_HIGH,
_loopback,
start //
);
result = IsValidIndex(iHIDX);
if (!result)
{
break;
}
//
XOHCL iHBar;
result = iHBar.Init(
bar.symbol,
bar.period,
iHIDX //
);
if (!result)
{
break;
}
//
double iH = iHBar.high;
bool isIHAccepted =
//
iH > 0 &&
(
//
lastH == 0
? true
: iH < lastH
//
)
//
;
if (isIHAccepted)
{
//
AddRef(
iHBar,
highSwingBars //
);
//
lastH = iH;
lastIDX = iHIDX;
}
//
int iLIDX = iLowest(
bar.symbol,
bar.period,
MODE_LOW,
_loopback,
start //
);
result = IsValidIndex(iLIDX);
if (!result)
{
break;
}
//
XOHCL iLBar;
result = iLBar.Init(
bar.symbol,
bar.period,
iLIDX //
);
if (!result)
{
break;
}
//
double iL = iLBar.low;
bool isILAccepted =
//
iL > 0 &&
(
//
lastL == 0
? true
: iL < lastL
//
)
//
;
if (isILAccepted)
{
//
AddRef(
iLBar,
lowSwingBars //
);
//
lastL = iL;
lastIDX = iLIDX;
}
}
}
//
if (result)
{
//
result =
//
ArraySize(lowSwingBars) == tries &&
ArraySize(highSwingBars) == tries
//
;
}
//
if (!result)
{
//
Clean(lowSwingBars);
Clean(highSwingBars);
}
//
return result;
}
//
// Find Bearish Trend ...
bool HasBearishTrend(
XOHCL &bar,
XOHCL &highSwingBars[],
XOHCL &lowSwingBars[],
bool forceMethod2 = false,
int _loopback = 3,
int tries = 3,
ENUM_X_PRICE type = X_PRICE_CLOSE //
)
{
//
bool result = false;
//
Clean(lowSwingBars);
Clean(highSwingBars);
//
result = bar.IsValid();
if (!result)
{
return result;
}
//
double price = bar.GetPrice(type);
//
int lastIDX = bar.Index();
double lastH = 0;
double lastL = 0;
for (int i = 1; i < tries + 1; i++)
{
//
// Use Regular Method ...
if (!forceMethod2)
{
//
int iHIDX = FindSwing(
bar.symbol,
bar.period,
X_SWING_HIGH,
_loopback,
lastIDX //
);
result = IsValidIndex(iHIDX);
if (!result)
{
break;
}
//
XOHCL iHBar;
result = iHBar.Init(
bar.symbol,
bar.period,
iHIDX //
);
if (!result)
{
break;
}
//
double iH = iHBar.high;
bool isIHAccepted =
//
iH > 0 &&
(
//
lastH == 0
? true
: iH > lastH
//
)
//
;
if (isIHAccepted)
{
//
AddRef(
iHBar,
highSwingBars //
);
//
lastH = iH;
lastIDX = iHIDX;
}
//
int iLIDX = FindSwing(
bar.symbol,
bar.period,
X_SWING_LOW,
_loopback,
lastIDX //
);
result = IsValidIndex(iLIDX);
if (!result)
{
break;
}
//
XOHCL iLBar;
result = iLBar.Init(
bar.symbol,
bar.period,
iLIDX //
);
if (!result)
{
break;
}
//
double iL = iLBar.low;
bool isILAccepted =
//
iL > 0 &&
(
//
lastL == 0
? true
: iL > lastL
//
)
//
;
if (isILAccepted)
{
//
AddRef(
iLBar,
lowSwingBars //
);
//
lastL = iL;
lastIDX = iLIDX;
}
}
//
// Use Other MEthod ...
else
{
//
int _length = i * _loopback;
int start =
//
i == 1
? 1
: _length - _loopback
//
;
//
int iHIDX = iHighest(
bar.symbol,
bar.period,
MODE_HIGH,
_loopback,
start //
);
result = IsValidIndex(iHIDX);
if (!result)
{
break;
}
//
XOHCL iHBar;
result = iHBar.Init(
bar.symbol,
bar.period,
iHIDX //
);
if (!result)
{
break;
}
//
double iH = iHBar.high;
bool isIHAccepted =
//
iH > 0 &&
(
//
lastH == 0
? true
: iH > lastH
//
)
//
;
if (isIHAccepted)
{
//
AddRef(
iHBar,
highSwingBars //
);
//
lastH = iH;
lastIDX = iHIDX;
}
//
int iLIDX = iLowest(
bar.symbol,
bar.period,
MODE_LOW,
_loopback,
start //
);
result = IsValidIndex(iLIDX);
if (!result)
{
break;
}
//
XOHCL iLBar;
result = iLBar.Init(
bar.symbol,
bar.period,
iLIDX //
);
if (!result)
{
break;
}
//
double iL = iLBar.low;
bool isILAccepted =
//
iL > 0 &&
(
//
lastL == 0
? true
: iL > lastL
//
)
//
;
if (isILAccepted)
{
//
AddRef(
iLBar,
lowSwingBars //
);
//
lastL = iL;
lastIDX = iLIDX;
}
}
}
//
if (result)
{
//
result =
//
ArraySize(lowSwingBars) == tries &&
ArraySize(highSwingBars) == tries
//
;
}
//
if (!result)
{
//
Clean(lowSwingBars);
Clean(highSwingBars);
}
//
return result;
}
//
// Order Blocks ...
//
// Find Bullish Order Block ...
bool HasBullishOrderBlock(
XOHCL &bar,
XOHCL &orderBlock,
int _minimumSameBars = 4 //
)
{
//
bool result = false;
//
orderBlock.Clean();
//
result = bar.IsValid();
if (!result)
{
return result;
}
//
if (_minimumSameBars < 0)
{
_minimumSameBars = 4;
}
//
XOHCL cBar;
int founded = 0;
int cIDX = bar.Index();
bool isEnough = false;
while (!isEnough)
{
//
result = cBar.Init(
bar.symbol,
bar.period,
cIDX //
);
if (!result)
{
break;
}
//
result = cBar.IsBullish();
if (!result && cBar.IsBearish())
{
break;
}
//
cIDX++;
founded++;
}
//
// Here we have to check founded and if it's fill
// our requirements ...
// cIDX is Order Block Index ...
result =
//
cBar.IsValid() &&
bar.high > cBar.high &&
founded >= _minimumSameBars
//
;
if (!result)
{
return result;
}
//
result = orderBlock.Init(
bar.symbol,
bar.period,
cIDX //
);
if (!result)
{
//
orderBlock.Clean();
return result;
}
//
return result;
}
//
// Find Bearish Order Block ...
bool HasBearishOrderBlock(
XOHCL &bar,
XOHCL &orderBlock,
int _minimumSameBars = 4 //
)
{
//
bool result = false;
//
orderBlock.Clean();
//
result = bar.IsValid();
if (!result)
{
return result;
}
//
if (_minimumSameBars < 0)
{
_minimumSameBars = 4;
}
//
XOHCL cBar;
int founded = 0;
int cIDX = bar.Index();
bool isEnough = false;
while (!isEnough)
{
//
bool isInited = cBar.Init(
bar.symbol,
bar.period,
cIDX //
);
//
result = cBar.IsBearish();
if (!result && cBar.IsBullish())
{
break;
}
//
cIDX++;
founded++;
}
//
// Here we have to check founded and if it's fill
// our requirements ...
// cIDX is Order Block Index ...
result =
//
cBar.IsValid() &&
bar.high < cBar.low &&
founded >= _minimumSameBars
//
;
if (!result)
{
return result;
}
//
result = orderBlock.Init(
bar.symbol,
bar.period,
cIDX //
);
if (!result)
{
//
orderBlock.Clean();
return result;
}
//
return result;
}