669 lines
10 KiB
Plaintext
669 lines
10 KiB
Plaintext
/////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// SaherElm IT Center MQL5 XLH 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
|
|
|
|
//
|
|
// Includes ...
|
|
#include "../Libraries/x-saherelm.log.lib.mq5"
|
|
#include "../Libraries/x-saherelm.common.lib.mq5"
|
|
|
|
//
|
|
// START Enum Definitions ...
|
|
//
|
|
|
|
//
|
|
// XLH Indicator Buffer Lines ...
|
|
enum ENUM_X_XLH_BUFFER_LINES
|
|
{
|
|
X_XLH_HH_LINE = 0,
|
|
X_XLH_LL_LINE = 1,
|
|
X_XLH_SIGNAL_LINE = 2,
|
|
};
|
|
|
|
//
|
|
// END Enum Definitions ...
|
|
//
|
|
|
|
//
|
|
// START Inputs ...
|
|
//
|
|
|
|
// input group "XLH Indicator";
|
|
|
|
// input int xLHLength = 72; // Length
|
|
// input ENUM_SERIESMODE xLHHHMode = MODE_HIGH; // Highest High Calculation Method
|
|
// input ENUM_SERIESMODE xLHLLMode = MODE_LOW; // Lowest Low Calculation Method
|
|
|
|
//
|
|
// Configurations ...
|
|
int xLHLength = 72; // Length
|
|
ENUM_SERIESMODE xLHHHMode = MODE_HIGH; // Highest High Calculation Method
|
|
ENUM_SERIESMODE xLHLLMode = MODE_LOW; // Lowest Low Calculation Method
|
|
|
|
//
|
|
// END Inputs ...
|
|
//
|
|
|
|
//
|
|
// START Definitions ...
|
|
//
|
|
|
|
//
|
|
int xLHHandler = INVALID_HANDLE;
|
|
|
|
//
|
|
double xLHHHBuffer[];
|
|
double xLHLLBuffer[];
|
|
double xLHSignalBuffer[];
|
|
|
|
//
|
|
// END Definitions ...
|
|
//
|
|
|
|
//
|
|
// START Handler Functions ...
|
|
//
|
|
|
|
//
|
|
// Validate Inputs ...
|
|
bool XLHValidateInputs()
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
result = xLHLength >= 2;
|
|
|
|
//
|
|
if (!result)
|
|
{
|
|
//
|
|
LogMessage("XLH Indicator Inputs Validation Failed ...");
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Init Indicators ...
|
|
bool XLHInitHandlers()
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Initialize Indicator/Oscillator Handlers ...
|
|
ResetLastError();
|
|
|
|
//
|
|
// XLH Handler ...
|
|
ArraySetAsSeries(xLHHHBuffer, true);
|
|
ArraySetAsSeries(xLHLLBuffer, true);
|
|
ArraySetAsSeries(xLHSignalBuffer, true);
|
|
|
|
//
|
|
xLHHandler = iCustom(
|
|
_Symbol,
|
|
_Period,
|
|
"x-saherelm.xlh.indicator",
|
|
//
|
|
// Inputs ...
|
|
xLHLength,
|
|
xLHHHMode,
|
|
xLHLLMode
|
|
//
|
|
);
|
|
if (xLHHandler == INVALID_HANDLE)
|
|
{
|
|
//
|
|
LogMessage("failed to Initialize XLH Indicator: " + (string)GetLastError());
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result = true;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Release Indicators ...
|
|
void XLHReleaseHandlers()
|
|
{
|
|
IndicatorRelease(xLHHandler);
|
|
}
|
|
|
|
//
|
|
// Handle Reading Buffers ...
|
|
void XLHReadBuffers(
|
|
int xLHItemsPerTick // Number Of Reading Buffer Items Per Tick
|
|
)
|
|
{
|
|
//
|
|
// HH Buffer ...
|
|
CopyBuffer(
|
|
xLHHandler,
|
|
X_XLH_HH_LINE,
|
|
0,
|
|
xLHItemsPerTick,
|
|
xLHHHBuffer
|
|
//
|
|
);
|
|
|
|
//
|
|
// LL Buffer ...
|
|
CopyBuffer(
|
|
xLHHandler,
|
|
X_XLH_LL_LINE,
|
|
0,
|
|
xLHItemsPerTick,
|
|
xLHLLBuffer
|
|
//
|
|
);
|
|
|
|
//
|
|
// Signal Buffer ...
|
|
CopyBuffer(
|
|
xLHHandler,
|
|
X_XLH_SIGNAL_LINE,
|
|
0,
|
|
xLHItemsPerTick,
|
|
xLHSignalBuffer
|
|
//
|
|
);
|
|
}
|
|
|
|
//
|
|
// END Handler Funcions ...
|
|
//
|
|
|
|
//
|
|
// START XLH Custom Functions ...
|
|
//
|
|
|
|
//
|
|
// TODO: What we have to Implement ...
|
|
// - []
|
|
|
|
//
|
|
// Check Candle High is HH ...
|
|
bool XLHIsHighAttachedHH(
|
|
int bar_index // Specified Index ...
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
if (
|
|
bar_index <= 0 ||
|
|
!XLHIsValidBuffersSize(bar_index + 1))
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
XOHCL candle = GetCandle(bar_index);
|
|
|
|
//
|
|
result =
|
|
//
|
|
candle.high == xLHHHBuffer[bar_index]
|
|
//
|
|
;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Check Candle Low is LL ...
|
|
bool XLHIsLowAttachedLL(
|
|
int bar_index // Specified Index ...
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
if (
|
|
bar_index <= 0 ||
|
|
!XLHIsValidBuffersSize(bar_index + 1))
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
XOHCL candle = GetCandle(bar_index);
|
|
|
|
//
|
|
result =
|
|
//
|
|
candle.low == xLHLLBuffer[bar_index]
|
|
//
|
|
;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Check Price Jumping Up Signal ...
|
|
bool XLHIsPriceCrossedOverSignal(
|
|
int bar_index // Specified Index ...
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
if (
|
|
bar_index <= 0 ||
|
|
!XLHIsValidBuffersSize(bar_index + 2))
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
XOHCL candle1 = GetCandle(bar_index);
|
|
XOHCL candle2 = GetCandle(bar_index + 1);
|
|
|
|
//
|
|
result =
|
|
//
|
|
candle1.low > xLHSignalBuffer[bar_index] &&
|
|
candle2.low < xLHSignalBuffer[bar_index + 1]
|
|
//
|
|
;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Check Price Over Signal ...
|
|
bool XLHIsPriceOverSignal(
|
|
int bar_index // Specified Index ...
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
if (
|
|
bar_index <= 0 ||
|
|
!XLHIsValidBuffersSize(bar_index + 1))
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
XOHCL candle1 = GetCandle(bar_index);
|
|
|
|
//
|
|
result =
|
|
//
|
|
candle1.low > xLHSignalBuffer[bar_index]
|
|
//
|
|
;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Check Price Jumping Down Signal ...
|
|
bool XLHIsPriceCrossedUnderSignal(
|
|
int bar_index // Specified Index ...
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
if (
|
|
bar_index <= 0 ||
|
|
!XLHIsValidBuffersSize(bar_index + 2))
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
XOHCL candle1 = GetCandle(bar_index);
|
|
XOHCL candle2 = GetCandle(bar_index + 1);
|
|
|
|
//
|
|
result =
|
|
//
|
|
candle1.high < xLHSignalBuffer[bar_index] &&
|
|
candle2.high > xLHSignalBuffer[bar_index + 1]
|
|
//
|
|
;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Check Price Down Signal ...
|
|
bool XLHIsPriceUnderSignal(
|
|
int bar_index // Specified Index ...
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
if (
|
|
bar_index <= 0 ||
|
|
!XLHIsValidBuffersSize(bar_index + 1))
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
XOHCL candle1 = GetCandle(bar_index);
|
|
|
|
//
|
|
result =
|
|
//
|
|
candle1.high < xLHSignalBuffer[bar_index]
|
|
//
|
|
;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Check Price Ranging Signal ...
|
|
bool XLHIsPriceInSignalRange(
|
|
int bar_index // Specified Index ...
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
if (
|
|
bar_index <= 0 ||
|
|
!XLHIsValidBuffersSize(bar_index + 1))
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
XOHCL candle1 = GetCandle(bar_index);
|
|
|
|
//
|
|
result =
|
|
//
|
|
candle1.high > xLHSignalBuffer[bar_index] &&
|
|
candle1.low < xLHSignalBuffer[bar_index]
|
|
//
|
|
;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Check HH Increased ...
|
|
bool XLHIsHHIncreased(
|
|
int bar_index, // Specified Index ...
|
|
int length = 10 // Specified Length ...
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
if (
|
|
length <= 0 ||
|
|
bar_index <= 0 ||
|
|
!XLHIsValidBuffersSize(bar_index + length + 1))
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result = IsIncreasing(
|
|
bar_index + length,
|
|
bar_index,
|
|
xLHHHBuffer
|
|
//
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Check HH Decreased ...
|
|
bool XLHIsHHDecreased(
|
|
int bar_index, // Specified Index ...
|
|
int length = 10 // Specified Length ...
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
if (
|
|
length <= 0 ||
|
|
bar_index <= 0 ||
|
|
!XLHIsValidBuffersSize(bar_index + length + 1))
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result = IsDecreasing(
|
|
bar_index + length,
|
|
bar_index,
|
|
xLHHHBuffer
|
|
//
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Check LL Increased ...
|
|
bool XLHIsLLIncreased(
|
|
int bar_index, // Specified Index ...
|
|
int length = 10 // Specified Length ...
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
if (
|
|
length <= 0 ||
|
|
bar_index <= 0 ||
|
|
!XLHIsValidBuffersSize(bar_index + length + 1))
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result = IsIncreasing(
|
|
bar_index + length,
|
|
bar_index,
|
|
xLHLLBuffer
|
|
//
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Check LL Decreased ...
|
|
bool XLHIsLLDecreased(
|
|
int bar_index, // Specified Index ...
|
|
int length = 10 // Specified Length ...
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
if (
|
|
length <= 0 ||
|
|
bar_index <= 0 ||
|
|
!XLHIsValidBuffersSize(bar_index + length + 1))
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result = IsDecreasing(
|
|
bar_index + length,
|
|
bar_index,
|
|
xLHLLBuffer
|
|
//
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Check HH Same in Length ...
|
|
bool XLHIsHHSameInLength(
|
|
int bar_index, // Specified Index ...
|
|
int length = 5 // Specified Length ...
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
if (
|
|
length <= 0 ||
|
|
bar_index <= 0 ||
|
|
!XLHIsValidBuffersSize(bar_index + length + 1))
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
double value1 = xLHHHBuffer[bar_index];
|
|
|
|
//
|
|
// Loop ...
|
|
result = true;
|
|
for (int i = bar_index + 1; i < bar_index + length + 1; i++)
|
|
{
|
|
//
|
|
double iValue = xLHHHBuffer[i];
|
|
if (iValue != value1)
|
|
{
|
|
//
|
|
result = false;
|
|
|
|
//
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Check LL Same in Length ...
|
|
bool XLHIsLLSameInLength(
|
|
int bar_index, // Specified Index ...
|
|
int length = 5 // Specified Length ...
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
if (
|
|
length <= 0 ||
|
|
bar_index <= 0 ||
|
|
!XLHIsValidBuffersSize(bar_index + length + 1))
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
double value1 = xLHLLBuffer[bar_index];
|
|
|
|
//
|
|
// Loop ...
|
|
result = true;
|
|
for (int i = bar_index + 1; i < bar_index + length + 1; i++)
|
|
{
|
|
//
|
|
double iValue = xLHLLBuffer[i];
|
|
if (iValue != value1)
|
|
{
|
|
//
|
|
result = false;
|
|
|
|
//
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Check all Buffers has valid Size ...
|
|
bool XLHIsValidBuffersSize(
|
|
int size // the size of buffers which min size for requirements
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
if (
|
|
size <= 0 ||
|
|
//
|
|
ArraySize(xLHHHBuffer) < size ||
|
|
ArraySize(xLHLLBuffer) < size ||
|
|
ArraySize(xLHSignalBuffer) < size
|
|
//
|
|
)
|
|
{
|
|
result = false;
|
|
}
|
|
else
|
|
{
|
|
result = true;
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// END XLH Custom Functions ...
|
|
//
|