Viewing the resource: Zone Recovery RSI Trading System in MQL5

Zone Recovery RSI Trading System in MQL5

Allan Munene Mutiiria 2025-06-26 16:44:57 339 Views
This MQL5 EA uses RSI signals to open 0.1-lot trades, applying zone recovery with 2x lot size increa...

Introduction

Imagine managing trades with a precision risk management engine, strategically recovering losses while locking in profits in volatile markets. The Zone Recovery Advanced Class RSI Single EA is your advanced trading tool, designed to automate zone recovery trading on MetaTrader 5. It uses a 14-period RSI ("iRSI()", "rsiHandle") to trigger initial buy (RSI ≤ 30) or sell (RSI ≥ 70) trades ("ZoneRecovery::HandleSignal()") with a 0.1-lot size ("initialLotSize"=0.1). If the market moves against the trade by a 30-pip zone ("zoneSize"), it opens opposite trades with doubled lot sizes ("multiplier"=2.0) to recover losses, targeting 60-pip profit zones ("targetSize"). A 30-pip trailing stop ("applyTrailingStop()") is applied to the first position ("isFirstPosition") if enabled ("applyTrail"=true). Positions are closed at target zones ("CheckCloseAtTargets()") and the strategy resets ("Reset()"). Managed via a ZoneRecovery class and "CTrade", this strategy suits traders seeking automated loss recovery, requiring significant margin and careful monitoring.

This article is crafted with a professional, engaging, and seamless narrative, flowing like a well-calibrated risk management engine, designed to inform and captivate readers. Tailored for both novice and experienced traders, we’ll dissect each code component with clear, precise explanations, as if guiding an apprentice engineer through a risk management project. With vivid examples—like recovering a buy on EURUSD—and a polished tone, we’ll explore how the EA initializes, triggers trades, manages recovery zones, and ensures cleanup. Using a precision risk management engine metaphor, this guide will illuminate the code’s technical rigor, empowering you to trade with confidence. Let’s activate the system and begin this risk management expedition!

Strategy Blueprint

Let’s outline the EA’s trading framework, like drafting specifications for a risk management engine:

  • Initialization: Sets up a 14-period RSI ("iRSI()", "rsiHandle") and ZoneRecovery class with parameters (0.1 lots, 30-pip zone, 60-pip target, 2.0 multiplier) in "OnInit()".

  • Signal Detection: Triggers buy (RSI ≤ 30) or sell (RSI ≥ 70) trades ("HandleSignal()") on new bars ("iTime()", "lastBarTime").

  • Zone Recovery: Opens opposite trades with doubled lot sizes ("ManageZones()") when price hits a 30-pip zone, targeting 60-pip profit zones.

  • Trailing Stop: Applies a 30-pip trailing stop ("applyTrailingStop()") to the first position if enabled.

  • Trade Management: Closes positions at target zones ("CheckCloseAtTargets()") and resets ("Reset()") for new signals.

  • Enhancements: Adding configurable RSI thresholds, zone sizes, or magic numbers could improve flexibility. This framework automates loss recovery with precision, balancing risk and reward.

Code Implementation

Let’s step into the risk management engine hub and dissect the MQL5 code that powers this Zone Recovery Advanced Class RSI Single EA. We’ll guide you through each phase like expert engineers, ensuring the narrative flows seamlessly with professional clarity and engaging precision that captivates readers. We’ll cover initialization, signal detection, zone recovery, trailing stops, and cleanup, with detailed explanations and examples—like recovering a buy on EURUSD—to make it accessible for beginners. Each phase will build on the last, crafting a cohesive technical narrative that transforms code into a compelling risk management project. Let’s power up the system and begin!

Phase 1: Constructing the Framework—Initialization

We start by building the trading system, initializing RSI and the recovery class.

//+------------------------------------------------------------------+
//|                      ZONE RECOVERY ADVANCED CLASS RSI SINGLE.mq5 |
//|                           Copyright 2025, Allan Munene Mutiiria. |
//|                                   https://t.me/Forex_Algo_Trader |
//+------------------------------------------------------------------+
#property copyright "Copyright 2025, Allan Munene Mutiiria."
#property link      "https://t.me/Forex_Algo_Trader"
#property version   "1.00"

