NonLag_ATR_v2

Download script
NonLag_ATR_v2

This indicator is designed to provide traders with a visual representation of market trends by analyzing price volatility in a way that minimizes "lag"—the delay between a price move and the indicator's reaction.

Core Logic and Mechanics

1. Volatility-Based Foundation Unlike standard indicators that might look only at the closing price, this script utilizes the ATR (Average True Range) as its primary data source. By focusing on the ATR, the logic measures how much the market is moving (volatility) rather than just where the price is located.

2. The Non-Lag Calculation To solve the common problem where moving averages react too slowly to sudden market shifts, the script uses a specialized mathematical weighting system. Instead of giving equal weight to all past data points, it applies a specific curve (a weighted "alfa" coefficient). This allows the indicator to prioritize relevant information, attempting to provide a smoother line that stays closer to current market reality without the jagged movements typical of standard averages.

3. Trend Identification and Visual Signaling The script identifies the direction of the market by monitoring the slope of the calculated data:

  • Upward Movement: When the indicator detects a significant rise, it activates an "Up" signal (visually represented as a Lime line).
  • Downward Movement: When a significant drop is detected, it activates a "Down" signal (visually represented as a FireBrick line).
  • Color Mode: There is a built-in toggle that allows the indicator to change colors dynamically based on whether the market is currently trending up or down.

4. Filtering and Smoothing The logic includes a "Filter" mechanism. This acts as a stabilizer; it prevents the indicator from triggering on tiny, insignificant price flickers. The movement must exceed a specific threshold (defined in points) before the script confirms a change in trend, helping to reduce "noise" during sideways markets.

5. Secondary Confirmation In addition to the primary non-lag line, the script calculates a secondary Moving Average based on the processed data. This provides an extra layer of confirmation, allowing traders to see the relationship between the immediate volatility trend and the slightly broader average movement.

6. Automated Alerts The system is programmed to monitor for specific "crosses"—moments where the trend flips from negative to positive or vice versa. When these transitions occur (and provided there is active trading volume), the script can trigger visual alerts on your screen and play an audible sound notification to signal a potential Buy or Sell opportunity.

Indicators Used
Indicator of the average true rangeMoving average indicator
Miscellaneous
Implements a curve of type %1It plays sound alerts
19 Views
0 Downloads
0 Favorites
NonLag_ATR_v2
/*-----------------------------+
|			       |
| Shared by www.Aptrafx.com    |
|			       |
+------------------------------*/

//+------------------------------------------------------------------+
//|                                                NonLag_ATR_v2.mq4 |
//+------------------------------------------------------------------+

#property indicator_separate_window
#property indicator_buffers 4
#property indicator_color1 White
#property indicator_color2 Orange
#property indicator_color3 Lime
#property indicator_color4 FireBrick

//---- input parameters

extern int     Length         =  14;  // Period of NonLagMA
extern int     Filter         =   0;  // Static filter in points
extern int NonLagLineWidth    =   2;

extern int     MaPeriods      =   8;  // Moving Average Line Periods
extern int     Displace       =   0;  // Moving Average Line DispLace or Shift
extern int     Price          =   1;  // Moving Average Line Method 0 SMA , 1 EMA , 2 SMMA , 3 LWMA
extern int MaLineWidth        =   1;

extern int     Color          =   1;  // Switch of Color mode (1-color)  
extern int     ColorBarBack   =   0;  // Bar back for color mode
double         Deviation      = 0.0;  // Up/down deviation        
extern int     SoundAlertMode =   0;  // Sound Alert switch 

//---- indicator buffers

double MaArray[];
double MABuffer[];
double UpBuffer[];
double DnBuffer[];
double trend[];

