diff --git a/Classes/x-saherelm.xtrade.class.mq5 b/Classes/x-saherelm.xtrade.class.mq5 index c859f3a5..e60fc584 100644 --- a/Classes/x-saherelm.xtrade.class.mq5 +++ b/Classes/x-saherelm.xtrade.class.mq5 @@ -4286,18 +4286,6 @@ public: mRecoverySLPoint = value; } - // - bool RecoverBasedOnPressures() - { - return mRecoverBasedOnPressures; - } - - // - void RecoverBasedOnPressures(bool value) - { - mRecoverBasedOnPressures = value; - } - // int MaxAllowedRecover() { @@ -4466,6 +4454,17 @@ public: item.recoverySLPoint = mRecoverySLPoint; item.maxAllowedRecover = mMaxAllowedRecover; item.recoveryVolumeMultiplier = mRecoveryVolumeMultiplier; + + // + ENUM_POSITION_TYPE _type; + bool isConverted = ToPositionType( + _type, + item.type // + ); + if (isConverted) + { + item.recoveryLookingType = GetOppositPositionType(_type); + } } // @@ -4734,6 +4733,29 @@ public: continue; } + // + // Try to Detect Recovered Positions ... + + // + XPosition positions[]; + XPosition recoveries[]; + int recoveriesCount = 0; + int positionsCount = mTrader.GetPositions( + positions, + symbol, + provider, + period // + ); + if (positionsCount > 0) + { + // + recoveriesCount = ExtractRecoveries( + ticket, + positions, + recoveries // + ); + } + // // Handle Recovery Break Event ... if (mData[i].allowRecover) @@ -4768,96 +4790,77 @@ public: else { // - XPosition positions[]; - int positionsCount = mTrader.GetPositions( - positions, - symbol, - provider, - period // - ); - if (positionsCount > 0) + if (recoveriesCount > 0) { // - XPosition recoveries[]; - int recoveriesCount = ExtractRecoveries( - ticket, - positions, - recoveries // + XPosition mustClose[]; + AddRef( + iPosition, + mustClose // ); // - if (recoveriesCount > 0) + double requiredProfitPoints = (mData[i].recoveryLevel + 1) * recoveryTPPoint; + + // + double rSwap = mData[i].swap; + double rVolume = volume; + double rProfit = profit; + double rCommission = mData[i].commission; + for (int i = 0; i < recoveriesCount; i++) { // - XPosition mustClose[]; + rSwap += recoveries[i].swap; + rProfit += recoveries[i].profit; + rVolume += recoveries[i].volume; + rCommission += mTrader.GetPositionCommission(recoveries[i].ticket); + + // AddRef( - iPosition, + recoveries[i], mustClose // ); + } + + // + double profitSummary = + rProfit + (-1 * rSwap) - MathAbs(rCommission); + if (profitSummary > 0) + { + // + double rProfitInPoints = profitSummary / volume; // - double requiredProfitPoints = (mData[i].recoveryLevel + 1) * recoveryTPPoint; - - // - double rSwap = mData[i].swap; - double rVolume = volume; - double rProfit = profit; - double rCommission = mData[i].commission; - for (int i = 0; i < recoveriesCount; i++) + bool canFinishRecovery = rProfitInPoints >= requiredProfitPoints; + if (canFinishRecovery) { // - rSwap += recoveries[i].swap; - rProfit += recoveries[i].profit; - rVolume += recoveries[i].volume; - rCommission += mTrader.GetPositionCommission(recoveries[i].ticket); + // Here we Have to close All Recoveries + // and Position it Self ... // - AddRef( - recoveries[i], - mustClose // + string comment = "Recovery Done ..."; + + // + int closeds = mTrader.Close( + mustClose, + comment // ); - } - - // - double profitSummary = - rProfit + (-1 * rSwap) - MathAbs(rCommission); - if (profitSummary > 0) - { - // - double rProfitInPoints = profitSummary / volume; - - // - bool canFinishRecovery = rProfitInPoints >= requiredProfitPoints; - if (canFinishRecovery) + if (closeds > 0) { // - // Here we Have to close All Recoveries - // and Position it Self ... + string msg = "EQM Done Recovery (" + ToString(closeds) + ") Positions ..."; + Alert(msg); // - string comment = "Recovery Done ..."; - - // - int closeds = mTrader.Close( - mustClose, - comment // - ); - if (closeds > 0) - { - // - string msg = "EQM Done Recovery (" + ToString(closeds) + ") Positions ..."; - Alert(msg); - - // - break; - } + break; } - - // - Clean(mustClose); - Clean(positions); - Clean(recoveries); } + + // + Clean(mustClose); + Clean(positions); + Clean(recoveries); } } } @@ -5119,184 +5122,12 @@ public: if (profit < 0) { // - if (mRecoverBasedOnPressures) - { - // - bool canRecover = distanceInPoints >= recoverySLPoint * 0.75; - if (canRecover) - { - // - XSignal rSignal; - bool isPrepared = false; - double longEntry = GetEntry(symbol, POSITION_TYPE_BUY); - double shortEntry = GetEntry(symbol, POSITION_TYPE_SELL); - - // - if (isBullishSigns) - { - // - rSignal.Clean(); - isPrepared = rSignal.Prepare( - symbol, - provider, - period, - POSITION_TYPE_BUY, - X_ORDER_MODE_MARKET, - longEntry, - _volume, - 0, - 0 // - ); - } - else if (isBearishSigns) - { - // - rSignal.Clean(); - isPrepared = rSignal.Prepare( - symbol, - provider, - period, - POSITION_TYPE_SELL, - X_ORDER_MODE_MARKET, - shortEntry, - _volume, - 0, - 0 // - ); - } - - // - if (isPrepared) - { - // - RemovePositionTPSL(iPosition); - - // - rSignal.comment = _comment; - - // - bool isExecuted = ExecuteRecoverySignal(rSignal); - if (isExecuted) - { - mData[i].recoveryLevel++; - } - } - } - } - else - { - // - bool canRecover = - distanceInPoints >= recoverySLPoint && - (mData[i].recoveryLevel == 0 || - (mData[i].recoveryLevel >= 2 && - mData[i].recoveryLevel / 2 == 0)); - if (canRecover) - { - // - RemovePositionTPSL(iPosition); - - // - ENUM_POSITION_TYPE _type = - isLong - ? POSITION_TYPE_SELL - : POSITION_TYPE_BUY; - double _entry = GetEntry(symbol, _type); - - // - XSignal rSignal; - bool isPrepared = rSignal.Prepare( - symbol, - provider, - period, - _type, - X_ORDER_MODE_MARKET, - _entry, - _volume, - 0, - 0 // - ); - if (isPrepared) - { - // - rSignal.comment = _comment; - - // - bool isExecuted = ExecuteRecoverySignal(rSignal); - if (isExecuted) - { - mData[i].recoveryLevel++; - } - } - } - } - } - else if (profit >= 0 && - (mData[i].recoveryLevel == 1 || - (mData[i].recoveryLevel >= 2 && - mData[i].recoveryLevel / 2 == 1))) - { - // - if (mRecoverBasedOnPressures) - { - // - XSignal rSignal; - bool isPrepared = false; - double longEntry = GetEntry(symbol, POSITION_TYPE_BUY); - double shortEntry = GetEntry(symbol, POSITION_TYPE_SELL); - - // - if (isBullishSigns) - { - // - rSignal.Clean(); - isPrepared = rSignal.Prepare( - symbol, - provider, - period, - POSITION_TYPE_BUY, - X_ORDER_MODE_MARKET, - longEntry, - _volume, - 0, - 0 // - ); - } - else if (isBearishSigns) - { - // - rSignal.Clean(); - isPrepared = rSignal.Prepare( - symbol, - provider, - period, - POSITION_TYPE_SELL, - X_ORDER_MODE_MARKET, - shortEntry, - _volume, - 0, - 0 // - ); - } - - // - if (isPrepared) - { - // - RemovePositionTPSL(iPosition); - - // - rSignal.comment = _comment; - - // - bool isExecuted = ExecuteRecoverySignal(rSignal); - if (isExecuted) - { - mData[i].recoveryLevel++; - } - } - } - else + bool canRecover = + distanceInPoints >= recoverySLPoint && + (mData[i].recoveryLevel == 0 || + (mData[i].recoveryLevel >= 2 && + mData[i].recoveryLevel / 2 == 0)); + if (canRecover) { // RemovePositionTPSL(iPosition); @@ -5304,8 +5135,8 @@ public: // ENUM_POSITION_TYPE _type = isLong - ? POSITION_TYPE_BUY - : POSITION_TYPE_SELL; + ? POSITION_TYPE_SELL + : POSITION_TYPE_BUY; double _entry = GetEntry(symbol, _type); // @@ -5335,6 +5166,47 @@ public: } } } + else if (profit >= 0 && + (mData[i].recoveryLevel == 1 || + (mData[i].recoveryLevel >= 2 && + mData[i].recoveryLevel / 2 == 1))) + { + // + RemovePositionTPSL(iPosition); + + // + ENUM_POSITION_TYPE _type = + isLong + ? POSITION_TYPE_BUY + : POSITION_TYPE_SELL; + double _entry = GetEntry(symbol, _type); + + // + XSignal rSignal; + bool isPrepared = rSignal.Prepare( + symbol, + provider, + period, + _type, + X_ORDER_MODE_MARKET, + _entry, + _volume, + 0, + 0 // + ); + if (isPrepared) + { + // + rSignal.comment = _comment; + + // + bool isExecuted = ExecuteRecoverySignal(rSignal); + if (isExecuted) + { + mData[i].recoveryLevel++; + } + } + } } } } @@ -5393,7 +5265,6 @@ protected: int mMaxAllowedRecover; // Max Allowed Recovery double mRecoveryTPPoint; // Recovery TP in Points double mRecoverySLPoint; // Recovery SL in Points - bool mRecoverBasedOnPressures; // Do Recovery based on Market Pressures double mRecoveryVolumeMultiplier; // Recovery Volume Multiplier // diff --git a/Experts/x-test-strategies.ea.mq5 b/Experts/x-test-strategies.ea.mq5 index c20418cd..eb1975d9 100644 --- a/Experts/x-test-strategies.ea.mq5 +++ b/Experts/x-test-strategies.ea.mq5 @@ -286,7 +286,6 @@ bool InitialEA() eaTradeHandler.RecoveryTPPoint(50); eaTradeHandler.RecoverySLPoint(eaSLPoint); eaTradeHandler.RecoveryVolumeMultiplier(2); - eaTradeHandler.RecoverBasedOnPressures(false); // XSymbolParser symbolParser; diff --git a/Libraries/x-saherelm.xtrade.lib.mq5 b/Libraries/x-saherelm.xtrade.lib.mq5 index 656b5a85..70ec314e 100644 --- a/Libraries/x-saherelm.xtrade.lib.mq5 +++ b/Libraries/x-saherelm.xtrade.lib.mq5 @@ -3785,12 +3785,13 @@ struct XTradeData // Recovery ... // - bool allowRecover; // Allow Recover Specified Position - double recoveryTPPoint; // Recovery TP Point - double recoverySLPoint; // Recovery SL Point - int maxAllowedRecover; // Max Allowed Recovery - int recoveryLevel; // Number of Recovery Signals - double recoveryVolumeMultiplier; // Recovery Volume Multiplier + bool allowRecover; // Allow Recover Specified Position + double recoveryTPPoint; // Recovery TP Point + double recoverySLPoint; // Recovery SL Point + int maxAllowedRecover; // Max Allowed Recovery + int recoveryLevel; // Number of Recovery Signals + double recoveryVolumeMultiplier; // Recovery Volume Multiplier + ENUM_X_POSITION_TYPES recoveryLookingType; // Looking for Next Recovery Type // void ResetRecovery() @@ -3801,6 +3802,7 @@ struct XTradeData recoveryTPPoint = 0; recoverySLPoint = 0; recoveryVolumeMultiplier = 0; + recoveryLookingType = X_POSITION_TYPE_NONE; } //