901 lines
15 KiB
Plaintext
901 lines
15 KiB
Plaintext
/////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// SaherElm IT Center MQL5 XTD Oscillator 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 ...
|
|
//
|
|
|
|
//
|
|
// XTD Oscillator States ...
|
|
enum ENUM_X_XTD_STATES
|
|
{
|
|
X_XTD_BULLISH_CROSSED_OVER_BEARISH = 2,
|
|
X_XTD_BULLISH_OVER_BEARISH = 1,
|
|
X_XTD_NEUTURAL = 0,
|
|
X_XTD_BULLISH_UNDER_BEARISH = -1,
|
|
X_XTD_BULLISH_CROSSED_UNDER_BEARISH = -2
|
|
};
|
|
|
|
//
|
|
// XTD Oscillator Buffer Lines ...
|
|
enum ENUM_X_XTD_BUFFER_LINES
|
|
{
|
|
X_XTD_BULLISH_POWER_LINE = 0,
|
|
X_XTD_BEARISH_POWER_LINE = 1,
|
|
X_XTD_SIGNAL_LINE = 2,
|
|
};
|
|
|
|
//
|
|
// END Enum Definitions ...
|
|
//
|
|
|
|
//
|
|
// START Inputs ...
|
|
//
|
|
|
|
input group "XTD Oscillator";
|
|
input int xTDLength = 18; // Market Length
|
|
input bool xTDDrawCrosses = false; // Draw Cross Arrows
|
|
input uchar xTDBullishArrowCode = 228; // Cross Over Arrow Code
|
|
input color xTDBullishArrowColor = clrAqua; // Cross Over Arrow Color
|
|
input uchar xTDBearishArrowCode = 230; // Cross Under Arrow Code
|
|
input color xTDBearishArrowColor = clrMagenta; // Cross Under Arrow Color
|
|
|
|
//
|
|
// END Inputs ...
|
|
//
|
|
|
|
//
|
|
// START Definitions ...
|
|
//
|
|
|
|
int xTDHandler = INVALID_HANDLE;
|
|
double xTDBullishBuffer[];
|
|
double xTDBearishBuffer[];
|
|
double xTDSignalBuffer[];
|
|
//
|
|
// END Definitions ...
|
|
//
|
|
|
|
//
|
|
// START Handler Functions ...
|
|
//
|
|
|
|
//
|
|
// Init Oscillators ...
|
|
bool XTDInitHandlers()
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Initialize Indicator/Oscillator Handlers ...
|
|
ResetLastError();
|
|
|
|
//
|
|
// XTD Handler ...
|
|
ArraySetAsSeries(xTDBullishBuffer, true);
|
|
ArraySetAsSeries(xTDBearishBuffer, true);
|
|
ArraySetAsSeries(xTDSignalBuffer, true);
|
|
xTDHandler = iCustom(
|
|
_Symbol,
|
|
_Period,
|
|
"x-saherelm.xtd.oscillator",
|
|
//
|
|
// Inputs ...
|
|
xTDLength,
|
|
xTDDrawCrosses,
|
|
xTDBullishArrowCode,
|
|
xTDBullishArrowColor,
|
|
xTDBearishArrowCode,
|
|
xTDBearishArrowColor);
|
|
if (xTDHandler == INVALID_HANDLE)
|
|
{
|
|
//
|
|
LogMessage("failed to Initialize XTD Oscillator: " + (string)GetLastError());
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result = true;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Release Oscillators ...
|
|
void XTDReleaseHandlers()
|
|
{
|
|
IndicatorRelease(xTDHandler);
|
|
}
|
|
|
|
//
|
|
// Handle Reading Buffers ...
|
|
void XTDReadBuffers(
|
|
int xTDItemsPerTick // Number Of Reading Buffer Items Per Tick
|
|
)
|
|
{
|
|
//
|
|
// XTD Bullish Buffer ...
|
|
CopyBuffer(
|
|
xTDHandler,
|
|
X_XTD_BULLISH_POWER_LINE,
|
|
0,
|
|
xTDItemsPerTick,
|
|
xTDBullishBuffer);
|
|
|
|
//
|
|
// XTD Bullish Buffer ...
|
|
CopyBuffer(
|
|
xTDHandler,
|
|
X_XTD_BEARISH_POWER_LINE,
|
|
0,
|
|
xTDItemsPerTick,
|
|
xTDBearishBuffer);
|
|
|
|
//
|
|
// XTD Signal Buffer ...
|
|
CopyBuffer(
|
|
xTDHandler,
|
|
X_XTD_SIGNAL_LINE,
|
|
0,
|
|
xTDItemsPerTick,
|
|
xTDSignalBuffer);
|
|
}
|
|
|
|
//
|
|
// END Handler Funcions ...
|
|
//
|
|
|
|
//
|
|
// START XTD Custom Functions ...
|
|
//
|
|
|
|
//
|
|
// Check Signal Vale ...
|
|
bool XTDIsSignalVale(
|
|
int bar_index, // Specified Index ...
|
|
int length = 10 // Specified Length ...
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
if (
|
|
length <= 0 ||
|
|
bar_index <= 0 ||
|
|
!XTDIsValidBuffersSize(bar_index + length + 1))
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result = IsDecreasing(
|
|
bar_index + length,
|
|
bar_index,
|
|
xTDSignalBuffer
|
|
//
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Check Signal Peak ...
|
|
bool XTDIsSignalPeak(
|
|
int bar_index, // Specified Index ...
|
|
int length = 10 // Specified Length ...
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
if (
|
|
length <= 0 ||
|
|
bar_index <= 0 ||
|
|
!XTDIsValidBuffersSize(bar_index + length + 1))
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Must Decreasing ...
|
|
bool isIncreasing = IsIncreasing(
|
|
bar_index + length,
|
|
bar_index,
|
|
xTDSignalBuffer
|
|
//
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Check Signal Vale ...
|
|
bool XTDIsBullishVale(
|
|
int bar_index, // Specified Index ...
|
|
int length = 10 // Specified Length ...
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
if (
|
|
length <= 0 ||
|
|
bar_index <= 0 ||
|
|
!XTDIsValidBuffersSize(bar_index + length + 1))
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result = IsDecreasing(
|
|
bar_index + length,
|
|
bar_index,
|
|
xTDBullishBuffer
|
|
//
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Check Signal Peak ...
|
|
bool XTDIsBullishPeak(
|
|
int bar_index, // Specified Index ...
|
|
int length = 10 // Specified Length ...
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
if (
|
|
length <= 0 ||
|
|
bar_index <= 0 ||
|
|
!XTDIsValidBuffersSize(bar_index + length + 1))
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Must Decreasing ...
|
|
bool isIncreasing = IsIncreasing(
|
|
bar_index + length,
|
|
bar_index,
|
|
xTDBullishBuffer
|
|
//
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Check Signal Vale ...
|
|
bool XTDIsBearishVale(
|
|
int bar_index, // Specified Index ...
|
|
int length = 10 // Specified Length ...
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
if (
|
|
length <= 0 ||
|
|
bar_index <= 0 ||
|
|
!XTDIsValidBuffersSize(bar_index + length + 1))
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result = IsDecreasing(
|
|
bar_index + length,
|
|
bar_index,
|
|
xTDBearishBuffer
|
|
//
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Check Signal Peak ...
|
|
bool XTDIsBearishPeak(
|
|
int bar_index, // Specified Index ...
|
|
int length = 10 // Specified Length ...
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
if (
|
|
length <= 0 ||
|
|
bar_index <= 0 ||
|
|
!XTDIsValidBuffersSize(bar_index + length + 1))
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Must Decreasing ...
|
|
bool isIncreasing = IsIncreasing(
|
|
bar_index + length,
|
|
bar_index,
|
|
xTDBearishBuffer
|
|
//
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Check Signal Peak ...
|
|
|
|
//
|
|
// Check Bullish Crossed Over Bearish ...
|
|
bool XTDIsBullCrossedOverBear(
|
|
int bar_index // Specified Bar Index
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
if (
|
|
bar_index <= 0 ||
|
|
!XTDIsValidBuffersSize(bar_index + 1))
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result = IsCrossOver(
|
|
xTDBullishBuffer,
|
|
xTDBearishBuffer,
|
|
1);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Check Bullish Over Bearish ...
|
|
bool XTDIsBullOverBear(
|
|
int bar_index // Specified Bar Index
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
if (
|
|
bar_index <= 0 ||
|
|
!XTDIsValidBuffersSize(bar_index + 1))
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result = IsOver(
|
|
xTDBullishBuffer,
|
|
xTDBearishBuffer,
|
|
1);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Check Bullish Crossed Under Bearish ...
|
|
bool XTDIsBullCrossedUnderBear(
|
|
int bar_index // Specified Bar Index
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
if (
|
|
bar_index <= 0 ||
|
|
!XTDIsValidBuffersSize(bar_index + 1))
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result = IsCrossUnder(
|
|
xTDBullishBuffer,
|
|
xTDBearishBuffer,
|
|
1);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Check Bullish Under Bearish ...
|
|
bool XTDIsBullUnderBear(
|
|
int bar_index // Specified Bar Index
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
if (
|
|
bar_index <= 0 ||
|
|
!XTDIsValidBuffersSize(bar_index + 1))
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result = IsUnder(
|
|
xTDBullishBuffer,
|
|
xTDBearishBuffer,
|
|
1);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Check Signal Crossed Over Bearish ...
|
|
bool XTDIsSignalCrossedOverBear(
|
|
int bar_index // Specified Bar Index
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
if (
|
|
bar_index <= 0 ||
|
|
!XTDIsValidBuffersSize(bar_index + 1))
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result = IsCrossOver(
|
|
xTDSignalBuffer,
|
|
xTDBearishBuffer,
|
|
1);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Check Signal Over Bearish ...
|
|
bool XTDIsSignalOverBear(
|
|
int bar_index // Specified Bar Index
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
if (
|
|
bar_index <= 0 ||
|
|
!XTDIsValidBuffersSize(bar_index + 1))
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result = IsOver(
|
|
xTDSignalBuffer,
|
|
xTDBearishBuffer,
|
|
1);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Check Signal Crossed Under Bearish ...
|
|
bool XTDIsSignalCrossedUnderBear(
|
|
int bar_index // Specified Bar Index
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
if (
|
|
bar_index <= 0 ||
|
|
!XTDIsValidBuffersSize(bar_index + 1))
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result = IsCrossUnder(
|
|
xTDSignalBuffer,
|
|
xTDBearishBuffer,
|
|
1);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Check Signal Under Bearish ...
|
|
bool XTDIsSignalUnderBear(
|
|
int bar_index // Specified Bar Index
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
if (
|
|
bar_index <= 0 ||
|
|
!XTDIsValidBuffersSize(bar_index + 1))
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result = IsUnder(
|
|
xTDSignalBuffer,
|
|
xTDBearishBuffer,
|
|
1);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Check all Buffers has valid Size ...
|
|
bool XTDIsValidBuffersSize(
|
|
int size // the size of buffers which min size for requirements
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
if (
|
|
size <= 0 ||
|
|
ArraySize(xTDBullishBuffer) < size ||
|
|
ArraySize(xTDBullishBuffer) < size ||
|
|
ArraySize(xTDSignalBuffer) < size)
|
|
{
|
|
result = false;
|
|
}
|
|
else
|
|
{
|
|
result = true;
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Count Signal Crossed Over Bear ...
|
|
int XTDCountSignalCrossedOverBearIndex(
|
|
int bar_index // Specified Bar Index
|
|
)
|
|
{
|
|
//
|
|
int result = 0;
|
|
|
|
//
|
|
int count = ArraySize(xTDSignalBuffer) - 1;
|
|
if (
|
|
bar_index <= 0 ||
|
|
count <= bar_index + 1)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Loop Through ...
|
|
for (int i = bar_index + 1; i < count && result == -1; i++)
|
|
{
|
|
//
|
|
// Check Cross On i Point ...
|
|
bool isCrossedOnI = XTDIsSignalCrossedOverBear(i);
|
|
if (isCrossedOnI)
|
|
{
|
|
result++;
|
|
}
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Count Signal Crossed Under Bear ...
|
|
int XTDCountSignalCrossedUnderBearIndex(
|
|
int bar_index // Specified Bar Index
|
|
)
|
|
{
|
|
//
|
|
int result = 0;
|
|
|
|
//
|
|
int count = ArraySize(xTDSignalBuffer) - 1;
|
|
if (
|
|
bar_index <= 0 ||
|
|
count <= bar_index + 1)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Loop Through ...
|
|
for (int i = bar_index + 1; i < count && result == -1; i++)
|
|
{
|
|
//
|
|
// Check Cross On i Point ...
|
|
bool isCrossedOnI = XTDIsSignalCrossedUnderBear(i);
|
|
if (isCrossedOnI)
|
|
{
|
|
result++;
|
|
}
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Count Bull Crossed Over Bear ...
|
|
int XTDCountBullCrossedOverBearIndex(
|
|
int bar_index // Specified Bar Index
|
|
)
|
|
{
|
|
//
|
|
int result = 0;
|
|
|
|
//
|
|
int count = ArraySize(xTDSignalBuffer) - 1;
|
|
if (
|
|
bar_index <= 0 ||
|
|
count <= bar_index + 1)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Loop Through ...
|
|
for (int i = bar_index + 1; i < count && result == -1; i++)
|
|
{
|
|
//
|
|
// Check Cross On i Point ...
|
|
bool isCrossedOnI = XTDIsBullCrossedOverBear(i);
|
|
if (isCrossedOnI)
|
|
{
|
|
result++;
|
|
}
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Count Bull Crossed Under Bear ...
|
|
int XTDCountBullCrossedUnderBearIndex(
|
|
int bar_index // Specified Bar Index
|
|
)
|
|
{
|
|
//
|
|
int result = 0;
|
|
|
|
//
|
|
int count = ArraySize(xTDSignalBuffer) - 1;
|
|
if (
|
|
bar_index <= 0 ||
|
|
count <= bar_index + 1)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Loop Through ...
|
|
for (int i = bar_index + 1; i < count && result == -1; i++)
|
|
{
|
|
//
|
|
// Check Cross On i Point ...
|
|
bool isCrossedOnI = XTDIsBullCrossedUnderBear(i);
|
|
if (isCrossedOnI)
|
|
{
|
|
result++;
|
|
}
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Find Last Signal Crossed Over Bear ...
|
|
int XTDFindLastSignalCrossedOverBearIndex(
|
|
int bar_index // Specified Bar Index
|
|
)
|
|
{
|
|
//
|
|
int result = -1;
|
|
|
|
//
|
|
int count = ArraySize(xTDSignalBuffer) - 1;
|
|
if (
|
|
bar_index <= 0 ||
|
|
count <= bar_index + 1)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Loop Through ...
|
|
for (int i = bar_index + 1; i < count && result == -1; i++)
|
|
{
|
|
//
|
|
// Check Cross On i Point ...
|
|
bool isCrossedOnI = XTDIsSignalCrossedOverBear(i);
|
|
if (isCrossedOnI)
|
|
{
|
|
//
|
|
result = i;
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Find Last Signal Crossed Onder Bear ...
|
|
int XTDFindLastSignalCrossedUnderBearIndex(
|
|
int bar_index // Specified Bar Index
|
|
)
|
|
{
|
|
//
|
|
int result = -1;
|
|
|
|
//
|
|
int count = ArraySize(xTDSignalBuffer) - 1;
|
|
if (
|
|
bar_index <= 0 ||
|
|
count <= bar_index + 1)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Loop Through ...
|
|
for (int i = bar_index + 1; i < count && result == -1; i++)
|
|
{
|
|
//
|
|
// Check Cross On i Point ...
|
|
bool isCrossedOnI = XTDIsSignalCrossedUnderBear(i);
|
|
if (isCrossedOnI)
|
|
{
|
|
//
|
|
result = i;
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Find Last Bull Crossed Over Bear ...
|
|
int XTDFindLastBullCrossedOverBearIndex(
|
|
int bar_index // Specified Bar Index
|
|
)
|
|
{
|
|
//
|
|
int result = -1;
|
|
|
|
//
|
|
int count = ArraySize(xTDSignalBuffer) - 1;
|
|
if (
|
|
bar_index <= 0 ||
|
|
count <= bar_index + 1)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Loop Through ...
|
|
for (int i = bar_index + 1; i < count && result == -1; i++)
|
|
{
|
|
//
|
|
// Check Cross On i Point ...
|
|
bool isCrossedOnI = XTDIsBullCrossedOverBear(i);
|
|
if (isCrossedOnI)
|
|
{
|
|
//
|
|
result = i;
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Find Last Bull Crossed Under Bear ...
|
|
int XTDFindLastBullCrossedUnderBearIndex(
|
|
int bar_index // Specified Bar Index
|
|
)
|
|
{
|
|
//
|
|
int result = -1;
|
|
|
|
//
|
|
int count = ArraySize(xTDSignalBuffer) - 1;
|
|
if (
|
|
bar_index <= 0 ||
|
|
count <= bar_index + 1)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Loop Through ...
|
|
for (int i = bar_index + 1; i < count && result == -1; i++)
|
|
{
|
|
//
|
|
// Check Cross On i Point ...
|
|
bool isCrossedOnI = XTDIsBullCrossedUnderBear(i);
|
|
if (isCrossedOnI)
|
|
{
|
|
//
|
|
result = i;
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// END XTD Custom Functions ...
|
|
//
|