LaguerreRSI

Download script
Author: Coded by Witold Wozniak
LaguerreRSI

This indicator is designed to provide traders with a sophisticated way to measure momentum and identify overbought or oversold conditions in financial markets. Unlike standard oscillators that might react slowly or create "noisy" signals, this tool utilizes a specific mathematical framework known as the Laguerre RSI, which aims to balance responsiveness with smoothness.

How the Logic Works

The script processes market data through several distinct layers to arrive at a final visual reading:

1. Data Smoothing (Laguerre Filters) Instead of looking directly at the raw price of an asset (like a stock or currency), the tool creates four separate internal "filters." Each filter takes the previous value and blends it with the current price based on a specific sensitivity factor (represented by the Gamma setting). This creates a cascading effect where each subsequent filter becomes more refined. By doing this, the tool filters out minor market "jitters" while still maintaining the core trend of the price movement.

2. Measuring Momentum Dynamics Once these four filtered values are established, the script calculates the differences between them. It looks at how much each value moves relative to the one before it.

  • If the values are increasing in a specific direction, they contribute to an "Upward" momentum total.
  • If they are decreasing or moving in opposition, they contribute to a "Downward" momentum total.

3. The Final RSI Calculation The final output (the line you see on your chart) is determined by comparing the total Upward momentum against the total Downward momentum. It essentially asks: "What percentage of the current price movement is driven by upward pressure versus downward pressure?"

Practical Application for the User

The result is a normalized value that moves between 0 and 1 (often displayed as 0% to 100% on many platforms). Because of the way the Laguerre filters are structured, this indicator is specifically engineered to:

  • Identify when a trend is becoming exhausted.
  • Provide clearer signals for potential reversals compared to standard RSI models.
  • Help traders spot "overbought" (near 0.8) or "oversold" (near 0.2) zones with more precision, as the underlying math prioritizes the structural integrity of the trend over simple price spikes.
Miscellaneous
Implements a curve of type %1
12 Views
0 Downloads
0 Favorites
LaguerreRSI
//+------------------------------------------------------------------+
//|                                                  LaguerreRSI.mq4 |
//|                                                                  |
//| Laguerre RSI                                                     |
//|                                                                  |
//| Algorithm taken from book                                        |
//|     "Cybernetics Analysis for Stock and Futures"                 |
//| by John F. Ehlers                                                |
//|                                                                  |
//|                                              contact@mqlsoft.com |
//|                                          http://www.mqlsoft.com/ |
//+------------------------------------------------------------------+
#property copyright "Coded by Witold Wozniak"
#property link      "www.mqlsoft.com"

#property indicator_separate_window
#property indicator_buffers 2
#property indicator_color1 Red
#property indicator_color2 Blue
#property indicator_minimum 0
#property indicator_maximum 1
#property indicator_level1 0.8
#property indicator_level2 0.2

extern double Gamma = 0.5;

double RSI[];
double L0[];
double L1[];
double L2[];
double L3[];

int buffers = 0;
int drawBegin = 0;

int init() {
    drawBegin = 4;
    initBuffer(RSI, "Laguerre RSI", DRAW_LINE);
    initBuffer(L0);
    initBuffer(L1);
    initBuffer(L2);
    initBuffer(L3);
    IndicatorBuffers(buffers);
    IndicatorShortName("Laguerre RSI [" + DoubleToStr(Gamma, 2) + "]");  
    return (0);
}

int start() {
    if (Bars <= drawBegin) return (0);
    int countedBars = IndicatorCounted();
    if (countedBars < 0) return (-1);
    if (countedBars > 0) countedBars--;
    int s, limit = Bars - countedBars - 1;
    for (s = limit; s >= 0; s--) {
        L0[s] = (1.0 - Gamma) * Close[s] + Gamma * L0[s + 1];
        L1[s] = -Gamma * L0[s] + L0[s + 1] + Gamma * L1[s + 1];
        L2[s] = -Gamma * L1[s] + L1[s + 1] + Gamma * L2[s + 1];
        L3[s] = -Gamma * L2[s] + L2[s + 1] + Gamma * L3[s + 1];
        double CU = 0.0;
        double CD = 0.0;
        if (L0[s] >= L1[s]) {
            CU = L0[s] - L1[s];
        } else {
            CD = L1[s] - L0[s];
        }
        if (L1[s] >= L2[s]) {
            CU += L1[s] - L2[s];
        } else {
            CD += L2[s] - L1[s];
        }
        if (L2[s] >= L3[s]) {
            CU += L2[s] - L3[s];
        } else {
            CD += L3[s] - L2[s];
        }        
        RSI[s] = 0.0;
        if (CU + CD != 0.0) {
            RSI[s] = CU / (CU + CD);
        }
    }   
    return (0);   
}

void initBuffer(double array[], string label = "", int type = DRAW_NONE, int arrow = 0, int style = EMPTY, int width = EMPTY, color clr = CLR_NONE) {
    SetIndexBuffer(buffers, array);
    SetIndexLabel(buffers, label);
    SetIndexEmptyValue(buffers, EMPTY_VALUE);
    SetIndexDrawBegin(buffers, drawBegin);
    SetIndexShift(buffers, 0);
    SetIndexStyle(buffers, type, style, width);
    SetIndexArrow(buffers, arrow);
    buffers++;
}

Comments