This technical indicator is designed to help traders identify specific moments in the market where price action transitions from a period of low volatility (consolidation) into a significant move. It combines several advanced mathematical concepts—specifically Bollinger Bands, Keltner Channels, and momentum oscillators—to provide a visual signal of "squeezes" and subsequent breakouts.
Core Logic and Mechanics
The indicator works by comparing two different types of market volatility models simultaneously: Bollinger Bands (which expand and contract based on standard deviation) and Keltner Channels (which move more smoothly based on Average True Range).
When the Bollinger Bands "contract" significantly inside the Keltner Channels, it indicates a "Squeeze." This suggests that the market is coiled like a spring, with very little movement occurring, often preceding a sharp price breakout.
Dynamic Signal Selection
The script allows you to choose between three different momentum triggers to determine the direction of the move:
- Stochastic Oscillator: Measures where the current price is relative to its recent range.
- Commodity Channel Index (CCI): Identifies new trends by comparing the current price to a simple moving average.
- Relative Strength Index (RSI): Evaluates the speed and change of price movements.
Visual Interpretation
The indicator displays these signals in a separate window on your chart using different colors and histogram styles:
- The Baseline: The script calculates a primary momentum value based on your chosen trigger (Stochastic, CCI, or RSI).
- Normal Momentum: When the market is moving normally (outside of a squeeze), the indicator shows the standard momentum bars. This helps you see the "health" of the current trend.
- The Squeeze Signal: When the mathematical conditions for a "Squeeze" are met (where volatility is at an extreme low), the logic switches the visual output. It emphasizes the potential for a breakout by isolating the momentum bars, helping you distinguish between regular market noise and high-probability setup zones.
Summary for the Trader
Instead of looking at every small price fluctuation, this tool filters the market data to highlight periods of high tension. By monitoring where these "squeezes" occur and observing which direction the momentum oscillator is pointing, traders can better identify potential entry points for breakout trades.
//+------------------------------------------------------------------+
//| bbsqueeze.mq4 |
//| Copyright © 2005, Nick Bilak, beluck[AT]gmail.com |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2005, Nick Bilak"
#property link "http://metatrader.50webs.com/"
#property indicator_separate_window
#property indicator_buffers 6
#property indicator_color1 Green
#property indicator_color2 IndianRed
#property indicator_color3 Blue
#property indicator_color4 Blue
#property indicator_color5 Blue
#property indicator_color6 Gray
int bolPrd=20;
double bolDev=2.0;
int keltPrd=20;
double keltFactor=1.5;
extern int triggerType=2;
extern int stochPeriod_trigger1=14;
extern int cciPeriod_trigger2=50;
extern int rsiPeriod_trigger3=14;
int cciPeriod=50;
double upB[];
double loB[];
double upB2[];
double loB2[];
double mm[];
double cciline[];
int i,j,slippage=3;
double breakpoint=0.0;
double ema=0.0;
int peakf=0;
int peaks=0;
int valleyf=0;
int valleys=0, limit=0;
double ccis[61],ccif[61];
double delta=0;
double ugol=0;
int init() {
IndicatorBuffers(6);
SetIndexStyle(0,DRAW_HISTOGRAM,STYLE_SOLID,1,indicator_color1);
SetIndexBuffer(0,upB);
SetIndexEmptyValue(0,EMPTY_VALUE);
SetIndexStyle(1,DRAW_HISTOGRAM,STYLE_SOLID,1,indicator_color2);
SetIndexBuffer(1,loB);
SetIndexEmptyValue(1,EMPTY_VALUE);
SetIndexStyle(2,DRAW_HISTOGRAM,STYLE_SOLID,2,indicator_color3);
SetIndexBuffer(2,upB2);
SetIndexEmptyValue(2,EMPTY_VALUE);
SetIndexStyle(3,DRAW_HISTOGRAM,STYLE_SOLID,2,indicator_color4);
SetIndexBuffer(3,loB2);
SetIndexEmptyValue(3,EMPTY_VALUE);
SetIndexBuffer(4,mm);
SetIndexStyle(5,DRAW_LINE);
SetIndexBuffer(5,cciline);
return(0);
}
int deinit() {
SetLevelValue(1,NULL);
SetLevelValue(2,NULL);
SetLevelValue(3,NULL);
SetLevelValue(4,NULL);
}
int start() {
int counted_bars=IndicatorCounted();
int shift,limit;
double diff,d,std,bbs;
if (counted_bars<0) return(-1);
if (counted_bars>0) counted_bars--;
limit=Bars-31;
if(counted_bars>=31) limit=Bars-counted_bars-1;
for (shift=limit;shift>=0;shift--) {
switch (triggerType) {
case 1:
d=iStochastic(NULL,0,14,3,3,MODE_SMA,0,MODE_MAIN,shift)-50;
SetLevelValue(1,30);
SetLevelValue(2,-30);
IndicatorShortName("Bollinger Squeeze with Stochastic");
break;
case 2:
d=iCCI(NULL,0,cciPeriod,PRICE_CLOSE,shift);
SetLevelValue(1,-200);
SetLevelValue(2,-100);
SetLevelValue(3,100);
SetLevelValue(4,200);
IndicatorShortName("Bollinger Squeeze with CCI");
break;
case 3:
d=iRSI(NULL,0,14,PRICE_CLOSE,shift)-50;
SetLevelValue(1,20);
SetLevelValue(2,-20);
IndicatorShortName("Bollinger Squeeze with RSI");
break;
}
mm[shift]=d;
if(d>0) {
upB[shift]=d;
} else if (d<0){
loB[shift]=d;
}
cciline[shift]=d;
diff = iATR(NULL,0,keltPrd,shift)*keltFactor;
std = iStdDev(NULL,0,bolPrd,MODE_SMA,0,PRICE_CLOSE,shift);
bbs = bolDev * std / diff;
if(bbs<1) {
if (d > 0) {
upB2[shift]=d;
upB[shift]=0;
loB[shift]=0;
loB2[shift]=0;
} else {
loB2[shift]=d;
loB[shift]=0;
upB[shift]=0;
upB2[shift]=0;
}
} else {
if (d > 0) {
upB[shift]=d;
upB2[shift]=0;
loB[shift]=0;
loB2[shift]=0;
} else {
loB[shift]=d;
loB2[shift]=0;
upB[shift]=0;
upB2[shift]=0;
}
}
}
return(0);
}
Comments