This script is designed to provide a visual representation of market volatility by calculating the average size of price bars over a specific period. Instead of tracking the closing price or a simple moving average of the asset's value, this tool focuses on the "range"—the distance between the highest and lowest points reached during a single trading interval (the bar).
Core Functionality
The primary goal of the script is to smooth out these daily or hourly price ranges into a readable line. By looking at the average range, traders can get a better sense of market activity and "stretch." For example, a rising line on this indicator suggests that price swings are becoming larger, while a falling line indicates that price action is tightening or consolidating.
Customizable Calculation Methods
The script offers four distinct ways to calculate these averages, allowing users to choose how much weight the "recent" price action should have compared to "older" data:
- Simple Moving Average (SMA): This provides a straightforward average where every bar in the chosen period carries equal importance. It is best for observing the general trend of volatility without giving too much weight to sudden, one-off spikes.
- Exponential Moving Average (EMA): This method places more significance on the most recent data points. It reacts more quickly to sudden changes in market volatility, making it useful for traders who need to see immediate shifts in price range.
- Smoothed Moving Average (SMMA): This is a slower, "weighted" average that filters out minor noise more effectively than a simple average. It provides a much smoother line, which is ideal for identifying long-term trends in market behavior.
- Linear Weighted Moving Average (LWMA): This method applies a linear weighting where the most recent bars have the highest impact on the current value, and the weight decreases progressively as you look further back into the past. It strikes a balance between the responsiveness of the EMA and the stability of the SMA.
Summary for the User
Essentially, this tool acts as a "volatility thermometer." By selecting your preferred period (how many bars to look back) and your preferred smoothing method (how reactive you want the line to be), you can visualize whether the market is expanding, contracting, or maintaining a steady range of movement. This helps in identifying periods of high-intensity trading versus times of low-activity stability.
//+------------------------------------------------------------------+
//| Average Size Bar.mq4 |
//| Êèì Èãîðü Â. aka KimIV. |
//| http://www.kimiv.ru/ |
//+------------------------------------------------------------------+
#property copyright "Êèì Èãîðü Â. aka KimIV."
#property link "http://www.kimiv.ru/"
#property indicator_separate_window
#property indicator_buffers 1
#property indicator_color1 Red
//---- indicator parameters
extern int MA_Period=10;
extern int MA_Shift=0;
extern int MA_Method=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_LINE);
SetIndexShift(0, MA_Shift);
IndicatorDigits(MarketInfo(Symbol(), MODE_DIGITS));
if(MA_Period<2) MA_Period=10;
draw_begin = MA_Period - 1;
//---- indicator short name
switch(MA_Method) {
case 1 : short_name = "EMA("; draw_begin = 0; break;
case 2 : short_name = "SMMA("; break;
case 3 : short_name = "LWMA("; break;
default : short_name = "SMA("; MA_Method = 0;
}
IndicatorShortName(short_name + MA_Period + ")");
SetIndexDrawBegin(0, draw_begin);
//---- indicator buffers mapping
SetIndexBuffer(0, ExtMapBuffer);
//---- 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(); break;
case 1 : ema(); break;
case 2 : smma(); break;
case 3 : lwma();
}
//---- done
return(0);
}
//+------------------------------------------------------------------+
//| Simple Average Size Bar |
//+------------------------------------------------------------------+
void sma() {
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+=High[pos]-Low[pos];
//---- main calculation loop
while(pos>=0) {
sum+=High[pos]-Low[pos];
ExtMapBuffer[pos]=sum/MA_Period;
sum-=High[pos+MA_Period-1]-Low[pos+MA_Period-1];
pos--;
}
//---- zero initial bars
if(ExtCountedBars<1) for(i=1;i<MA_Period;i++) ExtMapBuffer[Bars-i]=0;
}
//+------------------------------------------------------------------+
//| Exponential Average Size |
//+------------------------------------------------------------------+
void ema() {
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]=High[pos+1]-Low[pos+1];
ExtMapBuffer[pos]=(High[pos]-Low[pos])*pr+ExtMapBuffer[pos+1]*(1-pr);
pos--;
}
}
//+------------------------------------------------------------------+
//| Smoothed Average Size Bar |
//+------------------------------------------------------------------+
void smma() {
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+=High[k]-Low[k];
//---- zero initial bars
ExtMapBuffer[k]=0;
}
}
else sum=ExtMapBuffer[pos+1]*(MA_Period-1)+High[pos]-Low[pos];
ExtMapBuffer[pos]=sum/MA_Period;
pos--;
}
}
//+------------------------------------------------------------------+
//| Linear Weighted Average Size Bar |
//+------------------------------------------------------------------+
void lwma() {
double sum=0.0,lsum=0.0;
double price;
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--) {
price=High[pos]-Low[pos];
sum+=price*i;
lsum+=price;
weight+=i;
}
//---- main calculation loop
pos++;
i=pos+MA_Period;
while(pos>=0) {
ExtMapBuffer[pos]=sum/weight;
if(pos==0) break;
pos--;
i--;
price=High[pos]-Low[pos];
sum=sum-lsum+price*MA_Period;
lsum-=High[i]-Low[i];
lsum+=price;
}
//---- zero initial bars
if(ExtCountedBars<1) for(i=1;i<MA_Period;i++) ExtMapBuffer[Bars-i]=0;
}
//+------------------------------------------------------------------+
Comments