Laguerre RSI v1.00

Download script
Author: mladen
Laguerre RSI v1.00

Overview of the Laguerre RSI Indicator

The LaGuerre RSI is a specialized technical analysis tool designed to measure the momentum and velocity of price movements. Unlike standard oscillators that can sometimes be "noisy" or lag significantly behind market action, this script utilizes a sophisticated mathematical approach (based on Laguerre functions) to provide a smoother, more responsive representation of market strength.

Core Logic and Mechanics

1. Data Processing (The Foundation) The indicator begins by calculating a base price movement using a simple moving average. This ensures that the underlying data is stabilized before the main calculations occur, filtering out minor "market jitters" that might otherwise produce false signals.

2. The Laguerre Algorithm The heart of this script lies in its multi-layered calculation system:

  • Layered Smoothing: The logic processes the price through four distinct consecutive layers (referred to internally as L0 through L3). Each layer depends on the result of the previous one, adjusted by a "Gamma" factor.
  • Sensitivity Control: The Gamma value is a key setting that determines how much weight is given to recent price changes versus historical data. This allows the indicator to balance responsiveness with stability.
  • Momentum Calculation: By comparing these layers against one another, the script calculates the "Cumulative Up" and "Cumulative Down" movements. The final RSI value is then derived by dividing the upward momentum by the total momentum (up + down).

3. Visual Signaling The indicator provides several visual aids to help traders identify key turning points:

  • Trend Line: A primary line fluctuates between 0 and 1, representing the current strength of the trend.
  • Level Crossings: The script specifically monitors when the momentum line crosses predefined thresholds (Level 1 and Level 3). When these crossings occur, the script can automatically place visual markers (arrows) on the chart.
  • Dynamic Zones: The tool includes a system to draw visual boundaries on the indicator window, creating "zones" that help traders identify overbought or oversold territory relative to their specific settings.

Notification System

To ensure traders do not have to watch the screen constantly, the script includes an integrated alert engine. It is programmed to detect specific "Level Crossings"—moments where the momentum shifts significantly enough to breach a key threshold. When these events occur, the script can trigger multiple notification types:

  • On-Screen Alerts: Pop-up messages for immediate awareness.
  • Audio Alerts: Sound files to notify you of sudden movements.
  • Email Notifications: Remote alerts sent directly to your device (if configured).

Summary for Traders

Essentially, this script transforms complex price fluctuations into a smoothed momentum stream. It tells you not just where the price is moving, but how fast and with how much strength it is getting there. By focusing on the "crossings" of specific levels, it highlights potential shifts in market sentiment, allowing for more objective entries and exits based on momentum shifts rather than raw price action alone.

Indicators Used
Moving average indicator
Miscellaneous
Implements a curve of type %1It issuies visual alerts to the screenIt sends emailsIt plays sound alerts
12 Views
0 Downloads
0 Favorites
Laguerre RSI v1.00
//+------------------------------------------------------------------+
//|                                           LaGuerre RSI v1.00.mq4 |
//|                                                           mladen |
//+------------------------------------------------------------------+
#property copyright "mladen"
#property link      ""

#property indicator_separate_window
#property indicator_minimum 0
#property indicator_maximum 1
#property indicator_buffers 3
#property indicator_color1 Green
#property indicator_color2 Lime
#property indicator_color3 OrangeRed

//
//
// Alternative: Gama = 0.55,levels 0.75,0.45,0.15
//
//

extern double Gama          = 0.70;
extern int    PriceType     = 0;
extern double Level1        = 0.75;
extern double Level2        = 0.50;
extern double Level3        = 0.25;
extern bool   ShowLevels    = true; 
extern bool   ShowCrossings = true; 
extern bool   alertsOn      = false;
extern bool   alertsMessage = true;
extern bool   alertsSound   = false;
extern bool   alertsEmail   = false;
extern color  LevelsColor   = C'30,33,36';

//
//
//
//
//

double MainBuffer[];
double CUpBuffer[];
double CDnBuffer[];
double L0[];
double L1[];
double L2[];
double L3[];
string ShortName;


//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+

int init()
{
   IndicatorBuffers(7);
   SetIndexBuffer(0, MainBuffer);
   SetIndexBuffer(1, CUpBuffer);
   SetIndexBuffer(2, CDnBuffer);
   SetIndexBuffer(3, L0);
   SetIndexBuffer(4, L1);
   SetIndexBuffer(5, L2);
   SetIndexBuffer(6, L3);

   //
   //
   //
   //
   //
   
   if (ShowCrossings)
      {
         SetIndexStyle(1,DRAW_ARROW);         
         SetIndexStyle(2,DRAW_ARROW);         
         SetIndexArrow(1,159);
         SetIndexArrow(2,159);
      }
   else
      {
         SetIndexStyle(1,DRAW_NONE);
         SetIndexStyle(2,DRAW_NONE);
      }      

   //
   //
   //
   //
   //
   
   ShortName=MakeUniqueName("Laguerre RSI "," ("+DoubleToStr(Gama,2)+")");
   IndicatorShortName(ShortName);
   SetIndexLabel(0,"Laguerre RSI");
   return(0);
}
int deinit()
{
   DeleteBounds();
   return(0);
}

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+

