B3 Consolidation Box: Breakout / Breakdown Indicator for ThinkorSwim

BenTen

Administrative
Staff member
Staff
VIP
Lifetime
Want to know if a stock is under consolidation? Well, this indicator is perfect for that. It basically highlights when a stock is consolidating and at which level it will be breaking down or breaking out. In addition, a stop loss level will be provided in case it's a false breakout/breakdown and target levels so you can know where to take profit.

Here are a few examples:

eMdcH7K.png


5t51NRr.png


voXgIWa.png


Notes:
  • Grey shadow box is your Consolidation box.
  • The white dotted line is Stop loss
  • Red lines are Profit Target Levels for Breakdown
  • Green lines are Profit Target Levels for Breakout
  • Use this indicator on the 5, 10, or 15 mins timeframe with Pre-market on.
## OneNote Archive Name: Consolidation Box v01 _B3
## Suggested Tos Name using JQ naming convention: ConsolidationBox_v01_B3
## OneNote Section: Volatility
## Archive Date: 02.10.2019
## Provenance: Posted by Amalia in the Lounge on_volume 02.05.2019

## Archive, Usage or Lounge Notes:
# 19:35 amalia: B3 posted a new study in the afterhours room. "Script is based on a strategy I learned from Ben's webcasts on TOS. He was doing some futurescast thing on consolidation boxes, and I had to see if I could make it work too. My Hypothesis is it is a great little scalper... you have to be willing to take singles and doubles and forget homers."
# Here's a link with some information in the header section:
# https://tos.mx/G7g3YJ


## End OneNote Archive Header
For a stripped down version of this study, see this post:
https://usethinkscript.com/threads/...own-indicator-for-thinkorswim.103/#post-10280


thinkScript Code

Rich (BB code):
# B3 Consolidation Box   v1

# -- Automates a box and shows the breakouts via price color with targets based on the box's range.

# -- In a system the gray balance line would be your stop, or you may exit on any trip back within the old box range.

# -- The color of the candles does not tell you when to be long or short, it simply tells you the last signal given.

# -- You must manage your trade targets via your own profit protection tactics.

# Intended only for the use of the person(s) to who(m) this script was originally distributed.

# User of the script assumes all risk;

# The coder and the distributers are not responsible for any loss of capital incurred upon usage of this script.

# amalia added commentary after chatting more with B3 about the study:

# The first 2 inputs will need to be set for the chart you are looking at. What you want to find is the consolidation box settings that give you actionable targeting. If the price is shooting way past the tgt6 point, you need to lower the second input. The first input should likely be either 1, 2 or 3 only. Script is based on a strategy I learned from Ben's webcasts on TOS. He was doing some futurescast thing on consolidation boxes, and I had to see if I could make it work too. My Hypothesis is it is a great little scalper... you have to be willing to take singles and doubles and forget homers. He was trading ES

declare upper;

input BarsUsedForRange = 2;

input BarsRequiredToRemainInRange = 7;

input TargetMultiple = 0.5;

input ColorPrice = yes;

input HideTargets = no;

input HideBalance = no;

input HideBoxLines = no;

input HideCloud = no;

input HideLabels = no;

# Identify Consolidation

def HH = highest(high[1], BarsUsedForRange);

def LL = lowest(low[1], BarsUsedForRange);

def maxH = highest(hh, BarsRequiredToRemainInRange);

def maxL = lowest(ll, BarsRequiredToRemainInRange);

def HHn = if maxH == maxH[1] or maxL == maxL then maxH else HHn[1];

def LLn = if maxH == maxH[1] or maxL == maxL then maxL else LLn[1];

def Bh = if high <= HHn and HHn == HHn[1] then HHn else double.nan;

def Bl = if low >= LLn and LLn == LLn[1] then LLn else double.nan;

def CountH = if isnan(Bh) or isnan(Bl) then 2 else CountH[1] + 1;

def CountL = if isnan(Bh) or isnan(Bl) then 2 else CountL[1] + 1;

def ExpH = if barnumber() == 1 then double.nan else

            if CountH[-BarsRequiredToRemainInRange] >= BarsRequiredToRemainInRange then HHn[-BarsRequiredToRemainInRange] else

            if High <= ExpH[1] then ExpH[1] else double.nan;

def ExpL = if barnumber() == 1 then double.nan else

            if Countl[-BarsRequiredToRemainInRange] >= BarsRequiredToRemainInRange then LLn[-BarsRequiredToRemainInRange] else

            if Low >= ExpL[1] then ExpL[1] else double.nan;

