Files
xMQL5/MQLTestWorkspace/BKPS/14030308/Libraries/x-saherelm.common.lib.mq5
T
2024-05-28 08:03:47 +03:30

6882 lines
118 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,
};
//
// 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;
}
//
// 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;
}
//
// 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;
}
//
// Check Bar has Strong Body or Not ...
bool HasStrongBody()
{
//
bool result = false;
//
if (!IsValid())
{
return result;
}
//
double body = GetBody();
double shadow = GetShadows();
//
result = body > shadow * 1.5;
//
return result;
}
//
// Determines Swings based On this Bar ...
// Calculates Based on atleast 3 Bars Prev ...
ENUM_X_SWING_TYPE GetSwingType()
{
//
ENUM_X_SWING_TYPE result = X_NO_SWING;
//
// Find Current Index of Bar ...
int barIndex = Index();
if (barIndex <= -1)
{
return result;
}
//
// First we have to Retrieve atleast 3 Bars before this bar ...
XOHCL bars[];
int barsCount = GetBars(
bars,
symbol,
period,
barIndex + 1,
3
//
);
if (barsCount < 3)
{
return result;
}
//
// Check Swing Start Candle has Strong Body ...
bool isStrongBodyCandle = bars[2].HasStrongBody();
if (!isStrongBodyCandle)
{
return result;
}
//
// Check Swing Low Conditions ...
bool isSwingLowOrderBlock =
bars[2].low < bars[1].low &&
bars[1].low < bars[0].low &&
bars[2].low < bars[0].low;
if (isSwingLowOrderBlock)
{
result = X_SWING_LOW;
}
//
// Check Swing High Conditions ...
bool isSwingHighOrderBlock =
bars[2].high > bars[1].high &&
bars[1].high > bars[0].high &&
bars[2].high > bars[0].high;
if (isSwingHighOrderBlock)
{
result = X_SWING_HIGH;
}
//
return result;
}
//
// Find Swings (Highs nd Lows) ...
int FindSwing(
ENUM_X_SWING_TYPE swing, // Swing Based On Price mode ...
int mLength // Loopback ...
)
{
//
int result = -1;
//
if (!IsValid() ||
!IsValid(swing))
{
return result;
}
//
int current = Index();
int founded = FindNextSwing(
swing,
(mLength * 2) + 1,
current - mLength
//
);
//
while (founded != current)
{
//
current = FindNextSwing(
swing,
mLength,
current + 1
//
);
//
founded = FindNextSwing(
swing,
(mLength * 2) + 1,
current - mLength
//
);
}
//
result = current;
//
return result;
}
//
// Find Next Swing ...
int FindNextSwing(
ENUM_X_SWING_TYPE swing, // Swing Based On Price mode ...
int from, // from Bar Index
int mLength // Loopback ...
)
{
//
int result = -1;
//
if (!IsValid() ||
!IsValid(swing))
{
return result;
}
//
if (from < 0)
{
mLength += from;
from = 0;
}
//
ENUM_SERIESMODE mMode = swing == X_SWING_HIGH
? MODE_HIGH
: MODE_LOW;
//
result = swing == X_SWING_HIGH
? iHighest(
symbol,
period,
mMode,
mLength,
from)
: iLowest(
symbol,
period,
mMode,
mLength,
from);
//
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;
}
//
// 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;
}
};
//
// Model Support and Resistance
// for Specific Bar ...
struct XOHCLSupRes
{
//
// Props ...
//
/// Resistances ...
double res[];
//
// Supports ...
double sup[];
//
// Constructor ...
XOHCLSupRes()
{
Clean();
}
//
// Init ...
bool Init(
double price, // Price ...
const double &pivots[], // Provided Pivot Points ...
int count = 3, // Number of Requireds ...
double step = 0 // Distance between each item with it's Last Side ...
)
{
//
bool result = false;
//
Clean();
//
if (price <= 0)
{
return result;
}
//
int pivotsCount = ArraySize(pivots);
if (pivotsCount <= 0)
{
return result;
}
//
if (count <= 0 ||
count > pivotsCount - 1)
{
return result;
}
//
double lastR = 0;
double tmpR[];
//
double lastS = 0;
double tmpS[];
//
// Extract Supports ...
// which prices is under low of candle ...
//
// Extract Resistance ...
// which prices is over high of candle ...
for (int i = 0; i < pivotsCount; i++)
{
//
double iFlat = pivots[i];
//
if (iFlat > price)
{
//
bool canAdd =
step <= 0
? true
: lastR == 0 || MathAbs(iFlat - lastR) >= step;
if (canAdd)
{
//
Add(
iFlat,
tmpR);
//
lastR = iFlat;
}
}
else if (iFlat < price)
{
//
bool canAdd =
step <= 0
? true
: lastS == 0 || MathAbs(iFlat - lastS) >= step;
if (canAdd)
{
//
Add(
iFlat,
tmpS);
//
lastS = iFlat;
}
}
}
//
// Sorting Founded Resistance and Supports ...
//
// Since Resistance Levels must be Increasing ...
ArraySort(tmpR);
//
// Since Support Levels must be Decreasing ...
ArraySort(tmpS);
ArrayReverse(tmpS);
//
// Fill Resistance ...
int tmpRCount = ArraySize(tmpR);
if (tmpRCount > 0)
{
//
if (tmpRCount < count)
{
//
ArrayCopy(
res,
tmpR);
}
else
{
//
ArrayCopy(
res,
tmpR,
0,
0,
count);
}
}
//
// Fill Supports ...
int tmpSCount = ArraySize(tmpS);
if (tmpSCount > 0)
{
//
if (tmpSCount < count)
{
//
ArrayCopy(
sup,
tmpS);
}
else
{
//
ArrayCopy(
sup,
tmpS,
0,
0,
count);
}
}
//
result = IsValid();
//
return result;
}
//
// Tools ...
//
// Cleanup ...
void Clean()
{
//
Clean(sup);
Clean(res);
}
//
// Validate ...
bool IsValid()
{
//
bool result = false;
//
result =
//
CountSupports() > 0 ||
CountResistances() > 0
//
;
//
return result;
}
//
int CountSupports()
{
return ArraySize(sup);
}
//
int CountResistances()
{
return ArraySize(res);
}
};
//
// Tracking Times ...
struct XTimeTracker
{
//
// Props ...
int xMonth;
int xDayOfWeek;
int xForWeekDay;
int xDay;
int xHour;
//
// Constructor ...
XTimeTracker()
{
Clean();
}
//
// Tools ...
//
void Clean()
{
//
xDay = -1;
xHour = -1;
xMonth = -1;
xDayOfWeek = -1;
xForWeekDay = -1;
}
//
// 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 ...
//
// 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 Bars(
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;
}
//
// Tools ...
void Clean()
{
//
symbol = NormalizeSymbol(NULL);
period = NormalizePeriod(NULL);
}
};
//
// Track Value Changes ...
template <typename T>
struct XValueTracker
{
//
// Definitions ...
//
// Model a Value Change ...
struct XValueChange
{
//
// Props ...
datetime at; // Change Time
T from; // Before Change Value
T to; // After Change Value
//
// Constructor ...
XValueChange()
{
Clean();
}
//
// Cleanup ...
void Clean()
{
//
at = NULL;
from = NULL;
to = NULL;
}
//
// Validate ...
bool IsValid()
{
//
bool result = false;
//
result = IsValid(at);
if (!result)
{
return result;
}
//
result = NotEmpty(from) &&
NotEmpty(to);
//
return result;
}
};
//
// Props ...
XValueChange changes[]; // Hold Changes
//
// Constructor ...
XValueTracker()
{
Clean();
}
//
// Track a Change Happens Or Not ...
bool Track(
const T &source[] // Data Source for Track Changes
)
{
//
bool result = false;
//
if (ArraySize(source) <= 1)
{
return result;
}
//
datetime time = TimeCurrent();
//
double from = source[1];
double to = source[0];
//
result = to != from;
if (result)
{
return result;
}
//
XValueChange lastChange;
bool hasLastChange =
GetLastItem(
lastChange,
changes
//
);
result =
!hasLastChange
? true
: lastChange.at < time &&
lastChange.to != to &&
lastChange.from != from;
if (!result)
{
return result;
}
//
lastChange.Clean();
//
lastChange.to = to;
lastChange.at = time;
lastChange.from = from;
//
AddRef(
lastChange,
changes
//
);
//
return result;
}
//
// Tools ...
//
// Cleanup ...
void Clean()
{
Clean(changes);
}
};
//
// 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;
}
};
//
// 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;
}
//
// 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;
}
//
// 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;
}
//
// 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 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);
}
//
// 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;
}
//
// 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;
}
//
// 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;
}
//
// 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);
}
//
// 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
)
{
//
int result = 0;
//
if (forceClean)
{
Clean(dest);
}
//
if (start < 0)
{
start = 0;
}
//
if (start >= ArraySize(source))
{
start = ArraySize(source) - 1;
}
//
if (count == 0)
{
count = ArraySize(source);
}
//
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 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>
double GetMax(
T &buffer[], // the Buffer which required to search
int start = 0, // Start Index
int count = 0 // Count for Search
)
{
//
double 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++)
{
//
double iValue = tmp[i];
//
result =
//
result == 0 || result < iValue
//
? iValue
//
: result
//
;
}
//
return result;
}
//
// Get Min of Specific Loopback of a Buffer ...
template <typename T>
double GetMin(
T &buffer[], // the Buffer which required to search
int start = 0, // Start Index
int count = 0 // Count for Search
)
{
//
double 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++)
{
//
double iValue = tmp[i];
//
result =
//
result == 0 || result > iValue
//
? iValue
//
: result
//
;
}
//
return result;
}
//
// 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 prefixSeparator = ":", // Title Separator
string lineSeparator = "\n" // Line Separator
)
{
//
string result = NULL;
//
result = (value || !ignoreFalseConditions)
? 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;
}