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
 

Thomas

Active member
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
 

cswu1211

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


[/QUOTE]
following the steps above and starting a trial scan, but Can't find the choice of parameters: BB, bandwidth length, etc...Only
Any suggestion ?

[img]https://i.imgur.com/e6Zqxx8.png[/img]

tks
e6Zqxx8.png
 

MerryDay

Administrative
Staff member
Staff
VIP
@TY_Joe Technically, the scripts for studies, watchlists, and scans could be the same. Study scripts are saved under the study tab. Watchlist scripts are saved as Watch List columns, and scanning scripts are referenced in scans.

However, in reality, the chart studies and watchlists end up being slightly different, mostly because how you want to format a chart is different from how you format the watchlist column.

As for scans, a majority of the studies on this forum can be directly referenced in scans. Occasionally, a separate scan needs to be set up because of the complexity of the script, customization of the conditions upon which to scan, use of secondary aggregations, and other peculiarities of the TOS platform.
 

MerryDay

Administrative
Staff member
Staff
VIP
Explosive Squeeze Watchlist

a2.png

Shared Link for Explosive Squeeze watchlist: http://tos.mx/wYCkrrw
Click here for --> Easiest way to load shared links
Ruby:
# 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
plot 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;

def ExplosiveSqueeze = TBW and TBWA;
AssignBackGroundColor(if ExplosiveSqueeze then color.dark_orange else color.violet) ;
@TY_Joe
 

Almighty1

New member
Explosive Squeeze Watchlist

View attachment 725
Shared Link for Explosive Squeeze watchlist: http://tos.mx/wYCkrrw
Click here for --> Easiest way to load shared links
Ruby:
# 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
plot 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;

def ExplosiveSqueeze = TBW and TBWA;
AssignBackGroundColor(if ExplosiveSqueeze then color.dark_orange else color.violet) ;
@TY_Joe
I tried to use the import shared item under Setup in TOS but the shared items list is blank after it says successfully imported, what am I doing wrong? Is this the same thing as Short Squeeze scan?
 

MerryDay

Administrative
Staff member
Staff
VIP
@Almighty1 When you saved the watchlist, do you remember what name you saved it under? If not, follow these instructions exactly
--> Easiest way to load shared links again, to load the watchlist column again, making sure to write down what name you save the watchlist column under.

After that follow these instructions ---> https://usethinkscript.com/threads/answers-to-commonly-asked-questions.6006/#post-70999 to find that watchlist column so you can load it to your watchlist.

In answer to your question, The explosive squeeze is not EXACTLY like other squeeze indicators. The squeeze indicators on the forum are all slightly different flavors. I have found that reading through the threads, is the best way to understand the nuances between them as well as picking up tips as to how other members are using these indicators.
 

The ARC

New 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;
thank you for sharing this.

I am brand new to scripting and have no prior experience. Based on the book, Bollinger recommended 6 month "lookback" period. How do I add that?
Secondly, how do I modify the script such that it only shows stocks that are in low volatility state moving in tight range in the user selected timeperiod/lookback period?
Eg: if bandwidth in user selected time period of 20 days is in tight range of 11 to 12, it shows up on the squeeze scan
 

MerryDay

Administrative
Staff member
Staff
VIP
thank you for sharing this.

I am brand new to scripting and have no prior experience. Based on the book, Bollinger recommended 6 month "lookback" period. How do I add that?
Secondly, how do I modify the script such that it only shows stocks that are in low volatility state moving in tight range in the user selected timeperiod/lookback period?
Eg: if bandwidth in user selected time period of 20 days is in tight range of 11 to 12, it shows up on the squeeze scan
Looks like no contributor has been able to help you. It could be that it is not clear what you are asking or you did not provide enough information.
Did you provide a study as well as a marked up image?
Please reply with a detail explanation of what you are trying to accomplish. or there is a risk that your post will be deleted due to inactivity.
Provide a marked-up screenshot of what a chart that displays what all your conditions would look like.
Questions without images are much less likely to get a response!
Unsure of how to upload screenshots to the forum, Here are directions.
 

Similar threads

Top