# Plot the High and Low of the Box; Paint Cloud

plot BoxHigh = if !isnan(expL) and !isnan(ExpH) then ExpH else double.nan;

plot BoxLow = if !isnan(expL) and !isnan(ExpH) then ExpL else double.nan;

boxhigh.setdefaultColor(color.dark_green);

BoxHigh.setpaintingStrategy(paintingStrategy.HORIZONTAL);

BoxLow.setpaintingStrategy(paintingStrategy.HORIZONTAL);

BoxLow.setdefaultColor(color.dark_red);

BoxHigh.SETHIDING(HideBoxLines);

BoxLow.SETHIDING(HideBoxLines);

addcloud(if !HideCloud then BoxHigh else double.nan, BoxLow, color.gray, color.gray);

# Things to the Right of a Finished Box

def eH = if barnumber() == 1 then double.nan else if !isnan(BoxHigh[1]) and isnan(BoxHigh) then BoxHigh[1] else eh[1];

def eL = if barnumber() == 1 then double.nan else if !isnan(BoxLow[1]) and isnan(BoxLow) then BoxLow[1] else el[1];

def diff = (eh - el) * TargetMultiple;

plot Balance = if isnan(boxhigh) and isnan(boxlow) then (eh+el)/2 else double.nan;

plot Htgt_1 = if isnan(Boxhigh) and high >= eh then eh + diff else double.nan;

plot Htgt_2 = if isnan(Boxhigh) and high >= eh then eh + diff*2 else double.nan;

plot Htgt_3 = if isnan(Boxhigh) and high >= eh then eh + diff*3 else double.nan;

plot Htgt_4 = if isnan(Boxhigh) and high >= eh then eh + diff*4 else double.nan;

plot Htgt_5 = if isnan(Boxhigh) and high >= eh then eh + diff*5 else double.nan;

plot Htgt_6 = if isnan(Boxhigh) and high >= eh then eh + diff*6 else double.nan;

plot Ltgt_1 = if isnan(BoxLow) and Low <= eL then eL - diff else double.nan;

plot Ltgt_2 = if isnan(BoxLow) and Low <= eL then eL - diff*2 else double.nan;

plot Ltgt_3 = if isnan(BoxLow) and Low <= eL then eL - diff*3 else double.nan;

plot Ltgt_4 = if isnan(BoxLow) and Low <= eL then eL - diff*4 else double.nan;

plot Ltgt_5 = if isnan(BoxLow) and Low <= eL then eL - diff*5 else double.nan;

plot Ltgt_6 = if isnan(BoxLow) and Low <= eL then eL - diff*6 else double.nan;

Balance.SETHIDING(HideBalance);

Balance.setdefaultColor(CREATECOLOR(255,255,255));

Balance.setpaintingStrategy(PAIntingStrategy.SQUARES);

Htgt_2.setlineWeight(2);

Htgt_4.setlineWeight(2);

Htgt_6.setlineWeight(2);

Htgt_1.setdefaultColor(CREATECOLOR( 50, 100 , 75));

Htgt_1.setpaintingStrategy(PAIntingStrategy.DASHES);

Htgt_2.setdefaultColor(CREATECOLOR( 50, 100 , 75));

Htgt_2.setpaintingStrategy(paintingStrategy.HORIZONTAL);

Htgt_3.setdefaultColor(CREATECOLOR( 50, 100 , 75));

Htgt_3.setpaintingStrategy(PAIntingStrategy.DASHES);

Htgt_4.setdefaultColor(CREATECOLOR( 50, 100 , 75));

Htgt_4.setpaintingStrategy(paintingStrategy.HORIZONTAL);

Htgt_5.setdefaultColor(CREATECOLOR( 50, 100 , 75));

Htgt_5.setpaintingStrategy(PAIntingStrategy.DASHES);

Htgt_6.setdefaultColor(CREATECOLOR( 50, 100 , 75));

Htgt_6.setpaintingStrategy(paintingStrategy.HORIZONTAL);

Ltgt_2.setlineWeight(2);

Ltgt_4.setlineWeight(2);

Ltgt_6.setlineWeight(2);

Ltgt_1.setdefaultColor(CREATECOLOR( 100, 50 , 75));

Ltgt_1.setpaintingStrategy(PAIntingStrategy.DASHES);

Ltgt_2.setdefaultColor(CREATECOLOR( 100, 50 , 75));

