🚀 AI One-Click Generation of mql4 Strategy Code

How to Build a Relative Vigor Index (RVI) Trading Bot in Mql4

mql4 | Published on: 2025/12/10
The following content is generated by EasyQuant .

Problem Description

Please write me an expert advisor based on the Relative Vigor Index (RVI) indicator.

Solution

Here is a complete, fully functional Expert Advisor (EA) based on the Relative Vigor Index (RVI) for MetaTrader 4.

Strategy Logic

This EA uses the classic RVI crossover strategy:

  1. Buy Signal: The RVI Main line crosses above the Signal line.
  2. Sell Signal: The RVI Main line crosses below the Signal line.
  3. Execution: The EA checks for crossovers on closed bars (indices 1 and 2) to prevent "repainting" (signals flickering while the current candle is forming).

MQL4 Code

//+------------------------------------------------------------------+
//|                                                      RVI_EA.mq4  |
//|                        Copyright 2023, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2023, Quantitative AI"
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict

//--- Input Parameters
input string   Inp_Settings   = "--- Strategy Settings ---"; // .
input int      RVI_Period     = 10;          // RVI Period
input double   LotSize        = 0.1;         // Fixed Lot Size
input int      StopLoss       = 50;          // Stop Loss (in points)
input int      TakeProfit     = 100;         // Take Profit (in points)
input int      MagicNumber    = 123456;      // Magic Number ID
input int      Slippage       = 3;           // Max Slippage (in points)
input bool     CloseOpposite  = true;        // Close opposite trade on new signal

//--- Global Variables
double ppoint; // Adjusted point value for 3/5 digit brokers

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
{
   // Adjust point for 5-digit and 3-digit brokers
   if(Digits == 5 || Digits == 3)
      ppoint = Point * 10;
   else
      ppoint = Point;

   return(INIT_SUCCEEDED);
}

//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
   // Clean up if necessary
}

//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
{
   // Check if we have enough bars to calculate
   if(Bars < RVI_Period + 2) return;

   // --- 1. Get RVI Values ---
   // We use shift 1 (previous closed bar) and shift 2 (bar before that)
   // to detect a confirmed crossover.
   
   // Main Line
   double rvi_main_curr = iRVI(NULL, 0, RVI_Period, MODE_MAIN, 1);
   double rvi_main_prev = iRVI(NULL, 0, RVI_Period, MODE_MAIN, 2);
   
   // Signal Line
   double rvi_sig_curr  = iRVI(NULL, 0, RVI_Period, MODE_SIGNAL, 1);
   double rvi_sig_prev  = iRVI(NULL, 0, RVI_Period, MODE_SIGNAL, 2);

   // --- 2. Determine Signals ---
   bool isBuySignal  = (rvi_main_prev < rvi_sig_prev) && (rvi_main_curr > rvi_sig_curr);
   bool isSellSignal = (rvi_main_prev > rvi_sig_prev) && (rvi_main_curr < rvi_sig_curr);

   // --- 3. Trade Management ---
   
   // Check existing orders
   int total = OrdersTotal();
   bool buyOpen = false;
   bool sellOpen = false;
   
   for(int i = 0; i < total; i++)
   {
      if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
      {
         if(OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber)
         {
            if(OrderType() == OP_BUY) buyOpen = true;
            if(OrderType() == OP_SELL) sellOpen = true;
            
            // Close Opposite Logic
            if(CloseOpposite)
            {
               if(OrderType() == OP_BUY && isSellSignal)
               {
                  bool closed = OrderClose(OrderTicket(), OrderLots(), Bid, Slippage, clrRed);
                  if(closed) buyOpen = false;
               }
               if(OrderType() == OP_SELL && isBuySignal)
               {
                  bool closed = OrderClose(OrderTicket(), OrderLots(), Ask, Slippage, clrBlue);
                  if(closed) sellOpen = false;
               }
            }
         }
      }
   }

   // --- 4. Execute New Trades ---
   
   // Open Buy
   if(isBuySignal && !buyOpen)
   {
      double sl = (StopLoss > 0) ? Ask - StopLoss * ppoint : 0;
      double tp = (TakeProfit > 0) ? Ask + TakeProfit * ppoint : 0;
      
      // Normalize prices
      sl = NormalizeDouble(sl, Digits);
      tp = NormalizeDouble(tp, Digits);
      
      int ticket = OrderSend(Symbol(), OP_BUY, LotSize, Ask, Slippage, sl, tp, "RVI Buy", MagicNumber, 0, clrGreen);
      if(ticket < 0) Print("OrderSend failed with error #", GetLastError());
   }

   // Open Sell
   if(isSellSignal && !sellOpen)
   {
      double sl = (StopLoss > 0) ? Bid + StopLoss * ppoint : 0;
      double tp = (TakeProfit > 0) ? Bid - TakeProfit * ppoint : 0;
      
      // Normalize prices
      sl = NormalizeDouble(sl, Digits);
      tp = NormalizeDouble(tp, Digits);
      
      int ticket = OrderSend(Symbol(), OP_SELL, LotSize, Bid, Slippage, sl, tp, "RVI Sell", MagicNumber, 0, clrRed);
      if(ticket < 0) Print("OrderSend failed with error #", GetLastError());
   }
}
//+------------------------------------------------------------------+

