Explosive Squeeze Scan Using Custom Bollinger Bandwidth Indicator

justAnotherTrader

Member
VIP
VIP Enthusiast
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

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;
 

justAnotherTrader

Member
VIP
VIP Enthusiast
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.
 

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

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
 

cswu1211

Member
VIP
@justAnotherTrader how to set up a scan condition wizard that specify:

1. BB bandwidth >= 30 and
2. AvgVolatility7 <= 15
or
3. AvgVolatility14<= 15?!

How to write ac script that calculate (BB_Upperband - BB_Lowerband) - 1 = %; and condition that scan the above value which is great or lesser than a particular %.

def PercentBandwidth = ((upperBand - lowerBand) - 1 )* 100; #current bandwidth percentage
 

JE $$

Member
VIP
Hey @wtf_dude, thanks for your scan. What settings on the scan in the inputs section have you found work well?

ie what settings do you find are good for finding candidates?

What do you usually select under the inputs tab on the scan for
bandwidth avg length
bandwidth max
bandwidth avg min

I guess I was having trouble figuring out which selection on the input tab will give you stocks with current bandwidth of <15 and avg> 30 but it seems that these are already in there as default settings correct? and the one that specifies the current bandwidth is called "bandwidth max" correct?

thanks again
 

sbukosky

New member
How does do these compare to using a built in custom scan using the existing Bollinger Bandwidth indicator?
 

Thomas

Active member
VIP
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
Is this something in the right direction,...otherwise difficult to understand explanation all around without an example http://tos.mx/XXxoGRV
 

Similar threads

Top