Ltgt_2.setpaintingStrategy(paintingStrategy.HORIZONTAL);

Ltgt_3.setdefaultColor(CREATECOLOR( 100, 50 , 75));

Ltgt_3.setpaintingStrategy(PAIntingStrategy.DASHES);

Ltgt_4.setdefaultColor(CREATECOLOR( 100, 50 , 75));

Ltgt_4.setpaintingStrategy(paintingStrategy.HORIZONTAL);

Ltgt_5.setdefaultColor(CREATECOLOR( 100, 50 , 75));

Ltgt_5.setpaintingStrategy(PAIntingStrategy.DASHES);

Ltgt_6.setdefaultColor(CREATECOLOR( 100, 50 , 75));

Ltgt_6.setpaintingStrategy(paintingStrategy.HORIZONTAL);

Htgt_1.SETHIDING(HIDETARGETS);

Htgt_2.SETHIDING(HIDETARGETS);

Htgt_3.SETHIDING(HIDETARGETS);

Htgt_4.SETHIDING(HIDETARGETS);

Htgt_5.SETHIDING(HIDETARGETS);

Htgt_6.SETHIDING(HIDETARGETS);

Ltgt_1.SETHIDING(HIDETARGETS);

Ltgt_2.SETHIDING(HIDETARGETS);

Ltgt_3.SETHIDING(HIDETARGETS);

Ltgt_4.SETHIDING(HIDETARGETS);

Ltgt_5.SETHIDING(HIDETARGETS);

Ltgt_6.SETHIDING(HIDETARGETS);

# Labels

addlabel(!HideLabels, "TgtLvls = " + diff + "pts each | Bal = " + balance, if high > eh  and low < el then color.yellow else if high > eh then color.green else if low < el then color.red else color.gray);

addlabel(!HideLabels && high > eh && low < el, "OUTSIDE BAR!!", color.yellow);

addlabel(!HideLabels && high > eh && low >= el, "Long", color.green);

addlabel(!HideLabels && high <= eh && low < el, "Short", color.red);

#Price Color

assignPriceColor(if !ColorPrice then color.current else if !isnan(BoxHigh) then color.gray else

                    if high > eh  and low < el then color.yellow else

                    if high > eh then color.green else if low < el then color.red else color.gray);

Shareable Link

https://tos.mx/oPI7Kp

Video Tutorial

 
Last edited by a moderator:

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

Very nice @BenTen - Looking forward to checking it out. Thanks for posting it..!! :)

 
Last edited:
@Steve2286 I couldn't find a watchlist column or alert for this indicator yet.

 
Last edited:
I'm a little confused as to which side of the trade you're supposed to take when its just the consolidation box present and the stoploss line isn't available yet..? But this would also be the best time to take the trade, so how do we know which side to take?
 
I'm a little confused as to which side of the trade you're supposed to take when its just the consolidation box present and the stoploss line isn't available yet..? But this would also be the best time to take the trade, so how do we know which side to take?
@Adeel06 Please read inside the Code at the top of the page. @BenTen Also put some notes above the code. The coder wrote this for someone specifically, the rest of us are left to figure out how best to use it. Anyone else, please jump in.
 
Last edited:
This would be very fast like the ORB. In a paper account someone might want to try the ORB Breakout scanner to see how it lines up. (if one exists)

@markos @tenacity11 I looked at the code for B3 Consolidation Box, looks like the scanner barfed of complexity issues so unfortunately won't be scannable based on the code.

However here's a real simple ORB scan, run this on a small aggregation, say 5 minutes or less

Code:
def Active = SecondsFromTime(0930) > 0 and SecondsTillTime(1000) >= 0;
def ORBH = if Active and !Active[1] then high else if Active and high > ORBH[1] then high else ORBH[1];
plot scan = !Active and close > ORBH;
 
def Active = SecondsFromTime(0930) > 0 and SecondsTillTime(1000) >= 0; def ORBH = if Active and !Active[1] then high else if Active and high > ORBH[1] then high else ORBH[1]; plot scan = !Active and close > ORBH;
@tomsk Thanks so much. Will try this morning.
 
Is it possible to strip the code until I'm left with just the grey consolidation box? Don't need any other lines.

@Playstation As requested here is B3 Consolidation Box with all lines removed. Only the grey consolidation box remains
Load this study on a 5 minute chart of /ES and you 'll see all the consolidation boxes displayed

Code:
# Consolidation Box Barebones - with Grey Consolidation Box
# tomsk
# 11.23.2019

