Files
xMQL5/BKPS/14030412/Documents/BKP/Old/x-saherelm.xmatd.helper.mq5
T
2024-07-02 17:37:21 +03:30

1046 lines
22 KiB
Plaintext

///////////////////////////////////////////////////////
//
// SaherElm IT Center MQL5 Class Library
// ----------------------------------------------
// Name: XMATD
// Description: provides Indicator implementation
// requirements ...
//
//
// 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"
//
// Indicator Buffers ...
enum ENUM_XMATD_BUFFERS
{
XMATD_FAST_LINE = 0, // Fast Buffer ...
XMATD_MID_LINE = 1, // Mid Buffer ...
XMATD_SLOW_LINE = 2, // Slow Buffer ...
XMATD_PSAR_LINE = 3, // Parabolic Buffer ...
};
//
string GetTitle(ENUM_XMATD_BUFFERS bufferLine)
{
//
string result = NULL;
//
switch (bufferLine)
{
//
case XMATD_FAST_LINE:
result = "XFats";
break;
//
case XMATD_MID_LINE:
result = "XMid";
break;
//
case XMATD_SLOW_LINE:
result = "XSlow";
break;
}
//
return result;
}
//
// XMATD Indicator Inputs ...
struct XMATDInputs
{
//
// Props ...
string version;
//
// Market ...
//
int fastLength; // Fast Length
int midLength; // Mid Length
int slowLength; // Slow Length
//
double step; // Sar Step
double maximum; // Sar Maximum
//
// Calculation Mode ...
//
int shift; // Shift
ENUM_MA_METHOD method; // Method of MA
ENUM_APPLIED_PRICE appliedTo; // Applied To
//
// Constructor ...
XMATDInputs()
{
Clean();
}
//
// Tools ...
//
// Initial Inputs ...
bool Init(
int _fastLength = 21, // Fast Length
int _midLength = 50, // Mid Length
int _slowLength = 200, // Slow Length
ENUM_MA_METHOD _method = MODE_SMA, // Shift
ENUM_APPLIED_PRICE _appliedTo = PRICE_CLOSE, // Method of MA
int _shift = 0 // Applied To
)
{
//
bool result = false;
//
this.fastLength = _fastLength;
this.midLength = _midLength;
this.slowLength = _slowLength;
//
this.shift = _shift;
this.method = _method;
this.appliedTo = _appliedTo;
//
result = IsValid();
//
return result;
}
//
// Cleanup ...
void Clean()
{
//
fastLength = 0;
midLength = 0;
slowLength = 0;
//
shift = 0;
//
step = 0;
maximum = 0;
//
method = MODE_SMA;
appliedTo = PRICE_CLOSE;
}
//
// Default ...
void Default()
{
//
fastLength = 21;
midLength = 50;
slowLength = 200;
//
method = MODE_SMA;
appliedTo = PRICE_CLOSE;
//
step = 0.02;
maximum = 0.2;
}
//
// Validate ...
bool IsValid()
{
//
bool result = false;
//
result =
//
fastLength > 0 &&
midLength > fastLength &&
slowLength > midLength
//
&&
//
step > 0 &&
maximum > step
//
;
//
return result;
}
//
// Retrieve Max Length ...
int Max()
{
//
int result = 0;
//
int values[3] = {
fastLength,
midLength,
slowLength //
};
//
result = GetMax(values);
//
return result;
}
};
//
// Define Conditions ...
struct XMATDConditions
{
//
// Common ...
string symbol;
ENUM_TIMEFRAMES period;
datetime time;
//
// Buffers ...
double fast[];
double mid[];
double slow[];
//
double psar[];
//
// Conditions ...
//
// Trend ...
bool isBullish;
bool isBearish;
bool isSwitchedToBullish;
bool isSwitchedToBearish;
//
// Fast Mid ...
bool isFastOverMid;
bool isFastUnderMid;
bool isFastCrossedOverMid;
bool isFastCrossedUnderMid;
//
// Fast Slow ...
bool isFastOverSlow;
bool isFastUnderSlow;
bool isFastCrossedOverSlow;
bool isFastCrossedUnderSlow;
//
// Mid Slow ...
bool isMidOverSlow;
bool isMidUnderSlow;
bool isMidCrossedOverSlow;
bool isMidCrossedUnderSlow;
//
bool isSARBullish;
bool isSARBearish;
bool isSARSwitchedToBullish;
bool isSARSwitchedToBearish;
//
void Clean()
{
//
Clean(fast);
Clean(mid);
Clean(slow);
Clean(psar);
//
ArraySetAsSeries(fast, true);
ArraySetAsSeries(mid, true);
ArraySetAsSeries(slow, true);
ArraySetAsSeries(psar, true);
//
// Trend ...
isBullish = false;
isBearish = false;
isSwitchedToBullish = false;
isSwitchedToBearish = false;
//
// Fast Mid ...
isFastOverMid = false;
isFastUnderMid = false;
isFastCrossedOverMid = false;
isFastCrossedUnderMid = false;
//
// Fast Slow ...
isFastOverSlow = false;
isFastUnderSlow = false;
isFastCrossedOverSlow = false;
isFastCrossedUnderSlow = false;
//
// Mid Slow ...
isMidOverSlow = false;
isMidUnderSlow = false;
isMidCrossedOverSlow = false;
isMidCrossedUnderSlow = false;
//
isSARBullish = false;
isSARBearish = false;
isSARSwitchedToBullish = false;
isSARSwitchedToBearish = false;
}
//
void GenerateScore(
double &bullishScore,
double &bearishScore //
)
{
//
bullishScore = 0;
bearishScore = 0;
//
// Trend ...
//
if (isBullish)
{
bullishScore++;
}
if (isSwitchedToBullish)
{
bullishScore++;
}
//
if (isBearish)
{
bearishScore++;
}
if (isSwitchedToBearish)
{
bearishScore++;
}
//
// Fast Mid ...
//
if (isFastOverMid)
{
bullishScore++;
}
if (isFastCrossedOverMid)
{
bullishScore++;
}
//
if (isFastUnderMid)
{
bearishScore++;
}
if (isFastCrossedUnderMid)
{
bearishScore++;
}
//
// Fast Slow ...
//
if (isFastOverSlow)
{
bullishScore++;
}
if (isFastCrossedOverSlow)
{
bullishScore++;
}
//
if (isFastUnderSlow)
{
bearishScore++;
}
if (isFastCrossedUnderSlow)
{
bearishScore++;
}
//
// Mid Slow ...
//
if (isMidOverSlow)
{
bullishScore++;
}
if (isMidCrossedOverSlow)
{
bullishScore++;
}
//
if (isMidUnderSlow)
{
bearishScore++;
}
if (isMidCrossedUnderSlow)
{
bearishScore++;
}
//
if (isSARBullish)
{
bullishScore++;
}
if (isSARSwitchedToBullish)
{
bullishScore++;
}
//
if (isSARBearish)
{
bearishScore++;
}
if (isSARSwitchedToBearish)
{
bearishScore++;
}
}
//
string GenerateSummary(
bool onlyCommons = false,
bool onlyConditions = false,
bool includeScores = true,
bool ignoreFalseConditions = true,
string separator = "\n" //
)
{
//
string result = NULL;
//
double bullishScore = 0;
double bearishScore = 0;
GenerateScore(
bullishScore,
bearishScore //
);
//
string scoresStr =
//
"Scores: " + separator +
"---------------" + separator +
"Bullish: " + ToString(bullishScore) + separator +
"Bearish: " + ToString(bearishScore) + separator +
""
//
;
//
string commonStr = GenerateSpecifiedCommonSummary(
this,
separator,
includeScores //
);
//
string conditionsStr =
//
// Trend ...
ToString("isBullish", isBullish, ignoreFalseConditions, separator) +
ToString("isBearish", isBearish, ignoreFalseConditions, separator) +
ToString("isSwitchedToBullish", isSwitchedToBullish, ignoreFalseConditions, separator) +
ToString("isSwitchedToBearish", isSwitchedToBearish, ignoreFalseConditions, separator) +
//
// Fast Mid ...
ToString("isFastOverMid", isFastOverMid, ignoreFalseConditions, separator) +
ToString("isFastUnderMid", isFastUnderMid, ignoreFalseConditions, separator) +
ToString("isFastCrossedOverMid", isFastCrossedOverMid, ignoreFalseConditions, separator) +
ToString("isFastCrossedUnderMid", isFastCrossedUnderMid, ignoreFalseConditions, separator) +
//
// Fast Slow ...
ToString("isFastOverSlow", isFastOverSlow, ignoreFalseConditions, separator) +
ToString("isFastUnderSlow", isFastUnderSlow, ignoreFalseConditions, separator) +
ToString("isFastCrossedOverSlow", isFastCrossedOverSlow, ignoreFalseConditions, separator) +
ToString("isFastCrossedUnderSlow", isFastCrossedUnderSlow, ignoreFalseConditions, separator) +
//
// Mid Slow ...
ToString("isMidOverSlow", isMidOverSlow, ignoreFalseConditions, separator) +
ToString("isMidUnderSlow", isMidUnderSlow, ignoreFalseConditions, separator) +
ToString("isMidCrossedOverSlow", isMidCrossedOverSlow, ignoreFalseConditions, separator) +
ToString("isMidCrossedUnderSlow", isMidCrossedUnderSlow, ignoreFalseConditions, separator) +
//
// Psar ...
ToString("isSARBullish", isSARBullish, ignoreFalseConditions, separator) +
ToString("isSARBearish", isSARBearish, ignoreFalseConditions, separator) +
ToString("isSARSwitchedToBullish", isSARSwitchedToBullish, ignoreFalseConditions, separator) +
ToString("isSARSwitchedToBearish", isSARSwitchedToBearish, ignoreFalseConditions, separator) +
//
""
//
;
//
result =
//
"[" + GetTag() + "]" + separator +
(onlyConditions
? ""
: commonStr) +
(!includeScores
? ""
: scoresStr) +
" " + separator +
(onlyCommons
? ""
: conditionsStr) +
""
//
;
//
return result;
}
//
string GetTag()
{
return "XMATD";
}
};
//
// Indicator Class ...
class XSCXMATDHelper : public XSCBase
{
//
// Public ...
public:
//
// Props ...
//
// Constructor(s) ...
void XSCXMATDHelper(
string symbol, // Trading Symbol
ENUM_TIMEFRAMES period // Trading TimeFrame
)
{
//
mSymbol = symbol;
mPeriod = period;
}
//
// Deconstructor ...
void ~XSCXMATDHelper() {}
//
// Initialize Indicator ...
bool Init(
XMATDInputs &inputs // Indicator Properties
)
{
//
bool result = false;
//
result = inputs.IsValid();
if (!result)
{
return result;
}
//
// Set Inputs ...
this.mInputs = inputs;
//
// Validate Indicator State ...
result = this.IsValid();
if (!result)
{
return result;
}
//
result = DefineBuffers();
if (!result)
{
return result;
}
//
fastHandler = iMA(
mSymbol,
mPeriod,
mInputs.fastLength,
mInputs.shift,
mInputs.method,
mInputs.appliedTo //
);
midHandler = iMA(
mSymbol,
mPeriod,
mInputs.midLength,
mInputs.shift,
mInputs.method,
mInputs.appliedTo //
);
slowHandler = iMA(
mSymbol,
mPeriod,
mInputs.slowLength,
mInputs.shift,
mInputs.method,
mInputs.appliedTo //
);
result =
//
fastHandler != INVALID_HANDLE &&
midHandler != INVALID_HANDLE &&
slowHandler != INVALID_HANDLE
//
;
if (!result)
{
return result;
}
//
sarHandler = iSAR(
_Symbol,
_Period,
mInputs.step,
mInputs.maximum //
);
result = sarHandler != INVALID_HANDLE;
//
return result;
}
//
XMATDInputs GetInputs()
{
return mInputs;
}
//
bool SetInputs(
XMATDInputs &inputs // Indicator Properties
)
{
return Init(inputs);
}
//
// Get Tag ...
string GetTag()
{
//
string result = NULL;
//
result = GetToken();
//
return result;
}
//
// Get Token ...
string GetToken()
{
//
string result = NULL;
//
result = GetSpecificToken(this);
//
return result;
}
//
string GetSymbol()
{
return mSymbol;
}
//
ENUM_TIMEFRAMES GetPeriod()
{
return mPeriod;
}
//
// Validate ...
bool IsValid()
{
//
bool result = false;
//
result =
//
mInputs.IsValid() &&
IsSpecifiedValid(mPeriod) &&
IsSpecifiedValid(mSymbol)
//
;
//
return result;
}
//
// De Initialize Class ...
void DeInit(int reason)
{
//
IndicatorRelease(fastHandler);
IndicatorRelease(midHandler);
IndicatorRelease(slowHandler);
}
//
// Tools ...
int CopyData(
ENUM_XMATD_BUFFERS line,
double &dest[],
int start = 0,
int count = 1 //
)
{
//
int result = 0;
//
int mHandler = INVALID_HANDLE;
switch (line)
{
//
case XMATD_FAST_LINE:
mHandler = fastHandler;
break;
//
case XMATD_MID_LINE:
mHandler = midHandler;
break;
//
case XMATD_SLOW_LINE:
mHandler = slowHandler;
break;
//
case XMATD_PSAR_LINE:
mHandler = sarHandler;
break;
}
//
if (mHandler == INVALID_HANDLE)
{
return result;
}
//
result = CopyBuffer(
mHandler,
0,
start,
count,
dest //
);
//
return result;
}
//
bool GetConditions(
XMATDConditions &conditions, //
int barIndex = 0, //
int loopback = 3 //
)
{
//
bool result = true;
//
if (loopback < 3)
{
loopback = 3;
}
//
conditions.Clean();
//
conditions.symbol = mSymbol;
conditions.period = mPeriod;
conditions.time = TimeCurrent();
//
int zIndex = barIndex;
int cIndex = zIndex + 1;
int pIndex = cIndex + 1;
int ppIndex = pIndex + 1;
//
CopyData(
XMATD_FAST_LINE,
conditions.fast,
zIndex,
loopback //
);
CopyData(
XMATD_MID_LINE,
conditions.mid,
zIndex,
loopback //
);
CopyData(
XMATD_SLOW_LINE,
conditions.slow,
zIndex,
loopback //
);
//
// Calculate Conditions ...
//
// Trend ...
//
bool isBullish = conditions.fast[cIndex] > conditions.mid[cIndex] &&
conditions.mid[cIndex] > conditions.slow[cIndex];
bool isBearish = conditions.fast[cIndex] < conditions.mid[cIndex] &&
conditions.mid[cIndex] < conditions.slow[cIndex];
//
bool isBullishPrev = conditions.fast[pIndex] > conditions.mid[pIndex] &&
conditions.mid[pIndex] > conditions.slow[pIndex];
bool isBearishPrev = conditions.fast[pIndex] < conditions.mid[pIndex] &&
conditions.mid[pIndex] < conditions.slow[pIndex];
//
bool isSwitchedToBullish = isBullish &&
!isBullishPrev;
bool isSwitchedToBearish = isBearish &&
!isBearishPrev;
//
// Set Conditions to Structure ...
conditions.isBullish = isBullish;
conditions.isBearish = isBearish;
conditions.isSwitchedToBullish = isSwitchedToBullish;
conditions.isSwitchedToBearish = isSwitchedToBearish;
//
// Fast Mid ...
//
bool isFastOverMid = conditions.fast[cIndex] > conditions.mid[cIndex];
bool isFastUnderMid = conditions.fast[cIndex] < conditions.mid[cIndex];
//
bool isFastOverMidPrev = conditions.fast[pIndex] > conditions.mid[pIndex];
bool isFastUnderMidPrev = conditions.fast[pIndex] < conditions.mid[pIndex];
//
bool isFastCrossedOverMid = isFastOverMid &&
!isFastOverMidPrev;
bool isFastCrossedUnderMid = isFastUnderMid &&
!isFastUnderMidPrev;
//
conditions.isFastOverMid = isFastOverMid;
conditions.isFastUnderMid = isFastUnderMid;
conditions.isFastCrossedOverMid = isFastCrossedOverMid;
conditions.isFastCrossedUnderMid = isFastCrossedUnderMid;
//
// Fast Slow ...
//
bool isFastOverSlow = conditions.fast[cIndex] > conditions.slow[cIndex];
bool isFastUnderSlow = conditions.fast[cIndex] < conditions.slow[cIndex];
//
bool isFastOverSlowPrev = conditions.fast[pIndex] > conditions.slow[pIndex];
bool isFastUnderSlowPrev = conditions.fast[pIndex] < conditions.slow[pIndex];
//
bool isFastCrossedOverSlow = isFastOverSlow &&
!isFastOverSlowPrev;
bool isFastCrossedUnderSlow = isFastUnderSlow &&
!isFastUnderSlowPrev;
//
conditions.isFastOverSlow = isFastOverSlow;
conditions.isFastUnderSlow = isFastUnderSlow;
conditions.isFastCrossedOverSlow = isFastCrossedOverSlow;
conditions.isFastCrossedUnderSlow = isFastCrossedUnderSlow;
//
// Mid Slow ...
//
bool isMidOverSlow = conditions.mid[cIndex] > conditions.slow[cIndex];
bool isMidUnderSlow = conditions.mid[cIndex] < conditions.slow[cIndex];
//
bool isMidOverSlowPrev = conditions.mid[pIndex] > conditions.slow[pIndex];
bool isMidUnderSlowPrev = conditions.mid[pIndex] < conditions.slow[pIndex];
//
bool isMidCrossedOverSlow = isMidOverSlow &&
!isMidOverSlowPrev;
bool isMidCrossedUnderSlow = isMidUnderSlow &&
!isMidUnderSlowPrev;
//
conditions.isMidOverSlow = isMidOverSlow;
conditions.isMidUnderSlow = isMidUnderSlow;
conditions.isMidCrossedOverSlow = isMidCrossedOverSlow;
conditions.isMidCrossedUnderSlow = isMidCrossedUnderSlow;
//
// PSar ...
//
CopyData(
XMATD_PSAR_LINE,
conditions.psar,
zIndex,
loopback //
);
//
XOHCL cBar;
cBar.Init(
mSymbol,
mPeriod,
cIndex //
);
//
XOHCL pBar;
pBar.Init(
mSymbol,
mPeriod,
pIndex //
);
//
bool isSARBullish = conditions.psar[cIndex] < cBar.low;
bool isSARBearish = conditions.psar[cIndex] > cBar.high;
//
bool isSARBullishPrev = conditions.psar[pIndex] < pBar.low;
bool isSARBearishPrev = conditions.psar[pIndex] > pBar.high;
//
bool isSARSwitchedToBullish = isSARBullish &&
!isSARBullishPrev;
bool isSARSwitchedToBearish = isSARBearish &&
!isSARBearishPrev;
//
conditions.isSARBullish = isSARBullish;
conditions.isSARBearish = isSARBearish;
conditions.isSARSwitchedToBullish = isSARSwitchedToBullish;
conditions.isSARSwitchedToBearish = isSARSwitchedToBearish;
//
return result;
}
//
// Protected ...
protected:
//
// Props ...
int fastHandler;
int midHandler;
int slowHandler;
//
int sarHandler;
//
// Tools ...
bool DefineBuffers()
{
//
bool result = false;
//
result = true;
//
return result;
}
//
// Private ...
private:
//
// Props ...
//
string mSymbol; // Symbol
ENUM_TIMEFRAMES mPeriod; // TimeFrame
//
XMATDInputs mInputs; // Properties
};
//