Repaints MTF Intraday 3-8 Bollinger Band with Squeeze for ThinkOrSwim

Repaints

chewie76

Well-known member
VIP
VIP Enthusiast
This indicator is best for intraday trading. It uses a 3 and 8 EMA Bollinger band that is based on the daily aggregation. Arrows will appear when price is extended past the 3 upper or lower Bollinger band. Squeezes are red/orange and indicate when price is about to break out. When the 3 is above the 8, the colors are greenish, when the 3 is below the 8, colors are reddish. Since this is based on the daily aggregation, the bands and averages will move slightly throughout the day but will not repaint once the day is over. Here is an example of 15 min chart of /NQ.

DNjnIoA.jpg


Shareable Link:
http://tos.mx/kL4HrRt

Code:
Code:
#Intraday 3-8 BollingerBand with Squeeze
#Assembled by Chewie on 3-13-2023

input length1 = 3;
input length2 = 8;
input displace = 0;
input aggregationPeriod1 = AggregationPeriod.day;
input aggregationPeriod2 = AggregationPeriod.day;

def price1 = close(period = aggregationPeriod1);
def price2 = close(period = aggregationPeriod2);
 
plot AVG1 = ExpAverage(price1[-displace], length1);
plot AVG2 = ExpAverage(price2[-displace], length2);

AVG1.AssignValueColor(if AVG1 >= AVG2 then color.lime
else if AVG1 <= AVG2 then color.dark_orange else color.gray);

AVG2.AssignValueColor(if AVG2 >= AVG1 then color.red
else if AVG2 <= AVG1 then color.green else color.gray);

AVG1.SetLineWeight(2);
AVG2.SetLineWeight(2);


#Bands

input Num_Dev_Dn = -2.0;
input Num_Dev_up = 2.0;

def sDev = stdev(data = price1[-displace], length = length1);

plot LowerBand = AVG1 + num_Dev_Dn * sDev;
plot UpperBand = AVG1 + num_Dev_Up * sDev;

LowerBand.AssignValueColor(if AVG1 >= AVG2 then color.lime
else if AVG1 <= AVG2 then color.dark_orange else color.gray);
UpperBand.AssignValueColor(if AVG1 >= AVG2 then color.lime
else if AVG1 <= AVG2 then color.dark_orange else color.gray);

def sDev2 = stdev(data = price2[-displace], length = length2);
plot LowerBand2 = AVG2 + num_Dev_Dn * sDev2;
plot UpperBand2 = AVG2 + num_Dev_Up * sDev2;

LowerBand2.AssignValueColor(if AVG1 >= AVG2 then color.green
else if AVG1 <= AVG2 then color.red else color.gray);
UpperBand2.AssignValueColor(if AVG1 >= AVG2 then color.green
else if AVG1 <= AVG2 then color.red else color.gray);

plot OB = HIGH > UpperBand;
OB.SetDefaultColor(Color.light_red);
OB.SetLineWeight(1);
OB.SetPaintingStrategy(PaintingStrategy.Boolean_arrow_DOWN);

plot OS = LOW < LowerBand;
OS.SetDefaultColor(Color.light_green);
OS.SetLineWeight(1);
OS.SetPaintingStrategy(PaintingStrategy.Boolean_arrow_up);

AddCloud(lowerband, lowerband2,  Color.dark_GREEN, Color.CURRENT);
AddCloud(upperband2, upperband,  Color.RED, Color.CURRENT);

AddCloud(lowerband2, lowerband,  Color.dark_GREEN, Color.CURRENT);
AddCloud(upperband, upperband2,  Color.RED, Color.CURRENT);

# SQUEEZE

input Squeeze = yes;
def lengths = 5;
def averageTypes = AverageType.SIMPLE;
def sDev1 = StDev(data = price1[-displace], length = lengths);
def MidLine = if Squeeze then MovingAverage(averageTypes, data = price1[-displace], length = lengths) else Double.NaN;
def LowerBandS = if Squeeze then MidLine + Num_Dev_Dn * sDev1 else Double.NaN;
def UpperBandS = if Squeeze then MidLine + Num_Dev_up * sDev1 else Double.NaN;


#KELTNER CHANNELS

def factorH = 1.0;
def factorM = 1.5;
def high1 = high(period = aggregationPeriod1);
def low1 = close(period = aggregationPeriod1);

def trueRangeAverageType = AverageType.SIMPLE;
def shiftH = factorH * MovingAverage(trueRangeAverageType, TrueRange(high1, price1, low1), lengths);
def shiftM = factorM * MovingAverage(trueRangeAverageType, TrueRange(high1, price1, low1), lengths);

def average = MovingAverage(averageTypes, price1, lengths);

def Upper_BandH = if Squeeze then average[-displace] + shiftH[-displace] else Double.NaN;
def Lower_BandH = if Squeeze then average[-displace] - shiftH[-displace] else Double.NaN;
def Upper_BandM = if Squeeze then average[-displace] + shiftM[-displace] else Double.NaN;
def Lower_BandM = if Squeeze then average[-displace] - shiftM[-displace] else Double.NaN;