double alfa[];
int i,  Len, Cycle=4,Phase;
double Coeff, beta, t, Sum, Weight, g;
double pi = 3.1415926535;    
bool   UpTrendAlert=false, DownTrendAlert=false;

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+

  int init()
  {
   
   IndicatorBuffers(5);
   
   SetIndexStyle(0,DRAW_LINE,STYLE_SOLID,MaLineWidth);
   SetIndexBuffer(0,MaArray);
   
   SetIndexStyle(1,DRAW_LINE,STYLE_SOLID,NonLagLineWidth);
   SetIndexBuffer(1,MABuffer);
   
   SetIndexStyle(2,DRAW_LINE,STYLE_SOLID,NonLagLineWidth);
   SetIndexBuffer(2,UpBuffer);
   
   SetIndexStyle(3,DRAW_LINE,STYLE_SOLID,NonLagLineWidth);
   SetIndexBuffer(3,DnBuffer);
   
   SetIndexBuffer(4,trend);
    
   string short_name;

//---- indicator line
   
   IndicatorDigits(MarketInfo(Symbol(),MODE_DIGITS));

//---- name for DataWindow and indicator subwindow label
   
   short_name="NonLag_ATR_v2("+Length+")";
   
   IndicatorShortName(short_name);
   
   SetIndexLabel(0," ("+MaPeriods+") Period Ma of NonLag_ATR");
   SetIndexLabel(1,"NonLag_ATR");
   SetIndexLabel(2,"Up");
   SetIndexLabel(3,"Dn");
   
//----
   
   SetIndexEmptyValue(0,EMPTY_VALUE);
   SetIndexEmptyValue(1,EMPTY_VALUE);
   SetIndexEmptyValue(2,EMPTY_VALUE);
   SetIndexEmptyValue(3,EMPTY_VALUE);
   
   SetIndexDrawBegin(0,Length*Cycle+Length);
   SetIndexDrawBegin(1,Length*Cycle+Length);
   SetIndexDrawBegin(2,Length*Cycle+Length);
   SetIndexDrawBegin(3,Length*Cycle+Length);
   
//----
   
   Coeff =  3*pi;
   Phase = Length-1;
   Len = Length*Cycle + Length-1; 
   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_v6.1                                                      |
//+------------------------------------------------------------------+

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++) 
   {
   MaArray[Bars-i]=EMPTY_VALUE;
   MABuffer[Bars-i]=EMPTY_VALUE;
   UpBuffer[Bars-i]=EMPTY_VALUE;
   DnBuffer[Bars-i]=EMPTY_VALUE;
   }
   
   for(shift=limit;shift>=0;shift--) 
   {	
      Sum = 0;
      for (i=0;i<=Len-1;i++)
	   { 
      price = NormalizeDouble(iATR(Symbol(), 0, 1, i+shift),Digits);
      Sum += alfa[i]*price;
      
      }
   
	if (Weight > 0) MABuffer[shift] = NormalizeDouble((1.0+Deviation/100)*Sum/Weight,Digits);
   
      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 && trend[shift+1]<0 && shift==0) PlaySound("alert2.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 && trend[shift+1]>0 && shift==0) PlaySound("alert2.wav");
         }
      }
    }
   for(shift=limit;shift>=0;shift--) 
         {
         MaArray[shift] = iMAOnArray(MABuffer,0,MaPeriods,Displace,Price,shift);
         }
//----------   
   string Message;
   
   if ( trend[2]<0 && trend[1]>0 && Volume[0]>1 && !UpTrendAlert)
	{
	Message = " "+Symbol()+" M"+Period()+": Signal for BUY @ "+DoubleToStr(Ask,Digits);
	if ( SoundAlertMode>0 ) Alert (Message); 
	UpTrendAlert=true; DownTrendAlert=false;
	} 
	 	  
	if ( trend[2]>0 && trend[1]<0 && Volume[0]>1 && !DownTrendAlert)
	{
	Message = " "+Symbol()+" M"+Period()+": Signal for SELL @ "+DoubleToStr(Bid,Digits);
	if ( SoundAlertMode>0 ) Alert (Message); 
	DownTrendAlert=true; UpTrendAlert=false;
	} 	         
//----
	return(0);	
}

Comments