
        //
        // In Profit ...
        // When a Position running in Profit, we have to look pressures by Same Direction
        // of Main Position. for eaxmple if it is long, we look for Bullish Pressures and
        // if it is short we look for Bearish Pressures.
        // when pressure happens we must Trail position Stop ...
        if (isInProfit)
        {
            //
            // Do In Profit Protection Mechanism ...

            //
            // Trail Stops ...
            // Remove Trailed Positions TP ...
            bool allowTrailStop = AllowTrailStopInProfits();
            double trailStep = TrailStopStepsInPoint();
            bool allowOnlyUnprotecteds = OnlyTrailUnprotectedPositions();
            bool isProtectionTrailPassed = !allowOnlyUnprotecteds
                                               ? true
                                               : supportsCount == 0;
            if (allowTrailStop && trailStep > 0 && isProtectionTrailPassed)
            {
                //
                // Temp Vaiables ...
                bool canTrailStop = false;

                //
                if (isLong)
                {
                    //
                    // Check Conditions ...
                    canTrailStop = isTicksBullishForLong &&
                                   hasBullishConditions;
                }
                else
                {
                    //
                    // Check Conditions ...
                    canTrailStop = isTicksBearishForShort &&
                                   hasBearishConditions;
                }

                //
                // Do Stop Trailling ...
                if (canTrailStop)
                {
                    //
                    int lastTrailedStep = mData[iDX].trailStep;

                    //
                    double entry = position.entry;
                    double pointValue = position.GetPointsValue();
                    double profitInPoint = position.GetProfitInPoint();

                    //
                    double requiredProfit =
                        lastTrailedStep == 0
                            ? ProtectorStartDistanceInPoint()
                            : ProtectorStartDistanceInPoint() + (lastTrailedStep * trailStep);

                    //
                    bool isProfitsPassed = profitInPoint > requiredProfit;
                    if (isProfitsPassed)
                    {
                        //
                        double delta = (requiredProfit * pointValue);

                        //
                        double sl =
                            isLong
                                ? entry + delta
                                : entry - delta;

                        //
                        string comment = "EQM Trail Stop ...";

                        //
                        // Try to Modify Position ...
                        result = mTrader.Modify(
                            position.ticket,
                            sl,
                            position.tp,
                            comment //
                        );
                        if (result)
                        {
                            //
                            mData[iDX].trailStep++;

                            //
                            string message = "EQM Trail (" + ToString(position.ticket) + ") Stop ...";
                            Alert(message);

                            //
                            XPosition trailedPosition;
                            bool hasPosition = mTrader.GetPosition(
                                position.ticket,
                                trailedPosition //
                            );

                            //
                            // Check Remove Trailed Positions TP Conditions ...
                            int removeTPOnTrailStep = RmoveTPOnTrailStep();
                            if (removeTPOnTrailStep > 0 && mData[iDX].trailStep == removeTPOnTrailStep && trailedPosition.tp != 0)
                            {
                                //
                                string comment = "EQM Removes TP ...";

                                //
                                // Remove Position's TP ...
                                result = mTrader.Modify(
                                    trailedPosition.ticket,
                                    trailedPosition.sl,
                                    0,
                                    comment //
                                );
                                if (result)
                                {
                                    //
                                    string message = "EQM Removes (" + ToString(trailedPosition.ticket) + ") TP ...";
                                    Alert(message);
                                }
                            }
                        }
                    }
                }
            }

            //
            bool allowRecover = AllowRecoverInDrawdowns();
            double volumeMultiplier = RecoveryMultiplier();
            if (allowRecover && !canFreeze && volumeMultiplier > 0 && supportsCount > 0)
            {
                //
                bool canRecover = false;
                int delayMinutes = RecoveryDelayInMinute();
                double recoveryDistancePoint = RecoveryDistanceInPoint();

                //
                // Temparory Requirement for Recover Signal ...
                double sl = 0;
                double tp = 0;
                double entry = 0;
                ENUM_POSITION_TYPE type = NULL;
                ENUM_X_ORDER_MODES mode = X_ORDER_MODE_MARKET;
                double lastStep = mData[iDX].protectionStep;
                double volume = position.volume * volumeMultiplier;
                bool applyLevel = ApplyRecoveryLevelOnVolume();
                if (applyLevel)
                {
                    //
                    volume = supportsCount <= 0
                                 ? position.volume * volumeMultiplier
                                 : position.volume * ((supportsCount + 1) * volumeMultiplier);
                }

                //
                datetime currentTime = TimeCurrent();
                double currentProfit = position.GetProfitInPoint();
                datetime lastProtectedOn = mData[iDX].lastProtectedOn;
                double lastProtectedProfit = mData[iDX].lastProtectedInProfit;
                bool isRecoveryConditionsPassed =
                    //
                    // Check Regular Conditions ...
                    delayMinutes > 0 &&
                    recoveryDistancePoint > 0 &&
                    IsValid(lastProtectedOn) &&
                    //
                    // Check Time Delay Passed ...
                    (TimeToSeconds(currentTime) - TimeToSeconds(lastProtectedOn)) >= ulong(delayMinutes * 60) &&
                    //
                    // Check Recovery Distance Passed ...
                    MathAbs(currentProfit) - MathAbs(lastProtectedProfit) >= recoveryDistancePoint;

                //
                if (isRecoveryConditionsPassed)
                {
                    //
                    // Long Recovery ...
                    if (isLong)
                    {
                        //
                        // Same Direction ...
                        canRecover =
                            //
                            isTicksBullishForLong &&
                            hasBullishTrend &&
                            (hasBullishPower ||
                             hasBullishPattern ||
                             hasBullishPressure)
                            //
                            ;
                        if (canRecover)
                        {
                            //
                            sl = position.sl;
                            tp = position.tp;
                            type = POSITION_TYPE_BUY;
                        }
                    }
                    //
                    // Short Recovery ...
                    else
                    {
                        //
                        // Same Direction ...
                        canRecover =
                            //
                            isTicksBearishForShort &&
                            hasBearishTrend &&
                            (hasBearishPower ||
                             hasBearishPattern ||
                             hasBearishPressure)
                            //
                            ;
                        if (canRecover)
                        {
                            //
                            sl = position.sl;
                            tp = position.tp;
                            type = POSITION_TYPE_SELL;
                        }
                    }

                    //
                    if (canRecover)
                    {
                        //
                        XSignal signal;
                        entry = GetEntry(
                            position.symbol,
                            type //
                        );

                        //
                        // Prepare Signal ...
                        result = signal.Prepare(
                            position.symbol,
                            position.provider,
                            position.period,
                            type,
                            mode,
                            entry,
                            volume,
                            sl,
                            tp //
                        );

                        //
                        if (result)
                        {
                            //
                            // Generate Comment for Recover and Support ...
                            string comment = GenerateSupportTag(position.ticket);

                            //
                            signal.comment = comment;

                            //
                            ENUM_X_SIGNAL_EXECUTION_RESULT state;
                            result = ExecuteSignal(
                                signal,
                                state,
                                true // Support Signal need to Ignore Policies ...
                            );
                            if (result)
                            {
                                //
                                mData[iDX].protectionStep++;
                                mData[iDX].lastProtectedOn = currentTime;
                                mData[iDX].lastProtectedInProfit = currentProfit;

                                //
                                string message = "EQM Open " + (IsLong(type) ? "Long" : "Short") + " Recovery Position in Level: " +
                                                 ToString(lastStep + 1) +
                                                 " for (" + ToString(position.ticket) + ")";
                                Alert(message);
                            }
                        }
                    }
                }
            }

            //
            // Check Points of Profit and Do Partial Closing ...
            double partialCloseVolume = PartialCloseVolumeInProfit();
            double partialCloseProfitPoint = PartialCloseOnSpecificPointOfProfit();
            if (partialCloseVolume > 0 && partialCloseProfitPoint > 0)
            {
                //
                double profitPoints = position.GetProfitInPoint();
                if (profitPoints >= partialCloseProfitPoint && !mData[iDX].partiallyClosed)
                {
                    //
                    string comment = "EQM Partial Close ...";

                    //
                    // Do Partial Closing ...
                    result = mTrader.ClosePartial(
                        position.ticket,
                        partialCloseVolume,
                        comment //
                    );
                    if (result)
                    {
                        //
                        mData[iDX].partiallyClosed = true;

                        //
                        string message = "EQM Partially Closed " + ToString(partialCloseVolume) + " of (" + ToString(position.ticket) + ")";
                        Alert(message);
                    }
                }
            }
        }
        //
        // In Drawdown ...
        // When a Position running in Drawdown, we have to look for pressures by Indirection
        // of Main Position. for example if it is long, we Look For Bearish Pressures and if
        // it is short we Look for Bullish Pressure.
        // when indirectional pressure found we must Open a Recovery Position.
        // also if Same Direction Pressure Found we try to Recover Same Direction using Grid ...
        else
        {
            //
            bool allowRecover = AllowRecoverInDrawdowns();
            double volumeMultiplier = RecoveryMultiplier();
            if (allowRecover && !canFreeze && volumeMultiplier > 0)
            {
                //
                bool canRecover = false;
                int delayMinutes = RecoveryDelayInMinute();
                double recoveryDistancePoint = RecoveryDistanceInPoint();

                //
                // Temparory Requirement for Recover Signal ...
                double sl = 0;
                double tp = 0;
                double entry = 0;
                ENUM_POSITION_TYPE type = NULL;
                ENUM_X_ORDER_MODES mode = X_ORDER_MODE_MARKET;
                double lastStep = mData[iDX].protectionStep;
                double volume = position.volume * volumeMultiplier;
                bool applyLevel = ApplyRecoveryLevelOnVolume();
                if (applyLevel)
                {
                    //
                    volume = supportsCount <= 0
                                 ? position.volume * volumeMultiplier
                                 : position.volume * ((supportsCount + 1) * volumeMultiplier);
                }

                //
                datetime currentTime = TimeCurrent();
                double currentDrawdown = position.GetProfitInPoint();
                datetime lastProtectedOn = mData[iDX].lastProtectedOn;
                double lastProtectedDrawdown = mData[iDX].lastProtectedInDrawdown;
                bool isRecoveryConditionsPassed = supportsCount <= 0
                                                      ? true
                                                      :
                                                      //
                                                      // Check Regular Conditions ...
                                                      delayMinutes > 0 &&
                                                          recoveryDistancePoint > 0 &&
                                                          IsValid(lastProtectedOn) &&
                                                          lastProtectedDrawdown < 0 &&
                                                          //
                                                          // Check Time Delay Passed ...
                                                          (TimeToSeconds(currentTime) - TimeToSeconds(lastProtectedOn)) >= ulong(delayMinutes * 60) &&
                                                          //
                                                          // Check Recovery Distance Passed ...
                                                          MathAbs(currentDrawdown) - MathAbs(lastProtectedDrawdown) >= recoveryDistancePoint;

                //
                if (isRecoveryConditionsPassed)
                {
                    //
                    // Long Recovery ...
                    if (isLong)
                    {
                        //
                        // Opposit Direction ...
                        canRecover =
                            //
                            isTicksBearishForShort &&
                            hasBearishTrend &&
                            (hasBearishPower ||
                             hasBearishPattern ||
                             hasBearishPressure)
                            //
                            ;
                        if (canRecover)
                        {
                            //
                            sl = position.tp;
                            tp = position.sl;
                            type = POSITION_TYPE_SELL;
                        }
                    }
                    //
                    // Short Recovery ...
                    else
                    {
                        //
                        // Opposit Direction ...
                        canRecover =
                            //
                            isTicksBullishForLong &&
                            hasBullishTrend &&
                            (hasBullishPower ||
                             hasBullishPattern ||
                             hasBullishPressure)
                            //
                            ;
                        if (canRecover)
                        {
                            //
                            sl = position.tp;
                            tp = position.sl;
                            type = POSITION_TYPE_BUY;
                        }
                    }

                    //
                    if (canRecover)
                    {
                        //
                        XSignal signal;
                        entry = GetEntry(
                            position.symbol,
                            type //
                        );

                        //
                        // Prepare Signal ...
                        result = signal.Prepare(
                            position.symbol,
                            position.provider,
                            position.period,
                            type,
                            mode,
                            entry,
                            volume,
                            sl,
                            tp //
                        );

                        //
                        if (result)
                        {
                            //
                            // Generate Comment for Recover and Support ...
                            string comment = GenerateSupportTag(position.ticket);

                            //
                            signal.comment = comment;

                            //
                            ENUM_X_SIGNAL_EXECUTION_RESULT state;
                            result = ExecuteSignal(
                                signal,
                                state,
                                true // Support Signal need to Ignore Policies ...
                            );
                            if (result)
                            {
                                //
                                mData[iDX].protectionStep++;
                                mData[iDX].lastProtectedOn = currentTime;
                                mData[iDX].lastProtectedInDrawdown = currentDrawdown;

                                //
                                string message = "EQM Open " + (IsLong(type) ? "Long" : "Short") + " Recovery Position in Level: " +
                                                 ToString(lastStep + 1) +
                                                 " for (" + ToString(position.ticket) + ")";
                                Alert(message);
                            }
                        }
                    }
                }
            }

            //
            if (canFreeze &&
                supportsCount <= 0 &&
                position.profit < 0 &&
                !mData[iDX].freezed &&
                MathAbs(profitInPoint) >= freezePoint)
            {
                //
                bool removeTPSL = RemoveFreezedPositionsTPSL();
                //
                // Temparory Requirement for Recover Signal ...
                double sl = removeTPSL ? 0 : position.tp;
                double tp = removeTPSL ? 0 : position.sl;
                ENUM_POSITION_TYPE type = isLong
                                              ? POSITION_TYPE_SELL
                                              : POSITION_TYPE_BUY;
                double entry = GetEntry(
                    position.symbol,
                    type //
                );
                ENUM_X_ORDER_MODES mode = X_ORDER_MODE_MARKET;
                double volume = position.volume * freezeVolumeMultiplier;

                //
                XSignal signal;

                //
                // Prepare Signal ...
                result = signal.Prepare(
                    position.symbol,
                    position.provider,
                    position.period,
                    type,
                    mode,
                    entry,
                    volume,
                    sl,
                    tp //
                );

                //
                if (result)
                {
                    //
                    // Generate Comment for Recover and Support ...
                    string comment = GenerateSupportTag(position.ticket);

                    //
                    signal.comment = comment;

                    //
                    ENUM_X_SIGNAL_EXECUTION_RESULT state;
                    result = ExecuteSignal(
                        signal,
                        state,
                        true // Support Signal need to Ignore Policies ...
                    );
                    if (result)
                    {
                        //
                        mData[iDX].freezed = true;

                        //
                        string message = "EQM Open " + (IsLong(type) ? "Long" : "Short") + " Freeze Position for (" + ToString(position.ticket) + ")";
                        Alert(message);

                        //
                        string comment = "EQM Removes Freezed TP/SL ...";
                        result = mTrader.Modify(
                            position.ticket,
                            0,
                            0,
                            comment //
                        );

                        //
                        if (result)
                        {
                            //
                            string message = "EQM Remove Freezed Position (" + ToString(position.ticket) + ") TP/SL ..";
                            Alert(message);
                        }
                    }
                }
            }

            //
            // Check Points of Drawdown and Do Partial Closing ...
            double partialCloseVolume = PartialCloseVolumeInDrawdown();
            double partialCloseDrawdownPoint = PartialCloseOnSpecificPointOfDrawdown();
            if (partialCloseVolume > 0 && partialCloseDrawdownPoint > 0)
            {
                //
                double profitPoints = position.GetProfitInPoint();
                if (profitPoints < 0 && MathAbs(profitPoints) >= partialCloseDrawdownPoint && !mData[iDX].partiallyClosed)
                {
                    //
                    string comment = "EQM Partial Close ...";

                    //
                    // Do Partial Closing ...
                    result = mTrader.ClosePartial(
                        position.ticket,
                        partialCloseVolume,
                        comment //
                    );
                    if (result)
                    {
                        //
                        mData[iDX].partiallyClosed = true;

                        //
                        string message = "EQM Partially Closed " + ToString(partialCloseVolume) + " of (" + ToString(position.ticket) + ")";
                        Alert(message);
                    }
                }
            }
        }