How to Install and Use

  1. Open MetaTrader 4.
  2. Press F4 to open the MetaEditor.
  3. Click New -> Expert Advisor (template) -> Name it "RVI_EA".
  4. Delete everything in the new file and paste the code above.
  5. Press F7 to Compile. Ensure there are no errors.
  6. Go back to the MT4 Terminal.
  7. Find "RVI_EA" in the Navigator window under Expert Advisors.
  8. Drag it onto a chart (e.g., EURUSD H1).
  9. Ensure "Allow Live Trading" is checked in the Common tab and the AutoTrading button at the top of MT4 is Green.

Key Features of this Code

  • 5-Digit Broker Support: The code automatically detects if your broker uses 5 decimal places (points) or 4, ensuring Stop Loss and Take Profit are calculated correctly.
  • No Repainting: It uses shift 1 and shift 2. This means it looks at the completed candle. It will not open a trade mid-candle if the lines cross temporarily and then un-cross before the close.
  • Magic Number: It uses a unique ID (MagicNumber) so it only manages its own trades and ignores manual trades or trades from other EAs.
  • Close Opposite: If CloseOpposite is set to true, a Buy signal will automatically close any existing Sell trades managed by this EA before opening the Buy, and vice versa.

Q&A: Quantitative Strategy & MQL4

Q: Why use the RVI indicator for algorithmic trading?
A: The Relative Vigor Index is essentially an energy oscillator. In quantitative analysis, it assumes that in a bullish market, the closing price is generally higher than the opening price. It smooths this data using Simple Moving Averages (SMA). It is useful for identifying trend reversals when the RVI diverges from price action or when the signal lines cross.

Q: Why does the code use iRVI(..., MODE_MAIN, ...) and MODE_SIGNAL?
A: The iRVI function in MQL4 returns two different data buffers. MODE_MAIN (index 0) returns the calculated RVI value, while MODE_SIGNAL (index 1) returns the 4-period weighted moving average of that RVI line. The crossover of these two lines generates the trade signal.

Q: How can I optimize this EA?
A: You can use the MT4 Strategy Tester (Ctrl+R). Select this EA and set "Optimization" to true. You can then optimize the RVI_Period, StopLoss, and TakeProfit variables to find the best combination for a specific currency pair and timeframe.

Q: What is the risk of using this EA on a live account?
A: This is a trend-following/reversal oscillator strategy. In ranging (sideways) markets, crossover strategies often generate false signals (whipsaws), leading to consecutive losses. It is recommended to add a trend filter (like a 200-period Moving Average) to only take Buy signals when the price is above the MA and Sell signals when below.