int start()
{
   int    counted_bars=IndicatorCounted();
   int    i,limit;

   if(counted_bars<0) return(-1);
   if(counted_bars>0) counted_bars--;
         limit = Bars - counted_bars;

   //
   //
   //
   //
   //
   
   for(i = limit; i >= 0 ; i--)
      {
         MainBuffer[i] = LaGuerre(Gama,i,PriceType);
         CUpBuffer[i]  = EMPTY_VALUE;
         CDnBuffer[i]  = EMPTY_VALUE;
               if (MainBuffer[i] > Level1 && MainBuffer[i+1] < Level1) CUpBuffer[i] = Level1;
               if (MainBuffer[i] < Level1 && MainBuffer[i+1] > Level1) CDnBuffer[i] = Level1;
               if (MainBuffer[i] > Level3 && MainBuffer[i+1] < Level3) CUpBuffer[i] = Level3;
               if (MainBuffer[i] < Level3 && MainBuffer[i+1] > Level3) CDnBuffer[i] = Level3;
      }            
   
   //
   //
   //
   //
   //

   if (ShowLevels) UpdateBounds();
   if (alertsOn) CheckCrossings();
   return(0);
}


//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
//
//
//
//
//

double LaGuerre(double gamma, int i, int priceType)
{
	double Price = iMA(NULL,0,1,0,MODE_SMA,priceType,i);
	double RSI   = 0.00;
	double CU    = 0.00;
	double CD    = 0.00;


   L0[i] = (1.0 - gamma)*Price    + gamma*L0[i+1];
	L1[i] = -gamma*L0[i] + L0[i+1] + gamma*L1[i+1];
	L2[i] = -gamma*L1[i] + L1[i+1] + gamma*L2[i+1];
	L3[i] = -gamma*L2[i] + L2[i+1] + gamma*L3[i+1];

	if (L0[i] >= L1[i])
   			CU = L0[i] - L1[i];
	else	   CD = L1[i] - L0[i];
	if (L1[i] >= L2[i])
   			CU = CU + L1[i] - L2[i];
	else	   CD = CD + L2[i] - L1[i];
	if (L2[i] >= L3[i])
			   CU = CU + L2[i] - L3[i];
	else	   CD = CD + L3[i] - L2[i];

   //
   //
   //
   //
   //
   
	if (CU + CD != 0) RSI = CU / (CU + CD);
   return(RSI);
}


//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
//
//
//
//
//

void CheckCrossings()
{
   if (CUpBuffer[0] == Level1) doAlert("level "+DoubleToStr(Level1,2)+" crossed up");
   if (CDnBuffer[0] == Level1) doAlert("level "+DoubleToStr(Level1,2)+" crossed down");
   if (CUpBuffer[0] == Level3) doAlert("level "+DoubleToStr(Level3,2)+" crossed up");
   if (CDnBuffer[0] == Level3) doAlert("level "+DoubleToStr(Level3,2)+" crossed down");
}

//
//
//
//
//

void doAlert(string doWhat)
{
   static string   previousAlert="nothing";
   static datetime previousTime;
   string message;
   
      if (previousAlert != doWhat || previousTime != Time[0]) {
          previousAlert  = doWhat;
          previousTime   = Time[0];

          //
          //
          //
          //
          //

          message =  StringConcatenate(Symbol()," at ",TimeToStr(TimeLocal(),TIME_SECONDS)," Laguerre ",doWhat);
             if (alertsMessage) Alert(message);
             if (alertsEmail)   SendMail(StringConcatenate(Symbol()," Laguerre line crossing"),message);
             if (alertsSound)   PlaySound("alert2.wav");
      }
}


//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
//
//
//
//
//

string MakeUniqueName(string first, string rest)
{
   string result = first+(MathRand()%1001)+rest;

   while (WindowFind(result)> 0)
          result = first+(MathRand()%1001)+rest;
   return(result);
}

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
//
//
//
//
//

void DeleteBounds()
{
   ObjectDelete(ShortName+"-1");
   ObjectDelete(ShortName+"-2");
   ObjectDelete(ShortName+"-3");
}
void UpdateBounds()
{
   if (Level1 > 0) SetUpBound(ShortName+"-1",1.0000     ,Level1);
   if (Level2 > 0) SetUpBound(ShortName+"-2",Level2*1.01,Level2*0.99);
   if (Level3 > 0) SetUpBound(ShortName+"-3",Level3     ,     0.0000);
}
void SetUpBound(string name, double up, double down,int objType=OBJ_RECTANGLE)
{
   if (ObjectFind(name) == -1)
      {
         ObjectCreate(name,objType,WindowFind(ShortName),0,0);
         ObjectSet(name,OBJPROP_PRICE1,up);
         ObjectSet(name,OBJPROP_PRICE2,down);
         ObjectSet(name,OBJPROP_COLOR,LevelsColor);
         ObjectSet(name,OBJPROP_BACK,true);
         ObjectSet(name,OBJPROP_TIME1,iTime(NULL,0,Bars-1));
      }
   if (ObjectGet(name,OBJPROP_TIME2) != iTime(NULL,0,0))
       ObjectSet(name,OBJPROP_TIME2,    iTime(NULL,0,0));
}

Comments