AddCloud(if Squeeze and Upper_BandH < UpperBandS and Upper_BandH < Upper_BandM then Double.NaN else Upper_BandH, UpperBandS, Color.YELLOW, Color.YELLOW);
AddCloud(if Squeeze and Lower_BandH > LowerBandS then Double.NaN else Lower_BandH, LowerBandS, Color.YELLOW, Color.YELLOW);
AddCloud(if Squeeze and  Upper_BandM < UpperBandS then Double.NaN else Upper_BandM, UpperBandS, Color.RED, Color.RED);
AddCloud(if Squeeze and  Lower_BandM > LowerBandS then Double.NaN else Lower_BandM, LowerBandS, Color.RED, Color.RED);

# End Code
 
They are going to move on today's date. A good entry is when price is outside the band when you see arrows. Exit depends on where you want to place stop loss or profit taking. Reddish lines are downtrending and greenish lines are uptrending. If you would like more signals, you can change the aggregation period to 4 hours, 2 hour or 1 hour.
 
Last edited:
They are going to move on today's date. A good entry is when price is outside the band when you see arrows. Exit depends on where you want to place stop loss or profit taking. Reddish lines are downtrending and greenish lines are uptrending. If you would like more signals, you can change the aggregation period to 4 hours, 2 hour or 1 hour.
do you have scanner for this indicator ?
 
You can use the scan tab and create a scan with this study.

mod note --
scanner tutorial:
https://usethinkscript.com/threads/how-to-use-thinkorswim-stock-hacker-scans.284
I would also appreciate if someone could make a scan for this. I tried to make the scan myself but am having trouble setting the scan up to look for when the arrows are firing. I used this indicator today on AMZN & AAPL puts when it was sending red arrows in the red box and it worked like a charm. Thanks for sharing!
 
Many thanks @chewie76. Another helpful study, sir.

Just to add to above discourse for those who like to do weekly swings on an hourly chart: I am experimenting this study for weekly swing on the Hourly chart by setting both of the aggregation periods to Weekly from Day and it is showing me where we are in relationship to potential upside/downside if the momentum continues. Overall, this is a great addition along with Price Action. :)
 
This most obviously repaints, correct?

Any idea on how to backtest this strategy without lookahead bias?

What's the point of an indicator like this? I'm genuinely curious. Might as well just look back and grab high and low of the day and draw arrows.
 
Last edited by a moderator:
This most obviously repaints, correct?
Whenever you use a multi-timeframe study, by definition the close of the higher timeframe cannot be determined until the higher timeframe bar completely forms.
So in that sense, yes it repaints.

This type of repainting is desired in studies being used for support and resistance.
It redraws based on the most recent data.

Most of the support and resistance indicators on the forum repaint for this reason.

Any idea on how to backtest this strategy without lookahead bias?
It is not possible to backtest repainting indicators. They live in the moment. Due to the repainting, there is no way to capture that moment to attest to its profitability.

What's the point of an indicator like this? I'm genuinely curious. Might as well just look back and grab high and low of the day and draw arrows.
Bollinger bands determine whether prices are high or low on a relative basis.
Thus BBands react to changing dynamics; the fixed High / Low of the day do not.
 
Last edited:

Join useThinkScript to post your question to a community of 21,000+ developers and traders.

Not the exact question you're looking for?

Start a new thread and receive assistance from our community.

87k+ Posts
350 Online
Create Post

The Market Trading Game Changer

Join 2,500+ subscribers inside the useThinkScript VIP Membership Club
  • Exclusive indicators
  • Proven strategies & setups
  • Private Discord community
  • ‘Buy The Dip’ signal alerts
  • Exclusive members-only content
  • Add-ons and resources
  • 1 full year of unlimited support

Frequently Asked Questions

What is useThinkScript?

useThinkScript is the #1 community of stock market investors using indicators and other tools to power their trading strategies. Traders of all skill levels use our forums to learn about scripting and indicators, help each other, and discover new ways to gain an edge in the markets.

How do I get started?

We get it. Our forum can be intimidating, if not overwhelming. With thousands of topics, tens of thousands of posts, our community has created an incredibly deep knowledge base for stock traders. No one can ever exhaust every resource provided on our site.

If you are new, or just looking for guidance, here are some helpful links to get you started.

What are the benefits of VIP Membership?
VIP members get exclusive access to these proven and tested premium indicators: Buy the Dip, Advanced Market Moves 2.0, Take Profit, and Volatility Trading Range. In addition, VIP members get access to over 50 VIP-only custom indicators, add-ons, and strategies, private VIP-only forums, private Discord channel to discuss trades and strategies in real-time, customer support, trade alerts, and much more. Learn all about VIP membership here.
How can I access the premium indicators?
To access the premium indicators, which are plug and play ready, sign up for VIP membership here.
Back
Top