65 行
4.8 KiB
Markdown
65 行
4.8 KiB
Markdown
# Reverse RSI Bands
|
|
|
|
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).
|
|
|
|
---
|
|
|
|
## 1. Core Enhancements
|
|
|
|
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).
|
|
|
|
| Feature | Original Code (`Reverse_Engineering_RSI.mq5`) | Corrected Code (`Reverse_RSI_Bands.mq5`) |
|
|
| :--- | :--- | :--- |
|
|
| **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. Detailed Technical & Mathematical Corrections
|
|
|
|
### 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:
|
|
$$AvgU_i = AvgU_{i-1} \times (1 - \alpha) + UP_i \times \alpha$$
|
|
Where $\alpha = 1/N$. This matches the standard RSI internal state perfectly.
|
|
|
|
---
|
|
|
|
## 3. Mathematical Verification
|
|
|
|
For any bar $i$, we want the target price $P_i$ to result in $RSI_i = T$ (where $T$ is the target level).
|
|
Let $RS = T / (100 - T)$. We want:
|
|
$$\frac{AvgU_i}{AvgD_i} = RS$$
|
|
|
|
Substituting the recursive Wilder formulas:
|
|
$$\frac{AU_0 + U_i}{AD_0 + D_i} = RS \implies AU_0 + U_i = RS \times (AD_0 + D_i)$$
|
|
|
|
Where $U_i$ and $D_i$ are the current bar gains/losses, and $AU_0$, $AD_0$ are the decay-adjusted sums from the previous bar.
|
|
|
|
### Case 1: Positive Price Change ($P_i \ge P_{i-1}$)
|
|
Here, $U_i = P_i - P_{i-1}$ and $D_i = 0$.
|
|
$$AU_0 + (P_i - P_{i-1}) = RS \times AD_0$$
|
|
$$P_i = P_{i-1} + \underbrace{RS \times AD_0 - AU_0}_{x}$$
|
|
This is valid if the price change is positive, i.e., $x \ge 0$.
|
|
|
|
### Case 2: Negative Price Change ($P_i < P_{i-1}$)
|
|
Here, $U_i = 0$ and $D_i = P_{i-1} - P_i$.
|
|
$$AU_0 = RS \times (AD_0 + P_{i-1} - P_i)$$
|
|
$$P_{i-1} - P_i = \frac{AU_0}{RS} - AD_0$$
|
|
$$P_i = P_{i-1} + AD_0 - \frac{AU_0}{RS} = P_{i-1} + x \times \frac{100 - T}{T}$$
|
|
This is valid if the price change is negative, which occurs exactly when $x < 0$.
|
|
|
|
The implementation in `Reverse_RSI_Bands.mq5` implements this piecewise logic with 100% mathematical precision.
|