804 lines
14 KiB
Plaintext
804 lines
14 KiB
Plaintext
/////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// SaherElm IT Center MQL5 XPVHLP Indicator Helper for Signal Providers
|
|
// --------------------------------------------------------------------------
|
|
//
|
|
// 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
|
|
|
|
//
|
|
// START Includes ...
|
|
//
|
|
|
|
//
|
|
// Includes ...
|
|
#include "../../Libraries/x-saherelm.alert.lib.mq5"
|
|
#include "../../Libraries/x-saherelm.models.lib.mq5"
|
|
#include "../../Libraries/x-saherelm.common.lib.mq5"
|
|
|
|
//
|
|
// END Includes ...
|
|
//
|
|
|
|
//
|
|
// START Constants/Enums ...
|
|
//
|
|
|
|
//
|
|
// XPeaksAndVales Exported Buffers ...
|
|
enum ENUM_X_XPV_BUFFERS
|
|
{
|
|
//
|
|
// PEAKSANDVALES ...
|
|
X_PV_P_LINE = 0,
|
|
X_PV_V_LINE = 1,
|
|
//
|
|
// SUPPORTRESISTANCE ...
|
|
X_PV_R_LINE = 2,
|
|
X_PV_S_LINE = 4,
|
|
//
|
|
// SHORT ...
|
|
X_PV_SHH_LINE = 6,
|
|
X_PV_SLL_LINE = 7,
|
|
//
|
|
// MEDIUM ...
|
|
X_PV_MHH_LINE = 8,
|
|
X_PV_MLL_LINE = 9,
|
|
//
|
|
// LONG ...
|
|
X_PV_LHH_LINE = 10,
|
|
X_PV_LLL_LINE = 11,
|
|
//
|
|
// HIND ...
|
|
X_PV_HHH_LINE = 12,
|
|
X_PV_HLL_LINE = 13,
|
|
};
|
|
|
|
//
|
|
// END Constants/Enums ...
|
|
//
|
|
|
|
//
|
|
// START Definitions ...
|
|
//
|
|
|
|
//
|
|
double pvPivots[];
|
|
|
|
//
|
|
double pvPBuffer[];
|
|
double pvVBuffer[];
|
|
double pvRBuffer[];
|
|
double pvSBuffer[];
|
|
double pvSHHBuffer[];
|
|
double pvSLLBuffer[];
|
|
double pvMHHBuffer[];
|
|
double pvMLLBuffer[];
|
|
double pvLHHBuffer[];
|
|
double pvLLLBuffer[];
|
|
double pvHHHBuffer[];
|
|
double pvHLLBuffer[];
|
|
|
|
//
|
|
int mpvHandler = INVALID_HANDLE;
|
|
|
|
//
|
|
// END Definitions ...
|
|
//
|
|
|
|
//
|
|
// START Handler Functions ...
|
|
//
|
|
|
|
//
|
|
bool XPVHLPOnInit()
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
ArraySetAsSeries(pvPivots, true);
|
|
|
|
//
|
|
ArraySetAsSeries(pvPBuffer, true);
|
|
ArraySetAsSeries(pvVBuffer, true);
|
|
ArraySetAsSeries(pvRBuffer, true);
|
|
ArraySetAsSeries(pvSBuffer, true);
|
|
ArraySetAsSeries(pvSHHBuffer, true);
|
|
ArraySetAsSeries(pvSLLBuffer, true);
|
|
ArraySetAsSeries(pvMHHBuffer, true);
|
|
ArraySetAsSeries(pvMLLBuffer, true);
|
|
ArraySetAsSeries(pvLHHBuffer, true);
|
|
ArraySetAsSeries(pvLLLBuffer, true);
|
|
ArraySetAsSeries(pvHHHBuffer, true);
|
|
ArraySetAsSeries(pvHLLBuffer, true);
|
|
|
|
//
|
|
// Initial Handler ...
|
|
mpvHandler = iCustom(
|
|
_Symbol,
|
|
_Period,
|
|
"x-saherelm.x121.xpv",
|
|
//
|
|
// Inputs ...
|
|
//
|
|
// MARKET ...
|
|
"",
|
|
9,
|
|
17,
|
|
26,
|
|
35,
|
|
//
|
|
// TREND ...
|
|
"",
|
|
10,
|
|
//
|
|
// DETECTION ...
|
|
"",
|
|
MODE_HIGH,
|
|
MODE_LOW,
|
|
//
|
|
"",
|
|
true,
|
|
false,
|
|
false,
|
|
false
|
|
//
|
|
);
|
|
result = mpvHandler != INVALID_HANDLE;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
void XPVHLPOnDeInit()
|
|
{
|
|
//
|
|
// Release Indicators ...
|
|
IndicatorRelease(mpvHandler);
|
|
}
|
|
|
|
//
|
|
void XPVHLPReadBuffers(int bar_index = 0)
|
|
{
|
|
//
|
|
// PEAKS ...
|
|
CopyBuffer(
|
|
mpvHandler,
|
|
X_PV_P_LINE,
|
|
bar_index,
|
|
bar_index + 100,
|
|
pvPBuffer);
|
|
|
|
//
|
|
// VALES ...
|
|
CopyBuffer(
|
|
mpvHandler,
|
|
X_PV_V_LINE,
|
|
bar_index,
|
|
bar_index + 100,
|
|
pvVBuffer);
|
|
|
|
//
|
|
// R ...
|
|
CopyBuffer(
|
|
mpvHandler,
|
|
X_PV_R_LINE,
|
|
bar_index,
|
|
bar_index + 100,
|
|
pvRBuffer);
|
|
|
|
//
|
|
// S ...
|
|
CopyBuffer(
|
|
mpvHandler,
|
|
X_PV_S_LINE,
|
|
bar_index,
|
|
bar_index + 100,
|
|
pvSBuffer);
|
|
|
|
//
|
|
// SHORT ...
|
|
|
|
//
|
|
// HIGH ...
|
|
CopyBuffer(
|
|
mpvHandler,
|
|
X_PV_SHH_LINE,
|
|
bar_index,
|
|
bar_index + 100,
|
|
pvSHHBuffer);
|
|
|
|
//
|
|
// LOW ...
|
|
CopyBuffer(
|
|
mpvHandler,
|
|
X_PV_SLL_LINE,
|
|
bar_index,
|
|
bar_index + 100,
|
|
pvSLLBuffer);
|
|
|
|
//
|
|
// MEIUM ...
|
|
|
|
//
|
|
// HIGH ...
|
|
CopyBuffer(
|
|
mpvHandler,
|
|
X_PV_MHH_LINE,
|
|
bar_index,
|
|
bar_index + 100,
|
|
pvMHHBuffer);
|
|
|
|
//
|
|
// LOW ...
|
|
CopyBuffer(
|
|
mpvHandler,
|
|
X_PV_MLL_LINE,
|
|
bar_index,
|
|
bar_index + 100,
|
|
pvMLLBuffer);
|
|
|
|
//
|
|
// LONG ...
|
|
|
|
//
|
|
// HIGH ...
|
|
CopyBuffer(
|
|
mpvHandler,
|
|
X_PV_LHH_LINE,
|
|
bar_index,
|
|
bar_index + 100,
|
|
pvLHHBuffer);
|
|
|
|
//
|
|
// LOW ...
|
|
CopyBuffer(
|
|
mpvHandler,
|
|
X_PV_LLL_LINE,
|
|
bar_index,
|
|
bar_index + 100,
|
|
pvLLLBuffer);
|
|
|
|
//
|
|
// HIND ...
|
|
|
|
//
|
|
// HIGH ...
|
|
CopyBuffer(
|
|
mpvHandler,
|
|
X_PV_HHH_LINE,
|
|
bar_index,
|
|
bar_index + 100,
|
|
pvHHHBuffer);
|
|
|
|
//
|
|
// LOW ...
|
|
CopyBuffer(
|
|
mpvHandler,
|
|
X_PV_HLL_LINE,
|
|
bar_index,
|
|
bar_index + 100,
|
|
pvHLLBuffer);
|
|
|
|
//
|
|
XPVHLPFindPivotPoints();
|
|
}
|
|
|
|
//
|
|
// END Handler Functions ...
|
|
//
|
|
|
|
//
|
|
// START Helper Functions ...
|
|
//
|
|
|
|
//
|
|
// Check isPeak ...
|
|
bool XPVHLPIsPeak(int bar_index)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
if (!XPVHLPIsValidArraySize(bar_index))
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result = pvRBuffer[bar_index] == pvHHHBuffer[bar_index] &&
|
|
pvHHHBuffer[bar_index] == pvLHHBuffer[bar_index] &&
|
|
pvLHHBuffer[bar_index] == pvMHHBuffer[bar_index] &&
|
|
pvMHHBuffer[bar_index] == pvSHHBuffer[bar_index];
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Check isVale ...
|
|
bool XPVHLPIsVale(int bar_index)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
if (!XPVHLPIsValidArraySize(bar_index))
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result = pvSBuffer[bar_index] == pvHLLBuffer[bar_index] &&
|
|
pvHLLBuffer[bar_index] == pvLLLBuffer[bar_index] &&
|
|
pvLLLBuffer[bar_index] == pvMLLBuffer[bar_index] &&
|
|
pvMLLBuffer[bar_index] == pvSLLBuffer[bar_index];
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Is Strong Support ...
|
|
bool XPVHLPIsStrongSupport(int bar_index)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
if (!XPVHLPIsValidArraySize(bar_index + 3))
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result =
|
|
//
|
|
pvHLLBuffer[bar_index + 1] == pvHLLBuffer[bar_index + 2] &&
|
|
pvHLLBuffer[bar_index + 2] == pvHLLBuffer[bar_index + 3] &&
|
|
//
|
|
pvLLLBuffer[bar_index + 1] == pvLLLBuffer[bar_index + 2] &&
|
|
pvLLLBuffer[bar_index + 2] == pvLLLBuffer[bar_index + 3] &&
|
|
//
|
|
pvMLLBuffer[bar_index + 1] == pvMLLBuffer[bar_index + 2] &&
|
|
pvMLLBuffer[bar_index + 2] == pvMLLBuffer[bar_index + 3] &&
|
|
//
|
|
pvSLLBuffer[bar_index + 1] == pvSLLBuffer[bar_index + 2] &&
|
|
pvSLLBuffer[bar_index + 2] == pvSLLBuffer[bar_index + 3]
|
|
//
|
|
;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Is Strong Resistance ...
|
|
bool XPVHLPIsStrongResistance(int bar_index)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
if (!XPVHLPIsValidArraySize(bar_index + 2))
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result =
|
|
//
|
|
pvHHHBuffer[bar_index + 1] == pvHHHBuffer[bar_index + 2] &&
|
|
pvHHHBuffer[bar_index + 2] == pvHHHBuffer[bar_index + 3] &&
|
|
//
|
|
pvLHHBuffer[bar_index + 1] == pvLHHBuffer[bar_index + 2] &&
|
|
pvLHHBuffer[bar_index + 2] == pvLHHBuffer[bar_index + 3] &&
|
|
//
|
|
pvMHHBuffer[bar_index + 1] == pvMHHBuffer[bar_index + 2] &&
|
|
pvMHHBuffer[bar_index + 2] == pvMHHBuffer[bar_index + 3] &&
|
|
//
|
|
pvSHHBuffer[bar_index + 1] == pvSHHBuffer[bar_index + 2] &&
|
|
pvSHHBuffer[bar_index + 2] == pvSHHBuffer[bar_index + 3]
|
|
//
|
|
;
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Retrieve Highs ...
|
|
double XPVHLPGetMaxHH(int bar_index)
|
|
{
|
|
//
|
|
double result = 0;
|
|
|
|
//
|
|
if (!XPVHLPIsValidArraySize(bar_index))
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result = MathMax(pvSHHBuffer[bar_index], pvMHHBuffer[bar_index]);
|
|
result = MathMax(result, pvLHHBuffer[bar_index]);
|
|
result = MathMax(result, pvHHHBuffer[bar_index]);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
double XPVHLPGetMinHH(int bar_index)
|
|
{
|
|
//
|
|
double result = 0;
|
|
|
|
//
|
|
if (!XPVHLPIsValidArraySize(bar_index))
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result = MathMin(pvSHHBuffer[bar_index], pvMHHBuffer[bar_index]);
|
|
result = MathMin(result, pvLHHBuffer[bar_index]);
|
|
result = MathMin(result, pvHHHBuffer[bar_index]);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Retrieve Lows ...
|
|
double XPVHLPGetMaxLL(int bar_index)
|
|
{
|
|
//
|
|
double result = 0;
|
|
|
|
//
|
|
if (!XPVHLPIsValidArraySize(bar_index))
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result = MathMax(pvSLLBuffer[bar_index], pvMLLBuffer[bar_index]);
|
|
result = MathMax(result, pvLLLBuffer[bar_index]);
|
|
result = MathMax(result, pvHLLBuffer[bar_index]);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
double XPVHLPGetMinLL(int bar_index)
|
|
{
|
|
//
|
|
double result = 0;
|
|
|
|
//
|
|
if (!XPVHLPIsValidArraySize(bar_index))
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result = MathMin(pvSLLBuffer[bar_index], pvMLLBuffer[bar_index]);
|
|
result = MathMin(result, pvLLLBuffer[bar_index]);
|
|
result = MathMin(result, pvHLLBuffer[bar_index]);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
bool XPVHLPIsValidArraySize(int bar_index)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
if (bar_index < 0)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
int rCount = ArraySize(pvRBuffer);
|
|
result = rCount > bar_index + 1;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// SUPPORT and RESISTANCE ...
|
|
|
|
//
|
|
// Find Pivot Areas in PV ...
|
|
void XPVHLPFindPivotPoints()
|
|
{
|
|
//
|
|
double smoothingPoint = 3;
|
|
int verifications = 26;
|
|
|
|
//
|
|
// FLATS ...
|
|
double tmpFlats[];
|
|
int tmpFlatsCount = 0;
|
|
|
|
//
|
|
// PEAKS and VALES ...
|
|
|
|
//
|
|
// R ...
|
|
FindSameValueInBuffer(
|
|
tmpFlats,
|
|
pvRBuffer);
|
|
tmpFlatsCount = ArraySize(tmpFlats);
|
|
if (tmpFlatsCount > 0)
|
|
{
|
|
//
|
|
AddsIfNotExists(
|
|
tmpFlats,
|
|
pvPivots,
|
|
smoothingPoint);
|
|
|
|
//
|
|
Clean(tmpFlats);
|
|
}
|
|
|
|
//
|
|
// S ...
|
|
FindSameValueInBuffer(
|
|
tmpFlats,
|
|
pvSBuffer);
|
|
tmpFlatsCount = ArraySize(tmpFlats);
|
|
if (tmpFlatsCount > 0)
|
|
{
|
|
//
|
|
AddsIfNotExists(
|
|
tmpFlats,
|
|
pvPivots,
|
|
smoothingPoint);
|
|
|
|
//
|
|
Clean(tmpFlats);
|
|
}
|
|
|
|
//
|
|
// CYCLES ...
|
|
|
|
//
|
|
// SHORT ...
|
|
// LEVEL 1 ...
|
|
|
|
//
|
|
// HH ...
|
|
FindSameValueInBuffer(
|
|
tmpFlats,
|
|
pvSHHBuffer);
|
|
tmpFlatsCount = ArraySize(tmpFlats);
|
|
if (tmpFlatsCount > 0)
|
|
{
|
|
//
|
|
AddsIfNotExists(
|
|
tmpFlats,
|
|
pvPivots,
|
|
smoothingPoint);
|
|
|
|
//
|
|
Clean(tmpFlats);
|
|
}
|
|
|
|
//
|
|
// LL ...
|
|
FindSameValueInBuffer(
|
|
tmpFlats,
|
|
pvSLLBuffer);
|
|
tmpFlatsCount = ArraySize(tmpFlats);
|
|
if (tmpFlatsCount > 0)
|
|
{
|
|
//
|
|
AddsIfNotExists(
|
|
tmpFlats,
|
|
pvPivots,
|
|
smoothingPoint);
|
|
|
|
//
|
|
Clean(tmpFlats);
|
|
}
|
|
|
|
//
|
|
// MEDIUM ...
|
|
// LEVEL 2 ...
|
|
|
|
//
|
|
// HH ...
|
|
FindSameValueInBuffer(
|
|
tmpFlats,
|
|
pvMHHBuffer);
|
|
tmpFlatsCount = ArraySize(tmpFlats);
|
|
if (tmpFlatsCount > 0)
|
|
{
|
|
//
|
|
AddsIfNotExists(
|
|
tmpFlats,
|
|
pvPivots,
|
|
smoothingPoint);
|
|
|
|
//
|
|
Clean(tmpFlats);
|
|
}
|
|
|
|
//
|
|
// LL ...
|
|
FindSameValueInBuffer(
|
|
tmpFlats,
|
|
pvMLLBuffer);
|
|
tmpFlatsCount = ArraySize(tmpFlats);
|
|
if (tmpFlatsCount > 0)
|
|
{
|
|
//
|
|
AddsIfNotExists(
|
|
tmpFlats,
|
|
pvPivots,
|
|
smoothingPoint);
|
|
|
|
//
|
|
Clean(tmpFlats);
|
|
}
|
|
|
|
//
|
|
// LONG ...
|
|
// LEVEL 3 ...
|
|
|
|
//
|
|
// HH ...
|
|
FindSameValueInBuffer(
|
|
tmpFlats,
|
|
pvLHHBuffer);
|
|
tmpFlatsCount = ArraySize(tmpFlats);
|
|
if (tmpFlatsCount > 0)
|
|
{
|
|
//
|
|
AddsIfNotExists(
|
|
tmpFlats,
|
|
pvPivots,
|
|
smoothingPoint);
|
|
|
|
//
|
|
Clean(tmpFlats);
|
|
}
|
|
|
|
//
|
|
// LL ...
|
|
FindSameValueInBuffer(
|
|
tmpFlats,
|
|
pvLLLBuffer);
|
|
tmpFlatsCount = ArraySize(tmpFlats);
|
|
if (tmpFlatsCount > 0)
|
|
{
|
|
//
|
|
AddsIfNotExists(
|
|
tmpFlats,
|
|
pvPivots,
|
|
smoothingPoint);
|
|
|
|
//
|
|
Clean(tmpFlats);
|
|
}
|
|
|
|
//
|
|
// HINDMOST ...
|
|
// LEVEL 4 ...
|
|
|
|
//
|
|
// HH ...
|
|
FindSameValueInBuffer(
|
|
tmpFlats,
|
|
pvHHHBuffer);
|
|
tmpFlatsCount = ArraySize(tmpFlats);
|
|
if (tmpFlatsCount > 0)
|
|
{
|
|
//
|
|
AddsIfNotExists(
|
|
tmpFlats,
|
|
pvPivots,
|
|
smoothingPoint);
|
|
|
|
//
|
|
Clean(tmpFlats);
|
|
}
|
|
|
|
//
|
|
// LL ...
|
|
FindSameValueInBuffer(
|
|
tmpFlats,
|
|
pvHLLBuffer);
|
|
tmpFlatsCount = ArraySize(tmpFlats);
|
|
if (tmpFlatsCount > 0)
|
|
{
|
|
//
|
|
AddsIfNotExists(
|
|
tmpFlats,
|
|
pvPivots,
|
|
smoothingPoint);
|
|
|
|
//
|
|
Clean(tmpFlats);
|
|
}
|
|
|
|
//
|
|
// PEAKS and VALES ...
|
|
|
|
//
|
|
// PEAKS ...
|
|
FindSameValueInBuffer(
|
|
tmpFlats,
|
|
pvPBuffer);
|
|
tmpFlatsCount = ArraySize(tmpFlats);
|
|
if (tmpFlatsCount > 0)
|
|
{
|
|
//
|
|
AddsIfNotExists(
|
|
tmpFlats,
|
|
pvPivots,
|
|
smoothingPoint);
|
|
|
|
//
|
|
Clean(tmpFlats);
|
|
}
|
|
|
|
//
|
|
// VALES ...
|
|
FindSameValueInBuffer(
|
|
tmpFlats,
|
|
pvVBuffer);
|
|
tmpFlatsCount = ArraySize(tmpFlats);
|
|
if (tmpFlatsCount > 0)
|
|
{
|
|
//
|
|
AddsIfNotExists(
|
|
tmpFlats,
|
|
pvPivots,
|
|
smoothingPoint);
|
|
|
|
//
|
|
Clean(tmpFlats);
|
|
}
|
|
}
|
|
|
|
//
|
|
// Extract Support and Resistances ...
|
|
XOHCLSupRes XPVHLPFindCandleSupprtAndResistance(
|
|
int bar_index, // Bar Index ...
|
|
int count = 3 // Number of Requireds ...
|
|
)
|
|
{
|
|
//
|
|
XOHCLSupRes result = ExtractSupportAndResistance(
|
|
bar_index,
|
|
pvPivots,
|
|
count,
|
|
_Symbol,
|
|
_Period);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// END Helper Functions ...
|
|
//
|