/////////////////////////////////////////////////////// // // 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; }