Explosive Squeeze Scan Using Custom Bollinger Bandwidth Indicator

J

justAnotherTrader

Member
VIP
This one is fun. It uses the bollinger bandwidth as a measure of volatility.

The scan setup is simple:
  • High Average Bandwidth > 30 (This implies very high volatility. For instance the 60 day average bandwidth on TSLA is 43 compared to SPY which is 8)
  • Current Bandwidth < 15 (A low volatility state in a high volatility stock means squeeze is coming, the lower the volatility the better)

Here is the indicator:

Code:
declare lower;

input averageType = AverageType.Simple;
input price = close;
input displace = 0;
input length = 20;
input Num_Dev_Dn = -2.0;
input Num_Dev_Up = 2.0;
input BulgeLength = 150;
input SqueezeLength = 150;

def upperBand = BollingerBands(price, displace, length, Num_Dev_Dn, Num_Dev_Up, averageType).UpperBand;
def lowerBand = BollingerBands(price, displace, length, Num_Dev_Dn, Num_Dev_Up, averageType).LowerBand;
def midLine = BollingerBands(price, displace, length, Num_Dev_Dn, Num_Dev_Up, averageType).MidLine;

plot Bandwidth = (upperBand - lowerBand) / midLine * 100;
Bandwidth.SetDefaultColor(Color.GREEN);

plot Bulge = Highest(Bandwidth, BulgeLength);
Bulge.SetDefaultColor(GetColor(8));
Bulge.setStyle(Curve.SHORT_DASH);

plot Squeeze = Lowest(Bandwidth, SqueezeLength);
Squeeze.SetDefaultColor(GetColor(8));
Squeeze.setStyle(Curve.SHORT_DASH);

#Bandwidth Label
AddLabel(Bandwidth, Concat("CurrentVolatility = ", Bandwidth), color.GREEN);

#Moving Average Volatility
def var = Bandwidth;
input len = 7;
input len1 = 14;
input len2 = 60;
input len3 = 120;
def displace1 = 0;
plot AvgVolatility7 = ExpAverage(var[-displace], len);
plot AvgVolatility14 = ExpAverage(var[-displace], len1);
plot AvgVolatility60 = ExpAverage(var[-displace], len2);
plot AvgVolatility120 = ExpAverage(var[-displace], len3);

AvgVolatility7.SetDefaultColor(Color.Dark_Green);
AvgVolatility14.SetDefaultColor(Color.Yellow);
AvgVolatility60.SetDefaultColor(Color.Blue);
AvgVolatility120.SetDefaultColor(Color.Magenta);

#Average Volatility Labels
AddLabel(AvgVolatility7, Concat("7VolatilityAverage = ", AvgVolatility7), color.DARK_GREEN);
AddLabel(AvgVolatility14, Concat("14VolatilityAverage = ", AvgVolatility14), color.YELLOW);
AddLabel(AvgVolatility60, Concat("60VolatilityAverage = ", AvgVolatility60), color.BLUE);
AddLabel(AvgVolatility120, Concat("120VolatilityAverage = ", AvgVolatility120), color.MAGENTA);
 
Last edited by a moderator:
wtf_dude

wtf_dude

Active member
Did this for me, but others might want to use it. It's the same thing but it's a customizable scan. Save it as a chart study first and when you bring it up as a custom study on the scan tab you can adjust the bollinger bands, the bandwidth average length, the bandwidth average minimum, and the current bandwidth maximum. Just change your variables and select "is true" (which just confirms all your conditions are correct) Seems to work like a charm. Good job, JustAnotherTrader!!

Code:
# ExplosiveSqueeze by JustAnotherTrader
# Custom scan mods by WTF_Dude

input averageType = AverageType.Simple;
input price = close;
input length = 20;
input Num_Dev_Dn = -2.0;
input Num_Dev_Up = 2.0;
def displace = 0;

def upperBand = BollingerBands(price, displace, length, Num_Dev_Dn, Num_Dev_Up, averageType).UpperBand;
def lowerBand = BollingerBands(price, displace, length, Num_Dev_Dn, Num_Dev_Up, averageType).LowerBand;
def midLine = BollingerBands(price, displace, length, Num_Dev_Dn, Num_Dev_Up, averageType).MidLine;
def Bandwidth = (upperBand - lowerBand) / midLine * 100;   #current bandwidth

#Moving Average Volatility
input BandwidthAverageLength = 60; #length of bandwidth average
def BandwidthAverage = ExpAverage(Bandwidth[-displace], BandwidthAverageLength);

input BandwidthMax = 15;
def TBW = Bandwidth <= BandwidthMax;

input BandwidthAvgMin = 30;
def TBWA = Bandwidthaverage > BandwidthAvgMin;
#def TBWA = BandwidthAvgMin is greater than BandwidthAverage;

plot ExplosiveSqueeze = TBW and TBWA;
 
J

jeremyadorna

New member
VIP
This is interesting. trying to figure out how you use it. can you share? thanks
 
J

justAnotherTrader

Member
VIP
This is interesting. trying to figure out how you use it. can you share? thanks
I found two ways I like using it so far. The first way is on the daily chart top identify squeezes and buy/ sell the breakout and breakdown. Another way is to reverse the idea and look for a relatively low volatility average and a high volatility currently. I use this second idea intraday to identify stocks that possibly got some fundamentally changing news and is breaking up/ down. I'm still playing around with it but my thoughts are there are many ways to alter the strategy to find stocks in certain stages of boom bust cycles.
 
J

jeremyadorna

New member
VIP
So I see multiple timeframe volatity marks on the indicator, right? So how do you determine the squeeze? I’m used to Keltner over bollinger version. And how do you determine the post squeeze trajectory projection?

On the labels in the indicator, what does the number before the label mean? Is that the number of bars the average value is based on?
 
wtf_dude

wtf_dude

Active member
So I see multiple timeframe volatity marks on the indicator, right? So how do you determine the squeeze? I’m used to Keltner over bollinger version. And how do you determine the post squeeze trajectory projection?

On the labels in the indicator, what does the number before the label mean? Is that the number of bars the average value is based on?
I think you've misunderstood what he made here... This isn't a squeeze based on keltner channels. This indicator is based strictly on the width of the bollingers (how far away the top and bottom are from each other. Its a different indicator so there is no need for Keltners) goin way below their longtime average. Those aren't "marks" based on timeframe. Those are different smoothing averages you can use to compare the current bandwidth against.

Post squeeze trajectory isn't even a part of this. You'd need something else for that
 

Similar threads

Top