NonLagMA_v7
Download scriptThis script is a sophisticated technical analysis tool designed to track market trends while specifically addressing the common issue of "lag"—the delay between a price movement and its appearance on a standard moving average. By using a specialized mathematical approach, it aims to provide a smoother, more responsive visual of where the market is heading.
Core Logic & Functionality
1. Advanced Smoothing Technique Unlike basic moving averages that treat all past data points equally or simply look at the most recent ones, this script uses a weighted calculation. It applies specific mathematical coefficients to different segments of historical price data. This allows the indicator to remain "tight" to current price action while filtering out minor market "noise," resulting in a line that feels more reactive than standard tools.
2. Dynamic Volatility Filtering One of the unique features of this tool is its ability to "filter" out insignificant movements. It calculates the standard deviation (a measure of how much the price typically swings) over a specific period. If a change in the moving average is smaller than a predefined percentage of that volatility, the script ignores the movement and holds the previous value steady. This prevents the indicator from "jittering" during flat markets.
3. Trend Detection & Color Coding The logic identifies the direction of the market by comparing the current value of the moving average against its previous value:
- Upward Trend: If the average moves up beyond the volatility filter, the script recognizes a bullish trend and highlights it (typically in one color).
- Downward Trend: If the average moves down beyond the filter, it recognizes a bearish trend and highlights it in a different color.
4. Visual Continuity To ensure the chart is easy to read, the script includes a "Backfill" logic. When the trend switches (e.g., from up to down), it ensures that the colors connect smoothly across the transition point. This prevents visual gaps on your chart, providing a continuous ribbon of color that represents the prevailing momentum.
5. Automated Alerts The script continuously monitors for "Crossover" events—specifically when the trend direction flips from negative to positive (potential Buy signal) or from positive to negative (potential Sell signal). When these shifts occur, and provided there is active trading volume, the tool is programmed to trigger a notification alert to the user.
Summary of User Benefits
- Reduced Lag: Get a faster look at trend changes than standard moving averages provide.
- Noise Reduction: The dynamic filter prevents you from reacting to minor price fluctuations that don't represent a real change in trend.
- Clear Visuals: The color-changing lines provide an immediate, intuitive sense of market direction at a glance.
- Proactive Notifications: Receive instant alerts when the logic detects a significant shift in momentum.
//+------------------------------------------------------------------+
//| NonLagMA_v7.mq4 |
//| Copyright © 2006, TrendLaboratory |
//| http://finance.groups.yahoo.com/group/TrendLaboratory |
//| E-mail: igorad2003@yahoo.co.uk |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2006, TrendLaboratory"
#property link "http://finance.groups.yahoo.com/group/TrendLaboratory"
#property indicator_chart_window
#property indicator_buffers 3
#property indicator_color1 Magenta
#property indicator_width1 2
#property indicator_color2 Yellow
#property indicator_width2 2
#property indicator_color3 Tomato
#property indicator_width3 2
//---- input parameters
extern int Price = 0; //Apply to Price(0-Close;1-Open;2-High;3-Low;4-Median price;5-Typical price;6-Weighted Close)
extern int Length = 14; //Period of NonLagMA
extern int Displace = -3; //DispLace or Shift was 0
extern double PctFilter = 2; //Dynamic filter in decimal
extern int Color = 1; //Switch of Color mode (1-color)
extern int ColorBarBack = 1; //Bar back for color mode
extern double Deviation = 0; //Up/down deviation
extern int SoundAlertMode = 1; //Sound Alert switch
//---- indicator buffers
double MABuffer[];
double UpBuffer[];
double DnBuffer[];
double trend[];
double Del[];
double AvgDel[];
double alertTag;
double alfa[];
int i, Phase, Len, Cycle=4;
double Coeff, beta, t, Sum, Weight, g;
double pi = 3.1415926535;
bool UpTrendAlert=false, DownTrendAlert=false;
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int init()
{
IndicatorBuffers(6);
SetIndexStyle(0,DRAW_LINE,0,5);
SetIndexBuffer(0,MABuffer);
SetIndexStyle(1,DRAW_LINE,0,5);
SetIndexBuffer(1,UpBuffer);
SetIndexStyle(2,DRAW_LINE,0,5);
SetIndexBuffer(2,DnBuffer);
SetIndexBuffer(3,trend);
SetIndexBuffer(4,Del);
SetIndexBuffer(5,AvgDel);
string short_name;
//---- indicator line
IndicatorDigits(MarketInfo(Symbol(),MODE_DIGITS));
//---- name for DataWindow and indicator subwindow label
short_name="NonLagMA("+Length+")";
IndicatorShortName(short_name);
SetIndexLabel(0,"NonLagMA");
SetIndexLabel(1,"Up");
SetIndexLabel(2,"Dn");
//----
SetIndexShift(0,Displace);
SetIndexShift(1,Displace);
SetIndexShift(2,Displace);
SetIndexEmptyValue(0,EMPTY_VALUE);
SetIndexEmptyValue(1,EMPTY_VALUE);
SetIndexEmptyValue(2,EMPTY_VALUE);
SetIndexDrawBegin(0,Length*Cycle+Length+1);
SetIndexDrawBegin(1,Length*Cycle+Length+1);
SetIndexDrawBegin(2,Length*Cycle+Length+1);
//----
Coeff = 3*pi;
Phase = Length-1;
Len = Length*Cycle + Phase;
ArrayResize(alfa,Len);
Weight=0;
for (i=0;i<Len-1;i++)
{
if (i<=Phase-1) t = 1.0*i/(Phase-1);
else t = 1.0 + (i-Phase+1)*(2.0*Cycle-1.0)/(Cycle*Length-1.0);
beta = MathCos(pi*t);
g = 1.0/(Coeff*t+1);
if (t <= 0.5 ) g = 1;
alfa[i] = g * beta;
Weight += alfa[i];
}
return(0);
}
//+------------------------------------------------------------------+
//| NonLagMA_v7 |
//+------------------------------------------------------------------+
int start()
{
int i,shift, counted_bars=IndicatorCounted(),limit;
double price;
if ( counted_bars > 0 ) limit=Bars-counted_bars;
if ( counted_bars < 0 ) return(0);
if ( counted_bars ==0 ) limit=Bars-Len-1;
if ( counted_bars < 1 )
for(i=1;i<Length*Cycle+Length;i++)
{
MABuffer[Bars-i]=0;
UpBuffer[Bars-i]=0;
DnBuffer[Bars-i]=0;
}
for(shift=limit;shift>=0;shift--)
{
Sum = 0;
for (i=0;i<=Len-1;i++)
{
price = iMA(NULL,0,1,0,3,Price,i+shift);
Sum += alfa[i]*price;
}
if (Weight > 0) MABuffer[shift] = (1.0+Deviation/100)*Sum/Weight;
if (PctFilter>0)
{
Del[shift] = MathAbs(MABuffer[shift] - MABuffer[shift+1]);
double sumdel=0;
for (i=0;i<=Length-1;i++) sumdel = sumdel+Del[shift+i];
AvgDel[shift] = sumdel/Length;
double sumpow = 0;
for (i=0;i<=Length-1;i++) sumpow+=MathPow(Del[shift+i]-AvgDel[shift+i],2);
double StdDev = MathSqrt(sumpow/Length);
double Filter = PctFilter * StdDev;
if( MathAbs(MABuffer[shift]-MABuffer[shift+1]) < Filter ) MABuffer[shift]=MABuffer[shift+1];
}
if (Color>0)
{
trend[shift]=trend[shift+1];
if (MABuffer[shift]-MABuffer[shift+1] > Filter) trend[shift]= 1;
if (MABuffer[shift+1]-MABuffer[shift] > Filter) trend[shift]=-1;
if (trend[shift]>0)
{
UpBuffer[shift] = MABuffer[shift];
if (trend[shift+ColorBarBack]<0) UpBuffer[shift+ColorBarBack]=MABuffer[shift+ColorBarBack];
if(shift == 1 && DnBuffer[shift] == UpBuffer[shift] && DnBuffer[shift] != EMPTY_VALUE && UpBuffer[shift] != EMPTY_VALUE && alertTag!=Time[0]) {Alert("NonLagMA_V7 Trend Down on ",Symbol()," Period ",Period()," dn= ",DnBuffer[shift]," up= ",UpBuffer[shift]," shift= ",shift);alertTag = Time[0];}
DnBuffer[shift] = EMPTY_VALUE;
}
if (trend[shift]<0)
{
DnBuffer[shift] = MABuffer[shift];
if (trend[shift+ColorBarBack]>0) DnBuffer[shift+ColorBarBack]=MABuffer[shift+ColorBarBack];
if(shift == 1 && DnBuffer[shift] == UpBuffer[shift] && DnBuffer[shift] != EMPTY_VALUE && UpBuffer[shift] != EMPTY_VALUE && alertTag!=Time[0]) {Alert("NonLagMA_V7 Trend Up on ",Symbol()," Period ",Period()," dn= ",DnBuffer[shift]," up= ",UpBuffer[shift]," shift= ",shift);alertTag = Time[0];}
UpBuffer[shift] = EMPTY_VALUE;
}
}
}
//----------
string Message;
if ( trend[2]<0 && trend[1]>0 && Volume[0]>1 && !UpTrendAlert)
{
Message = "NonLagMA "+Symbol()+" M"+Period()+": Signal for BUY";
// if ( SoundAlertMode>0 ) Alert (" ", Message);
UpTrendAlert=true; DownTrendAlert=false;
}
if ( trend[2]>0 && trend[1]<0 && Volume[0]>1 && !DownTrendAlert)
{
Message = "NonLagMA "+Symbol()+" M"+Period()+": Signal for SELL";
// if ( SoundAlertMode>0 ) Alert (" ", Message);
DownTrendAlert=true; UpTrendAlert=false;
}
//----
return(0);
}
Comments