/////////////////////////////////////////////////////// // // 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 ... // // 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; } // // 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 (mPType == NULL) { mPType = X_PRICE_CLOSE; } // 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; } // // Calculate Applied Price ... double GetPrice( ENUM_APPLIED_PRICE appliedTo // Select Application Method ) { // double result = 0; // // Calculate Applied Price ... switch (appliedTo) { // 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; } // // 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; } // // 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 mode = swing == X_SWING_HIGH ? MODE_HIGH : MODE_LOW; // result = swing == X_SWING_HIGH ? iHighest( symbol, period, mode, mLength, from) : iLowest( symbol, period, mode, mLength, from); // return result; } // // Find Lowest Bar Index ... int FindHighestIndex( int mLength, // Loopback ... ENUM_SERIESMODE mode // Calculation mode ) { // int result = -1; // if (!IsValid()) { return result; } // if (mLength < 2) { mLength = 2; } // result = iHighest( symbol, period, mode, mLength, Index()); // return result; } // // Find Lowest ... double FindHighest( int mLength, // Loopback ... ENUM_SERIESMODE mode // Calculation mode ) { // double result = 0; // if (!IsValid()) { return result; } // int idx = FindHighestIndex( mLength, mode); if (idx <= -1) { return result; } // ENUM_X_PRICE pMode = ToPrice(mode); // XOHCL iH; result = iH.Init( symbol, period, idx // ); if (!result) { return result; } // result = iH.GetPrice(pMode); // return result; } // // Find Lowest Bar Index ... int FindLowestIndex( int mLength, // Loopback ... ENUM_SERIESMODE mode // Calculation mode ) { // int result = -1; // if (!IsValid()) { return result; } // if (mLength < 2) { mLength = 2; } // result = iLowest( symbol, period, mode, mLength, Index()); // return result; } // // Find Lowest ... double FindLowest( int mLength, // Loopback ... ENUM_SERIESMODE mode // Calculation mode ) { // double result = 0; // if (!IsValid()) { return result; } // int idx = FindLowestIndex( mLength, mode); if (idx <= -1) { return result; } // ENUM_X_PRICE pMode = ToPrice(mode); // XOHCL iL; result = iL.Init( symbol, period, idx // ); if (!result) { return result; } // result = iL.GetPrice(pMode); // 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; } }; // // 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; } // // 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; } // // 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; } // // 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; } }; // // 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; } // // 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; } // // 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; } // // 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; } // // Check Expert Running in Testing Mode or not ... bool IsRunningOnTestMode() { // bool result = false; // // check programm mode ... result = MQL5InfoInteger(MQL5_TESTING); // 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; } // // 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 mode // Specified Series Mode ... ) { // ENUM_X_PRICE result = X_PRICE_CLOSE; // switch (mode) { // // 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); } // // 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 ... // // 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; } // // 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; } // // Templates ... // // Retrieve Specific Object Types Name ... template string GetTypeName(const T &t) { return typename(T); } // // 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 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; } // 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; } // // 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; // 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 GetMinValue( 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; } // // 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 FindLesserThanValue( 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 FindBiggerThanValue( 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 FindSameValues( 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 ... // // 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; } // // 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; } // // 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; } // // 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; }