mNLMAv6
Download scriptThis indicator is designed to analyze market trends by creating a moving average that prioritizes responsiveness. In many standard trading tools, there is often a trade-off between "smoothness" (filtering out noise) and "lag" (the delay between a price change and the indicator's reaction). This script specifically aims to minimize that lag while still providing a clear picture of the market's direction.
Core Logic and Functionality
1. Advanced Calculation Method Unlike a simple moving average that treats all past data equally, this tool uses a specialized mathematical weighting system. It calculates a specific "coefficient" for different points in time to determine how much influence each price point should have on the current average. This allows the indicator to react more quickly to recent price movements while maintaining a stable curve.
2. Noise Reduction and Smoothing The script includes a "Filter" mechanism. If the price movement is very small or insignificant (below a user-defined threshold), the indicator ignores these tiny fluctuations. This prevents the line from "jittering" or creating false signals during periods of sideways market movement, ensuring that only meaningful trends are displayed.
3. Trend Identification and Visuals The indicator does more than just draw a single line; it interprets the direction of the market:
- Trend Detection: It compares the current average value to its previous value. If the value is rising significantly enough to pass the filter, it identifies an upward trend. If it falls significantly, it identifies a downward trend.
- Dynamic Coloring: Depending on your settings, the indicator can change color based on these trends (e.g., turning green for up and red for down). It also includes a "Back Bar" feature, which allows the color to persist slightly into the past to make the visual transition between trends easier to see.
4. Signal Generation The script looks for specific "turning points." When the trend logic detects a reversal—meaning the market has switched from a downward movement to an upward one (or vice versa)—it identifies this as a potential signal. These signals are intended to highlight where a shift in momentum might be occurring.
User Customization Options
The logic allows you to fine-tune how the indicator behaves on your specific chart:
- Price Source: You can choose which price data to follow (e.g., Close, Open, High, or Low).
- Length and Displacement: You can adjust how many bars of history the indicator looks at and shift the visual line forward or backward on the chart.
- Deviation: This allows for a manual adjustment to increase or decrease the sensitivity of the average calculation.
- Color Mode: You can toggle between a single consistent line or a multi-colored line that changes based on market direction.
//+------------------------------------------------------------------+
//| NonLagMA_v6.mq4 |
//| Copyright © 2006, TrendLaboratory |
//| http://finance.groups.yahoo.com/group/TrendLaboratory |
//| E-mail: igorad2003@yahoo.co.uk |
//+------------------------------------------------------------------+
//------------------------mNLMAv6.mq4--------------------------------
#property indicator_chart_window
#property indicator_buffers 3
#property indicator_color1 Orange
#property indicator_width1 2
#property indicator_color2 Green
#property indicator_width2 2
#property indicator_color3 Red
#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 = 9; //Period of NonLagMA
extern int Displace = 0; //DispLace or Shift
extern int Filter = 0; //Static filter in points
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 = 0; //Sound Alert switch
extern int WarnAlertMode = 0; //Movement warning Sound Alert switch
//---- indicator buffers
double MABuffer[];
double UpBuffer[];
double DnBuffer[];
double trend[];
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(4);
SetIndexStyle(0,DRAW_LINE);
SetIndexBuffer(0,MABuffer);
SetIndexStyle(1,DRAW_LINE);
SetIndexBuffer(1,UpBuffer);
SetIndexStyle(2,DRAW_LINE);
SetIndexBuffer(2,DnBuffer);
SetIndexBuffer(3,trend);
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);
SetIndexDrawBegin(1,Length*Cycle+Length);
SetIndexDrawBegin(2,Length*Cycle+Length);
//----
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_v5 |
//+------------------------------------------------------------------+
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,1,Price,i+shift);
Sum += alfa[i]*price;
}
if (Weight > 0) MABuffer[shift] = (1.0+Deviation/100)*Sum/Weight;
if (Filter>0)
{
if( MathAbs(MABuffer[shift]-MABuffer[shift+1]) < Filter*Point ) MABuffer[shift]=MABuffer[shift+1];
}
if (Color>0)
{
trend[shift]=trend[shift+1];
if (MABuffer[shift]-MABuffer[shift+1] > Filter*Point) trend[shift]= 1;
if (MABuffer[shift+1]-MABuffer[shift] > Filter*Point) trend[shift]=-1;
if (trend[shift]>0)
{
UpBuffer[shift] = MABuffer[shift];
if (trend[shift+ColorBarBack]<0) UpBuffer[shift+ColorBarBack]=MABuffer[shift+ColorBarBack];
DnBuffer[shift] = EMPTY_VALUE;
//if (SoundAlertMode>0 && WarnAlertMode>0 && trend[shift+1]<0 && shift==0) PlaySound("alert.wav");
}
if (trend[shift]<0)
{
DnBuffer[shift] = MABuffer[shift];
if (trend[shift+ColorBarBack]>0) DnBuffer[shift+ColorBarBack]=MABuffer[shift+ColorBarBack];
UpBuffer[shift] = EMPTY_VALUE;
//if (SoundAlertMode>0 && WarnAlertMode>0 && trend[shift+1]>0 && shift==0) PlaySound("alert.wav");
}
}
//string tComment="mNLMAv6 in UpTrend";
//tComment="UpBuffer[0]="+DoubleToStr(UpBuffer[0],4)+"DnBuffer[0]="+DoubleToStr(DnBuffer[0],4);
//if(UpBuffer[0]==EMPTY_VALUE) tComment="mNLMAv6 in DownTrend";
//Comment(tComment);
}
//----------
string Message;
if ( trend[2]<0 && trend[1]>0 && Volume[0]>1 && !UpTrendAlert)
{
Message = " "+Symbol()+" M"+Period()+": NonLag Signal for BUY";
//if ( SoundAlertMode>0 ) Alert (Message);
UpTrendAlert=true; DownTrendAlert=false;
}
if ( trend[2]>0 && trend[1]<0 && Volume[0]>1 && !DownTrendAlert)
{
Message = " "+Symbol()+" M"+Period()+": NonLag Signal for SELL";
//if ( SoundAlertMode>0 ) Alert (Message);
DownTrendAlert=true; UpTrendAlert=false;
}
//----
return(0);
}
Comments