Ind-StDev-AVG
Download scriptThis indicator is designed to provide a smoothed visual representation of market volatility over time. Instead of plotting the price directly, it focuses on calculating the "Standard Deviation"—a mathematical measure of how much an asset's price fluctuates from its average—and then applies various smoothing techniques to that data to make it easier for traders to interpret.
Core Logic and Functionality
The script operates by combining two primary financial concepts: Standard Deviation and Moving Averages.
-
Volatility Measurement (Standard Deviation): The foundation of this tool is the Standard Deviation calculation. This identifies the degree of "noise" or movement in the market during a specific period. High values indicate significant price swings, while low values suggest a period of relative stability or consolidation.
-
Smoothing Process (Moving Averages): Because raw volatility data can be jagged and difficult to read, the script takes these standard deviation values and "smooths" them out using a Moving Average. This allows the user to see the general trend of market volatility rather than every tiny, erratic spike.
User Customization Options
The logic is versatile because it allows for four different types of smoothing, each behaving differently depending on how much weight you want to give to recent data:
- Simple Moving Average (SMA): This treats all periods in the calculation equally. It is the most basic form of smoothing, providing a steady look at average volatility over a set timeframe.
- Exponential Moving Average (EMA): This gives more importance to the most recent data points. It reacts faster to sudden changes in market volatility than the Simple version.
- Smoothed Moving Average (SMMA): This produces an even more gradual curve by considering a longer history of the data. It is ideal for identifying long-term trends while filtering out minor fluctuations.
- Linear Weighted Moving Average (LWMA): This applies a linear multiplier to the data, giving the highest weight to the most recent price action while still maintaining a connection to historical values.
Visual Representation
The resulting output is displayed as a histogram in a separate window below the main price chart. By observing this histogram, traders can more easily identify periods of expanding volatility (which may precede major price moves) or contracting volatility (which may indicate a period of cooling off). This helps in understanding the "heartbeat" of the market independent of the actual price direction.
//+------------------------------------------------------------------+
//| Ind-StDev-AVG.mq4 |
//| GGekko |
//| |
//+------------------------------------------------------------------+
#property copyright "GGekko"
#property indicator_separate_window
#property indicator_buffers 1
#property indicator_color1 Green
#property indicator_width1 2
//---- indicator parameters
extern int MA_Period=12;
extern int MA_Method=1;
extern int STDEV_Period=12;
extern int STDEV_Method=1;
extern int STDEV_Price=0;
//---- indicator buffers
double ExtMapBuffer[];
//----
int ExtCountedBars=0;
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int init()
{
int draw_begin;
string short_name;
//---- drawing settings
SetIndexStyle(0,DRAW_HISTOGRAM);
SetIndexBuffer(0,ExtMapBuffer);
SetIndexShift(0,0);
/*
SetIndexStyle(0,DRAW_LINE);
SetIndexShift(0,0);
*/
IndicatorDigits(MarketInfo(Symbol(),MODE_DIGITS));
if(MA_Period<2) MA_Period=13;
draw_begin=MA_Period-1;
SetIndexDrawBegin(0,draw_begin);
//---- indicator buffers mapping
SetIndexBuffer(0,ExtMapBuffer);
IndicatorShortName("StDev-AVG ("+MA_Period+","+MA_Method+","+STDEV_Period+","+STDEV_Method+","+STDEV_Price+")");
//---- initialization done
return(0);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
int start()
{
if(Bars<=MA_Period) return(0);
ExtCountedBars=IndicatorCounted();
//---- check for possible errors
if (ExtCountedBars<0) return(-1);
//---- last counted bar will be recounted
if (ExtCountedBars>0) ExtCountedBars--;
//----
switch(MA_Method)
{
case 0 : sma_stdev(); break;
case 1 : ema_stdev(); break;
case 2 : smma_stdev(); break;
case 3 : lwma_stdev();
}
//---- done
return(0);
}
//+------------------------------------------------------------------+
//| Simple MA |
//+------------------------------------------------------------------+
void sma_stdev()
{
double sum=0;
int i,pos=Bars-ExtCountedBars-1;
//---- initial accumulation
if(pos<MA_Period) pos=MA_Period;
for(i=1;i<MA_Period;i++,pos--)
{
sum+=iStdDev(NULL,0,STDEV_Period,0,STDEV_Method,STDEV_Price,pos);
}
//---- main calculation loop
while(pos>=0)
{
sum+=iStdDev(NULL,0,STDEV_Period,0,STDEV_Method,STDEV_Price,pos);
ExtMapBuffer[pos]=sum/MA_Period;
sum-=iStdDev(NULL,0,STDEV_Period,0,STDEV_Method,STDEV_Price,pos+MA_Period-1);
pos--;
}
//---- zero initial bars
if(ExtCountedBars<1)
for(i=1;i<MA_Period;i++) ExtMapBuffer[Bars-i]=0;
}
//+------------------------------------------------------------------+
//| Exponential MA |
//+------------------------------------------------------------------+
void ema_stdev()
{
double pr=2.0/(MA_Period+1);
int pos=Bars-2;
if(ExtCountedBars>2) pos=Bars-ExtCountedBars-1;
//---- main calculation loop
while(pos>=0)
{
if(pos==Bars-2) ExtMapBuffer[pos+1]=iStdDev(NULL,0,STDEV_Period,0,STDEV_Method,STDEV_Price,pos+1);
ExtMapBuffer[pos]=iStdDev(NULL,0,STDEV_Period,0,STDEV_Method,STDEV_Price,pos)*pr+ExtMapBuffer[pos+1]*(1-pr);
pos--;
}
}
//+------------------------------------------------------------------+
//| Smoothed MA |
//+------------------------------------------------------------------+
void smma_stdev()
{
double sum=0;
int i,k,pos=Bars-ExtCountedBars+1;
//---- main calculation loop
pos=Bars-MA_Period;
if(pos>Bars-ExtCountedBars) pos=Bars-ExtCountedBars;
while(pos>=0)
{
if(pos==Bars-MA_Period)
{
//---- initial accumulation
for(i=0,k=pos;i<MA_Period;i++,k++)
{
sum+=iStdDev(NULL,0,STDEV_Period,0,STDEV_Method,STDEV_Price,k);
//---- zero initial bars
ExtMapBuffer[k]=0;
}
}
else sum=ExtMapBuffer[pos+1]*(MA_Period-1)+iStdDev(NULL,0,STDEV_Period,0,STDEV_Method,STDEV_Price,pos);
ExtMapBuffer[pos]=sum/MA_Period;
pos--;
}
}
//+------------------------------------------------------------------+
//| Linear Weighted MA |
//+------------------------------------------------------------------+
void lwma_stdev()
{
double sum=0.0,lsum=0.0;
double val;
int i,weight=0,pos=Bars-ExtCountedBars-1;
//---- initial accumulation
if(pos<MA_Period) pos=MA_Period;
for(i=1;i<=MA_Period;i++,pos--)
{
val=iStdDev(NULL,0,STDEV_Period,0,STDEV_Method,STDEV_Price,pos);
sum+=val*i;
lsum+=val;
weight+=i;
}
//---- main calculation loop
pos++;
i=pos+MA_Period;
while(pos>=0)
{
ExtMapBuffer[pos]=sum/weight;
if(pos==0) break;
pos--;
i--;
val=iStdDev(NULL,0,STDEV_Period,0,STDEV_Method,STDEV_Price,pos);
sum=sum-lsum+val*MA_Period;
lsum-=iStdDev(NULL,0,STDEV_Period,0,STDEV_Method,STDEV_Price,i);
lsum+=val;
}
//---- zero initial bars
if(ExtCountedBars<1)
for(i=1;i<MA_Period;i++) ExtMapBuffer[Bars-i]=0;
}
//+------------------------------------------------------------------+
Comments