BB_MACD_CCT
Download scriptThis custom technical indicator, known as the BB MACD, is designed to provide traders with a visual representation of market momentum by combining two popular analytical tools: the Moving Average Convergence Divergence (MACD) and Bollinger Bands.
Instead of viewing these metrics separately, this script blends them into a single cohesive visual in a separate window below the main price chart. Here is a breakdown of how the logic functions:
1. Core Momentum Calculation
The foundation of the indicator starts with the MACD calculation. It tracks the relationship between two different Exponential Moving Averages (EMA)—a "Fast" length and a "Slow" length. By subtracting the Slow EMA from the Fast EMA, the script identifies the speed and direction of price movement. If the gap between these averages is widening, it suggests strengthening momentum; if narrowing, it suggests the trend may be weakening.
2. Dynamic Volatility Envelopes
The unique feature of this script is that it applies Bollinger Band logic directly to the MACD values rather than the price itself.
- The Mean: The script calculates a moving average of the MACD results.
- Standard Deviation: It measures how much the MACD fluctuates around its average.
- Upper and Lower Bands: Based on these calculations, it draws two boundary lines (Upper and Lower bands). These act as "volatility zones." When the momentum values push toward or exceed these bands, it signals that the current move is significantly stronger than normal market conditions.
3. Visual Signaling Logic
To make the data easy to read at a glance, the script uses a system of dynamic visual markers:
- Trend Detection: The indicator identifies whether the momentum is currently rising or falling by comparing the current MACD value to the previous one.
- Dynamic Icons: Rather than just drawing a continuous line that might become cluttered, the script uses specific symbols (arrows/markers) to highlight the direction of the trend.
- Smart Filtering: To ensure clarity, the script intelligently hides markers that contradict the current trend. It only displays upward-moving markers when the momentum is increasing and downward-moving markers when it is decreasing.
Summary for the User
In practical terms, this tool helps you see not just where the price is going, but how fast it is moving relative to its recent history. By wrapping the MACD inside a Bollinger Band structure, it allows you to identify "overextended" momentum—situations where the market is moving so aggressively that it might be due for a correction or a period of consolidation.
//+------------------------------------------------------------------+
//| 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 MediumBlue //bbMacd up
#property indicator_color2 Red //bbMacd up
#property indicator_color3 MediumBlue //Upperband
#property indicator_color4 Red //Lowerband
//---- indicator parameters
extern int FastLen = 38;
extern int SlowLen = 120;
extern int Length = 20;
extern double StDv = 1.1;
//----
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