/////////////////////////////////////////////////////// // // 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; } // // 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; } // // 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; } // // 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 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; } // // 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 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; // 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; } // // 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; } // // 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 string ToString(T value) { return (string)value; } // // Search Array For Specific Item ... template 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 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; } // // 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: case PERIOD_M5: case PERIOD_M6: case PERIOD_M10: case PERIOD_M12: case PERIOD_M15: result = PERIOD_H12; break; // case PERIOD_M20: case PERIOD_M30: case PERIOD_H1: case PERIOD_H2: case PERIOD_H3: case PERIOD_H4: result = PERIOD_D1; break; // case PERIOD_H6: case PERIOD_H8: case PERIOD_H12: case PERIOD_D1: result = PERIOD_W1; 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: 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; // case PERIOD_H1: case PERIOD_H2: case PERIOD_H3: case PERIOD_H4: result = PERIOD_H12; break; // case PERIOD_H6: case PERIOD_H8: case PERIOD_H12: case PERIOD_D1: result = PERIOD_W1; 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: case PERIOD_M5: case PERIOD_M6: case PERIOD_M10: case PERIOD_M12: 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_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; } // // 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; } // // END Provided Functions ... //