Files
MQL5Data/Classes/z-saherelm.x-bar.analyser.class.mq5
T
2024-11-08 22:57:49 +03:30

1177 lines
24 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"
//
// Definitions ...
//
// Implementations ...
class XCBarAnalyser : public XSCBase
{
//
public:
//
//
// Constructor(s) ...
void XCBarAnalyser()
{
}
//
// Deconstructor ...
void ~XCBarAnalyser()
{
}
//
// Getter(s) / Setter(s) ...
//
// Providers ...
//
// Actions ...
//
// 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;
}
//
// Rejection Bar ...
/**
* Check Specific Bar is Rejection Bar or not ...
*
* @param dir: ENUM_X_DIRECTION member, Specified Direction ...
* @param bar: XOHCL instance, Specified Bar ...
* @param strength: Double, Specified Shadow Percent Range ...
*
* @return ( bool )
*/
bool IsRejectionBar(
ENUM_X_DIRECTION &dir,
XOHCL &bar,
double strength //
)
{
//
bool result = false;
//
if (strength < 20)
{
strength = 20;
}
//
dir = X_DIRECTION_NONE;
//
result = bar.IsValid();
if (!result)
{
return result;
}
//
double barLowShadow = bar.GetLowShadow();
double barHighShadow = bar.GetHighShadow();
double barRange = bar.GetRange();
double barRangePercent = barRange / 100;
//
bool isBullishRejectionBar =
barLowShadow > barHighShadow &&
barLowShadow > barRangePercent * 40;
//
bool isBearishRejectionBar =
barHighShadow > barLowShadow &&
barHighShadow > barRangePercent * 40;
//
result = isBullishRejectionBar ||
isBearishRejectionBar;
if (result)
{
//
dir = isBullishRejectionBar
? X_DIRECTION_BULLISH
: X_DIRECTION_BEARISH;
}
//
return result;
}
/**
* Check Specific Bar is Bullish Rejection Bar or not ...
*
* @param bar: XOHCL instance, Specified Bar ...
* @param strength: Double, Specified Shadow Percent Range ...
*
* @return ( bool )
*/
bool IsBullishRejectionBar(
XOHCL &bar,
double strength = 40 //
)
{
//
bool result = false;
//
ENUM_X_DIRECTION dir;
result = IsRejectionBar(
dir,
bar,
strength //
);
result =
result &&
dir == X_DIRECTION_BULLISH;
//
return result;
}
/**
* Check Specific Bar is Bearish Rejection Bar or not ...
*
* @param bar: XOHCL instance, Specified Bar ...
* @param strength: Double, Specified Shadow Percent Range ...
*
* @return ( bool )
*/
bool IsBearishRejectionBar(
XOHCL &bar,
double strength = 40 //
)
{
//
bool result = false;
//
ENUM_X_DIRECTION dir;
result = IsRejectionBar(
dir,
bar,
strength //
);
result =
result &&
dir == X_DIRECTION_BEARISH;
//
return result;
}
//
// Momentum Bar ...
/**
* Check Specific Bar is Momentum Bar or not ...
*
* @param dir: ENUM_X_DIRECTION member, Specified Direction ...
* @param bar: XOHCL instance, Specified Bar ...
* @param strength: Double, Specified Shadow Percent Range ...
*
* @return ( bool )
*/
bool IsMomentumBar(
ENUM_X_DIRECTION &dir,
XOHCL &bar,
double strength //
)
{
//
bool result = false;
//
if (strength < 50)
{
strength = 50;
}
//
dir = X_DIRECTION_NONE;
//
double rangePercent = GetBarRangePercent(bar);
bool isStrong = bar.GetBody() > rangePercent * strength;
//
result = isStrong;
if (result)
{
//
dir = bar.IsBullish()
? X_DIRECTION_BULLISH
: X_DIRECTION_BEARISH;
}
//
return result;
}
/**
* Check Specific Bar is Bullish Momentum Bar or not ...
*
* @param bar: XOHCL instance, Specified Bar ...
* @param strength: Double, Specified Shadow Percent Range ...
*
* @return ( bool )
*/
bool IsBullishMomentumBar(
XOHCL &bar,
double strength = 40 //
)
{
//
bool result = false;
//
ENUM_X_DIRECTION dir;
result = IsMomentumBar(
dir,
bar,
strength //
);
result =
result &&
dir == X_DIRECTION_BULLISH;
//
return result;
}
/**
* Check Specific Bar is Bearish Momentum Bar or not ...
*
* @param bar: XOHCL instance, Specified Bar ...
* @param strength: Double, Specified Shadow Percent Range ...
*
* @return ( bool )
*/
bool IsBearishMomentumBar(
XOHCL &bar,
double strength = 40 //
)
{
//
bool result = false;
//
ENUM_X_DIRECTION dir;
result = IsMomentumBar(
dir,
bar,
strength //
);
result =
result &&
dir == X_DIRECTION_BEARISH;
//
return result;
}
//
// Engulfing ...
/**
* Check Bar is Engulfed or not ...
*
* @param dir: ENUM_X_DIRECTION member, Specified Direction ...
* @param bar: XOHCL instance, Speciied Bar ...
* @param loopback: Integer, loopback Length ...
*
* @return ( bool )
*/
bool IsEngulfed(
ENUM_X_DIRECTION &dir,
XOHCL &bar,
int loopback //
)
{
//
bool result = false;
//
dir = X_DIRECTION_NONE;
//
int hhIDX = 0;
double hh = 0;
//
int llIDX = 0;
double ll = 0;
//
result = CalculateLoopbackHLData(
hhIDX,
hh,
llIDX,
ll,
bar,
loopback //
);
if (!result)
{
return result;
}
//
result = bar.GetDown() < ll &&
bar.GetUp() > hh;
if (result)
{
//
dir = bar.IsBullish()
? X_DIRECTION_BULLISH
: X_DIRECTION_BEARISH;
}
//
return result;
}
/**
* Check Bar is Bullish Engulfed or not ...
*
* @param bar: XOHCL instance, Speciied Bar ...
* @param loopback: Integer, loopback Length ...
*
* @return ( bool )
*/
bool IsBullishEngulfed(
XOHCL &bar,
int loopback = 2 //
)
{
//
bool result = false;
//
ENUM_X_DIRECTION dir;
result = IsEngulfed(
dir,
bar,
loopback //
);
result =
result &&
dir == X_DIRECTION_BULLISH;
//
return result;
}
/**
* Check Bar is Bearish Engulfed or not ...
*
* @param bar: XOHCL instance, Speciied Bar ...
* @param loopback: Integer, loopback Length ...
*
* @return ( bool )
*/
bool IsBearishEngulfed(
XOHCL &bar,
int loopback = 2 //
)
{
//
bool result = false;
//
ENUM_X_DIRECTION dir;
result = IsEngulfed(
dir,
bar,
loopback //
);
result =
result &&
dir == X_DIRECTION_BEARISH;
//
return result;
}
//
// Bar CHOCH ...
/**
* Check Specified Bar Has CHOCH 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 HasCHOCH(
ENUM_X_DIRECTION &dir,
XOHCL &bar,
int loopback = 2,
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;
}
/**
* Check Specified Bar Has Bullish CHOCH or not ...
*
* @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 HasBullishCHOCH(
XOHCL &bar,
int loopback = 2,
bool forceBody = false //
)
{
//
bool result = false;
//
ENUM_X_DIRECTION dir;
result = HasCHOCH(
dir,
bar,
loopback,
forceBody //
);
result =
result &&
dir == X_DIRECTION_BULLISH;
//
return result;
}
/**
* Check Specified Bar Has Bearish CHOCH or not ...
*
* @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 HasBearishCHOCH(
XOHCL &bar,
int loopback = 2,
bool forceBody = false //
)
{
//
bool result = false;
//
ENUM_X_DIRECTION dir;
result = HasCHOCH(
dir,
bar,
loopback,
forceBody //
);
result =
result &&
dir == X_DIRECTION_BEARISH;
//
return result;
}
//
// Directions ...
/**
* Check Specified Bar Possible Direction Pressure ...
*
* @param dir: ENUM_X_DIRECTION member ...
* @param bar: XOHCL instance, Specified Bar ...
*
* @return ( bool )
*/
bool HasDirection(
ENUM_X_DIRECTION &dir,
XOHCL &bar //
)
{
//
bool result = false;
//
dir = X_DIRECTION_NONE;
//
result = bar.IsValid();
if (!result)
{
return result;
}
//
// Check Bar isExtended or not ...
bool isExtended = IsExtended(
bar,
3 //
);
//
// Check Rejection ...
ENUM_X_DIRECTION rejectionDir;
bool isRejection = IsRejectionBar(rejectionDir, bar, 40);
bool isBullishRejection = isRejection &&
rejectionDir == X_DIRECTION_BULLISH;
bool isBearishRejection = isRejection &&
rejectionDir == X_DIRECTION_BEARISH;
//
// Check Momentum ...
ENUM_X_DIRECTION momentumDir;
bool isMomentum = IsMomentumBar(momentumDir, bar, 40);
bool isBullisMomentumn = isMomentum &&
momentumDir == X_DIRECTION_BULLISH;
bool isBearishMomentum = isMomentum &&
momentumDir == X_DIRECTION_BEARISH;
//
// Check Engulfing ...
ENUM_X_DIRECTION engulfDir;
bool isEngulfed = IsEngulfed(
engulfDir,
bar,
2 //
);
bool isBullishEngulfed = isEngulfed &&
engulfDir == X_DIRECTION_BULLISH;
bool isBearishEngulfed = isEngulfed &&
engulfDir == X_DIRECTION_BEARISH;
//
// Check CHOCH ...
ENUM_X_DIRECTION chochDir;
bool hasCHOCH = HasCHOCH(
chochDir,
bar,
2,
false //
);
bool hasBullishCHOCH = hasCHOCH &&
chochDir == X_DIRECTION_BULLISH;
bool hasBearishCHOCH = hasCHOCH &&
chochDir == X_DIRECTION_BEARISH;
//
bool hasBullishDirection =
//
isExtended &&
(hasBullishCHOCH ||
isBullishEngulfed) &&
(isBullisMomentumn ||
isBullishRejection)
//
;
//
bool hasBearishDirection =
//
isExtended &&
(hasBearishCHOCH ||
isBearishEngulfed) &&
(isBearishMomentum ||
isBearishRejection)
//
;
//
result = hasBullishDirection ||
hasBearishDirection;
if (result)
{
//
dir = hasBullishDirection
? X_DIRECTION_BULLISH
: X_DIRECTION_BEARISH;
}
//
return result;
}
/**
* Check Specified Bar has Possibly Bullish Direction ...
*
* @param bar: XOHCL instance, Specified Bar ...
*
* @return ( virtual bool )
*/
virtual bool HasBullishDirection(
XOHCL &bar //
)
{
//
bool result = false;
//
ENUM_X_DIRECTION dir;
result = HasDirection(dir, bar);
result =
result &&
dir == X_DIRECTION_BULLISH;
//
return result;
}
/**
* Check Specified Bar has Possibly Bearish Direction ...
*
* @param bar: XOHCL instance, Specified Bar ...
*
* @return ( virtual bool )
*/
virtual bool HasBearishhDirection(
XOHCL &bar //
)
{
//
bool result = false;
//
ENUM_X_DIRECTION dir;
result = HasDirection(dir, bar);
result =
result &&
dir == X_DIRECTION_BEARISH;
//
return result;
}
//
protected:
//
//
// 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;
}
//
private:
//
//
// Props ...
//
// Actions ...
//
};
//