Laguerre_RSI_v1.01_mtf

Author: mladen

This script is designed to visually represent market trends by calculating a modified version of the Relative Strength Index (RSI) called the Laguerre RSI and displaying it on a chart. Think of it as a custom speedometer for the market, indicating whether the price is trending upwards or downwards and how strongly.

Here's a breakdown of the script's logic:

  1. Core Calculation (Laguerre RSI): The script's heart is the Laguerre RSI calculation. This calculation takes price data and, using a smoothing technique and a customizable sensitivity factor ("Gama"), generates a value between 0 and 1. This value is plotted on the chart as the "Laguerre RSI" line. A "Gama" close to 1 makes the RSI slower to react, while a value closer to 0 makes it very sensitive.

  2. Smoothing: The script allows for smoothing the price data before the Laguerre RSI is calculated, and/or smoothing the Laguerre RSI directly after it is calculated. Smoothing averages prices over a period to reduce noise. This can make the indicator line smoother and potentially easier to read, but can also delay its reaction to new price movements.

  3. Multi-Timeframe Analysis: It has the ability to calculate the Laguerre RSI based on price data from a different timeframe than the current chart. For instance, you could view a 15-minute chart but calculate the Laguerre RSI based on hourly data. This provides a broader perspective on the trend.

  4. Visual Representation: The primary output is the Laguerre RSI line itself. The script also provides visual cues by drawing arrows when the Laguerre RSI crosses specific levels that you define (Level1, Level2, Level3). These levels can be thought of as thresholds; crossing above or below them might signal potential buying or selling opportunities.

  5. Alerts: The script can generate alerts (visual pop-ups, email, sound) when the Laguerre RSI crosses these defined levels. This provides immediate notification of potential trading signals.

  6. Customization: Users can customize several parameters:

    • Gama: The sensitivity of the Laguerre RSI calculation.
    • PriceType: Which price to use for calculation (e.g., open, close, high, low).
    • Smooth: The type of smoothing to apply.
    • Levels: The threshold levels for generating visual cues and alerts.
    • TimeFrame: The timeframe for the price data used in the Laguerre RSI calculation.
    • Alerts: Options to enable or disable and customize the types of alerts.
  7. Initialization and Cleanup: When the script starts, it sets up the buffers (memory areas to store data), defines how the indicator will be displayed (colors, styles), and creates unique names for the visual elements. When the script is removed, it cleans up by deleting the drawn levels.

In essence, this script is a tool for technical analysis. It calculates a momentum indicator (Laguerre RSI), displays it visually, and provides alerts based on user-defined thresholds, all with the goal of assisting traders in making informed decisions about when to buy or sell.

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

#property indicator_separate_window
#property indicator_buffers 3
#property indicator_minimum 0
#property indicator_maximum 1
#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 int    Smooth        = 0;           // smz: 1...3; if>3 smz=3
extern bool   SmoothPrice   = false;
extern double Level1        = 0.85;
extern double Level2        = 0.50;
extern double Level3        = 0.15;
extern string timeFrame     = "Current time frame";
extern bool   ShowLevels    = true; 
extern bool   ShowCrossings = false; 
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[];
double L4[];
string ShortName;
string IndicatorName;
int    TimeFrame;

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

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

   //
   //
   //
   //
   //
   
   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);
      }      

   //
   //
   //
   //
   //

   IndicatorName     = WindowExpertName();
   TimeFrame         = stringToTimeFrame(timeFrame);
   string shortName  = "Laguerre RSI ";
   if (TimeFrame != Period()) shortName=shortName+TimeFrameToString(TimeFrame);
                              ShortName=MakeUniqueName(shortName," ("+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;

   //
   //
   //
   //
   //
   
   if (TimeFrame != Period())
   {
      datetime TimeArray[];
         limit = MathMax(limit,TimeFrame/Period());
         ArrayCopySeries(TimeArray ,MODE_TIME ,NULL,TimeFrame);
         
         //
         //
         //
         //
         //
         
         for(i=0,int y=0; i<limit; i++)
         {
            if(Time[i]<TimeArray[y]) y++;
               MainBuffer[i] = iCustom(NULL,TimeFrame,IndicatorName,Gama,PriceType,Smooth,SmoothPrice,0,y);
         }
   }
   
   //
   //
   //
   //
   //
   
   if (TimeFrame == Period())
   for(i = limit; i >= 0 ; i--) MainBuffer[i] = LaGuerre(Gama,i,PriceType);
   for(i = limit; i >= 0 ; i--)
   {
      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;


   if (SmoothPrice)
   {
      	L4[i] = Price;
      	Price = smooth(L4,i);
   }
   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) ;
   if (!SmoothPrice)
   {
      L4[i] = RSI;
      RSI   = smooth(L4,i);
   }
   return(RSI);
}

//
//
//
//
//

double smooth(double& array[],int i)
{
   double result;
      if (Smooth <= 0) result = (array[i]);
      if (Smooth == 1) result = (array[i] +   array[i+1] +   array[i+2])/3 ;
      if (Smooth == 2) result = (array[i] + 2*array[i+1] + 2*array[i+2] +   array[i+3])/6 ;
      if (Smooth >= 3) result = (array[i] + 2*array[i+1] + 3*array[i+2] + 3*array[i+3] + 2*array[i+4] + array[i+5])/12 ;
   return(result);
}

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

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="";
   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));
}


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

int stringToTimeFrame(string tfs)
{
   int tf=0;
       tfs = StringUpperCase(tfs);
         if (tfs=="M1" || tfs=="1")     tf=PERIOD_M1;
         if (tfs=="M5" || tfs=="5")     tf=PERIOD_M5;
         if (tfs=="M15"|| tfs=="15")    tf=PERIOD_M15;
         if (tfs=="M30"|| tfs=="30")    tf=PERIOD_M30;
         if (tfs=="H1" || tfs=="60")    tf=PERIOD_H1;
         if (tfs=="H4" || tfs=="240")   tf=PERIOD_H4;
         if (tfs=="D1" || tfs=="1440")  tf=PERIOD_D1;
         if (tfs=="W1" || tfs=="10080") tf=PERIOD_W1;
         if (tfs=="MN" || tfs=="43200") tf=PERIOD_MN1;
         if (tf<Period()) tf=Period();
  return(tf);
}
string TimeFrameToString(int tf)
{
   string tfs="Current time frame";
   switch(tf) {
      case PERIOD_M1:  tfs="M1"  ; break;
      case PERIOD_M5:  tfs="M5"  ; break;
      case PERIOD_M15: tfs="M15" ; break;
      case PERIOD_M30: tfs="M30" ; break;
      case PERIOD_H1:  tfs="H1"  ; break;
      case PERIOD_H4:  tfs="H4"  ; break;
      case PERIOD_D1:  tfs="D1"  ; break;
      case PERIOD_W1:  tfs="W1"  ; break;
      case PERIOD_MN1: tfs="MN1";
   }
   return(tfs);
}

//
//
//
//
//

string StringUpperCase(string str)
{
   string   s = str;
   int      lenght = StringLen(str) - 1;
   int      char;
   
   while(lenght >= 0)
      {
         char = StringGetChar(s, lenght);
         
         //
         //
         //
         //
         //
         
         if((char > 96 && char < 123) || (char > 223 && char < 256))
                  s = StringSetChar(s, lenght, char - 32);
         else 
              if(char > -33 && char < 0)
                  s = StringSetChar(s, lenght, char + 224);
         lenght--;
   }
   
   //
   //
   //
   //
   //
   
   return(s);
}

Comments