Scanner for consolidation box less than 2% move in a 3-5 day period

DevBar

New member
I haven't been able to find a scan that you can look for a consolidation period of choice, in this case 3-5days where the price has stayed within a 1-2% move up or down. I'd like to scan for stocks where I can adjust the time periods and the percentage moved in that time period. I have seen the "B3 Consolidation Box" which looks like it could work and also the "ECI Gaussian Indicator" but these are either for charting or the scans don't seem to allow adjustment for lengths of days, or desired % move. (So basically controlling the length and width of the box parameters and scanning for those parameters). If anyone can help with sending me to the correct thread or script that would be great. Or maybe I'm not using the scan scripts correctly on the ECI Gaussian version? Any help would be appreciated. Thank you
 
Solution
I haven't been able to find a scan that you can look for a consolidation period of choice, in this case 3-5days where the price has stayed within a 1-2% move up or down. I'd like to scan for stocks where I can adjust the time periods and the percentage moved in that time period. I have seen the "B3 Consolidation Box" which looks like it could work and also the "ECI Gaussian Indicator" but these are either for charting or the scans don't seem to allow adjustment for lengths of days, or desired % move. (So basically controlling the length and width of the box parameters and scanning for those parameters). If anyone can help with sending me to the correct thread or script that would be great. Or maybe I'm not using the scan scripts...
I haven't been able to find a scan that you can look for a consolidation period of choice, in this case 3-5days where the price has stayed within a 1-2% move up or down. I'd like to scan for stocks where I can adjust the time periods and the percentage moved in that time period. I have seen the "B3 Consolidation Box" which looks like it could work and also the "ECI Gaussian Indicator" but these are either for charting or the scans don't seem to allow adjustment for lengths of days, or desired % move. (So basically controlling the length and width of the box parameters and scanning for those parameters). If anyone can help with sending me to the correct thread or script that would be great. Or maybe I'm not using the scan scripts correctly on the ECI Gaussian version? Any help would be appreciated. Thank you

here is a study to test in a lower chart.
it will plot a spike at 1, when price has stayed within a range of x% of the close, over the past x days.
i think it will work for a scan...

set the chart to days

Code:
declare lower;
input days = 5;
input percent = 1.0;

def hi = highest(high, days);
def lo = lowest(low, days);
def rng = hi - lo;
def rng_per = round(100 * rng / close, 1);
plot isrng = (rng_per <= percent);
 
Solution
Thanks for looking into this. I can enter the script into the thinkorswim editor which doesn't show any errors but when I run it as a scan it doesn't return any results. I put it into the lower chart and it worked there with a 5m up to an hour chart. If I put it at a yearly chart (1yr:1D) with each candle being a day, it doesn't seem to work. You think that'd why it doesn't work in as a scan?
 
This is one chart script that seems to have the idea but can it be made into a scan where you can choose the length of days and the movement parameters?
Found this really interesting indicator for ThinkorSwim called B3 Consolidation Box that I wanted to share with everyone here.

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.


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

 
This is also another example of a scanner but the inputs aren't fully clear what they do so maybe I am using it wrong or it doesn't give you the ability to determine the length of the box and the percentage of the price movement in that box.
Given some of the recent discussion on consolidation and Mobius ECI study, for those folks that might be interested to scan the universe of stocks for such setups, I have converted Mobius ECI study into a scan. Two scan conditions are created - one for the bullish case and another for the bearish case. I have also removed extraneous variables not required for the scan.

Tested this on a scan of the S&P 500 (Daily aggregation) with the following results
Bullish scan - 138 hits, e.g. AMZN
Bearish scan - 20 hits e.go. PSX

Please remember that the scanner only expects one plot so comment out the scan plot statement you do not wish.
Here then is the scan code

Code:
# ECI Scan
# tomsk
# 11.25.2019

# Given some of the recent discussion on consolidation and Mobius ECI study,
# for those folks that might be interested to scan the universe of stocks for
# such setups, I have converted Mobius ECI study into a scan. Two scan conditions
# are created - one for the bullish case and another for the bearish case. I
# have also removed variables not required for the scan.

