BB_SqueezeLRSml_4c

Download script
BB_SqueezeLRSml_4c

This script is a specialized technical analysis tool designed to identify market momentum and volatility "squeezes"—periods where market price action is consolidating before a potential breakout. It combines three distinct mathematical concepts: Linear Regression, Bollinger Bands, and Keltner Channels.

Momentum Tracking via Linear Regression

The core of the logic relies on Linear Regression Slope. Rather than simply looking at whether the price is higher or lower than it was yesterday, the script calculates the "slope" of the price movement over a specific period.

  • Directional Strength: It determines if the market trend is moving upward (positive slope) or downward (negative slope).
  • Momentum Change: The logic distinguishes between active momentum and decelerating momentum. By comparing the current slope to the previous one, it can identify when a trend is gaining strength or beginning to lose steam, visually highlighting these transitions on your chart.

Volatility Filtering (The "Squeeze")

To ensure that trades are only considered during significant market movements, the script employs a volatility filter by comparing two different types of price channels:

  1. Bollinger Bands: These measure standard deviation (how much the price is "swinging" relative to its average).
  2. Keltner Channels: These measure the Average True Range (the actual distance the price moves).

The script calculates a "Squeeze Signal" by comparing these two metrics. When the Bollinger Bands contract significantly inside the Keltner Channels, it indicates that market volatility is extremely low—often referred to as a "squeeze."

Visual Signals

The script combines these two pieces of information to provide actionable visual cues:

  • Trend Identification: It paints different colors to represent the direction and intensity of the current price slope.
  • Breakout Alerts: When the volatility filter detects a "squeeze" (low volatility) combined with a specific directional slope, it generates a visual signal (an arrow). This tells the user that the market is coiled like a spring and may be about to move significantly in the direction of the current slope.

In summary, this tool acts as a dual-filter system: it identifies where the price wants to go (via Regression Slope) and when the price is primed to make a big move (via the Volatility Squeeze).

Indicators Used
Indicator of the average true rangeStandard Deviation indicatorMoving average indicator
Miscellaneous
Implements a curve of type %1
15 Views
0 Downloads
0 Favorites
BB_SqueezeLRSml_4c
//+------------------------------------------------------------------+
//|BB_SqueezeLRSm_4c  basedon ml code                  bbsqueeze.mq4 |
//|2007fxtsd ki    Copyright © 2005, Nick Bilak, beluck[AT]gmail.com |
//|           enhanced a little bit by CJ Rivas, carlos[AT]vealo.com |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2005, Nick Bilak" //
#property link      "http://metatrader.50webs.com/"

#property indicator_separate_window
#property indicator_buffers 5
#property indicator_color1 LimeGreen
#property indicator_color2 Red
#property indicator_color3 DarkGreen
#property indicator_color4 Maroon
#property indicator_color5 Yellow


#property  indicator_width1  2
#property  indicator_width2  2
#property  indicator_width3  2
#property  indicator_width4  2


//---- input parameters

extern int       LinRegrPeriod = 13;
extern int       Price =6;

extern int       bolPrd  = 20;
extern double    bolDev  = 2.0;
extern int       keltPrd = 20;
extern double    keltFactor= 1.5;
extern double    SqzSigLevel = -0.016;

extern int       MaxBarsToCount = 1500;
extern bool      ValuesDisplayOff  = true;

extern string    note_Price = "COHLMTW: C0,O1,H2,L3,Md4,Tp5,6WghC: Md(HL/2)4,Tp(HLC/3)5,Wgh(HLCC/4)6";

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


double SumSqrBars;
double SumBars;
double Num2;

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+

int init()
  {
//---- indicators
   SetIndexStyle(0,DRAW_HISTOGRAM,EMPTY);
   SetIndexBuffer(0,upB);
   SetIndexEmptyValue(0,EMPTY_VALUE);
   
   SetIndexStyle(1,DRAW_HISTOGRAM,EMPTY);
   SetIndexBuffer(1,loB);
   SetIndexEmptyValue(1,EMPTY_VALUE);

   SetIndexStyle(4,DRAW_ARROW,EMPTY);
   SetIndexBuffer(4,upK);
   SetIndexEmptyValue(4,EMPTY_VALUE);
   SetIndexArrow(4,159);
   
   SetIndexStyle(2,DRAW_HISTOGRAM,EMPTY);
   SetIndexEmptyValue(2,EMPTY_VALUE);
   SetIndexBuffer(2,upB2);

   SetIndexStyle(3,DRAW_HISTOGRAM,EMPTY);
   SetIndexEmptyValue(3,EMPTY_VALUE);
   SetIndexBuffer(3,loB2);


      SetIndexLabel(0,"upB");
      SetIndexLabel(1,"loB");
      SetIndexLabel(2,"upB2");
      SetIndexLabel(3,"loB2");
      SetIndexLabel(4,"upK");

  if (ValuesDisplayOff)
     {
      SetIndexLabel(0,"");
      SetIndexLabel(1,"");
      SetIndexLabel(2,"");
      SetIndexLabel(3,"");
      SetIndexLabel(4,"");
     }  
 
   IndicatorShortName("BB_Sqz ("+LinRegrPeriod+") "+Price+" |");


//----
   return(0);
  }
//+------------------------------------------------------------------+
//| Custor indicator deinitialization function                       |
//+------------------------------------------------------------------+

int deinit()
  {
//---- 
   
   return(0);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+

int start()
  {
   int   shift, limit=IndicatorCounted();
   double diff,d,dPrev, std,bbs;
   
   
   if (limit<0) return(-1);
   if (limit>0) limit--;
      limit=MathMin(Bars-limit,MaxBarsToCount);

   for (shift=limit;shift>=0;shift--)   
 
  {
    
   SumBars    = LinRegrPeriod * (LinRegrPeriod-1) * 0.5;
   SumSqrBars = LinRegrPeriod* (LinRegrPeriod-1) * (2 * LinRegrPeriod - 1)/6;
   Num2       = MathPow(SumBars,2) - LinRegrPeriod * SumSqrBars;

       d=LinearRegressionSlope(LinRegrPeriod,shift);      
       dPrev=LinearRegressionSlope(LinRegrPeriod,shift+1);        


      if(d>0) {
         if ((dPrev>0) && (dPrev > d))
         { upB2[shift]=d; upB[shift] = 0; }
 
          else { upB[shift]= d; upB2[shift] = 0; }
         loB[shift]=0;
         loB2[shift]=0;
 
      } else {
         if ((dPrev<0) && (dPrev < d))
         { loB2[shift]=d; loB[shift] = 0; }

          else { loB[shift]= d; loB2[shift] = 0; }
         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) 
      {
        if (d>0)
            upK[shift]= SqzSigLevel;
        else
            upK[shift]= -SqzSigLevel;
 
      } else {
 
         upK[shift]=EMPTY_VALUE;
      }
   }
   return(0);
  }
//+------------------------------------------------------------------+

double LinearRegressionSlope(int Len,int shift)
{
   double LinearRegSlope;
   double SumY = 0;
   double Sum1 = 0;
   double Num1;
   int    i;

   
   for (i=0; i<Len; i++) {
         Sum1 += i*iMA(NULL,0,1,0,0,Price,i+shift);
         SumY +=   iMA(NULL,0,1,0,0,Price,i+shift);
      }
      Num1 = Len * Sum1 - SumBars * SumY;



   if( Num2 != 0 ) 
         	LinearRegSlope = 100*Num1/Num2;
   else     LinearRegSlope = 0; 
   return  (LinearRegSlope);
}

Comments