A request that was addressed to ProRealTime:
I would like to translate from MT4 a volatility indicator that I found on a italian trading text. The indicator is based on a modified ATR. Here attached MQL4 source file.
Best regards
#property indicator_separate_window
#property indicator_buffers 3
//COLORS
#property indicator_color1 DodgerBlue
#property indicator_color2 Green
#property indicator_color3 Yellow
//--- input parameters
extern int ATRDPeriods = 3;
//--- buffers
double AtrBuffer[];
double AtrDPlusBuffer[];
double AtrDMinusBuffer[];
double TempBuffer[];
//|Custom indicator initialization function|
int init()
{
string short_name;
IndicatorBuffers(3);
//---- indicator line
SetIndexStyle(0,DRAW_LINE);
SetIndexStyle(1,DRAW_LINE);
SetIndexStyle(2,DRAW_LINE);
SetIndexBuffer(0,AtrDPlusBuffer);
SetIndexBuffer(1,AtrDMinusBuffer);
SetIndexBuffer(2,AtrBuffer);
//---- name for DataWindow and indicator subwindow label
short_name="ATRD(" + ATRDPeriods + ")";
IndicatorShortName(short_name);
SetIndexLabel(0,"Plus volatility");
SetIndexLabel(1,"Minus volatility");
SetIndexLabel(2,"ATR");
//----
SetIndexDrawBegin(0,ATRDPeriods);
SetIndexDrawBegin(1,ATRDPeriods);
SetIndexDrawBegin(2,ATRDPeriods);
//----
return(0);
}
// Average True Range
int start()
{
int i;
int counted_bars=IndicatorCounted();
if(Bars<=ATRDPeriods) return(0);
//---- initial zero
if(counted_bars<1)
{
for(i=1;i<=ATRDPeriods;i++)
{
AtrBuffer[Bars-i]=0;
AtrDPlusBuffer[Bars-i]=0;
AtrDMinusBuffer[Bars-i]=0;
}
}
if(counted_bars>0) counted_bars--;
int limit = Bars-counted_bars;
for(i=0; i<limit; i++)
{
double ATRI;
double RPlus;
double RMinus;
ATRI = 0;
RPlus = 0;
RMinus = 0;
for(int y=i;y<i+ATRDPeriods;y++)
{
ATRI = ATRI+MathMax(High[y],High[y+1])-MathMin(Low[y],Low[y+1]);
//Corpo Positivo
if(Open[y]<Close[y])
{
RPlus=RPlus+(Close[y]-Open[y]);
//Il Body + le Shadow
RMinus=RMinus+(High[y]-Close[y])+(Open[y]-Low[y]);
RPlus=RPlus+(High[y]-Open[y])+(Close[y]-Low[y]);
if(High[y+1]>High[y])RMinus=RMinus + (High[y+1]-High[y]);
if(Low[y+1]<Low[y])RPlus=RPlus+(Low[y]-Low[y+1]);
}
//Corpo Negativo
if(Open[y]>Close[y])
{
RMinus = RMinus+(Open[y]-Close[y]);
RPlus = RPlus+(High[y]-Open[y])+(Close[y]-Low[y]);
RMinus = RMinus + (High[y]-Close[y])+(Open[y]-Low[y]);
if(High[y+1]>High[y])RMinus=RMinus+(High[y+1]-High[y]);
if(Low[y+1]<Low[y])RPlus = RPlus+(Low[y]-Low[y+1]);
}
//Doji
if(Open[y]==Close[y])
{
RPlus = RPlus+(High[y]-Low[y]);
RMinus = RMinus + (High[y]-Low[y]);
if(High[y+1]>High[y])RMinus = RMinus+(High[y+1]-High[y]);
if(Low[y+1]<Low[y])RPlus = RPlus+(Low[y]-Low[y+1]);
}
}
AtrBuffer[i]=ATRI/ATRDPeriods;
AtrDPlusBuffer[i]=RPlus/ATRDPeriods;
AtrDMinusBuffer[i]=RMinus/ATRDPeriods;
}
return(0);
}
Suggestion for an anwser:
Once period = 3
ATR = Highest[2](High) - Lowest[2](Low)
RMinus = 0
RPlus = 0
If Open < Close then
RPlus = (Close - Open) + (High - Open) + (Close - Low)
RMinus = (High - Close) + (Open - Low)
Elsif Open > Close then
RMinus = (Open - Close) + (High - Close) + (Open - Low)
RPlus = (High - Open) + (Close - Low)
Elsif Open = Close then
RPlus = High - Low
RMinus = High - Low
Endif
If High > High[1] then
RMinus = RMinus + (High - High[1])
Endif
If Low < Low[1] then
RPlus = RPlus + (Low[1] - Low)
Endif
ATRD = Average[period](ATR)
ATRDPlus = Average[period](RPlus)
ATRDMinus = Average[period](RMinus)
Return ATRD Coloured(200,200,0) as "ATR", ATRDPlus Coloured(0,150,200) as "Volatility Plus", ATRDMinus Coloured(0,200,0) as "Volatility Minus"