Files
MQL5Data/Libraries/x-saherelm.tools.mq5
T
2024-07-09 17:28:07 +03:30

1793 lines
34 KiB
Plaintext

///////////////////////////////////////////////////////
//
// SaherElm IT Center MQL5 Tools Library
// --------------------------------------
// Name: XToolsLib
// Description: provide all commonly used Tools ...
//
//
// 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 "../Libraries/x-saherelm.draw.lib.mq5"
#include "../Libraries/x-saherelm.common.lib.mq5"
//
// Definitions ...
//
// a Pivot Point ...
struct XPivot
{
//
string symbol; // Trading Symbol ...
ENUM_TIMEFRAMES period; // Trading TimeFrame ...
//
double price; // Price ...
datetime time; // Time ...
//
int breakedAsSupport; // Number of Breaked As Support ...
int rejectedAsSupport; // Number of Rejected As Support ...
//
int breakedAsResistance; // Number of Breaked As Resistance ...
int rejectedAsResistance; // Number of Rejected As Resistance ...
//
bool isSupport;
datetime supportTime;
//
bool isResistance;
datetime resistanceTime;
//
int _lastCalculatedBar;
int _loopbackForSupportAndResistance; // Number of LoopBacks for Support or Resistance ...
//
// Constructor ...
XPivot()
{
Clean();
}
//
// Initialization ...
bool Init(
string _symbol,
ENUM_TIMEFRAMES _period,
double _price,
int barIndex = 0,
int _supResVerificationsStep = 21 //
)
{
//
bool result = false;
//
if (barIndex < 0)
{
barIndex = 0;
}
//
if (_supResVerificationsStep < 0)
{
_supResVerificationsStep = 21;
}
//
result =
//
_price > 0 &&
IsValid(_symbol) &&
IsValid(_period) &&
IsValidSize(_supResVerificationsStep)
//
;
if (!result)
{
return result;
}
//
symbol = _symbol;
period = _period;
price = _price;
//
_loopbackForSupportAndResistance = _supResVerificationsStep;
//
Calculate(
barIndex //
);
//
result = IsValid();
//
return result;
}
//
// Find Last Support for Market and
// Initialize Pivot Based On it ...
bool FindLastSupport(
string _symbol,
ENUM_TIMEFRAMES _period,
int barIndex = 0,
int _supResVerificationsStep = 21 //
)
{
//
bool result = false;
//
if (barIndex < 0)
{
barIndex = 0;
}
//
if (_supResVerificationsStep < 0)
{
_supResVerificationsStep = 21;
}
//
result =
//
IsValid(_symbol) &&
IsValid(_period) &&
IsValidSize(_supResVerificationsStep)
//
;
if (!result)
{
return result;
}
//
// Find Resistance ...
//
// Retrieve Current Bar ...
XOHCL cBar;
result = cBar.Init(
_symbol,
_period,
barIndex //
);
if (!result)
{
return result;
}
//
// Calculate Available Bars ...
//
int bars = iBars(
_symbol,
_period //
);
int maxAllowedBars = bars - 500;
int currentLength = _supResVerificationsStep;
//
// Find Highest High ...
for (int i = barIndex; i < maxAllowedBars; i++)
{
//
// Validate and Regenrate Current Length ...
if (i > 1)
{
//
currentLength = _supResVerificationsStep * i;
//
if (currentLength > maxAllowedBars)
{
currentLength = maxAllowedBars;
}
}
//
// Clean ...
Clean();
//
int llIndex = cBar.FindLowestIndex(
currentLength,
MODE_LOW //
);
XOHCL llBar;
result = llBar.Init(
_Symbol,
_Period,
llIndex //
);
if (!result)
{
continue;
}
//
result = Init(
_symbol,
_period,
llBar.low,
barIndex //
);
if (!result)
{
//
Clean();
continue;
}
//
result = isSupport;
if (result)
{
//
supportTime = llBar.time;
break;
}
}
//
result = IsValid() && isSupport;
//
return result;
}
//
// Find Last Resistance for Market and
// Initialized Pivot Based On it ...
bool FindLastResistance(
string _symbol,
ENUM_TIMEFRAMES _period,
int barIndex = 0,
int _supResVerificationsStep = 21 //
)
{
//
bool result = false;
//
if (barIndex < 0)
{
barIndex = 0;
}
//
if (_supResVerificationsStep < 0)
{
_supResVerificationsStep = 21;
}
//
result =
//
IsValid(_symbol) &&
IsValid(_period) &&
IsValidSize(_supResVerificationsStep)
//
;
if (!result)
{
return result;
}
//
// Find Resistance ...
//
// Retrieve Current Bar ...
XOHCL cBar;
result = cBar.Init(
_symbol,
_period,
barIndex //
);
if (!result)
{
return result;
}
//
// Calculate Available Bars ...
//
int bars = iBars(
_symbol,
_period //
);
int maxAllowedBars = bars - 500;
int currentLength = _supResVerificationsStep;
//
// Find Highest High ...
for (int i = barIndex; i < maxAllowedBars; i++)
{
//
// Validate and Regenrate Current Length ...
if (i > 1)
{
//
currentLength = _supResVerificationsStep * i;
//
if (currentLength > maxAllowedBars)
{
currentLength = maxAllowedBars;
}
}
//
// Clean ...
Clean();
//
int hhIndex = cBar.FindHighestIndex(
currentLength,
MODE_HIGH //
);
XOHCL hhBar;
result = hhBar.Init(
_Symbol,
_Period,
hhIndex //
);
if (!result)
{
continue;
}
//
result = Init(
_symbol,
_period,
hhBar.high,
barIndex //
);
if (!result)
{
//
Clean();
continue;
}
//
result = isResistance;
if (result)
{
//
resistanceTime = hhBar.time;
break;
}
}
//
result = IsValid() && isResistance;
//
return result;
}
//
// Check Rejection Based On Pivot Type ...
bool IsRejected()
{
//
bool result = false;
//
result =
//
IsValid() &&
(
//
isSupport ||
isResistance
//
)
//
;
if (!result)
{
return result;
}
//
result =
//
isSupport
? IsSupportRejected()
: IsResistanceRejected()
//
;
//
return result;
}
//
// Check Breake Based On Pivot Type ...
bool IsBreaked()
{
//
bool result = false;
//
result =
//
IsValid() &&
(
//
isSupport ||
isResistance
//
)
//
;
if (!result)
{
return result;
}
//
result =
//
isSupport
? IsSupportBreaked()
: IsResistanceBreaked()
//
;
//
return result;
}
//
// Tools ...
//
// Check Support Rejected ...
bool IsSupportRejected()
{
//
bool result = false;
//
result = isSupport;
if (!result)
{
return result;
}
//
// Initialize Required Bars ...
//
XOHCL cBar;
result = cBar.Init(
symbol,
period,
1 //
);
if (!result)
{
return result;
}
//
XOHCL pBar;
result = pBar.Init(
symbol,
period,
2 //
);
if (!result)
{
return result;
}
//
result =
//
// Check Support Touch or Fake Break ...
pBar.low < price
//
&&
//
// Check Rejection ...
cBar.low > price
//
;
//
return result;
}
//
// Check Support Breaked ...
bool IsSupportBreaked()
{
//
bool result = false;
//
result = isSupport;
if (!result)
{
return result;
}
//
// Initialize Required Bars ...
//
XOHCL cBar;
result = cBar.Init(
symbol,
period,
1 //
);
if (!result)
{
return result;
}
//
XOHCL pBar;
result = pBar.Init(
symbol,
period,
2 //
);
if (!result)
{
return result;
}
//
result =
//
// Check Support Breaks ...
pBar.close < price
//
&&
//
// Check 50% ...
(price - pBar.close) > (pBar.GetBody() / 100) * 50
//
&&
//
// Also Next Bar must Closed Below Support ...
cBar.high < price
//
&&
//
cBar.close < price
//
&&
//
cBar.IsBullish()
//
;
//
return result;
}
//
// Check Resistance Rejected ...
bool IsResistanceRejected()
{
//
bool result = false;
//
result = isResistance;
if (!result)
{
return result;
}
//
// Initialize Required Bars ...
//
XOHCL cBar;
result = cBar.Init(
symbol,
period,
1 //
);
if (!result)
{
return result;
}
//
XOHCL pBar;
result = pBar.Init(
symbol,
period,
2 //
);
if (!result)
{
return result;
}
//
result =
//
// Check Resistance Touch or Fake Break ...
pBar.high > price
//
&&
//
// Check Rejection ...
cBar.high < price
//
;
//
return result;
}
//
// Check Resistance Breaked ...
bool IsResistanceBreaked()
{
//
bool result = false;
//
result = isResistance;
if (!result)
{
return result;
}
//
// Initialize Required Bars ...
//
XOHCL cBar;
result = cBar.Init(
symbol,
period,
1 //
);
if (!result)
{
return result;
}
//
XOHCL pBar;
result = pBar.Init(
symbol,
period,
2 //
);
if (!result)
{
return result;
}
//
result =
//
// Check Resistance Breaks ...
pBar.close > price
//
&&
//
// Check 50% ...
(pBar.close - price) > (pBar.GetBody() / 100) * 50
//
&&
//
// Also Next Bar Must Closed Above Resistance ...
cBar.low > price
//
&&
//
cBar.close > price
//
&&
//
cBar.IsBullish()
//
;
//
return result;
}
//
// Cleanup ...
void Clean()
{
//
time = NULL;
symbol = NULL;
period = NULL;
supportTime = NULL;
resistanceTime = NULL;
//
price = 0;
//
breakedAsSupport = 0;
rejectedAsSupport = 0;
breakedAsResistance = 0;
rejectedAsResistance = 0;
//
_lastCalculatedBar = -1;
//
isSupport = false;
isResistance = false;
//
_objName = NULL;
}
//
// Validate Model ...
bool IsValid()
{
//
bool result = false;
//
result =
//
IsValid(symbol) &&
IsValid(period) &&
price > 0
//
;
//
return result;
}
//
// Calculate Required Data ...
void Calculate(
int barIndex,
int loopback = 288 //
)
{
//
if (isSupport || isResistance)
{
return;
}
//
int bars = iBars(
symbol,
period //
);
//
loopback += barIndex;
//
// Normalizing Loopback ...
if (loopback > bars)
{
loopback = bars - 2 - _loopbackForSupportAndResistance;
}
//
// Check Previous Calculation ...
if (bars == _lastCalculatedBar)
{
return;
}
//
_lastCalculatedBar = bars;
//
// First Get Current State of Pivot ...
// Means Use Zero Index ...
XOHCL pBar;
bool isInited = pBar.Init(
symbol,
period,
barIndex + 1 //
);
if (!isInited)
{
return;
}
//
// Retrieve Highest High and Lowest Low of SupRes Loopback ...
double hhValue = pBar
.FindHighest(
_loopbackForSupportAndResistance,
MODE_HIGH //
);
//
double llValue = pBar
.FindLowest(
_loopbackForSupportAndResistance,
MODE_LOW //
);
//
isSupport = llValue > price;
isResistance = hhValue < price;
//
// Prevent Moving Forward if it isn't Support or Resistance ...
if (!isSupport && !isResistance)
{
return;
}
//
time = TimeCurrent();
//
for (int i = 2; i < loopback; i++)
{
//
XOHCL iBar;
isInited = iBar.Init(
symbol,
period,
i //
);
if (!isInited)
{
continue;
}
//
XOHCL iPBar;
isInited = iPBar.Init(
symbol,
period,
i + 1 //
);
if (!isInited)
{
continue;
}
//
XOHCL iPPBar;
isInited = iPPBar.Init(
symbol,
period,
i + 2 //
);
if (!isInited)
{
continue;
}
//
bool isBreaked = false;
bool isRejected = false;
//
if (isSupport)
{
//
// Count Support Rejects
// and Support Breaks ...
//
// Support Rejected ...
isRejected =
//
// Check Support Touch or Fake Break ...
iPBar.low < price
//
&&
//
// Check Rejection ...
iBar.low > price
//
;
if (isRejected)
{
rejectedAsSupport++;
}
//
// Support Breaked ...
isBreaked =
//
// Check Support Breaks ...
iPBar.close < price
//
&&
//
// Check 50% ...
(price - iPBar.close) > (iPBar.GetBody() / 100) * 50
//
&&
//
// Also Next Bar must Closed Below Support ...
iBar.high < price
//
&&
//
iBar.close < price
//
&&
//
iBar.IsBullish()
//
;
if (isBreaked)
{
breakedAsSupport++;
}
}
else if (isResistance)
{
//
// Count Resistance Reject
// or Resistance Breaks ...
//
// Resistance Rejected ...
isRejected =
//
// Check Resistance Touch or Fake Break ...
iPBar.high > price
//
&&
//
// Check Rejection ...
iBar.high < price
//
;
if (isRejected)
{
rejectedAsResistance++;
}
//
// Resistance Breaked ...
isBreaked =
//
// Check Resistance Breaks ...
iPBar.close > price
//
&&
//
// Check 50% ...
(iPBar.close - price) > (iPBar.GetBody() / 100) * 50
//
&&
//
// Also Next Bar Must Closed Above Resistance ...
iBar.low > price
//
&&
//
iBar.close > price
//
&&
//
iBar.IsBullish()
//
;
if (isBreaked)
{
breakedAsResistance++;
}
}
}
}
//
string GetTag()
{
return "XPivot";
}
//
// Draw Functions ...
//
// Last Draw Object Name ...
string _objName;
//
// Draw ...
bool Draw(
long _chartId,
string _prefix = "",
color _color = clrYellow,
ENUM_LINE_STYLE _style = STYLE_DOT,
bool _ray = true,
int _width = 1,
int _subWindow = 0,
bool forcePrefix = false //
)
{
//
bool result = false;
//
if (!isSupport && !isResistance)
{
return result;
}
//
_objName = (IsValid(_prefix) && forcePrefix)
? _prefix
: GetTag() + "_" + (IsValid(_prefix) ? _prefix + "_" : "") + ToString(NormalizeDouble(price, 2));
//
int timeBarIndex = iBarShift(
symbol,
period,
time,
false //
);
datetime time1 =
//
isSupport
? supportTime
: resistanceTime
//
;
//
result = DrawTrendLine(
_chartId,
_objName,
_subWindow,
time1,
price,
time,
price,
_color,
_style,
_width,
false,
false,
_ray //
);
//
return result;
}
//
// Remove Draw ...
void Remove()
{
//
if (!IsValid(_objName))
{
return;
}
//
RemoveDraws(_objName);
}
};
//
// a Zone Modeling ...
//
enum ENUM_XZONE_STATE
{
XZONE_STATE_INVALID = 0, // Invalid Zone ...
XZONE_STATE_FULL_SUPPORT = 1, // Full Support (up / down) are Support ...
XZONE_STATE_FULL_RESISTANCE = 2, // Full Resistance (up / down) are Resistaence ...
XZONE_STATE_CONSOLIDATE = 3, // Down are Support and Up are Resistance ...
};
//
// a Zone Consists an Area of
// an Upper Pivot and a Lower Pivot ...
struct XZone
{
//
string symbol; // Trading Symbol ...
ENUM_TIMEFRAMES period; // Trading TimeFrame ...
//
datetime time;
//
XPivot up; // Up pivot ...
XPivot down; // Down Pivot ...
//
// Constructor ...
XZone()
{
Clean();
}
//
// Initialize a Zone ...
bool Init(
string _symbol,
ENUM_TIMEFRAMES _period,
double _upPrice,
double _downPrice,
int barIndex = 0,
int pivotVerificationStep = 21 //
)
{
//
bool result = false;
//
result =
//
IsValid(_symbol) &&
IsValid(_period) &&
_upPrice > 0 &&
_downPrice > 0 &&
_downPrice < _upPrice
//
;
if (!result)
{
return result;
}
//
symbol = _symbol;
period = _period;
//
result = up.Init(
symbol,
period,
_upPrice,
barIndex,
pivotVerificationStep //
);
if (!result)
{
return result;
}
//
result = down.Init(
symbol,
period,
_downPrice,
barIndex,
pivotVerificationStep //
);
if (!result)
{
return result;
}
//
result = IsValid();
//
if (result)
{
time = TimeCurrent();
}
//
return result;
}
//
// Find Last Support Zone ...
bool FindLastSupportZone(
string _symbol,
ENUM_TIMEFRAMES _period,
int barIndex = 0,
int pivotVerificationStep = 21 //
)
{
//
bool result = false;
//
// Since Support Pivots Used Target Bar's Low price
// Last Resistance Set in Down Line of Zone ...
result = down.FindLastSupport(
_symbol,
_Period,
barIndex,
pivotVerificationStep //
);
if (!result)
{
return result;
}
//
// Since Support Pivots Used Target Bar's Low price
// we can Set it's High as Up Zone ...
XOHCL tBar;
result = tBar.Init(
_symbol,
_period,
down.supportTime //
);
if (!result)
{
return result;
}
//
// Now we Have Target Bar ...
// Set it's High as Up Line of Zone ...
result = up.Init(
_symbol,
_period,
tBar.high,
barIndex,
pivotVerificationStep //
);
if (!result)
{
return result;
}
//
up.supportTime = down.supportTime;
//
if (result)
{
//
symbol = _symbol;
period = _period;
//
time = TimeCurrent();
}
//
return result;
}
//
// Find Last Resistance Zone ...
bool FindLastResistanceZone(
string _symbol,
ENUM_TIMEFRAMES _period,
int barIndex = 0,
int pivotVerificationStep = 21 //
)
{
//
bool result = false;
//
// Since Resistance Pivots Used Target Bar's High price
// Last Resistance Set in Up Line of Zone ...
result = up.FindLastResistance(
_symbol,
_Period,
barIndex,
pivotVerificationStep //
);
if (!result)
{
return result;
}
//
// Since Resistance Pivots Used Target Bar's High price
// we can Set it's Low as Down Zone ...
XOHCL tBar;
result = tBar.Init(
_symbol,
_period,
up.resistanceTime //
);
if (!result)
{
return result;
}
//
// Now we Have Target Bar ...
// Set it's Low as Down Line of Zone ...
result = down.Init(
_symbol,
_period,
tBar.low,
barIndex,
pivotVerificationStep //
);
if (!result)
{
return result;
}
//
down.resistanceTime = up.resistanceTime;
//
if (result)
{
//
symbol = _symbol;
period = _period;
//
time = TimeCurrent();
}
//
return result;
}
//
// Tools ...
//
// Check XZone State ...
ENUM_XZONE_STATE GetState()
{
//
ENUM_XZONE_STATE result = XZONE_STATE_INVALID;
if (!IsValid())
{
return result;
}
//
if (up.isSupport && down.isSupport)
{
result = XZONE_STATE_FULL_SUPPORT;
}
else if (up.isResistance && down.isResistance)
{
result = XZONE_STATE_FULL_RESISTANCE;
}
else if (up.isSupport && down.isResistance)
{
result = XZONE_STATE_CONSOLIDATE;
}
//
return result;
}
//
// Zone Tools ...
double _threshold;
double GetThresholdPoints()
{
//
double result = 0;
//
if (!IsValid())
{
return result;
}
//
double _points = GetPoints(symbol);
result =
//
_points &&
_threshold
//
;
//
return result;
}
//
// Check Zone Rejected ...
bool IsSupportRejected() {
//
bool result = false;
//
// Check is Full Support or Not ...
ENUM_XZONE_STATE state = GetState();
result = state == XZONE_STATE_FULL_SUPPORT;
if (!result) {
return result;
}
//
// First Check Price Rejection Above Upper Line ...
//
return result;
}
//
// Check Zone Breaked ...
//
// Cleanup ...
void Clean()
{
//
symbol = NULL;
period = NULL;
time = NULL;
//
up.Clean();
down.Clean();
//
_threshold = 15;
//
_objName = NULL;
}
//
// Validate ...
bool IsValid()
{
//
bool result = false;
//
result =
//
IsValid(symbol) &&
IsValid(period) &&
up.IsValid() &&
down.IsValid() &&
_threshold > 0
//
;
//
return result;
}
//
string GetTag()
{
return "XZone";
}
//
// Draw Functions ...
//
// Last Draw Object Name ...
string _objName;
//
// Draw ...
bool Draw(
long _chartId,
string _prefix = "",
color _color = clrYellow,
ENUM_LINE_STYLE _style = STYLE_DOT,
bool _ray = true,
int _width = 1,
int _subWindow = 0 //
)
{
//
bool result = false;
//
ENUM_XZONE_STATE state = GetState();
//
result =
//
IsValid() &&
state != XZONE_STATE_INVALID
//
;
if (!result)
{
return result;
}
//
_objName = GetTag() + "_" + (IsValid(_prefix) ? _prefix + "_" : "") + ToString(NormalizeDouble(up.price, 2)) + "," + ToString(NormalizeDouble(down.price, 2));
//
datetime time1 =
//
down.isSupport
? down.supportTime
: down.resistanceTime
//
;
//
result = down.Draw(
_chartId,
_objName + "_DOWN",
_color,
_style,
_ray,
_width,
_subWindow,
true // Force PRefix ...
);
if (!result)
{
return result;
}
//
result = up.Draw(
_chartId,
_objName + "_UP",
_color,
_style,
_ray,
_width,
_subWindow,
true // Force PRefix ...
);
//
return result;
}
//
// Remove Draw ...
void Remove()
{
//
if (!IsValid(_objName))
{
return;
}
//
RemoveDraws(_objName);
}
};
//
// a Range Box Model ...
// struct XRBox
// {
// //
// string symbol;
// ENUM_TIMEFRAMES period;
// //
// datetime time;
// datetime expiration;
// //
// XZone up; // Up Zone ...
// XZone down; // Down Zone ...
// //
// // Constructor ...
// XRBox()
// {
// Clean();
// }
// //
// // Initialization ...
// bool Init(
// string _symbol,
// ENUM_TIMEFRAMES _period,
// double _upZoneUpperPrice,
// double _upZoneLowerPrice,
// double _downZoneUpperPrice,
// double _downZoneLowerPrice,
// datetime _expiration = NULL //
// )
// {
// //
// bool result = false;
// //
// result =
// //
// IsValid(_symbol) &&
// IsValid(_period) &&
// _upZoneUpperPrice > 0 &&
// _upZoneLowerPrice > 0 &&
// _upZoneLowerPrice < _upZoneUpperPrice &&
// _downZoneUpperPrice > 0 &&
// _downZoneLowerPrice > 0 &&
// _downZoneLowerPrice < _downZoneUpperPrice
// //
// ;
// //
// if (!result)
// {
// return result;
// }
// //
// result = IsValid();
// //
// if (result)
// {
// //
// time = TimeCurrent();
// }
// //
// return result;
// }
// //
// // Tools ...
// //
// // Cleanup ...
// void Clean()
// {
// //
// time = NULL;
// symbol = NULL;
// period = NULL;
// expiration = NULL;
// //
// up.Clean();
// down.Clean();
// }
// //
// // Validation ...
// bool IsValid()
// {
// //
// bool result = false;
// //
// result =
// //
// IsValid(symbol) &&
// IsValid(period) &&
// up.IsValid() &&
// down.IsValid()
// //
// ;
// //
// return result;
// }
// };
// //
// // Detect Trends ...
// struct XTrendDetector
// {
// //
// string symbol;
// ENUM_TIMEFRAMES period;
// //
// double higherHighs[];
// datetime higherHighTimes[];
// //
// double higherLows[];
// datetime higherLowTimes[];
// //
// double lowerHighs[];
// datetime lowerHighTimes[];
// //
// double lowerLows[];
// datetime lowerLowTimes[];
// //
// int _numberOfPivots;
// int _pivotShoulders;
// //
// // Constructor ...
// XTrendDetector()
// {
// Clean();
// }
// //
// // Tools ...
// //
// // Cleanup ...
// void Clean()
// {
// //
// symbol = NULL;
// period = NULL;
// //
// _numberOfPivots = 0;
// _pivotShoulders = 0;
// //
// Clean(higherHighs);
// Clean(higherHighTimes);
// //
// Clean(higherLows);
// Clean(higherLowTimes);
// //
// Clean(lowerHighs);
// Clean(lowerHighTimes);
// //
// Clean(lowerLows);
// Clean(lowerLowTimes);
// }
// //
// // Validate ...
// bool IsValid()
// {
// //
// bool result = false;
// //
// result =
// //
// IsValid(symbol) &&
// IsValid(period)
// //
// ;
// //
// return result;
// }
// };