# Expansion Contraction Indication
# Flags: Uses Fractal enregy to locate price compression or flag areas
# Mobius
# 3.18.2017

# User Inputs
input EciLength = 5; #hint EciLength: Length for calculations.
input AvgType = AverageType.Simple; #hint AvgType: Average Type
input MeanValue = HL2; #hint MeanValue: Point of origen.
input betaDev = 4;

script G {
    input p = close;
    input n = 2;
    input b = 1.05;
    def w;
    def beta;
    def alpha;
    def G;
    w = (2 * Double.Pi / n);
    beta = (1 - Cos(w)) / (Power(1.414, 2.0 / b) - 1 );
    alpha = (-beta + Sqrt(beta * beta + 2 * beta));
    G = Power(alpha, 4) * p +
                 4 * (1 – alpha) * G[1] – 6 * Power( 1 - alpha, 2 ) * G[2] +
                 4 * Power( 1 - alpha, 3 ) * G[3] - Power( 1 - alpha, 4 ) * G[4];
    plot data = G;
}
# Variables:
def bar = barNumber();
def o = g(open, ECIlength, betaDev);
def h = g(high, ECIlength, betaDev);
def l = g(low, ECIlength, betaDev);
def c = g(close, ECIlength, betaDev);
def ECI = Log(Sum(Max(h, c[1]) - Min(l, c[1]), ECIlength) /
           (Highest(h, ECIlength) - Lowest(l, ECIlength))) /
            Log(ECIlength);
def Avg = MovingAverage(AverageType = AvgType, ECI, ECILength);
def S1 = if ECI crosses above Avg
         then MeanValue
         else S1[1];
def S = ECI > Avg;
def SBars = if ECI > Avg
            then bar
            else Double.NaN;
def StartBar = if ECI crosses above Avg
               then bar
               else StartBar[1];
def LastSBar = if ECI crosses below Avg
               then bar
               else LastSBar[1];
def PP = if ECI crosses above Avg
         then MeanValue
         else PP[1];
def Mean_Limit = if bar != StartBar
                 then bar - StartBar
                 else if bar == StartBar
                      then Double.NaN
                      else Mean_Limit[1];
def SHigh = if ECI crosses above Avg
            then h
            else SHigh[1];
def SHighBar = if S and
                  h == SHigh
               then bar
               else SHighBar[1];
def SHigh_Limit = if bar == StartBar
                  then Double.NaN
                  else if bar > StartBar
                       then bar - SHighBar
                       else SHigh_Limit[1];
def SLow = if ECI crosses above Avg
           then l
           else SLow[1];
def SLowBar = if S and
                  l == SLow
              then bar
              else SLowBar[1];
def SLow_Limit = if bar == StartBar
                 then Double.NaN
                 else if bar > StartBar
                      then bar - SLowBar
                      else SLow_Limit[1];

# Comment out (#) the ONE not needed
plot BullScan = close crosses above SHigh;
#plot BearScan = close crosses below SLow;
# ECI Scan
 
here is a study to test in a lower chart.
it will plot a spike at 1, when price has stayed within a range of x% of the close, over the past x days.
i think it will work for a scan...

set the chart to days

Code:
declare lower;
input days = 5;
input percent = 1.0;

def hi = highest(high, days);
def lo = lowest(low, days);
def rng = hi - lo;
def rng_per = round(100 * rng / close, 1);
plot isrng = (rng_per <= percent);

so it will plot a 1 if the defined percent is greater than the stock's price range %
I'm having a little trouble figuring out how to scan for if stocks have had a small, tight 6 month (120 days) consolidation.

This is the day chart with 120 days and 40% range (I'm looking for far less range)
safasdfasdfasfasd.png


Theres something wrong with the scan sir
 

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

Similar threads

Not the exact question you're looking for?

Start a new thread and receive assistance from our community.

87k+ Posts
419 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