1272 lines
23 KiB
Plaintext
1272 lines
23 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;
|
|
}
|
|
|
|
//
|
|
// 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;
|
|
}
|
|
|
|
//
|
|
// 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 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;
|
|
}
|
|
|
|
//
|
|
// Get a Candle Body ...
|
|
double GetCandleBody(
|
|
XOHCL &candle // specified candle
|
|
)
|
|
{
|
|
//
|
|
double result = MathAbs(candle.open - candle.close);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Get a Candle Range ...
|
|
double GetCandleRange(
|
|
XOHCL &candle // specified candle
|
|
)
|
|
{
|
|
//
|
|
double result = MathAbs(candle.high - candle.low);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Get a Candle Shadow ...
|
|
double GetCandleShadow(
|
|
XOHCL &candle // specified candle
|
|
)
|
|
{
|
|
//
|
|
double range = GetCandleRange(candle);
|
|
double body = GetCandleBody(candle);
|
|
|
|
//
|
|
double result = MathAbs(range - body);
|
|
|
|
//
|
|
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;
|
|
}
|
|
|
|
//
|
|
// 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 period, // specify timeframe
|
|
int bar_index // specify candle 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(
|
|
string symbol, // specify symbol
|
|
ENUM_TIMEFRAMES period, // specify timeframe
|
|
int bar_index // specify candle 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;
|
|
}
|
|
|
|
//
|
|
// 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;
|
|
}
|
|
|
|
//
|
|
// Check a Candle is Bullish or not ...
|
|
bool IsBullishCandle(
|
|
XOHCL &candle // specified candle
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
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 period, // specify timeframe
|
|
int bar_index // candle index
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
XOHCL candle = GetCandle(
|
|
symbol,
|
|
period,
|
|
bar_index);
|
|
|
|
//
|
|
result = IsBullishCandle(candle);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Check a Candle is Bullish or not ...
|
|
bool IsBearishCandle(
|
|
XOHCL &candle // specified candle
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
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 period, // specify timeframe
|
|
int bar_index // candle index
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
XOHCL candle = GetCandle(
|
|
symbol,
|
|
period,
|
|
bar_index);
|
|
|
|
//
|
|
result = IsBearishCandle(candle);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Check Candle Body Bigger Than it's Shadow ...
|
|
bool HasStrongBody(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;
|
|
}
|
|
|
|
//
|
|
// 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 = HasStrongBody(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 period, // 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(period, bar_index + 1);
|
|
candles[1] = GetCandle(period, bar_index + 2);
|
|
candles[2] = GetCandle(period, bar_index + 3);
|
|
|
|
//
|
|
// Check Swing Start Candle has Strong Body ...
|
|
bool isStrongBodyCandle = HasStrongBody(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 period, // 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, period, bar_index + 1);
|
|
candles[1] = GetCandle(symbol, period, bar_index + 2);
|
|
candles[2] = GetCandle(symbol, period, bar_index + 3);
|
|
|
|
//
|
|
// Check Swing Start Candle has Strong Body ...
|
|
bool isStrongBodyCandle = HasStrongBody(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;
|
|
}
|
|
|
|
//
|
|
// 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(
|
|
string symbol, // Specified Symbol
|
|
ENUM_TIMEFRAMES period, // Specified Period
|
|
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;
|
|
}
|
|
|
|
//
|
|
// 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(
|
|
string symbol, // Specified Symbol
|
|
ENUM_TIMEFRAMES period, // Specified Period
|
|
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;
|
|
}
|
|
|
|
//
|
|
// 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;
|
|
}
|
|
//
|
|
// END Provided Functions ...
|
|
//
|
|
|
|
//
|
|
// Find Farest Time Frame ...
|
|
ENUM_TIMEFRAMES GetFarestTimeFrame()
|
|
{
|
|
//
|
|
ENUM_TIMEFRAMES result = PERIOD_MN1;
|
|
|
|
//
|
|
switch (_Period)
|
|
{
|
|
//
|
|
// M1-M30 ...
|
|
case PERIOD_M1:
|
|
case PERIOD_M2:
|
|
case PERIOD_M3:
|
|
case PERIOD_M4:
|
|
case PERIOD_M5:
|
|
case PERIOD_M6:
|
|
case PERIOD_M10:
|
|
case PERIOD_M12:
|
|
case PERIOD_M15:
|
|
case PERIOD_M20:
|
|
case PERIOD_M30:
|
|
result = PERIOD_D1;
|
|
break;
|
|
|
|
//
|
|
// H1-H12 ...
|
|
case PERIOD_H1:
|
|
case PERIOD_H2:
|
|
case PERIOD_H3:
|
|
case PERIOD_H4:
|
|
case PERIOD_H6:
|
|
case PERIOD_H8:
|
|
case PERIOD_H12:
|
|
result = PERIOD_W1;
|
|
break;
|
|
|
|
//
|
|
// D!, W1 ...
|
|
case PERIOD_D1:
|
|
case PERIOD_W1:
|
|
result = PERIOD_MN1;
|
|
break;
|
|
|
|
//
|
|
// Otherwise ...
|
|
default:
|
|
result = PERIOD_MN1;
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Find Medium Time Frame ...
|
|
ENUM_TIMEFRAMES GetMediumTimeFrame()
|
|
{
|
|
//
|
|
ENUM_TIMEFRAMES result = PERIOD_D1;
|
|
|
|
//
|
|
switch (_Period)
|
|
{
|
|
//
|
|
// M1-M30 ...
|
|
case PERIOD_M1:
|
|
case PERIOD_M2:
|
|
case PERIOD_M3:
|
|
case PERIOD_M4:
|
|
case PERIOD_M5:
|
|
case PERIOD_M6:
|
|
case PERIOD_M10:
|
|
case PERIOD_M12:
|
|
case PERIOD_M15:
|
|
case PERIOD_M20:
|
|
case PERIOD_M30:
|
|
result = PERIOD_H4;
|
|
break;
|
|
|
|
//
|
|
// H1-H12 ...
|
|
case PERIOD_H1:
|
|
case PERIOD_H2:
|
|
case PERIOD_H3:
|
|
case PERIOD_H4:
|
|
case PERIOD_H6:
|
|
case PERIOD_H8:
|
|
case PERIOD_H12:
|
|
result = PERIOD_D1;
|
|
break;
|
|
|
|
//
|
|
// D!, W1 ...
|
|
case PERIOD_D1:
|
|
result = PERIOD_W1;
|
|
break;
|
|
|
|
//
|
|
// Otherwise ...
|
|
default:
|
|
result = PERIOD_MN1;
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Find Smallest Time Frame ...
|
|
ENUM_TIMEFRAMES GetSmallestTimeFrame()
|
|
{
|
|
//
|
|
ENUM_TIMEFRAMES result = PERIOD_M5;
|
|
|
|
//
|
|
switch (_Period)
|
|
{
|
|
//
|
|
// M1-M5 ...
|
|
case PERIOD_M1:
|
|
case PERIOD_M2:
|
|
case PERIOD_M3:
|
|
case PERIOD_M4:
|
|
case PERIOD_M5:
|
|
result = _Period;
|
|
break;
|
|
|
|
//
|
|
// M6-M30 ...
|
|
case PERIOD_M6:
|
|
case PERIOD_M10:
|
|
case PERIOD_M12:
|
|
case PERIOD_M15:
|
|
case PERIOD_M20:
|
|
case PERIOD_M30:
|
|
result = PERIOD_M5;
|
|
break;
|
|
|
|
//
|
|
// H1-H12 ...
|
|
case PERIOD_H1:
|
|
case PERIOD_H2:
|
|
case PERIOD_H3:
|
|
case PERIOD_H4:
|
|
case PERIOD_H6:
|
|
case PERIOD_H8:
|
|
case PERIOD_H12:
|
|
result = PERIOD_H1;
|
|
break;
|
|
|
|
//
|
|
// D! ...
|
|
case PERIOD_D1:
|
|
result = PERIOD_H2;
|
|
break;
|
|
|
|
//
|
|
// Otherwise ...
|
|
default:
|
|
result = PERIOD_H4;
|
|
}
|
|
|
|
//
|
|
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;
|
|
}
|
|
|
|
//
|
|
// Validate Struct ...
|
|
bool IsValid(XSignal &model, ulong magicNumber)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Validate Signal Type ...
|
|
result = model.type != X_SIGNAL_UNKNOWN;
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Check Symbol ...
|
|
result = StringLen(model.symbol) == 0 ? true : model.symbol == _Symbol;
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Check magic number ...
|
|
result = model.magicNumber <= 0 ? true : model.magicNumber == magicNumber;
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Check Entry ...
|
|
result = model.entry > 0;
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Check SL ...
|
|
result = model.sl == 0 ? true : model.type == X_SIGNAL_LONG ? model.sl < model.entry
|
|
: model.sl > model.entry;
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Check TP ...
|
|
result = model.tp == 0 ? true : model.type == X_SIGNAL_LONG ? model.tp > model.entry
|
|
: model.tp < model.entry;
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Check Volume ...
|
|
result = model.volume > 0;
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Check Time ...
|
|
result = model.time > 0;
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
bool IsValid(XTPSL &model)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
result = model.entry > 0 && model.r2r > 0 && model.type != X_SIGNAL_UNKNOWN;
|
|
|
|
//
|
|
return result;
|
|
} |