# As requested by Playstation, this is B3 Consolidation Box with all lines removed
# Only the grey consolidation box remains

# B3 Consolidation Box
# Hammond B3
# 2.2.2019

input BarsUsedForRange = 2;
input BarsRequiredToRemainInRange = 7;
input ColorPrice = yes;
input HideBoxLines = no;
input HideLabels = no;

# Identify Consolidation
def HH = highest(high[1], BarsUsedForRange);
def LL = lowest(low[1], BarsUsedForRange);
def maxH = highest(hh, BarsRequiredToRemainInRange);
def maxL = lowest(ll, BarsRequiredToRemainInRange);
def HHn = if maxH == maxH[1] or maxL == maxL then maxH else HHn[1];
def LLn = if maxH == maxH[1] or maxL == maxL then maxL else LLn[1];
def Bh = if high <= HHn and HHn == HHn[1] then HHn else double.nan;
def Bl = if low >= LLn and LLn == LLn[1] then LLn else double.nan;
def CountH = if isnan(Bh) or isnan(Bl) then 2 else CountH[1] + 1;
def CountL = if isnan(Bh) or isnan(Bl) then 2 else CountL[1] + 1;

def ExpH = if barnumber() == 1 then double.nan 
           else if CountH[-BarsRequiredToRemainInRange] >= BarsRequiredToRemainInRange then HHn[-BarsRequiredToRemainInRange] 
           else if High <= ExpH[1] then ExpH[1] 
           else double.nan;

def ExpL = if barnumber() == 1 then double.nan 
           else if Countl[-BarsRequiredToRemainInRange] >= BarsRequiredToRemainInRange then LLn[-BarsRequiredToRemainInRange] 
           else if Low >= ExpL[1] then ExpL[1] else double.nan;

# Plot the High and Low of the Box; Paint Cloud
plot BoxHigh = if !isnan(expL) and !isnan(ExpH) then ExpH else double.nan;
     boxhigh.setdefaultColor(color.dark_green);
     BoxHigh.setpaintingStrategy(paintingStrategy.HORIZONTAL);
     BoxHigh.SETHIDING(HideBoxLines);

plot BoxLow = if !isnan(expL) and !isnan(ExpH) then ExpL else double.nan;
     BoxLow.setpaintingStrategy(paintingStrategy.HORIZONTAL);
     BoxLow.setdefaultColor(color.dark_red);
     BoxLow.SETHIDING(HideBoxLines);

addcloud(BoxHigh, BoxLow, color.gray, color.gray);

# Things to the Right of a Finished Box
def eH = if barnumber() == 1 then double.nan else if !isnan(BoxHigh[1]) and isnan(BoxHigh) then BoxHigh[1] else eh[1];
def eL = if barnumber() == 1 then double.nan else if !isnan(BoxLow[1]) and isnan(BoxLow) then BoxLow[1] else el[1];

assignPriceColor(if !ColorPrice then color.current else if !isnan(BoxHigh) then color.gray else
                    if high > eh  and low < el then color.yellow else 
                    if high > eh then color.green else if low < el then color.red else color.gray);
# Consolidation Box Barebones
 
Is it possible to change code to work on longer time frames such as daily 1 year chart or weekly 5 year charts?

I mean a scan for those time frames.
 
Last edited by a moderator:
1. Tried this indicator out today on ULTA...worked great! Took +60% in less than an hour.
2. A scanner for this would be gold (I did read that isn't possible though)! You have to manually look for the setup...that's how I found ULTA.
3. It works on mobile!!! You get everthing except the shaded grey box - but you do get the red and green consolidation boundaries.

I used TMO and RSI Leguerre to validate. Also added my MAs after the fact...
 
1. Tried this indicator out today on ULTA...worked great! Took +60% in less than an hour.
2. A scanner for this would be gold (I did read that isn't possible though)! You have to manually look for the setup...that's how I found ULTA.
3. It works on mobile!!! You get everthing except the shaded grey box - but you do get the red and green consolidation boundaries.

I used TMO and RSI Leguerre to validate. Also added my MAs after the fact...


@hurricane5 The ECI sure is scannable, I previously converted that to be scannable. Here's the link

https://usethinkscript.com/threads/eci-gaussian-indicator-for-thinkorswim.1160/#post-10456
 

Similar threads

Not the exact question you're looking for?

Start a new thread and receive assistance from our community.

87k+ Posts
516 Online
Create Post

Similar threads

Similar threads

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