This script is designed as a visual trading tool for the MetaTrader platform, specifically created to help traders analyze market volume through a combination of dynamic coloring and moving averages. Instead of just showing raw numbers, it interprets volume data to provide a clearer picture of market activity trends.
Core Functionality
The logic operates on three primary components that are displayed simultaneously in a separate window below your price chart:
1. Dynamic Volume Histograms (Color-Coded) The script tracks the volume of every price bar and compares it to the volume of the previous bar. It uses this comparison to assign colors to the histogram:
- Red Bars: These appear when the current volume is lower than the preceding bar's volume, signaling a potential decrease in momentum or participation.
- Green Bars: These appear when the current volume is higher than the preceding bar's volume, suggesting increasing market activity.
- Persistence: If the volume remains exactly the same as the previous bar, the script intelligently maintains the color from the previous move to ensure a smooth visual flow.
2. Customizable Moving Average Overlaying the volume data is a "Moving Average" line. This line acts as a smoothing tool, filtering out "noise" to help you see the underlying trend of the volume. The script offers four different mathematical methods to calculate this average, allowing you to choose how "sensitive" or "smooth" the line should be:
- Simple (SMA): A standard average that treats all data points equally.
- Exponential (EMA): Gives more weight to the most recent data, making it react faster to sudden changes.
- Smoothed (SMMA): A slower, more gradual calculation for identifying long-term trends.
- Linear Weighted (LWMA): Applies a linear weight to data points, prioritizing recent activity while maintaining a steady curve.
User Controls
The logic is built to be flexible for the user through several adjustable settings:
- Period: You can define how many previous bars are used to calculate the average (e.g., looking at the last 13 bars).
- Shift: This allows you to move the visual display forward or backward on the chart.
- Method: This lets you toggle between the four mathematical styles of moving averages mentioned above.
Summary for the Trader
In essence, this script transforms raw volume data into a visual narrative. By looking at the color changes, you can quickly identify if market participation is accelerating or decelerating. By observing the Moving Average line, you can determine if the overall volume trend is rising or falling over a longer timeframe. Together, these elements help traders gauge the strength behind price movements.
//+------------------------------------------------------------------+
//| Volume with Custom Moving Average.mq4 |
//| Copyright © 2004, MetaQuotes Software Corp. |
//| http://www.metaquotes.net/ |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2004, MetaQuotes Software Corp. Modified RonT"
#property link "http://www.metaquotes.net/"
#property indicator_separate_window
#property indicator_buffers 3
#property indicator_color1 Red
#property indicator_color2 Green
#property indicator_color3 White
// User input
extern int MA_Period=13;
extern int MA_Shift=0;
extern int MA_Method=0;
// Buffers
double VolBuffer1[]; // value down
double VolBuffer2[]; // value up
double VolBuffer3[]; // moving average
//----
int ExtCountedBars=0;
int lastcolor=0;
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int init()
{
int draw_begin;
string short_name;
// indicator buffers mapping, drawing settings and Shift
// Histogram downArrow Red
SetIndexBuffer(0,VolBuffer1);
SetIndexStyle(0,DRAW_HISTOGRAM);
SetIndexShift(0,MA_Shift);
// Histogram upArrow Green
SetIndexBuffer(1,VolBuffer2);
SetIndexStyle(1,DRAW_HISTOGRAM);
SetIndexShift(1,MA_Shift);
// Moving average line white
SetIndexBuffer(2,VolBuffer3);
SetIndexStyle(2,DRAW_LINE);
SetIndexShift(2,MA_Shift);
IndicatorDigits(MarketInfo(Symbol(),MODE_DIGITS));
if(MA_Period<2) MA_Period=2;
draw_begin=MA_Period-1;
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);
return(0);
}
//+------------------------------------------------------------------+
//| Main |
//+------------------------------------------------------------------+
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();
}
return(0);
}
//+------------------------------------------------------------------+
//| Simple Moving Average |
//+------------------------------------------------------------------+
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+=Volume[pos];
while(pos>=0)
{
sum+=Volume[pos];
VolBuffer3[pos]=sum/MA_Period;
sum-=Volume[pos+MA_Period-1];
Vcolor(pos);
pos--;
}
// zero initial bars
if(ExtCountedBars<1)
for(i=1;i<MA_Period;i++) VolBuffer1[Bars-i]=0;
}
//+------------------------------------------------------------------+
//| Exponential Moving Average |
//+------------------------------------------------------------------+
void ema()
{
double pr=2.0/(MA_Period+1);
int pos=Bars-2;
if(ExtCountedBars>2) pos=Bars-ExtCountedBars-1;
while(pos>=0)
{
if(pos==Bars-2) VolBuffer3[pos+1]=Volume[pos+1];
VolBuffer3[pos]=Volume[pos]*pr+VolBuffer3[pos+1]*(1-pr);
Vcolor(pos);
pos--;
}
}
//+------------------------------------------------------------------+
//| Smoothed Moving Average |
//+------------------------------------------------------------------+
void smma()
{
double sum=0;
int i,k,pos=Bars-ExtCountedBars+1;
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+=Volume[k];
// zero initial bars
VolBuffer3[k]=0;
}
}
else sum=VolBuffer3[pos+1]*(MA_Period-1)+Volume[pos];
VolBuffer3[pos]=sum/MA_Period;
pos--;
}
}
//+------------------------------------------------------------------+
//| Linear Weighted Moving Average |
//+------------------------------------------------------------------+
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=Volume[pos];
sum+=price*i;
lsum+=price;
weight+=i;
}
//---- main calculation loop
pos++;
i=pos+MA_Period;
while(pos>=0)
{
VolBuffer3[pos]=sum/weight;
if(pos==0) break;
pos--;
i--;
price=Volume[pos];
sum=sum-lsum+price*MA_Period;
lsum-=Volume[i];
lsum+=price;
}
//---- zero initial bars
if(ExtCountedBars<1)
for(i=1;i<MA_Period;i++) VolBuffer3[Bars-i]=0;
}
//+------------------------------------------------------------------+
//| Color depends on gain or loss and previous volume |
//+------------------------------------------------------------------+
// 1 - histo down red
// 2 - histo up green
// 3 - line white
void Vcolor(int p)
{
if (Volume[p+1]>Volume[p])
{
VolBuffer1[p]=Volume[p];
VolBuffer2[p]=0;
lastcolor=Red;
}
if (Volume[p+1]<Volume[p])
{
VolBuffer1[p]=0;
VolBuffer2[p]=Volume[p];
lastcolor=Green;
}
if (Volume[p+1]==Volume[p])
{
if ( lastcolor==Red )
{
VolBuffer1[p]=Volume[p];
VolBuffer2[p]=0;
}
if ( lastcolor==Green )
{
VolBuffer1[p]=0;
VolBuffer2[p]=Volume[p];
}
}
}
//+------------------------------------------------------------------+
Comments