/////////////////////////////////////////////////////// // // SaherElm IT Center MQL5 Common Library // -------------------------------------- // Name: XCommonLib // Description: provide all commonly used functions ... // // // Maintainer: // ------------ // Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) // ////////////////////////////////////////////////////// // // Global Properties ... #property library #property copyright "Copyright 2023, SaherElm IT Center" #property link "https://www.saherelm.ir" #property version "1.00" #property strict // // Imports ... #include "../Classes/x-saherelm.xmd5.class.mq5" // // Models ... // // Specified Price Type ... enum ENUM_X_PRICE { X_PRICE_HIGH, X_PRICE_OPEN, X_PRICE_CLOSE, X_PRICE_LOW }; // // Swing Types Enum ... enum ENUM_X_SWING_TYPE { X_NO_SWING = 0, X_SWING_HIGH = 1, X_SWING_LOW = -1, }; // // XPERIOD Calculation Method ... enum ENUM_X_PERIOD_METHOD { // X_PERIOD_NOTHING, // Nothing X_PERIOD_AUTO, // Auto Select X_PERIOD_MANUALLY // Manually }; // // Available Market Cycles ... enum ENUM_X_MARKET_CYCLES { // X_MARKET_CYCLE_UNKNOWN, // Unknown Cycle X_MARKET_CYCLE_SHORT, // Short Cycle X_MARKET_CYCLE_MEDIUM, // Medium Cycle X_MARKET_CYCLE_LONG, // Long Cycle X_MARKET_CYCLE_HIND, // Hind Cycle }; // // Structs ... // // Model a Bar Remains Time ... struct XBarRemainsTime { // int days; int hours; int minutes; int seconds; // // Constructor ... XBarRemainsTime() { Clean(); } // // Always Calculate Current 0 Bar Timing ... bool Init( string mSymbol = NULL, // Trading Symbol ENUM_TIMEFRAMES mPeriod = NULL // Trading Period ) { // bool result = false; // mSymbol = NormalizeSymbol(mSymbol); mPeriod = NormalizePeriod(mPeriod); // int minuteSecoonds = 60; int hourSeconds = minuteSecoonds * 60; int daySeconds = 24 * hourSeconds; // int periodSeconds = PeriodSeconds( mPeriod); datetime startTime = GetBarTime( mSymbol, mPeriod, 0 // ); // int secondsDiff = (int)startTime + periodSeconds - (int)TimeCurrent(); // int mWorkingSecondsDiff = secondsDiff; if (mWorkingSecondsDiff > daySeconds) { // days = mWorkingSecondsDiff / daySeconds; mWorkingSecondsDiff -= days * daySeconds; } if (mWorkingSecondsDiff > hourSeconds) { // hours = mWorkingSecondsDiff / hourSeconds; mWorkingSecondsDiff -= hours * hourSeconds; } if (mWorkingSecondsDiff > minuteSecoonds) { // minutes = mWorkingSecondsDiff / minuteSecoonds; mWorkingSecondsDiff -= minutes * minuteSecoonds; } seconds = mWorkingSecondsDiff; // result = true; // return result; } // // Tools ... // // Cleanup ... void Clean() { days = 0; hours = 0; minutes = 0; seconds = 0; } // // To String Representation ... string ToString( string dayId = "d", string hourId = "h", string minuteId = "m", string secondId = "s", string idSeparator = ": ", string separator = ", ", bool ignoreZeroValues = true // ) { // string result = ""; // // Days ... if (!ignoreZeroValues || days > 0) { result += dayId + idSeparator + (string)days + separator; } // // Hours ... if (!ignoreZeroValues || hours > 0) { // string strHour = ToString(hours); if (StringLen(strHour) == 1) { strHour = "0" + strHour; } // result += hourId + idSeparator + strHour + separator; } // // Minutes ... if (!ignoreZeroValues || minutes > 0) { // string strMinute = ToString(minutes); if (StringLen(strMinute) == 1) { strMinute = "0" + strMinute; } // result += minuteId + idSeparator + strMinute + separator; } // // Seconds ... if (!ignoreZeroValues || seconds > 0) { // string strSec = ToString(seconds); if (StringLen(strSec) == 1) { strSec = "0" + strSec; } // result += secondId + idSeparator + strSec; } // return result; } }; // // Describe an Specific Candle ... struct XOHCL { // // Props ... // double high; double open; double close; double low; // string symbol; datetime time; ENUM_TIMEFRAMES period; // // Constructor ... XOHCL() { Clean(); } // // Init a Bar ... // Using Bar Index ... bool Init( string mSymbol = NULL, // Trading Symbol ENUM_TIMEFRAMES mPeriod = NULL, // Trading Period int barIndex = 0 // Bar Index ) { // mSymbol = NormalizeSymbol(mSymbol); mPeriod = NormalizePeriod(mPeriod); // symbol = mSymbol; period = mPeriod; // time = iTime( mSymbol, mPeriod, barIndex // ); // open = iOpen( mSymbol, mPeriod, barIndex // ); // close = iClose( mSymbol, mPeriod, barIndex // ); // high = iHigh( mSymbol, mPeriod, barIndex); // low = iLow( mSymbol, mPeriod, barIndex // ); // bool result = IsValid(); // return result; } // // Init a Bar ... // Using Bar Time ... bool Init( string mSymbol = NULL, // Trading Symbol ENUM_TIMEFRAMES mPeriod = NULL, // Trading Period datetime mTime = NULL // Bar Time ) { // mTime = NormalizeTime(mTime); // int barIndex = iBarShift( mSymbol, mPeriod, mTime, false // ); // bool result = Init( mSymbol, mPeriod, barIndex // ); // return result; } // bool Init( string mSymbol = NULL, // Trading Symbol ENUM_TIMEFRAMES mPeriod = NULL, // Trading Period double mOpen = 0, // Open double mHigh = 0, // High double mClose = 0, // Close double mLow = 0, // Low int barIndex = 0 // Bar Index ) { // mSymbol = NormalizeSymbol(mSymbol); mPeriod = NormalizePeriod(mPeriod); // symbol = mSymbol; period = mPeriod; // time = iTime( mSymbol, mPeriod, barIndex // ); // open = mOpen; high = mHigh; close = mClose; low = mLow; // return IsValid(); } // bool Init( string mSymbol = NULL, // Trading Symbol ENUM_TIMEFRAMES mPeriod = NULL, // Trading Period double mOpen = 0, // Open double mHigh = 0, // High double mClose = 0, // Close double mLow = 0, // Low datetime mTime = NULL // Bar Time ) { // mSymbol = NormalizeSymbol(mSymbol); mPeriod = NormalizePeriod(mPeriod); // symbol = mSymbol; period = mPeriod; // int barIndex = iBarShift( symbol, period, mTime); // time = iTime( mSymbol, mPeriod, barIndex // ); // open = mOpen; high = mHigh; close = mClose; low = mLow; // return IsValid(); } // // Tools ... // void Clean() { // high = 0; open = 0; close = 0; low = 0; // time = NULL; symbol = NULL; period = NULL; } // // Validate Bar ... bool IsValid() { // bool result = false; // result = // high > 0 && open > 0 && close > 0 && low > 0 // ; // return result; } // // Calculate X_PRICE Specified Type ... double GetPrice(ENUM_X_PRICE mPType) { // double result = 0; // if (!IsValid()) { return result; } // switch (mPType) { // case X_PRICE_OPEN: result = open; break; // case X_PRICE_HIGH: result = high; break; // case X_PRICE_CLOSE: result = close; break; // case X_PRICE_LOW: result = low; break; } // return result; } // // Retrieve Price base On Series Mode ... double GetPrice(ENUM_SERIESMODE mMode) { // ENUM_X_PRICE mXMode = ToPrice(mMode); // return GetPrice(mXMode); } // // Calculate Applied Price ... double GetPrice( ENUM_APPLIED_PRICE mAppliedTo // Select Application Method ) { // double result = 0; // // Calculate Applied Price ... switch (mAppliedTo) { // case PRICE_CLOSE: result = close; break; // case PRICE_OPEN: result = open; break; // case PRICE_HIGH: result = high; break; // case PRICE_LOW: result = low; break; // case PRICE_MEDIAN: result = (high + low) / 2; break; // case PRICE_TYPICAL: result = (high + low + close) / 3; break; // case PRICE_WEIGHTED: result = (high + low + close + close) / 4; break; } // return result; } // // Calculate Bar Mid Line ... double GetMid() { // double result = 0; // if (!IsValid()) { return result; } // result = (high + low) / 2; // return result; } // // Calculate up Price ... double GetUp() { // double result = 0; // if (!IsValid()) { return result; } // result = MathMax(open, close); // return result; } // // Calculate Down Price ... double GetDown() { // double result = 0; // if (!IsValid()) { return result; } // result = MathMin(open, close); // return result; } // // Calculate Bar Body ... double GetBody() { // double result = 0; // if (!IsValid()) { return result; } // result = GetUp() - GetDown(); // return result; } // // Calculate Bar Range ... double GetRange() { // double result = 0; // if (!IsValid()) { return result; } // result = high - low; // return result; } // // Calculate Bar Shadows ... double GetShadows() { // double result = 0; // if (!IsValid()) { return result; } // result = GetRange() - GetBody(); // return result; } // // Calculate Bar High Shadow ... double GetHighShadow() { // double result = 0; // if (!IsValid()) { return result; } // result = // high - GetUp() // ; // return result; } // // Calculate Bar Low Shadow ... double GetLowShadow() { // double result = 0; // if (!IsValid()) { return result; } // result = // GetDown() - low; // ; // return result; } // // Check Bar is Bullish ... bool IsBullish() { // bool result = false; // if (!IsValid()) { return result; } // result = open < close; // return result; } // // Check Bar is Bearish ... bool IsBearish() { // bool result = false; // if (!IsValid()) { return result; } // result = open > close; // return result; } // // Find Next Bar Time ... datetime NextAt() { // datetime result = NULL; // if (!IsValid()) { return result; } // int prSeconds = PeriodSeconds(period); // result = time + prSeconds; // return result; } // // Find Prev Bar Time ... datetime BeforeOn() { // datetime result = NULL; // if (!IsValid()) { return result; } // int prSeconds = PeriodSeconds(period); // result = time - prSeconds; // return result; } // // Find Current Bar Index on Chart ... int Index() { // int result = -1; // if (!IsValid()) { return result; } // result = iBarShift( symbol, period, time // ); // return result; } // bool GetPreviousBar(XOHCL &bar) { // bool result = false; // result = IsValid(); if (!result) { return result; } // int idx = Index(); // result = bar.Init( this.symbol, this.period, idx + 1 // ); // return result; } // // Check Bar has Strong Body or Not ... bool HasStrongBody() { // bool result = false; // if (!IsValid()) { return result; } // double body = GetBody(); double shadow = GetShadows(); // result = body > shadow * 1.5; // return result; } // // Bar Must Open Below Prce // and Close Above it ... bool IsBreakUp( double price // a Price to Check Breake ) { // bool result = false; // result = HasStrongBody(); if (!result || price <= 0) { return result; } // // Select required Prices ... // result = // close > price && open < price; // return result; } // // Bar Must Open Above Prce // and Close Below it ... bool IsBreakDown( double price // a Price to Check Breake ) { // bool result = false; // result = HasStrongBody(); if (!result || price <= 0) { return result; } // // Select required Prices ... // result = // open > price && close < price; // return result; } // bool IsBreakOut( double price, // a Price to Check Breake bool useHighLow = true // if true using High and Low price for Breakeouts, if not use Open Close ) { // bool result = false; // result = HasStrongBody(); if (!result || price <= 0) { return result; } // // Select required Prices ... // double selectedUp = useHighLow ? high : GetUp(); double selectedDown = useHighLow ? low : GetDown(); // result = // selectedUp > price && selectedDown < price; // return result; } // // Check a Support Line Rejected or not ... bool IsSupportRejected( double price // Support Price ) { // bool result = false; // // this is zBar ... // so we are try to Recieve CBar ... XOHCL cBar; result = this.GetPreviousBar(cBar); if (!result) { return result; } // // Now we are going to Recieve PBar ... XOHCL pBar; result = cBar.GetPreviousBar(pBar); if (!result) { return result; } // // We Have this (0) Bar, cBar (1) and pBar (2) ... // // pBar Down Shadow must break Price Line ... // cBar and zBar Close must be Above Price Line ... // also zBar Open must be Above Price Line ... result = // pBar.high > price && pBar.low < price && cBar.close > price && this.close > price && this.open > price // ; // return result; } // // Check a Support Line Breaked or not ... bool IsSupportBreaked( double price // Support Price ) { // bool result = false; // // this is zBar ... // so we are try to Recieve CBar ... XOHCL cBar; result = this.GetPreviousBar(cBar); if (!result) { return result; } // // Now we are going to Recieve PBar ... XOHCL pBar; result = cBar.GetPreviousBar(pBar); if (!result) { return result; } // // We Have this (0) Bar, cBar (1) and pBar (2) ... // // pBar Down Shadow must break Price Line ... // cBar and zBar Close must be Below Price Line ... // also zBar Open must be Below Price Line ... result = // pBar.high > price && pBar.low < price && cBar.close < price && this.close < price && this.open < price // ; // return result; } // // Check a Resistance Line Rejected or not ... bool IsResistanceRejected( double price // Resistance Price ) { // bool result = false; // // this is zBar ... // so we are try to Recieve CBar ... XOHCL cBar; result = this.GetPreviousBar(cBar); if (!result) { return result; } // // Now we are going to Recieve PBar ... XOHCL pBar; result = cBar.GetPreviousBar(pBar); if (!result) { return result; } // // We Have this (0) Bar, cBar (1) and pBar (2) ... // // pBar Up Shadow must break Price Line ... // cBar and zBar Close must be Under Price Line ... // also zBar Open must be Under Price Line ... result = // pBar.high > price && pBar.low < price && cBar.close < price && this.close < price && this.open < price // ; // return result; } // // Check a Resistance Line Breaked or not ... bool IsResistanceBreaked( double price // Support Price ) { // bool result = false; // // this is zBar ... // so we are try to Recieve CBar ... XOHCL cBar; result = this.GetPreviousBar(cBar); if (!result) { return result; } // // Now we are going to Recieve PBar ... XOHCL pBar; result = cBar.GetPreviousBar(pBar); if (!result) { return result; } // // We Have this (0) Bar, cBar (1) and pBar (2) ... // // pBar Up Shadow must break Price Line ... // cBar and zBar Close must be Over Price Line ... // also zBar Open must be Pver Price Line ... result = // pBar.low < price && pBar.high > price && cBar.close > price && this.close > price && this.open > price // ; // return result; } // // Check Bar is Inside Previus Bar ... bool IsInsideBar( double threshold = 5 // Points Distance between Up and Down ) { // bool result = false; // if (threshold < 0) { threshold = 0; } // XOHCL pBar; result = GetPreviousBar(pBar); if (!result) { return result; } // double offset = PointToPrice(threshold, this.symbol); // result = // pBar.high > this.high && pBar.low < this.low && MathAbs(pBar.low - this.low) > offset && MathAbs(pBar.high - this.high) > offset // ; // return result; } // // Check Bar has Strongest Body in a Range ... bool HasStrongestBody( int mLoopback = 3 // loopback candles to compare it ... ) { // bool result = false; // result = IsValid(); if (!result) { return result; } // double body = GetBody(); XOHCL prev = this; for (int i = 0; i < mLoopback; i++) { // bool isValid = prev.GetPreviousBar(prev); if (!isValid) { // result = false; break; } // result = // result && body > prev.GetBody() // ; if (!result) { break; } } // return result; } // // Check Bar has Weakest Body in a Range ... bool HasWeakestBody( int mLoopback = 3 // loopback candles to compare it ... ) { // bool result = false; // result = IsValid(); if (!result) { return result; } // double body = GetBody(); XOHCL prev = this; for (int i = 0; i < mLoopback; i++) { // bool isValid = prev.GetPreviousBar(prev); if (!isValid) { // result = false; break; } // result = // result && body < prev.GetBody() // ; if (!result) { break; } } // return result; } // // Determines Swings based On this Bar ... // Calculates Based on atleast 3 Bars Prev ... ENUM_X_SWING_TYPE GetSwingType() { // ENUM_X_SWING_TYPE result = X_NO_SWING; // // Find Current Index of Bar ... int barIndex = Index(); if (barIndex <= -1) { return result; } // // First we have to Retrieve atleast 3 Bars before this bar ... XOHCL bars[]; int barsCount = GetBars( bars, symbol, period, barIndex + 1, 3 // ); if (barsCount < 3) { return result; } // // Check Swing Start Candle has Strong Body ... bool isStrongBodyCandle = bars[2].HasStrongBody(); if (!isStrongBodyCandle) { return result; } // // Check Swing Low Conditions ... bool isSwingLowOrderBlock = bars[2].low < bars[1].low && bars[1].low < bars[0].low && bars[2].low < bars[0].low; if (isSwingLowOrderBlock) { result = X_SWING_LOW; } // // Check Swing High Conditions ... bool isSwingHighOrderBlock = bars[2].high > bars[1].high && bars[1].high > bars[0].high && bars[2].high > bars[0].high; if (isSwingHighOrderBlock) { result = X_SWING_HIGH; } // return result; } // // Find Swings (Highs nd Lows) ... int FindSwing( ENUM_X_SWING_TYPE swing, // Swing Based On Price mode ... int mLength // Loopback ... ) { // int result = -1; // if (!IsValid() || !IsValid(swing)) { return result; } // int current = Index(); int founded = FindNextSwing( swing, (mLength * 2) + 1, current - mLength // ); // while (founded != current) { // current = FindNextSwing( swing, mLength, current + 1 // ); // founded = FindNextSwing( swing, (mLength * 2) + 1, current - mLength // ); } // result = current; // return result; } // // Find Next Swing ... int FindNextSwing( ENUM_X_SWING_TYPE swing, // Swing Based On Price mode ... int from, // from Bar Index int mLength // Loopback ... ) { // int result = -1; // if (!IsValid() || !IsValid(swing)) { return result; } // if (from < 0) { mLength += from; from = 0; } // ENUM_SERIESMODE mMode = swing == X_SWING_HIGH ? MODE_HIGH : MODE_LOW; // result = swing == X_SWING_HIGH ? iHighest( symbol, period, mMode, mLength, from) : iLowest( symbol, period, mMode, mLength, from); // return result; } // // Find Lowest Bar Index ... int FindHighestIndex( int mLength, // Loopback ... ENUM_SERIESMODE mMode // Calculation mode ) { // int result = -1; // if (!IsValid()) { return result; } // if (mLength < 2) { mLength = 2; } // result = iHighest( symbol, period, mMode, mLength, Index()); // return result; } // // Find Lowest ... double FindHighest( int mLength, // Loopback ... ENUM_SERIESMODE mMode // Calculation mode ) { // double result = 0; // if (!IsValid()) { return result; } // int idx = FindHighestIndex( mLength, mMode); if (idx <= -1) { return result; } // XOHCL iH; result = iH.Init( symbol, period, idx // ); if (!result) { return result; } // result = iH.GetPrice(mMode); // return result; } // // Find Lowest Bar Index ... int FindLowestIndex( int mLength, // Loopback ... ENUM_SERIESMODE mMode // Calculation mode ) { // int result = -1; // if (!IsValid()) { return result; } // if (mLength < 2) { mLength = 2; } // result = iLowest( symbol, period, mMode, mLength, Index()); // return result; } // // Find Lowest ... double FindLowest( int mLength, // Loopback ... ENUM_SERIESMODE mMode // Calculation mode ) { // double result = 0; // if (!IsValid()) { return result; } // int idx = FindLowestIndex( mLength, mMode); if (idx <= -1) { return result; } // XOHCL iL; result = iL.Init( symbol, period, idx // ); if (!result) { return result; } // result = iL.GetPrice(mMode); // return result; } // // Candlestic Tools ... // bool IsDoji() { // bool result = false; // // Validate Content and Ignore 0 Bar // since it is not Completed ... result = IsValid() && Index() > 0; if (!result) { return result; } // result = open == close; // return result; } // // Convert to String Representation ... string ToString() { // string result = ""; // result = GetTypeName(this) + "(O(" + ToString(open) + "),H(" + ToString(high) + "),C(" + ToString(close) + "),L(" + ToString(low) + "))"; // return result; } }; // struct XPivot { // double pivot; // Pivot Price ... int breaks; // Number of Breaks ... int rejects; // Number of Rejects ... // void XPivot() { Clean(); } // // Tools ... // // Cleanup ... void Clean() { // pivot = 0; breaks = 0; rejects = 0; } // // Validate ... bool IsValid() { // bool result = false; // result = pivot > 0; // return result; } }; // struct XPivotTracker { // XPivot pivots[]; // // Constructor ... void XPivotTracker() { Clean(); } // // Tools ... // // Cleanup ... void Clean() { // Clean(pivots); } // int Count() { return ArraySize(pivots); } // double Get(int index) { // double result = 0; // NormalizeIndex(index, pivots); // XPivot iPivot = pivots[index]; // result = iPivot.pivot; // return result; } // XPivot GetPivot(int index) { // XPivot result; // NormalizeIndex(index, pivots); // result = pivots[index]; // return result; } // bool Add(double mPivot) { // bool result = false; // result = mPivot > 0 && !Has(mPivot); if (!result) { return result; } // XPivot pivot; pivot.pivot = mPivot; // AddRef( pivot, pivots // ); // result = true; // return result; } // int Adds(double &mPivots[]) { // int result = 0; // int pivotsCount = ArraySize(mPivots); if (!IsValidSize(pivotsCount)) { return result; } // for (int i = 0; i < pivotsCount; i++) { // double iPivot = mPivots[i]; // bool isAdded = Add(iPivot); if (isAdded) { result++; } } // return result; } // int FindIndex(double mPivot) { // int result = -1; // if (mPivot <= 0) { return result; } // int count = Count(); if (!IsValidSize(count)) { return result; } // for (int i = 0; i < count; i++) { // XPivot iPivot = pivots[i]; // if (iPivot.pivot == mPivot) { // result = i; break; } } // return result; } // double Has(double mPivot) { // bool result = false; // int pivotIDX = FindIndex(mPivot); result = pivotIDX >= 0; // return result; } // int Reject(double mPivot) { // int result = 0; // int pivotIDX = FindIndex(mPivot); if (pivotIDX < 0) { return result; } // pivots[pivotIDX].rejects++; // result = pivots[pivotIDX].rejects; // return result; } // int Break(double mPivot) { // int result = 0; // int pivotIDX = FindIndex(mPivot); if (pivotIDX < 0) { return result; } // pivots[pivotIDX].breaks++; // result = pivots[pivotIDX].breaks; // return result; } // bool Remove(double mPivot) { // bool result = false; // int pivotIDX = FindIndex(mPivot); result = pivotIDX >= 0; if (!result) { return result; } // result = ArrayRemove( pivots, pivotIDX, 1 // ); // return result; } // bool HasChild() { // bool result = false; // int count = Count(); result = IsValidSize(count); // return result; } }; // // Model Support and Resistance // for Specific Bar ... struct XOHCLSupRes { // // Props ... // /// Resistances ... double res[]; // // Supports ... double sup[]; // // Constructor ... XOHCLSupRes() { Clean(); } // // Init ... bool Init( double price, // Price ... const double &pivots[], // Provided Pivot Points ... int count = 3, // Number of Requireds ... double step = 0 // Distance between each item with it's Last Side ... ) { // bool result = false; // Clean(); // if (price <= 0) { return result; } // int pivotsCount = ArraySize(pivots); if (pivotsCount <= 0) { return result; } // if (count <= 0 || count > pivotsCount - 1) { return result; } // double lastR = 0; double tmpR[]; // double lastS = 0; double tmpS[]; // // Extract Supports ... // which prices is under low of candle ... // // Extract Resistance ... // which prices is over high of candle ... for (int i = 0; i < pivotsCount; i++) { // double iFlat = pivots[i]; // if (iFlat > price) { // bool canAdd = step <= 0 ? true : lastR == 0 || MathAbs(iFlat - lastR) >= step; if (canAdd) { // Add( iFlat, tmpR); // lastR = iFlat; } } else if (iFlat < price) { // bool canAdd = step <= 0 ? true : lastS == 0 || MathAbs(iFlat - lastS) >= step; if (canAdd) { // Add( iFlat, tmpS); // lastS = iFlat; } } } // // Sorting Founded Resistance and Supports ... // // Since Resistance Levels must be Increasing ... ArraySort(tmpR); // // Since Support Levels must be Decreasing ... ArraySort(tmpS); ArrayReverse(tmpS); // // Fill Resistance ... int tmpRCount = ArraySize(tmpR); if (tmpRCount > 0) { // if (tmpRCount < count) { // ArrayCopy( res, tmpR); } else { // ArrayCopy( res, tmpR, 0, 0, count); } } // // Fill Supports ... int tmpSCount = ArraySize(tmpS); if (tmpSCount > 0) { // if (tmpSCount < count) { // ArrayCopy( sup, tmpS); } else { // ArrayCopy( sup, tmpS, 0, 0, count); } } // result = IsValid(); // return result; } // // Tools ... // // Cleanup ... void Clean() { // Clean(sup); Clean(res); } // // Validate ... bool IsValid() { // bool result = false; // result = // CountSupports() > 0 || CountResistances() > 0 // ; // return result; } // int CountSupports() { return ArraySize(sup); } // int CountResistances() { return ArraySize(res); } }; // // Tracking Times ... struct XTimeTracker { // // Props ... int xMonth; int xDayOfWeek; int xForWeekDay; int xDay; int xHour; // // Constructor ... XTimeTracker() { Clean(); } // // Tools ... // void Clean() { // xDay = -1; xHour = -1; xMonth = -1; xDayOfWeek = -1; xForWeekDay = -1; } // // Detecting New Houre ... bool IsNewHour() { // bool result = false; // // Retrieve Current Time as Struct ... MqlDateTime timeStruct = GetCurrentTime(); // // Check Houre ... result = timeStruct.hour != xHour; if (result) { xHour = timeStruct.hour; } // return result; } // // Detecting New Day ... bool IsNewDay() { // bool result = false; // // Retrieve Current Time as Struct ... MqlDateTime timeStruct = GetCurrentTime(); // // Check Houre ... result = timeStruct.day_of_year != xDay; if (result) { xDay = timeStruct.day_of_year; } // return result; } // // Detecting New Week ... bool IsNewWeek() { // bool result = false; // // Retrieve Current Time as Struct ... MqlDateTime timeStruct = GetCurrentTime(); // // Check Week ... // Since Week Starts From Monday in Forex World ... // we Calculate Start of Week by 1-Monday ... result = xDayOfWeek == -1 && xForWeekDay == -1 ? true : timeStruct.day_of_week == 1 && timeStruct.day_of_year > xForWeekDay; // xForWeekDay = timeStruct.day_of_year; xDayOfWeek = timeStruct.day_of_week; // return result; } // // Detecting End Of Week ... bool IsWeekEnd() { // bool result = false; // // Retrieve Current Time as Struct ... MqlDateTime timeStruct = GetCurrentTime(); // // Check WeekEnd ... // Since Week Starts From Monday in Forex World ... // we Calculate End of Week by 5-Friday ... result = xDayOfWeek != -1 && timeStruct.day_of_week == 5 && timeStruct.hour == 23 && timeStruct.min == 59 && timeStruct.sec == 59; // return result; } // // Detecting New Month ... bool IsNewMonth() { // bool result = false; // // Retrieve Current Time as Struct ... MqlDateTime timeStruct = GetCurrentTime(); // // Check Houre ... result = timeStruct.mon != xMonth; if (result) { xMonth = timeStruct.mon; } // return result; } }; // // Tracking Bars on Specified Environment ... struct XBarTracker { // string symbol; // Tracking Symbol ENUM_TIMEFRAMES period; // Tracking Time Frame // int lastTrackedBar; // Last Tracked Bar ... // // Constructor ... XBarTracker() { Clean(); } // // Initializer ... bool Init( string mSymbol = NULL, // Trading Symbol ENUM_TIMEFRAMES mPeriod = NULL // Trading Period ) { // bool result = false; // mSymbol = NormalizeSymbol(mSymbol); mPeriod = NormalizePeriod(mPeriod); // this.symbol = mSymbol; this.period = mPeriod; // this.lastTrackedBar = 0; // result = true; // return result; } // // Retrieve all Bars ... int CountBars() { // return Bars( symbol, period // ); } // // Check if it's New Bar ... bool IsNewBar() { // bool result = false; // int currentBars = CountBars(); // result = currentBars > lastTrackedBar; if (result) { lastTrackedBar = currentBars; } // return result; } // // Tools ... void Clean() { // symbol = NormalizeSymbol(NULL); period = NormalizePeriod(NULL); } }; // // Track Value Changes ... template struct XValueTracker { // // Definitions ... // // Model a Value Change ... struct XValueChange { // // Props ... datetime at; // Change Time T from; // Before Change Value T to; // After Change Value // // Constructor ... XValueChange() { Clean(); } // // Cleanup ... void Clean() { // at = NULL; from = NULL; to = NULL; } // // Validate ... bool IsValid() { // bool result = false; // result = IsValid(at); if (!result) { return result; } // result = NotEmpty(from) && NotEmpty(to); // return result; } }; // // Props ... XValueChange changes[]; // Hold Changes // // Constructor ... XValueTracker() { Clean(); } // // Track a Change Happens Or Not ... bool Track( const T &source[] // Data Source for Track Changes ) { // bool result = false; // if (ArraySize(source) <= 1) { return result; } // datetime time = TimeCurrent(); // double from = source[1]; double to = source[0]; // result = to != from; if (result) { return result; } // XValueChange lastChange; bool hasLastChange = GetLastItem( lastChange, changes // ); result = !hasLastChange ? true : lastChange.at < time && lastChange.to != to && lastChange.from != from; if (!result) { return result; } // lastChange.Clean(); // lastChange.to = to; lastChange.at = time; lastChange.from = from; // AddRef( lastChange, changes // ); // return result; } // // Tools ... // // Cleanup ... void Clean() { Clean(changes); } }; // // Model a Market Cycle ... struct XMarketCycle { // // Props ... // string prefix; // Prefix Trag ... // string symbol; // Market Symbol ... // ENUM_TIMEFRAMES period; // Period of Cycle ... ENUM_X_PERIOD_METHOD method; // Period Selection Method ... ENUM_X_MARKET_CYCLES cycle; // Cycles of MArket ... // int length; // Number Of Candles per Current Time Frame ... ENUM_TIMEFRAMES hostPeriod; // Current Time Frame ... // datetime lastStart; // Last Candle Bar Time ... // XBarTracker barTracker; // Bar Tracker ... XBarRemainsTime remains; // Current Bar Remains Model ... // // Constructor ... XMarketCycle() { Clean(); } // // Init Cycle ... bool Init( string mSymbol, // Trading Symbol ENUM_TIMEFRAMES mHostPeriod, // Host Period ENUM_X_MARKET_CYCLES mCycle, // Init Cycle string mPrefix = "" // Prefix ) { // bool result = false; // mSymbol = NormalizeSymbol(mSymbol); mHostPeriod = NormalizePeriod(mHostPeriod); // result = IsValid(mCycle); if (!result) { return result; } // this.cycle = mCycle; // // Set Automatically Prefix ... if (StringLen(mPrefix) == 0) { this.prefix = ToString(cycle); } // result = IsValid( method, period // ); if (!result) { return result; } // this.symbol = mSymbol; this.hostPeriod = mHostPeriod; // // Find Cycle Period ... if (method == X_PERIOD_AUTO) { // // Select Period ... this.period = GetCyclePeriod( this.cycle, this.hostPeriod); } // // Set Prefix if Provided ... if (StringLen(mPrefix) > 0) { this.prefix = mPrefix; } // // Calculate Required Info ... // // Length ... this.length = PeriodSeconds(this.period) / PeriodSeconds(this.hostPeriod); // // Update Additional Data ... result = this.Update(0); // return result; } // bool Init( string mSymbol, // Trading Symbol ENUM_TIMEFRAMES mHostPeriod, // Host Period ENUM_X_MARKET_CYCLES mCycle, // Init Cycle ENUM_X_PERIOD_METHOD mMethod, // Period Selection Method ENUM_TIMEFRAMES mPeriod, // Provided Period string mPrefix = "" // Prefix ) { // this.period = mPeriod; this.method = mMethod; // return Init( mSymbol, mHostPeriod, mCycle, mPrefix // ); } // // Tools ... // // Cleanup ... void Clean() { // length = 0; lastStart = 0; // cycle = NULL; prefix = NULL; symbol = NULL; period = NULL; method = NULL; hostPeriod = NULL; // remains.Clean(); barTracker.Clean(); } // // Check Structure Valid ... bool IsValid() { // bool result = false; // result = IsValid( method, period); if (!result) { return result; } // result = // length > 0 && symbol != NULL && period != NULL && method != NULL && hostPeriod != NULL && method != X_PERIOD_NOTHING // ; // return result; } // // Update Market Cycle Additional Info ... bool Update(int hostBarIndex) { // bool result = false; // result = this.IsValid(); if (!result) { return result; } // // Init Remains ... result = remains.Init( this.symbol, this.period); if (!result) { return result; } // // Init Bar Tracker ... result = barTracker.Init( this.symbol, this.period); if (!result) { return result; } // return result; } // // Count Bars ... int CountBars() { // int result = 0; // if (!IsValid()) { return result; } // result = barTracker.CountBars(); // return result; } // // Check New Bar ... bool IsNewBar() { // bool result = false; // if (!IsValid()) { return result; } // result = barTracker.IsNewBar(); // return result; } // // Retrieve Current Bar Index based on Host Period bar Index ... int GetBarIndex(int barIndex) { // int result = 0; // if (!IsValid()) { return result; } // if (barIndex < 0) { return result; } // int totalBars = CountBars(); if (barIndex >= totalBars) { // result = totalBars - 1; return result; } // datetime hostBarTime = iTime( this.symbol, this.hostPeriod, barIndex // ); // result = iBarShift( this.symbol, this.period, hostBarTime // ); // return result; } // // Retrieve Current Cycles Specific Bar ... XOHCL GetBar(int barIndex) { // if (barIndex < 0) { barIndex = 0; } // int totalBars = CountBars(); if (barIndex >= totalBars) { barIndex = totalBars - 1; } // XOHCL result; result.Init( this.symbol, this.period, barIndex // ); // return result; } // // Extract Specific Range of Bars ... // using Start Bar Index ... int GetBars( XOHCL &result[], // Hold Result int from = 0, // Start Bar Index int count = 1, // Number of Bars bool forceClean = true // Clean Result Array ) { // int mResult = 0; // if (from < 0) { from = 0; } // int total = Bars( symbol, period); if (from > total - 2) { from = total - 2; } // if (count < 0) { count = 1; } // int start = from; int end = start + count; if (end > total - 1) { end = total - 1; } // if (forceClean) { Clean(result); } // int beforeSize = ArraySize(result); // for (int i = start; i < end; i++) { // XOHCL iBar; bool isValid = iBar.Init( symbol, period, i // ); // if (isValid) { // AddRef( iBar, result // ); } } // int afterSize = ArraySize(result); // mResult = afterSize - beforeSize; // return mResult; } // // Extract Specific Range of Bars ... // using Start Bar Time ... int GetBars( XOHCL &result[], // Hold Result datetime from = NULL, // Start Bar Time int count = 1, // Number of Bars bool forceClean = true // Clean Result Array ) { // from = NormalizeTime(from); // int barIndex = iBarShift( symbol, period, from, false // ); // return GetBars( result, symbol, period, barIndex, count, forceClean // ); } // // Retrieve Bar Time ... datetime GetBarTime(int barIndex) { // datetime result = NULL; // if (!IsValid()) { return result; } // if (barIndex < 0) { barIndex = 0; } // int totalBars = CountBars(); if (barIndex >= totalBars) { barIndex = totalBars - 1; } // result = iTime( this.symbol, this.period, barIndex // ); // return result; } // // Find Chart ID ... ulong GetChartID() { // ulong result = 0; // long firstChart = ChartFirst(); result = firstChart; // while (result >= 0) { // string chSymbol = ChartSymbol(result); ENUM_TIMEFRAMES chPeriod = ChartPeriod(result); // bool isOwnChart = // symbol == chSymbol && period == chPeriod // ; if (isOwnChart) { break; } // result = ChartNext(result); if (result < 0) { break; } } // return result; } // // Create and String Representation for Unique Taging ... string ToString() { // string result = ""; // if (!IsValid()) { return result; } // result = GetTypeName(this) + "(" + "PRFX(" + this.prefix + ")" + "SMBL(" + this.symbol + ")" + "CYC(" + ToString(this.cycle) + ")" + "PRD(" + ToString(this.period) + ")" + "PRDHST(" + ToString(this.hostPeriod) + ")" + "MTH(" + EnumToString(this.method) + ")" + ")"; // return result; } // // Here we Produce a Summary brief of // state of Cycle ... string GenerateSummary() { // string result = ""; // bool hasPrefix = StringLen(this.prefix) > 0 && this.prefix != ToString(this.cycle); result += (hasPrefix ? this.prefix + "[" : "") + ToString(this.cycle) + (hasPrefix ? "]" : "") + "\n"; // result += " - PR: " + ToString(this.period) + "\n"; // XOHCL cBar = GetBar(0); // result += " - State: " + (cBar.IsBullish() ? "Bullish" : cBar.IsBearish() ? "Bearish" : "Neutural"); // return result; } }; // // Styling Buffers ... // struct XBufferPlotStyle { // int width; // Width color clr; // Color uchar arrow; // Arrow Code ENUM_DRAW_TYPE type; // Type ENUM_LINE_STYLE style; // Style // // Constructor ... XBufferPlotStyle() { Default(); } // // Tools ... // // Default ... void Default() { // width = 1; arrow = 0; clr = CLR_NONE; type = DRAW_NONE; style = STYLE_SOLID; } }; // // Register a Buffer as Indexed Buffer ... void SetIndexBuffer( int &index, // the Index refrence for Buffer double &buffer[], // Buffer to Set XBufferPlotStyle &style, // Style to Apply to Buffer double &colorBuffer[], // Color Buffer string label = NULL, // Buffer Label bool showData = true, // Show Data on Data Window double empty = -1, // Set 0 or EMPTY_VALUE used for setting Empty Value int drawBegin = -1 // if Set More Than -1 applied ) { // // Set Buffer Index ... SetIndexBuffer(index, buffer, INDICATOR_DATA); // // Show Date ... PlotIndexSetInteger(index, PLOT_SHOW_DATA, showData); // // Set Buffer Label ... if (IsValid(label)) { PlotIndexSetString(index, PLOT_LABEL, label); } // if (empty == 0 || empty == EMPTY_VALUE) { PlotIndexSetDouble(index, PLOT_EMPTY_VALUE, empty); } // if (drawBegin > -1) { PlotIndexSetInteger(index, PLOT_DRAW_BEGIN, drawBegin); } // if (style.type == DRAW_ARROW) { PlotIndexSetInteger(index, PLOT_ARROW, style.arrow); } // PlotIndexSetInteger(index, PLOT_LINE_STYLE, style.style); PlotIndexSetInteger(index, PLOT_LINE_WIDTH, style.width); // string drawTypeStr = EnumToString(style.type); bool hasColorBuffer = Contains("COLOR", drawTypeStr); // if (!hasColorBuffer) { PlotIndexSetInteger(index, PLOT_LINE_COLOR, style.clr); } else { // // Since Color Buffers must add as next Index of it's own Buffer // here before applied Color Buffer increase index ... index++; // SetIndexBuffer(index, colorBuffer, INDICATOR_COLOR_INDEX); } // // Increase Index for Next Buffer ... index++; } // void SetIndexCandleBuffers( int &index, // the Index refrence for Buffer string openLabel, // Open Label double &open[], // Open Buffer string highLabel, // High Label double &high[], // High Buffer string lowLabel, // Low Label double &low[], // Low Buffer string closeLabel, // Close Label double &close[], // Close Buffer bool showData = true, // Show Data on Data Window double empty = -1, // Set 0 or EMPTY_VALUE used for setting Empty Value int drawBegin = -1 // if Set More Than -1 applied ) { // bool hasLabel = // IsValid(openLabel) && IsValid(highLabel) && IsValid(lowLabel) && IsValid(closeLabel) // ; // string label = !hasLabel ? NULL : openLabel + ";" + highLabel + ";" + lowLabel + ";" + closeLabel; // // Set Buffer Index ... SetIndexBuffer(index, open, INDICATOR_DATA); // // Set Draw Candles Type ... PlotIndexSetInteger(index, PLOT_LINE_STYLE, DRAW_CANDLES); // // Show Date ... PlotIndexSetInteger(index, PLOT_SHOW_DATA, showData); // // Set Buffer Label ... if (IsValid(label)) { PlotIndexSetString(index, PLOT_LABEL, label); } // if (empty == 0 || empty == EMPTY_VALUE) { PlotIndexSetDouble(index, PLOT_EMPTY_VALUE, empty); } // if (drawBegin > -1) { PlotIndexSetInteger(index, PLOT_DRAW_BEGIN, drawBegin); } // index++; // // Set Buffer Index ... SetIndexBuffer(index, high, INDICATOR_DATA); index++; // // Set Buffer Index ... SetIndexBuffer(index, low, INDICATOR_DATA); index++; // // Set Buffer Index ... SetIndexBuffer(index, close, INDICATOR_DATA); index++; } // void SetIndexCandleBuffers( int &index, // the Index refrence for Buffer string openLabel, // Open Label double &open[], // Open Buffer string highLabel, // High Label double &high[], // High Buffer string lowLabel, // Low Label double &low[], // Low Buffer string closeLabel, // Close Label double &close[], // Close Buffer double &colorBuffer[], // Candle Color Buffer bool showData = true, // Show Data on Data Window double empty = -1, // Set 0 or EMPTY_VALUE used for setting Empty Value int drawBegin = -1 // if Set More Than -1 applied ) { // SetIndexCandleBuffers( index, openLabel, open, highLabel, high, lowLabel, low, closeLabel, close, showData, empty, drawBegin // ); // int mFirstIndex = index - 4; // // Set Draw Candles Type ... PlotIndexSetInteger(mFirstIndex, PLOT_LINE_STYLE, DRAW_COLOR_CANDLES); // // Set Color Buffer ... SetIndexBuffer(index, colorBuffer, INDICATOR_COLOR_INDEX); // index++; } // // Functions ... // // Validators ... // // Validate an String has length and not NULL ... bool IsValid(string value) { // bool result = false; // result = // value != NULL && StringLen(value) > 0 // ; // return result; } bool IsSpecifiedValid(string value) { return IsValid(value); } // // Validate a Date ... bool IsValid(datetime value) { // bool result = false; // result = NotEmpty(value) && value != NULL; // return result; } // // Validate a Period Param ... bool IsValid(ENUM_TIMEFRAMES value) { // bool result = false; // result = // value != NULL // ; // return result; } bool IsSpecifiedValid(ENUM_TIMEFRAMES value) { // return IsValid(value); } // // Validate Specified Cycle ... bool IsValid(ENUM_X_MARKET_CYCLES value) { // bool result = false; // result = // value != NULL && value != X_MARKET_CYCLE_UNKNOWN // ; // return result; } // // Validate Specific Period Mode ... bool IsValid( ENUM_X_PERIOD_METHOD mMethod, // Period Select Method ENUM_TIMEFRAMES mPeriod // Selected Period ) { // bool result = false; // result = // mMethod == X_PERIOD_NOTHING ? false : mMethod == X_PERIOD_MANUALLY ? mPeriod != NULL : mMethod == X_PERIOD_AUTO ? true : false // ; // return result; } // bool IsSpecifiedValid( ENUM_X_PERIOD_METHOD mMethod, // Period Select Method ENUM_TIMEFRAMES mPeriod // Selected Period ) { return IsValid(mMethod, mPeriod // ); } // // Validate Swing Mode ... bool IsValid(ENUM_X_SWING_TYPE value) { // bool result = false; // result = // value == X_SWING_HIGH || value == X_SWING_LOW // ; // return result; } // // As IS ... // // Determine a Position type is Long or not ... bool IsLong(ENUM_POSITION_TYPE type) { // bool result = type == POSITION_TYPE_BUY; // return result; } bool IsLong(ENUM_ORDER_TYPE type) { // bool result = type == ORDER_TYPE_BUY; // return result; } // // Determine a Position type is Short or not ... bool IsShort(ENUM_POSITION_TYPE type) { // bool result = type == POSITION_TYPE_SELL; // return result; } bool IsShort(ENUM_ORDER_TYPE type) { // bool result = type == ORDER_TYPE_SELL; // return result; } // // Retrieve Opposit Direction Type ... ENUM_POSITION_TYPE GetOpposit(ENUM_POSITION_TYPE type) { // ENUM_POSITION_TYPE result = NULL; // bool isLong = IsLong(type); result = isLong ? POSITION_TYPE_SELL : POSITION_TYPE_BUY; // return result; } ENUM_ORDER_TYPE GetOpposit(ENUM_ORDER_TYPE type) { // ENUM_ORDER_TYPE result = NULL; // bool isLong = IsLong(type); result = isLong ? ORDER_TYPE_SELL : ORDER_TYPE_BUY; // return result; } // // Check Expert Running in Testing Mode or not ... bool IsRunningOnTestMode() { // bool result = false; // // check programm mode ... result = MQL5InfoInteger(MQL5_TESTING); // return result; } // // Find Chart ID ... long FindChartID( string mSymbol = NULL, // Trading Symbol ENUM_TIMEFRAMES mPeriod = NULL // Trading Period ) { // long result = ChartFirst(); long first = result; // while (result > 0) { // string chSymbol = ChartSymbol(result); ENUM_TIMEFRAMES chPeriod = ChartPeriod(result); // bool isOwn = // chSymbol == mSymbol && chPeriod == mPeriod // ; if (isOwn) { break; } // result = ChartNext(result); } // return result; } // // Normalizers ... // // Check a Symbol provided or not ... // if not use Default ... string NormalizeSymbol(string value) { // string result = value; // if (!IsValid(result)) { result = _Symbol; } // return result; } // // Check a Datetime provided or not ... // if not use Current ... datetime NormalizeTime(datetime value) { // datetime result = value; // if (!IsValid(result)) { result = TimeCurrent(); } // return result; } // // Check a Period provided or not ... // if not use Default ... ENUM_TIMEFRAMES NormalizePeriod(ENUM_TIMEFRAMES value) { // ENUM_TIMEFRAMES result = value; // if (!IsValid(value)) { result = _Period; } // return result; } // // Normalize Cycle ... ENUM_X_MARKET_CYCLES NormalizeCycle(ENUM_X_MARKET_CYCLES value) { // ENUM_X_MARKET_CYCLES result = value; // if (!IsValid(result)) { result = X_MARKET_CYCLE_SHORT; } // return value; } // // Validate a Buffer Size for Looping or etc ... bool IsValidSize(int size) { // bool result = size > 0; // return result; } // // Normalize Index Based On Specified Buffer ... template void NormalizeIndex( int &index, T &buffer[] // ) { // int bufferSize = ArraySize(buffer); // if (bufferSize <= 0) { index = 0; } // if (index <= 0) { index = 0; } // if (index > bufferSize - 1) { index = bufferSize - 1; } } // // Normalize Start and Count based on Specified Buffer ... template void NormalizeCount( int &start, int &count, T &buffer[] // ) { // // Validate Buffer Size ... int bufferSize = ArraySize(buffer); if (!IsValidSize(bufferSize)) { return; } // // Normalization Start ... NormalizeIndex( start, buffer // ); // if (count < start) { count = (start - count); } // // Normalization Count ... // if (count < 0) { count = start; } // if (count > bufferSize) { count = bufferSize; } } // // Normalize a give Volume ... double NormalizeVolume( double mVolume, // desired volume to normalize string mSymbol = NULL, // Trading Symbol int mLength = 2 // Length of Digits ) { // double result = mVolume; // mSymbol = NormalizeSymbol(mSymbol); // // Normalize Digits ... int digits = GetDigits(mSymbol); // mLength = mLength == 0 || mLength > digits ? digits : MathMin(mLength, digits); // // Normalize Volume ... result = NormalizeDouble(result, mLength); // double maxAvailableVolume = SymbolInfoDouble(mSymbol, SYMBOL_VOLUME_MAX); double minAvailableVolume = SymbolInfoDouble(mSymbol, SYMBOL_VOLUME_MIN); // // Validate Result ... if (result > maxAvailableVolume) { result = maxAvailableVolume; } else if (result < minAvailableVolume) { result = minAvailableVolume; } // return result; } // // Normallize Price ... double NormalizePrice( double mPrice, // desired Price for normalization string mSymbol = NULL // Trading Symbol ) { // double result = 0; // mSymbol = NormalizeSymbol(mSymbol); // double tickSize = 0; result = SymbolInfoDouble(mSymbol, SYMBOL_TRADE_TICK_SIZE, tickSize); // int digits = GetDigits(mSymbol); result = NormalizeDouble(MathRound(mPrice / tickSize) * tickSize, digits); // return result; } // // Prices ... // // Retrieve Ask Price ... double GetAsk( string mSymbol = NULL // Trading Symbol ) { // mSymbol = NormalizeSymbol(mSymbol); // double result = SymbolInfoDouble(mSymbol, SYMBOL_ASK); // return result; } // // Retrieve Bid Price ... double GetBid( string mSymbol = NULL // Trading Symbol ) { // mSymbol = NormalizeSymbol(mSymbol); // double result = SymbolInfoDouble(mSymbol, SYMBOL_BID); // return result; } // // Retrieve Spread Price ... double GetSpread( string mSymbol = NULL // Trading Symbol ) { // mSymbol = NormalizeSymbol(mSymbol); // double ask = GetAsk(mSymbol); double bid = GetBid(mSymbol); // double result = MathAbs(ask - bid); // return result; } // // Retrieve Point Value ... double GetPoints( string mSymbol = NULL // Trading Symbol ) { // mSymbol = NormalizeSymbol(mSymbol); // double result = SymbolInfoDouble(mSymbol, SYMBOL_POINT); // return result; } // // Retrieve Point Digits ... int GetDigits( string mSymbol = NULL // Trading Symbol ) { // mSymbol = NormalizeSymbol(mSymbol); // int result = (int)SymbolInfoInteger(mSymbol, SYMBOL_DIGITS); // return result; } // // Retrieve Entry Price ... double GetEntry( string mSymbol = NULL, // Trading Symbol ENUM_POSITION_TYPE type = POSITION_TYPE_BUY // Get entry price for Which direction trade ... ) { // double result = 0; // mSymbol = NormalizeSymbol(mSymbol); // result = IsLong(type) ? GetAsk(mSymbol) : GetBid(mSymbol); result = NormalizePrice(result, mSymbol); // return result; } // // Retrieve Exit Price ... double GetExit( string mSymbol = NULL, // Trading Symbol ENUM_POSITION_TYPE type = POSITION_TYPE_BUY // Get entry price for Which direction trade ... ) { // double result = 0; // mSymbol = NormalizeSymbol(mSymbol); // result = IsLong(type) ? GetBid(mSymbol) : GetAsk(mSymbol); result = NormalizePrice(result, mSymbol); // return result; } // // Get 1 Pip in Price Value ... double GetPipPrice( string mSymbol = NULL // Trading Symbol ) { // mSymbol = NormalizeSymbol(mSymbol); // double symbolPoint = GetPoints(mSymbol); int symbolDigits = GetDigits(mSymbol); // double result = symbolPoint; if (symbolDigits == 3 || symbolDigits == 5) { result *= 10; } // return result; } // // Converts Pips To Price ... double PipsToPrice( double mPips, // pips amount string mSymbol = NULL // Trading Symbol ) { // mSymbol = NormalizeSymbol(mSymbol); // int digits = GetDigits(mSymbol); double pipValue = GetPipPrice(mSymbol); double result = mPips * pipValue; // result = NormalizePrice(result, mSymbol); // return result; } // // Converts Price to Pips ... double PriceToPips( double mPrice, // the price amount which required to calculate string mSymbol = NULL // Trading Symbol ) { // mSymbol = NormalizeSymbol(mSymbol); mPrice = NormalizePrice(mPrice, mSymbol); // int digits = GetDigits(mSymbol); double pipPrice = GetPipPrice(mSymbol); // double result = mPrice / pipPrice; // result = NormalizeDouble(result, digits); // return result; } // // Convert Price to Point ... double PriceToPoint( double price, // the price amount which required to calculate string mSymbol = NULL // Trading Symbol ) { // double result = 0; // mSymbol = NormalizeSymbol(mSymbol); price = NormalizePrice(price, mSymbol); // double point = GetPoints(mSymbol); result = price / point; // return result; } // // Converts Point to Price ... double PointToPrice( double points, // Points Amount string mSymbol = NULL // Trading Symbol ) { // double result = 0; // mSymbol = NormalizeSymbol(mSymbol); // double point = GetPoints(mSymbol); result = points * point; // result = NormalizePrice(result, mSymbol); // return result; } // // Converts Series Mode to XPRICE ... ENUM_X_PRICE ToPrice( ENUM_SERIESMODE mMode // Specified Series Mode ... ) { // ENUM_X_PRICE result = X_PRICE_CLOSE; // switch (mMode) { // // High ... case MODE_HIGH: result = X_PRICE_HIGH; break; // // Open ... case MODE_OPEN: result = X_PRICE_OPEN; break; // // Low ... case MODE_LOW: result = X_PRICE_LOW; break; // // Close ... // Default ... case MODE_CLOSE: default: result = X_PRICE_CLOSE; break; } // return result; } // // Retrieve Applied Price ... template double GetAppliedPrice( ENUM_APPLIED_PRICE tprice, // Type of Price Selection T &open[], // Open Prices T &high[], // High Preices T &low[], // Low Prices T &close[], // Close Prices int i // Bar Index ) { switch (tprice) { case PRICE_CLOSE: return (close[i]); case PRICE_OPEN: return (open[i]); case PRICE_HIGH: return (high[i]); case PRICE_LOW: return (low[i]); case PRICE_MEDIAN: return ((high[i] + low[i]) / 2.0); case PRICE_TYPICAL: return ((high[i] + low[i] + close[i]) / 3.0); case PRICE_WEIGHTED: return ((high[i] + low[i] + close[i] + close[i]) / 4.0); } return (0); } // // Calculate TP/SL for Specified Type of Positions ... void CalculateTPSL( double &mSL, // Hold SL double &mTP, // Hold TP ENUM_POSITION_TYPE mType, // Position Type Long (Buy) / Short (Sell) double mEntry, // Entry Price double mR2R = 1, // Provided Risk To Reward Ratio double slPrice = 0, // Provided SL Price double tpPrice = 0 // Provided TP Price ) { // // if Both TP and SL Provided, ignore R2R and Calculate direct ... // if SL provided, Calculate TP based on Provided R2R ... // if TP provided, Calculate SL based on Provided R2R ... // default R2R is set to 1 ... // mSL = 0; mTP = 0; // bool isLong = IsLong(mType); // // Set Default R2R ... if (mR2R < 1) { mR2R = 1; } // if (mEntry <= 0 || (tpPrice <= 0 && slPrice <= 0)) { return; } // double risk = 0; double reward = 0; // bool canCalculateBasedOnSL = slPrice > 0 && (isLong ? slPrice < mEntry : slPrice > mEntry); // bool canCalculateBasedOnTP = tpPrice > 0 && (isLong ? tpPrice > mEntry : tpPrice < mEntry); // if (canCalculateBasedOnSL && !canCalculateBasedOnTP) { // risk = MathAbs(mEntry - slPrice); reward = risk * mR2R; } else if (!canCalculateBasedOnSL && canCalculateBasedOnTP) { // reward = MathAbs(mEntry - tpPrice); risk = reward / mR2R; } else if (!canCalculateBasedOnSL && !canCalculateBasedOnTP) { // bool canSetTPPrice = isLong ? tpPrice > mEntry : tpPrice < mEntry; if (canSetTPPrice) { mTP = tpPrice; } // bool canSetSLPrice = isLong ? slPrice < mEntry : slPrice > mEntry; if (canSetSLPrice) { mSL = slPrice; } // return; } // mTP = isLong ? mEntry + reward : mEntry - reward; // mSL = isLong ? mEntry - reward : mEntry + reward; } // bool GetTick( string mSymbol, MqlTick &tick // ) { return SymbolInfoTick(mSymbol, tick); } // // Symbols ... // // Retrieve Available Symbols ... int GetAllSymbols( string &symbols[], // Hold Result bool onlyInWatchList = false, // Specified Retrieve only Symbols which in Watch List bool forceClean = true // Force To Clean Result Array ) { // int result = 0; // if (forceClean) { Clean(symbols); } // int beforeSize = ArraySize(symbols); // int symbolsCount = SymbolsTotal(onlyInWatchList); if (symbolsCount <= 0) { return result; } // for (int i = 0; i < symbolsCount; i++) { // string iSymbol = SymbolName( i, onlyInWatchList // ); if (!IsValid(iSymbol)) { continue; } // Add( iSymbol, symbols // ); } // int afterSize = ArraySize(symbols); // result = afterSize - beforeSize; // return result; } // // This is a Global Way to Filter Symbols // you can pass Specific string as Query or a List String for Filtering ... int FilterSymbols( string query, // Which Query to Search Symbol string &symbols[], // Hold Result bool onlyInWatchList = false, // Specified Retrieve only Symbols which in Watch List bool forceClean = true, // Force To Clean Result Array bool ignoreCase = true, // Ignore Case string querySeparator = "," // If Provided means query is a COllection of Queries and need to be Splitted ) { // int result = 0; // if (forceClean) { Clean(symbols); } // if (!IsValid(query)) { return result; } // // Check Query is an String array or not ... string mQueries[]; int queriesCount = 0; if (IsValid(querySeparator) && Contains(querySeparator, query, true)) { // queriesCount = SplitContent( mQueries, query, querySeparator // ); } // int beforeSize = ArraySize(symbols); // string allSymbols[]; int allSymbolsCount = GetAllSymbols( allSymbols, onlyInWatchList, forceClean); if (allSymbolsCount <= 0) { return result; } // // Loop Through all Symbols ... for (int i = 0; i < allSymbolsCount; i++) { // string iSymbol = allSymbols[i]; // bool isFilterPassed = false; if (queriesCount == 0) { // isFilterPassed = Contains( query, iSymbol, ignoreCase // ); } else if (queriesCount > 0) { // isFilterPassed = Contains( mQueries, iSymbol, ignoreCase // ); } // if (isFilterPassed) { // Add( iSymbol, symbols // ); } } // int afterSize = ArraySize(symbols); // result = afterSize - beforeSize; // return result; } // int FilterUSDSymbols( string &symbols[], // Hold Result bool onlyInWatchList = false, // Specified Retrieve only Symbols which in Watch List bool forceClean = true, // Force To Clean Result Array bool ignoreCase = true, // Ignore Case string querySeparator = "," // If Provided means query is a COllection of Queries and need to be Splitted ) { // return FilterSymbols( "USD", symbols, onlyInWatchList, forceClean, ignoreCase, querySeparator // ); } // // Time / Date ... // // Representation of Time Struct ... // struct MqlDateTime // { // int year; // Year // int mon; // Month // int day; // Day // int hour; // Hour // int min; // Minutes // int sec; // Seconds // int day_of_week; // Day of week (0-Sunday, 1-Monday, ... ,6-Saturday) // int day_of_year; // Day number of the year (January 1st is assigned the number value of zero) // }; // // Converts Time to Seconds ... ulong TimeToSeconds( datetime time // Specify time to Convert ... ) { // ulong result = (ulong)time; // return result; } ulong TimeToSeconds( MqlDateTime &time // Specify time to Convert ... ) { // datetime dTime = StructToTime(time); // ulong result = TimeToSeconds(dTime); // return result; } // // Converts Seconds To Time ... datetime SecondsToTime( ulong seconds // Specify Seconds to Convert ... ) { // datetime result = (datetime)seconds; // return result; } MqlDateTime SecondsToStruct( ulong seconds // Specify Seconds to Convert ... ) { // datetime dTime = SecondsToTime(seconds); // MqlDateTime result = {}; TimeToStruct( dTime, result); // return result; } // // Converts Time to MilliSeconds ... ulong TimeToMilliSeconds( datetime time // Specify time to Convert ... ) { // ulong result = TimeToSeconds(time) * 1000; // return result; } ulong TimeToMilliSeconds( MqlDateTime &time // Specify time to Convert ... ) { // datetime dTime = StructToTime(time); // ulong result = TimeToMilliSeconds(dTime); // return result; } // // Converts MillisSeconds to Time ... datetime MilliSecondsToTiem( ulong milliSeconds // Specify MilliSeconds to Convert ... ) { // ulong seconds = milliSeconds / 1000; // datetime result = SecondsToTime(seconds); // return result; } MqlDateTime MilliSecondsToStruct( ulong milliSeconds // Specify MilliSeconds to Convert ... ) { // datetime dTime = MilliSecondsToTiem(milliSeconds); // MqlDateTime result = {}; TimeToStruct( dTime, result); // return result; } // // Retrieve DateTime Structure ... MqlDateTime GetCurrentTime() { // MqlDateTime result = {}; // TimeCurrent(result); // return result; } // // Retrieve Current Time as Seconds ... ulong GetCurrentTimeAsSeconds() { // datetime time = TimeCurrent(); // ulong result = TimeToSeconds(time); // return result; } // // Retrieve Current Time as MilliSeconds ... ulong GetCurrentTimeAsMilliSeconds() { // datetime time = TimeCurrent(); // ulong result = TimeToMilliSeconds(time); // return result; } // // Bar Times ... // // Retrieve Specified Bar Time ... datetime GetBarTime( string mSymbol = "", // Specify Symbol ENUM_TIMEFRAMES mPeriod = NULL, // Specify TimeFrame int barIndex = 0 // Specify Bar Index ) { // // Validate and Normalize Args ... // mSymbol = NormalizeSymbol(mSymbol); mPeriod = NormalizePeriod(mPeriod); // // Retrieve Bar Time ... datetime result = iTime( mSymbol, mPeriod, barIndex); // return result; } // // Retrieve Specified Bar Time ... ulong GetBarTimeAsSeconds( string mSymbol = "", // Specify Symbol ENUM_TIMEFRAMES mPeriod = NULL, // Specify TimeFrame int barIndex = 0 // Specify Bar Index ) { // // Retrieve Bar Time ... datetime time = GetBarTime( mSymbol, mPeriod, barIndex); // ulong result = TimeToSeconds(time); // return result; } // // Retrieve Specified Bar Time ... ulong GetBarTimeAsMilliSeconds( string mSymbol = "", // Specify Symbol ENUM_TIMEFRAMES mPeriod = NULL, // Specify TimeFrame int barIndex = 0 // Specify Bar Index ) { // // Retrieve Bar Time ... datetime time = GetBarTime( mSymbol, mPeriod, barIndex); // ulong result = TimeToMilliSeconds(time); // return result; } // // Retrieve a Bar Time Structure ... MqlDateTime GetBarTimeStruct( string mSymbol = "", // Specify Symbol ENUM_TIMEFRAMES mPeriod = NULL, // Specify TimeFrame int barIndex = 0 // Specify Bar Index ) { // MqlDateTime result = {}; // // Retrieve Bar Time ... datetime barTime = GetBarTime( mSymbol, mPeriod, barIndex); // // Convert to Structure ... TimeToStruct(barTime, result); // return result; } // // Other Tools ... // template bool IsSame( T &buffer[], // Search Buffer int count = 5, // Number of Searchs int start = 0 // Start ... ) { // bool result = false; // int bufferSize = ArraySize(buffer); result = bufferSize > 0; if (!result) { return result; } // // Validate Count ... result = start + count < bufferSize; if (!result) { return result; } // T iTem = buffer[start]; for (int i = start; i < start + count; i++) { // if (iTem != buffer[i]) { result = false; break; } // if (!result) { result = true; } } // return result; } // // Check first Cross Over second at index ... bool IsCrossedOver( const double &first[], // the buffer which check crossing over second buffer const double &second[], // first buffer checks based on this buffer const int index = 0 // check crosses in specific index ) { // bool result = false; // // Validate Args ... if (ArraySize(first) < index + 1 || ArraySize(second) < index + 1) { return result; } // result = first[index] > second[index] && !(first[index + 1] > second[index + 1]); // return result; } // // Check first is Over second at index ... bool IsOver( const double &first[], // the buffer which check over second buffer const double &second[], // first buffer checks based on this buffer const int index = 0 // check crosses in specific index ) { // bool result = false; // // Validate Args ... if (ArraySize(first) < index + 1 || ArraySize(second) < index + 1) { return result; } // result = first[index] > second[index] && first[index + 1] > second[index + 1]; // return result; } // // Check first Cross Under second at index ... bool IsCrossedUnder( const double &first[], // the buffer which check crossing under second buffer const double &second[], // first buffer checks based on this buffer const int index = 0 // check crosses in specific index ) { // bool result = false; // // Validate Args ... if (ArraySize(first) < index + 1 || ArraySize(second) < index + 1) { return result; } // result = first[index] < second[index] && !(first[index + 1] < second[index + 1]); // return result; } // // Check first is Under second at index ... bool IsUnder( const double &first[], // the buffer which check under second buffer const double &second[], // first buffer checks based on this buffer const int index = 0 // check crosses in specific index ) { // bool result = false; // // Validate Args ... if (ArraySize(first) < index + 1 || ArraySize(second) < index + 1) { return result; } // result = first[index] < second[index] && first[index + 1] < second[index + 1]; // return result; } // // Check if a Value Increasing in Loopback ... bool IsIncreasing( const int from, // Last Time Index const int to, // Fisrs Tima Index const double &buffer[] // the Buffer which required to search ) { // bool result = false; // // Validate Args ... if ( from <= to || ArraySize(buffer) < from + 1) { return result; } // // Loop through Items ... double toValue = buffer[to]; double fromValue = buffer[from]; result = toValue > fromValue; for (int i = to + 1; i <= from - 1; i++) { // double iValue = buffer[i]; bool isPassed = toValue >= iValue; // bool isIIncreasing = IsIncreasing( from, i, buffer); // // Check Result ... result = result && isPassed && isIIncreasing; if (!result) { break; } } // return result; } // // Check if a Value Decreasing in Loopback ... bool IsDecreasing( const int from, // Last Time Index const int to, // Fisr Tima Index const double &buffer[] // the Buffer which required to search ) { // bool result = false; // // Validate Args ... if ( from <= to || ArraySize(buffer) < from + 1) { return result; } // // Loop through Items ... double toValue = buffer[to]; double fromValue = buffer[from]; result = toValue < fromValue; for (int i = to + 1; i <= from - 1; i++) { // double iValue = buffer[i]; bool isPassed = toValue <= iValue; // bool isIDecreasing = IsDecreasing( from, i, buffer); // // Check Result ... result = result && isPassed && isIDecreasing; if (!result) { break; } } // return result; } // bool IsTrendingUp( const double &buffer1[], // First Buffer const double &buffer2[] // Seccend Buffer ) { // bool result = false; // int buffer1Count = ArraySize(buffer1); int buffer2Count = ArraySize(buffer2); if (buffer1Count <= 0 || buffer2Count <= 0) { return result; } // int count = MathMin(buffer1Count, buffer2Count); if (count <= 1) { return result; } // int upCounts = 0; int downCounts = 0; double value = MathAbs(buffer1[0] - buffer2[0]); for (int i = 1; i < count; i++) { // double iValue = MathAbs(buffer1[i] - buffer2[i]); // if (value > iValue) { upCounts++; } // if (value < iValue) { downCounts++; } } // result = upCounts > 1 && upCounts > downCounts; // return result; } // bool IsTrendingDown( const double &buffer1[], // First Buffer const double &buffer2[] // Seccend Buffer ) { // bool result = false; // int buffer1Count = ArraySize(buffer1); int buffer2Count = ArraySize(buffer2); if (buffer1Count <= 0 || buffer2Count <= 0) { return result; } // int count = MathMin(buffer1Count, buffer2Count); if (count <= 1) { return result; } // int upCounts = 0; int downCounts = 0; double value = MathAbs(buffer1[0] - buffer2[0]); for (int i = 1; i < count; i++) { // double iValue = MathAbs(buffer1[i] - buffer2[i]); // if (value > iValue) { upCounts++; } // if (value < iValue) { downCounts++; } } // result = downCounts > 1 && downCounts > upCounts; // return result; } // // Calculate Slope of Specified Buffer at Specified Index ... double GetSlope( const double &buffer[], // Buffer int from, // In Past Index ... int to // In Past Index ... ) { // double result = 0; // if (from > ArraySize(buffer) || to > ArraySize(buffer)) { return result; } // double toValue = buffer[to]; double fromValue = buffer[from]; double deltaValue = toValue - fromValue; double deltaTime = from - to; // result = deltaValue / deltaTime; // return result; } // // Calculate Fib Level ... double GetFibonacciLevel( double upPrice, // Upper Bound double downPrice, // Downer Bound double level, // Level Multiplier Factor int direction // From Down to Up < 0, other wise Vice Versa // ) { // double ling = upPrice - downPrice; double pLevel = (ling / 100) * (level * 100); // double result = direction > 0 ? upPrice - pLevel : downPrice + pLevel; // return result; } // // Method 1 // Normalize between 1 and 0 ... template double GetNormalizedValueMethod1( T &buffer[], // Array which required to Normalize int mLength, // Length of Normalization int mStart = 0, // start index int digits = 5 // Normalization Digits ) { // double result = 0; // if (digits <= 5) { digits = 5; } // int bufferSize = ArraySize(buffer); if (!IsValidSize(bufferSize)) { return result; } // // Normalize Count ... NormalizeCount( mStart, mLength, buffer // ); // T max = 0; T min = 0; // if (bufferSize != mLength) { // T tmp[]; Copy( mStart, mLength, buffer, tmp // ); // max = GetMax(tmp); min = GetMin(tmp); } // if (bufferSize == mLength) { // max = GetMax(buffer); min = GetMin(buffer); } // T iValue = buffer[mStart]; // double minMaxDiff = (max - min); if (minMaxDiff <= 0) { return result; } // result = (iValue - min) / minMaxDiff; // result = NormalizeDouble(result, digits); // return result; } // // Method 2 // Normalize Between Specified Upper and Lower ... template double GetNormalizedValueMethod2( T &buffer[], // Array which required to Normalize int mLength, // Length of Normalization int mUpper, // Specified Upper Value int mLower, // Specified Lower Value int mStart = 0, // start index int digits = 5 // Normalization Digits ) { // double result = 0; // if (digits <= 5) { digits = 5; } // int bufferSize = ArraySize(buffer); if (!IsValidSize(bufferSize)) { return result; } // // Normalize Count ... NormalizeCount( mStart, mLength, buffer // ); // T max = 0; T min = 0; // if (bufferSize != mLength) { // T tmp[]; Copy( mStart, mLength, buffer, tmp // ); // max = GetMax(tmp); min = GetMin(tmp); } // if (bufferSize == mLength) { // max = GetMax(buffer); min = GetMin(buffer); } // T iValue = buffer[mStart]; // double minMaxDiff = (max - min); double boundaryDiff = (mUpper - mLower); if (minMaxDiff <= 0 || boundaryDiff <= 0) { return result; } // result = boundaryDiff / (minMaxDiff * (iValue - max) + max); // result = NormalizeDouble(result, digits); // return result; } // // Templates ... // // Retrieve Specific Object Types Name ... template string GetTypeName(const T &t) { return typename(T); } // template string GetToken(T &item) { // string mType = GetTypeName(item); // string result = mType; // string parts[]; int partsCount = SplitContent( parts, result, " " // ); if (partsCount <= 0) { // result = mType; return result; } // bool hasLastPart = GetLastItem( result, parts // ); if (!hasLastPart) { // result = mType; return result; } // return result; } // // Same as Get Token for Use in Classes ... template string GetSpecificToken(T &item) { // string mType = GetTypeName(item); // string result = mType; // string parts[]; int partsCount = SplitContent( parts, result, " " // ); if (partsCount <= 0) { // result = mType; return result; } // bool hasLastPart = GetLastItem( result, parts // ); if (!hasLastPart) { // result = mType; return result; } // return result; } // // Generate Unique Tags ... template string GenerateTag(T &model) { // string result = ""; // string tag = model.ToString(); if (StringLen(tag) == 0) { return result; } // static XSCMD5 md5; // result = md5.Hash(tag); // return result; } // // Hash Specified Content ... template string ToMD5(T content) { // string result = ""; // string strContent = ToString(content); if (StringLen(strContent) == 0) { return result; } // static XSCMD5 md5; // result = md5.Hash(strContent); // return result; } // // Check a Value Not Empty ... template bool NotEmpty(T value) { return value != EMPTY_VALUE; } // // Add Specified Item to Array ... template int Add( T item, // item want to add T &buffer[] // Destination buffer ) { // int result = 0; // ArrayResize( buffer, ArraySize(buffer) + 1); // buffer[ArraySize(buffer) - 1] = item; // result = ArraySize(buffer); // return result; } template int AddSpecific( T item, // item want to add T &buffer[] // Destination buffer ) { // return Add( item, buffer // ); } template int AddRef( T &item, // item want to add T &buffer[] // Destination buffer ) { // int result = 0; // ArrayResize( buffer, ArraySize(buffer) + 1); // buffer[ArraySize(buffer) - 1] = item; // result = ArraySize(buffer); // return result; } // // Remove Specified Item from an Array ... template bool Remove( T item, T &buffer[]) { // bool result = false; // int itemIndex = FindIndex( item, buffer); if (itemIndex < 0) { return result; } // result = ArrayRemove( buffer, itemIndex, 1); // return result; } // // Clean Specified Array ... template void Clean(T &buffer[]) { // ArrayFree(buffer); ArrayResize(buffer, 0); } // // Copy Whole Content of Source to Dest array ... template void Copy( T &source[], // Source Buffer ... T &dest[], // Dest Buffer ... bool cleanDest = true // Force Clen Dest Buffer ... ) { // if (cleanDest) { Clean(dest); } // int sourceCount = ArraySize(source); if (sourceCount <= 0) { return; } // for (int i = 0; i < sourceCount; i++) { // T iSource = source[i]; // AddRef( iSource, dest); } } // // Copy Items from a Buffer ... template int Copy( int start, // Start int count, // Number of Items for read T &source[], // Source Buffer T &dest[], // Dest Buffer bool forceClean = true // Force To Clean buffer ) { // int result = 0; // if (forceClean) { Clean(dest); } // if (start < 0) { start = 0; } // if (start >= ArraySize(source)) { start = ArraySize(source) - 1; } // if (count == 0) { count = ArraySize(source) - 1 - start; } // if (start + count > ArraySize(source)) { return result; } // int beforeSize = ArraySize(dest); // bool asSeriesDest = ArrayGetAsSeries(dest); bool asSeriesSource = ArrayGetAsSeries(source); // ArraySetAsSeries(dest, true); ArraySetAsSeries(source, true); // ArrayCopy( dest, source, 0, start, count // ); // int afterSize = ArraySize(dest); // result = afterSize - beforeSize; // ArraySetAsSeries(dest, asSeriesDest); ArraySetAsSeries(source, asSeriesSource); // return result; } // // Copy Items from a Buffer ... template int CopyRef( int start, // Start int count, // Number of Items for read T &source[], // Source Buffer T &dest[], // Dest Buffer bool forceClean = true // Force To Clean buffer ) { // int result = 0; // if (forceClean) { Clean(dest); } // if (start < 0) { start = 0; } // if (start >= ArraySize(source)) { start = ArraySize(source) - 1; } // int beforeSize = ArraySize(dest); // bool asSeriesDest = ArrayGetAsSeries(dest); bool asSeriesSource = ArrayGetAsSeries(source); // ArraySetAsSeries(dest, true); ArraySetAsSeries(source, true); // for (int i = start; i < start + count; i++) { // AddRef( source[i], dest // ); } // int afterSize = ArraySize(dest); // result = afterSize - beforeSize; // ArraySetAsSeries(dest, asSeriesDest); ArraySetAsSeries(source, asSeriesSource); // return result; } // // Retrive Last Item of Specified Buffer ... template bool GetLastItem( T &item, // Holds Result T &buffer[] // Specified Buffer ) { // bool result = false; // int bufferSize = ArraySize(buffer); if (bufferSize <= 0) { return result; } // item = buffer[bufferSize - 1]; // result = true; return result; } // // Search Array For Specific Item ... template int FindIndex( T item, // What is Search ... T &buffer[] // Search in ... ) { // int result = -1; // int count = ArraySize(buffer); if (count <= 0) { return result; } // for (int i = 0; i < count; i++) { // T iT = buffer[i]; // if (iT == item) { // result = i; break; } } // return result; } // // Check an Array Contains Specified Value ... template bool Contains( T item, // What is Search ... T &buffer[] // Search in ... ) { // bool result = false; // int idx = FindIndex( item, buffer); result = idx > -1; // return result; } // // Calculate a Buffer's Average ... template double GetAverage( T &buffer[], // the Buffer which required to search int start = 0, // Start Index int count = 0 // Count for Search ) { // double result = 0; // T tmp[]; int tmpCount = Copy( start, count, buffer, tmp // ); if (tmpCount <= 0) { return result; } // // Calculate Summary ... for (int i = 0; i < tmpCount; i++) { result += buffer[i]; } // // Calculate Average ... result = result / tmpCount; // return result; } // // Get Max of Specific Loopback of a Buffer ... template double GetMax( T &buffer[], // the Buffer which required to search int start = 0, // Start Index int count = 0 // Count for Search ) { // double result = 0; // if (count <= 0) { count = ArraySize(buffer); } // T tmp[]; int tmpCount = Copy( start, count, buffer, tmp // ); if (tmpCount <= 0) { return result; } // // Loop Through LoopBack ... for (int i = 0; i < tmpCount; i++) { // double iValue = tmp[i]; // result = // result == 0 || result < iValue // ? iValue // : result // ; } // return result; } // // Get Min of Specific Loopback of a Buffer ... template double GetMin( T &buffer[], // the Buffer which required to search int start = 0, // Start Index int count = 0 // Count for Search ) { // double result = 0; // if (count <= 0) { count = ArraySize(buffer); } // T tmp[]; int tmpCount = Copy( start, count, buffer, tmp // ); if (tmpCount <= 0) { return result; } // // Loop Through LoopBack ... for (int i = 0; i < tmpCount; i++) { // double iValue = tmp[i]; // result = // result == 0 || result > iValue // ? iValue // : result // ; } // return result; } // // Find a Value less than Specified ... template T FindLesserThan( T value, // Specified Value ... const T &source[], // Source ... bool isDescend = false // Find Biggest Lesser Value ... ) { // T result = -1; // int itemsCount = ArraySize(source); if (itemsCount <= 0) { return result; } // // Make a Copy of source ... T tmp[]; // ArrayResize( tmp, ArraySize(source)); // ArrayCopy( tmp, source); // // Sort Temp Buffer ... ArraySort(tmp); if (isDescend) { ArrayReverse(tmp); } // int tmpCount = ArraySize(tmp); for (int i = 0; i < tmpCount; i++) { // T iValue = tmp[i]; // if (iValue < value) { // result = iValue; break; } } // return result; } // // Find a Value less than Specified ... template T FindBiggerThan( T value, // Specified Value ... const T &source[], // Source ... bool isDescend = false // Find Smallest Bigger Value ... ) { // T result = -1; // int itemsCount = ArraySize(source); if (itemsCount <= 0) { return result; } // // Make a Copy of source ... T tmp[]; // ArrayResize( tmp, ArraySize(source)); // ArrayCopy( tmp, source); // // Sort Temp Buffer ... ArraySort(tmp); if (!isDescend) { ArrayReverse(tmp); } // int tmpCount = ArraySize(tmp); for (int i = 0; i < tmpCount; i++) { // T iValue = tmp[i]; // if (iValue > value) { // result = iValue; break; } } // return result; } // // Find Same Values in Array ... template void FindSames( T &result[], // Holds Result ... T &source[], // Source ... int verifications = 3 // Number of Consequence Repeat ... ) { // Clean(result); // // TenkanSen Flats ... int sourceCount = ArraySize(source); if (sourceCount > verifications) { // T mLast = 0; int mVerified = 0; for (int i = 0; i < sourceCount; i++) { // T iVal = source[i]; if (mLast == 0) { mLast = iVal; } else if (mLast == iVal) { mVerified++; } else { mLast = iVal; mVerified = 0; } // if (iVal == mLast && mVerified >= verifications) { // Add( iVal, result); // mLast = 0; mVerified = 0; } } } } // // Add an Item to a Buffer if not Exists ... void AddIfNotExists( double value, double &values[], double smoothingPoint = 3) { // double smoothingValue = smoothingPoint * GetPoints(_Symbol); // int valuesCount = ArraySize(values); if (valuesCount <= 0) { // Add(value, values); } else { // bool isExists = false; for (int i = 0; i < valuesCount; i++) { // double iVal = values[i]; // double diff = MathAbs(iVal - value); // if (iVal == value || diff < smoothingValue) { // isExists = true; break; } } // if (!isExists) { // Add(value, values); } } } // // Add a Buffers Child to another Buffer // if it's not Contains them ... void AddsIfNotExists( double &source[], double &dest[], double smoothingPoint = 3) { // double smoothingValue = smoothingPoint * GetPoints(_Symbol); // int sourceCount = ArraySize(source); if (sourceCount <= 0) { return; } // for (int i = 0; i < sourceCount; i++) { // double iSource = source[i]; // AddIfNotExists( iSource, dest, smoothingPoint); } } // // Bar XOHCL ... // // Extract Specific Range of Bars ... // using Start Bar Index ... int GetBars( XOHCL &result[], // Hold Result string mSymbol = NULL, // Trading Symbol ENUM_TIMEFRAMES mPeriod = NULL, // Trading Time Frame int from = 0, // Start Bar Index int count = 1, // Number of Bars bool forceClean = true // Clean Result Array ) { // int mResult = 0; // if (from < 0) { from = 0; } // mSymbol = NormalizeSymbol(mSymbol); mPeriod = NormalizePeriod(mPeriod); // int total = Bars( mSymbol, mPeriod); if (from > total - 2) { from = total - 2; } // if (count < 0) { count = 1; } // int start = from; int end = start + count; if (end > total - 1) { end = total - 1; } // if (forceClean) { Clean(result); } // int beforeSize = ArraySize(result); // for (int i = start; i < end; i++) { // XOHCL iBar; bool isValid = iBar.Init( mSymbol, mPeriod, i // ); // if (isValid) { // AddRef( iBar, result // ); } } // int afterSize = ArraySize(result); // mResult = afterSize - beforeSize; // return mResult; } // // Extract Specific Range of Bars ... // using Start Bar Time ... int GetBars( XOHCL &result[], // Hold Result string mSymbol = NULL, // Trading Symbol ENUM_TIMEFRAMES mPeriod = NULL, // Trading Time Frame datetime from = NULL, // Start Bar Time int count = 1, // Number of Bars bool forceClean = true // Clean Result Array ) { // mSymbol = NormalizeSymbol(mSymbol); mPeriod = NormalizePeriod(mPeriod); // from = NormalizeTime(from); // int barIndex = iBarShift( mSymbol, mPeriod, from, false // ); // return GetBars( result, mSymbol, mPeriod, barIndex, count, forceClean // ); } // // String ... // // Search a Content Contains Specific String or not ... bool Contains( string mQuery, // Search String string mContent, // Search Content bool ignoreCase = true // Ignore Case ) { // bool result = false; // // Validate Query ... result = IsValid(mQuery); if (!result) { return result; } // // Validate Content ... result = IsValid(mContent); if (!result) { return result; } // // Normalize Inputs ... string query = mQuery; string content = mContent; if (ignoreCase) { // StringToLower(query); StringToLower(content); } // int queryIdx = StringFind( content, query); // result = queryIdx >= 0; // return result; } // bool Contains( string &mQueries[], // Search Strings string mContent, // Search Content bool ignoreCase = true // Ignore Case ) { // bool result = false; // // Validate Queries ... int queriesCount = ArraySize(mQueries); result = queriesCount > 0; if (!result) { return result; } // // Validate Content ... result = IsValid(mContent); if (!result) { return result; } // int containsCount = 0; for (int i = 0; i < queriesCount; i++) { // bool isContains = Contains( mQueries[i], mContent, ignoreCase); // if (!isContains) { // result = false; break; } // containsCount++; } // result = containsCount == queriesCount; // return result; } // // Convert From String ... template T FromString(string value) { // T result = NULL; // if (!IsValid(value)) { return result; } // result = (T)value; // return result; } // // Converts an item to String ... template string ToString(T value) { return (string)value; } // // Used In Report or Summary Generators ... string ToString( string prefix, // Title bool value, // Value bool ignoreFalseConditions = true, // Ignore False Conditions string lineSeparator = "\n", // Line Separator string prefixSeparator = ":" // Title Separator ) { // string result = NULL; // result = (value || !ignoreFalseConditions) ? prefix + prefixSeparator + " " + ToString(value) + lineSeparator : ""; // return result; } // string SetLabel( string mLabel, // Provided Label ... string value, // Source Value ... string separator = "\n", // Line Separator bool addTopEmptyLine = true // Add Empty Line On top ) { // string result = value; // if (StringLen(mLabel) <= 0) { return result; } // result = (StringLen(value) > 0) ? (addTopEmptyLine ? separator : "") + mLabel + separator + "-----------------------------" + separator + value : value; // return result; } // // Converts a Buffer to String Representation ... template string ToString( const T &buffer[], // Specified Buffer string separator = ",", // Specified Separator bool addIndex = false, // Specified Add Items Indexes or Not string indexLabel = "i:", // Specified Index Label string indexSeparator = ">" // Specified Index Separator ) { // string result = ""; // int bufferSize = ArraySize(buffer); if (bufferSize <= 0) { return result; } // for (int i = 0; i < bufferSize; i++) { // if (addIndex) { // if (StringLen(indexLabel) > 0) { result += indexLabel + " "; } // result += (string)i + " "; // if (StringLen(indexSeparator) > 0) { result += indexSeparator + " "; } } // string iItemString = (string)buffer[i]; // result += iItemString; // if (i < bufferSize - 1) { result += separator; } } // return result; } // // Converts String to boolean ... bool ToBoolean(string value) { // bool result = false; // if (StringLen(value) <= 0) { return result; } // StringToLower(value); result = value == "true"; // return result; } // // Split an String Representation of an Array ... int SplitContent( string &result[], // Hold Result ... string content, // Source ... string separator = ",", // Separator ... bool forceCleanResult = true // Clean Result ... ) { // int mResult = 0; // if (forceCleanResult) { Clean(result); } // int before = ArraySize(result); // if (separator == NULL || StringLen(separator) == 0) { separator = ","; } // if (StringLen(content) == 0) { return mResult; } // StringSplit( content, StringGetCharacter( separator, 0), result); // int after = ArraySize(result); // mResult = after - before; // return mResult; } // // Extract Data from String ... string ExtractString( const string source, // Source String used for Extracting const string startString = "(", // Expression Start String must be Unique const string endString = ")" // Where to End Extraction, usually a Sign ) { // string result = ""; // // Validate String ... if ( StringLen(source) == 0 || StringLen(endString) == 0 || StringLen(startString) == 0) { return result; } // // Find Start String Position ... int sPos = StringFind( source, startString); if (sPos < 0) { return result; } // // Find End String Position after Start String ... int searchEndFromPos = sPos + StringLen(startString); int ePos = StringFind( source, endString, searchEndFromPos); if (ePos < 0) { return result; } // // Extract Data from Source ... int dLength = ePos - searchEndFromPos; result = StringSubstr( source, searchEndFromPos, dLength); // return result; } // // Extract an Array of Contents ... int ExtractStrings( string &result[], // Hold Result const string source, // Source String used for Extracting const string startString = "(", // Expression Start String must be Unique const string endString = ")" // Where to End Extraction, usually a Sign ) { // int mResult = 0; // Clean(result); // // Validate Args ... int sourceLength = StringLen(source); int startLength = StringLen(startString); int endLength = StringLen(endString); // int minRequiredLength = startLength + endLength; // if ( endLength <= 0 || startLength <= 0 || sourceLength <= 0 || sourceLength < minRequiredLength) { return mResult; } // // Make a Copy of Source for Manipulating ... string workStr = source; // // Define a Loop ... while (StringLen(workStr) > minRequiredLength) { // // Find Item ... string item = ExtractString( workStr, startString, endString); // // Breakout when couldn't find anymore item ... int itemLength = StringLen(item); if (itemLength <= 0) { break; } // // Prepare Item Source String for Replacing in Work String ... string itemSource = startString + item + endString; // // Add Item to Result Array ... Add( item, result); // // Replace Item Soure in Work String ... StringReplace( workStr, itemSource, ""); } // // Calculate Size of Array ... mResult = ArraySize(result); // return mResult; } // string ExtractSurrounded( const string surrounded, // Surrounded Content const string mToken, // Specified Token const string startString = "(", // Expression Start String must be Unique const string endString = ")" // Where to End Extraction, usually a Sign ) { // return ExtractString( surrounded, mToken + startString, endString // ); } // int ParseIntSurrounded( const string surrounded, // Surrounded Content const string mToken, // Specified Token const string startString = "(", // Expression Start String must be Unique const string endString = ")" // Where to End Extraction, usually a Sign ) { // int result = NULL; // string strContent = ExtractSurrounded( surrounded, mToken, startString, endString // ); if (!IsValid(strContent)) { return result; } // result = (int)strContent; // return result; } long ParseLongSurrounded( const string surrounded, // Surrounded Content const string mToken, // Specified Token const string startString = "(", // Expression Start String must be Unique const string endString = ")" // Where to End Extraction, usually a Sign ) { // long result = NULL; // string strContent = ExtractSurrounded( surrounded, mToken, startString, endString // ); if (!IsValid(strContent)) { return result; } // result = (long)strContent; // return result; } string ParseStringSurrounded( const string surrounded, // Surrounded Content const string mToken, // Specified Token const string startString = "(", // Expression Start String must be Unique const string endString = ")" // Where to End Extraction, usually a Sign ) { // string result = NULL; // string strContent = ExtractSurrounded( surrounded, mToken, startString, endString // ); if (!IsValid(strContent)) { return result; } // result = (string)strContent; // return result; } double ParseDoubleSurrounded( const string surrounded, // Surrounded Content const string mToken, // Specified Token const string startString = "(", // Expression Start String must be Unique const string endString = ")" // Where to End Extraction, usually a Sign ) { // double result = NULL; // string strContent = ExtractSurrounded( surrounded, mToken, startString, endString // ); if (!IsValid(strContent)) { return result; } // result = (double)strContent; // return result; } datetime ParseTimeSurrounded( const string surrounded, // Surrounded Content const string mToken, // Specified Token const string startString = "(", // Expression Start String must be Unique const string endString = ")" // Where to End Extraction, usually a Sign ) { // datetime result = NULL; // string strContent = ExtractSurrounded( surrounded, mToken, startString, endString // ); if (!IsValid(strContent)) { return result; } // result = (datetime)strContent; // return result; } // int ParseIntArraySurrounded( int &result[], // Holds Result const string surrounded, // Surrounded Content const string mToken, // Specified Token string separator = ",", // Separator ... const string startString = "(", // Expression Start String must be Unique const string endString = ")", // Where to End Extraction, usually a Sign bool forceClean = true // Clean Result ... ) { // int count = 0; // if (forceClean) { Clean(result); } // int before = ArraySize(result); // string contentStr = ParseStringSurrounded(surrounded, mToken); if (!IsValid(contentStr)) { return count; } // string tmps[]; int tmpsCount = SplitContent( tmps, contentStr // ); if (tmpsCount <= 0) { return count; } // for (int i = 0; i < tmpsCount; i++) { // string iTMP = tmps[i]; if (!IsValid(iTMP)) { continue; } // int iValue = (int)iTMP; // Add( iValue, result // ); } // int after = ArraySize(result); // count = after - before; // return count; } int ParseLongArraySurrounded( long &result[], // Holds Result const string surrounded, // Surrounded Content const string mToken, // Specified Token string separator = ",", // Separator ... const string startString = "(", // Expression Start String must be Unique const string endString = ")", // Where to End Extraction, usually a Sign bool forceClean = true // Clean Result ... ) { // int count = 0; // if (forceClean) { Clean(result); } // int before = ArraySize(result); // string contentStr = ParseStringSurrounded(surrounded, mToken); if (!IsValid(contentStr)) { return count; } // string tmps[]; int tmpsCount = SplitContent( tmps, contentStr // ); if (tmpsCount <= 0) { return count; } // for (int i = 0; i < tmpsCount; i++) { // string iTMP = tmps[i]; if (!IsValid(iTMP)) { continue; } // long iValue = (long)iTMP; // Add( iValue, result // ); } // int after = ArraySize(result); // count = after - before; // return count; } int ParseDoubleArraySurrounded( double &result[], // Holds Result const string surrounded, // Surrounded Content const string mToken, // Specified Token string separator = ",", // Separator ... const string startString = "(", // Expression Start String must be Unique const string endString = ")", // Where to End Extraction, usually a Sign bool forceClean = true // Clean Result ... ) { // int count = 0; // if (forceClean) { Clean(result); } // int before = ArraySize(result); // string contentStr = ParseStringSurrounded(surrounded, mToken); if (!IsValid(contentStr)) { return count; } // string tmps[]; int tmpsCount = SplitContent( tmps, contentStr // ); if (tmpsCount <= 0) { return count; } // for (int i = 0; i < tmpsCount; i++) { // string iTMP = tmps[i]; if (!IsValid(iTMP)) { continue; } // double iValue = (double)iTMP; // Add( iValue, result // ); } // int after = ArraySize(result); // count = after - before; // return count; } int ParseTimeArraySurrounded( datetime &result[], // Holds Result const string surrounded, // Surrounded Content const string mToken, // Specified Token string separator = ",", // Separator ... const string startString = "(", // Expression Start String must be Unique const string endString = ")", // Where to End Extraction, usually a Sign bool forceClean = true // Clean Result ... ) { // int count = 0; // if (forceClean) { Clean(result); } // int before = ArraySize(result); // string contentStr = ParseStringSurrounded(surrounded, mToken); if (!IsValid(contentStr)) { return count; } // string tmps[]; int tmpsCount = SplitContent( tmps, contentStr // ); if (tmpsCount <= 0) { return count; } // for (int i = 0; i < tmpsCount; i++) { // string iTMP = tmps[i]; if (!IsValid(iTMP)) { continue; } // datetime iValue = (datetime)iTMP; // Add( iValue, result // ); } // int after = ArraySize(result); // count = after - before; // return count; } // // Surround an String by Specific Token ... template string Surround( string mToken, // an String which used to Tokenize T &value, // a Value for Tokenize it string startString = "(", // Token Start Content string endString = ")" // Token End Content ) { // string result = NULL; // string strValue = ToString(value); if (!IsValid(strValue)) { return result; } // result = // (IsValid(mToken) ? mToken : "") + // startString + strValue + endString // ; // return result; } // template string SurroundArray( string mToken, T &value[], string startString = "(", // Token Start Content string endString = ")" // Token End Content ) { // string result = NULL; // string valueStr = ToString(value); if (!IsValid(valueStr)) { return result; } // result = Surround( mToken, valueStr, startString, endString // ); // return result; } // // Periods / Cycles ... // // Converts an String to TimeFrame ... ENUM_TIMEFRAMES ToPeriod(string value) { // if (StringLen(value) == 0) { return _Period; } // StringTrimLeft(value); StringTrimRight(value); // ENUM_TIMEFRAMES result = _Period; // if (value == "M1") { result = PERIOD_M1; } else if (value == "M2") { result = PERIOD_M2; } else if (value == "M3") { result = PERIOD_M3; } else if (value == "M4") { result = PERIOD_M4; } else if (value == "M5") { result = PERIOD_M5; } else if (value == "M6") { result = PERIOD_M6; } else if (value == "M10") { result = PERIOD_M10; } else if (value == "M12") { result = PERIOD_M12; } else if (value == "M15") { result = PERIOD_M15; } else if (value == "M20") { result = PERIOD_M20; } else if (value == "M30") { result = PERIOD_M30; } else if (value == "H1") { result = PERIOD_H1; } else if (value == "H2") { result = PERIOD_H2; } else if (value == "H3") { result = PERIOD_H3; } else if (value == "H4") { result = PERIOD_H4; } else if (value == "H6") { result = PERIOD_H6; } else if (value == "H8") { result = PERIOD_H8; } else if (value == "H12") { result = PERIOD_H12; } else if (value == "D1") { result = PERIOD_D1; } else if (value == "W1") { result = PERIOD_W1; } else if (value == "MN1") { result = PERIOD_MN1; } // return result; } // // Converts Period to String ... string ToString(ENUM_TIMEFRAMES mPeriod) { // string result = ""; // string mPStr = EnumToString(mPeriod); string mPStrParts[]; int partsCount = StringSplit( mPStr, StringGetCharacter("_", 0), mPStrParts); if (partsCount <= 0) { return result; } // result = mPStrParts[1]; // return result; } // // Retrieve All Available Period as an Array ...s int GetAllAvailablePeriods( ENUM_TIMEFRAMES &result[] // Holds Result ... ) { // Clean(result); // Add( PERIOD_M1, result // ); // Add( PERIOD_M2, result // ); // Add( PERIOD_M3, result // ); // Add( PERIOD_M4, result // ); // Add( PERIOD_M5, result // ); // Add( PERIOD_M6, result // ); // Add( PERIOD_M10, result // ); // Add( PERIOD_M12, result // ); // Add( PERIOD_M15, result // ); // Add( PERIOD_M20, result // ); // Add( PERIOD_M30, result // ); // Add( PERIOD_H1, result // ); // Add( PERIOD_H2, result // ); // Add( PERIOD_H3, result // ); // Add( PERIOD_H4, result // ); // Add( PERIOD_H6, result // ); // Add( PERIOD_H8, result // ); // Add( PERIOD_H12, result // ); // Add( PERIOD_D1, result // ); // Add( PERIOD_W1, result // ); // Add( PERIOD_MN1, result // ); // int mResult = ArraySize(result); // return mResult; } // // Get Specific Time Frame Start Candle Time ... datetime GetPeriodStartTime( string mSymbol = NULL, // Specified Symbol ... ENUM_TIMEFRAMES mPeriod = NULL, // Specified Period ... datetime mTime = NULL // Specified Bar Time of Host Period ... ) { // // Normalize Arg ... mTime = NormalizeTime(mTime); mSymbol = NormalizeSymbol(mSymbol); mPeriod = NormalizePeriod(mPeriod); // int barIndex = iBarShift( mSymbol, mPeriod, mTime, false // ); // datetime result = GetBarTime( mSymbol, mPeriod, barIndex // ); // return result; } // // Converts an String to it's related Market Cycle ... ENUM_X_MARKET_CYCLES ToCycle(string value) { // ENUM_X_MARKET_CYCLES result = X_MARKET_CYCLE_UNKNOWN; // ENUM_X_MARKET_CYCLES cycles[]; int count = GetAllMarketCycles(cycles); for (int i = 0; i < count; i++) { // ENUM_X_MARKET_CYCLES iCycle = cycles[i]; string iStr = ToString(iCycle); // if (value == iStr) { // result = iCycle; break; } } // return result; } // // Converts a Cycle to it's String Representation ... string ToString(ENUM_X_MARKET_CYCLES cycle) { // string result = ""; // string mPStr = EnumToString(cycle); string mPStrParts[]; int partsCount = StringSplit( mPStr, StringGetCharacter("_", 0), mPStrParts); if (partsCount <= 0) { return result; } // result = mPStrParts[3]; // return result; } // // Retrieve all Available Cycles ... int GetAllMarketCycles(ENUM_X_MARKET_CYCLES &result[]) { // int mResult = 0; // Clean(result); // ENUM_X_MARKET_CYCLES tmp[] = { X_MARKET_CYCLE_UNKNOWN, X_MARKET_CYCLE_SHORT, X_MARKET_CYCLE_MEDIUM, X_MARKET_CYCLE_LONG, X_MARKET_CYCLE_HIND}; // Copy( tmp, result); // Clean(tmp); // mResult = ArraySize(result); // return mResult; } // // Retrieve Nearest Period base on Given Period ... ENUM_TIMEFRAMES GetNearestPeriod(ENUM_TIMEFRAMES mPeriod) { // ENUM_TIMEFRAMES result = _Period; // mPeriod = NormalizePeriod(mPeriod); // switch (mPeriod) { // case PERIOD_M1: case PERIOD_M2: result = PERIOD_M4; break; // case PERIOD_M3: case PERIOD_M4: result = PERIOD_M6; break; // case PERIOD_M5: case PERIOD_M6: case PERIOD_M10: case PERIOD_M12: result = PERIOD_M15; break; // case PERIOD_M15: case PERIOD_M20: result = PERIOD_M30; break; // case PERIOD_H1: case PERIOD_H2: case PERIOD_H3: result = PERIOD_H4; break; // case PERIOD_H6: case PERIOD_H8: result = PERIOD_H12; break; // case PERIOD_H12: result = PERIOD_D1; break; // case PERIOD_D1: result = PERIOD_W1; break; // default: result = PERIOD_MN1; break; } // return result; } // // Retrieve Mediest Period base on Given Period ... ENUM_TIMEFRAMES GetMediestPeriod(ENUM_TIMEFRAMES mPeriod) { // ENUM_TIMEFRAMES result = _Period; // mPeriod = NormalizePeriod(mPeriod); // switch (mPeriod) { // case PERIOD_M1: case PERIOD_M2: result = PERIOD_M15; break; // case PERIOD_M3: case PERIOD_M4: result = PERIOD_M30; break; // case PERIOD_M5: case PERIOD_M6: case PERIOD_M10: case PERIOD_M12: result = PERIOD_H1; break; // case PERIOD_M15: case PERIOD_M20: result = PERIOD_H2; break; // case PERIOD_H1: case PERIOD_H2: case PERIOD_H3: result = PERIOD_H8; break; // case PERIOD_H6: case PERIOD_H8: result = PERIOD_D1; break; // case PERIOD_H12: result = PERIOD_W1; break; // case PERIOD_D1: result = PERIOD_MN1; break; // default: result = PERIOD_MN1; break; } // return result; } // // Retrieve Longest Period base on Given Period ... ENUM_TIMEFRAMES GetLongestPeriod(ENUM_TIMEFRAMES mPeriod) { // ENUM_TIMEFRAMES result = _Period; // mPeriod = NormalizePeriod(mPeriod); // switch (mPeriod) { // case PERIOD_M1: case PERIOD_M2: result = PERIOD_M30; break; // case PERIOD_M3: case PERIOD_M4: result = PERIOD_H1; break; // case PERIOD_M5: case PERIOD_M6: case PERIOD_M10: case PERIOD_M12: result = PERIOD_H2; break; // case PERIOD_M15: case PERIOD_M20: result = PERIOD_H4; break; // case PERIOD_H1: case PERIOD_H2: case PERIOD_H3: result = PERIOD_H12; break; // case PERIOD_H6: case PERIOD_H8: result = PERIOD_W1; break; // case PERIOD_H12: result = PERIOD_MN1; break; // case PERIOD_D1: result = PERIOD_MN1; break; // default: result = PERIOD_MN1; break; } // return result; } // // Retrieve Hindmost Period base on Given Period ... ENUM_TIMEFRAMES GetHindMostPeriod(ENUM_TIMEFRAMES mPeriod) { // ENUM_TIMEFRAMES result = _Period; // mPeriod = NormalizePeriod(mPeriod); // switch (mPeriod) { // case PERIOD_M1: case PERIOD_M2: result = PERIOD_H1; break; // case PERIOD_M3: case PERIOD_M4: result = PERIOD_H2; break; // case PERIOD_M5: case PERIOD_M6: case PERIOD_M10: case PERIOD_M12: result = PERIOD_H4; break; // case PERIOD_M15: case PERIOD_M20: result = PERIOD_H8; break; // case PERIOD_H1: case PERIOD_H2: case PERIOD_H3: result = PERIOD_D1; break; // case PERIOD_H6: case PERIOD_H8: result = PERIOD_MN1; break; // case PERIOD_H12: result = PERIOD_MN1; break; // case PERIOD_D1: result = PERIOD_MN1; break; // default: result = PERIOD_MN1; break; } // return result; } // // Retrieve Specified Cycles Period related to Host Period ... ENUM_TIMEFRAMES GetCyclePeriod( ENUM_X_MARKET_CYCLES mCycle = NULL, // Specified Cycle ENUM_TIMEFRAMES mPeriod = NULL // Host Period ) { // ENUM_TIMEFRAMES result = NULL; // mPeriod = NormalizePeriod(mPeriod); mCycle = NormalizeCycle(mCycle); // switch (mCycle) { // // Short ... case X_MARKET_CYCLE_SHORT: result = GetNearestPeriod(mPeriod); break; // // Medium ... case X_MARKET_CYCLE_MEDIUM: result = GetMediestPeriod(mPeriod); break; // // Long ... case X_MARKET_CYCLE_LONG: result = GetLongestPeriod(mPeriod); break; // // Hind ... case X_MARKET_CYCLE_HIND: result = GetHindMostPeriod(mPeriod); break; } // return result; }