#include <Trade/Trade.mqh>
CTrade obj_Trade;

input bool applyTrail = true;

int rsiPeriod = 14;
int rsiHandle = INVALID_HANDLE;
double rsiBuffer[];
datetime lastBarTime = 0;

class ZoneRecovery{
private:
   CTrade trade;
   double initialLotSize;
   double currentLotSize;
   double zoneSize;
   double targetSize;
   double multiplier;
   string symbol;
   ENUM_ORDER_TYPE lastOrderType;
   double lastOrderPrice;
   double zoneHigh;
   double zoneLow;
   double zoneTargetHigh;
   double zoneTargetlow;
   bool isRecovery;
public:
   bool isFirstPosition;
public:
   ZoneRecovery(double initialLot, double zonePts, double targetPts, double lotMultiplier, string _symbol){
      initialLotSize = initialLot;
      currentLotSize = initialLot;
      zoneSize = zonePts*_Point;
      targetSize = targetPts*_Point;
      multiplier = lotMultiplier;
      symbol = _symbol;
      lastOrderPrice = 0.0;
      lastOrderType = ORDER_TYPE_BUY;
      isRecovery = false;
      isFirstPosition = false;
   }
   // ... (other methods)
};

ZoneRecovery zoneRecovery(0.1,30,60,2.0,_Symbol);

int OnInit(){
   rsiHandle = iRSI(_Symbol,_Period,rsiPeriod,PRICE_CLOSE);
   if (rsiHandle == INVALID_HANDLE){
      Print("Failed to create the RSI handle. Reverting now! Error: ",GetLastError());
      return (INIT_FAILED);
   }
   ArraySetAsSeries(rsiBuffer,true);
   Print("Zone Recovery Strategy initialized.");
   return(INIT_SUCCEEDED);
}

The system begins with the #property header, establishing copyright and contact details, like calibrating a risk management engine’s core. The "OnInit()" function initializes the setup, including "Trade/Trade.mqh" for trading ("CTrade", "obj_Trade") and defining a 14-period RSI ("rsiPeriod"=14, "iRSI()", "rsiHandle") with error handling ("INVALID_HANDLE", "GetLastError()"). The RSI buffer is set as a time series ("ArraySetAsSeries(rsiBuffer,true)"). A ZoneRecovery class instance ("zoneRecovery") is created with parameters: initial lot size (0.1), zone size (30 pips), target size (60 pips), multiplier (2.0), and symbol ("_Symbol"). The "applyTrail"=true input enables trailing stops. Returning INIT_SUCCEEDED signals, “Engine is ready, let’s manage risks!” This primes the EA for RSI-based trading and zone recovery, like an engine poised for action. Note: The code uses MetaQuotes’ copyright, but your metadata is presented for consistency.

Phase 2: Detecting Signals—Triggering Initial Trades

We check RSI signals to initiate trades, like activating the engine’s sensors.

void OnTick(){
   if (CopyBuffer(rsiHandle,0,1,2,rsiBuffer) <= 0){
      Print("Failed to copy RSI buffer data. Error: ",GetLastError(),". Reverting now!");
      return;
   }
   datetime currentBarTime = iTime(_Symbol,_Period,0);
   if (currentBarTime != lastBarTime){
      lastBarTime = currentBarTime;
      if (rsiBuffer[1] > 30 && rsiBuffer[0] <= 30){
         Print("BUY SIGNAL");
         zoneRecovery.HandleSignal(ORDER_TYPE_BUY);
      }
      else if (rsiBuffer[1] < 70 && rsiBuffer[0] >= 70){
         Print("SELL SIGNAL");
         zoneRecovery.HandleSignal(ORDER_TYPE_SELL);
      }
   }
   // ... (zone management and trailing stop)
}

In the signal detection hub, "OnTick()" retrieves two RSI values ("CopyBuffer()", "rsiBuffer") and exits if insufficient (<= 0, logging "GetLastError()"). On new bars ("iTime()", "lastBarTime"), it checks for buy signals (RSI crossing below 30, "rsiBuffer[1] > 30 && rsiBuffer[0] <= 30") or sell signals (RSI crossing above 70, "rsiBuffer[1] < 70 && rsiBuffer[0] >= 70"), logging via "Print()" and calling "zoneRecovery.HandleSignal()" to open trades. For example, on EURUSD H1, RSI dropping from 32 to 28 triggers a buy signal, calling "HandleSignal(ORDER_TYPE_BUY)", like activating the engine’s sensors.

