// // 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 double priceToRisk = 0, // If Entry equal to Provided SL Price Risk Point double priceToReward = 0 // If Entry equal to Provided TP Price Reward Point ) { // // 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); if (risk == 0) { risk = priceToRisk; } reward = risk * mR2R; } else if (!canCalculateBasedOnSL && canCalculateBasedOnTP) { // reward = MathAbs(mEntry - tpPrice); if (reward == 0) { reward = priceToReward; } 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; } 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 - risk : mEntry + risk; } // bool CalculateTPSLByPoint( double &mSL, // Hold SL double &mTP, // Hold TP ENUM_POSITION_TYPE mType, // Position Type Long (Buy) / Short (Sell) double mEntry, // Entry Price double mPointValue, // Point Value double mR2R = 1, // Provided Risk To Reward Ratio double slPoint = 0, // Provided SL Point double tpPoint = 0 // Provided TP Point ) { // bool result = false; // mSL = 0; mTP = 0; // bool isLong = IsLong(mType); // // Set Default R2R ... if (mR2R < 1) { mR2R = 1; } // if (mEntry <= 0 || mPointValue <= 0 || (slPoint <= 0 && tpPoint <= 0)) { return result; } // double risk = 0; double reward = 0; // bool canCalculateBasedOnSL = slPoint > 0; // bool canCalculateBasedOnTP = tpPoint > 0; // if (!canCalculateBasedOnSL && !canCalculateBasedOnTP) { return result; } // if (canCalculateBasedOnSL && canCalculateBasedOnTP) { // reward = tpPoint * mPointValue; risk = slPoint * mPointValue; } else if (!canCalculateBasedOnSL && canCalculateBasedOnTP) { // reward = tpPoint * mPointValue; risk = reward / mR2R; } else if (canCalculateBasedOnSL && !canCalculateBasedOnTP) { // risk = slPoint * mPointValue; reward = risk * mR2R; } // result = risk > 0 && reward > 0; if (!result) { return result; } // mTP = isLong ? mEntry + reward : mEntry - reward; // mSL = isLong ? mEntry - risk : mEntry + risk; // return result; } // bool CalculateTPSLByPrice( 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 ) { // bool result = false; // bool isLong = IsLong(mType); // // Set Default R2R ... if (mR2R < 1) { mR2R = 1; } // if (mEntry <= 0 || (mSL <= 0 && mTP <= 0)) { return result; } // double risk = 0; double reward = 0; // bool canCalculateBasedOnSL = mSL > 0; bool canCalculateBasedOnTP = mTP > 0; // if ( !canCalculateBasedOnSL && !canCalculateBasedOnTP) { return result; } // if (!canCalculateBasedOnSL && canCalculateBasedOnTP) { // reward = MathAbs(mTP - mEntry); risk = reward / mR2R; } else if (canCalculateBasedOnSL && !canCalculateBasedOnTP) { // risk = MathAbs(mEntry - mSL); reward = risk * mR2R; } // result = risk > 0 && reward > 0; if (!result) { return result; } // mTP = isLong ? mEntry + reward : mEntry - reward; // mSL = isLong ? mEntry - risk : mEntry + risk; // return result; } /** * Calculate Momentum Changes based on Given Price */ double CalculateMomentum( double currentPrice, double previousPrice // ) { // double result = 0; // return result; } /** * Detect Possible Momentum Changes * Using MqlTick ... */ bool DetectMomentumChange( ENUM_POSITION_TYPE type, string mSymbol = NULL, int mLength = 14 // ) { // bool result = false; // mSymbol = NormalizeSymbol(mSymbol); // MqlTick ticks[]; int copied = CopyTicks( mSymbol, ticks, COPY_TICKS_ALL, 0, mLength + 1 // ); // result = copied > mLength; if (!result) { return result; } // double previousPrice = GetTickExit( ticks[mLength], type, mSymbol // ); for (int i = mLength - 1; i >= 0; i--) { // double currentPrice = GetTickExit( ticks[i], type, mSymbol // ); // double momentum = CalculateMomentum( currentPrice, previousPrice // ); // if (fabs(momentum) > 1.0) { // result = true; break; } } // return result; } // // // // // Extension Methods ... // // Find Swing Points ... int FindSwing( string mSymbol, // Trading Symbol ... ENUM_TIMEFRAMES mPeriod, // Trading Period ... ENUM_X_SWING_TYPE mMode, // Swing Based On Price mode ... int mLength, // Loopback ... int bar_index // BarIndex ... ) { // int result = -1; // if (StringLen(mSymbol) == 0 || (mMode != X_SWING_HIGH && mMode != X_SWING_LOW)) { return result; } // int current = bar_index; int founded = FindNextSwing( mSymbol, mPeriod, mMode, (mLength * 2) + 1, current - mLength); // while (founded != current) { // current = FindNextSwing( mSymbol, mPeriod, mMode, mLength, current + 1); // founded = FindNextSwing( mSymbol, mPeriod, mMode, (mLength * 2) + 1, current - mLength); } // result = current; // return result; } // // Find Next Swing ... int FindNextSwing( string mSymbol, // Trading Symbol ... ENUM_TIMEFRAMES mPeriod, // Trading Period ... ENUM_X_SWING_TYPE mMode, // Swing Based On Price mode ... int mLength, // Loopback ... int bar_index // BarIndex ... ) { // int result = -1; // if (bar_index < 0) { mLength += bar_index; bar_index = 0; } // ENUM_SERIESMODE mSeriesMode = ToSeriesMode(mMode); // result = mMode == X_SWING_HIGH ? iHighest( mSymbol, mPeriod, mSeriesMode, mLength, bar_index) : iLowest( mSymbol, mPeriod, mSeriesMode, mLength, bar_index); // return result; } /** * Extract values of swings from specified Collection ... * * @param swings: XSwingPoint instance Collection ... * @param values: double Collection ... * * @return ( int ) */ int ExtractSwings( XSwingPoint &swings[], double &values[] // ) { // int result = 0; // Clean(values); // int count = ArraySize(swings); if (!IsValidSize(count)) { return result; } // for (int i = 0; i < count; i++) { // Add( swings[i].swing, values // ); } // result = ArraySize(values); // return result; } // // Functions ... // // Validators ... // // Validate an String has length and not NULL ... // // Validate a Date ... // // Validate a Period Param ... // // Validate Specific Period Mode ... // // As IS ... // // Normalizers ... // // Prices ... /** * Calculates Price Change Percentage based on * Several Params ... * * @param _symbol: Symbol ... * @param _period: Time Frame ... * @param _from: start Bar Index ... * @param _length: Length of Bars ... * * @return ( double ) */ double GetPriceChanged( string _symbol = NULL, ENUM_TIMEFRAMES _period = NULL, int _from = 0, int _length = 3 // ) { // double result = 0; // NormalizeSymbol(_symbol); NormalizePeriod(_period); // if (_from < 0) { _from = 0; } // if (_length < 2) { _length = 2; } // double closes[]; int copiedCloses = CopyClose( _symbol, _period, _from, _length, closes // ); if (copiedCloses < _length) { return result; } ArrayReverse(closes); // double change = (closes[0] - closes[_length - 1]) / closes[_length - 1] * 100; result = change; // return result; } /** * Retrieve Current Tick ... */ bool GetTick( string mSymbol, MqlTick &tick // ) { return SymbolInfoTick(mSymbol, tick); } /** * Retrieve Tick Entry ... */ double GetTickEntry( MqlTick &mTick, ENUM_POSITION_TYPE type, string mSymbol = NULL // ) { // double result = 0; // mSymbol = NormalizeSymbol(mSymbol); // result = IsLong(type) ? mTick.ask : mTick.bid; result = NormalizePrice(result, mSymbol); // return result; } /** * Retrieve Tick Exit ... */ double GetTickExit( MqlTick &mTick, ENUM_POSITION_TYPE type, string mSymbol = NULL // ) { // double result = 0; // mSymbol = NormalizeSymbol(mSymbol); // result = IsLong(type) ? mTick.bid : mTick.ask; result = NormalizePrice(result, mSymbol); // return result; } // // Fill Specified Applied Prices ... int FillPrice( double &buffer[], ENUM_APPLIED_PRICE _mAppliedTo = PRICE_CLOSE, string _mSymbol = NULL, ENUM_TIMEFRAMES _mPeriod = NULL, int _mStart = 0, int _mLoopback = 10 // ) { // int result = 0; // if (_mStart < 0) { _mStart = 0; } // if (_mLoopback < 1) { _mLoopback = 1; } // _mSymbol = NormalizeSymbol(_mSymbol); _mPeriod = NormalizePeriod(_mPeriod); // Clean(buffer); ArraySetAsSeries(buffer, true); // double open[]; result = CopyOpen( _mSymbol, _mPeriod, _mStart, _mLoopback, open // ); if (!IsValidSize(result)) { return result; } // double high[]; result = CopyHigh( _mSymbol, _mPeriod, _mStart, _mLoopback, high // ); if (!IsValidSize(result)) { return result; } // double low[]; result = CopyLow( _mSymbol, _mPeriod, _mStart, _mLoopback, low // ); if (!IsValidSize(result)) { return result; } // double close[]; result = CopyClose( _mSymbol, _mPeriod, _mStart, _mLoopback, close // ); if (!IsValidSize(result)) { return result; } // for (int i = 0; i < result; i++) { // double iPrice = GetAppliedPrice( _mAppliedTo, open, high, low, close, i // ); // Add( iPrice, buffer // ); } // result = ArraySize(buffer); // return result; } // // Symbols ... // // Time / Date ... // // Retrieve Day of Week ... ENUM_X_WEEK_DAYS GetDayOfWeek( datetime time = NULL // ) { // ENUM_X_WEEK_DAYS result = X_WEEK_DAY_NONE; // time = NormalizeTime(time); MqlDateTime timeStruct; bool hasDate = TimeToStruct( time, timeStruct // ); if (!hasDate) { return result; } // result = (ENUM_X_WEEK_DAYS)timeStruct.day_of_week; // return result; } // // 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) // }; // // Bar Times ... // // 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; } // // Retrieve Last Available Bar Time of // Dest Period inside Source Period ... datetime GetLastBarTime( ENUM_TIMEFRAMES sourcePeriod, ENUM_TIMEFRAMES destPeriod // ) { // datetime result = NULL; // if (!IsValid(sourcePeriod) || !IsValid(destPeriod)) { return result; } // int sourceSeconds = PeriodSeconds(sourcePeriod); int destSeconds = PeriodSeconds(destPeriod); if (sourceSeconds < destSeconds) { return result; } // XOHCL sourceBar; bool isInited = sourceBar.Init( _Symbol, sourcePeriod, 0 // ); if (!isInited) { return result; } // result = (datetime)((((int)sourceBar.time) + sourceSeconds) - destSeconds); // return result; } // // Other Tools ... // // Check Bar Reject Specified Value ... bool IsBarReject( double value, ENUM_X_DIRECTION dir, XOHCL &bar // ) { // bool result = false; // result = value > 0 && bar.IsValid() && HasDirection(dir); if (!result) { return result; } // bool isUp = IsBullish(dir); bool isDown = IsBearish(dir); // result = // isUp ? bar.IsBullish() && bar.low < value && bar.GetDown() > value : isDown ? bar.IsBearish() && bar.high > value && bar.GetUp() < value : false // ; // return result; } // // Check Bar Break Specified Value ... bool IsBarBreak( double value, ENUM_X_DIRECTION dir, XOHCL &bar // ) { // bool result = false; // result = value > 0 && bar.IsValid() && HasDirection(dir); if (!result) { return result; } // XOHCL pBar; result = bar.GetPreviousBar(pBar); if (!result) { return result; } // bool isUp = IsBullish(dir); bool isDown = IsBearish(dir); // result = isUp ? bar.IsBullish() && ((bar.GetDown() < value && bar.GetUp() > value) || (bar.close > value && pBar.close < value)) : isDown ? bar.IsBearish() && ((bar.GetUp() > value && bar.GetDown() < value) || (bar.close < value && pBar.close > value)) : false; // 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; } // double GetFibonacciLevel( double mUp, double mDown, ENUM_X_FIBO_LEVELS mLevel, ENUM_X_DIRECTION mForDir // ) { // double result = 0; // double levelValue = GetFiboLevelValue(mLevel); // bool isValid = // mUp > 0 && mDown > 0 && levelValue > 0 && mUp > mDown && HasDirection(mForDir) // ; if (!isValid) { return result; } // bool isBullish = IsBullish(mForDir); // double ling = mUp - mDown; double pLevel = (ling / 100) * (levelValue * 100); // result = isBullish ? mUp - pLevel : mDown + 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; } // void NormalizeBuffer( double &source[], // Source Buffer double &dest[], // Result Buffer double upper = 100, // Upper Value to Normalize double lower = -100, // Lower Value to Normalize int size = -1, // Size Of Normalization int digits = 5 // Digits for Result ) { // if (size <= 0) { size = ArraySize(source); } // bool asSeriesFlag = ArrayGetAsSeries(source); // ArraySetAsSeries(source, false); ArraySetAsSeries(dest, false); // double min = ArrayMinimum(source, 0, size); double max = ArrayMaximum(source, 0, size); // for (int i = 0; i < size; i++) { // double iNormal = lower + ((source[i] - min) / (max - min)) * (upper - lower); // if (digits > 0) { iNormal = NormalizeDouble(iNormal, digits); } // dest[i] = iNormal; } // ArraySetAsSeries(source, asSeriesFlag); ArraySetAsSeries(dest, asSeriesFlag); } // // Templates ... // // Bar XOHCL ... // // String ... // // Periods / Cycles ... // // Moving Average ...