Bollinger Squeeze v4_v1

Download script
Author: Copyright � 2005, Nick Bilak
Bollinger Squeeze v4_v1

This tool is designed to analyze market trends and volatility by combining three distinct mathematical concepts: momentum tracking, linear regression, and standard deviation analysis. It translates complex price movements into a visual representation that helps traders identify when the market is "squeezing" (consolidating) or preparing for a significant breakout.

Core Logic Components

1. Price Momentum & Trend Direction The script calculates a specific momentum value based on a Linear Regression model. Unlike a simple moving average, this method looks at the relationship between the current closing price and a calculated midpoint of the high and low ranges over a set period.

  • Upward Momentum: If the momentum value is positive and increasing, it highlights a bullish trend.
  • Downward Momentum: If the momentum value is negative and decreasing, it highlights a bearish trend. The visual output uses different colors to distinguish between these growing strengths.

2. Volatility Normalization (The "Squeeze" Factor) The script performs a sophisticated calculation to determine if the current market activity is unusually quiet or volatile. It compares two primary metrics:

  • Average True Range (ATR): This measures the typical price movement over a specific timeframe.
  • Standard Deviation: This measures how much the price fluctuates away from its average.

By dividing the standard deviation by the adjusted ATR, the script generates a "Volatility Ratio." When this ratio falls below a specific threshold, it indicates that the market is in a "Squeeze" state—meaning price action is becoming tight and compressed.

3. Signal Generation The final output combines these two streams of data to provide visual cues on the chart:

  • Trend Indicators: The primary histograms show the current direction of momentum.
  • Breakout Alerts: When the market enters a "Squeeze" state (low volatility), the script places specific markers (arrows) on the chart. These are intended to signal moments where the price is coiled like a spring, suggesting that a significant move in one direction may be imminent.

Summary for the User

In plain terms, this script monitors how "stretched" or "compressed" the market is. It filters out general noise by calculating a smoothed regression of price movements and then alerts you when the market becomes unusually calm. When the volatility drops into a "squeeze," the tool provides visual markers to help you identify potential high-probability entry points for when the price eventually breaks out of its current range.

Indicators Used
Indicator of the average true rangeStandard Deviation indicatorMoving average indicator
Miscellaneous
Implements a curve of type %1
16 Views
0 Downloads
0 Favorites
Bollinger Squeeze v4_v1
//+------------------------------------------------------------------+
//|                                                    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 LimeGreen
#property indicator_color4 LightPink
#property indicator_color5 Blue
#property indicator_color6 Red

//---- input parameters
extern int       bolPrd=20;
extern double    bolDev=2.0;
extern int       keltPrd=20;
extern double    keltFactor=1.5;
extern int       momPrd=10;

//---- buffers
double upB[];
double loB[];
double upK[];
double loK[];
double upB2[];
double loB2[];
double mm[];

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()
  {
//---- indicators
   IndicatorBuffers(7);
   SetIndexStyle(0,DRAW_HISTOGRAM,STYLE_SOLID,2);
   SetIndexBuffer(0,upB);
   SetIndexEmptyValue(0,EMPTY_VALUE);
   SetIndexStyle(1,DRAW_HISTOGRAM,STYLE_SOLID,2);
   SetIndexBuffer(1,loB);
   SetIndexEmptyValue(1,EMPTY_VALUE);

   SetIndexStyle(2,DRAW_HISTOGRAM,STYLE_SOLID,2);
   SetIndexBuffer(2,upB2);
   SetIndexEmptyValue(2,EMPTY_VALUE);
   SetIndexStyle(3,DRAW_HISTOGRAM,STYLE_SOLID,2);
   SetIndexBuffer(3,loB2);
   SetIndexEmptyValue(3,EMPTY_VALUE);
   SetIndexBuffer(6,mm);

   SetIndexStyle(4,DRAW_ARROW);
   SetIndexBuffer(4,upK);
   SetIndexEmptyValue(4,EMPTY_VALUE);
   SetIndexArrow(4,167);
   SetIndexStyle(5,DRAW_ARROW);
   SetIndexBuffer(5,loK);
   SetIndexEmptyValue(5,EMPTY_VALUE);
   SetIndexArrow(5,167);
   
   return(0);
  }
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--)   {
      //d=iMomentum(NULL,0,momPrd,PRICE_CLOSE,shift);
      d=LinearRegressionValue(momPrd,shift);
      
      //d=iCCI(NULL,0,cciPeriod,PRICE_CLOSE,shift);
      
      mm[shift]=d;
      if(d>0) {
         if (mm[shift]>mm[shift+1]) {
            upB[shift]=d;
            upB2[shift]=0;
            loB[shift]=0;
            loB2[shift]=0;
         } else {
            upB[shift]=0;
            upB2[shift]=d;
            loB[shift]=0;
            loB2[shift]=0;
         }
         
      } else {
         if (mm[shift]<mm[shift+1]) {
            loB[shift]=d;
            loB2[shift]=0;
            upB[shift]=0;
            upB2[shift]=0;
         } else {
            loB[shift]=0;
            loB2[shift]=d;
            upB[shift]=0;
            upB2[shift]=0;
         }
         
      }
      
      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) {
         upK[shift]=0;
         loK[shift]=EMPTY_VALUE;
      } else {
         loK[shift]=0;
         upK[shift]=EMPTY_VALUE;
      }
   }
   return(0);
  }
//+------------------------------------------------------------------+


double LinearRegressionValue(int Len,int shift) {
   double SumBars = 0;
   double SumSqrBars = 0;
   double SumY = 0;
   double Sum1 = 0;
   double Sum2 = 0;
   double Slope = 0;

   SumBars = Len * (Len-1) * 0.5;
   SumSqrBars = (Len - 1) * Len * (2 * Len - 1)/6;

  for (int x=0; x<=Len-1;x++) {
   double HH = Low[x+shift];
   double LL = High[x+shift];
   for (int y=x; y<=(x+Len)-1; y++) {
     HH = MathMax(HH, High[y+shift]);
     LL = MathMin(LL, Low[y+shift]);
   }
    Sum1 += x* (Close[x+shift]-((HH+LL)/2 + iMA(NULL,0,Len,0,MODE_EMA,PRICE_CLOSE,x+shift))/2);
    SumY += (Close[x+shift]-((HH+LL)/2 + iMA(NULL,0,Len,0,MODE_EMA,PRICE_CLOSE,x+shift))/2);
  }
  Sum2 = SumBars * SumY;
  double Num1 = Len * Sum1 - Sum2;
  double Num2 = SumBars * SumBars-Len * SumSqrBars;

  if (Num2 != 0.0)  { 
    Slope = Num1/Num2; 
  } else { 
    Slope = 0; 
  }

  double Intercept = (SumY - Slope*SumBars) /Len;
  //debugPrintln(Intercept+" : "+Slope);
  double LinearRegValue = Intercept+Slope * (Len - 1);

  return (LinearRegValue);

}

Comments