NonLag_ATR
Download scriptThis script is a specialized technical analysis tool designed to help traders visualize market trends and volatility with high precision. It focuses on smoothing out the "noise" of the market to reveal the underlying direction of price movements more clearly than standard moving averages.
Here is a breakdown of how the logic functions:
Core Concept: Non-Lag Smoothing
The primary goal of this tool is to calculate a "Non-Lag" average. In standard trading indicators, there is often a trade-off between smoothness and speed: a smooth line reacts slowly to price changes (lag), while a fast line is jagged and produces many false signals.
This script uses a sophisticated mathematical weighting system (based on cosine cycles) to weight recent data more intelligently. By distributing weights across a specific period, it attempts to create a moving average that stays closer to the current price action while remaining smooth enough to ignore minor, insignificant price flickers.
Data Source: Volatility Tracking
Unlike many indicators that track the actual price of an asset (like Gold or EUR/USD), this script specifically tracks ATR (Average True Range). The ATR is a common measure of market volatility. By applying the "Non-Lag" logic to volatility rather than price, the tool helps traders understand how the intensity of market movement is evolving over time.
Visual Elements and Trend Detection
The script provides several visual layers to help with decision-making:
- Primary Trend Line: The core non-lag smoothed line serves as the foundation.
- Dual Directional Buffers: When the "Color Mode" is active, the script identifies whether the trend is moving up or down. It separates these into two distinct paths (Up and Down), making it easier to see when a trend has officially flipped.
- Secondary Moving Average: The script takes its own smoothed results and applies a second moving average on top of them. This creates a "smoothed-average-of-a-smooth-average," which provides an even higher level of stability for long-term trend following.
Smart Filtering and Alerts
To ensure the user isn't overwhelmed by constant fluctuations, the logic includes several protective layers:
- Static Filtering: You can set a specific "point" threshold. If the movement in the indicator is smaller than this number, the script ignores it, preventing the line from jumping around due to tiny price ticks.
- Color Transitioning: The script can highlight specific bars during trend shifts to provide an immediate visual cue of a change in momentum.
- Automated Alerts: The logic monitors for "crossovers"—points where the trend flips from negative to positive (or vice versa). If these conditions are met alongside a minimum volume requirement, the script can trigger a pop-up alert or sound notification on your platform.
Summary for the User
In simple terms, this tool takes the market's volatility data, strips away the "jitter" using a custom mathematical weight, and produces a smooth line that shows you the current momentum. It then watches that line for major shifts, alerting you when the trend changes direction so you can make informed trading decisions based on the overall flow of the market.
/*-----------------------------+
| |
| Shared by www.Aptrafx.com |
| |
+------------------------------*/
//+------------------------------------------------------------------+
//| NonLag_ATR.mq4 |
//+------------------------------------------------------------------+
#property indicator_separate_window
#property indicator_buffers 4
#property indicator_color1 Orange
#property indicator_width1 2
#property indicator_color2 SkyBlue
#property indicator_width2 2
#property indicator_color3 FireBrick
#property indicator_width3 2
#property indicator_color4 White
#property indicator_width4 2
//---- input parameters
extern int Length = 14; // Period of NonLagMA
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 Filter = 0; // Static filter in points
extern int Color = 1; // Switch of Color mode (1-color)
extern int ColorBarBack = 0; // Bar back for color mode
extern double Deviation = 0.0; // Up/down deviation
extern int SoundAlertMode = 0; // Sound Alert switch
//---- indicator buffers
double MABuffer[];
double UpBuffer[];
double DnBuffer[];
double MaArray[];
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);
SetIndexBuffer(0,MABuffer);
SetIndexStyle(1,DRAW_LINE);
SetIndexBuffer(1,UpBuffer);
SetIndexStyle(2,DRAW_LINE);
SetIndexBuffer(2,DnBuffer);
SetIndexStyle(3,DRAW_LINE);
SetIndexBuffer(3,MaArray);
SetIndexBuffer(4,trend);
string short_name;
//---- indicator line
IndicatorDigits(MarketInfo(Symbol(),MODE_DIGITS));
//---- name for DataWindow and indicator subwindow label
short_name="NonLag_ATR("+Length+")";
IndicatorShortName(short_name);
SetIndexLabel(0,"NonLag_ATR");
SetIndexLabel(1,"Up");
SetIndexLabel(2,"Dn");
SetIndexLabel(3," ("+MaPeriods+") Period Ma of NonLag_ATR");
//----
SetIndexShift(0,Displace);
SetIndexShift(1,Displace);
SetIndexShift(2,Displace);
SetIndexShift(3,Displace);
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++)
{
MABuffer[Bars-i]=EMPTY_VALUE;
UpBuffer[Bars-i]=EMPTY_VALUE;
DnBuffer[Bars-i]=EMPTY_VALUE;
MaArray[Bars-i]=EMPTY_VALUE;
}
for(shift=limit;shift>=0;shift--)
{
Sum = 0;
for (i=0;i<=Len-1;i++)
{
//price = NormalizeDouble(iMA(NULL,0,2,0,3,Price,i+shift),Digits);
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