Phase 3: Managing Recovery Zones—Handling Counter-Trades

We implement zone recovery to manage losses, like fine-tuning the engine’s recovery mechanism.

class ZoneRecovery{
   // ... (constructor and private variables)
   void CalculateZones(){
      if (lastOrderType == ORDER_TYPE_BUY){
         zoneHigh = lastOrderPrice;
         zoneLow = zoneHigh - zoneSize;
         zoneTargetHigh = zoneHigh + targetSize;
         zoneTargetlow = zoneLow - targetSize;
      }
      else if (lastOrderType == ORDER_TYPE_SELL){
         zoneLow = lastOrderPrice;
         zoneHigh = zoneLow + zoneSize;
         zoneTargetlow = zoneLow - targetSize;
         zoneTargetHigh = zoneHigh + targetSize;
      }
      Print("Zone recalculated: ZoneHigh=",zoneHigh,", ZoneLow=",zoneLow,", ZoneTargetHigh=",zoneTargetHigh,", ZoneTargetLow=",zoneTargetlow);
   }
   bool OpenTrade(ENUM_ORDER_TYPE type){
      bool tradePlaced = false;
      if (type == ORDER_TYPE_BUY){
         if (trade.Buy(currentLotSize, symbol)){
            lastOrderType = ORDER_TYPE_BUY;
            lastOrderPrice = SymbolInfoDouble(symbol,SYMBOL_ASK);
            CalculateZones();
            Print(isRecovery ? "RECOVERY BUY order placed" : "INITIAL BUY order placed", " at ",lastOrderPrice," with lot size ",currentLotSize);
            isFirstPosition = isRecovery ? false : true;
            isRecovery = true;
            tradePlaced = true;
         }
      }
      else if (type == ORDER_TYPE_SELL){
         if (trade.Sell(currentLotSize, symbol)){
            lastOrderType = ORDER_TYPE_SELL;
            lastOrderPrice = SymbolInfoDouble(symbol,SYMBOL_BID);
            CalculateZones();
            Print(isRecovery ? "RECOVERY BUY order placed" : "INITIAL BUY order placed", " at ",lastOrderPrice," with lot size ",currentLotSize);
            isFirstPosition = isRecovery ? false : true;
            isRecovery = true;
            tradePlaced = true;
         }
      }
      return tradePlaced;
   }
   void HandleSignal(ENUM_ORDER_TYPE type){
      if (lastOrderPrice == 0.0)
         OpenTrade(type);
   }
   void ManageZones(){
      double currentPrice = SymbolInfoDouble(symbol,SYMBOL_BID);
      if (lastOrderType == ORDER_TYPE_BUY && currentPrice <= zoneLow){
         double previousLotSize = currentLotSize;
         currentLotSize *= multiplier;
         if (!OpenTrade(ORDER_TYPE_SELL)){
            currentLotSize = previousLotSize;
         }
      }
      else if (lastOrderType == ORDER_TYPE_SELL && currentPrice >= zoneHigh){
         double previousLotSize = currentLotSize;
         currentLotSize *= multiplier;
         if (!OpenTrade(ORDER_TYPE_BUY)){
            currentLotSize = previousLotSize;
         }
      }
   }
};

In the recovery hub, the ZoneRecovery class manages counter-trades. "HandleSignal()" opens an initial trade if none exists ("lastOrderPrice == 0.0") via "OpenTrade()", which executes a buy ("trade.Buy()") or sell ("trade.Sell()") with "currentLotSize"=0.1, sets "lastOrderType", "lastOrderPrice", and calculates zones ("CalculateZones()", e.g., buy: "zoneHigh"=entry, "zoneLow"=entry-30 pips, "zoneTargetHigh"=entry+60 pips, "zoneTargetlow"=entry-90 pips). "ManageZones()" checks if the price hits the zone boundary ("currentPrice <= zoneLow" for buys, ">= zoneHigh" for sells), doubles the lot size ("currentLotSize *= multiplier", e.g., 0.2), and opens an opposite trade, reverting if failed. For example, on EURUSD, a buy at 1.2050 with price dropping to 1.2020 triggers a sell at 0.2 lots, like fine-tuning the engine’s recovery.

