This technical tool is designed to help traders identify and visualize market trends by automatically calculating dynamic "stop" levels based on historical price volatility. Rather than using fixed price points, it adjusts to the market's behavior, expanding or contracting as conditions change.
How the Logic Works
1. Volatility-Based Calculation The core of this script relies on a metric that measures how much a market "breathes." It looks at a specific period of recent price action to determine the current level of volatility. By multiplying this volatility by a user-defined multiplier, the tool creates a "buffer zone" around the current price. This ensures that the trend lines are not triggered by minor, insignificant price flickers but rather by significant market movements.
2. Establishing Highs and Lows The script constantly scans a set number of past candles to find the most extreme boundaries. Specifically, it calculates:
- A minimum boundary based on recent highs minus the volatility buffer.
- A maximum boundary based on recent lows plus the volatility buffer.
3. Trend Detection & Switching The tool monitors the relationship between the current closing price and these boundaries:
- Bullish Trend: If the price closes above the previous maximum boundary, the script identifies an upward trend. It then tracks the lowest point of this move to draw a support line (the "Up" line).
- Bearish Trend: If the price closes below the previous minimum boundary, the script identifies a downward trend and tracks the highest point of this move to draw a resistance line (the "Dn" line).
4. Dynamic Adjustment A key feature of this logic is how it handles these lines once a trend is established. To prevent the lines from moving backward against the trend (which would create "noise"), the script includes a safety check:
- In an uptrend, the support line will only move higher, never lower.
- In a downtrend, the resistance line will only move lower, never higher.
Summary for the User
Essentially, this indicator acts as a "smart" trailing stop. It filters out market noise by using volatility to define what counts as a significant price move. When the trend is clear, it provides you with a visual boundary that follows the price closely enough to protect profits but far enough away to avoid being triggered by standard market fluctuations.
/*-----------------------------+
| |
| Shared by www.Aptrafx.com |
| |
+------------------------------*/
//+------------------------------------------------------------------+
//| ATRStops_v1.mq4 |
//| Copyright © 2006, Forex-TSD.com |
//| Written by IgorAD,igorad2003@yahoo.co.uk |
//| http://finance.groups.yahoo.com/group/TrendLaboratory |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2006, Forex-TSD.com "
#property link "http://www.forex-tsd.com/"
#property indicator_chart_window
#property indicator_buffers 2
#property indicator_color1 Blue
#property indicator_color2 Red
//---- input parameters
extern int Length=10;
extern int ATRperiod=5;
extern double Kv=2.5;
//---- indicator buffers
double UpBuffer1[];
double DnBuffer1[];
double smin[];
double smax[];
double trend[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int init()
{
string short_name;
//---- indicator line
SetIndexStyle(0,DRAW_LINE);
SetIndexStyle(1,DRAW_LINE);
IndicatorBuffers(5);
SetIndexBuffer(0,UpBuffer1);
SetIndexBuffer(1,DnBuffer1);
SetIndexBuffer(2,smin);
SetIndexBuffer(3,smax);
SetIndexBuffer(4,trend);
//---- name for DataWindow and indicator subwindow label
short_name="ATRStops("+Length+")";
IndicatorShortName(short_name);
SetIndexLabel(0,"Up");
SetIndexLabel(1,"Dn");
//----
SetIndexDrawBegin(0,Length);
SetIndexDrawBegin(1,Length);
//----
return(0);
}
//+------------------------------------------------------------------+
//| ATRStops_v1 |
//+------------------------------------------------------------------+
int start()
{
int shift,limit, counted_bars=IndicatorCounted();
if ( counted_bars > 0 ) limit=Bars-counted_bars;
if ( counted_bars < 0 ) return(0);
if ( counted_bars ==0 ) limit=Bars-Length-1;
for(shift=limit;shift>=0;shift--)
{
smin[shift] = -100000; smax[shift] = 100000;
for (int i = Length-1;i>=0;i--)
{
smin[shift] = MathMax( smin[shift], High[shift+i] - Kv*iATR(NULL,0,ATRperiod,shift+i));
smax[shift] = MathMin( smax[shift], Low[shift+i] + Kv*iATR(NULL,0,ATRperiod,shift+i));
}
trend[shift]=trend[shift+1];
if ( Close[shift] > smax[shift+1] ) trend[shift] = 1;
if ( Close[shift] < smin[shift+1] ) trend[shift] = -1;
if ( trend[shift] >0 )
{
if( smin[shift]<smin[shift+1] ) smin[shift]=smin[shift+1];
UpBuffer1[shift]=smin[shift];
DnBuffer1[shift] = EMPTY_VALUE;
}
if ( trend[shift] <0 )
{
if( smax[shift]>smax[shift+1] ) smax[shift]=smax[shift+1];
UpBuffer1[shift]=EMPTY_VALUE;
DnBuffer1[shift] = smax[shift];
}
}
return(0);
}
Comments