586 lines
11 KiB
Plaintext
586 lines
11 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;
|
|
}
|
|
|
|
//
|
|
// 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;
|
|
}
|
|
|
|
//
|
|
protected:
|
|
//
|
|
|
|
//
|
|
private:
|
|
//
|
|
|
|
//
|
|
// Props ...
|
|
|
|
//
|
|
// Actions ...
|
|
|
|
//
|
|
};
|
|
|
|
// |