NonLagMA_v1

Author: Copyright � 2006, TrendLaboratory
NonLagMA_v1

This tool is designed to provide a smoother and more responsive way to track market trends without the common "lag" found in standard moving averages. In typical technical analysis, most indicators react to past price data with a delay; this script uses a specialized mathematical approach to minimize that delay while still filtering out significant market noise.

Core Logic and Mechanics

The primary function of this indicator is to calculate a modified moving average that accounts for the "momentum" of price movements. Instead of giving every historical price point equal importance, it applies a weighted calculation based on two main components:

  • Weighted Smoothing: The logic uses a trigonometric (cosine) function combined with a weight distribution. This allows the indicator to prioritize certain data points over others, creating a curve that follows the price more naturally.
  • Cycle Compensation: By incorporating a "cycle" factor, the script attempts to harmonize the data points so that the resulting line isn't just a reactive average, but a proactive representation of where the price is heading.

Trend Identification and Visualization

The script does more than just draw a single line; it actively interprets the direction of the market to provide clear visual cues:

  • Dynamic Trend Detection: The system monitors the change between current and previous calculations. If the movement exceeds a specific threshold (the "Filter"), the script identifies a shift in momentum.
  • Color-Coded Directional Paths: Based on these shifts, the indicator separates into two distinct visual paths:
    • An Upward Path is displayed when the trend is positive.
    • A Downward Path is displayed when the trend is negative.
  • Trend Smoothing (Filtering): You can enable a filter to prevent "jitter" or minor fluctuations from causing constant color changes. This ensures that the trend path only flips when a significant and sustained move occurs, rather than reacting to every tiny price tick.

Summary for Users

For a trader, this means you receive a cleaner visual representation of the market's direction. It aims to provide a "lead" on the trend by reducing the lag time typical of standard moving averages, allowing you to see whether the current momentum is leaning upward or downward with greater clarity and less visual clutter.

Indicators Used
Moving average indicator
Miscellaneous
Implements a curve of type %1
16 Views
0 Downloads
0 Favorites
NonLagMA_v1
//+------------------------------------------------------------------+
//|                                                     NonLagMA.mq4 |
//|                                Copyright © 2006, TrendLaboratory |
//|                                                                  |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2006, TrendLaboratory"

#property indicator_chart_window
#property indicator_buffers 3
#property indicator_color1 Yellow
#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;
extern int     Length         = 21;
extern int     Displace       = 0;
extern int     Filter         = 0;
extern int     Color          = 1;
extern int     ColorBarBack   = 0;
extern double  Deviation      = 0;         

double Cycle =  4;

//---- indicator buffers
double MABuffer[];
double UpBuffer[];
double DnBuffer[];
double price[];
double trend[];

  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,"Down");
//----
   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                                                     |
//+--------------------------------------------------------------+
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;
      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