Laguerre RSI v1.00
Download scriptOverview 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.
//+------------------------------------------------------------------+
//| 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