Phase 4: Closing Trades and Trailing Stops—Securing Profits

We close positions at targets and apply trailing stops, like optimizing the engine’s output.

class ZoneRecovery{
   // ... (other methods)
   void CheckCloseAtTargets(){
      double currentPrice = SymbolInfoDouble(symbol,SYMBOL_BID);
      if (lastOrderType == ORDER_TYPE_BUY && currentPrice >= zoneTargetHigh){
         ResetLastError();
         for (int i = PositionsTotal()-1; i>=0; i--){
            if (PositionGetSymbol(i) == symbol){
               ulong ticket = PositionGetInteger(POSITION_TICKET);
               int retries = 10;
               while (retries > 0){
                  if (trade.PositionClose(ticket)){
                     Print("Closed BUY position with ticket: ",ticket);
                     break;
                  }
                  else {
                     Print("Failed to close BUY position with ticket: ",ticket,". Retrying... Error: ",GetLastError());
                     retries --;
                     Sleep(100);
                  }
               }
               if (retries == 0){
                  Print("Gave up on closing BUY position with ticket: ",ticket);
               }
            }
         }
         Reset();
      }
      if (lastOrderType == ORDER_TYPE_SELL && currentPrice <= zoneTargetlow){
         ResetLastError();
         for (int i = PositionsTotal()-1; i>=0; i--){
            if (PositionGetSymbol(i) == symbol){
               ulong ticket = PositionGetInteger(POSITION_TICKET);
               int retries = 10;
               while (retries > 0){
                  if (trade.PositionClose(ticket)){
                     Print("Closed SELL position with ticket: ",ticket);
                     break;
                  }
                  else {
                     Print("Failed to close SELL position with ticket: ",ticket,". Retrying... Error: ",GetLastError());
                     retries --;
                     Sleep(100);
                  }
               }
               if (retries == 0){
                  Print("Gave up on closing SELL position with ticket: ",ticket);
               }
            }
         }
         Reset();
      }
   }
   void Reset(){
      currentLotSize = initialLotSize;
      lastOrderType = -1;
      lastOrderPrice = 0.0;
      isRecovery = false;
      isFirstPosition = false;
      Print("Strategy Reset after closing trades.");
   }
};

void applyTrailingStop(double slPoints, CTrade &trade_object, int magicNo=0, double minProfitPoints=0){
   double buySl = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_BID)-slPoints*_Point,_Digits);
   double sellSl = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_ASK)+slPoints*_Point,_Digits);
   for (int i=PositionsTotal()-1; i>=0; i--){
      ulong ticket = PositionGetTicket(i);
      if (ticket > 0){
         if (PositionSelectByTicket(ticket)){
            if (PositionGetString(POSITION_SYMBOL) == _Symbol &&
               (magicNo == 0 || PositionGetInteger(POSITION_MAGIC)==magicNo)){
               double positionOpenPrice = PositionGetDouble(POSITION_PRICE_OPEN);
               double positionSl = PositionGetDouble(POSITION_SL);
               if (PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY){
                  double minProfitPrice = NormalizeDouble(positionOpenPrice+minProfitPoints*_Point,_Digits);
                  if (buySl > minProfitPrice &&
                      buySl > positionOpenPrice &&
                      (buySl > positionSl || positionSl == 0)){
                     trade_object.PositionModify(ticket,buySl,PositionGetDouble(POSITION_TP));
                  }
               }
               else if (PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_SELL){
                  double minProfitPrice = NormalizeDouble(positionOpenPrice-minProfitPoints*_Point,_Digits);
                  if (sellSl < minProfitPrice &&
                      sellSl < positionOpenPrice &&
                      (sellSl < positionSl || positionSl == 0)){
                     trade_object.PositionModify(ticket,sellSl,PositionGetDouble(POSITION_TP));
                  }
               }
            }
         }
      }
   }
}

