Files
xMQL5/BKPS/14030513/Libraries/x-saherelm.common.lib.mq5
T
2024-08-04 12:09:42 +03:30

11336 lines
201 KiB
Plaintext

///////////////////////////////////////////////////////
//
// SaherElm IT Center MQL5 Common Library
// --------------------------------------
// Name: XCommonLib
// Description: provide all commonly used functions ...
//
//
// 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.xmd5.class.mq5"
//
// Models ...
//
// Specified Price Type ...
enum ENUM_X_PRICE
{
X_PRICE_HIGH,
X_PRICE_OPEN,
X_PRICE_CLOSE,
X_PRICE_LOW
};
//
// Swing Types Enum ...
enum ENUM_X_SWING_TYPE
{
X_NO_SWING = 0,
X_SWING_HIGH = 1,
X_SWING_LOW = -1,
};
//
ENUM_SERIESMODE ToSeriesMode(ENUM_X_SWING_TYPE value)
{
//
ENUM_SERIESMODE result = MODE_HIGH;
//
switch (value)
{
//
case X_SWING_HIGH:
result = MODE_HIGH;
break;
//
case X_SWING_LOW:
result = MODE_LOW;
break;
}
//
return result;
}
//
// Find Swing Points ...
int FindSwing(
string mSymbol, // Trading Symbol ...
ENUM_TIMEFRAMES mPeriod, // Trading Period ...
ENUM_X_SWING_TYPE mMode, // Swing Based On Price mode ...
int mLength, // Loopback ...
int bar_index // BarIndex ...
)
{
//
int result = -1;
//
if (StringLen(mSymbol) == 0 || (mMode != X_SWING_HIGH && mMode != X_SWING_LOW))
{
return result;
}
//
int current = bar_index;
int founded = FindNextSwing(
mSymbol,
mPeriod,
mMode,
(mLength * 2) + 1,
current - mLength);
//
while (founded != current)
{
//
current = FindNextSwing(
mSymbol,
mPeriod,
mMode,
mLength,
current + 1);
//
founded = FindNextSwing(
mSymbol,
mPeriod,
mMode,
(mLength * 2) + 1,
current - mLength);
}
//
result = current;
//
return result;
}
//
// Find Next Swing ...
int FindNextSwing(
string mSymbol, // Trading Symbol ...
ENUM_TIMEFRAMES mPeriod, // Trading Period ...
ENUM_X_SWING_TYPE mMode, // Swing Based On Price mode ...
int mLength, // Loopback ...
int bar_index // BarIndex ...
)
{
//
int result = -1;
//
if (bar_index < 0)
{
mLength += bar_index;
bar_index = 0;
}
//
ENUM_SERIESMODE mSeriesMode = ToSeriesMode(mMode);
//
result = mMode == X_SWING_HIGH
? iHighest(
mSymbol,
mPeriod,
mSeriesMode,
mLength,
bar_index)
: iLowest(
mSymbol,
mPeriod,
mSeriesMode,
mLength,
bar_index);
//
return result;
}
//
// XPERIOD Calculation Method ...
enum ENUM_X_PERIOD_METHOD
{
//
X_PERIOD_NOTHING, // Nothing
X_PERIOD_AUTO, // Auto Select
X_PERIOD_MANUALLY // Manually
};
//
// Available Market Cycles ...
enum ENUM_X_MARKET_CYCLES
{
//
X_MARKET_CYCLE_UNKNOWN, // Unknown Cycle
X_MARKET_CYCLE_SHORT, // Short Cycle
X_MARKET_CYCLE_MEDIUM, // Medium Cycle
X_MARKET_CYCLE_LONG, // Long Cycle
X_MARKET_CYCLE_HIND, // Hind Cycle
};
//
// Structs ...
//
// Model a Bar Remains Time ...
struct XBarRemainsTime
{
//
int days;
int hours;
int minutes;
int seconds;
//
// Constructor ...
XBarRemainsTime()
{
Clean();
}
//
// Always Calculate Current 0 Bar Timing ...
bool Init(
string mSymbol = NULL, // Trading Symbol
ENUM_TIMEFRAMES mPeriod = NULL // Trading Period
)
{
//
bool result = false;
//
mSymbol = NormalizeSymbol(mSymbol);
mPeriod = NormalizePeriod(mPeriod);
//
int minuteSecoonds = 60;
int hourSeconds = minuteSecoonds * 60;
int daySeconds = 24 * hourSeconds;
//
int periodSeconds = PeriodSeconds(
mPeriod);
datetime startTime = GetBarTime(
mSymbol,
mPeriod,
0
//
);
//
int secondsDiff = (int)startTime + periodSeconds - (int)TimeCurrent();
//
int mWorkingSecondsDiff = secondsDiff;
if (mWorkingSecondsDiff > daySeconds)
{
//
days = mWorkingSecondsDiff / daySeconds;
mWorkingSecondsDiff -= days * daySeconds;
}
if (mWorkingSecondsDiff > hourSeconds)
{
//
hours = mWorkingSecondsDiff / hourSeconds;
mWorkingSecondsDiff -= hours * hourSeconds;
}
if (mWorkingSecondsDiff > minuteSecoonds)
{
//
minutes = mWorkingSecondsDiff / minuteSecoonds;
mWorkingSecondsDiff -= minutes * minuteSecoonds;
}
seconds = mWorkingSecondsDiff;
//
result = true;
//
return result;
}
//
// Tools ...
//
// Cleanup ...
void Clean()
{
days = 0;
hours = 0;
minutes = 0;
seconds = 0;
}
//
// To String Representation ...
string ToString(
string dayId = "d",
string hourId = "h",
string minuteId = "m",
string secondId = "s",
string idSeparator = ": ",
string separator = ", ",
bool ignoreZeroValues = true
//
)
{
//
string result = "";
//
// Days ...
if (!ignoreZeroValues || days > 0)
{
result += dayId + idSeparator + (string)days + separator;
}
//
// Hours ...
if (!ignoreZeroValues || hours > 0)
{
//
string strHour = ToString(hours);
if (StringLen(strHour) == 1)
{
strHour = "0" + strHour;
}
//
result += hourId + idSeparator + strHour + separator;
}
//
// Minutes ...
if (!ignoreZeroValues || minutes > 0)
{
//
string strMinute = ToString(minutes);
if (StringLen(strMinute) == 1)
{
strMinute = "0" + strMinute;
}
//
result += minuteId + idSeparator + strMinute + separator;
}
//
// Seconds ...
if (!ignoreZeroValues || seconds > 0)
{
//
string strSec = ToString(seconds);
if (StringLen(strSec) == 1)
{
strSec = "0" + strSec;
}
//
result += secondId + idSeparator + strSec;
}
//
return result;
}
};
//
// Describe an Specific Candle ...
struct XOHCL
{
//
// Props ...
//
double high;
double open;
double close;
double low;
//
string symbol;
datetime time;
ENUM_TIMEFRAMES period;
//
// Constructor ...
XOHCL()
{
Clean();
}
//
// Init a Bar ...
// Using Bar Index ...
bool Init(
string mSymbol = NULL, // Trading Symbol
ENUM_TIMEFRAMES mPeriod = NULL, // Trading Period
int barIndex = 0 // Bar Index
)
{
//
mSymbol = NormalizeSymbol(mSymbol);
mPeriod = NormalizePeriod(mPeriod);
//
symbol = mSymbol;
period = mPeriod;
//
time = iTime(
mSymbol,
mPeriod,
barIndex
//
);
//
open = iOpen(
mSymbol,
mPeriod,
barIndex
//
);
//
close = iClose(
mSymbol,
mPeriod,
barIndex
//
);
//
high = iHigh(
mSymbol,
mPeriod,
barIndex);
//
low = iLow(
mSymbol,
mPeriod,
barIndex
//
);
//
bool result = IsValid();
//
return result;
}
//
// Init a Bar ...
// Using Bar Time ...
bool Init(
string mSymbol = NULL, // Trading Symbol
ENUM_TIMEFRAMES mPeriod = NULL, // Trading Period
datetime mTime = NULL // Bar Time
)
{
//
mTime = NormalizeTime(mTime);
//
int barIndex = iBarShift(
mSymbol,
mPeriod,
mTime,
false //
);
//
bool result = Init(
mSymbol,
mPeriod,
barIndex
//
);
//
return result;
}
//
bool Init(
string mSymbol = NULL, // Trading Symbol
ENUM_TIMEFRAMES mPeriod = NULL, // Trading Period
double mOpen = 0, // Open
double mHigh = 0, // High
double mClose = 0, // Close
double mLow = 0, // Low
int barIndex = 0 // Bar Index
)
{
//
mSymbol = NormalizeSymbol(mSymbol);
mPeriod = NormalizePeriod(mPeriod);
//
symbol = mSymbol;
period = mPeriod;
//
time = iTime(
mSymbol,
mPeriod,
barIndex
//
);
//
open = mOpen;
high = mHigh;
close = mClose;
low = mLow;
//
return IsValid();
}
//
bool Init(
string mSymbol = NULL, // Trading Symbol
ENUM_TIMEFRAMES mPeriod = NULL, // Trading Period
double mOpen = 0, // Open
double mHigh = 0, // High
double mClose = 0, // Close
double mLow = 0, // Low
datetime mTime = NULL // Bar Time
)
{
//
mSymbol = NormalizeSymbol(mSymbol);
mPeriod = NormalizePeriod(mPeriod);
//
symbol = mSymbol;
period = mPeriod;
//
int barIndex = iBarShift(
symbol,
period,
mTime);
//
time = iTime(
mSymbol,
mPeriod,
barIndex
//
);
//
open = mOpen;
high = mHigh;
close = mClose;
low = mLow;
//
return IsValid();
}
//
// Tools ...
//
void Clean()
{
//
high = 0;
open = 0;
close = 0;
low = 0;
//
time = NULL;
symbol = NULL;
period = NULL;
}
//
// Validate Bar ...
bool IsValid()
{
//
bool result = false;
//
result =
//
high > 0 &&
open > 0 &&
close > 0 &&
low > 0
//
;
//
return result;
}
//
int TotalBars()
{
//
int result = 0;
//
result = iBars(
symbol,
period //
);
//
return result;
}
//
// Calculate X_PRICE Specified Type ...
double GetPrice(ENUM_X_PRICE mPType)
{
//
double result = 0;
//
if (!IsValid())
{
return result;
}
//
switch (mPType)
{
//
case X_PRICE_OPEN:
result = open;
break;
//
case X_PRICE_HIGH:
result = high;
break;
//
case X_PRICE_CLOSE:
result = close;
break;
//
case X_PRICE_LOW:
result = low;
break;
}
//
return result;
}
//
// Retrieve Price base On Series Mode ...
double GetPrice(ENUM_SERIESMODE mMode)
{
//
ENUM_X_PRICE mXMode = ToPrice(mMode);
//
return GetPrice(mXMode);
}
//
// Calculate Applied Price ...
double GetPrice(
ENUM_APPLIED_PRICE mAppliedTo // Select Application Method
)
{
//
double result = 0;
//
// Calculate Applied Price ...
switch (mAppliedTo)
{
//
case PRICE_CLOSE:
result = close;
break;
//
case PRICE_OPEN:
result = open;
break;
//
case PRICE_HIGH:
result = high;
break;
//
case PRICE_LOW:
result = low;
break;
//
case PRICE_MEDIAN:
result = (high + low) / 2;
break;
//
case PRICE_TYPICAL:
result = (high + low + close) / 3;
break;
//
case PRICE_WEIGHTED:
result = (high + low + close + close) / 4;
break;
}
//
return result;
}
//
// Find Specific Price ...
bool FindHigherPriceBar(
XOHCL &bar,
double price,
ENUM_X_PRICE _type = X_PRICE_HIGH //
)
{
//
bool result = false;
//
result = IsValid();
if (!result)
{
return result;
}
//
int totalBars = TotalBars();
result = IsValidSize(totalBars);
if (!result)
{
return result;
}
//
int start = Index();
int maxAllowedLoopback = totalBars / 5;
for (int i = start; i < maxAllowedLoopback; i++)
{
//
result = bar.Init(
symbol,
period,
i //
);
//
if (!result)
{
break;
}
//
double iPrice = bar.GetPrice(_type);
//
result =
//
iPrice > 0 &&
iPrice > price
//
;
if (result)
{
break;
}
}
//
if (!result)
{
bar.Clean();
}
//
return result;
}
//
// Find Specific Price ...
bool FindLowerPriceBar(
XOHCL &bar,
double price,
ENUM_X_PRICE _type = X_PRICE_HIGH //
)
{
//
bool result = false;
//
result = IsValid();
if (!result)
{
return result;
}
//
int totalBars = TotalBars();
result = IsValidSize(totalBars);
if (!result)
{
return result;
}
//
int start = Index();
int maxAllowedLoopback = totalBars / 5;
for (int i = start; i < maxAllowedLoopback; i++)
{
//
result = bar.Init(
symbol,
period,
i //
);
//
if (!result)
{
break;
}
//
double iPrice = bar.GetPrice(_type);
//
result =
//
iPrice > 0 &&
iPrice < price
//
;
if (result)
{
break;
}
}
//
if (!result)
{
bar.Clean();
}
//
return result;
}
//
// Calculate Bar Mid Line ...
double GetMid()
{
//
double result = 0;
//
if (!IsValid())
{
return result;
}
//
result = (high + low) / 2;
//
return result;
}
//
// Calculate up Price ...
double GetUp()
{
//
double result = 0;
//
if (!IsValid())
{
return result;
}
//
result = MathMax(open, close);
//
return result;
}
//
// Calculate Down Price ...
double GetDown()
{
//
double result = 0;
//
if (!IsValid())
{
return result;
}
//
result = MathMin(open, close);
//
return result;
}
//
// Calculate Bar Body ...
double GetBody()
{
//
double result = 0;
//
if (!IsValid())
{
return result;
}
//
result = GetUp() - GetDown();
//
return result;
}
//
// Calculate Bar Range ...
double GetRange()
{
//
double result = 0;
//
if (!IsValid())
{
return result;
}
//
result = high - low;
//
return result;
}
//
// Calculate Bar Shadows ...
double GetShadows()
{
//
double result = 0;
//
if (!IsValid())
{
return result;
}
//
result = GetRange() - GetBody();
//
return result;
}
//
// Calculate Bar High Shadow ...
double GetHighShadow()
{
//
double result = 0;
//
if (!IsValid())
{
return result;
}
//
result =
//
high - GetUp()
//
;
//
return result;
}
//
// Calculate Bar Low Shadow ...
double GetLowShadow()
{
//
double result = 0;
//
if (!IsValid())
{
return result;
}
//
result =
//
GetDown() - low;
//
;
//
return result;
}
//
// Check Bar is Bullish ...
bool IsBullish()
{
//
bool result = false;
//
if (!IsValid())
{
return result;
}
//
result = open < close;
//
return result;
}
//
// Check Bar is Bearish ...
bool IsBearish()
{
//
bool result = false;
//
if (!IsValid())
{
return result;
}
//
result = open > close;
//
return result;
}
//
// Find Next Bar Time ...
datetime NextAt()
{
//
datetime result = NULL;
//
if (!IsValid())
{
return result;
}
//
int prSeconds = PeriodSeconds(period);
//
result = time + prSeconds;
//
return result;
}
//
// Find Prev Bar Time ...
datetime BeforeOn()
{
//
datetime result = NULL;
//
if (!IsValid())
{
return result;
}
//
int prSeconds = PeriodSeconds(period);
//
result = time - prSeconds;
//
return result;
}
//
// Find Current Bar Index on Chart ...
int Index()
{
//
int result = -1;
//
if (!IsValid())
{
return result;
}
//
result = iBarShift(
symbol,
period,
time
//
);
//
return result;
}
//
bool GetPreviousBar(XOHCL &bar)
{
//
bool result = false;
//
result = IsValid();
if (!result)
{
return result;
}
//
int idx = Index();
//
result = bar.Init(
this.symbol,
this.period,
idx + 1 //
);
//
if (!result)
{
bar.Clean();
}
//
return result;
}
//
bool IsStrong(
double percent = 50 // Percent of Body
)
{
//
bool result = false;
//
result = IsValid() && Index() > 0;
if (!result)
{
return result;
}
//
result =
(GetRange() * percent) / 100 <= GetBody();
//
return result;
}
//
bool IsStrongBullish(
double percent = 50 // Percent of Body
)
{
//
bool result = false;
//
result =
IsStrong() && IsBullish();
//
return result;
}
//
bool IsStrongBearish(
double percent = 50 // Percent of Body
)
{
//
bool result = false;
//
result =
IsStrong() && IsBearish();
//
return result;
}
//
bool IsSharpBullish(
int __loopback = 2,
double _sharpRatio = 2.5 //
)
{
//
bool result = false;
//
result = IsValid();
if (!result)
{
return result;
}
//
if (__loopback < 0)
{
__loopback = 2;
}
//
if (_sharpRatio < 0)
{
_sharpRatio = 2.5;
}
//
int hIDX = FindHighestIndex(
__loopback,
MODE_HIGH //
);
int lIDX = FindLowestIndex(
__loopback,
MODE_LOW //
);
//
result =
//
hIDX >= 0 &&
lIDX >= 0 &&
MathAbs(hIDX - Index()) < 2
//
;
//
if (!result)
{
return result;
}
//
XOHCL hBar;
result = hBar.Init(
symbol,
period,
hIDX //
);
if (!result)
{
return result;
}
//
XOHCL lBar;
result = lBar.Init(
symbol,
period,
lIDX //
);
if (!result)
{
return result;
}
//
double lhDif = hBar.high - lBar.low;
//
int hhIDX = hBar.FindHighestIndex(
__loopback,
MODE_HIGH //
);
//
int llIDX = lBar.FindLowestIndex(
__loopback,
MODE_LOW //
);
//
XOHCL hhBar;
result = hhBar.Init(
symbol,
period,
hhIDX + hIDX //
);
if (!result)
{
return result;
}
//
XOHCL llBar;
result = llBar.Init(
symbol,
period,
llIDX + lIDX //
);
if (!result)
{
return result;
}
//
double llhhDif = hhBar.high - llBar.low;
//
result =
//
lBar.low > llBar.low &&
hBar.high > hhBar.high &&
lhDif >= llhhDif * _sharpRatio
//
;
//
return result;
}
//
bool IsSharpBearish(
int __loopback = 2,
double _sharpRatio = 2.5 //
)
{
//
bool result = false;
//
result = IsValid();
if (!result)
{
return result;
}
//
if (__loopback < 0)
{
__loopback = 2;
}
//
if (_sharpRatio < 0)
{
_sharpRatio = 2.5;
}
//
int hIDX = FindHighestIndex(
__loopback,
MODE_HIGH //
);
int lIDX = FindLowestIndex(
__loopback,
MODE_LOW //
);
//
result =
//
hIDX >= 0 &&
lIDX >= 0 &&
MathAbs(hIDX - Index()) < 2
//
;
//
if (!result)
{
return result;
}
//
XOHCL hBar;
result = hBar.Init(
symbol,
period,
hIDX //
);
if (!result)
{
return result;
}
//
XOHCL lBar;
result = lBar.Init(
symbol,
period,
lIDX //
);
if (!result)
{
return result;
}
//
double lhDif = hBar.high - lBar.low;
//
int hhIDX = hBar.FindHighestIndex(
__loopback,
MODE_HIGH //
);
//
int llIDX = lBar.FindLowestIndex(
__loopback,
MODE_LOW //
);
//
XOHCL hhBar;
result = hhBar.Init(
symbol,
period,
hhIDX + hIDX //
);
if (!result)
{
return result;
}
//
XOHCL llBar;
result = llBar.Init(
symbol,
period,
llIDX + lIDX //
);
if (!result)
{
return result;
}
//
double llhhDif = hhBar.high - llBar.low;
//
result =
//
lBar.low < llBar.low &&
hBar.high < hhBar.high &&
lhDif >= llhhDif * _sharpRatio
//
;
//
return result;
}
//
// Find Lowest Bar Index ...
int FindHighestIndex(
int mLength, // Loopback ...
ENUM_SERIESMODE mMode // Calculation mode
)
{
//
int result = -1;
//
if (!IsValid())
{
return result;
}
//
if (mLength < 2)
{
mLength = 2;
}
//
result = iHighest(
symbol,
period,
mMode,
mLength,
Index());
//
return result;
}
//
// Find Lowest ...
double FindHighest(
int mLength, // Loopback ...
ENUM_SERIESMODE mMode // Calculation mode
)
{
//
double result = 0;
//
if (!IsValid())
{
return result;
}
//
int idx = FindHighestIndex(
mLength,
mMode);
if (idx <= -1)
{
return result;
}
//
XOHCL iH;
result = iH.Init(
symbol,
period,
idx
//
);
if (!result)
{
return result;
}
//
result = iH.GetPrice(mMode);
//
return result;
}
//
// Find Lowest Bar Index ...
int FindLowestIndex(
int mLength, // Loopback ...
ENUM_SERIESMODE mMode // Calculation mode
)
{
//
int result = -1;
//
if (!IsValid())
{
return result;
}
//
if (mLength < 2)
{
mLength = 2;
}
//
result = iLowest(
symbol,
period,
mMode,
mLength,
Index());
//
return result;
}
//
// Find Lowest ...
double FindLowest(
int mLength, // Loopback ...
ENUM_SERIESMODE mMode // Calculation mode
)
{
//
double result = 0;
//
if (!IsValid())
{
return result;
}
//
int idx = FindLowestIndex(
mLength,
mMode);
if (idx <= -1)
{
return result;
}
//
XOHCL iL;
result = iL.Init(
symbol,
period,
idx
//
);
if (!result)
{
return result;
}
//
result = iL.GetPrice(mMode);
//
return result;
}
//
// Retrieve Bullish Pressure ...
double GetBullishPressure(
int __loopback = 7 //
)
{
//
double result = 0;
//
if (!IsValid())
{
return result;
}
//
XOHCL bars[];
int barsCount = GetBars(
bars,
symbol,
period,
Index(),
__loopback //
);
if (!IsValidSize(barsCount))
{
return result;
}
//
for (int i = 0; i < barsCount; i++)
{
result += bars[i].GetLowShadow();
}
//
return result;
}
//
// Retrieve Bearish Pressure ...
double GetBearishPressure(
int __loopback = 7 //
)
{
//
double result = 0;
//
if (!IsValid())
{
return result;
}
//
XOHCL bars[];
int barsCount = GetBars(
bars,
symbol,
period,
Index(),
__loopback //
);
if (!IsValidSize(barsCount))
{
return result;
}
//
for (int i = 0; i < barsCount; i++)
{
result += bars[i].GetHighShadow();
}
//
return result;
}
//
bool HasBullishPressure(
int __loopback = 7 //
)
{
//
bool result = false;
//
if (__loopback < 0)
{
__loopback = 7;
}
//
double bullishPressure = GetBullishPressure(__loopback);
double bearishPressure = GetBearishPressure(__loopback);
//
result =
//
bullishPressure > 0 &&
bearishPressure >= 0 &&
bullishPressure > bearishPressure
//
;
//
return result;
}
//
bool HasBearishPressure(
int __loopback = 7 //
)
{
//
bool result = false;
//
if (__loopback < 0)
{
__loopback = 7;
}
//
double bullishPressure = GetBullishPressure(__loopback);
double bearishPressure = GetBearishPressure(__loopback);
//
result =
//
bearishPressure > 0 &&
bullishPressure >= 0 &&
bearishPressure > bullishPressure
//
;
//
return result;
}
//
// Retrieve Bullish Power ...
double GetBullishPower(
int __loopback = 7 //
)
{
//
double result = 0;
//
if (!IsValid())
{
return result;
}
//
XOHCL bars[];
int barsCount = GetBars(
bars,
symbol,
period,
Index(),
__loopback //
);
if (!IsValidSize(barsCount))
{
return result;
}
//
for (int i = 0; i < barsCount; i++)
{
//
if (bars[i].IsBullish())
{
result += bars[i].GetBody();
}
}
//
return result;
}
//
// Retrieve Bearish Pressure ...
double GetBearishPower(
int __loopback = 7 //
)
{
//
double result = 0;
//
if (!IsValid())
{
return result;
}
//
XOHCL bars[];
int barsCount = GetBars(
bars,
symbol,
period,
Index(),
__loopback //
);
if (!IsValidSize(barsCount))
{
return result;
}
//
for (int i = 0; i < barsCount; i++)
{
//
if (bars[i].IsBearish())
{
result += bars[i].GetBody();
}
}
//
return result;
}
//
bool HasBullishPower(
int __loopback = 7 //
)
{
//
bool result = false;
//
if (__loopback < 0)
{
__loopback = 7;
}
//
double bullishPressure = GetBullishPower(__loopback);
double bearishPressure = GetBearishPower(__loopback);
//
result =
//
bullishPressure > 0 &&
bearishPressure >= 0 &&
bullishPressure > bearishPressure
//
;
//
return result;
}
//
bool HasBearishPower(
int __loopback = 7 //
)
{
//
bool result = false;
//
if (__loopback < 0)
{
__loopback = 7;
}
//
double bullishPressure = GetBullishPower(__loopback);
double bearishPressure = GetBearishPower(__loopback);
//
result =
//
bearishPressure > 0 &&
bullishPressure >= 0 &&
bearishPressure > bullishPressure
//
;
//
return result;
}
//
// Touches ...
//
bool IsBullishTouched(double price)
{
//
bool result = false;
//
result =
//
IsValid()
//
&&
//
price > 0
//
;
if (!result)
{
return result;
}
//
XOHCL pBar;
result = GetPreviousBar(pBar);
if (!result)
{
return result;
}
//
result =
//
(pBar.low <= price ||
pBar.GetDown() <= price)
//
&&
//
(pBar.high > price ||
pBar.GetUp() > price)
//
&&
//
open > price &&
low > price
//
;
//
return result;
}
//
bool IsBearishTouched(double price)
{
//
bool result = false;
//
result =
//
IsValid()
//
&&
//
price > 0
//
;
if (!result)
{
return result;
}
//
XOHCL pBar;
result = GetPreviousBar(pBar);
if (!result)
{
return result;
}
//
result =
//
(pBar.high >= price ||
pBar.GetUp() >= price)
//
&&
//
(pBar.low < price ||
pBar.GetDown() < price)
//
&&
//
open < price &&
high < price
//
;
//
return result;
}
//
// Candlestic Patterns ...
//
// Check Doji ...
bool IsDoji()
{
//
bool result = false;
//
// Validate Content and Ignore 0 Bar
// since it is not Completed ...
result = IsValid() && Index() > 0;
if (!result)
{
return result;
}
//
result = open == close;
//
return result;
}
//
// Check Hammer ...
bool IsHammer(
double _upShadowFactor = 0.1,
double _downShadowFactor = 0.6,
bool applyFib382Check = true,
bool applyPrevShadowCheck = true //
)
{
//
bool result = false;
//
// Validate Content and Ignore 0 Bar
// since it is not Completed ...
result = IsValid() && Index() > 0;
if (!result)
{
return result;
}
//
if (_upShadowFactor < 0)
{
_upShadowFactor = 0.1;
}
//
if (_downShadowFactor < 0)
{
_upShadowFactor = 0.6;
}
//
double range = GetRange();
//
// Check Upper Shadow Must be 0 or Under 10% ...
double upShadow = GetHighShadow();
result = upShadow < range * _upShadowFactor;
if (!result)
{
return result;
}
//
// Check Down Shadow Must at least 60% ...
double downShadow = GetLowShadow();
result = downShadow > range * _downShadowFactor;
if (!result)
{
return result;
}
//
// Check Fib 382 ...
if (result && applyFib382Check)
{
//
double fib382 = GetFibonacciLevel(
high,
low,
0.382,
-1 //
);
result = GetDown() > fib382;
}
//
// Check Shadow Based on Prev Bar ...
if (result && applyPrevShadowCheck)
{
//
XOHCL pBar;
result = GetPreviousBar(pBar);
if (!result)
{
return result;
}
//
result = low < pBar.low;
}
//
return result;
}
//
// Check Sgooting Star ...
// Reversal Hammer ...
bool IsShootingStar(
double _upShadowFactor = 0.6,
double _downShadowFactor = 0.1,
bool applyFib382Check = true,
bool applyPrevShadowCheck = true //
)
{
//
bool result = false;
//
// Validate Content and Ignore 0 Bar
// since it is not Completed ...
result = IsValid() && Index() > 0;
if (!result)
{
return result;
}
//
if (_upShadowFactor < 0)
{
_upShadowFactor = 0.6;
}
//
if (_downShadowFactor < 0)
{
_upShadowFactor = 0.1;
}
//
double range = GetRange();
//
// Check Upper Shadow Must be 0 or Under 10% ...
double upShadow = GetHighShadow();
result = upShadow > range * _upShadowFactor;
if (!result)
{
return result;
}
//
// Check Down Shadow Must at least 60% ...
double downShadow = GetLowShadow();
result = downShadow < range * _downShadowFactor;
if (!result)
{
return result;
}
//
// Check Fib 382 ...
if (result && applyFib382Check)
{
//
double fib382 = GetFibonacciLevel(
high,
low,
0.382,
1 //
);
result = GetUp() < fib382;
}
//
// Check Shadow Based on Prev Bar ...
if (result && applyPrevShadowCheck)
{
//
XOHCL pBar;
result = GetPreviousBar(pBar);
if (!result)
{
return result;
}
//
result = high > pBar.high;
}
//
return result;
}
//
// Check Bullish Engulfing ...
bool IsBullishEngulfing(
double _engulfBarBodyFactor = 0.7 //
)
{
//
bool result = false;
//
// Validate Content and Ignore 0 Bar
// since it is not Completed ...
result = IsValid() && Index() > 0;
if (!result)
{
return result;
}
//
if (_engulfBarBodyFactor < 0)
{
_engulfBarBodyFactor = 0.7;
}
//
// Check Bar Is Bullish ...
result = IsBullish();
if (!result)
{
return result;
}
//
// Retrieve Previous Bar ...
XOHCL pBar;
result = GetPreviousBar(pBar);
if (!result)
{
return result;
}
//
double range = GetRange();
double body = GetBody();
//
// Check Prev Bar Must Bearish ...
result = pBar.IsBearish();
if (!result)
{
return result;
}
//
// Check Shadows Engulf Prev Bar ...
result =
//
high > pBar.high &&
low <= pBar.low
//
;
if (!result)
{
return result;
}
//
// Check Engulfed Bar Must Inside Engulfer Body ...
result =
//
GetUp() > pBar.GetUp() &&
GetDown() < pBar.GetDown()
//
;
if (!result)
{
return result;
}
//
// Check Body of Engulfing Bar ...
if (result && _engulfBarBodyFactor > 0)
{
result = body >= range * _engulfBarBodyFactor;
}
//
return result;
}
//
// Check Bearish Engulfing ...
bool IsBearishEngulfing(
double _engulfBarBodyFactor = 0.7 //
)
{
//
bool result = false;
//
// Validate Content and Ignore 0 Bar
// since it is not Completed ...
result = IsValid() && Index() > 0;
if (!result)
{
return result;
}
//
if (_engulfBarBodyFactor < 0)
{
_engulfBarBodyFactor = 0.7;
}
//
// Check Bar Is Bearish ...
result = IsBearish();
if (!result)
{
return result;
}
//
// Retrieve Previous Bar ...
XOHCL pBar;
result = GetPreviousBar(pBar);
if (!result)
{
return result;
}
//
double range = GetRange();
double body = GetBody();
//
// Check Prev Bar Must Bullish ...
result = pBar.IsBullish();
if (!result)
{
return result;
}
//
// Check Shadows Engulf Prev Bar ...
result = high >= pBar.high && low < pBar.low;
if (!result)
{
return result;
}
//
// Check Engulfed Bar Must Inside Engulfer Body ...
result =
//
GetUp() > pBar.GetUp() &&
GetDown() < pBar.GetDown()
//
;
if (!result)
{
return result;
}
//
// Check Body of Engulfing Bar ...
if (result && _engulfBarBodyFactor > 0)
{
result = body >= range * _engulfBarBodyFactor;
}
//
return result;
}
//
// Check Morning Star Pattern ...
bool IsMorningStar(
double _middleRangeFactor = 0.3,
double _startBodyFactor = 0.6,
bool forceCheckMiddleBarDirection = true,
bool forceCheckStartBody = true //
)
{
//
bool result = false;
//
// Validate Content and Ignore 0 Bar
// since it is not Completed ...
result = IsValid() && Index() > 0;
if (!result)
{
return result;
}
//
if (_middleRangeFactor < 0)
{
_middleRangeFactor = 0.3;
}
//
if (_startBodyFactor < 0)
{
_startBodyFactor = 0.6;
}
//
// Current Bar Must be Bullish ...
result = IsBullish();
if (!result)
{
return result;
}
//
// Retrieve Previous Bar ...
XOHCL pBar;
result = GetPreviousBar(pBar);
if (!result)
{
return result;
}
//
// Prev Bar must be Bearish ...
if (result && forceCheckMiddleBarDirection)
{
//
result = pBar.IsBearish();
if (!result)
{
return result;
}
}
//
// Retrieve Previous Bar of Prev Bar ...
XOHCL ppBar;
result = pBar.GetPreviousBar(ppBar);
if (!result)
{
return result;
}
//
// Prev Of Prev Bar Must be Bearish ...
result = ppBar.IsBearish();
if (!result)
{
return result;
}
//
double range = GetRange();
double pRange = pBar.GetRange();
double ppRange = ppBar.GetRange();
//
// Middle Bar must be Smaller than Ratio of other ...
result =
//
pRange < range * _middleRangeFactor &&
pRange < ppRange * _middleRangeFactor
//
;
if (!result)
{
return result;
}
//
if (result && forceCheckStartBody)
{
//
result = ppBar.GetBody() > ppRange * _startBodyFactor;
if (!result)
{
return result;
}
}
//
return result;
}
//
// Check Evening Star Pattern ...
bool IsEveningStar(
double _middleRangeFactor = 0.3,
double _startBodyFactor = 0.6,
bool forceCheckMiddleBarDirection = true,
bool forceCheckStartBody = true //
)
{
//
bool result = false;
//
// Validate Content and Ignore 0 Bar
// since it is not Completed ...
result = IsValid() && Index() > 0;
if (!result)
{
return result;
}
//
if (_middleRangeFactor < 0)
{
_middleRangeFactor = 0.3;
}
//
if (_startBodyFactor < 0)
{
_startBodyFactor = 0.6;
}
//
// Current Bar Must be Bearish ...
result = IsBearish();
if (!result)
{
return result;
}
//
// Retrieve Previous Bar ...
XOHCL pBar;
result = GetPreviousBar(pBar);
if (!result)
{
return result;
}
//
// Prev Bar must be Bullish ...
if (result && forceCheckMiddleBarDirection)
{
//
result = pBar.IsBullish();
if (!result)
{
return result;
}
}
//
// Retrieve Previous Bar of Prev Bar ...
XOHCL ppBar;
result = pBar.GetPreviousBar(ppBar);
if (!result)
{
return result;
}
//
// Prev Of Prev Bar Must be Bullish ...
result = ppBar.IsBullish();
if (!result)
{
return result;
}
//
double range = GetRange();
double pRange = pBar.GetRange();
double ppRange = ppBar.GetRange();
//
// Middle Bar must be Smaller than Ratio of other ...
result =
//
pRange < range * _middleRangeFactor &&
pRange < ppRange * _middleRangeFactor
//
;
if (!result)
{
return result;
}
//
if (result && forceCheckStartBody)
{
//
result = ppBar.GetBody() > ppRange * _startBodyFactor;
if (!result)
{
return result;
}
}
//
return result;
}
//
// Bullish Marubozu ...
bool IsBullishMarubozu()
{
//
bool result = false;
//
result = IsValid() && Index() > 0;
if (!result)
{
return result;
}
//
result = IsBullish();
if (!result)
{
return result;
}
//
result =
//
GetUp() == high &&
GetDown() == low
//
;
//
return result;
}
//
// Bearish Marubozu ...
bool IsBearishMarubozu()
{
//
bool result = false;
//
result = IsValid() && Index() > 0;
if (!result)
{
return result;
}
//
result = IsBearish();
if (!result)
{
return result;
}
//
result =
//
GetUp() == high &&
GetDown() == low
//
;
//
return result;
}
//
// Contextual Patterns ...
//
// Check Swing High ...
bool IsSwingHigh()
{
//
bool result = false;
//
// Validate Content and Ignore 0 Bar
// since it is not Completed ...
result = IsValid() && Index() > 0;
if (!result)
{
return result;
}
//
// Current Bar Must be Bearish ...
result = IsBearish();
if (!result)
{
return result;
}
//
// Retrieve Prev Bar ...
XOHCL pBar;
result = GetPreviousBar(pBar);
if (!result)
{
return result;
}
//
// Prev Bar Must be Bullish ...
result = pBar.IsBullish();
if (!result)
{
return result;
}
//
// Retrieve Prev of Prev Bar ...
XOHCL ppBar;
result = pBar.GetPreviousBar(ppBar);
if (!result)
{
return result;
}
//
// Prev of Prev Bar Must be Bullish ...
result = ppBar.IsBullish();
if (!result)
{
return result;
}
//
// Check All Highs ...
result =
//
high < pBar.high &&
pBar.high > ppBar.high
//
;
//
return result;
}
//
// Find Last Swing High ...
bool FindLastSwingHigh(XOHCL &swing)
{
//
bool result = false;
//
swing.Clean();
//
result = IsValid();
if (!result)
{
return result;
}
//
int totalBars = iBars(
symbol,
period //
);
int maxAllowed = MathMin(100, (totalBars / 100));
//
int idx = Index();
for (int i = idx; i <= idx + maxAllowed; i++)
{
//
swing.Clean();
result = swing.Init(
symbol,
period,
i //
);
if (!result)
{
//
swing.Clean();
break;
}
//
result = swing.IsSwingHigh();
if (result)
{
break;
}
}
//
return result;
}
//
// Check Swing Low ...
bool IsSwingLow()
{
//
bool result = false;
//
// Validate Content and Ignore 0 Bar
// since it is not Completed ...
result = IsValid() && Index() > 0;
if (!result)
{
return result;
}
//
// Current Bar Must be Bullish ...
result = IsBullish();
if (!result)
{
return result;
}
//
// Retrieve Prev Bar ...
XOHCL pBar;
result = GetPreviousBar(pBar);
if (!result)
{
return result;
}
//
// Prev Bar Must be Bearish ...
result = pBar.IsBearish();
if (!result)
{
return result;
}
//
// Retrieve Prev of Prev Bar ...
XOHCL ppBar;
result = pBar.GetPreviousBar(ppBar);
if (!result)
{
return result;
}
//
// Prev of Prev Bar Must be Bearish ...
result = ppBar.IsBearish();
if (!result)
{
return result;
}
//
// Check All Lows ...
result =
//
low > pBar.low &&
pBar.low < ppBar.low
//
;
//
return result;
}
//
// Find Last Swing Low ...
bool FindLastSwingLow(XOHCL &swing)
{
//
bool result = false;
//
swing.Clean();
//
result = IsValid();
if (!result)
{
return result;
}
//
int totalBars = iBars(
symbol,
period //
);
int maxAllowed = MathMin(100, (totalBars / 100));
//
int idx = Index();
for (int i = idx; i <= idx + maxAllowed; i++)
{
//
swing.Clean();
result = swing.Init(
symbol,
period,
i //
);
if (!result)
{
//
swing.Clean();
break;
}
//
result = swing.IsSwingLow();
if (result)
{
break;
}
}
//
return result;
}
//
// Check Bullish FVG ...
bool HasBullishFVG(
double &upper,
double &lower,
bool forceMiddleBarCheck = true //
)
{
//
bool result = false;
//
upper = 0;
lower = 0;
//
// Validate Content and Ignore 0 Bar
// since it is not Completed ...
result = IsValid() && Index() > 0;
if (!result)
{
return result;
}
//
// Current Bar Must be Bullish ...
result = IsBullish();
if (!result)
{
return result;
}
//
// Retrieve Prev Bar ...
XOHCL pBar;
result = GetPreviousBar(pBar);
if (!result)
{
return result;
}
//
// Prev Bar Must be Bullish ...
result = pBar.IsBullish();
if (!result)
{
return result;
}
//
// Retrieve Prev of Prev Bar ...
XOHCL ppBar;
result = pBar.GetPreviousBar(ppBar);
if (!result)
{
return result;
}
//
// Prev of Prev Bar Must be Bullish ...
result = ppBar.IsBullish();
if (!result)
{
return result;
}
//
// Other Conditions ...
result =
//
low > ppBar.high
//
;
//
// Check Middle Bar Range ...
if (result && forceMiddleBarCheck)
{
//
result =
//
pBar.high > low &&
pBar.low < ppBar.high
//
;
//
if (!result)
{
return result;
}
}
//
if (result)
{
//
upper = low;
lower = ppBar.high;
}
//
return result;
}
//
// Check Bearish FVG ...
bool HasBearishFVG(
double &upper,
double &lower,
bool forceMiddleBarCheck = true //
)
{
//
bool result = false;
//
upper = 0;
lower = 0;
//
// Validate Content and Ignore 0 Bar
// since it is not Completed ...
result = IsValid() && Index() > 0;
if (!result)
{
return result;
}
//
// Current Bar Must be Bearish ...
result = IsBearish();
if (!result)
{
return result;
}
//
// Retrieve Prev Bar ...
XOHCL pBar;
result = GetPreviousBar(pBar);
if (!result)
{
return result;
}
//
// Prev Bar Must be Bearish ...
result = pBar.IsBearish();
if (!result)
{
return result;
}
//
// Retrieve Prev of Prev Bar ...
XOHCL ppBar;
result = pBar.GetPreviousBar(ppBar);
if (!result)
{
return result;
}
//
// Prev of Prev Bar Must be Bearish ...
result = ppBar.IsBearish();
if (!result)
{
return result;
}
//
// Other Conditions ...
result =
//
high < ppBar.low
//
;
//
// Check Middle Bar Range ...
if (result && forceMiddleBarCheck)
{
//
result =
//
pBar.high > low &&
pBar.low < ppBar.high
//
;
//
if (!result)
{
return result;
}
}
//
if (result)
{
//
upper = ppBar.low;
lower = high;
}
//
return result;
}
//
// Find Support ...
bool HasSupport(
XOHCL &bar,
ENUM_X_PRICE type = X_PRICE_CLOSE,
int _loopback = 21,
int tries = 100 //
)
{
//
bool result = false;
//
bar.Clean();
//
if (_loopback < 0)
{
_loopback = 21;
}
//
if (tries < 0)
{
tries = 100;
}
//
result = IsValid();
if (!result)
{
return result;
}
//
double price = GetPrice(type);
//
for (int i = 1; i < tries; i++)
{
//
int _length = _loopback * i;
//
int lowestIDX = FindLowestIndex(
_length,
MODE_LOW //
);
result = IsValidSize(lowestIDX);
if (!result)
{
break;
}
//
XOHCL iLBar;
result = iLBar.Init(
symbol,
period,
lowestIDX //
);
if (!result)
{
break;
}
//
result =
//
price > iLBar.high
//
;
if (result)
{
//
bar = iLBar;
break;
}
}
//
return result;
}
//
// Find Resistance ...
bool HasResistance(
XOHCL &bar,
ENUM_X_PRICE type = X_PRICE_CLOSE,
int _loopback = 21,
int tries = 100 //
)
{
//
bool result = false;
//
bar.Clean();
//
if (_loopback < 0)
{
_loopback = 21;
}
//
if (tries < 0)
{
tries = 100;
}
//
result = IsValid();
if (!result)
{
return result;
}
//
double price = GetPrice(type);
//
for (int i = 1; i < tries; i++)
{
//
int _length = _loopback * i;
//
int highestIDX = FindHighestIndex(
_length,
MODE_LOW //
);
result = IsValidSize(highestIDX);
if (!result)
{
break;
}
//
XOHCL iHBar;
result = iHBar.Init(
symbol,
period,
highestIDX //
);
if (!result)
{
break;
}
//
result =
//
price < iHBar.high
//
;
if (result)
{
//
bar = iHBar;
break;
}
}
//
return result;
}
//
// Trend Detection ...
//
// Find Bullish Trend ...
bool HasBullishTrend(
XOHCL &highSwingBars[],
XOHCL &lowSwingBars[],
bool forceMethod2 = false,
int _loopback = 3,
int tries = 3,
ENUM_X_PRICE type = X_PRICE_CLOSE //
)
{
//
bool result = false;
//
Clean(lowSwingBars);
Clean(highSwingBars);
//
result = IsValid();
if (!result)
{
return result;
}
//
double price = GetPrice(type);
//
int lastIDX = Index();
double lastH = 0;
double lastL = 0;
for (int i = 1; i < tries + 1; i++)
{
//
// Use Regular Method ...
if (!forceMethod2)
{
//
int iHIDX = FindSwing(
symbol,
period,
X_SWING_HIGH,
_loopback,
lastIDX //
);
result = IsValidIndex(iHIDX);
if (!result)
{
break;
}
//
XOHCL iHBar;
result = iHBar.Init(
symbol,
period,
iHIDX //
);
if (!result)
{
break;
}
//
double iH = iHBar.high;
bool isIHAccepted =
//
iH > 0 &&
(
//
lastH == 0
? true
: iH < lastH
//
)
//
;
if (isIHAccepted)
{
//
AddRef(
iHBar,
highSwingBars //
);
//
lastH = iH;
lastIDX = iHIDX;
}
//
int iLIDX = FindSwing(
symbol,
period,
X_SWING_LOW,
_loopback,
lastIDX //
);
result = IsValidIndex(iLIDX);
if (!result)
{
break;
}
//
XOHCL iLBar;
result = iLBar.Init(
symbol,
period,
iLIDX //
);
if (!result)
{
break;
}
//
double iL = iLBar.low;
bool isILAccepted =
//
iL > 0 &&
(
//
lastL == 0
? true
: iL < lastL
//
)
//
;
if (isILAccepted)
{
//
AddRef(
iLBar,
lowSwingBars //
);
//
lastL = iL;
lastIDX = iLIDX;
}
}
//
// Use Other MEthod ...
else
{
//
int _length = i * _loopback;
int start =
//
i == 1
? 1
: _length - _loopback
//
;
//
int iHIDX = iHighest(
symbol,
period,
MODE_HIGH,
_loopback,
start //
);
result = IsValidIndex(iHIDX);
if (!result)
{
break;
}
//
XOHCL iHBar;
result = iHBar.Init(
symbol,
period,
iHIDX //
);
if (!result)
{
break;
}
//
double iH = iHBar.high;
bool isIHAccepted =
//
iH > 0 &&
(
//
lastH == 0
? true
: iH < lastH
//
)
//
;
if (isIHAccepted)
{
//
AddRef(
iHBar,
highSwingBars //
);
//
lastH = iH;
lastIDX = iHIDX;
}
//
int iLIDX = iLowest(
symbol,
period,
MODE_LOW,
_loopback,
start //
);
result = IsValidIndex(iLIDX);
if (!result)
{
break;
}
//
XOHCL iLBar;
result = iLBar.Init(
symbol,
period,
iLIDX //
);
if (!result)
{
break;
}
//
double iL = iLBar.low;
bool isILAccepted =
//
iL > 0 &&
(
//
lastL == 0
? true
: iL < lastL
//
)
//
;
if (isILAccepted)
{
//
AddRef(
iLBar,
lowSwingBars //
);
//
lastL = iL;
lastIDX = iLIDX;
}
}
}
//
if (result)
{
//
result =
//
ArraySize(lowSwingBars) == tries &&
ArraySize(highSwingBars) == tries
//
;
}
//
if (!result)
{
//
Clean(lowSwingBars);
Clean(highSwingBars);
}
//
return result;
}
//
// Find Bearish Trend ...
bool HasBearishTrend(
XOHCL &highSwingBars[],
XOHCL &lowSwingBars[],
bool forceMethod2 = false,
int _loopback = 3,
int tries = 3,
ENUM_X_PRICE type = X_PRICE_CLOSE //
)
{
//
bool result = false;
//
Clean(lowSwingBars);
Clean(highSwingBars);
//
result = IsValid();
if (!result)
{
return result;
}
//
double price = GetPrice(type);
//
int lastIDX = Index();
double lastH = 0;
double lastL = 0;
for (int i = 1; i < tries + 1; i++)
{
//
// Use Regular Method ...
if (!forceMethod2)
{
//
int iHIDX = FindSwing(
symbol,
period,
X_SWING_HIGH,
_loopback,
lastIDX //
);
result = IsValidIndex(iHIDX);
if (!result)
{
break;
}
//
XOHCL iHBar;
result = iHBar.Init(
symbol,
period,
iHIDX //
);
if (!result)
{
break;
}
//
double iH = iHBar.high;
bool isIHAccepted =
//
iH > 0 &&
(
//
lastH == 0
? true
: iH > lastH
//
)
//
;
if (isIHAccepted)
{
//
AddRef(
iHBar,
highSwingBars //
);
//
lastH = iH;
lastIDX = iHIDX;
}
//
int iLIDX = FindSwing(
symbol,
period,
X_SWING_LOW,
_loopback,
lastIDX //
);
result = IsValidIndex(iLIDX);
if (!result)
{
break;
}
//
XOHCL iLBar;
result = iLBar.Init(
symbol,
period,
iLIDX //
);
if (!result)
{
break;
}
//
double iL = iLBar.low;
bool isILAccepted =
//
iL > 0 &&
(
//
lastL == 0
? true
: iL > lastL
//
)
//
;
if (isILAccepted)
{
//
AddRef(
iLBar,
lowSwingBars //
);
//
lastL = iL;
lastIDX = iLIDX;
}
}
//
// Use Other MEthod ...
else
{
//
int _length = i * _loopback;
int start =
//
i == 1
? 1
: _length - _loopback
//
;
//
int iHIDX = iHighest(
symbol,
period,
MODE_HIGH,
_loopback,
start //
);
result = IsValidIndex(iHIDX);
if (!result)
{
break;
}
//
XOHCL iHBar;
result = iHBar.Init(
symbol,
period,
iHIDX //
);
if (!result)
{
break;
}
//
double iH = iHBar.high;
bool isIHAccepted =
//
iH > 0 &&
(
//
lastH == 0
? true
: iH > lastH
//
)
//
;
if (isIHAccepted)
{
//
AddRef(
iHBar,
highSwingBars //
);
//
lastH = iH;
lastIDX = iHIDX;
}
//
int iLIDX = iLowest(
symbol,
period,
MODE_LOW,
_loopback,
start //
);
result = IsValidIndex(iLIDX);
if (!result)
{
break;
}
//
XOHCL iLBar;
result = iLBar.Init(
symbol,
period,
iLIDX //
);
if (!result)
{
break;
}
//
double iL = iLBar.low;
bool isILAccepted =
//
iL > 0 &&
(
//
lastL == 0
? true
: iL > lastL
//
)
//
;
if (isILAccepted)
{
//
AddRef(
iLBar,
lowSwingBars //
);
//
lastL = iL;
lastIDX = iLIDX;
}
}
}
//
if (result)
{
//
result =
//
ArraySize(lowSwingBars) == tries &&
ArraySize(highSwingBars) == tries
//
;
}
//
if (!result)
{
//
Clean(lowSwingBars);
Clean(highSwingBars);
}
//
return result;
}
//
// Order Blocks ...
//
// Find Bullish Order Block ...
bool HasBullishOrderBlock(
XOHCL &orderBlock,
int _minimumSameBars = 4 //
)
{
//
bool result = false;
//
orderBlock.Clean();
//
result = IsValid();
if (!result)
{
return result;
}
//
if (_minimumSameBars < 0)
{
_minimumSameBars = 4;
}
//
XOHCL cBar;
int founded = 0;
int cIDX = Index();
bool isEnough = false;
while (!isEnough)
{
//
result = cBar.Init(
symbol,
period,
cIDX //
);
if (!result)
{
break;
}
//
result = cBar.IsBullish();
if (!result && cBar.IsBearish())
{
break;
}
//
cIDX++;
founded++;
}
//
// Here we have to check founded and if it's fill
// our requirements ...
// cIDX is Order Block Index ...
result =
//
cBar.IsValid() &&
high > cBar.high &&
founded >= _minimumSameBars
//
;
if (!result)
{
return result;
}
//
result = orderBlock.Init(
symbol,
period,
cIDX //
);
if (!result)
{
//
orderBlock.Clean();
return result;
}
//
return result;
}
//
// Find Bearish Order Block ...
bool HasBearishOrderBlock(
XOHCL &orderBlock,
int _minimumSameBars = 4 //
)
{
//
bool result = false;
//
orderBlock.Clean();
//
result = IsValid();
if (!result)
{
return result;
}
//
if (_minimumSameBars < 0)
{
_minimumSameBars = 4;
}
//
XOHCL cBar;
int founded = 0;
int cIDX = Index();
bool isEnough = false;
while (!isEnough)
{
//
bool isInited = cBar.Init(
symbol,
period,
cIDX //
);
//
result = cBar.IsBearish();
if (!result && cBar.IsBullish())
{
break;
}
//
cIDX++;
founded++;
}
//
// Here we have to check founded and if it's fill
// our requirements ...
// cIDX is Order Block Index ...
result =
//
cBar.IsValid() &&
high < cBar.low &&
founded >= _minimumSameBars
//
;
if (!result)
{
return result;
}
//
result = orderBlock.Init(
symbol,
period,
cIDX //
);
if (!result)
{
//
orderBlock.Clean();
return result;
}
//
return result;
}
//
// Order Blocks ...
//
// Supply and Demand ...
//
// Other ...
//
// Convert to String Representation ...
string ToString()
{
//
string result = "";
//
result = GetTypeName(this) +
"(O(" + ToString(open) + "),H(" + ToString(high) + "),C(" + ToString(close) + "),L(" + ToString(low) + "))";
//
return result;
}
};
//
// Tracking Times ...
struct XTimeTracker
{
//
// Props ...
int xMonth;
int xDayOfWeek;
int xForWeekDay;
int xDay;
int xHour;
int xMinute;
//
// Constructor ...
XTimeTracker()
{
Clean();
}
//
// Tools ...
//
void Clean()
{
//
xDay = -1;
xHour = -1;
xMonth = -1;
xMinute = -1;
xDayOfWeek = -1;
xForWeekDay = -1;
}
//
// Detecting New Minute ...
bool IsNewMinute()
{
//
bool result = false;
//
// Retrieve Current Time as Struct ...
MqlDateTime timeStruct = GetCurrentTime();
//
// Check Houre ...
result = timeStruct.min != xMinute;
if (result)
{
xMinute = timeStruct.min;
}
//
return result;
}
//
// Detecting New Houre ...
bool IsNewHour()
{
//
bool result = false;
//
// Retrieve Current Time as Struct ...
MqlDateTime timeStruct = GetCurrentTime();
//
// Check Houre ...
result = timeStruct.hour != xHour;
if (result)
{
xHour = timeStruct.hour;
}
//
return result;
}
//
// Detecting New Day ...
bool IsNewDay()
{
//
bool result = false;
//
// Retrieve Current Time as Struct ...
MqlDateTime timeStruct = GetCurrentTime();
//
// Check Houre ...
result = timeStruct.day_of_year != xDay;
if (result)
{
xDay = timeStruct.day_of_year;
}
//
return result;
}
//
// Detecting New Week ...
bool IsNewWeek()
{
//
bool result = false;
//
// Retrieve Current Time as Struct ...
MqlDateTime timeStruct = GetCurrentTime();
//
// Check Week ...
// Since Week Starts From Monday in Forex World ...
// we Calculate Start of Week by 1-Monday ...
result =
xDayOfWeek == -1 &&
xForWeekDay == -1
? true
: timeStruct.day_of_week == 1 &&
timeStruct.day_of_year > xForWeekDay;
//
xForWeekDay = timeStruct.day_of_year;
xDayOfWeek = timeStruct.day_of_week;
//
return result;
}
//
// Detecting End Of Week ...
bool IsWeekEnd()
{
//
bool result = false;
//
// Retrieve Current Time as Struct ...
MqlDateTime timeStruct = GetCurrentTime();
//
// Check WeekEnd ...
// Since Week Starts From Monday in Forex World ...
// we Calculate End of Week by 5-Friday ...
result =
xDayOfWeek != -1 &&
timeStruct.day_of_week == 5 &&
timeStruct.hour == 23 &&
timeStruct.min == 59 &&
timeStruct.sec == 59;
//
return result;
}
//
// Detecting New Month ...
bool IsNewMonth()
{
//
bool result = false;
//
// Retrieve Current Time as Struct ...
MqlDateTime timeStruct = GetCurrentTime();
//
// Check Houre ...
result = timeStruct.mon != xMonth;
if (result)
{
xMonth = timeStruct.mon;
}
//
return result;
}
};
//
// Tracking Bars on Specified Environment ...
struct XBarTracker
{
//
string symbol; // Tracking Symbol
ENUM_TIMEFRAMES period; // Tracking Time Frame
//
int lastTrackedBar; // Last Tracked Bar ...
//
bool waitsUntilNext; // Waits Until Next Bar ...
//
// Constructor ...
XBarTracker()
{
Clean();
}
//
// Initializer ...
bool Init(
string mSymbol = NULL, // Trading Symbol
ENUM_TIMEFRAMES mPeriod = NULL // Trading Period
)
{
//
bool result = false;
//
mSymbol = NormalizeSymbol(mSymbol);
mPeriod = NormalizePeriod(mPeriod);
//
this.symbol = mSymbol;
this.period = mPeriod;
//
this.lastTrackedBar = 0;
//
result = true;
//
return result;
}
//
// Retrieve all Bars ...
int CountBars()
{
//
return iBars(
symbol,
period
//
);
}
//
// Check if it's New Bar ...
bool IsNewBar()
{
//
bool result = false;
//
int currentBars = CountBars();
//
result = currentBars > lastTrackedBar;
if (result)
{
lastTrackedBar = currentBars;
}
//
return result;
}
//
bool CanProcessBar()
{
//
bool _isInTestMode = IsRunningOnTestMode();
//
bool isNewBar = IsNewBar();
//
bool result =
_isInTestMode
? isNewBar
: !waitsUntilNext
? true
: isNewBar;
if (result && waitsUntilNext)
{
waitsUntilNext = false;
}
//
return result;
}
//
void Waits()
{
this.waitsUntilNext = true;
}
//
// Tools ...
void Clean()
{
//
symbol = NormalizeSymbol(NULL);
period = NormalizePeriod(NULL);
}
//
bool GetBar(
XOHCL &bar,
int index = 0 //
)
{
//
bool result = false;
//
result = bar.Init(
symbol,
period,
index //
);
//
return result;
}
//
bool GetBar(
XOHCL &bar,
datetime time = NULL //
)
{
//
bool result = false;
//
NormalizeTime(time);
//
int barIndex = iBarShift(
symbol,
period,
time,
false //
);
//
result = barIndex >= 0;
if (!result)
{
return result;
}
//
result = bar.Init(
symbol,
period,
barIndex //
);
//
return result;
}
//
int Index(datetime time = NULL)
{
//
int result = 0;
//
NormalizeTime(time);
//
result = iBarShift(
symbol,
period,
time,
false //
);
//
return result;
}
};
//
// Model a Market Cycle ...
struct XMarketCycle
{
//
// Props ...
//
string prefix; // Prefix Trag ...
//
string symbol; // Market Symbol ...
//
ENUM_TIMEFRAMES period; // Period of Cycle ...
ENUM_X_PERIOD_METHOD method; // Period Selection Method ...
ENUM_X_MARKET_CYCLES cycle; // Cycles of MArket ...
//
int length; // Number Of Candles per Current Time Frame ...
ENUM_TIMEFRAMES hostPeriod; // Current Time Frame ...
//
datetime lastStart; // Last Candle Bar Time ...
//
XBarTracker barTracker; // Bar Tracker ...
XBarRemainsTime remains; // Current Bar Remains Model ...
//
// Constructor ...
XMarketCycle()
{
Clean();
}
//
// Init Cycle ...
bool Init(
string mSymbol, // Trading Symbol
ENUM_TIMEFRAMES mHostPeriod, // Host Period
ENUM_X_MARKET_CYCLES mCycle, // Init Cycle
string mPrefix = "" // Prefix
)
{
//
bool result = false;
//
mSymbol = NormalizeSymbol(mSymbol);
mHostPeriod = NormalizePeriod(mHostPeriod);
//
result = IsValid(mCycle);
if (!result)
{
return result;
}
//
this.cycle = mCycle;
//
// Set Automatically Prefix ...
if (StringLen(mPrefix) == 0)
{
this.prefix = ToString(cycle);
}
//
result = IsValid(
method,
period //
);
if (!result)
{
return result;
}
//
this.symbol = mSymbol;
this.hostPeriod = mHostPeriod;
//
// Find Cycle Period ...
if (method == X_PERIOD_AUTO)
{
//
// Select Period ...
this.period = GetCyclePeriod(
this.cycle,
this.hostPeriod);
}
//
// Set Prefix if Provided ...
if (StringLen(mPrefix) > 0)
{
this.prefix = mPrefix;
}
//
// Calculate Required Info ...
//
// Length ...
this.length = PeriodSeconds(this.period) / PeriodSeconds(this.hostPeriod);
//
// Update Additional Data ...
result = this.Update(0);
//
return result;
}
//
bool Init(
string mSymbol, // Trading Symbol
ENUM_TIMEFRAMES mHostPeriod, // Host Period
ENUM_X_MARKET_CYCLES mCycle, // Init Cycle
ENUM_X_PERIOD_METHOD mMethod, // Period Selection Method
ENUM_TIMEFRAMES mPeriod, // Provided Period
string mPrefix = "" // Prefix
)
{
//
this.period = mPeriod;
this.method = mMethod;
//
return Init(
mSymbol,
mHostPeriod,
mCycle,
mPrefix
//
);
}
//
// Tools ...
//
// Cleanup ...
void Clean()
{
//
length = 0;
lastStart = 0;
//
cycle = NULL;
prefix = NULL;
symbol = NULL;
period = NULL;
method = NULL;
hostPeriod = NULL;
//
remains.Clean();
barTracker.Clean();
}
//
// Check Structure Valid ...
bool IsValid()
{
//
bool result = false;
//
result = IsValid(
method,
period);
if (!result)
{
return result;
}
//
result =
//
length > 0 &&
symbol != NULL &&
period != NULL &&
method != NULL &&
hostPeriod != NULL &&
method != X_PERIOD_NOTHING
//
;
//
return result;
}
//
// Update Market Cycle Additional Info ...
bool Update(int hostBarIndex)
{
//
bool result = false;
//
result = this.IsValid();
if (!result)
{
return result;
}
//
// Init Remains ...
result = remains.Init(
this.symbol,
this.period);
if (!result)
{
return result;
}
//
// Init Bar Tracker ...
result = barTracker.Init(
this.symbol,
this.period);
if (!result)
{
return result;
}
//
return result;
}
//
// Count Bars ...
int CountBars()
{
//
int result = 0;
//
if (!IsValid())
{
return result;
}
//
result = barTracker.CountBars();
//
return result;
}
//
// Check New Bar ...
bool IsNewBar()
{
//
bool result = false;
//
if (!IsValid())
{
return result;
}
//
result = barTracker.IsNewBar();
//
return result;
}
//
// Retrieve Current Bar Index based on Host Period bar Index ...
int GetBarIndex(int barIndex)
{
//
int result = 0;
//
if (!IsValid())
{
return result;
}
//
if (barIndex < 0)
{
return result;
}
//
int totalBars = CountBars();
if (barIndex >= totalBars)
{
//
result = totalBars - 1;
return result;
}
//
datetime hostBarTime = iTime(
this.symbol,
this.hostPeriod,
barIndex
//
);
//
result = iBarShift(
this.symbol,
this.period,
hostBarTime
//
);
//
return result;
}
//
// Retrieve Current Cycles Specific Bar ...
XOHCL GetBar(int barIndex)
{
//
if (barIndex < 0)
{
barIndex = 0;
}
//
int totalBars = CountBars();
if (barIndex >= totalBars)
{
barIndex = totalBars - 1;
}
//
XOHCL result;
result.Init(
this.symbol,
this.period,
barIndex
//
);
//
return result;
}
//
// Extract Specific Range of Bars ...
// using Start Bar Index ...
int GetBars(
XOHCL &result[], // Hold Result
int from = 0, // Start Bar Index
int count = 1, // Number of Bars
bool forceClean = true // Clean Result Array
)
{
//
int mResult = 0;
//
if (from < 0)
{
from = 0;
}
//
int total = Bars(
symbol,
period);
if (from > total - 2)
{
from = total - 2;
}
//
if (count < 0)
{
count = 1;
}
//
int start = from;
int end = start + count;
if (end > total - 1)
{
end = total - 1;
}
//
if (forceClean)
{
Clean(result);
}
//
int beforeSize = ArraySize(result);
//
for (int i = start; i < end; i++)
{
//
XOHCL iBar;
bool isValid = iBar.Init(
symbol,
period,
i
//
);
//
if (isValid)
{
//
AddRef(
iBar,
result
//
);
}
}
//
int afterSize = ArraySize(result);
//
mResult = afterSize - beforeSize;
//
return mResult;
}
//
// Extract Specific Range of Bars ...
// using Start Bar Time ...
int GetBars(
XOHCL &result[], // Hold Result
datetime from = NULL, // Start Bar Time
int count = 1, // Number of Bars
bool forceClean = true // Clean Result Array
)
{
//
from = NormalizeTime(from);
//
int barIndex = iBarShift(
symbol,
period,
from,
false
//
);
//
return GetBars(
result,
symbol,
period,
barIndex,
count,
forceClean
//
);
}
//
// Retrieve Bar Time ...
datetime GetBarTime(int barIndex)
{
//
datetime result = NULL;
//
if (!IsValid())
{
return result;
}
//
if (barIndex < 0)
{
barIndex = 0;
}
//
int totalBars = CountBars();
if (barIndex >= totalBars)
{
barIndex = totalBars - 1;
}
//
result = iTime(
this.symbol,
this.period,
barIndex
//
);
//
return result;
}
//
// Find Chart ID ...
ulong GetChartID()
{
//
ulong result = 0;
//
long firstChart = ChartFirst();
result = firstChart;
//
while (result >= 0)
{
//
string chSymbol = ChartSymbol(result);
ENUM_TIMEFRAMES chPeriod = ChartPeriod(result);
//
bool isOwnChart =
//
symbol == chSymbol &&
period == chPeriod
//
;
if (isOwnChart)
{
break;
}
//
result = ChartNext(result);
if (result < 0)
{
break;
}
}
//
return result;
}
//
// Create and String Representation for Unique Taging ...
string ToString()
{
//
string result = "";
//
if (!IsValid())
{
return result;
}
//
result =
GetTypeName(this) + "(" +
"PRFX(" + this.prefix + ")" +
"SMBL(" + this.symbol + ")" +
"CYC(" + ToString(this.cycle) + ")" +
"PRD(" + ToString(this.period) + ")" +
"PRDHST(" + ToString(this.hostPeriod) + ")" +
"MTH(" + EnumToString(this.method) + ")" +
")";
//
return result;
}
//
// Here we Produce a Summary brief of
// state of Cycle ...
string GenerateSummary()
{
//
string result = "";
//
bool hasPrefix =
StringLen(this.prefix) > 0 &&
this.prefix != ToString(this.cycle);
result += (hasPrefix ? this.prefix + "[" : "") +
ToString(this.cycle) +
(hasPrefix ? "]" : "") + "\n";
//
result += " - PR: " + ToString(this.period) + "\n";
//
XOHCL cBar = GetBar(0);
//
result += " - State: " + (cBar.IsBullish() ? "Bullish" : cBar.IsBearish() ? "Bearish"
: "Neutural");
//
return result;
}
};
//
// Linear Regression ...
//
struct XLinearRegressionWorkStruct
{
//
struct sDataStruct
{
//
double value;
double sumY;
double sumXY;
};
//
sDataStruct data[];
//
int dataSize;
int period;
double sumX;
double sumXX;
double divisor;
//
// Constructor ...
XLinearRegressionWorkStruct() : dataSize(-1), period(-1) {}
};
//
struct XLinearRegression
{
//
XLinearRegressionWorkStruct m_work;
//
// Calculate Linear Regression ...
double Calculate(
double value,
int period,
double &_slope,
double &_intercept,
int r,
int bars //
)
{
//
if (m_work.dataSize <= bars)
{
m_work.dataSize = ArrayResize(m_work.data, bars + 500, 2000);
}
//
if (period < 1)
{
period = 1;
}
//
if (m_work.period != (int)period)
{
//
m_work.period = (int)period;
m_work.sumX = m_work.period * (m_work.period - 1.0) / 2.0;
m_work.sumXX = m_work.period * (m_work.period - 1.0) * (2.0 * m_work.period - 1.0) / 6.0;
m_work.divisor = m_work.sumX * m_work.sumX - m_work.period * m_work.sumXX;
//
if (m_work.divisor)
{
m_work.divisor = 1.0 / m_work.divisor;
}
}
//
m_work.data[r].value = value;
//
if (r >= m_work.period)
{
//
m_work.data[r].sumY = m_work.data[r - 1].sumY + value - m_work.data[r - m_work.period].value;
m_work.data[r].sumXY = m_work.data[r - 1].sumXY + m_work.data[r].sumY - m_work.data[r - m_work.period].value * (m_work.period - 1.0) - value;
}
else
{
//
m_work.data[r].sumY = value;
m_work.data[r].sumXY = 0;
//
for (int _k = 1; _k < m_work.period && r >= _k; _k++)
{
//
m_work.data[r].sumY += m_work.data[r - _k].value;
m_work.data[r].sumXY += _k * m_work.data[r - _k].value;
}
}
//
_slope = (m_work.period * m_work.data[r].sumXY - m_work.sumX * m_work.data[r].sumY) * m_work.divisor;
_intercept = (m_work.data[r].sumY - _slope * m_work.sumX) / (double)m_work.period;
//
double result = (_intercept + _slope * (m_work.period - 1.0));
//
return result;
}
//
};
//
// Use To Parse Symbols for
// Ignore Brokers Additional Suffixes ...
struct XSymbolParser
{
//
string version; // Temp ...
//
// Forext ...
//
// Symbol Parsing ...
//
bool IsEURUSD(string symbol)
{
//
string symbolIdentifiers[] = {
"EUR",
"USD" //
};
//
bool result = Contains(
symbolIdentifiers,
symbol //
);
//
return result;
}
//
bool IsUSDJPY(string symbol)
{
//
string symbolIdentifiers[] = {
"USD",
"JPY" //
};
//
bool result = Contains(
symbolIdentifiers,
symbol //
);
//
return result;
}
//
bool IsEURJPY(string symbol)
{
//
string symbolIdentifiers[] = {
"EUR",
"JPY" //
};
//
bool result = Contains(
symbolIdentifiers,
symbol //
);
//
return result;
}
//
bool IsUSDCHF(string symbol)
{
//
string symbolIdentifiers[] = {
"USD",
"CHF" //
};
//
bool result = Contains(
symbolIdentifiers,
symbol //
);
//
return result;
}
//
bool IsEURCHF(string symbol)
{
//
string symbolIdentifiers[] = {
"EUR",
"CHF" //
};
//
bool result = Contains(
symbolIdentifiers,
symbol //
);
//
return result;
}
//
bool IsGBPUSD(string symbol)
{
//
string symbolIdentifiers[] = {
"GBP",
"USD" //
};
//
bool result = Contains(
symbolIdentifiers,
symbol //
);
//
return result;
}
//
bool IsEURGBP(string symbol)
{
//
string symbolIdentifiers[] = {
"EUR",
"GBP" //
};
//
bool result = Contains(
symbolIdentifiers,
symbol //
);
//
return result;
}
//
bool IsAUDUSD(string symbol)
{
//
string symbolIdentifiers[] = {
"AUD",
"USD" //
};
//
bool result = Contains(
symbolIdentifiers,
symbol //
);
//
return result;
}
//
bool IsEURAUD(string symbol)
{
//
string symbolIdentifiers[] = {
"EUR",
"AUD" //
};
//
bool result = Contains(
symbolIdentifiers,
symbol //
);
//
return result;
}
//
bool IsUSDCAD(string symbol)
{
//
string symbolIdentifiers[] = {
"USD",
"CAD" //
};
//
bool result = Contains(
symbolIdentifiers,
symbol //
);
//
return result;
}
//
bool IsEURCAD(string symbol)
{
//
string symbolIdentifiers[] = {
"EUR",
"CAD" //
};
//
bool result = Contains(
symbolIdentifiers,
symbol //
);
//
return result;
}
//
bool IsNZDUSD(string symbol)
{
//
string symbolIdentifiers[] = {
"NZD",
"USD" //
};
//
bool result = Contains(
symbolIdentifiers,
symbol //
);
//
return result;
}
//
bool IsEURNZD(string symbol)
{
//
string symbolIdentifiers[] = {
"EUR",
"NZD" //
};
//
bool result = Contains(
symbolIdentifiers,
symbol //
);
//
return result;
}
//
// Metals ...
//
bool IsXAUUSD(string symbol)
{
//
string symbolIdentifiers[] = {
"XAU",
"USD" //
};
//
bool result = Contains(
symbolIdentifiers,
symbol //
);
//
return result;
}
//
bool IsXAGUSD(string symbol)
{
//
string symbolIdentifiers[] = {
"XAG",
"USD" //
};
//
bool result = Contains(
symbolIdentifiers,
symbol //
);
//
return result;
}
//
// Symbol Finder ...
string GetEURUSDSymbol()
{
//
string result = NULL;
//
string symbols[];
int symbolsCount = GetAllSymbols(
symbols //
);
if (!IsValidSize(symbolsCount))
{
return result;
}
//
for (int i = 0; i < symbolsCount; i++)
{
//
string iSymbol = symbols[i];
if (IsEURUSD(iSymbol))
{
//
result = iSymbol;
break;
}
}
//
return result;
}
};
//
// Styling Buffers ...
//
struct XBufferPlotStyle
{
//
int width; // Width
color clr; // Color
uchar arrow; // Arrow Code
ENUM_DRAW_TYPE type; // Type
ENUM_LINE_STYLE style; // Style
//
// Constructor ...
XBufferPlotStyle()
{
Default();
}
//
// Tools ...
//
// Default ...
void Default()
{
//
width = 1;
arrow = 0;
clr = CLR_NONE;
type = DRAW_NONE;
style = STYLE_SOLID;
}
};
//
// Register a Buffer as Indexed Buffer ...
void SetIndexBuffer(
int &index, // the Index refrence for Buffer
double &buffer[], // Buffer to Set
XBufferPlotStyle &style, // Style to Apply to Buffer
double &colorBuffer[], // Color Buffer
string label = NULL, // Buffer Label
bool showData = true, // Show Data on Data Window
double empty = -1, // Set 0 or EMPTY_VALUE used for setting Empty Value
int drawBegin = -1 // if Set More Than -1 applied
)
{
//
// Set Buffer Index ...
SetIndexBuffer(index, buffer, INDICATOR_DATA);
//
// Show Date ...
PlotIndexSetInteger(index, PLOT_SHOW_DATA, showData);
//
// Set Buffer Label ...
if (IsValid(label))
{
PlotIndexSetString(index, PLOT_LABEL, label);
}
//
if (empty == 0 || empty == EMPTY_VALUE)
{
PlotIndexSetDouble(index, PLOT_EMPTY_VALUE, empty);
}
//
if (drawBegin > -1)
{
PlotIndexSetInteger(index, PLOT_DRAW_BEGIN, drawBegin);
}
//
if (style.type == DRAW_ARROW)
{
PlotIndexSetInteger(index, PLOT_ARROW, style.arrow);
}
//
PlotIndexSetInteger(index, PLOT_LINE_STYLE, style.style);
PlotIndexSetInteger(index, PLOT_LINE_WIDTH, style.width);
//
string drawTypeStr = EnumToString(style.type);
bool hasColorBuffer = Contains("COLOR", drawTypeStr);
//
if (!hasColorBuffer)
{
PlotIndexSetInteger(index, PLOT_LINE_COLOR, style.clr);
}
else
{
//
// Since Color Buffers must add as next Index of it's own Buffer
// here before applied Color Buffer increase index ...
index++;
//
SetIndexBuffer(index, colorBuffer, INDICATOR_COLOR_INDEX);
}
//
// Increase Index for Next Buffer ...
index++;
}
//
void SetIndexCandleBuffers(
int &index, // the Index refrence for Buffer
string openLabel, // Open Label
double &open[], // Open Buffer
string highLabel, // High Label
double &high[], // High Buffer
string lowLabel, // Low Label
double &low[], // Low Buffer
string closeLabel, // Close Label
double &close[], // Close Buffer
bool showData = true, // Show Data on Data Window
double empty = -1, // Set 0 or EMPTY_VALUE used for setting Empty Value
int drawBegin = -1 // if Set More Than -1 applied
)
{
//
bool hasLabel =
//
IsValid(openLabel) &&
IsValid(highLabel) &&
IsValid(lowLabel) &&
IsValid(closeLabel)
//
;
//
string label =
!hasLabel
? NULL
: openLabel + ";" + highLabel + ";" + lowLabel + ";" + closeLabel;
//
// Set Buffer Index ...
SetIndexBuffer(index, open, INDICATOR_DATA);
//
// Set Draw Candles Type ...
PlotIndexSetInteger(index, PLOT_LINE_STYLE, DRAW_CANDLES);
//
// Show Date ...
PlotIndexSetInteger(index, PLOT_SHOW_DATA, showData);
//
// Set Buffer Label ...
if (IsValid(label))
{
PlotIndexSetString(index, PLOT_LABEL, label);
}
//
if (empty == 0 || empty == EMPTY_VALUE)
{
PlotIndexSetDouble(index, PLOT_EMPTY_VALUE, empty);
}
//
if (drawBegin > -1)
{
PlotIndexSetInteger(index, PLOT_DRAW_BEGIN, drawBegin);
}
//
index++;
//
// Set Buffer Index ...
SetIndexBuffer(index, high, INDICATOR_DATA);
index++;
//
// Set Buffer Index ...
SetIndexBuffer(index, low, INDICATOR_DATA);
index++;
//
// Set Buffer Index ...
SetIndexBuffer(index, close, INDICATOR_DATA);
index++;
}
//
void SetIndexCandleBuffers(
int &index, // the Index refrence for Buffer
string openLabel, // Open Label
double &open[], // Open Buffer
string highLabel, // High Label
double &high[], // High Buffer
string lowLabel, // Low Label
double &low[], // Low Buffer
string closeLabel, // Close Label
double &close[], // Close Buffer
double &colorBuffer[], // Candle Color Buffer
bool showData = true, // Show Data on Data Window
double empty = -1, // Set 0 or EMPTY_VALUE used for setting Empty Value
int drawBegin = -1 // if Set More Than -1 applied
)
{
//
SetIndexCandleBuffers(
index,
openLabel,
open,
highLabel,
high,
lowLabel,
low,
closeLabel,
close,
showData,
empty,
drawBegin //
);
//
int mFirstIndex = index - 4;
//
// Set Draw Candles Type ...
PlotIndexSetInteger(mFirstIndex, PLOT_LINE_STYLE, DRAW_COLOR_CANDLES);
//
// Set Color Buffer ...
SetIndexBuffer(index, colorBuffer, INDICATOR_COLOR_INDEX);
//
index++;
}
//
// Functions ...
//
// Validators ...
//
// Validate an String has length and not NULL ...
bool IsValid(string value)
{
//
bool result = false;
//
result =
//
value != NULL &&
StringLen(value) > 0
//
;
//
return result;
}
bool IsSpecifiedValid(string value)
{
return IsValid(value);
}
//
// Validate a Date ...
bool IsValid(datetime value)
{
//
bool result = false;
//
result = NotEmpty(value) && value != NULL;
//
return result;
}
bool IsSpecifiedValid(datetime value)
{
return IsValid(value);
}
//
// Validate a Period Param ...
bool IsValid(ENUM_TIMEFRAMES value)
{
//
bool result = false;
//
result =
//
value != NULL
//
;
//
return result;
}
bool IsSpecifiedValid(ENUM_TIMEFRAMES value)
{
//
return IsValid(value);
}
//
// Validate Specified Cycle ...
bool IsValid(ENUM_X_MARKET_CYCLES value)
{
//
bool result = false;
//
result =
//
value != NULL &&
value != X_MARKET_CYCLE_UNKNOWN
//
;
//
return result;
}
//
// Validate Specific Period Mode ...
bool IsValid(
ENUM_X_PERIOD_METHOD mMethod, // Period Select Method
ENUM_TIMEFRAMES mPeriod // Selected Period
)
{
//
bool result = false;
//
result =
//
mMethod == X_PERIOD_NOTHING
? false
: mMethod == X_PERIOD_MANUALLY
? mPeriod != NULL
: mMethod == X_PERIOD_AUTO
? true
: false
//
;
//
return result;
}
//
bool IsSpecifiedValid(
ENUM_X_PERIOD_METHOD mMethod, // Period Select Method
ENUM_TIMEFRAMES mPeriod // Selected Period
)
{
return IsValid(mMethod,
mPeriod //
);
}
//
// Validate Swing Mode ...
bool IsValid(ENUM_X_SWING_TYPE value)
{
//
bool result = false;
//
result =
//
value == X_SWING_HIGH ||
value == X_SWING_LOW
//
;
//
return result;
}
//
// As IS ...
//
// Determine a Position type is Long or not ...
bool IsLong(ENUM_POSITION_TYPE type)
{
//
bool result = type == POSITION_TYPE_BUY;
//
return result;
}
bool IsLong(ENUM_ORDER_TYPE type)
{
//
bool result = type == ORDER_TYPE_BUY;
//
return result;
}
//
// Determine a Position type is Short or not ...
bool IsShort(ENUM_POSITION_TYPE type)
{
//
bool result = type == POSITION_TYPE_SELL;
//
return result;
}
bool IsShort(ENUM_ORDER_TYPE type)
{
//
bool result = type == ORDER_TYPE_SELL;
//
return result;
}
//
// Retrieve Opposit Direction Type ...
ENUM_POSITION_TYPE GetOpposit(ENUM_POSITION_TYPE type)
{
//
ENUM_POSITION_TYPE result = NULL;
//
bool isLong = IsLong(type);
result = isLong
? POSITION_TYPE_SELL
: POSITION_TYPE_BUY;
//
return result;
}
ENUM_ORDER_TYPE GetOpposit(ENUM_ORDER_TYPE type)
{
//
ENUM_ORDER_TYPE result = NULL;
//
bool isLong = IsLong(type);
result = isLong
? ORDER_TYPE_SELL
: ORDER_TYPE_BUY;
//
return result;
}
//
string ToString(ENUM_POSITION_TYPE value)
{
//
string result = NULL;
//
result =
//
IsLong(value)
? "Long"
: "Short"
//
;
//
return result;
}
string ToString(ENUM_ORDER_TYPE value)
{
//
string result = NULL;
//
result =
//
IsLong(value)
? "Long"
: "Short"
//
;
//
return result;
}
//
// Check Expert Running in Testing Mode or not ...
bool IsRunningOnTestMode()
{
//
bool result = false;
//
// check programm mode ...
result = MQL5InfoInteger(MQL5_TESTING);
//
return result;
}
//
// Find Chart ID ...
long FindChartID(
string mSymbol = NULL, // Trading Symbol
ENUM_TIMEFRAMES mPeriod = NULL // Trading Period
)
{
//
long result = ChartFirst();
long first = result;
//
while (result > 0)
{
//
string chSymbol = ChartSymbol(result);
ENUM_TIMEFRAMES chPeriod = ChartPeriod(result);
//
bool isOwn =
//
chSymbol == mSymbol &&
chPeriod == mPeriod
//
;
if (isOwn)
{
break;
}
//
result = ChartNext(result);
}
//
return result;
}
//
// Normalizers ...
//
// Check a Symbol provided or not ...
// if not use Default ...
string NormalizeSymbol(string value)
{
//
string result = value;
//
if (!IsValid(result))
{
result = _Symbol;
}
//
return result;
}
//
// Check a Datetime provided or not ...
// if not use Current ...
datetime NormalizeTime(datetime value)
{
//
datetime result = value;
//
if (!IsValid(result))
{
result = TimeCurrent();
}
//
return result;
}
//
// Check a Period provided or not ...
// if not use Default ...
ENUM_TIMEFRAMES NormalizePeriod(ENUM_TIMEFRAMES value)
{
//
ENUM_TIMEFRAMES result = value;
//
if (!IsValid(value))
{
result = _Period;
}
//
return result;
}
//
// Normalize Cycle ...
ENUM_X_MARKET_CYCLES NormalizeCycle(ENUM_X_MARKET_CYCLES value)
{
//
ENUM_X_MARKET_CYCLES result = value;
//
if (!IsValid(result))
{
result = X_MARKET_CYCLE_SHORT;
}
//
return value;
}
//
// Validate a Buffer Size for Looping or etc ...
bool IsValidSize(int size)
{
//
bool result = size > 0;
//
return result;
}
template <typename T>
bool IsValidSize(T &buffer[])
{
//
bool result = false;
//
result =
//
IsValidSize(ArraySize(buffer))
//
;
//
return result;
}
//
// Check a Given Index is Valid or not ...
bool IsValidIndex(int index)
{
return index >= 0;
}
//
// Normalize Index Based On Specified Buffer ...
template <typename T>
void NormalizeIndex(
int &index,
T &buffer[] //
)
{
//
int bufferSize = ArraySize(buffer);
//
if (bufferSize <= 0)
{
index = 0;
}
//
if (index <= 0)
{
index = 0;
}
//
if (index > bufferSize - 1)
{
index = bufferSize - 1;
}
}
//
// Normalize Start and Count based on Specified Buffer ...
template <typename T>
void NormalizeCount(
int &start,
int &count,
T &buffer[] //
)
{
//
// Validate Buffer Size ...
int bufferSize = ArraySize(buffer);
if (!IsValidSize(bufferSize))
{
return;
}
//
// Normalization Start ...
NormalizeIndex(
start,
buffer //
);
//
if (count < start)
{
count = (start - count);
}
//
// Normalization Count ...
//
if (count < 0)
{
count = start;
}
//
if (count > bufferSize)
{
count = bufferSize;
}
}
//
// Normalize a give Volume ...
double NormalizeVolume(
double mVolume, // desired volume to normalize
string mSymbol = NULL, // Trading Symbol
int mLength = 2 // Length of Digits
)
{
//
double result = mVolume;
//
mSymbol = NormalizeSymbol(mSymbol);
//
// Normalize Digits ...
int digits = GetDigits(mSymbol);
//
mLength =
mLength == 0 || mLength > digits
? digits
: MathMin(mLength, digits);
//
// Normalize Volume ...
result = NormalizeDouble(result, mLength);
//
double maxAvailableVolume = SymbolInfoDouble(mSymbol, SYMBOL_VOLUME_MAX);
double minAvailableVolume = SymbolInfoDouble(mSymbol, SYMBOL_VOLUME_MIN);
//
// Validate Result ...
if (result > maxAvailableVolume)
{
result = maxAvailableVolume;
}
else if (result < minAvailableVolume)
{
result = minAvailableVolume;
}
//
return result;
}
//
// Normallize Price ...
double NormalizePrice(
double mPrice, // desired Price for normalization
string mSymbol = NULL // Trading Symbol
)
{
//
double result = 0;
//
mSymbol = NormalizeSymbol(mSymbol);
//
double tickSize = 0;
result = SymbolInfoDouble(mSymbol, SYMBOL_TRADE_TICK_SIZE, tickSize);
//
int digits = GetDigits(mSymbol);
result = NormalizeDouble(MathRound(mPrice / tickSize) * tickSize, digits);
//
return result;
}
//
// Prices ...
//
// Retrieve Ask Price ...
double GetAsk(
string mSymbol = NULL // Trading Symbol
)
{
//
mSymbol = NormalizeSymbol(mSymbol);
//
double result = SymbolInfoDouble(mSymbol, SYMBOL_ASK);
//
return result;
}
//
// Retrieve Bid Price ...
double GetBid(
string mSymbol = NULL // Trading Symbol
)
{
//
mSymbol = NormalizeSymbol(mSymbol);
//
double result = SymbolInfoDouble(mSymbol, SYMBOL_BID);
//
return result;
}
//
// Retrieve Spread Price ...
double GetSpread(
string mSymbol = NULL // Trading Symbol
)
{
//
mSymbol = NormalizeSymbol(mSymbol);
//
double ask = GetAsk(mSymbol);
double bid = GetBid(mSymbol);
//
double result = MathAbs(ask - bid);
//
return result;
}
//
// Retrieve Point Value ...
double GetPoints(
string mSymbol = NULL // Trading Symbol
)
{
//
mSymbol = NormalizeSymbol(mSymbol);
//
double result = SymbolInfoDouble(mSymbol, SYMBOL_POINT);
//
return result;
}
//
// Retrieve Point Digits ...
int GetDigits(
string mSymbol = NULL // Trading Symbol
)
{
//
mSymbol = NormalizeSymbol(mSymbol);
//
int result = (int)SymbolInfoInteger(mSymbol, SYMBOL_DIGITS);
//
return result;
}
//
// Retrieve Entry Price ...
double GetEntry(
string mSymbol = NULL, // Trading Symbol
ENUM_POSITION_TYPE type = POSITION_TYPE_BUY // Get entry price for Which direction trade ...
)
{
//
double result = 0;
//
mSymbol = NormalizeSymbol(mSymbol);
//
result =
IsLong(type)
? GetAsk(mSymbol)
: GetBid(mSymbol);
result = NormalizePrice(result, mSymbol);
//
return result;
}
//
// Retrieve Exit Price ...
double GetExit(
string mSymbol = NULL, // Trading Symbol
ENUM_POSITION_TYPE type = POSITION_TYPE_BUY // Get entry price for Which direction trade ...
)
{
//
double result = 0;
//
mSymbol = NormalizeSymbol(mSymbol);
//
result =
IsLong(type)
? GetBid(mSymbol)
: GetAsk(mSymbol);
result = NormalizePrice(result, mSymbol);
//
return result;
}
//
// Get 1 Pip in Price Value ...
double GetPipPrice(
string mSymbol = NULL // Trading Symbol
)
{
//
mSymbol = NormalizeSymbol(mSymbol);
//
double symbolPoint = GetPoints(mSymbol);
int symbolDigits = GetDigits(mSymbol);
//
double result = symbolPoint;
if (symbolDigits == 3 || symbolDigits == 5)
{
result *= 10;
}
//
return result;
}
//
// Converts Pips To Price ...
double PipsToPrice(
double mPips, // pips amount
string mSymbol = NULL // Trading Symbol
)
{
//
mSymbol = NormalizeSymbol(mSymbol);
//
int digits = GetDigits(mSymbol);
double pipValue = GetPipPrice(mSymbol);
double result = mPips * pipValue;
//
result = NormalizePrice(result, mSymbol);
//
return result;
}
//
// Converts Price to Pips ...
double PriceToPips(
double mPrice, // the price amount which required to calculate
string mSymbol = NULL // Trading Symbol
)
{
//
mSymbol = NormalizeSymbol(mSymbol);
mPrice = NormalizePrice(mPrice, mSymbol);
//
int digits = GetDigits(mSymbol);
double pipPrice = GetPipPrice(mSymbol);
//
double result = mPrice / pipPrice;
//
result = NormalizeDouble(result, digits);
//
return result;
}
//
// Convert Price to Point ...
double PriceToPoint(
double price, // the price amount which required to calculate
string mSymbol = NULL // Trading Symbol
)
{
//
double result = 0;
//
mSymbol = NormalizeSymbol(mSymbol);
price = NormalizePrice(price, mSymbol);
//
double point = GetPoints(mSymbol);
result = price / point;
//
return result;
}
//
// Converts Point to Price ...
double PointToPrice(
double points, // Points Amount
string mSymbol = NULL // Trading Symbol
)
{
//
double result = 0;
//
mSymbol = NormalizeSymbol(mSymbol);
//
double point = GetPoints(mSymbol);
result = points * point;
//
result = NormalizePrice(result, mSymbol);
//
return result;
}
//
// Converts Series Mode to XPRICE ...
ENUM_X_PRICE ToPrice(
ENUM_SERIESMODE mMode // Specified Series Mode ...
)
{
//
ENUM_X_PRICE result = X_PRICE_CLOSE;
//
switch (mMode)
{
//
// High ...
case MODE_HIGH:
result = X_PRICE_HIGH;
break;
//
// Open ...
case MODE_OPEN:
result = X_PRICE_OPEN;
break;
//
// Low ...
case MODE_LOW:
result = X_PRICE_LOW;
break;
//
// Close ...
// Default ...
case MODE_CLOSE:
default:
result = X_PRICE_CLOSE;
break;
}
//
return result;
}
//
// Retrieve Applied Price ...
template <typename T>
double GetAppliedPrice(
ENUM_APPLIED_PRICE tprice, // Type of Price Selection
T &open[], // Open Prices
T &high[], // High Preices
T &low[], // Low Prices
T &close[], // Close Prices
int i // Bar Index
)
{
switch (tprice)
{
case PRICE_CLOSE:
return (close[i]);
case PRICE_OPEN:
return (open[i]);
case PRICE_HIGH:
return (high[i]);
case PRICE_LOW:
return (low[i]);
case PRICE_MEDIAN:
return ((high[i] + low[i]) / 2.0);
case PRICE_TYPICAL:
return ((high[i] + low[i] + close[i]) / 3.0);
case PRICE_WEIGHTED:
return ((high[i] + low[i] + close[i] + close[i]) / 4.0);
}
return (0);
}
//
double iGetPrice(
int tprice,
double open,
double high,
const double low,
const double close //
)
{
//
switch (tprice)
{
case PRICE_CLOSE:
return (close);
case PRICE_OPEN:
return (open);
case PRICE_HIGH:
return (high);
case PRICE_LOW:
return (low);
case PRICE_MEDIAN:
return ((high + low) / 2.0);
case PRICE_TYPICAL:
return ((high + low + close) / 3.0);
case PRICE_WEIGHTED:
return ((high + low + close + close) / 4.0);
}
//
return (0);
}
//
// Calculate TP/SL for Specified Type of Positions ...
void CalculateTPSL(
double &mSL, // Hold SL
double &mTP, // Hold TP
ENUM_POSITION_TYPE mType, // Position Type Long (Buy) / Short (Sell)
double mEntry, // Entry Price
double mR2R = 1, // Provided Risk To Reward Ratio
double slPrice = 0, // Provided SL Price
double tpPrice = 0, // Provided TP Price
double priceToRisk = 0, // If Entry equal to Provided SL Price Risk Point
double priceToReward = 0 // If Entry equal to Provided TP Price Reward Point
)
{
//
// if Both TP and SL Provided, ignore R2R and Calculate direct ...
// if SL provided, Calculate TP based on Provided R2R ...
// if TP provided, Calculate SL based on Provided R2R ...
// default R2R is set to 1 ...
//
mSL = 0;
mTP = 0;
//
bool isLong = IsLong(mType);
//
// Set Default R2R ...
if (mR2R < 1)
{
mR2R = 1;
}
//
if (mEntry <= 0 ||
(tpPrice <= 0 && slPrice <= 0))
{
return;
}
//
double risk = 0;
double reward = 0;
//
bool canCalculateBasedOnSL = slPrice > 0 &&
(isLong
? slPrice <= mEntry
: slPrice >= mEntry);
//
bool canCalculateBasedOnTP = tpPrice > 0 &&
(isLong
? tpPrice >= mEntry
: tpPrice <= mEntry);
//
if (canCalculateBasedOnSL && !canCalculateBasedOnTP)
{
//
risk = MathAbs(mEntry - slPrice);
if (risk == 0)
{
risk = priceToRisk;
}
reward = risk * mR2R;
}
else if (!canCalculateBasedOnSL && canCalculateBasedOnTP)
{
//
reward = MathAbs(mEntry - tpPrice);
if (reward == 0)
{
reward = priceToReward;
}
risk = reward / mR2R;
}
else if (!canCalculateBasedOnSL && !canCalculateBasedOnTP)
{
//
bool canSetTPPrice = isLong
? tpPrice > mEntry
: tpPrice < mEntry;
if (canSetTPPrice)
{
mTP = tpPrice;
}
//
bool canSetSLPrice = isLong
? slPrice < mEntry
: slPrice > mEntry;
if (canSetSLPrice)
{
mSL = slPrice;
}
//
return;
}
else if (canCalculateBasedOnSL && canCalculateBasedOnTP)
{
//
bool canSetTPPrice = isLong
? tpPrice > mEntry
: tpPrice < mEntry;
if (canSetTPPrice)
{
mTP = tpPrice;
}
//
bool canSetSLPrice = isLong
? slPrice < mEntry
: slPrice > mEntry;
if (canSetSLPrice)
{
mSL = slPrice;
}
//
return;
}
//
mTP = isLong
? mEntry + reward
: mEntry - reward;
//
mSL = isLong
? mEntry - risk
: mEntry + risk;
}
//
bool CalculateTPSLByPoint(
double &mSL, // Hold SL
double &mTP, // Hold TP
ENUM_POSITION_TYPE mType, // Position Type Long (Buy) / Short (Sell)
double mEntry, // Entry Price
double mPointValue, // Point Value
double mR2R = 1, // Provided Risk To Reward Ratio
double slPoint = 0, // Provided SL Point
double tpPoint = 0 // Provided TP Point
)
{
//
bool result = false;
//
mSL = 0;
mTP = 0;
//
bool isLong = IsLong(mType);
//
// Set Default R2R ...
if (mR2R < 1)
{
mR2R = 1;
}
//
if (mEntry <= 0 ||
mPointValue <= 0 ||
(slPoint <= 0 && tpPoint <= 0))
{
return result;
}
//
double risk = 0;
double reward = 0;
//
bool canCalculateBasedOnSL = slPoint > 0;
//
bool canCalculateBasedOnTP = tpPoint > 0;
//
if (!canCalculateBasedOnSL && !canCalculateBasedOnTP)
{
return result;
}
//
if (canCalculateBasedOnSL && canCalculateBasedOnTP)
{
//
reward = tpPoint * mPointValue;
risk = slPoint * mPointValue;
}
else if (!canCalculateBasedOnSL && canCalculateBasedOnTP)
{
//
reward = tpPoint * mPointValue;
risk = reward / mR2R;
}
else if (canCalculateBasedOnSL && !canCalculateBasedOnTP)
{
//
risk = slPoint * mPointValue;
reward = risk * mR2R;
}
//
result = risk > 0 && reward > 0;
if (!result)
{
return result;
}
//
mTP = isLong
? mEntry + reward
: mEntry - reward;
//
mSL = isLong
? mEntry - risk
: mEntry + risk;
//
return result;
}
//
bool CalculateTPSLByPrice(
double &mSL, // Hold SL
double &mTP, // Hold TP
ENUM_POSITION_TYPE mType, // Position Type Long (Buy) / Short (Sell)
double mEntry, // Entry Price
double mR2R = 1 // Provided Risk To Reward Ratio
)
{
//
bool result = false;
//
bool isLong = IsLong(mType);
//
// Set Default R2R ...
if (mR2R < 1)
{
mR2R = 1;
}
//
if (mEntry <= 0 ||
(mSL <= 0 && mTP <= 0))
{
return result;
}
//
double risk = 0;
double reward = 0;
//
bool canCalculateBasedOnSL = mSL > 0;
bool canCalculateBasedOnTP = mTP > 0;
//
if (
!canCalculateBasedOnSL &&
!canCalculateBasedOnTP)
{
return result;
}
//
if (!canCalculateBasedOnSL && canCalculateBasedOnTP)
{
//
reward = MathAbs(mTP - mEntry);
risk = reward / mR2R;
}
else if (canCalculateBasedOnSL && !canCalculateBasedOnTP)
{
//
risk = MathAbs(mEntry - mSL);
reward = risk * mR2R;
}
//
result = risk > 0 && reward > 0;
if (!result)
{
return result;
}
//
mTP = isLong
? mEntry + reward
: mEntry - reward;
//
mSL = isLong
? mEntry - risk
: mEntry + risk;
//
return result;
}
//
bool GetTick(
string mSymbol,
MqlTick &tick //
)
{
return SymbolInfoTick(mSymbol, tick);
}
//
// Symbols ...
//
// Retrieve Available Symbols ...
int GetAllSymbols(
string &symbols[], // Hold Result
bool onlyInWatchList = false, // Specified Retrieve only Symbols which in Watch List
bool forceClean = true // Force To Clean Result Array
)
{
//
int result = 0;
//
if (forceClean)
{
Clean(symbols);
}
//
int beforeSize = ArraySize(symbols);
//
int symbolsCount = SymbolsTotal(onlyInWatchList);
if (symbolsCount <= 0)
{
return result;
}
//
for (int i = 0; i < symbolsCount; i++)
{
//
string iSymbol = SymbolName(
i,
onlyInWatchList
//
);
if (!IsValid(iSymbol))
{
continue;
}
//
Add(
iSymbol,
symbols
//
);
}
//
int afterSize = ArraySize(symbols);
//
result = afterSize - beforeSize;
//
return result;
}
//
// This is a Global Way to Filter Symbols
// you can pass Specific string as Query or a List String for Filtering ...
int FilterSymbols(
string query, // Which Query to Search Symbol
string &symbols[], // Hold Result
bool onlyInWatchList = false, // Specified Retrieve only Symbols which in Watch List
bool forceClean = true, // Force To Clean Result Array
bool ignoreCase = true, // Ignore Case
string querySeparator = "," // If Provided means query is a COllection of Queries and need to be Splitted
)
{
//
int result = 0;
//
if (forceClean)
{
Clean(symbols);
}
//
if (!IsValid(query))
{
return result;
}
//
// Check Query is an String array or not ...
string mQueries[];
int queriesCount = 0;
if (IsValid(querySeparator) && Contains(querySeparator, query, true))
{
//
queriesCount = SplitContent(
mQueries,
query,
querySeparator
//
);
}
//
int beforeSize = ArraySize(symbols);
//
string allSymbols[];
int allSymbolsCount = GetAllSymbols(
allSymbols,
onlyInWatchList,
forceClean);
if (allSymbolsCount <= 0)
{
return result;
}
//
// Loop Through all Symbols ...
for (int i = 0; i < allSymbolsCount; i++)
{
//
string iSymbol = allSymbols[i];
//
bool isFilterPassed = false;
if (queriesCount == 0)
{
//
isFilterPassed = Contains(
query,
iSymbol,
ignoreCase
//
);
}
else if (queriesCount > 0)
{
//
isFilterPassed = Contains(
mQueries,
iSymbol,
ignoreCase
//
);
}
//
if (isFilterPassed)
{
//
Add(
iSymbol,
symbols
//
);
}
}
//
int afterSize = ArraySize(symbols);
//
result = afterSize - beforeSize;
//
return result;
}
//
int FilterUSDSymbols(
string &symbols[], // Hold Result
bool onlyInWatchList = false, // Specified Retrieve only Symbols which in Watch List
bool forceClean = true, // Force To Clean Result Array
bool ignoreCase = true, // Ignore Case
string querySeparator = "," // If Provided means query is a COllection of Queries and need to be Splitted
)
{
//
return FilterSymbols(
"USD",
symbols,
onlyInWatchList,
forceClean,
ignoreCase,
querySeparator
//
);
}
//
// Time / Date ...
//
// Representation of Time Struct ...
// struct MqlDateTime
// {
// int year; // Year
// int mon; // Month
// int day; // Day
// int hour; // Hour
// int min; // Minutes
// int sec; // Seconds
// int day_of_week; // Day of week (0-Sunday, 1-Monday, ... ,6-Saturday)
// int day_of_year; // Day number of the year (January 1st is assigned the number value of zero)
// };
//
// Converts Time to Seconds ...
ulong TimeToSeconds(
datetime time // Specify time to Convert ...
)
{
//
ulong result = (ulong)time;
//
return result;
}
ulong TimeToSeconds(
MqlDateTime &time // Specify time to Convert ...
)
{
//
datetime dTime = StructToTime(time);
//
ulong result = TimeToSeconds(dTime);
//
return result;
}
//
// Converts Seconds To Time ...
datetime SecondsToTime(
ulong seconds // Specify Seconds to Convert ...
)
{
//
datetime result = (datetime)seconds;
//
return result;
}
MqlDateTime SecondsToStruct(
ulong seconds // Specify Seconds to Convert ...
)
{
//
datetime dTime = SecondsToTime(seconds);
//
MqlDateTime result = {};
TimeToStruct(
dTime,
result);
//
return result;
}
//
// Converts Time to MilliSeconds ...
ulong TimeToMilliSeconds(
datetime time // Specify time to Convert ...
)
{
//
ulong result = TimeToSeconds(time) * 1000;
//
return result;
}
ulong TimeToMilliSeconds(
MqlDateTime &time // Specify time to Convert ...
)
{
//
datetime dTime = StructToTime(time);
//
ulong result = TimeToMilliSeconds(dTime);
//
return result;
}
//
// Converts MillisSeconds to Time ...
datetime MilliSecondsToTiem(
ulong milliSeconds // Specify MilliSeconds to Convert ...
)
{
//
ulong seconds = milliSeconds / 1000;
//
datetime result = SecondsToTime(seconds);
//
return result;
}
MqlDateTime MilliSecondsToStruct(
ulong milliSeconds // Specify MilliSeconds to Convert ...
)
{
//
datetime dTime = MilliSecondsToTiem(milliSeconds);
//
MqlDateTime result = {};
TimeToStruct(
dTime,
result);
//
return result;
}
//
// Retrieve DateTime Structure ...
MqlDateTime GetCurrentTime()
{
//
MqlDateTime result = {};
//
TimeCurrent(result);
//
return result;
}
//
// Retrieve Current Time as Seconds ...
ulong GetCurrentTimeAsSeconds()
{
//
datetime time = TimeCurrent();
//
ulong result = TimeToSeconds(time);
//
return result;
}
//
// Retrieve Current Time as MilliSeconds ...
ulong GetCurrentTimeAsMilliSeconds()
{
//
datetime time = TimeCurrent();
//
ulong result = TimeToMilliSeconds(time);
//
return result;
}
//
// Converts a Date time to File Format ...
string ToFormatString(
datetime mTime,
string separator = "_" //
)
{
//
string result = NULL;
//
if (!IsValid(mTime))
{
return result;
}
//
MqlDateTime timeStruct;
bool isConverts = TimeToStruct(
mTime,
timeStruct //
);
if (!isConverts)
{
return result;
}
//
string year = ToString(timeStruct.year);
string month = ToString(timeStruct.mon);
string day = ToString(timeStruct.day);
string hour = ToString(timeStruct.hour);
string minute = ToString(timeStruct.min);
string second = ToString(timeStruct.sec);
//
result =
//
// Year ...
year + separator +
//
// Month ...
(StringLen(month) == 1
? "0" + month
: month) +
separator +
//
// Day ...
(StringLen(day) == 1
? "0" + day
: day) +
separator +
//
// Hour ...
(StringLen(hour) == 1
? "0" + hour
: hour) +
separator +
//
// Minute ...
(StringLen(minute) == 1
? "0" + minute
: minute) +
separator +
//
// Seconds ...
(StringLen(second) == 1
? "0" + second
: second) +
separator +
//
""
//
;
//
return result;
}
//
// Bar Times ...
//
// Retrieve Specified Bar Time ...
datetime GetBarTime(
string mSymbol = "", // Specify Symbol
ENUM_TIMEFRAMES mPeriod = NULL, // Specify TimeFrame
int barIndex = 0 // Specify Bar Index
)
{
//
// Validate and Normalize Args ...
//
mSymbol = NormalizeSymbol(mSymbol);
mPeriod = NormalizePeriod(mPeriod);
//
// Retrieve Bar Time ...
datetime result = iTime(
mSymbol,
mPeriod,
barIndex);
//
return result;
}
//
// Retrieve Specified Bar Time ...
ulong GetBarTimeAsSeconds(
string mSymbol = "", // Specify Symbol
ENUM_TIMEFRAMES mPeriod = NULL, // Specify TimeFrame
int barIndex = 0 // Specify Bar Index
)
{
//
// Retrieve Bar Time ...
datetime time = GetBarTime(
mSymbol,
mPeriod,
barIndex);
//
ulong result = TimeToSeconds(time);
//
return result;
}
//
// Retrieve Specified Bar Time ...
ulong GetBarTimeAsMilliSeconds(
string mSymbol = "", // Specify Symbol
ENUM_TIMEFRAMES mPeriod = NULL, // Specify TimeFrame
int barIndex = 0 // Specify Bar Index
)
{
//
// Retrieve Bar Time ...
datetime time = GetBarTime(
mSymbol,
mPeriod,
barIndex);
//
ulong result = TimeToMilliSeconds(time);
//
return result;
}
//
// Retrieve a Bar Time Structure ...
MqlDateTime GetBarTimeStruct(
string mSymbol = "", // Specify Symbol
ENUM_TIMEFRAMES mPeriod = NULL, // Specify TimeFrame
int barIndex = 0 // Specify Bar Index
)
{
//
MqlDateTime result = {};
//
// Retrieve Bar Time ...
datetime barTime = GetBarTime(
mSymbol,
mPeriod,
barIndex);
//
// Convert to Structure ...
TimeToStruct(barTime, result);
//
return result;
}
//
// Other Tools ...
//
template <typename T>
bool IsSame(
T &buffer[], // Search Buffer
int count = 5, // Number of Searchs
int start = 0 // Start ...
)
{
//
bool result = false;
//
int bufferSize = ArraySize(buffer);
result = bufferSize > 0;
if (!result)
{
return result;
}
//
// Validate Count ...
result = start + count < bufferSize;
if (!result)
{
return result;
}
//
T iTem = buffer[start];
for (int i = start; i < start + count; i++)
{
//
if (iTem != buffer[i])
{
result = false;
break;
}
//
if (!result)
{
result = true;
}
}
//
return result;
}
//
// Check first Cross Over second at index ...
bool IsCrossedOver(
const double &first[], // the buffer which check crossing over second buffer
const double &second[], // first buffer checks based on this buffer
const int index = 0 // check crosses in specific index
)
{
//
bool result = false;
//
// Validate Args ...
if (ArraySize(first) < index + 1 || ArraySize(second) < index + 1)
{
return result;
}
//
result = first[index] > second[index] &&
!(first[index + 1] > second[index + 1]);
//
return result;
}
//
// Check first is Over second at index ...
bool IsOver(
const double &first[], // the buffer which check over second buffer
const double &second[], // first buffer checks based on this buffer
const int index = 0 // check crosses in specific index
)
{
//
bool result = false;
//
// Validate Args ...
if (ArraySize(first) < index + 1 || ArraySize(second) < index + 1)
{
return result;
}
//
result = first[index] > second[index] &&
first[index + 1] > second[index + 1];
//
return result;
}
//
// Check first Cross Under second at index ...
bool IsCrossedUnder(
const double &first[], // the buffer which check crossing under second buffer
const double &second[], // first buffer checks based on this buffer
const int index = 0 // check crosses in specific index
)
{
//
bool result = false;
//
// Validate Args ...
if (ArraySize(first) < index + 1 || ArraySize(second) < index + 1)
{
return result;
}
//
result = first[index] < second[index] &&
!(first[index + 1] < second[index + 1]);
//
return result;
}
//
// Check first is Under second at index ...
bool IsUnder(
const double &first[], // the buffer which check under second buffer
const double &second[], // first buffer checks based on this buffer
const int index = 0 // check crosses in specific index
)
{
//
bool result = false;
//
// Validate Args ...
if (ArraySize(first) < index + 1 || ArraySize(second) < index + 1)
{
return result;
}
//
result = first[index] < second[index] &&
first[index + 1] < second[index + 1];
//
return result;
}
//
// Check if a Value Increasing in Loopback ...
bool IsIncreasing(
const int from, // Last Time Index
const int to, // Fisrs Tima Index
const double &buffer[] // the Buffer which required to search
)
{
//
bool result = false;
//
// Validate Args ...
if (
from <= to ||
ArraySize(buffer) < from + 1)
{
return result;
}
//
// Loop through Items ...
double toValue = buffer[to];
double fromValue = buffer[from];
result = toValue > fromValue;
for (int i = to + 1; i <= from - 1; i++)
{
//
double iValue = buffer[i];
bool isPassed = toValue >= iValue;
//
bool isIIncreasing = IsIncreasing(
from,
i,
buffer);
//
// Check Result ...
result = result && isPassed && isIIncreasing;
if (!result)
{
break;
}
}
//
return result;
}
//
// Check if a Value Decreasing in Loopback ...
bool IsDecreasing(
const int from, // Last Time Index
const int to, // Fisr Tima Index
const double &buffer[] // the Buffer which required to search
)
{
//
bool result = false;
//
// Validate Args ...
if (
from <= to ||
ArraySize(buffer) < from + 1)
{
return result;
}
//
// Loop through Items ...
double toValue = buffer[to];
double fromValue = buffer[from];
result = toValue < fromValue;
for (int i = to + 1; i <= from - 1; i++)
{
//
double iValue = buffer[i];
bool isPassed = toValue <= iValue;
//
bool isIDecreasing = IsDecreasing(
from,
i,
buffer);
//
// Check Result ...
result = result && isPassed && isIDecreasing;
if (!result)
{
break;
}
}
//
return result;
}
//
bool IsTrendingUp(
const double &buffer1[], // First Buffer
const double &buffer2[] // Seccend Buffer
)
{
//
bool result = false;
//
int buffer1Count = ArraySize(buffer1);
int buffer2Count = ArraySize(buffer2);
if (buffer1Count <= 0 || buffer2Count <= 0)
{
return result;
}
//
int count = MathMin(buffer1Count, buffer2Count);
if (count <= 1)
{
return result;
}
//
int upCounts = 0;
int downCounts = 0;
double value = MathAbs(buffer1[0] - buffer2[0]);
for (int i = 1; i < count; i++)
{
//
double iValue = MathAbs(buffer1[i] - buffer2[i]);
//
if (value > iValue)
{
upCounts++;
}
//
if (value < iValue)
{
downCounts++;
}
}
//
result = upCounts > 1 && upCounts > downCounts;
//
return result;
}
//
bool IsTrendingDown(
const double &buffer1[], // First Buffer
const double &buffer2[] // Seccend Buffer
)
{
//
bool result = false;
//
int buffer1Count = ArraySize(buffer1);
int buffer2Count = ArraySize(buffer2);
if (buffer1Count <= 0 || buffer2Count <= 0)
{
return result;
}
//
int count = MathMin(buffer1Count, buffer2Count);
if (count <= 1)
{
return result;
}
//
int upCounts = 0;
int downCounts = 0;
double value = MathAbs(buffer1[0] - buffer2[0]);
for (int i = 1; i < count; i++)
{
//
double iValue = MathAbs(buffer1[i] - buffer2[i]);
//
if (value > iValue)
{
upCounts++;
}
//
if (value < iValue)
{
downCounts++;
}
}
//
result = downCounts > 1 && downCounts > upCounts;
//
return result;
}
//
// Calculate Slope of Specified Buffer at Specified Index ...
double GetSlope(
const double &buffer[], // Buffer
int from, // In Past Index ...
int to // In Past Index ...
)
{
//
double result = 0;
//
if (from > ArraySize(buffer) || to > ArraySize(buffer))
{
return result;
}
//
double toValue = buffer[to];
double fromValue = buffer[from];
double deltaValue = toValue - fromValue;
double deltaTime = from - to;
//
result = deltaValue / deltaTime;
//
return result;
}
//
// Calculate Fib Level ...
double GetFibonacciLevel(
double upPrice, // Upper Bound
double downPrice, // Downer Bound
double level, // Level Multiplier Factor
int direction // From Down to Up < 0, other wise Vice Versa
//
)
{
//
double ling = upPrice - downPrice;
double pLevel = (ling / 100) * (level * 100);
//
double result = direction > 0 ? upPrice - pLevel : downPrice + pLevel;
//
return result;
}
//
double MAOnArray(
double &array[],
int total,
int period,
int ma_shift,
int ma_method,
int shift //
)
{
//
double result = 0;
//
double buf[];
double arr[];
//
if (total == 0)
{
total = ArraySize(array);
}
//
if (total > 0 && total <= period)
{
return result;
}
//
if (shift > total - period - ma_shift)
{
return result;
}
//
// MA Method ...
switch (ma_method)
{
//
// Mode SMA ...
case MODE_SMA:
{
//
total = ArrayCopy(arr, array, 0, shift + ma_shift, period);
if (ArrayResize(buf, total) < 0)
{
return result;
}
//
double sum = 0;
int i, pos = total - 1;
for (i = 1; i < period; i++, pos--)
{
sum += arr[pos];
}
//
while (pos >= 0)
{
//
sum += arr[pos];
buf[pos] = sum / period;
sum -= arr[pos + period - 1];
pos--;
}
//
result = buf[0];
return result;
}
//
// Mode EMA ...
case MODE_EMA:
{
//
if (ArrayResize(buf, total) < 0)
{
return result;
}
//
int pos = total - 2;
double pr = 2.0 / (period + 1);
//
while (pos >= 0)
{
//
if (pos == total - 2)
{
buf[pos + 1] = array[pos + 1];
}
//
buf[pos] = array[pos] * pr + buf[pos + 1] * (1 - pr);
pos--;
}
//
result = buf[shift + ma_shift];
return result;
}
//
// Mode SMMA ...
case MODE_SMMA:
{
//
if (ArrayResize(buf, total) < 0)
{
return result;
}
//
int i, kk, pos;
double sum = 0;
pos = total - period;
//
while (pos >= 0)
{
//
if (pos == total - period)
{
//
for (i = 0, kk = pos; i < period; i++, kk++)
{
//
sum += array[kk];
buf[kk] = 0;
}
}
else
{
sum = buf[pos + 1] * (period - 1) + array[pos];
}
//
buf[pos] = sum / period;
pos--;
}
//
result = buf[shift + ma_shift];
return result;
}
//
// Mode LWMA ...
case MODE_LWMA:
{
//
if (ArrayResize(buf, total) < 0)
{
return result;
}
//
double price;
double sum = 0.0, lsum = 0.0;
int i, weight = 0, pos = total - 1;
//
for (i = 1; i <= period; i++, pos--)
{
//
price = array[pos];
sum += price * i;
lsum += price;
weight += i;
}
//
pos++;
i = pos + period;
while (pos >= 0)
{
//
buf[pos] = sum / weight;
if (pos == 0)
{
break;
}
//
i--;
pos--;
price = array[pos];
sum = sum - lsum + price * period;
lsum -= array[i];
lsum += price;
}
//
result = buf[shift + ma_shift];
return result;
}
//
default:
return result;
}
//
return result;
}
//
// Method 1
// Normalize between 1 and 0 ...
template <typename T>
double GetNormalizedValueMethod1(
T &buffer[], // Array which required to Normalize
int mLength, // Length of Normalization
int mStart = 0, // start index
int digits = 5 // Normalization Digits
)
{
//
double result = 0;
//
if (digits <= 5)
{
digits = 5;
}
//
int bufferSize = ArraySize(buffer);
if (!IsValidSize(bufferSize))
{
return result;
}
//
// Normalize Count ...
NormalizeCount(
mStart,
mLength,
buffer //
);
//
T max = 0;
T min = 0;
//
if (bufferSize != mLength)
{
//
T tmp[];
Copy(
mStart,
mLength,
buffer,
tmp //
);
//
max = GetMax(tmp);
min = GetMin(tmp);
}
//
if (bufferSize == mLength)
{
//
max = GetMax(buffer);
min = GetMin(buffer);
}
//
T iValue = buffer[mStart];
//
double minMaxDiff = (max - min);
if (minMaxDiff <= 0)
{
return result;
}
//
result = (iValue - min) / minMaxDiff;
//
result = NormalizeDouble(result, digits);
//
return result;
}
//
// Method 2
// Normalize Between Specified Upper and Lower ...
template <typename T>
double GetNormalizedValueMethod2(
T &buffer[], // Array which required to Normalize
int mLength, // Length of Normalization
int mUpper, // Specified Upper Value
int mLower, // Specified Lower Value
int mStart = 0, // start index
int digits = 5 // Normalization Digits
)
{
//
double result = 0;
//
if (digits <= 5)
{
digits = 5;
}
//
int bufferSize = ArraySize(buffer);
if (!IsValidSize(bufferSize))
{
return result;
}
//
// Normalize Count ...
NormalizeCount(
mStart,
mLength,
buffer //
);
//
T max = 0;
T min = 0;
//
if (bufferSize != mLength)
{
//
T tmp[];
Copy(
mStart,
mLength,
buffer,
tmp //
);
//
max = GetMax(tmp);
min = GetMin(tmp);
}
//
if (bufferSize == mLength)
{
//
max = GetMax(buffer);
min = GetMin(buffer);
}
//
T iValue = buffer[mStart];
//
double minMaxDiff = (max - min);
double boundaryDiff = (mUpper - mLower);
if (minMaxDiff <= 0 || boundaryDiff <= 0)
{
return result;
}
//
result = boundaryDiff / (minMaxDiff * (iValue - max) + max);
//
result = NormalizeDouble(result, digits);
//
return result;
}
//
void NormalizeBuffer(
double &source[], // Source Buffer
double &dest[], // Result Buffer
double upper = 100, // Upper Value to Normalize
double lower = -100, // Lower Value to Normalize
int size = -1, // Size Of Normalization
int digits = 5 // Digits for Result
)
{
//
if (size <= 0)
{
size = ArraySize(source);
}
//
bool asSeriesFlag = ArrayGetAsSeries(source);
//
ArraySetAsSeries(source, false);
ArraySetAsSeries(dest, false);
//
double min = ArrayMinimum(source, 0, size);
double max = ArrayMaximum(source, 0, size);
//
for (int i = 0; i < size; i++)
{
//
double iNormal = lower + ((source[i] - min) / (max - min)) * (upper - lower);
//
if (digits > 0)
{
iNormal = NormalizeDouble(iNormal, digits);
}
//
dest[i] = iNormal;
}
//
ArraySetAsSeries(source, asSeriesFlag);
ArraySetAsSeries(dest, asSeriesFlag);
}
//
// Templates ...
//
// Retrieve Specific Object Types Name ...
template <typename T>
string GetTypeName(const T &t)
{
return typename(T);
}
//
template <typename T>
string GetToken(T &item)
{
//
string mType = GetTypeName(item);
//
string result = mType;
//
string parts[];
int partsCount = SplitContent(
parts,
result,
" "
//
);
if (partsCount <= 0)
{
//
result = mType;
return result;
}
//
bool hasLastPart = GetLastItem(
result,
parts
//
);
if (!hasLastPart)
{
//
result = mType;
return result;
}
//
return result;
}
//
// Same as Get Token for Use in Classes ...
template <typename T>
string GetSpecificToken(T &item)
{
//
string mType = GetTypeName(item);
//
string result = mType;
//
string parts[];
int partsCount = SplitContent(
parts,
result,
" "
//
);
if (partsCount <= 0)
{
//
result = mType;
return result;
}
//
bool hasLastPart = GetLastItem(
result,
parts
//
);
if (!hasLastPart)
{
//
result = mType;
return result;
}
//
return result;
}
//
// Generate Unique Tags ...
template <typename T>
string GenerateTag(T &model)
{
//
string result = "";
//
string tag = model.ToString();
if (StringLen(tag) == 0)
{
return result;
}
//
static XSCMD5 md5;
//
result = md5.Hash(tag);
//
return result;
}
//
// Hash Specified Content ...
template <typename T>
string ToMD5(T content)
{
//
string result = "";
//
string strContent = ToString(content);
if (StringLen(strContent) == 0)
{
return result;
}
//
static XSCMD5 md5;
//
result = md5.Hash(strContent);
//
return result;
}
//
// Check a Value Not Empty ...
template <typename T>
bool NotEmpty(T value)
{
return value != EMPTY_VALUE;
}
//
// Check a Value Not Empty and Zero ...
template <typename T>
bool NotEmptyZero(T value)
{
return value != EMPTY_VALUE && value != 0;
}
//
// Add Specified Item to Array ...
template <typename T>
int Add(
T item, // item want to add
T &buffer[] // Destination buffer
)
{
//
int result = 0;
//
ArrayResize(
buffer,
ArraySize(buffer) + 1);
//
buffer[ArraySize(buffer) - 1] = item;
//
result = ArraySize(buffer);
//
return result;
}
template <typename T>
int AddSpecific(
T item, // item want to add
T &buffer[] // Destination buffer
)
{
//
return Add(
item,
buffer //
);
}
template <typename T>
int AddRef(
T &item, // item want to add
T &buffer[] // Destination buffer
)
{
//
int result = 0;
//
ArrayResize(
buffer,
ArraySize(buffer) + 1);
//
buffer[ArraySize(buffer) - 1] = item;
//
result = ArraySize(buffer);
//
return result;
}
//
// Remove Specified Item from an Array ...
template <typename T>
bool Remove(
T item,
T &buffer[])
{
//
bool result = false;
//
int itemIndex = FindIndex(
item,
buffer);
if (itemIndex < 0)
{
return result;
}
//
result = ArrayRemove(
buffer,
itemIndex,
1);
//
return result;
}
//
// Clean Specified Array ...
template <typename T>
void Clean(T &buffer[])
{
//
ArrayFree(buffer);
ArrayResize(buffer, 0);
}
template <typename T>
void SpecificClean(T &buffer[])
{
Clean(buffer);
}
//
// Copy Whole Content of Source to Dest array ...
template <typename T>
void Copy(
T &source[], // Source Buffer ...
T &dest[], // Dest Buffer ...
bool cleanDest = true // Force Clen Dest Buffer ...
)
{
//
if (cleanDest)
{
Clean(dest);
}
//
int sourceCount = ArraySize(source);
if (sourceCount <= 0)
{
return;
}
//
for (int i = 0; i < sourceCount; i++)
{
//
T iSource = source[i];
//
AddRef(
iSource,
dest);
}
}
//
// Copy Items from a Buffer ...
template <typename T>
int Copy(
int start, // Start
int count, // Number of Items for read
T &source[], // Source Buffer
T &dest[], // Dest Buffer
bool forceClean = true, // Force To Clean buffer
bool forceStart = true // Force To Clean buffer
)
{
//
int result = 0;
//
if (forceClean)
{
Clean(dest);
}
//
if (start < 0 && forceStart)
{
start = 0;
}
//
if (start >= ArraySize(source))
{
start = ArraySize(source) - 1;
}
//
if (count == 0)
{
count = ArraySize(source) - 1 - start;
}
//
if (start + count > ArraySize(source))
{
return result;
}
//
int beforeSize = ArraySize(dest);
//
bool asSeriesDest = ArrayGetAsSeries(dest);
bool asSeriesSource = ArrayGetAsSeries(source);
//
ArraySetAsSeries(dest, true);
ArraySetAsSeries(source, true);
//
ArrayCopy(
dest,
source,
0,
start,
count
//
);
//
int afterSize = ArraySize(dest);
//
result = afterSize - beforeSize;
//
ArraySetAsSeries(dest, asSeriesDest);
ArraySetAsSeries(source, asSeriesSource);
//
return result;
}
//
// Copy Items from a Buffer ...
template <typename T>
int CopyRef(
int start, // Start
int count, // Number of Items for read
T &source[], // Source Buffer
T &dest[], // Dest Buffer
bool forceClean = true // Force To Clean buffer
)
{
//
int result = 0;
//
if (forceClean)
{
Clean(dest);
}
//
if (start < 0)
{
start = 0;
}
//
if (start >= ArraySize(source))
{
start = ArraySize(source) - 1;
}
//
int beforeSize = ArraySize(dest);
//
bool asSeriesDest = ArrayGetAsSeries(dest);
bool asSeriesSource = ArrayGetAsSeries(source);
//
ArraySetAsSeries(dest, true);
ArraySetAsSeries(source, true);
//
for (int i = start; i < start + count; i++)
{
//
AddRef(
source[i],
dest
//
);
}
//
int afterSize = ArraySize(dest);
//
result = afterSize - beforeSize;
//
ArraySetAsSeries(dest, asSeriesDest);
ArraySetAsSeries(source, asSeriesSource);
//
return result;
}
//
// Retrive Last Item of Specified Buffer ...
template <typename T>
bool GetLastItem(
T &item, // Holds Result
T &buffer[] // Specified Buffer
)
{
//
bool result = false;
//
int bufferSize = ArraySize(buffer);
if (bufferSize <= 0)
{
return result;
}
//
item = buffer[bufferSize - 1];
//
result = true;
return result;
}
//
// Search Array For Specific Item ...
template <typename T>
int FindIndex(
T item, // What is Search ...
T &buffer[] // Search in ...
)
{
//
int result = -1;
//
int count = ArraySize(buffer);
if (count <= 0)
{
return result;
}
//
for (int i = 0; i < count; i++)
{
//
T iT = buffer[i];
//
if (iT == item)
{
//
result = i;
break;
}
}
//
return result;
}
//
// Check an Array Contains Specified Value ...
template <typename T>
bool Contains(
T item, // What is Search ...
T &buffer[] // Search in ...
)
{
//
bool result = false;
//
int idx = FindIndex(
item,
buffer);
result = idx > -1;
//
return result;
}
//
// Calculate a Buffer's Sum ...
template <typename T>
double GetSum(
T &buffer[], // the Buffer which required to search
int start = 0, // Start Index
int count = 0 // Count for Search
)
{
//
double result = 0;
//
T tmp[];
int tmpCount = Copy(
start,
count,
buffer,
tmp
//
);
if (tmpCount <= 0)
{
return result;
}
//
// Calculate Summary ...
for (int i = 0; i < tmpCount; i++)
{
result += buffer[i];
}
//
return result;
}
//
// Calculate a Buffer's Average ...
template <typename T>
double GetAverage(
T &buffer[], // the Buffer which required to search
int start = 0, // Start Index
int count = 0 // Count for Search
)
{
//
double result = 0;
//
T tmp[];
int tmpCount = Copy(
start,
count,
buffer,
tmp
//
);
if (tmpCount <= 0)
{
return result;
}
//
// Calculate Summary ...
for (int i = 0; i < tmpCount; i++)
{
result += buffer[i];
}
//
// Calculate Average ...
result = result / tmpCount;
//
return result;
}
//
// Get Max of Specific Loopback of a Buffer ...
template <typename T>
T GetMax(
T &buffer[], // the Buffer which required to search
int start = 0, // Start Index
int count = 0 // Count for Search
)
{
//
T result = 0;
//
if (count <= 0)
{
count = ArraySize(buffer);
}
//
T tmp[];
int tmpCount = Copy(
start,
count,
buffer,
tmp
//
);
if (tmpCount <= 0)
{
return result;
}
//
// Loop Through LoopBack ...
for (int i = 0; i < tmpCount; i++)
{
//
T iValue = tmp[i];
//
result =
//
result == 0 || result < iValue
//
? iValue
//
: result
//
;
}
//
return result;
}
template <typename T>
T GetSpecifiedMax(
T &buffer[], // the Buffer which required to search
int start = 0, // Start Index
int count = 0 // Count for Search
)
{
return GetMax(
buffer,
start,
count //
);
}
//
// Get Min of Specific Loopback of a Buffer ...
template <typename T>
T GetMin(
T &buffer[], // the Buffer which required to search
int start = 0, // Start Index
int count = 0 // Count for Search
)
{
//
T result = 0;
//
if (count <= 0)
{
count = ArraySize(buffer);
}
//
T tmp[];
int tmpCount = Copy(
start,
count,
buffer,
tmp
//
);
if (tmpCount <= 0)
{
return result;
}
//
// Loop Through LoopBack ...
for (int i = 0; i < tmpCount; i++)
{
//
T iValue = tmp[i];
//
result =
//
result == 0 || result > iValue
//
? iValue
//
: result
//
;
}
//
return result;
}
template <typename T>
T GetSpecifiedMin(
T &buffer[], // the Buffer which required to search
int start = 0, // Start Index
int count = 0 // Count for Search
)
{
return GetMin(
buffer,
start,
count //
);
}
//
// Find a Value less than Specified ...
template <typename T>
T FindLesserThan(
T value, // Specified Value ...
const T &source[], // Source ...
bool isDescend = false // Find Biggest Lesser Value ...
)
{
//
T result = -1;
//
int itemsCount = ArraySize(source);
if (itemsCount <= 0)
{
return result;
}
//
// Make a Copy of source ...
T tmp[];
//
ArrayResize(
tmp,
ArraySize(source));
//
ArrayCopy(
tmp,
source);
//
// Sort Temp Buffer ...
ArraySort(tmp);
if (isDescend)
{
ArrayReverse(tmp);
}
//
int tmpCount = ArraySize(tmp);
for (int i = 0; i < tmpCount; i++)
{
//
T iValue = tmp[i];
//
if (iValue < value)
{
//
result = iValue;
break;
}
}
//
return result;
}
//
// Find a Value less than Specified ...
template <typename T>
T FindBiggerThan(
T value, // Specified Value ...
const T &source[], // Source ...
bool isDescend = false // Find Smallest Bigger Value ...
)
{
//
T result = -1;
//
int itemsCount = ArraySize(source);
if (itemsCount <= 0)
{
return result;
}
//
// Make a Copy of source ...
T tmp[];
//
ArrayResize(
tmp,
ArraySize(source));
//
ArrayCopy(
tmp,
source);
//
// Sort Temp Buffer ...
ArraySort(tmp);
if (!isDescend)
{
ArrayReverse(tmp);
}
//
int tmpCount = ArraySize(tmp);
for (int i = 0; i < tmpCount; i++)
{
//
T iValue = tmp[i];
//
if (iValue > value)
{
//
result = iValue;
break;
}
}
//
return result;
}
//
// Find Same Values in Array ...
template <typename T>
void FindSames(
T &result[], // Holds Result ...
T &source[], // Source ...
int verifications = 3 // Number of Consequence Repeat ...
)
{
//
Clean(result);
//
// TenkanSen Flats ...
int sourceCount = ArraySize(source);
if (sourceCount > verifications)
{
//
T mLast = 0;
int mVerified = 0;
for (int i = 0; i < sourceCount; i++)
{
//
T iVal = source[i];
if (mLast == 0)
{
mLast = iVal;
}
else if (mLast == iVal)
{
mVerified++;
}
else
{
mLast = iVal;
mVerified = 0;
}
//
if (iVal == mLast && mVerified >= verifications)
{
//
Add(
iVal,
result);
//
mLast = 0;
mVerified = 0;
}
}
}
}
//
// Add an Item to a Buffer if not Exists ...
void AddIfNotExists(
double value,
double &values[],
double smoothingPoint = 3)
{
//
double smoothingValue = smoothingPoint * GetPoints(_Symbol);
//
int valuesCount = ArraySize(values);
if (valuesCount <= 0)
{
//
Add(value,
values);
}
else
{
//
bool isExists = false;
for (int i = 0; i < valuesCount; i++)
{
//
double iVal = values[i];
//
double diff = MathAbs(iVal - value);
//
if (iVal == value || diff < smoothingValue)
{
//
isExists = true;
break;
}
}
//
if (!isExists)
{
//
Add(value,
values);
}
}
}
//
// Add a Buffers Child to another Buffer
// if it's not Contains them ...
void AddsIfNotExists(
double &source[],
double &dest[],
double smoothingPoint = 3)
{
//
double smoothingValue = smoothingPoint * GetPoints(_Symbol);
//
int sourceCount = ArraySize(source);
if (sourceCount <= 0)
{
return;
}
//
for (int i = 0; i < sourceCount; i++)
{
//
double iSource = source[i];
//
AddIfNotExists(
iSource,
dest,
smoothingPoint);
}
}
//
// Bar XOHCL ...
//
// Extract Specific Range of Bars ...
// using Start Bar Index ...
int GetBars(
XOHCL &result[], // Hold Result
string mSymbol = NULL, // Trading Symbol
ENUM_TIMEFRAMES mPeriod = NULL, // Trading Time Frame
int from = 0, // Start Bar Index
int count = 1, // Number of Bars
bool forceClean = true // Clean Result Array
)
{
//
int mResult = 0;
//
if (from < 0)
{
from = 0;
}
//
mSymbol = NormalizeSymbol(mSymbol);
mPeriod = NormalizePeriod(mPeriod);
//
int total = Bars(
mSymbol,
mPeriod);
if (from > total - 2)
{
from = total - 2;
}
//
if (count < 0)
{
count = 1;
}
//
int start = from;
int end = start + count;
if (end > total - 1)
{
end = total - 1;
}
//
if (forceClean)
{
Clean(result);
}
//
int beforeSize = ArraySize(result);
//
for (int i = start; i < end; i++)
{
//
XOHCL iBar;
bool isValid = iBar.Init(
mSymbol,
mPeriod,
i
//
);
//
if (isValid)
{
//
AddRef(
iBar,
result
//
);
}
}
//
int afterSize = ArraySize(result);
//
mResult = afterSize - beforeSize;
//
return mResult;
}
//
// Extract Specific Range of Bars ...
// using Start Bar Time ...
int GetBars(
XOHCL &result[], // Hold Result
string mSymbol = NULL, // Trading Symbol
ENUM_TIMEFRAMES mPeriod = NULL, // Trading Time Frame
datetime from = NULL, // Start Bar Time
int count = 1, // Number of Bars
bool forceClean = true // Clean Result Array
)
{
//
mSymbol = NormalizeSymbol(mSymbol);
mPeriod = NormalizePeriod(mPeriod);
//
from = NormalizeTime(from);
//
int barIndex = iBarShift(
mSymbol,
mPeriod,
from,
false
//
);
//
return GetBars(
result,
mSymbol,
mPeriod,
barIndex,
count,
forceClean
//
);
}
//
// String ...
//
// Search a Content Contains Specific String or not ...
bool Contains(
string mQuery, // Search String
string mContent, // Search Content
bool ignoreCase = true // Ignore Case
)
{
//
bool result = false;
//
// Validate Query ...
result = IsValid(mQuery);
if (!result)
{
return result;
}
//
// Validate Content ...
result = IsValid(mContent);
if (!result)
{
return result;
}
//
// Normalize Inputs ...
string query = mQuery;
string content = mContent;
if (ignoreCase)
{
//
StringToLower(query);
StringToLower(content);
}
//
int queryIdx = StringFind(
content,
query);
//
result = queryIdx >= 0;
//
return result;
}
//
bool Contains(
string &mQueries[], // Search Strings
string mContent, // Search Content
bool ignoreCase = true // Ignore Case
)
{
//
bool result = false;
//
// Validate Queries ...
int queriesCount = ArraySize(mQueries);
result = queriesCount > 0;
if (!result)
{
return result;
}
//
// Validate Content ...
result = IsValid(mContent);
if (!result)
{
return result;
}
//
int containsCount = 0;
for (int i = 0; i < queriesCount; i++)
{
//
bool isContains = Contains(
mQueries[i],
mContent,
ignoreCase);
//
if (!isContains)
{
//
result = false;
break;
}
//
containsCount++;
}
//
result = containsCount == queriesCount;
//
return result;
}
//
// Convert From String ...
template <typename T>
T FromString(string value)
{
//
T result = NULL;
//
if (!IsValid(value))
{
return result;
}
//
result = (T)value;
//
return result;
}
//
// Converts an item to String ...
template <typename T>
string ToString(T value)
{
return (string)value;
}
//
// Used In Report or Summary Generators ...
string ToString(
string prefix, // Title
bool value, // Value
bool ignoreFalseConditions = true, // Ignore False Conditions
string lineSeparator = "\n", // Line Separator
string prefixSeparator = ":" // Title Separator
)
{
//
string result = NULL;
//
result = (value || !ignoreFalseConditions)
? prefix +
prefixSeparator + " " +
ToString(value) +
lineSeparator
: "";
//
return result;
}
//
template <typename T>
string ToString(
string prefix, // Title
T value, // Value
string lineSeparator = "\n", // Line Separator
string prefixSeparator = ":" // Title Separator
)
{
//
string result = NULL;
//
result = prefix +
prefixSeparator + " " +
ToString(value) +
lineSeparator;
//
return result;
}
//
string SetLabel(
string mLabel, // Provided Label ...
string value, // Source Value ...
string separator = "\n", // Line Separator
bool addTopEmptyLine = true // Add Empty Line On top
)
{
//
string result = value;
//
if (StringLen(mLabel) <= 0)
{
return result;
}
//
result = (StringLen(value) > 0)
? (addTopEmptyLine ? separator : "") +
mLabel +
separator +
"-----------------------------" +
separator +
value
: value;
//
return result;
}
//
// Converts a Buffer to String Representation ...
template <typename T>
string ToString(
const T &buffer[], // Specified Buffer
string separator = ",", // Specified Separator
bool addIndex = false, // Specified Add Items Indexes or Not
string indexLabel = "i:", // Specified Index Label
string indexSeparator = ">" // Specified Index Separator
)
{
//
string result = "";
//
int bufferSize = ArraySize(buffer);
if (bufferSize <= 0)
{
return result;
}
//
for (int i = 0; i < bufferSize; i++)
{
//
if (addIndex)
{
//
if (StringLen(indexLabel) > 0)
{
result += indexLabel + " ";
}
//
result += (string)i + " ";
//
if (StringLen(indexSeparator) > 0)
{
result += indexSeparator + " ";
}
}
//
string iItemString = (string)buffer[i];
//
result += iItemString;
//
if (i < bufferSize - 1)
{
result += separator;
}
}
//
return result;
}
//
// Converts String to boolean ...
bool ToBoolean(string value)
{
//
bool result = false;
//
if (StringLen(value) <= 0)
{
return result;
}
//
StringToLower(value);
result = value == "true";
//
return result;
}
//
// Split an String Representation of an Array ...
int SplitContent(
string &result[], // Hold Result ...
string content, // Source ...
string separator = ",", // Separator ...
bool forceCleanResult = true // Clean Result ...
)
{
//
int mResult = 0;
//
if (forceCleanResult)
{
Clean(result);
}
//
int before = ArraySize(result);
//
if (separator == NULL || StringLen(separator) == 0)
{
separator = ",";
}
//
if (StringLen(content) == 0)
{
return mResult;
}
//
StringSplit(
content,
StringGetCharacter(
separator,
0),
result);
//
int after = ArraySize(result);
//
mResult = after - before;
//
return mResult;
}
//
// Extract Data from String ...
string ExtractString(
const string source, // Source String used for Extracting
const string startString = "(", // Expression Start String must be Unique
const string endString = ")" // Where to End Extraction, usually a Sign
)
{
//
string result = "";
//
// Validate String ...
if (
StringLen(source) == 0 ||
StringLen(endString) == 0 ||
StringLen(startString) == 0)
{
return result;
}
//
// Find Start String Position ...
int sPos = StringFind(
source,
startString);
if (sPos < 0)
{
return result;
}
//
// Find End String Position after Start String ...
int searchEndFromPos = sPos + StringLen(startString);
int ePos = StringFind(
source,
endString,
searchEndFromPos);
if (ePos < 0)
{
return result;
}
//
// Extract Data from Source ...
int dLength = ePos - searchEndFromPos;
result = StringSubstr(
source,
searchEndFromPos,
dLength);
//
return result;
}
//
// Extract an Array of Contents ...
int ExtractStrings(
string &result[], // Hold Result
const string source, // Source String used for Extracting
const string startString = "(", // Expression Start String must be Unique
const string endString = ")" // Where to End Extraction, usually a Sign
)
{
//
int mResult = 0;
//
Clean(result);
//
// Validate Args ...
int sourceLength = StringLen(source);
int startLength = StringLen(startString);
int endLength = StringLen(endString);
//
int minRequiredLength = startLength + endLength;
//
if (
endLength <= 0 ||
startLength <= 0 ||
sourceLength <= 0 ||
sourceLength < minRequiredLength)
{
return mResult;
}
//
// Make a Copy of Source for Manipulating ...
string workStr = source;
//
// Define a Loop ...
while (StringLen(workStr) > minRequiredLength)
{
//
// Find Item ...
string item = ExtractString(
workStr,
startString,
endString);
//
// Breakout when couldn't find anymore item ...
int itemLength = StringLen(item);
if (itemLength <= 0)
{
break;
}
//
// Prepare Item Source String for Replacing in Work String ...
string itemSource = startString + item + endString;
//
// Add Item to Result Array ...
Add(
item,
result);
//
// Replace Item Soure in Work String ...
StringReplace(
workStr,
itemSource,
"");
}
//
// Calculate Size of Array ...
mResult = ArraySize(result);
//
return mResult;
}
//
string ExtractSurrounded(
const string surrounded, // Surrounded Content
const string mToken, // Specified Token
const string startString = "(", // Expression Start String must be Unique
const string endString = ")" // Where to End Extraction, usually a Sign
)
{
//
return ExtractString(
surrounded,
mToken + startString,
endString
//
);
}
//
int ParseIntSurrounded(
const string surrounded, // Surrounded Content
const string mToken, // Specified Token
const string startString = "(", // Expression Start String must be Unique
const string endString = ")" // Where to End Extraction, usually a Sign
)
{
//
int result = NULL;
//
string strContent = ExtractSurrounded(
surrounded,
mToken,
startString,
endString
//
);
if (!IsValid(strContent))
{
return result;
}
//
result = (int)strContent;
//
return result;
}
long ParseLongSurrounded(
const string surrounded, // Surrounded Content
const string mToken, // Specified Token
const string startString = "(", // Expression Start String must be Unique
const string endString = ")" // Where to End Extraction, usually a Sign
)
{
//
long result = NULL;
//
string strContent = ExtractSurrounded(
surrounded,
mToken,
startString,
endString
//
);
if (!IsValid(strContent))
{
return result;
}
//
result = (long)strContent;
//
return result;
}
string ParseStringSurrounded(
const string surrounded, // Surrounded Content
const string mToken, // Specified Token
const string startString = "(", // Expression Start String must be Unique
const string endString = ")" // Where to End Extraction, usually a Sign
)
{
//
string result = NULL;
//
string strContent = ExtractSurrounded(
surrounded,
mToken,
startString,
endString
//
);
if (!IsValid(strContent))
{
return result;
}
//
result = (string)strContent;
//
return result;
}
double ParseDoubleSurrounded(
const string surrounded, // Surrounded Content
const string mToken, // Specified Token
const string startString = "(", // Expression Start String must be Unique
const string endString = ")" // Where to End Extraction, usually a Sign
)
{
//
double result = NULL;
//
string strContent = ExtractSurrounded(
surrounded,
mToken,
startString,
endString
//
);
if (!IsValid(strContent))
{
return result;
}
//
result = (double)strContent;
//
return result;
}
datetime ParseTimeSurrounded(
const string surrounded, // Surrounded Content
const string mToken, // Specified Token
const string startString = "(", // Expression Start String must be Unique
const string endString = ")" // Where to End Extraction, usually a Sign
)
{
//
datetime result = NULL;
//
string strContent = ExtractSurrounded(
surrounded,
mToken,
startString,
endString
//
);
if (!IsValid(strContent))
{
return result;
}
//
result = (datetime)strContent;
//
return result;
}
//
int ParseIntArraySurrounded(
int &result[], // Holds Result
const string surrounded, // Surrounded Content
const string mToken, // Specified Token
string separator = ",", // Separator ...
const string startString = "(", // Expression Start String must be Unique
const string endString = ")", // Where to End Extraction, usually a Sign
bool forceClean = true // Clean Result ...
)
{
//
int count = 0;
//
if (forceClean)
{
Clean(result);
}
//
int before = ArraySize(result);
//
string contentStr = ParseStringSurrounded(surrounded, mToken);
if (!IsValid(contentStr))
{
return count;
}
//
string tmps[];
int tmpsCount = SplitContent(
tmps,
contentStr
//
);
if (tmpsCount <= 0)
{
return count;
}
//
for (int i = 0; i < tmpsCount; i++)
{
//
string iTMP = tmps[i];
if (!IsValid(iTMP))
{
continue;
}
//
int iValue = (int)iTMP;
//
Add(
iValue,
result
//
);
}
//
int after = ArraySize(result);
//
count = after - before;
//
return count;
}
int ParseLongArraySurrounded(
long &result[], // Holds Result
const string surrounded, // Surrounded Content
const string mToken, // Specified Token
string separator = ",", // Separator ...
const string startString = "(", // Expression Start String must be Unique
const string endString = ")", // Where to End Extraction, usually a Sign
bool forceClean = true // Clean Result ...
)
{
//
int count = 0;
//
if (forceClean)
{
Clean(result);
}
//
int before = ArraySize(result);
//
string contentStr = ParseStringSurrounded(surrounded, mToken);
if (!IsValid(contentStr))
{
return count;
}
//
string tmps[];
int tmpsCount = SplitContent(
tmps,
contentStr
//
);
if (tmpsCount <= 0)
{
return count;
}
//
for (int i = 0; i < tmpsCount; i++)
{
//
string iTMP = tmps[i];
if (!IsValid(iTMP))
{
continue;
}
//
long iValue = (long)iTMP;
//
Add(
iValue,
result
//
);
}
//
int after = ArraySize(result);
//
count = after - before;
//
return count;
}
int ParseDoubleArraySurrounded(
double &result[], // Holds Result
const string surrounded, // Surrounded Content
const string mToken, // Specified Token
string separator = ",", // Separator ...
const string startString = "(", // Expression Start String must be Unique
const string endString = ")", // Where to End Extraction, usually a Sign
bool forceClean = true // Clean Result ...
)
{
//
int count = 0;
//
if (forceClean)
{
Clean(result);
}
//
int before = ArraySize(result);
//
string contentStr = ParseStringSurrounded(surrounded, mToken);
if (!IsValid(contentStr))
{
return count;
}
//
string tmps[];
int tmpsCount = SplitContent(
tmps,
contentStr
//
);
if (tmpsCount <= 0)
{
return count;
}
//
for (int i = 0; i < tmpsCount; i++)
{
//
string iTMP = tmps[i];
if (!IsValid(iTMP))
{
continue;
}
//
double iValue = (double)iTMP;
//
Add(
iValue,
result
//
);
}
//
int after = ArraySize(result);
//
count = after - before;
//
return count;
}
int ParseTimeArraySurrounded(
datetime &result[], // Holds Result
const string surrounded, // Surrounded Content
const string mToken, // Specified Token
string separator = ",", // Separator ...
const string startString = "(", // Expression Start String must be Unique
const string endString = ")", // Where to End Extraction, usually a Sign
bool forceClean = true // Clean Result ...
)
{
//
int count = 0;
//
if (forceClean)
{
Clean(result);
}
//
int before = ArraySize(result);
//
string contentStr = ParseStringSurrounded(surrounded, mToken);
if (!IsValid(contentStr))
{
return count;
}
//
string tmps[];
int tmpsCount = SplitContent(
tmps,
contentStr
//
);
if (tmpsCount <= 0)
{
return count;
}
//
for (int i = 0; i < tmpsCount; i++)
{
//
string iTMP = tmps[i];
if (!IsValid(iTMP))
{
continue;
}
//
datetime iValue = (datetime)iTMP;
//
Add(
iValue,
result
//
);
}
//
int after = ArraySize(result);
//
count = after - before;
//
return count;
}
//
// Surround an String by Specific Token ...
template <typename T>
string Surround(
string mToken, // an String which used to Tokenize
T &value, // a Value for Tokenize it
string startString = "(", // Token Start Content
string endString = ")" // Token End Content
)
{
//
string result = NULL;
//
string strValue = ToString(value);
if (!IsValid(strValue))
{
return result;
}
//
result =
//
(IsValid(mToken)
? mToken
: "") +
//
startString +
strValue +
endString
//
;
//
return result;
}
//
template <typename T>
string SurroundArray(
string mToken,
T &value[],
string startString = "(", // Token Start Content
string endString = ")" // Token End Content
)
{
//
string result = NULL;
//
string valueStr = ToString(value);
if (!IsValid(valueStr))
{
return result;
}
//
result = Surround(
mToken,
valueStr,
startString,
endString
//
);
//
return result;
}
//
// Periods / Cycles ...
//
// Converts an String to TimeFrame ...
ENUM_TIMEFRAMES ToPeriod(string value)
{
//
if (StringLen(value) == 0)
{
return _Period;
}
//
StringTrimLeft(value);
StringTrimRight(value);
//
ENUM_TIMEFRAMES result = _Period;
//
if (value == "M1")
{
result = PERIOD_M1;
}
else if (value == "M2")
{
result = PERIOD_M2;
}
else if (value == "M3")
{
result = PERIOD_M3;
}
else if (value == "M4")
{
result = PERIOD_M4;
}
else if (value == "M5")
{
result = PERIOD_M5;
}
else if (value == "M6")
{
result = PERIOD_M6;
}
else if (value == "M10")
{
result = PERIOD_M10;
}
else if (value == "M12")
{
result = PERIOD_M12;
}
else if (value == "M15")
{
result = PERIOD_M15;
}
else if (value == "M20")
{
result = PERIOD_M20;
}
else if (value == "M30")
{
result = PERIOD_M30;
}
else if (value == "H1")
{
result = PERIOD_H1;
}
else if (value == "H2")
{
result = PERIOD_H2;
}
else if (value == "H3")
{
result = PERIOD_H3;
}
else if (value == "H4")
{
result = PERIOD_H4;
}
else if (value == "H6")
{
result = PERIOD_H6;
}
else if (value == "H8")
{
result = PERIOD_H8;
}
else if (value == "H12")
{
result = PERIOD_H12;
}
else if (value == "D1")
{
result = PERIOD_D1;
}
else if (value == "W1")
{
result = PERIOD_W1;
}
else if (value == "MN1")
{
result = PERIOD_MN1;
}
//
return result;
}
//
// Converts Period to String ...
string ToString(ENUM_TIMEFRAMES mPeriod)
{
//
string result = "";
//
string mPStr = EnumToString(mPeriod);
string mPStrParts[];
int partsCount = StringSplit(
mPStr,
StringGetCharacter("_", 0),
mPStrParts);
if (partsCount <= 0)
{
return result;
}
//
result = mPStrParts[1];
//
return result;
}
//
// Retrieve All Available Period as an Array ...s
int GetAllAvailablePeriods(
ENUM_TIMEFRAMES &result[] // Holds Result ...
)
{
//
Clean(result);
//
Add(
PERIOD_M1,
result
//
);
//
Add(
PERIOD_M2,
result
//
);
//
Add(
PERIOD_M3,
result
//
);
//
Add(
PERIOD_M4,
result
//
);
//
Add(
PERIOD_M5,
result
//
);
//
Add(
PERIOD_M6,
result
//
);
//
Add(
PERIOD_M10,
result
//
);
//
Add(
PERIOD_M12,
result
//
);
//
Add(
PERIOD_M15,
result
//
);
//
Add(
PERIOD_M20,
result
//
);
//
Add(
PERIOD_M30,
result
//
);
//
Add(
PERIOD_H1,
result
//
);
//
Add(
PERIOD_H2,
result
//
);
//
Add(
PERIOD_H3,
result
//
);
//
Add(
PERIOD_H4,
result
//
);
//
Add(
PERIOD_H6,
result
//
);
//
Add(
PERIOD_H8,
result
//
);
//
Add(
PERIOD_H12,
result
//
);
//
Add(
PERIOD_D1,
result
//
);
//
Add(
PERIOD_W1,
result
//
);
//
Add(
PERIOD_MN1,
result
//
);
//
int mResult = ArraySize(result);
//
return mResult;
}
//
// Get Specific Time Frame Start Candle Time ...
datetime GetPeriodStartTime(
string mSymbol = NULL, // Specified Symbol ...
ENUM_TIMEFRAMES mPeriod = NULL, // Specified Period ...
datetime mTime = NULL // Specified Bar Time of Host Period ...
)
{
//
// Normalize Arg ...
mTime = NormalizeTime(mTime);
mSymbol = NormalizeSymbol(mSymbol);
mPeriod = NormalizePeriod(mPeriod);
//
int barIndex = iBarShift(
mSymbol,
mPeriod,
mTime,
false
//
);
//
datetime result = GetBarTime(
mSymbol,
mPeriod,
barIndex
//
);
//
return result;
}
//
// Converts an String to it's related Market Cycle ...
ENUM_X_MARKET_CYCLES ToCycle(string value)
{
//
ENUM_X_MARKET_CYCLES result = X_MARKET_CYCLE_UNKNOWN;
//
ENUM_X_MARKET_CYCLES cycles[];
int count = GetAllMarketCycles(cycles);
for (int i = 0; i < count; i++)
{
//
ENUM_X_MARKET_CYCLES iCycle = cycles[i];
string iStr = ToString(iCycle);
//
if (value == iStr)
{
//
result = iCycle;
break;
}
}
//
return result;
}
//
// Converts a Cycle to it's String Representation ...
string ToString(ENUM_X_MARKET_CYCLES cycle)
{
//
string result = "";
//
string mPStr = EnumToString(cycle);
string mPStrParts[];
int partsCount = StringSplit(
mPStr,
StringGetCharacter("_", 0),
mPStrParts);
if (partsCount <= 0)
{
return result;
}
//
result = mPStrParts[3];
//
return result;
}
//
// Retrieve all Available Cycles ...
int GetAllMarketCycles(ENUM_X_MARKET_CYCLES &result[])
{
//
int mResult = 0;
//
Clean(result);
//
ENUM_X_MARKET_CYCLES tmp[] = {
X_MARKET_CYCLE_UNKNOWN,
X_MARKET_CYCLE_SHORT,
X_MARKET_CYCLE_MEDIUM,
X_MARKET_CYCLE_LONG,
X_MARKET_CYCLE_HIND};
//
Copy(
tmp,
result //
);
//
Clean(tmp);
//
mResult = ArraySize(result);
//
return mResult;
}
//
// Retrieve Nearest Period base on Given Period ...
ENUM_TIMEFRAMES GetNearestPeriod(ENUM_TIMEFRAMES mPeriod)
{
//
ENUM_TIMEFRAMES result = _Period;
//
mPeriod = NormalizePeriod(mPeriod);
//
switch (mPeriod)
{
//
case PERIOD_M1:
case PERIOD_M2:
result = PERIOD_M4;
break;
//
case PERIOD_M3:
case PERIOD_M4:
result = PERIOD_M6;
break;
//
case PERIOD_M5:
case PERIOD_M6:
case PERIOD_M10:
case PERIOD_M12:
result = PERIOD_M15;
break;
//
case PERIOD_M15:
case PERIOD_M20:
result = PERIOD_M30;
break;
//
case PERIOD_H1:
case PERIOD_H2:
case PERIOD_H3:
result = PERIOD_H4;
break;
//
case PERIOD_H6:
case PERIOD_H8:
result = PERIOD_H12;
break;
//
case PERIOD_H12:
result = PERIOD_D1;
break;
//
case PERIOD_D1:
result = PERIOD_W1;
break;
//
default:
result = PERIOD_MN1;
break;
}
//
return result;
}
//
// Retrieve Mediest Period base on Given Period ...
ENUM_TIMEFRAMES GetMediestPeriod(ENUM_TIMEFRAMES mPeriod)
{
//
ENUM_TIMEFRAMES result = _Period;
//
mPeriod = NormalizePeriod(mPeriod);
//
switch (mPeriod)
{
//
case PERIOD_M1:
case PERIOD_M2:
result = PERIOD_M15;
break;
//
case PERIOD_M3:
case PERIOD_M4:
result = PERIOD_M30;
break;
//
case PERIOD_M5:
case PERIOD_M6:
case PERIOD_M10:
case PERIOD_M12:
result = PERIOD_H1;
break;
//
case PERIOD_M15:
case PERIOD_M20:
result = PERIOD_H2;
break;
//
case PERIOD_H1:
case PERIOD_H2:
case PERIOD_H3:
result = PERIOD_H8;
break;
//
case PERIOD_H6:
case PERIOD_H8:
result = PERIOD_D1;
break;
//
case PERIOD_H12:
result = PERIOD_W1;
break;
//
case PERIOD_D1:
result = PERIOD_MN1;
break;
//
default:
result = PERIOD_MN1;
break;
}
//
return result;
}
//
// Retrieve Longest Period base on Given Period ...
ENUM_TIMEFRAMES GetLongestPeriod(ENUM_TIMEFRAMES mPeriod)
{
//
ENUM_TIMEFRAMES result = _Period;
//
mPeriod = NormalizePeriod(mPeriod);
//
switch (mPeriod)
{
//
case PERIOD_M1:
case PERIOD_M2:
result = PERIOD_M30;
break;
//
case PERIOD_M3:
case PERIOD_M4:
result = PERIOD_H1;
break;
//
case PERIOD_M5:
case PERIOD_M6:
case PERIOD_M10:
case PERIOD_M12:
result = PERIOD_H2;
break;
//
case PERIOD_M15:
case PERIOD_M20:
result = PERIOD_H4;
break;
//
case PERIOD_H1:
case PERIOD_H2:
case PERIOD_H3:
result = PERIOD_H12;
break;
//
case PERIOD_H6:
case PERIOD_H8:
result = PERIOD_W1;
break;
//
case PERIOD_H12:
result = PERIOD_MN1;
break;
//
case PERIOD_D1:
result = PERIOD_MN1;
break;
//
default:
result = PERIOD_MN1;
break;
}
//
return result;
}
//
// Retrieve Hindmost Period base on Given Period ...
ENUM_TIMEFRAMES GetHindMostPeriod(ENUM_TIMEFRAMES mPeriod)
{
//
ENUM_TIMEFRAMES result = _Period;
//
mPeriod = NormalizePeriod(mPeriod);
//
switch (mPeriod)
{
//
case PERIOD_M1:
case PERIOD_M2:
result = PERIOD_H1;
break;
//
case PERIOD_M3:
case PERIOD_M4:
result = PERIOD_H2;
break;
//
case PERIOD_M5:
case PERIOD_M6:
case PERIOD_M10:
case PERIOD_M12:
result = PERIOD_H4;
break;
//
case PERIOD_M15:
case PERIOD_M20:
result = PERIOD_H8;
break;
//
case PERIOD_H1:
case PERIOD_H2:
case PERIOD_H3:
result = PERIOD_D1;
break;
//
case PERIOD_H6:
case PERIOD_H8:
result = PERIOD_MN1;
break;
//
case PERIOD_H12:
result = PERIOD_MN1;
break;
//
case PERIOD_D1:
result = PERIOD_MN1;
break;
//
default:
result = PERIOD_MN1;
break;
}
//
return result;
}
//
// Retrieve Specified Cycles Period related to Host Period ...
ENUM_TIMEFRAMES GetCyclePeriod(
ENUM_X_MARKET_CYCLES mCycle = NULL, // Specified Cycle
ENUM_TIMEFRAMES mPeriod = NULL // Host Period
)
{
//
ENUM_TIMEFRAMES result = NULL;
//
mPeriod = NormalizePeriod(mPeriod);
mCycle = NormalizeCycle(mCycle);
//
switch (mCycle)
{
//
// Short ...
case X_MARKET_CYCLE_SHORT:
result = GetNearestPeriod(mPeriod);
break;
//
// Medium ...
case X_MARKET_CYCLE_MEDIUM:
result = GetMediestPeriod(mPeriod);
break;
//
// Long ...
case X_MARKET_CYCLE_LONG:
result = GetLongestPeriod(mPeriod);
break;
//
// Hind ...
case X_MARKET_CYCLE_HIND:
result = GetHindMostPeriod(mPeriod);
break;
}
//
return result;
}
//