This custom technical indicator for MetaTrader 4 is designed to merge two popular trading methodologies—Bollinger Bands and the MACD (Moving Average Convergence Divergence)—into a single visual tool. Its primary purpose is to identify price momentum and volatility simultaneously, helping traders spot potential trend shifts or extremes in market activity.
How the Logic Works
The indicator operates through a three-step mathematical process:
1. Momentum Calculation (MACD Foundation) First, the script looks at the relationship between two different types of moving averages: a "fast" average and a "slow" average. By subtracting the slow average from the fast one, it generates a momentum value. This tells you whether the price is accelerating upward, downward, or staying flat.
2. Volatility Wrapping (Bollinger Band Logic) Instead of applying Bollinger Bands directly to the price of the asset, this script applies them to the momentum values calculated in the first step. It calculates a "middle line" (a smoothed average of the momentum) and then establishes an Upper and Lower boundary based on the standard deviation (volatility).
3. Visual Signal Processing The indicator translates these complex calculations into clear visual cues on your chart:
- Boundary Lines: It plots two solid lines representing the upper and lower volatility limits for the momentum.
- Dynamic Trend Arrows: The script monitors the direction of the momentum value. If the momentum is increasing, it highlights specific markers; if the momentum is decreasing, it filters those markers out. This helps filter out "noise" so that the user can more easily see when a trend is gaining strength versus when it is losing steam.
Summary for the Trader
In simple terms, this tool doesn't just show you if the price is going up or down; it shows you how strongly it is moving and whether that movement is becoming unusually volatile. By combining these two factors, the indicator provides a more refined view of market "energy," allowing you to see when momentum is reaching an extreme point (hitting the bands) or when the underlying trend is beginning to change direction.
//+------------------------------------------------------------------+
//| Custom BB_MACD.mq4 |
//| Copyright © 2005, adoleh2000 |
//| http://www.metaquotes.net/ |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2005, adoleh2000"
#property link "http://www.metaquotes.net/"
//---- indicator settings
#property indicator_separate_window
#property indicator_buffers 4
#property indicator_color1 Lime //bbMacd up
#property indicator_color2 Magenta //bbMacd up
#property indicator_color3 Blue //Upperband
#property indicator_color4 Red //Lowerband
//---- indicator parameters
extern int FastLen = 12;
extern int SlowLen = 26;
extern int Length = 10;
extern double StDv = 2.5;
//----
int loopbegin;
int shift;
double zeroline;
//---- indicator buffers
double ExtMapBuffer1[]; // bbMacd
double ExtMapBuffer2[]; // bbMacd
double ExtMapBuffer3[]; // Upperband Line
double ExtMapBuffer4[]; // Lowerband Line
//---- buffers
double bbMacd[];
double Upperband[];
double Lowerband[];
double avg[];
double bbMacdline;
double sDev;
double mean;
double sumSqr;
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int init()
{
//---- 6 additional buffers are used for counting.
IndicatorBuffers(8);
//---- drawing settings
SetIndexBuffer(0, ExtMapBuffer1); // bbMacd line
SetIndexStyle(0, DRAW_ARROW);
SetIndexArrow(0, 108);
IndicatorDigits(Digits + 1);
//----
SetIndexBuffer(1, ExtMapBuffer2); // bbMacd line
SetIndexStyle(1, DRAW_ARROW);
SetIndexArrow(1, 108);
IndicatorDigits(Digits + 1);
//----
SetIndexBuffer(2, ExtMapBuffer3); // Upperband line
SetIndexStyle(2, DRAW_LINE, STYLE_SOLID, 1);
IndicatorDigits(Digits + 1);
//----
SetIndexBuffer(3, ExtMapBuffer4); // Lowerband line
SetIndexStyle(3, DRAW_LINE, STYLE_SOLID, 1);
IndicatorDigits(Digits + 1);
//----
SetIndexBuffer(4, bbMacd);
SetIndexBuffer(5, Upperband);
SetIndexBuffer(6, Lowerband);
SetIndexBuffer(7, avg);
//---- name for DataWindow and indicator subwindow label
IndicatorShortName("BB MACD(" + FastLen + "," + SlowLen + "," + Length+")");
SetIndexLabel(0, "bbMacd");
SetIndexLabel(1, "Upperband");
SetIndexLabel(2, "Lowerband");
//---- initialization done
return(0);
}
//+------------------------------------------------------------------+
//| Custor indicator deinitialization function |
//+------------------------------------------------------------------+
int deinit()
{
//----
return(0);
}
//+------------------------------------------------------------------+
//| Custom BB_MACD |
//+------------------------------------------------------------------+
int start()
{
int limit;
int counted_bars = IndicatorCounted();
//---- 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;
//----
for(int i = 0; i < limit; i++)
bbMacd[i] = iMA(NULL, 0, FastLen, 0, MODE_EMA, PRICE_CLOSE, i) -
iMA(NULL, 0, SlowLen, 0, MODE_EMA, PRICE_CLOSE, i);
//----
for(i = 0; i < limit; i++)
{
avg[i] = iMAOnArray(bbMacd, 0, Length, 0, MODE_EMA, i);
sDev = iStdDevOnArray(bbMacd, 0, Length, MODE_EMA, 0, i);
Upperband[i] = avg[i] + (StDv * sDev);
Lowerband[i] = avg[i] - (StDv * sDev);
ExtMapBuffer1[i]=bbMacd[i]; // Uptrend bbMacd
ExtMapBuffer2[i]=bbMacd[i]; // downtrend bbMacd
ExtMapBuffer3[i]=Upperband[i]; // Upperband
ExtMapBuffer4[i]=Lowerband[i]; // Lowerband
//----
if(bbMacd[i] > bbMacd[i+1])
ExtMapBuffer2[i] = EMPTY_VALUE;
//----
if(bbMacd[i] < bbMacd[i+1])
ExtMapBuffer1[i] = EMPTY_VALUE;
}
//---- done
return(0);
}
//+------------------------------------------------------------------+
Comments