BAT ATR v1
Download scriptThe ATR Trailing Stop is a technical analysis tool designed to help traders manage their risk by automatically adjusting "stop-loss" levels based on the prevailing market volatility. Unlike static stop-losses, this indicator moves dynamically with the price, seeking to protect profits during uptrends and provide a floor for downtrends.
Core Logic and Functionality
The script operates by measuring market volatility using the Average True Range (ATR). The ATR tells the system how much an asset typically moves in a given timeframe. By multiplying this volatility by a specific "Factor," the tool determines a safe buffer zone around the current price.
1. Dynamic Trend Detection
The indicator continuously monitors price action to determine the current market direction. It tracks two primary boundaries:
- Support Level (Uptrend): As the price rises, the script calculates a trailing floor. This floor only moves upward; it "trails" the price as it climbs, ensuring that if the trend reverses, the trader can exit at a profit.
- Resistance Level (Downtrend): Conversely, during a decline, the script calculates a trailing ceiling. This ceiling only moves downward, tracking the price drop to establish a point where a potential recovery might begin.
2. Smart Adjustment Mechanism
The logic is designed to be "reactive" rather than just following the price blindly:
- In an Uptrend: The indicator tracks the highest point reached by the trailing floor. It will not move down even if the price dips slightly, maintaining the integrity of the trend line until a specific price break occurs.
- In a Downtrend: The indicator tracks the lowest point reached by the trailing ceiling, ensuring it only moves lower as the market stays bearish.
3. Automatic Trend Reversal (The "Flip")
The most critical logic within this script is its ability to switch directions automatically:
- If the price drops below the current Support Level, the script recognizes a potential trend breakdown. It immediately switches its logic to the "Downtrend" mode and begins plotting the Resistance Level.
- If the price climbs above the current Resistance Level, the script recognizes a potential trend breakout. It flips back to "Uptrend" mode and begins plotting the Support Level.
Key Visual Elements
- Blue Line (Support): Represents your protective floor during an upward move.
- Red Line (Resistance): Represents your protective ceiling during a downward move.
- Price Source: Users can choose to base these calculations on the standard closing price or a "Typical Price" (an average of the high, low, and close) to smooth out erratic market spikes.
By using this logic, traders can visualize clear boundaries for their positions, allowing them to stay in profitable trends longer while systematically cutting losses when the market structure fundamentally changes.
//+------------------------------------------------------------------+
//| ATR Trailing Stop.mq4 |
//| |
//| |
//+------------------------------------------------------------------+
#property copyright "Copyright Team Aphid"
#property link ""
//---- indicator settings
#property indicator_chart_window
#property indicator_buffers 2
#property indicator_color1 Blue
#property indicator_color2 Red
//---- indicator parameters
extern int BackPeriod = 1000;
extern int ATRPeriod = 3;
extern double Factor = 3;
extern bool TypicalPrice = false;
//---- indicator buffers
double ind_buffer1[];
double ind_buffer2[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int init()
{
//---- drawing settings
SetIndexStyle(0,DRAW_LINE,EMPTY,2);
SetIndexDrawBegin(0,ATRPeriod);
SetIndexBuffer(0,ind_buffer1);
SetIndexStyle(1,DRAW_LINE,EMPTY,2);
SetIndexDrawBegin(1,ATRPeriod);
SetIndexBuffer(1,ind_buffer2);
IndicatorDigits(MarketInfo(Symbol(),MODE_DIGITS)+2);
//---- name for DataWindow and indicator subwindow label
IndicatorShortName("ATR Trailing Stop("+ATRPeriod+" * "+Factor+")");
SetIndexLabel(0,"Support");
SetIndexLabel(1,"Resistance");
//---- initialization done
return(0);
}
//+------------------------------------------------------------------+
//| Moving Averages Convergence/Divergence |
//+------------------------------------------------------------------+
int start()
{
int limit;
int counted_bars=IndicatorCounted();
double PrevUp, PrevDn;
double CurrUp, CurrDn;
double PriceLvl;
double LvlUp = 0;
double LvlDn = 1000;
int Dir = 1;
int InitDir;
//---- check for possible errors
if(counted_bars<0) return(-1);
//---- last counted bar will be recounted
if(counted_bars>0) counted_bars--;
limit=Bars-counted_bars;
//---- fill in buffervalues
InitDir = 0;
for(int i=BackPeriod; i>=0; i--)
{
if (TypicalPrice) PriceLvl = (High[i] + Low[i] + Close[i])/3;
else PriceLvl = Close[i];
if(InitDir == 0) {
CurrUp=Close[i] - (iATR(NULL,0,ATRPeriod,i) * Factor);
PrevUp=Close[i-1] - (iATR(NULL,0,ATRPeriod,i-1) * Factor);
CurrDn=Close[i] + (iATR(NULL,0,ATRPeriod,i) * Factor);
PrevDn=Close[i-1] + (iATR(NULL,0,ATRPeriod,i-1) * Factor);
if (CurrUp > PrevUp) Dir = 1;
LvlUp = CurrUp;
if (CurrDn < PrevDn) Dir = -1;
LvlDn = CurrDn;
InitDir = 1;
}
CurrUp=PriceLvl - (iATR(NULL,0,ATRPeriod,i) * Factor);
CurrDn=PriceLvl + (iATR(NULL,0,ATRPeriod,i) * Factor);
if (Dir == 1) {
if (CurrUp > LvlUp) {
ind_buffer1[i] = CurrUp;
LvlUp = CurrUp;
}
else {
ind_buffer1[i] = LvlUp;
}
ind_buffer2[i] = EMPTY_VALUE;
if (Low[i] < ind_buffer1[i]) {
Dir = -1;
LvlDn = 1000;
}
}
if (Dir == -1) {
if (CurrDn < LvlDn) {
ind_buffer2[i] = CurrDn;
LvlDn = CurrDn;
}
else {
ind_buffer2[i] = LvlDn;
}
ind_buffer1[i] = EMPTY_VALUE;
if (High[i] > ind_buffer2[i]) {
Dir = 1;
LvlUp = 0;
}
}
}
//---- done
return(0);
}
Comments