// // 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); } } } }