BB_SqueezeLRSml_4c
Download scriptThis 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:
- Bollinger Bands: These measure standard deviation (how much the price is "swinging" relative to its average).
- 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).
//+------------------------------------------------------------------+
//|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