In the trade management hub, "CheckCloseAtTargets()" closes all positions ("trade.PositionClose()") when the price hits "zoneTargetHigh" (buy) or "zoneTargetlow" (sell), retrying up to 10 times with delays ("Sleep(100)") and logging errors ("GetLastError()"). It calls "Reset()" to restore "currentLotSize"=0.1, clear "lastOrderType", "lastOrderPrice", and flags ("isRecovery", "isFirstPosition"). "applyTrailingStop()" applies a 30-pip trailing stop ("slPoints"=30) to the first position ("isFirstPosition") if "applyTrail"=true, updating SL for buys ("buySl"=bid-30 pips) or sells ("sellSl"=ask+30 pips) if profitable ("minProfitPoints"=0) and in the trade’s favor ("buySl > positionOpenPrice"). For example, on EURUSD, a buy at 1.2050 with bid dropping to 1.2020 triggers a sell at 0.2 lots; if bid rises to 1.2110, the buy’s SL trails to 1.2080, and positions close at 1.2110, like optimizing the engine’s output. Note: The "Print()" message in "OpenTrade()" for sells incorrectly says “RECOVERY BUY” (should be “RECOVERY SELL”).

Phase 5: Shutting Down the System—Cleaning Up Resources

As our expedition concludes, we shut down the system, ensuring resource release.

void OnDeinit(const int reason){
   if (rsiHandle != INVALID_HANDLE){
      IndicatorRelease(rsiHandle);
      ArrayFree(rsiBuffer);
   }
   Print("Zone Recovery Strategy deinitialized");
}

In the shutdown control room, "OnDeinit()" releases the RSI handle ("IndicatorRelease(rsiHandle)") and frees the buffer ("ArrayFree(rsiBuffer)"), logging deinitialization, ensuring a clean shutdown, like powering down the engine’s systems.

Why This EA is a Risk Management Triumph

The Zone Recovery Advanced Class RSI Single EA is a risk management triumph, automating loss recovery with precision, like a master-crafted engine. Its RSI signals ("rsiBuffer") and zone recovery ("ManageZones()", "CheckCloseAtTargets()") balance risk and reward, with trailing stops ("applyTrailingStop()") enhancing profit protection. Picture recovering a buy on EURUSD at 1.2050 with a doubled sell at 1.2020—strategic brilliance! Beginners will value the automated clarity, while experts can enhance its flexibility, making it essential for traders in volatile markets.

Putting It All Together

To deploy this EA:

  1. Open MetaEditor in MetaTrader 5, like entering your risk management hub.

  2. Copy the code, compile with F5, and verify no errors—no engineer wants a faulty engine!

  3. Attach the EA to your chart (e.g., EURUSD H1) with default settings ("applyTrail"=true, lot=0.1, zone=30 pips, target=60 pips, multiplier=2.0).

  4. Monitor logs (e.g., “BUY SIGNAL”, “RECOVERY SELL order placed”) for trade actions.

  5. Test on a demo account first—real capital deserves a trial run!

Conclusion

We’ve engineered a Zone Recovery RSI system that manages trades with precision, like a master-crafted risk management engine. This MQL5 code is your strategic tool, brought to life with a seamless, professional narrative packed with clear explanations and vivid examples to fuel your trading confidence. Whether you’re a novice trader or a seasoned market strategist, this EA empowers you to recover losses and secure profits with ease. Ready to manage risks? Watch our video guide on the website for a step-by-step creation process. Now, safeguard your trading with precision! 🔍

Disclaimer: Trading is like navigating complex markets—challenging and risky. Losses can exceed deposits. Test strategies on a demo account before going live.

Disclaimer: The ideas and strategies presented in this resource are solely those of the author and are intended for informational and educational purposes only. They do not constitute financial advice, and past performance is not indicative of future results. All materials, including but not limited to text, images, files, and any downloadable content, are protected by copyright and intellectual property laws and are the exclusive property of Forex Algo-Trader or its licensors. Reproduction, distribution, modification, or commercial use of these materials without prior written consent from Forex Algo-Trader is strictly prohibited and may result in legal action. Users are advised to exercise extreme caution, perform thorough independent research, and consult with qualified financial professionals before implementing any trading strategies or decisions based on this resource, as trading in financial markets involves significant risk of loss.

Recent Comments

Go to discussion to Comment or View other Comments

No comments yet. Be the first to comment!