This document details the mathematical and architectural corrections applied to the original MQL5 implementation of the Reverse RSI indicator: [Free download of the 'Reverse_Engineering_RSI' indicator by 'Scriptor' for MetaTrader 5 in the MQL5 Code Base, 2018.07.09](https://www.mql5.com/en/code/21046).
The objective of the Reverse RSI indicator is to plot the exact price levels where the Relative Strength Index (RSI) would reach specific thresholds (like 70 for overbought and 30 for oversold).
| **Target RSI Level** | Dynamic (uses a Moving Average of the current RSI). | **Fixed/Static** (uses user-defined levels, default 70 and 30). |
| **Smoothing Method** | MT5 Library EMA on Buffers (`2N-1` period approximation). | **Exact Wilder Smoothing** recursive implementation. |
| **Temporal Alignment** | Uses current bar averages (`i`), creating a feedback loop. | Uses previous bar averages (`i-1` or `i+1` in series) for **true lookahead**. |
| **Plot Count** | 1 Line (Dynamic "Fair Value" line). | **2 Bands** (Overbought crimson band and Oversold green band). |
| **Initialization Seed** | None (starts with raw value, causing persistent offsets). | **Simple Moving Average (SMA)** of the first window (identical to standard RSI). |
### 2.1 Fixed Target RSI Levels vs. Dynamic Smoothing (The Purpose Gap)
***Original Issue:** The original code used a moving average of the actual RSI as its target (`RSI_MA = BufferAvgRSI[i]`). This calculated the price needed to keep the RSI at its average line, resulting in a single "fair value" band. It failed to answer the primary trading question: *"At what price will my RSI hit the 70 overbought level?"*
***Correction:** We replaced the dynamic target with user-configurable levels (`InpObLevel` and `InpOsLevel`). The code now calculates and plots the two distinct boundaries corresponding to these target RSI values.
### 2.2 Correcting the Temporal Lookahead (Preventing Self-Contamination)
***Original Issue:** The original formula used `BufferAvgUP[i]` and `BufferAvgDN[i]` (the smoothed values for the *current* bar) to solve for the *current* bar's target price. Since the current bar's averages already include the current bar's price change, this created a logical contradiction and contaminated the mathematical deduction.
***Correction:** To find the price at bar $i$ that results in target RSI $T$, we must compute using the state of the indicator *before* bar $i$ was formed. The calculations now correctly extract the preceding bar's state (`BufferAvgU[i-1]` and `BufferAvgD[i-1]` in normal indexing order):
$$AU_0 = AvgU_{i-1} \times (N-1)$$
$$AD_0 = AvgD_{i-1} \times (N-1)$$
### 2.3 Eliminating Initialization Offsets (Wilder Smoothing vs. EMA)
***Original Issue:** Standard MQL5 `iRSI` initializes its average gain/loss buffers with a Simple Moving Average (SMA) over the first $N$ bars. The original code used `ExponentialMAOnBuffer` to smooth gains/losses. Since `ExponentialMAOnBuffer` initializes using the first raw buffer value without an SMA seed, it created a permanent offset that decayed slowly but never reached zero.
***Correction:** We implemented a manual loop for the Wilder Smoothing that calculates an SMA for the first $N$ bars to establish an exact matching seed, then switches to the recursive Wilder calculation: