Files
xMQL5/MQLTestWorkspace/X121/14030217/Libraries/x-saherelm.common.lib.mq5
T
2024-05-05 23:08:24 +03:30

5096 lines
91 KiB
Plaintext

///////////////////////////////////////////////////////
//
// SaherElm IT Center MQL5 Common Library
// --------------------------------------
// Name: XCommon
// 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
//
// START Inputs ...
//
//
// END Inputs ...
//
//
// Include Models Library ...
#include "x-saherelm.models.lib.mq5"
//
// START Global Definitions: Variables, Properties and etc ...
//
//
// END Global Definitions: Variables, Properties and etc ...
//
//
// START Provided Functions ...
//
//
// Detect is new Candle or not ...
bool IsNewCandle()
{
//
bool result = false;
//
static int barsOnChart = 0;
int currentBarsOnChart = Bars(_Symbol, _Period);
result = currentBarsOnChart > barsOnChart;
if (!result)
{
return result;
}
//
barsOnChart = currentBarsOnChart;
result = true;
//
return result;
}
bool IsNewCandle(
string mSymbol, // Trading Symbol ...
ENUM_TIMEFRAMES mPeriod // Trading Time Frame ...
)
{
//
bool result = false;
//
static string mChartTags[];
static int mChartBars[];
//
string chTag = mSymbol + "," + ToString(mPeriod);
//
int currChTagIdx = -1;
int chCountedBars = 0;
int currentBars = Bars(mSymbol, mPeriod);
//
if (ArraySize(mChartTags) > 0)
{
//
for (int i = 0; i < ArraySize(mChartTags); i++)
{
//
string iTag = mChartTags[i];
if (iTag != chTag)
{
continue;
}
//
currChTagIdx = i;
break;
}
//
if (currChTagIdx > -1)
{
chCountedBars = mChartBars[currChTagIdx];
}
}
//
result = currentBars > chCountedBars;
if (result)
{
//
if (currChTagIdx > -1)
{
//
mChartTags[currChTagIdx] = chTag;
mChartBars[currChTagIdx] = currentBars;
}
else
{
//
Add(chTag, mChartTags);
Add(currentBars, mChartBars);
}
}
//
return result;
}
//
double XNZ(double check, double val = 0)
{
if (check == EMPTY_VALUE || check == 0)
{
return val;
}
else
{
return check;
}
}
//
// Retrive Ask Price ...
double GetAsk()
{
return SymbolInfoDouble(_Symbol, SYMBOL_ASK);
}
double GetAsk(
string symbol // selected symbol for calculations
)
{
//
double result = SymbolInfoDouble(symbol, SYMBOL_ASK);
//
return result;
}
//
// Retrieve Bid Price ...
double GetBid()
{
return SymbolInfoDouble(_Symbol, SYMBOL_BID);
}
double GetBid(
string symbol // selected symbol for calculations
)
{
//
double result = SymbolInfoDouble(symbol, SYMBOL_BID);
//
return result;
}
//
// Calculate and Retrieve Spread Price ...
double GetSpread()
{
//
double ask = GetAsk();
double bid = GetBid();
double result = MathAbs(ask - bid);
//
return result;
}
double GetSpread(
string symbol // selected symbol for calculations
)
{
//
double ask = GetAsk(symbol);
double bid = GetBid(symbol);
double result = MathAbs(ask - bid);
//
return result;
}
//
// Get Points ...
double GetPoints()
{
return _Point;
}
double GetPoints(
string symbol // selected symbol for calculations
)
{
//
double result = SymbolInfoDouble(symbol, SYMBOL_POINT);
//
return result;
}
//
// Get Digits ...
int GetDigits()
{
return _Digits;
}
int GetDigits(
string symbol // selected symbol for calculations
)
{
//
int result = (int)SymbolInfoInteger(symbol, SYMBOL_DIGITS);
//
return result;
}
//
// Get Signal Entry ...
double GetEntry(
ENUM_POSITION_TYPE type // Get entry price for Which direction trade ...
)
{
//
double result = 0;
//
bool isLong = type == POSITION_TYPE_BUY;
result = isLong ? GetAsk() : GetBid();
result = NormalizePrice(result);
//
return result;
}
double GetEntry(
string symbol, // Specified Symbol
ENUM_POSITION_TYPE type // Get entry price for Which direction trade ...
)
{
//
double result = 0;
//
bool isLong = type == POSITION_TYPE_BUY;
result = isLong ? GetAsk(symbol) : GetBid(symbol);
result = NormalizePrice(result, symbol);
//
return result;
}
//
// Get Signal Exit ...
double GetExit(
ENUM_POSITION_TYPE type // Get entry price for Which direction trade ...
)
{
//
double result = 0;
//
bool isLong = type == POSITION_TYPE_BUY;
result = isLong ? GetBid() : GetAsk();
result = NormalizePrice(result);
//
return result;
}
double GetExit(
string symbol, // Specified Symbol
ENUM_POSITION_TYPE type // Get entry price for Which direction trade ...
)
{
//
double result = 0;
//
bool isLong = type == POSITION_TYPE_BUY;
result = isLong ? GetBid(symbol) : GetAsk(symbol);
result = NormalizePrice(result, symbol);
//
return result;
}
//
// 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;
}
//
// Get 1 Pip in Price Value ...
double GetPipPrice()
{
//
double result = _Point;
if (_Digits == 3 || _Digits == 5)
{
result *= 10;
}
//
return result;
}
double GetPipPrice(
string symbol // selected symbol for calculations
)
{
//
double symbolPoint = GetPoints(symbol);
int symbolDigits = GetDigits(symbol);
//
double result = symbolPoint;
if (symbolDigits == 3 || symbolDigits == 5)
{
result *= 10;
}
//
return result;
}
//
// Converts Pips To Price ...
double PipsToPrice(
int pips // pips amount
)
{
//
int digits = GetDigits();
double pipValue = GetPipPrice();
double result = pips * pipValue;
//
result = NormalizeDouble(result, digits);
//
return result;
}
double PipsToPrice(
double pips // pips amount
)
{
//
int digits = GetDigits();
double pipValue = GetPipPrice();
double result = pips * pipValue;
//
result = NormalizeDouble(result, digits);
//
return result;
}
double PipsToPrice(
string symbol, // selected symbol for calculation
int pips // pips amount
)
{
//
int digits = GetDigits(symbol);
double pipValue = GetPipPrice(symbol);
double result = pips * pipValue;
//
result = NormalizeDouble(result, digits);
//
return result;
}
double PipsToPrice(
string symbol, // selected symbol for calculation
double pips // pips amount
)
{
//
int digits = GetDigits(symbol);
double pipValue = GetPipPrice(symbol);
double result = pips * pipValue;
//
result = NormalizeDouble(result, digits);
//
return result;
}
//
// Converts Price to Pips ...
double PriceToPips(
double price // the price amount which required to calculate
)
{
//
int digits = GetDigits();
double pipPrice = GetPipPrice();
//
double result = price / pipPrice;
//
result = NormalizeDouble(result, digits);
//
return result;
}
double PriceToPips(
string symbol, // Selected Symbol
double price // the price amount which required to calculate
)
{
//
int digits = GetDigits(symbol);
double pipPrice = GetPipPrice(symbol);
//
double result = price / pipPrice;
//
result = NormalizeDouble(result, digits);
//
return result;
}
//
// Convert Price to Point ...
double PriceToPoint(
double price // the price amount which required to calculate
)
{
return PriceToPoint(_Symbol, price);
}
double PriceToPoint(
string symbol, // Selected Symbol
double price // the price amount which required to calculate
)
{
//
double result = 0;
//
double point = GetPoints(symbol);
result = price / point;
//
return result;
}
//
// Converts Point to Price ...
double PointToPrice(
double points // Points Size
)
{
return PointToPrice(_Symbol, points);
}
double PointToPrice(
string symbol, // Selected Symbol
double points // Points Size
)
{
//
double result = 0;
//
double point = GetPoints(symbol);
result = points * point;
//
return result;
}
//
// CANDLES ...
//
// Validate Candle ...
bool IsValid(
XOHCL &candle // specified candle
)
{
//
bool result = false;
//
result =
//
candle.open > 0 &&
candle.close > 0 &&
candle.high > 0 &&
candle.low > 0
//
;
//
return result;
}
//
// Get a Candle Body ...
double GetCandleBody(
XOHCL &candle // specified candle
)
{
//
double result = 0;
//
bool isValid = IsValid(candle);
if (!isValid)
{
return result;
}
//
result = MathAbs(candle.open - candle.close);
//
return result;
}
//
// Get a Candle Range ...
double GetCandleRange(
XOHCL &candle // specified candle
)
{
//
double result = 0;
//
bool isValid = IsValid(candle);
if (!isValid)
{
return result;
}
//
result = MathAbs(candle.high - candle.low);
//
return result;
}
//
// Get a Candle Shadow ...
double GetCandleShadow(
XOHCL &candle // specified candle
)
{
//
double result = 0;
//
bool isValid = IsValid(candle);
if (!isValid)
{
return 0;
}
//
double range = GetCandleRange(candle);
double body = GetCandleBody(candle);
//
result = MathAbs(range - body);
//
return result;
}
//
// Retrieve High Shadow of Candle ...
double GetCandleHighShadow(
XOHCL &candle // specified candle
)
{
//
double result = 0;
//
bool isValid = IsValid(candle);
if (!isValid)
{
return result;
}
//
double upPrice = MathMax(candle.open, candle.close);
//
result = candle.high - upPrice;
//
return result;
}
//
// Retrieve Low Shadow of Candle ...
double GetCandleLowShadow(
XOHCL &candle // specified candle
)
{
//
double result = 0;
//
bool isValid = IsValid(candle);
if (!isValid)
{
return result;
}
//
double downPrice = MathMin(candle.open, candle.close);
//
result = downPrice - candle.low;
//
return result;
}
//
// Check a Candle is Base Candle for RTM or not ...
bool IsBaseCandle(
XOHCL &candle // specified candle
)
{
//
double range = GetCandleRange(candle);
double body = GetCandleBody(candle);
//
bool result = body > range;
//
return result;
}
//
// Check Candle Body Bigger Than it's Shadow ...
bool CandleHasStrongBody(XOHCL &candle)
{
//
double bodySize = MathAbs(candle.open - candle.close);
double shadowSize = MathAbs(candle.high - candle.low) - bodySize;
//
bool result = bodySize > (shadowSize * 1.5);
//
return result;
}
//
// Detect Doji Candle ...
bool IsDojiCandle(
XOHCL &candle, // Specified Candle
double detectFactor = 0.05 // Detect Factor
)
{
//
bool result = false;
//
bool isValid = IsValid(candle);
if (
!isValid ||
detectFactor <= 0 ||
detectFactor > 1)
{
return result;
}
//
// Retrieve Candle Parts ...
double body = GetCandleBody(candle);
double range = GetCandleRange(candle);
double shadows = GetCandleShadow(candle);
//
// Calculate Candle Rate ...
double factor = range * detectFactor;
double shadowFactor = (1 - detectFactor) * range;
//
result =
//
body > 0 &&
range > 0 &&
factor > 0 &&
shadows > 0 &&
body <= factor &&
shadowFactor > 0 &&
shadows >= shadowFactor
//
;
//
return result;
}
//
// Detect Shadows of Specific Candles must be same ..
bool IsCrossShadowCandle(
XOHCL &candle, // Specified Candle
double smoothingFactor = 0.05 // Smoothing Factor
)
{
//
bool result = false;
//
bool isValid = IsValid(candle);
if (!isValid ||
smoothingFactor <= 0 ||
smoothingFactor >= 1)
{
return result;
}
//
// Retrieve Candle Parts ...
double body = GetCandleBody(candle);
double range = GetCandleRange(candle);
double shadows = GetCandleShadow(candle);
//
double upBody = MathMax(candle.open, candle.close);
double downBody = MathMin(candle.open, candle.close);
//
double upShadow = candle.high - upBody;
double downShadow = downBody - candle.low;
//
// Calculate Candle Rate ...
double factor = range * smoothingFactor;
//
result =
upShadow > 0 &&
downShadow > 0 &&
body > 0 &&
range > 0 &&
shadows > 0 &&
((upShadow == downShadow) ||
MathAbs(upShadow - downShadow) <= factor);
//
return result;
}
//
// Detect a Candle Shadow Hunt Specific price or not ...
bool IsShadowHuntCandle(
XOHCL &candle, // Specified Candle
double price // Specified Price
)
{
//
bool result = false;
//
// Validate Args ...
bool isValid = IsValid(candle);
if (!isValid || price <= 0)
{
return result;
}
//
double upBody = MathMax(candle.open, candle.close);
double downBody = MathMin(candle.open, candle.close);
//
double hShadow = GetCandleHighShadow(candle);
double lShadow = GetCandleLowShadow(candle);
//
double range = GetCandleRange(candle);
double factor = range * 0.3;
//
bool isStrongHShadow = hShadow >= factor;
bool isStrongLShadow = lShadow >= factor;
//
bool isPriceUp =
price >= candle.high ||
price >= upBody;
//
result =
//
isPriceUp
//
?
//
isStrongHShadow &&
(price == candle.high ||
(price > upBody && price < candle.high))
//
:
//
isStrongLShadow &&
(price == candle.low ||
(price < downBody && price > candle.low))
//
;
//
return result;
}
//
// Check a Candle is Bullish or not ...
bool IsBullishCandle(
XOHCL &candle // specified candle
)
{
//
bool result = false;
//
bool isValid = IsValid(candle);
if (!isValid)
{
return result;
}
//
result = candle.open < candle.close;
//
return result;
}
bool IsBullishCandle(
int bar_index // candle index
)
{
//
bool result = false;
//
XOHCL candle = GetCandle(bar_index);
//
result = IsBullishCandle(candle);
//
return result;
}
bool IsBullishCandle(
string symbol, // specify symbol
ENUM_TIMEFRAMES mPeriod, // specify timeframe
int bar_index // candle index
)
{
//
bool result = false;
//
XOHCL candle = GetCandle(
symbol,
mPeriod,
bar_index);
//
result = IsBullishCandle(candle);
//
return result;
}
//
// Check a Candle is Bullish or not ...
bool IsBearishCandle(
XOHCL &candle // specified candle
)
{
//
bool result = false;
//
bool isValid = IsValid(candle);
if (!isValid)
{
return result;
}
//
result = candle.open > candle.close;
//
return result;
}
bool IsBearishCandle(
int bar_index // candle index
)
{
//
bool result = false;
//
XOHCL candle = GetCandle(bar_index);
//
result = IsBearishCandle(candle);
//
return result;
}
bool IsBearishCandle(
string symbol, // specify symbol
ENUM_TIMEFRAMES mPeriod, // specify timeframe
int bar_index // candle index
)
{
//
bool result = false;
//
XOHCL candle = GetCandle(
symbol,
mPeriod,
bar_index);
//
result = IsBearishCandle(candle);
//
return result;
}
//
// Retrieve Applied Price at Specific Candle ...
double GetAppliedPrice(
XOHCL &candle, // specified candle
ENUM_APPLIED_PRICE source = PRICE_CLOSE // specified Applied To
)
{
//
double result = EMPTY_VALUE;
//
switch (source)
{
//
// Open ...
case PRICE_OPEN:
result = candle.open;
break;
//
// High ...
case PRICE_HIGH:
result = candle.high;
break;
//
// Low ...
case PRICE_LOW:
result = candle.low;
break;
//
// Median ((High + Low) / 2) ...
case PRICE_MEDIAN:
result = (candle.high + candle.low) / 2;
break;
//
// Typical ((High + Low + Close)/3) ...
case PRICE_TYPICAL:
result = (candle.high + candle.low + candle.close) / 3;
break;
//
// Weighted ((High + Low + Close + Close)/4) ...
case PRICE_WEIGHTED:
result = (candle.high + candle.low + (candle.close * 2)) / 4;
break;
//
// Close ...
default:
case PRICE_CLOSE:
result = candle.close;
break;
}
//
return result;
}
double GetAppliedPrice(
int bar_index, // specify candle index
ENUM_APPLIED_PRICE source = PRICE_CLOSE // specified Applied To
)
{
//
double result = EMPTY_VALUE;
//
XOHCL candle = GetCandle(bar_index);
result = GetAppliedPrice(candle, source);
//
return result;
}
double GetAppliedPrice(
int bar_index, // specify candle index
ENUM_SERIESMODE mode // converts Series Mode to Applied Price ...
)
{
//
double result = 0;
//
ENUM_APPLIED_PRICE mAppliedTo = To(mode);
result = GetAppliedPrice(
bar_index,
mAppliedTo);
//
return result;
}
//
template <typename T>
double GetAppliedPrice(ENUM_APPLIED_PRICE tprice, T &open[], T &high[], T &low[], T &close[], int i)
{
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);
}
//
// Converts ...
ENUM_APPLIED_PRICE To(
ENUM_SERIESMODE mode // converts Series Mode to Applied Price ...
)
{
//
ENUM_APPLIED_PRICE result = PRICE_CLOSE;
//
switch (mode)
{
//
// High ...
case MODE_HIGH:
result = PRICE_HIGH;
break;
//
// Open ...
case MODE_OPEN:
result = PRICE_OPEN;
break;
//
// Low ...
case MODE_LOW:
result = PRICE_LOW;
break;
//
// Close ...
// Default ...
case MODE_CLOSE:
default:
result = PRICE_CLOSE;
break;
}
//
return result;
}
//
// Retrieve a Candel Data ...
XOHCL GetCandle(int bar_index)
{
//
XOHCL result = {};
//
double open = iOpen(_Symbol, _Period, bar_index);
double high = iHigh(_Symbol, _Period, bar_index);
double close = iClose(_Symbol, _Period, bar_index);
double low = iLow(_Symbol, _Period, bar_index);
//
result.low = low;
result.open = open;
result.high = high;
result.close = close;
//
return result;
}
XOHCL GetCandle(
ENUM_TIMEFRAMES mPeriod, // specify timeframe
int bar_index // specify candle index
)
{
//
XOHCL result = {};
//
double open = iOpen(_Symbol, mPeriod, bar_index);
double high = iHigh(_Symbol, mPeriod, bar_index);
double close = iClose(_Symbol, mPeriod, bar_index);
double low = iLow(_Symbol, mPeriod, bar_index);
//
result.low = low;
result.open = open;
result.high = high;
result.close = close;
//
return result;
}
XOHCL GetCandle(
string symbol, // specify symbol
ENUM_TIMEFRAMES mPeriod, // specify timeframe
int bar_index // specify candle index
)
{
//
XOHCL result = {};
//
double open = iOpen(symbol, mPeriod, bar_index);
double high = iHigh(symbol, mPeriod, bar_index);
double close = iClose(symbol, mPeriod, bar_index);
double low = iLow(symbol, mPeriod, bar_index);
//
result.low = low;
result.open = open;
result.high = high;
result.close = close;
//
return result;
}
//
// Get a Series Of Candles ...
bool GetCandles(
XOHCL &result[], // Hold Result ...
string mSymbol = NULL, // Specified Symbol ...
ENUM_TIMEFRAMES mPeriod = NULL, // Specified Period ...
int mStart = 0, // Start Bar Index ...
int mCount = 1 // Specified Number of Candles ...
)
{
//
bool mResult = false;
//
if (mStart < 0)
{
mStart = 0;
}
//
if (mCount <= 0)
{
mCount = 1;
}
//
Clean(result);
//
for (int i = mStart; i < mStart + mCount; i++)
{
//
XOHCL iC = GetCandle(
mSymbol,
mPeriod,
i);
//
Add(
iC,
result);
}
//
mResult = ArraySize(result) > 0;
//
return mResult;
}
//
// Retrieve a candle index in current timeframe inside another timeframe ...
int GetCandleBarIndex(
int bar_index, // Specify Candle index in current timeframe
ENUM_TIMEFRAMES destPeriod // Specify destination timeframe
)
{
//
int result = -1;
//
datetime barTime = iTime(_Symbol, _Period, bar_index);
result = iBarShift(_Symbol, destPeriod, barTime);
//
return result;
}
//
// Retrieve a symbol candle index in source time frame inside dest timeframe ...
int GetCandleBarIndex(
int bar_index, // Specify Candle index in current timeframe
string symbol, // Specify desired Symbol
ENUM_TIMEFRAMES sourcePeriod, // Specify bar_index timeframe
ENUM_TIMEFRAMES destPeriod // Specify destination timeframe
)
{
//
int result = -1;
//
datetime barTime = iTime(symbol, sourcePeriod, bar_index);
result = iBarShift(symbol, destPeriod, barTime);
//
return result;
}
//
// Determines a cnadle is Swing High
// or Swing Low order block ...
ENUM_X_SWING_TYPE GetCandleSwing(int bar_index)
{
//
ENUM_X_SWING_TYPE result = X_NO_SWING;
//
// Reading Candle Models ...
XOHCL candles[3];
candles[0] = GetCandle(bar_index + 1);
candles[1] = GetCandle(bar_index + 2);
candles[2] = GetCandle(bar_index + 3);
//
// Check Swing Start Candle has Strong Body ...
bool isStrongBodyCandle = CandleHasStrongBody(candles[2]);
if (!isStrongBodyCandle)
{
return result;
}
//
// Check Swing Low Conditions ...
bool isSwingLowOrderBlock =
candles[2].low < candles[1].low &&
candles[1].low < candles[0].low &&
candles[2].low < candles[0].low;
if (isSwingLowOrderBlock)
{
result = X_SWING_LOW;
}
//
// Check Swing High Conditions ...
bool isSwingHighOrderBlock =
candles[2].high > candles[1].high &&
candles[1].high > candles[0].high &&
candles[2].high > candles[0].high;
if (isSwingHighOrderBlock)
{
result = X_SWING_HIGH;
}
//
return result;
}
ENUM_X_SWING_TYPE GetCandleSwing(
ENUM_TIMEFRAMES mPeriod, // specify timeframe
int bar_index // specify candle index
)
{
//
ENUM_X_SWING_TYPE result = X_NO_SWING;
//
// Reading Candle Models ...
XOHCL candles[3];
candles[0] = GetCandle(mPeriod, bar_index + 1);
candles[1] = GetCandle(mPeriod, bar_index + 2);
candles[2] = GetCandle(mPeriod, bar_index + 3);
//
// Check Swing Start Candle has Strong Body ...
bool isStrongBodyCandle = CandleHasStrongBody(candles[2]);
if (!isStrongBodyCandle)
{
return result;
}
//
// Check Swing Low Conditions ...
bool isSwingLowOrderBlock =
candles[2].low < candles[1].low &&
candles[1].low < candles[0].low &&
candles[2].low < candles[0].low;
if (isSwingLowOrderBlock)
{
result = X_SWING_LOW;
}
//
// Check Swing High Conditions ...
bool isSwingHighOrderBlock =
candles[2].high > candles[1].high &&
candles[1].high > candles[0].high &&
candles[2].high > candles[0].high;
if (isSwingHighOrderBlock)
{
result = X_SWING_HIGH;
}
//
return result;
}
ENUM_X_SWING_TYPE GetCandleSwing(
string symbol, // specify symbol
ENUM_TIMEFRAMES mPeriod, // specify timeframe
int bar_index // specify candle index
)
{
//
ENUM_X_SWING_TYPE result = X_NO_SWING;
//
// Reading Candle Models ...
XOHCL candles[3];
candles[0] = GetCandle(symbol, mPeriod, bar_index + 1);
candles[1] = GetCandle(symbol, mPeriod, bar_index + 2);
candles[2] = GetCandle(symbol, mPeriod, bar_index + 3);
//
// Check Swing Start Candle has Strong Body ...
bool isStrongBodyCandle = CandleHasStrongBody(candles[2]);
if (!isStrongBodyCandle)
{
return result;
}
//
// Check Swing Low Conditions ...
bool isSwingLowOrderBlock =
candles[2].low < candles[1].low &&
candles[1].low < candles[0].low &&
candles[2].low < candles[0].low;
if (isSwingLowOrderBlock)
{
result = X_SWING_LOW;
}
//
// Check Swing High Conditions ...
bool isSwingHighOrderBlock =
candles[2].high > candles[1].high &&
candles[1].high > candles[0].high &&
candles[2].high > candles[0].high;
if (isSwingHighOrderBlock)
{
result = X_SWING_HIGH;
}
//
return result;
}
//
// Find Swing Points ...
int FindSwing(
string mSymbol, // Trading Symbol ...
ENUM_TIMEFRAMES mPeriod, // Trading Period ...
ENUM_SERIESMODE mode, // Swing Based On Price mode ...
int mLength, // Loopback ...
int bar_index // BarIndex ...
)
{
//
int result = -1;
//
if (StringLen(mSymbol) == 0 || (mode != MODE_HIGH && mode != MODE_LOW))
{
return result;
}
//
int current = bar_index;
int founded = FindNextSwing(
mSymbol,
mPeriod,
mode,
(mLength * 2) + 1,
current - mLength);
//
while (founded != current)
{
//
current = FindNextSwing(
mSymbol,
mPeriod,
mode,
mLength,
current + 1);
//
founded = FindNextSwing(
mSymbol,
mPeriod,
mode,
(mLength * 2) + 1,
current - mLength);
}
//
result = current;
//
return result;
}
//
// Find Next Swing ...
int FindNextSwing(
string mSymbol, // Trading Symbol ...
ENUM_TIMEFRAMES mPeriod, // Trading Period ...
ENUM_SERIESMODE mode, // 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;
}
//
result = mode == MODE_HIGH
? iHighest(
mSymbol,
mPeriod,
mode,
mLength,
bar_index)
: iLowest(
mSymbol,
mPeriod,
mode,
mLength,
bar_index);
//
return result;
}
//
// Retrieve Market Highest High ...
double GetHighestHigh(
int mLength, // Which market Length use
int bar_index // bar index
)
{
//
double result = -1;
//
int rIdx = iHighest(
_Symbol,
_Period,
MODE_HIGH,
mLength,
bar_index);
//
result = iHigh(
_Symbol,
_Period,
rIdx);
//
return result;
}
double GetHighestHigh(
int mLength, // Which market Length use
int bar_index, // bar index
ENUM_SERIESMODE mode // Calculation mode
)
{
//
double result = -1;
//
int rIdx = iHighest(
_Symbol,
_Period,
mode,
mLength,
bar_index);
//
result = iHigh(
_Symbol,
_Period,
rIdx);
//
return result;
}
double GetHighestHigh(
string symbol, // Specified Symbol
ENUM_TIMEFRAMES mPeriod, // Specified Period
int mLength, // Which market Length use
int bar_index // bar index
)
{
//
double result = -1;
//
int rIdx = iHighest(
symbol,
mPeriod,
MODE_HIGH,
mLength,
bar_index);
//
result = iHigh(
symbol,
mPeriod,
rIdx);
//
return result;
}
double GetHighestHigh(
string symbol, // Specified Symbol
ENUM_TIMEFRAMES mPeriod, // Specified Period
ENUM_SERIESMODE mode, // Calculation mode
int mLength, // Which market Length use
int bar_index // bar index
)
{
//
double result = -1;
//
int rIdx = iHighest(
symbol,
mPeriod,
mode,
mLength,
bar_index);
//
result = iHigh(
symbol,
mPeriod,
rIdx);
//
return result;
}
//
// Retrieve Market Lowest Low ...
double GetLowestLow(
int mLength, // Which market Length use
int bar_index // bar index
)
{
//
double result = -1;
//
int rIdx = iLowest(
_Symbol,
_Period,
MODE_LOW,
mLength,
bar_index);
//
result = iLow(
_Symbol,
_Period,
rIdx);
//
return result;
}
double GetLowestLow(
int mLength, // Which market Length use
int bar_index, // bar index
ENUM_SERIESMODE mode // Calculation mode
)
{
//
double result = -1;
//
int rIdx = iLowest(
_Symbol,
_Period,
mode,
mLength,
bar_index);
//
result = iLow(
_Symbol,
_Period,
rIdx);
//
return result;
}
double GetLowestLow(
string symbol, // Specified Symbol
ENUM_TIMEFRAMES mPeriod, // Specified Period
int mLength, // Which market Length use
int bar_index // bar index
)
{
//
double result = -1;
//
int rIdx = iLowest(
symbol,
mPeriod,
MODE_LOW,
mLength,
bar_index);
//
result = iLow(
symbol,
mPeriod,
rIdx);
//
return result;
}
double GetLowestLow(
string symbol, // Specified Symbol
ENUM_TIMEFRAMES mPeriod, // Specified Period
ENUM_SERIESMODE mode, // Calculation mode
int mLength, // Which market Length use
int bar_index // bar index
)
{
//
double result = -1;
//
int rIdx = iLowest(
symbol,
mPeriod,
mode,
mLength,
bar_index);
//
result = iLow(
symbol,
mPeriod,
rIdx);
//
return result;
}
//
// Find Support and Resistance for Specific Bar based on provided Buffer ...
XOHCLSupRes ExtractSupportAndResistance(
int barIndex, // Bar Index ...
const double &pivots[], // Provided Pivot Points ...
int count = 3, // Number of Requireds ...
string mSymbol = NULL, // Trading Symbol ...
ENUM_TIMEFRAMES mPeriod = NULL // Trading Period ...
)
{
//
if (StringLen(mSymbol) == 0 || mSymbol == NULL)
{
mSymbol = _Symbol;
}
//
if (mPeriod == NULL)
{
mPeriod = _Period;
}
//
if (barIndex < 0)
{
barIndex = 0;
}
//
XOHCLSupRes result;
Clean(result.res);
Clean(result.sup);
//
int pivotsCount = ArraySize(pivots);
if (pivotsCount <= 0)
{
return result;
}
//
if (count <= 0 ||
count > pivotsCount - 1)
{
return result;
}
//
XOHCL cBar = GetCandle(
mSymbol,
mPeriod,
barIndex);
//
double tmpR[];
//
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 > cBar.high)
{
Add(
iFlat,
tmpR);
}
else if (iFlat < cBar.low)
{
Add(
iFlat,
tmpS);
}
}
//
// 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(
result.res,
tmpR);
}
else
{
//
ArrayCopy(
result.res,
tmpR,
0,
0,
count);
}
}
//
// Fill Supports ...
int tmpSCount = ArraySize(tmpS);
if (tmpSCount > 0)
{
//
if (tmpSCount < count)
{
//
ArrayCopy(
result.sup,
tmpS);
}
else
{
//
ArrayCopy(
result.sup,
tmpS,
0,
0,
count);
}
}
//
return result;
}
//
// Find Support and Resistance for Specific Price based on provided Buffer ...
XOHCLSupRes ExtractSupportAndResistance(
double price, // Price ...
const double &pivots[], // Provided Pivot Points ...
int count = 3 // Number of Requireds ...
)
{
//
XOHCLSupRes result;
Clean(result.res);
Clean(result.sup);
//
if (price <= 0)
{
return result;
}
//
int pivotsCount = ArraySize(pivots);
if (pivotsCount <= 0)
{
return result;
}
//
if (count <= 0 ||
count > pivotsCount - 1)
{
return result;
}
//
double tmpR[];
//
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)
{
Add(
iFlat,
tmpR);
}
else if (iFlat < price)
{
Add(
iFlat,
tmpS);
}
}
//
// 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(
result.res,
tmpR);
}
else
{
//
ArrayCopy(
result.res,
tmpR,
0,
0,
count);
}
}
//
// Fill Supports ...
int tmpSCount = ArraySize(tmpS);
if (tmpSCount > 0)
{
//
if (tmpSCount < count)
{
//
ArrayCopy(
result.sup,
tmpS);
}
else
{
//
ArrayCopy(
result.sup,
tmpS,
0,
0,
count);
}
}
//
return result;
}
//
// Find a Value less than Specified ...
double FindLesserThanValue(
double value, // Specified Value ...
const double &source[], // Source ...
bool isDescend = false // Find Biggest Lesser Value ...
)
{
//
double result = -1;
//
int itemsCount = ArraySize(source);
if (itemsCount <= 0)
{
return result;
}
//
// Make a Copy of source ...
double 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++)
{
//
double iValue = tmp[i];
//
if (iValue < value)
{
//
result = iValue;
break;
}
}
//
return result;
}
//
// Find a Value less than Specified ...
double FindBiggerThanValue(
double value, // Specified Value ...
const double &source[], // Source ...
bool isDescend = false // Find Smallest Bigger Value ...
)
{
//
double result = -1;
//
int itemsCount = ArraySize(source);
if (itemsCount <= 0)
{
return result;
}
//
// Make a Copy of source ...
double 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++)
{
//
double iValue = tmp[i];
//
if (iValue > value)
{
//
result = iValue;
break;
}
}
//
return result;
}
//
// Calculate Fib Level ...
double GetFibonacciLevel(
double upPrice,
double downPrice,
double level,
int direction)
{
//
double ling = upPrice - downPrice;
double pLevel = (ling / 100) * (level * 100);
//
double result = direction > 0 ? upPrice - pLevel : downPrice + pLevel;
result = NormalizeDouble(result, _Digits);
//
return result;
}
//
// Check first Cross Over second at bar_index ...
bool IsCrossOver(
const double &first[], // the buffer which check crossing over second buffer
const double &second[], // first buffer checks based on this buffer
const int bar_index // check crosses in specific index
)
{
//
bool result = false;
//
ArraySetAsSeries(first, true);
ArraySetAsSeries(second, true);
//
// Validate Args ...
if (ArraySize(first) < bar_index + 1 || ArraySize(second) < bar_index + 1)
{
return result;
}
//
result = first[bar_index] > second[bar_index] &&
!(first[bar_index + 1] > second[bar_index + 1]);
//
return result;
}
//
// Check first is Over second at bar_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 bar_index // check crosses in specific index
)
{
//
bool result = false;
//
ArraySetAsSeries(first, true);
ArraySetAsSeries(second, true);
//
// Validate Args ...
if (ArraySize(first) < bar_index + 1 || ArraySize(second) < bar_index + 1)
{
return result;
}
//
result = first[bar_index] > second[bar_index] &&
first[bar_index + 1] > second[bar_index + 1];
//
return result;
}
//
// Check first Cross Under second at bar_index ...
bool IsCrossUnder(
const double &first[], // the buffer which check crossing under second buffer
const double &second[], // first buffer checks based on this buffer
const int bar_index // check crosses in specific index
)
{
//
bool result = false;
//
ArraySetAsSeries(first, true);
ArraySetAsSeries(second, true);
//
// Validate Args ...
if (ArraySize(first) < bar_index + 1 || ArraySize(second) < bar_index + 1)
{
return result;
}
//
result = first[bar_index] < second[bar_index] &&
!(first[bar_index + 1] < second[bar_index + 1]);
//
return result;
}
//
// Check first is Under second at bar_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 bar_index // check crosses in specific index
)
{
//
bool result = false;
//
ArraySetAsSeries(first, true);
ArraySetAsSeries(second, true);
//
// Validate Args ...
if (ArraySize(first) < bar_index + 1 || ArraySize(second) < bar_index + 1)
{
return result;
}
//
result = first[bar_index] < second[bar_index] &&
first[bar_index + 1] < second[bar_index + 1];
//
return result;
}
//
// Calculate Slope of Specified Buffer at Specified Index ...
double GetSlope(
int from, // In Past Index ...
int to, // In Past Index ...
double &buffer[])
{
//
double result = 0;
//
double toValue = buffer[to];
double fromValue = buffer[from];
double deltaValue = toValue - fromValue;
double deltaTime = from - to;
//
result = deltaValue / deltaTime;
//
return result;
}
//
// Check if a Value Increasing in Loopback ...
bool IsIncreasing(
int from, // Last Time Index
int to, // Fisr Tima Index
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(
int from, // Last Time Index
int to, // Fisr Tima Index
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;
}
//
// Get Max Value of Specific Loopback of a Buffer ...
double GetMaxValue(
int mLoopback, // loopback length
double &buffer[] // the Buffer which required to search
)
{
//
double result = 0;
//
// Validate Args ...
if (
mLoopback < 2 ||
ArraySize(buffer) < mLoopback)
{
return result;
}
//
// Loop Through LoopBack ...
for (int i = 0; i < mLoopback; i++)
{
//
double iValue = buffer[i];
//
result =
//
result == 0 || result < iValue
//
? iValue
//
: result
//
;
}
//
return result;
}
//
// Get Min Value of Specific Loopback of a Buffer ...
double GetMinValue(
int mLoopback, // loopback length
double &buffer[] // the Buffer which required to search
)
{
//
double result = 0;
//
// Validate Args ...
if (
mLoopback < 2 ||
ArraySize(buffer) < mLoopback)
{
return result;
}
//
// Loop Through LoopBack ...
for (int i = 0; i < mLoopback; i++)
{
//
double iValue = buffer[i];
//
result =
//
result == 0 || result > iValue
//
? iValue
//
: result
//
;
}
//
return result;
}
//
// Find Same Values in Array ...
void FindSameValueInBuffer(
double &result[], // Holds Result ...
double &source[], // Source ...
int verifications = 3 // Number of Consequence Repeat ...
)
{
//
Clean(result);
//
// TenkanSen Flats ...
int sourceCount = ArraySize(source);
if (sourceCount > verifications)
{
//
double mLast = 0;
int mVerified = 0;
for (int i = 0; i < sourceCount; i++)
{
//
double 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;
}
}
}
}
//
bool IsInPeak(
int mLoopback, // loopback length
double &buffer[] // the Buffer which required to search
)
{
//
bool result = false;
//
// Validate Args ...
if (
mLoopback < 2 ||
ArraySize(buffer) < mLoopback + 1)
{
return result;
}
//
int q1Length = mLoopback / 4;
int halfLength = mLoopback / 2;
int q2Length = halfLength + q1Length;
//
double firstValue = buffer[1];
double q1Value = buffer[q1Length];
double q2Value = buffer[q2Length];
double halfValue = buffer[halfLength];
double lastValue = buffer[ArraySize(buffer) - 1];
//
// Peak ...
result =
//
firstValue > lastValue
//
&&
//
(
firstValue > q1Value &&
firstValue > halfValue)
//
;
//
return result;
}
//
bool IsInVale(
int mLoopback, // loopback length
double &buffer[] // the Buffer which required to search
)
{
//
bool result = false;
//
// Validate Args ...
if (
mLoopback < 2 ||
ArraySize(buffer) < mLoopback + 1)
{
return result;
}
//
int q1Length = mLoopback / 4;
int halfLength = mLoopback / 2;
int q2Length = halfLength + q1Length;
//
double firstValue = buffer[1];
double q1Value = buffer[q1Length];
double q2Value = buffer[q2Length];
double halfValue = buffer[halfLength];
double lastValue = buffer[ArraySize(buffer) - 1];
//
// Peak ...
result =
//
firstValue < lastValue
//
&&
//
(
firstValue < q1Value &&
firstValue < halfValue)
//
;
//
return result;
}
//
// Check Sharp Happens or not ...
bool IsSharpChanged(
double fromValue, // Past Value
double toValue, // Present Value
double maxValue, // Max in Range Value
double minValue // Min in Range Value
)
{
//
bool result = false;
//
// This Used In Increased or Decreased Sharp Detection ...
bool isIncreased = toValue > fromValue;
//
double toFromDelta = MathAbs(toValue - fromValue);
double minMaxDelta = maxValue - minValue;
//
result = toFromDelta >= (minMaxDelta / 3);
//
return result;
}
bool IsSharpChanged(
int from, // Past Index in Series
int to, // Present Index in Series
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];
//
// This Used In Increased or Decreased Sharp Detection ...
bool isIncreased = toValue > fromValue;
//
double minValue = GetMinValue(
ArraySize(buffer) - 1,
buffer);
double maxValue = GetMaxValue(
ArraySize(buffer) - 1,
buffer);
double minMaxDelta = maxValue - minValue;
//
// Sharp Detection ...
result = IsSharpChanged(
fromValue,
toValue,
maxValue,
minValue);
//
return result;
}
bool IsSharpChanged(
int from, // Past Bar Index
int to, // Present Bar Index
ENUM_APPLIED_PRICE appliedPrice // Which Price Choose in From or To
)
{
//
bool result = false;
//
double toValue = GetAppliedPrice(
to,
appliedPrice);
double fromValue = GetAppliedPrice(
from,
appliedPrice);
//
int hIdx = iHighest(
_Symbol,
_Period,
MODE_HIGH,
from,
to);
double maxValue = iHigh(
_Symbol,
_Period,
hIdx);
//
int lIdx = iLowest(
_Symbol,
_Period,
MODE_LOW,
from,
to);
double minValue = iLow(
_Symbol,
_Period,
lIdx);
//
result = IsSharpChanged(
fromValue,
toValue,
maxValue,
minValue);
//
return result;
}
//
// Check InCreased Sharp Happens or not ...
bool IsSharpIncreasedChanged(
double fromValue, // Past Value
double toValue, // Present Value
double maxValue, // Max in Range Value
double minValue // Min in Range Value
)
{
//
bool result = false;
//
// This Used In Increased or Decreased Sharp Detection ...
bool isIncreased = toValue > fromValue;
//
double toFromDelta = MathAbs(toValue - fromValue);
double minMaxDelta = maxValue - minValue;
//
result =
isIncreased &&
toFromDelta >= (minMaxDelta / 3);
//
return result;
}
bool IsSharpIncreasedChanged(
int from, // Past Index in Series
int to, // Present Index in Series
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];
//
double minValue = GetMinValue(
ArraySize(buffer) - 1,
buffer);
double maxValue = GetMaxValue(
ArraySize(buffer) - 1,
buffer);
double minMaxDelta = maxValue - minValue;
//
// Sharp Detection ...
result = IsSharpIncreasedChanged(
fromValue,
toValue,
maxValue,
minValue);
//
return result;
}
bool IsSharpIncreasedChanged(
int from, // Past Bar Index
int to, // Present Bar Index
ENUM_APPLIED_PRICE appliedPrice // Which Price Choose in From or To
)
{
//
bool result = false;
//
double toValue = GetAppliedPrice(
to,
appliedPrice);
double fromValue = GetAppliedPrice(
from,
appliedPrice);
//
int hIdx = iHighest(
_Symbol,
_Period,
MODE_HIGH,
from,
to);
double maxValue = iHigh(
_Symbol,
_Period,
hIdx);
//
int lIdx = iLowest(
_Symbol,
_Period,
MODE_LOW,
from,
to);
double minValue = iLow(
_Symbol,
_Period,
lIdx);
//
result = IsSharpIncreasedChanged(
fromValue,
toValue,
maxValue,
minValue);
//
return result;
}
//
// Check Decreased Sharp Happens or not ...
bool IsSharpDecreasedChanged(
double fromValue, // Past Value
double toValue, // Present Value
double maxValue, // Max in Range Value
double minValue // Min in Range Value
)
{
//
bool result = false;
//
// This Used In Increased or Decreased Sharp Detection ...
bool isIncreased = toValue > fromValue;
//
double toFromDelta = MathAbs(toValue - fromValue);
double minMaxDelta = maxValue - minValue;
//
result =
!isIncreased &&
toFromDelta >= (minMaxDelta / 3);
//
return result;
}
bool IsSharpDecreasedChanged(
int from, // Past Index in Series
int to, // Present Index in Series
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];
//
double minValue = GetMinValue(
ArraySize(buffer) - 1,
buffer);
double maxValue = GetMaxValue(
ArraySize(buffer) - 1,
buffer);
double minMaxDelta = maxValue - minValue;
//
// Sharp Detection ...
result = IsSharpDecreasedChanged(
fromValue,
toValue,
maxValue,
minValue);
//
return result;
}
bool IsSharpDecreasedChanged(
int from, // Past Bar Index
int to, // Present Bar Index
ENUM_APPLIED_PRICE appliedPrice // Which Price Choose in From or To
)
{
//
bool result = false;
//
double toValue = GetAppliedPrice(
to,
appliedPrice);
double fromValue = GetAppliedPrice(
from,
appliedPrice);
//
int hIdx = iHighest(
_Symbol,
_Period,
MODE_HIGH,
from,
to);
double maxValue = iHigh(
_Symbol,
_Period,
hIdx);
//
int lIdx = iLowest(
_Symbol,
_Period,
MODE_LOW,
from,
to);
double minValue = iLow(
_Symbol,
_Period,
lIdx);
//
result = IsSharpDecreasedChanged(
fromValue,
toValue,
maxValue,
minValue);
//
return result;
}
//
void Clean(int &buffer[])
{
//
ArrayFree(buffer);
ArrayResize(buffer, 0);
}
void Clean(ulong &buffer[])
{
//
ArrayFree(buffer);
ArrayResize(buffer, 0);
}
void Clean(string &buffer[])
{
//
ArrayFree(buffer);
ArrayResize(buffer, 0);
}
void Clean(double &buffer[])
{
//
ArrayFree(buffer);
ArrayResize(buffer, 0);
}
//
bool GetLastItem(
double &item, // Holds Result
double &buffer[] // Specified Buffer
)
{
//
bool result = false;
//
int bufferSize = ArraySize(buffer);
if (bufferSize <= 0)
{
return result;
}
//
item = buffer[bufferSize - 1];
//
result = true;
return result;
}
bool GetLastItem(
datetime &item, // Holds Result
datetime &buffer[] // Specified Buffer
)
{
//
bool result = false;
//
int bufferSize = ArraySize(buffer);
if (bufferSize <= 0)
{
return result;
}
//
item = buffer[bufferSize - 1];
//
result = true;
return result;
}
//
void Add(
int item, // item want to add
int &buffer[] // Destination buffer
)
{
//
ArrayResize(
buffer,
ArraySize(buffer) + 1);
//
buffer[ArraySize(buffer) - 1] = item;
}
void Add(
ulong item, // item want to add
ulong &buffer[] // Destination buffer
)
{
//
ArrayResize(
buffer,
ArraySize(buffer) + 1);
//
buffer[ArraySize(buffer) - 1] = item;
}
void Add(
string item, // item want to add
string &buffer[] // Destination buffer
)
{
//
ArrayResize(
buffer,
ArraySize(buffer) + 1);
//
buffer[ArraySize(buffer) - 1] = item;
}
void Add(
double item, // item want to add
double &buffer[] // Destination buffer
)
{
//
ArrayResize(
buffer,
ArraySize(buffer) + 1);
//
buffer[ArraySize(buffer) - 1] = item;
}
void Add(
XOHCL &item, // item want to add
XOHCL &buffer[] // Destination buffer
)
{
//
ArrayResize(
buffer,
ArraySize(buffer) + 1);
//
buffer[ArraySize(buffer) - 1] = item;
}
void Add(
datetime &item, // item want to add
datetime &buffer[] // Destination buffer
)
{
//
ArrayResize(
buffer,
ArraySize(buffer) + 1);
//
buffer[ArraySize(buffer) - 1] = item;
}
//
// 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);
}
}
//
// Converts a Buffer to String Representation ...
string ToString(
const int &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;
}
string ToString(
const double &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;
}
string ToString(
const string &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;
}
string ToString(
const datetime &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;
}
template <typename T>
string ToString(T value)
{
return (string)value;
}
//
// Converts String to boolean ...
bool ToBoolean(string value)
{
//
bool result = false;
//
if (StringLen(value) <= 0)
{
return result;
}
//
StringToLower(value);
result = value == "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;
}
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;
}
//
// Split an String Representation of an Array ...
void SplitContent(
string &result[], // Hold Result ...
string content, // Source ...
string separator = ",", // Separator ...
bool forceCleanResult = true // Clean Result ...
)
{
//
if (forceCleanResult)
{
Clean(result);
}
//
if (separator == NULL || StringLen(separator) == 0)
{
separator = ",";
}
//
if (StringLen(content) == 0)
{
return;
}
//
StringSplit(
content,
StringGetCharacter(
separator,
0),
result);
}
//
// 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;
}
//
// Normalize a give Volume ...
double NormalizeVolume(
double volume, // desired volume to normalize
string symbol = NULL, // Specified Symbol for Normalization
int mLength = 2 // Length of Digits
)
{
//
double result = volume;
//
// Normalize Symbol ...
if (StringLen(symbol) == 0)
{
symbol = _Symbol;
}
//
// Normalize Digits ...
int digits = GetDigits(symbol);
mLength =
mLength == 0 || mLength > digits
? digits
: MathMin(mLength, digits);
//
// Normalize Volume ...
result = NormalizeDouble(result, mLength);
//
double maxAvailableVolume = SymbolInfoDouble(symbol, SYMBOL_VOLUME_MAX);
double minAvailableVolume = SymbolInfoDouble(symbol, SYMBOL_VOLUME_MIN);
//
// Validate Result ...
if (result > maxAvailableVolume)
{
result = maxAvailableVolume;
}
else if (result < minAvailableVolume)
{
result = minAvailableVolume;
}
//
return result;
}
//
// Normallize Price ...
double NormalizePrice(
double price, // desired Price for normalization
string symbol = NULL // Specified Symbol for Normalization
)
{
//
double result = 0;
//
// Mormalize Symbol ...
if (StringLen(symbol) == 0)
{
symbol = _Symbol;
}
//
int digits = GetDigits(symbol);
result = NormalizeDouble(price, digits);
//
return result;
}
//
// Do All Normalization on Specific Signal ...
void NormalizeSignal(XSignal &signal)
{
//
// ENTRY ...
if (signal.entry > 0)
{
signal.entry = NormalizePrice(signal.entry, signal.symbol);
}
//
// TP ...
if (signal.tp > 0)
{
signal.tp = NormalizePrice(signal.tp, signal.symbol);
}
//
// SL ...
if (signal.sl > 0)
{
signal.sl = NormalizePrice(signal.sl, signal.symbol);
}
//
// VOLUME ...
if (signal.volume > 0)
{
signal.volume = NormalizeVolume(signal.volume, signal.symbol);
}
}
//
// Check Expert Running in Testing Mode or not ...
bool IsRunningOnTestMode()
{
//
bool result = false;
//
// check programm mode ...
result = MQL5InfoInteger(MQL5_TESTING);
//
return result;
}
//
// Calculate Volume Weighted Moving Average ...
double iVWMA(
double price,
double volume,
int period,
int i,
int bars,
int instance = 0 //
)
{
#define ¤ instance
#ifdef _averageInstances
#define _functionInstances _averageInstances
#else #define _functionInstances 1
#endif
struct sVwmaArrayStruct
{
double price;
double volume;
double sump;
double sumv;
};
static sVwmaArrayStruct m_array[][_functionInstances];
static int m_arraySize = 0;
if (m_arraySize < bars)
{
int _res = ArrayResize(m_array, bars + 500);
if (_res <= bars)
return (0);
m_arraySize = _res;
}
//
//---
//
if (volume == 0)
volume = 1;
m_array[i][¤].price = volume * price;
m_array[i][¤].volume = volume;
if (i > period)
{
m_array[i][¤].sump = m_array[i - 1][¤].sump + m_array[i][¤].price - m_array[i - period][¤].price;
m_array[i][¤].sumv = m_array[i - 1][¤].sumv + volume - m_array[i - period][¤].volume;
}
else
{
m_array[i][¤].sump = m_array[i][¤].price;
m_array[i][¤].sumv = m_array[i][¤].volume;
for (int k = 1; k < period && i >= k; k++)
{
m_array[i][¤].sump += m_array[i - k][¤].price;
m_array[i][¤].sumv += m_array[i - k][¤].volume;
}
}
return (m_array[i][¤].sump / m_array[i][¤].sumv);
//
//---
//
#undef ¤ #undef _functionInstances
}
//
// Date Time Manipulation Functions ...
//
//
// 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;
}
//
// Retrieve Specified Candle Time ...
datetime GetCandleTime(
string symbol = "", // Specify Symbol
ENUM_TIMEFRAMES period = NULL, // Specify TimeFrame
int bar_index = 0 // Specify Bar Index
)
{
//
// Validate and Normalize Args ...
//
// Normalize Symbol ...
symbol = StringLen(symbol) == 0
? _Symbol
: symbol;
//
// Normalize Period ...
period = period == NULL
? _Period
: period;
//
// Retrieve Bar Time ...
datetime result = iTime(
symbol,
period,
bar_index);
//
return result;
}
//
// Retrieve Specified Candle Time ...
ulong GetCandleTimeAsSeconds(
string symbol = "", // Specify Symbol
ENUM_TIMEFRAMES period = NULL, // Specify TimeFrame
int bar_index = 0 // Specify Bar Index
)
{
//
// Retrieve Bar Time ...
datetime time = GetCandleTime(
symbol,
period,
bar_index);
//
ulong result = TimeToSeconds(time);
//
return result;
}
//
// Retrieve Specified Candle Time ...
ulong GetCandleTimeAsMilliSeconds(
string symbol = "", // Specify Symbol
ENUM_TIMEFRAMES period = NULL, // Specify TimeFrame
int bar_index = 0 // Specify Bar Index
)
{
//
// Retrieve Bar Time ...
datetime time = GetCandleTime(
symbol,
period,
bar_index);
//
ulong result = TimeToMilliSeconds(time);
//
return result;
}
//
// Retrieve a Candle Time Structure ...
MqlDateTime GetCandleTimeStruct(
string symbol = "", // Specify Symbol
ENUM_TIMEFRAMES period = NULL, // Specify TimeFrame
int bar_index = 0 // Specify Bar Index
)
{
//
MqlDateTime result = {};
//
// Retrieve Bar Time ...
datetime barTime = GetCandleTime(
symbol,
period,
bar_index);
//
// Convert to Structure ...
TimeToStruct(barTime, result);
//
return result;
}
//
// Retrieve Number of Candles in a Day ...
int GetDailyCandleCount(ENUM_TIMEFRAMES mPeriod)
{
//
int seconds = PeriodSeconds(mPeriod);
//
int daySeconds = 24 * 60 * 60;
//
int result = daySeconds / seconds;
//
return result;
}
int GetDailyCandleCount()
{
//
int result = GetDailyCandleCount(_Period);
//
return result;
}
//
//
//
//
// Holds Month ...
static int xMonth = -1;
//
// Holds Day Of Week ...
static int xDayOfWeek = -1;
static int xForWeekDay = -1;
//
// Holds Day ...
static int xDay = -1;
//
// Holds Hour ...
static int xHour = -1;
//
// Reset Timing Variables ...
void ResetTiming()
{
//
xHour = -1;
xDay = -1;
xDayOfWeek = -1;
xMonth = -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;
}
//
// Find Hindmost Time Frame ...
ENUM_TIMEFRAMES GetHindmostTimeFrame(
ENUM_TIMEFRAMES mPeriod // Specified Period
)
{
//
ENUM_TIMEFRAMES result = NULL;
//
// Normalize Period ...
if (
mPeriod < 0 ||
mPeriod == NULL)
{
mPeriod = _Period;
}
//
switch (mPeriod)
{
//
case PERIOD_M1:
case PERIOD_M2:
case PERIOD_M3:
case PERIOD_M4:
result = PERIOD_H4;
break;
//
case PERIOD_M5:
case PERIOD_M6:
case PERIOD_M10:
case PERIOD_M12:
result = PERIOD_H8;
break;
//
case PERIOD_M15:
case PERIOD_M20:
result = PERIOD_H12;
break;
//
case PERIOD_M30:
result = PERIOD_D1;
break;
//
case PERIOD_H1:
case PERIOD_H2:
case PERIOD_H3:
result = PERIOD_W1;
break;
//
case PERIOD_H4:
case PERIOD_H6:
case PERIOD_H8:
result = PERIOD_MN1;
break;
//
case PERIOD_H12:
result = PERIOD_MN1;
break;
//
case PERIOD_D1:
result = PERIOD_MN1;
break;
//
case PERIOD_W1:
result = PERIOD_MN1;
break;
//
default:
result = PERIOD_MN1;
break;
}
//
return result;
}
//
// Find Farest Time Frame ...
ENUM_TIMEFRAMES GetFarestTimeFrame(
ENUM_TIMEFRAMES mPeriod // Specified Period
)
{
//
ENUM_TIMEFRAMES result = NULL;
//
// Normalize Period ...
if (
mPeriod < 0 ||
mPeriod == NULL)
{
mPeriod = _Period;
}
//
switch (mPeriod)
{
//
case PERIOD_M1:
case PERIOD_M2:
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_H3;
break;
//
case PERIOD_M30:
result = PERIOD_H4;
break;
//
case PERIOD_H1:
case PERIOD_H2:
case PERIOD_H3:
result = PERIOD_H8;
break;
//
case PERIOD_H4:
case PERIOD_H6:
case PERIOD_H8:
result = PERIOD_D1;
break;
//
case PERIOD_H12:
result = PERIOD_MN1;
break;
//
case PERIOD_D1:
result = PERIOD_MN1;
break;
//
case PERIOD_W1:
result = PERIOD_MN1;
break;
//
default:
result = PERIOD_MN1;
break;
}
//
return result;
}
//
// Find Medium Time Frame ...
ENUM_TIMEFRAMES GetMediestTimeFrame(
ENUM_TIMEFRAMES mPeriod // Specified Period
)
{
//
ENUM_TIMEFRAMES result = NULL;
//
// Normalize Period ...
if (
mPeriod < 0 ||
mPeriod == NULL)
{
mPeriod = _Period;
}
//
switch (mPeriod)
{
//
case PERIOD_M1:
case PERIOD_M2:
case PERIOD_M3:
case PERIOD_M4:
result = PERIOD_M12;
break;
//
case PERIOD_M5:
case PERIOD_M6:
case PERIOD_M10:
case PERIOD_M12:
result = PERIOD_M30;
break;
//
case PERIOD_M15:
case PERIOD_M20:
result = PERIOD_H1;
break;
//
case PERIOD_M30:
result = PERIOD_H2;
break;
//
case PERIOD_H1:
case PERIOD_H2:
case PERIOD_H3:
result = PERIOD_H6;
break;
//
case PERIOD_H4:
case PERIOD_H6:
case PERIOD_H8:
result = PERIOD_H12;
break;
//
case PERIOD_H12:
result = PERIOD_W1;
break;
//
case PERIOD_D1:
result = PERIOD_MN1;
break;
//
case PERIOD_W1:
result = PERIOD_MN1;
break;
//
default:
result = PERIOD_MN1;
break;
}
//
return result;
}
//
// Find Nearest Time Frame ...
ENUM_TIMEFRAMES GetNearestTimeFrame(
ENUM_TIMEFRAMES mPeriod // Specified Period
)
{
//
ENUM_TIMEFRAMES result = NULL;
//
// Normalize Period ...
if (
mPeriod < 0 ||
mPeriod == NULL)
{
mPeriod = _Period;
}
//
switch (mPeriod)
{
//
case PERIOD_M1:
case PERIOD_M2:
case PERIOD_M3:
case PERIOD_M4:
result = PERIOD_M5;
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_M30:
result = PERIOD_H1;
break;
//
case PERIOD_H1:
case PERIOD_H2:
case PERIOD_H3:
result = PERIOD_H4;
break;
//
case PERIOD_H4:
case PERIOD_H6:
case PERIOD_H8:
result = PERIOD_H12;
break;
//
case PERIOD_H12:
result = PERIOD_D1;
break;
//
case PERIOD_D1:
result = PERIOD_W1;
break;
//
case PERIOD_W1:
result = PERIOD_MN1;
break;
//
default:
result = PERIOD_MN1;
break;
}
//
return result;
}
//
// 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 ...
)
{
//
// Normalize Arg ...
//
if (
mSymbol == NULL ||
StringLen(mSymbol) == 0)
{
mSymbol = _Symbol;
}
//
if (
mPeriod < 0 ||
mPeriod == NULL)
{
mPeriod = _Period;
}
//
if (
mTime < 0 ||
mTime == NULL)
{
mTime = TimeCurrent();
}
//
int barIndex = iBarShift(
mSymbol,
mPeriod,
mTime,
false);
//
datetime result = iTime(
mSymbol,
mPeriod,
barIndex);
//
return result;
}
//
struct XCandleRemains
{
//
int days;
int hours;
int minutes;
int seconds;
};
//
string ToString(
XCandleRemains &item,
string dayId = "d",
string hourId = "h",
string minuteId = "m",
string secondId = "s",
string idSeparator = ": ",
string separator = ", ",
bool ignoreZeroValues = true)
{
//
string result = "";
//
// Days ...
if (!ignoreZeroValues || item.days > 0)
{
result += dayId + idSeparator + (string)item.days + separator;
}
//
// Hours ...
if (!ignoreZeroValues || item.hours > 0)
{
//
string strHour = ToString(item.hours);
if (StringLen(strHour) == 1)
{
strHour = "0" + strHour;
}
//
result += hourId + idSeparator + strHour + separator;
}
//
// Minutes ...
if (!ignoreZeroValues || item.minutes > 0)
{
//
string strMinute = ToString(item.minutes);
if (StringLen(strMinute) == 1)
{
strMinute = "0" + strMinute;
}
//
result += minuteId + idSeparator + strMinute + separator;
}
//
// Seconds ...
if (!ignoreZeroValues || item.seconds > 0)
{
//
string strSec = ToString(item.seconds);
if (StringLen(strSec) == 1)
{
strSec = "0" + strSec;
}
//
result += secondId + idSeparator + strSec;
}
//
return result;
}
//
// Retrieve Specific Candles Ramained Time ...
void GetCandleRemainsTime(
XCandleRemains &result, // Holds Result ...
string mSymbol = NULL, // Specified Symbol ...
ENUM_TIMEFRAMES mPeriod = NULL, // Specified Period ...
int mBarIndex = 0 // Specified Bar Index ...
)
{
//
int minuteSecoonds = 60;
int hourSeconds = minuteSecoonds * 60;
int daySeconds = 24 * hourSeconds;
//
int periodSeconds = PeriodSeconds(
mPeriod);
datetime startTime = GetCandleTime(
mSymbol,
mPeriod,
mBarIndex);
//
int secondsDiff = (int)startTime + periodSeconds - (int)TimeCurrent();
//
int days = 0;
int hours = 0;
int minutes = 0;
int seconds = 0;
//
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.days = days;
result.hours = hours;
result.minutes = minutes;
result.seconds = seconds;
}
//
// 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 period)
{
//
string result = "";
//
string mPStr = EnumToString(period);
string mPStrParts[];
int partsCount = StringSplit(
mPStr,
StringGetCharacter("_", 0),
mPStrParts);
if (partsCount <= 0)
{
return result;
}
//
result = mPStrParts[1];
//
return result;
}
//
// TYPES ...
//
//
// Retrieve Specific Object Types Name ...
template <typename T>
string GetTypeName(const T &t)
{
return typename(T);
}
//
// END Provided Functions ...
//