The NonLagMA (Non-Lag Moving Average) is a specialized technical analysis tool designed to provide a smoother, more responsive view of price trends on a trading chart. Its primary objective is to solve a common problem in trading: the "lag" effect. Most standard moving averages react slowly to new price movements because they rely heavily on historical data; this script utilizes a sophisticated mathematical approach to minimize that delay while maintaining a clean visual representation of the market's direction.
Core Logic and Methodology
1. Weighted Calculation Engine Unlike a Simple Moving Average (SMA) where every data point carries equal weight, this indicator uses a dynamic weighting system based on trigonometric functions. It calculates the influence of each price point using a combination of cosine waves and a specialized coefficient. This allows the tool to prioritize relevant recent information more effectively than standard calculations.
2. Dynamic Time Progression The script processes data through a multi-stage cycle. Instead of looking at a fixed window of time, it applies a "phase" logic. It adjusts how it perceives the progression of price over different intervals (cycles), which helps in creating a curve that flows naturally with the market's momentum rather than jumping abruptly.
3. Trend Detection and Visualization The indicator does not just provide a single line; it actively identifies the underlying trend to assist in visual analysis:
- Directional Tracking: The script monitors the change between current and previous values to determine if the trend is moving upward or downward.
- Dynamic Coloring: Based on these movements, the indicator assigns specific colors (typically representing "Up" and "Down" trends).
- Smoothing Filter: It includes a built-in filtering mechanism that can prevent "noise"—minor, insignificant price flickers—from changing the trend color too frequently, ensuring that only significant moves are highlighted.
4. Deviation and Customization The logic allows for an optional "Deviation" factor, which provides the user with the ability to slightly scale the resulting average. This helps traders fine-tune how closely the indicator hugs the price action versus how much it smooths out the volatility.
Summary for the User
In essence, this tool acts as a high-precision filter. It takes raw, volatile market prices and converts them into a fluid trend line that reacts quickly to new information without being "distracted" by minor market noise. By distinguishing between upward and downward momentum through distinct colors, it provides a clearer visual map of whether the current market sentiment is bullish or bearish.
//+------------------------------------------------------------------+
//| NonLagMA_v4.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 Yellow
#property indicator_width1 2
#property indicator_color2 SkyBlue
#property indicator_width2 2
#property indicator_color3 Tomato
#property indicator_width3 2
//---- input parameters
extern int Price = 0;
extern int Length = 9;
extern int Displace = 0;
extern int Filter = 0;
extern int Color = 0;
extern int ColorBarBack = 1;
extern double Deviation = 0;
double Cycle = 4;
//---- indicator buffers
double MABuffer[];
double UpBuffer[];
double DnBuffer[];
double price[];
double trend[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int init()
{
int ft=0;
string short_name;
//---- indicator line
IndicatorBuffers(5);
SetIndexStyle(0,DRAW_LINE);
SetIndexBuffer(0,MABuffer);
SetIndexStyle(1,DRAW_LINE);
SetIndexBuffer(1,UpBuffer);
SetIndexStyle(2,DRAW_LINE);
SetIndexBuffer(2,DnBuffer);
SetIndexBuffer(3,price);
SetIndexBuffer(4,trend);
IndicatorDigits(MarketInfo(Symbol(),MODE_DIGITS));
//---- name for DataWindow and indicator subwindow label
short_name="NonLagMA("+Length+")";
IndicatorShortName(short_name);
SetIndexLabel(0,"NLMA");
SetIndexLabel(1,"Up");
SetIndexLabel(2,"Dn");
//----
SetIndexShift(0,Displace);
SetIndexShift(1,Displace);
SetIndexShift(2,Displace);
SetIndexDrawBegin(0,Length*Cycle+Length);
SetIndexDrawBegin(1,Length*Cycle+Length);
SetIndexDrawBegin(2,Length*Cycle+Length);
//----
return(0);
}
//+------------------------------------------------------------------+
//| NonLagMA_v4 |
//+------------------------------------------------------------------+
int start()
{
int i,shift, counted_bars=IndicatorCounted(),limit;
double alfa, beta, t, Sum, Weight, step,g;
double pi = 3.1415926535;
double Coeff = 3*pi;
int Phase = Length-1;
double Len = Length*Cycle + Phase;
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--)
{
Weight=0; Sum=0; t=0;
for (i=0;i<=Len-1;i++)
{
g = 1.0/(Coeff*t+1);
if (t <= 0.5 ) g = 1;
beta = MathCos(pi*t);
alfa = g * beta;
//if (shift>=1) price[i] = iMA(NULL,0,Per,Displace,Mode,Price,shift+i);
//else
price[i] = iMA(NULL,0,1,0,MODE_SMA,Price,shift+i);
Sum += alfa*price[i];
Weight += alfa;
if ( t < 1 ) t += 1.0/(Phase-1);
else if ( t < Len-1 ) t += (2*Cycle-1)/(Cycle*Length-1);
}
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 (trend[shift]<0)
{
DnBuffer[shift] = MABuffer[shift];
if (trend[shift+ColorBarBack]>0) DnBuffer[shift+ColorBarBack]=MABuffer[shift+ColorBarBack];
UpBuffer[shift] = EMPTY_VALUE;
}
}
}
return(0);
}
Comments