736 lines
13 KiB
Plaintext
736 lines
13 KiB
Plaintext
///////////////////////////////////////////////////////
|
|
//
|
|
// SaherElm IT Center MQL5 Class Library
|
|
// ----------------------------------------------
|
|
// Name: XSCRange
|
|
// Description: provides all Range 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"
|
|
#include "../Libraries/x-saherelm.draw.lib.mq5"
|
|
|
|
//
|
|
// Definitions ...
|
|
|
|
//
|
|
struct XSCCFInput
|
|
{
|
|
//
|
|
// Props ...
|
|
|
|
//
|
|
int length; // Minimum of Same Bars
|
|
|
|
//
|
|
color clrUpper; // Upper Color ...
|
|
color clrLower; // Lower Color ...
|
|
|
|
//
|
|
// Constructor ...
|
|
void XSCCFInput()
|
|
{
|
|
Clean();
|
|
}
|
|
|
|
//
|
|
// Tools ...
|
|
|
|
//
|
|
// Cleanup ...
|
|
void Clean()
|
|
{
|
|
//
|
|
length = 0;
|
|
|
|
//
|
|
clrUpper = CLR_NONE;
|
|
clrLower = CLR_NONE;
|
|
}
|
|
|
|
//
|
|
// Defualt Configs ...
|
|
void Default()
|
|
{
|
|
//
|
|
length = 4;
|
|
|
|
//
|
|
clrLower = clrAqua;
|
|
clrUpper = clrMagenta;
|
|
}
|
|
|
|
//
|
|
// Validate ...
|
|
bool IsValid()
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
result =
|
|
//
|
|
length >= 2
|
|
//
|
|
;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
};
|
|
|
|
//
|
|
// Class ...
|
|
|
|
class XSCCF : public XSCBase
|
|
{
|
|
//
|
|
// Public ...
|
|
public:
|
|
//
|
|
// Props ...
|
|
|
|
//
|
|
// Constructor ...
|
|
void XSCCF(
|
|
string symbol,
|
|
ENUM_TIMEFRAMES period //
|
|
) : XSCBase()
|
|
{
|
|
//
|
|
mSymbol = symbol;
|
|
mPeriod = period;
|
|
}
|
|
|
|
//
|
|
// Deconstructor ...
|
|
void ~XSCCF() {}
|
|
|
|
//
|
|
// Initialize ...
|
|
bool Init(XSCCFInput &inputs)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
result = inputs.IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
mInputs = inputs;
|
|
|
|
//
|
|
// Find Bullish Bar ...
|
|
result = FindBullishBar(0);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Find Bearish Bar ...
|
|
result = FindBearishBar(0);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Getter(s) / Setter(s) ...
|
|
|
|
//
|
|
string GetSymbol()
|
|
{
|
|
return mSymbol;
|
|
}
|
|
|
|
//
|
|
ENUM_TIMEFRAMES GetPeriod()
|
|
{
|
|
return mPeriod;
|
|
}
|
|
|
|
//
|
|
XSCCFInput GetInputs()
|
|
{
|
|
return mInputs;
|
|
}
|
|
|
|
//
|
|
bool SetInputs(XSCCFInput &inputs)
|
|
{
|
|
return Init(inputs);
|
|
}
|
|
|
|
//
|
|
XOHCL GetBullishBar()
|
|
{
|
|
return bullishBar;
|
|
}
|
|
|
|
//
|
|
XOHCL GetBearishBar()
|
|
{
|
|
return bearishBar;
|
|
}
|
|
|
|
//
|
|
// Overrides ...
|
|
string GetTag() override
|
|
{
|
|
return "XCF";
|
|
}
|
|
|
|
//
|
|
// Tools ...
|
|
|
|
//
|
|
// Validate ...
|
|
bool IsValid()
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
result =
|
|
//
|
|
bullishBar.IsValid() &&
|
|
bearishBar.IsValid()
|
|
//
|
|
;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Retrieve Title Prefix ...
|
|
string GetIdentifier()
|
|
{
|
|
//
|
|
string result = NULL;
|
|
|
|
//
|
|
if (!IsValid())
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result = GetTag() + "_" +
|
|
mSymbol + "_" +
|
|
ToString(mPeriod) + "_" +
|
|
ToFormatString(bullishBar.time) + "_";
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Remove Draws ...
|
|
bool Remove(
|
|
long chartId = 0,
|
|
int subWindow = 0 //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
string prefix = GetIdentifier();
|
|
result = IsSpecifiedValid(prefix);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
RemoveDraws(
|
|
prefix,
|
|
chartId,
|
|
subWindow //
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
bool Draw(
|
|
long chartId = 0,
|
|
string prefix = NULL,
|
|
int subWindow = 0,
|
|
string upperPrefix = "Upper",
|
|
string lowerPrefix = "Lower" //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result = DrawBullishBar(
|
|
chartId,
|
|
prefix,
|
|
subWindow,
|
|
upperPrefix,
|
|
lowerPrefix //
|
|
);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result = DrawBearishBar(
|
|
chartId,
|
|
prefix,
|
|
subWindow,
|
|
upperPrefix,
|
|
lowerPrefix //
|
|
);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Protected ...
|
|
protected:
|
|
//
|
|
// Tools ...
|
|
|
|
//
|
|
bool FindBullishBar(
|
|
int barIndex //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
int next = barIndex + 1;
|
|
|
|
//
|
|
int totalBars = iBars(
|
|
mSymbol,
|
|
mPeriod //
|
|
);
|
|
result = barIndex >= 0 && barIndex + 1 + mInputs.length < totalBars;
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
bool isNextValid = next >= 0 && next + 1 + mInputs.length < totalBars;
|
|
|
|
//
|
|
int bullBarIndex = barIndex + 1;
|
|
int start = bullBarIndex + 1;
|
|
int end = start + mInputs.length;
|
|
|
|
//
|
|
XOHCL startBar;
|
|
result = startBar.Init(
|
|
mSymbol,
|
|
mPeriod,
|
|
bullBarIndex //
|
|
);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result = startBar.IsBullish();
|
|
if (!result)
|
|
{
|
|
if (isNextValid)
|
|
{
|
|
return FindBullishBar(next);
|
|
}
|
|
else
|
|
{
|
|
return result;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Loop Back to Find Bearish Bars ...
|
|
for (int i = start; i < end; i++)
|
|
{
|
|
//
|
|
XOHCL iBar;
|
|
result = iBar.Init(
|
|
mSymbol,
|
|
mPeriod,
|
|
i //
|
|
);
|
|
if (!result || !iBar.IsBearish())
|
|
{
|
|
//
|
|
if (isNextValid)
|
|
{
|
|
return FindBullishBar(next);
|
|
}
|
|
else
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
if (result)
|
|
{
|
|
bullishBar = startBar;
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
bool FindBearishBar(
|
|
int barIndex //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
int next = barIndex + 1;
|
|
|
|
//
|
|
int totalBars = iBars(
|
|
mSymbol,
|
|
mPeriod //
|
|
);
|
|
result = barIndex >= 0 && barIndex + 1 + mInputs.length < totalBars;
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
bool isNextValid = next >= 0 && next + 1 + mInputs.length < totalBars;
|
|
|
|
//
|
|
int bearBarIndex = barIndex + 1;
|
|
int start = bearBarIndex + 1;
|
|
int end = start + mInputs.length;
|
|
|
|
//
|
|
XOHCL startBar;
|
|
result = startBar.Init(
|
|
mSymbol,
|
|
mPeriod,
|
|
bearBarIndex //
|
|
);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result = startBar.IsBearish();
|
|
if (!result)
|
|
{
|
|
if (isNextValid)
|
|
{
|
|
return FindBearishBar(next);
|
|
}
|
|
else
|
|
{
|
|
return result;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Loop Back to Find Bearish Bars ...
|
|
for (int i = start; i < end; i++)
|
|
{
|
|
//
|
|
XOHCL iBar;
|
|
result = iBar.Init(
|
|
mSymbol,
|
|
mPeriod,
|
|
i //
|
|
);
|
|
if (!result || !iBar.IsBullish())
|
|
{
|
|
//
|
|
if (isNextValid)
|
|
{
|
|
return FindBearishBar(next);
|
|
}
|
|
else
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
if (result)
|
|
{
|
|
bearishBar = startBar;
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
bool DrawBullishBar(
|
|
long chartId = 0,
|
|
string prefix = NULL,
|
|
int subWindow = 0,
|
|
string upperPrefix = "Upper",
|
|
string lowerPrefix = "Lower" //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
result = bullishBar.IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
if (!IsSpecifiedValid(upperPrefix))
|
|
{
|
|
upperPrefix = "High";
|
|
}
|
|
|
|
//
|
|
if (!IsSpecifiedValid(lowerPrefix))
|
|
{
|
|
lowerPrefix = "Low";
|
|
}
|
|
|
|
//
|
|
datetime cTime = TimeCurrent();
|
|
|
|
//
|
|
string identifier = GetIdentifier();
|
|
|
|
//
|
|
// High Line ...
|
|
string bullishHighLineName =
|
|
(IsSpecifiedValid(prefix)
|
|
? prefix + "_"
|
|
: "") +
|
|
identifier + "_" +
|
|
"BULL_" +
|
|
upperPrefix;
|
|
|
|
//
|
|
result = DrawTrendLine(
|
|
chartId,
|
|
bullishHighLineName,
|
|
subWindow,
|
|
bullishBar.time,
|
|
bullishBar.high,
|
|
cTime,
|
|
bullishBar.high,
|
|
mInputs.clrUpper,
|
|
STYLE_SOLID,
|
|
2,
|
|
false,
|
|
false,
|
|
true // Ray Right ...
|
|
);
|
|
|
|
//
|
|
// Low Line ...
|
|
string bullishLowLineName =
|
|
(IsSpecifiedValid(prefix)
|
|
? prefix + "_"
|
|
: "") +
|
|
identifier + "_" +
|
|
"BULL_" +
|
|
lowerPrefix;
|
|
|
|
//
|
|
result = DrawTrendLine(
|
|
chartId,
|
|
bullishLowLineName,
|
|
subWindow,
|
|
bullishBar.time,
|
|
bullishBar.low,
|
|
cTime,
|
|
bullishBar.low,
|
|
mInputs.clrLower,
|
|
STYLE_SOLID,
|
|
2,
|
|
false,
|
|
false,
|
|
true // Ray Right ...
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
bool DrawBearishBar(
|
|
long chartId = 0,
|
|
string prefix = NULL,
|
|
int subWindow = 0,
|
|
string upperPrefix = "Upper",
|
|
string lowerPrefix = "Lower" //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
result = bearishBar.IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
if (!IsSpecifiedValid(upperPrefix))
|
|
{
|
|
upperPrefix = "High";
|
|
}
|
|
|
|
//
|
|
if (!IsSpecifiedValid(lowerPrefix))
|
|
{
|
|
lowerPrefix = "Low";
|
|
}
|
|
|
|
//
|
|
datetime cTime = TimeCurrent();
|
|
|
|
//
|
|
string identifier = GetIdentifier();
|
|
|
|
//
|
|
// High Line ...
|
|
string bearishHighLineName =
|
|
(IsSpecifiedValid(prefix)
|
|
? prefix + "_"
|
|
: "") +
|
|
identifier + "_" +
|
|
"BEAR_" +
|
|
upperPrefix;
|
|
|
|
//
|
|
result = DrawTrendLine(
|
|
chartId,
|
|
bearishHighLineName,
|
|
subWindow,
|
|
bearishBar.time,
|
|
bearishBar.high,
|
|
cTime,
|
|
bearishBar.high,
|
|
mInputs.clrUpper,
|
|
STYLE_SOLID,
|
|
2,
|
|
false,
|
|
false,
|
|
true // Ray Right ...
|
|
);
|
|
|
|
//
|
|
// Low Line ...
|
|
string bearishLowLineName =
|
|
(IsSpecifiedValid(prefix)
|
|
? prefix + "_"
|
|
: "") +
|
|
identifier + "_" +
|
|
"BEAR_" +
|
|
lowerPrefix;
|
|
|
|
//
|
|
result = DrawTrendLine(
|
|
chartId,
|
|
bearishLowLineName,
|
|
subWindow,
|
|
bearishBar.time,
|
|
bearishBar.low,
|
|
cTime,
|
|
bearishBar.low,
|
|
mInputs.clrLower,
|
|
STYLE_SOLID,
|
|
2,
|
|
false,
|
|
false,
|
|
true // Ray Right ...
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Private ...
|
|
private:
|
|
//
|
|
// Props ...
|
|
string mSymbol; // Trading Symbol ...
|
|
ENUM_TIMEFRAMES mPeriod; // Trading Period ...
|
|
|
|
//
|
|
XOHCL bearishBar; // Bearish Order Block Bar
|
|
XOHCL bullishBar; // Bullish Order Block Bar
|
|
|
|
//
|
|
XSCCFInput mInputs; // Configs ...
|
|
};
|
|
|
|
// |