Dynamic TTM Squeeze Watchlist For ThinkOrSwim

Aktion

New member
Plus
mod note:
This watchlist column is a momentum + squeeze radar that tells you, at a glance, which stocks are building energy and which direction that energy is flowing.

OK this is kind of detailed fo my Tastes but do to the popularity of the TTM Squeeze Thought some might find it handy. NOTE you'll have to turn on "USE SYSTEM FONTS"
in the LOOK and FEEL Options

SO -
BackGround colors indicate Squeeze conditon , GREEN or Gray = Not in a SQUEEZE and RED = Squeezed
The Text gets a little more detailed, they indicate the HISTOGRAM Conditons. Cyan Blue Red Yellow followed by a arrow indicating the DIRECTION of the HISTOGRAM.

sqzplaywl.png


Code:
# Custom Watchlist Column: Squeeze + Momentum Histogram Trend

input price = close;
input length = 20;
input Num_Dev_Dn = -2.0;
input Num_Dev_up = 2.0;
input averageType = AverageType.SIMPLE;
input displace = 0;

def sDev = StDev(data = price[-displace], length = length);
def MidLineBB = MovingAverage(averageType, data = price[-displace], length = length);
def LowerBandBB = MidLineBB + Num_Dev_Dn * sDev;
def UpperBandBB = MidLineBB + Num_Dev_up * sDev;

input factorhigh = 1.0;
input factormid = 1.5;
input factorlow = 2.0;
input trueRangeAverageType = AverageType.SIMPLE;

def shifthigh = factorhigh * MovingAverage(trueRangeAverageType, TrueRange(high, close, low), length);
def shiftMid   = factormid   * MovingAverage(trueRangeAverageType, TrueRange(high, close, low), length);
def shiftlow   = factorlow   * MovingAverage(trueRangeAverageType, TrueRange(high, close, low), length);

def average = MovingAverage(averageType, price, length);
def Avg = average[-displace];

def UpperBandKCLow  = Avg + shiftlow[-displace];
def LowerBandKCLow  = Avg - shiftlow[-displace];
def UpperBandKCMid  = Avg + shiftMid[-displace];
def LowerBandKCMid  = Avg - shiftMid[-displace];
def UpperBandKCHigh = Avg + shifthigh[-displace];
def LowerBandKCHigh = Avg - shifthigh[-displace];

def K = (Highest(high, length) + Lowest(low, length)) / 2 + ExpAverage(close, length);
def momo = Inertia(price - K / 2, length);

# Squeeze definitions
def presqueeze   = LowerBandBB > LowerBandKCLow  and UpperBandBB < UpperBandKCLow;
def originalSqueeze = LowerBandBB > LowerBandKCMid and UpperBandBB < UpperBandKCMid;
def ExtrSqueeze  = LowerBandBB > LowerBandKCHigh and UpperBandBB < UpperBandKCHigh;

# Momentum states
def pos = momo >= 0;
def neg = momo < 0;
def up  = momo >= momo[1];
def dn  = momo < momo[1];

def PosUp = pos and up; #Cyan
def PosDn = pos and dn; # Blue
def NegDn = neg and dn; # Red
def NegUp = neg and up; # Yellow

def cyanup = PosUp and up[1];
def cyandn = PosUp and dn[1];
def blueup = posdn and up[1];
def bluedn = posdn and dn[1];
def redup = negdn and up[1];
def reddn = negdn and dn[1];
def yllwup = negup and up[1];
def yllwdn = negup and dn[1];




# Numeric output for watchlist sorting + display
def trendValue =
         if cyanup    then  4.0
    else if cyandn   then  3.0
    else if blueup   then  2.0
    else if bluedn   then  1.0   # Bullish but weakening
    else if redup   then -4.0
    else if reddn   then -3.0
    else if yllwup   then -2.0   # Bearish but improving (less negative)
    else if yllwdn   then -1.0   # Strong bearish (decreasing momentum)
    else  0.0;              # Neutral / flat

# Optional: tighter visual scale if you prefer
# def trendValue =
#     if PosUp then 2 else if PosDn then 1 else if NegUp then -1 else if NegDn then -2 else 0;

# Background coloring stays exactly the same
AssignBackgroundColor(
    if ExtrSqueeze then Color.DARK_RED
    else if originalSqueeze then Color.RED
    else if presqueeze then CreateColor(128, 128, 128)
    else Color.LIGHT_GREEN
);

AddLabel(yes,
    if trendValue == 4.0 then "C ▰🢅"
else if trendValue == 3.0 then "C ▰🢆"
else if trendValue == 2.0 then "B ▰🢅"
else if trendValue == 1.0 then "B ▰🢆"
else if trendValue == -4.0 then "R ▰🢅"
else if trendValue == -3.0 then "R ▰🢆"
else if trendValue == -2.0 then "Y ▰🢅"
else if trendValue == -1.0 then "Y ▰🢆"
else "0.0",
 
    if trendValue == 4.0 then CreateColor(0, 204, 204) # cyan
else if trendValue == 3.0 then CreateColor(0, 204, 204) # cyan
else if trendValue == 2.0 then Color.BLUE
else if trendValue == 1.0 then Color.BLUE
else if trendValue == -4.0 then CreateColor(204, 0, 0) # dark red
else if trendValue == -3.0 then CreateColor(204, 0, 0) # dark red
else if trendValue == -2.0 then Color.DARK_ORANGE # or Color.YELLOW
else if trendValue == -1.0 then Color.DARK_ORANGE
else Color.GRAY
);

This watchlist column displays two elements: the squeeze background color and the momentum label.

The squeeze background is produced by comparing the Bollinger Band envelope to three Keltner Channel envelopes of increasing width.

The momentum label is produced by evaluating the inertia‑based momentum engine, determining whether momentum is positive or negative, and then determining whether the current bar’s momentum is rising or falling relative to the prior bar.

The label encodes both direction and slope in a compact symbol, and the background encodes the volatility state.
BackgroundDisplayed Meaning
Dark RedBollinger Bands contracted inside the widest Keltner Channel
RedBollinger Bands contracted inside the mid‑width Keltner Channel
GrayBollinger Bands contracted inside the narrowest Keltner Channel
Light GreenBollinger Bands outside all Keltner Channels

The momentum label is generated by computing an inertia value from price relative to a composite level built from the highest high, lowest low, and an exponential average. The script then compares the current inertia value to the previous bar to determine slope direction. The combination of sign and slope produces eight possible states, each mapped to a specific label code.
Label CodeDisplayed Meaning
C ▰🢅Positive momentum with rising slope, cyan label
C ▰🢆Positive momentum with falling slope, cyan label
B ▰🢅Positive momentum with rising slope, blue label
B ▰🢆Positive momentum with falling slope, blue label
Y ▰🢅Negative momentum with rising slope, yellow label
Y ▰🢆Negative momentum with falling slope, yellow label
R ▰🢅Negative momentum with rising slope, red label
R ▰🢆Negative momentum with falling slope, red label
0.0Neutral momentum with no slope advantage

The column therefore functions as a combined volatility‑compression and momentum‑direction display, with the background conveying the state of the squeeze and the label conveying the state of momentum.
 
Last edited by a moderator:

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

It does not work, please fix the code. Thank you!!
NOTE you'll have to turn on "USE SYSTEM FONTS"
in the LOOK and FEEL Options
Screenshot chekbox.png


Here is user Default code...

Code:
# Custom Watchlist Column: Squeeze + Momentum Histogram Trend

input price = close;
input length = 20;
input Num_Dev_Dn = -2.0;
input Num_Dev_up = 2.0;
input averageType = AverageType.SIMPLE;
input displace = 0;

def sDev = StDev(data = price[-displace], length = length);
def MidLineBB = MovingAverage(averageType, data = price[-displace], length = length);
def LowerBandBB = MidLineBB + Num_Dev_Dn * sDev;
def UpperBandBB = MidLineBB + Num_Dev_up * sDev;

input factorhigh = 1.0;
input factormid = 1.5;
input factorlow = 2.0;
input trueRangeAverageType = AverageType.SIMPLE;

def shifthigh = factorhigh * MovingAverage(trueRangeAverageType, TrueRange(high, close, low), length);
def shiftMid   = factormid   * MovingAverage(trueRangeAverageType, TrueRange(high, close, low), length);
def shiftlow   = factorlow   * MovingAverage(trueRangeAverageType, TrueRange(high, close, low), length);

def average = MovingAverage(averageType, price, length);
def Avg = average[-displace];

def UpperBandKCLow  = Avg + shiftlow[-displace];
def LowerBandKCLow  = Avg - shiftlow[-displace];
def UpperBandKCMid  = Avg + shiftMid[-displace];
def LowerBandKCMid  = Avg - shiftMid[-displace];
def UpperBandKCHigh = Avg + shifthigh[-displace];
def LowerBandKCHigh = Avg - shifthigh[-displace];

def K = (Highest(high, length) + Lowest(low, length)) / 2 + ExpAverage(close, length);
def momo = Inertia(price - K / 2, length);

# Squeeze definitions
def presqueeze   = LowerBandBB > LowerBandKCLow  and UpperBandBB < UpperBandKCLow;
def originalSqueeze = LowerBandBB > LowerBandKCMid and UpperBandBB < UpperBandKCMid;
def ExtrSqueeze  = LowerBandBB > LowerBandKCHigh and UpperBandBB < UpperBandKCHigh;

# Momentum states
def pos = momo >= 0;
def neg = momo < 0;
def up  = momo >= momo[1];
def dn  = momo < momo[1];

def PosUp = pos and up; #Cyan
def PosDn = pos and dn; # Blue
def NegDn = neg and dn; # Red
def NegUp = neg and up; # Yellow

def cyanup = PosUp and up[1];
def cyandn = PosUp and dn[1];
def blueup = posdn and up[1];
def bluedn = posdn and dn[1];
def redup = negdn and up[1];
def reddn = negdn and dn[1];
def yllwup = negup and up[1];
def yllwdn = negup and dn[1];




# Numeric output for watchlist sorting + display
def trendValue =
         if cyanup    then  4.0   
    else if cyandn   then  3.0
    else if blueup   then  2.0
    else if bluedn   then  1.0   # Bullish but weakening
    else if redup   then -4.0
    else if reddn   then -3.0
    else if yllwup   then -2.0   # Bearish but improving (less negative)
    else if yllwdn   then -1.0   # Strong bearish (decreasing momentum)
    else  0.0;              # Neutral / flat

# Optional: tighter visual scale if you prefer
# def trendValue =
#     if PosUp then 2 else if PosDn then 1 else if NegUp then -1 else if NegDn then -2 else 0;

# Background coloring stays exactly the same
AssignBackgroundColor(
    if ExtrSqueeze then Color.DARK_RED
    else if originalSqueeze then Color.RED
    else if presqueeze then CreateColor(128, 128, 128)
    else Color.LIGHT_GREEN
);

AddLabel(yes,
    if trendValue == 4.0 then "C ^"
else if trendValue == 3.0 then "C v"
else if trendValue == 2.0 then "B ^"
else if trendValue == 1.0 then "B v"
else if trendValue == -4.0 then "R ^"
else if trendValue == -3.0 then "R v"
else if trendValue == -2.0 then "Y ^"
else if trendValue == -1.0 then "Y v"
else "0.0",
    
    if trendValue == 4.0 then CreateColor(0, 204, 204) # cyan
else if trendValue == 3.0 then CreateColor(0, 204, 204) # cyan
else if trendValue == 2.0 then Color.BLUE
else if trendValue == 1.0 then Color.BLUE
else if trendValue == -4.0 then CreateColor(204, 0, 0) # dark red
else if trendValue == -3.0 then CreateColor(204, 0, 0) # dark red
else if trendValue == -2.0 then Color.DARK_ORANGE # or Color.YELLOW
else if trendValue == -1.0 then Color.DARK_ORANGE
else Color.GRAY
);
 
mod note:
This watchlist column is a momentum + squeeze radar that tells you, at a glance, which stocks are building energy and which direction that energy is flowing.

OK this is kind of detailed fo my Tastes but do to the popularity of the TTM Squeeze Thought some might find it handy. NOTE you'll have to turn on "USE SYSTEM FONTS"
in the LOOK and FEEL Options

SO -
BackGround colors indicate Squeeze conditon , GREEN or Gray = Not in a SQUEEZE and RED = Squeezed
The Text gets a little more detailed, they indicate the HISTOGRAM Conditons. Cyan Blue Red Yellow followed by a arrow indicating the DIRECTION of the HISTOGRAM.

View attachment 27257

Code:
# Custom Watchlist Column: Squeeze + Momentum Histogram Trend

input price = close;
input length = 20;
input Num_Dev_Dn = -2.0;
input Num_Dev_up = 2.0;
input averageType = AverageType.SIMPLE;
input displace = 0;

def sDev = StDev(data = price[-displace], length = length);
def MidLineBB = MovingAverage(averageType, data = price[-displace], length = length);
def LowerBandBB = MidLineBB + Num_Dev_Dn * sDev;
def UpperBandBB = MidLineBB + Num_Dev_up * sDev;

input factorhigh = 1.0;
input factormid = 1.5;
input factorlow = 2.0;
input trueRangeAverageType = AverageType.SIMPLE;

def shifthigh = factorhigh * MovingAverage(trueRangeAverageType, TrueRange(high, close, low), length);
def shiftMid   = factormid   * MovingAverage(trueRangeAverageType, TrueRange(high, close, low), length);
def shiftlow   = factorlow   * MovingAverage(trueRangeAverageType, TrueRange(high, close, low), length);

def average = MovingAverage(averageType, price, length);
def Avg = average[-displace];

def UpperBandKCLow  = Avg + shiftlow[-displace];
def LowerBandKCLow  = Avg - shiftlow[-displace];
def UpperBandKCMid  = Avg + shiftMid[-displace];
def LowerBandKCMid  = Avg - shiftMid[-displace];
def UpperBandKCHigh = Avg + shifthigh[-displace];
def LowerBandKCHigh = Avg - shifthigh[-displace];

def K = (Highest(high, length) + Lowest(low, length)) / 2 + ExpAverage(close, length);
def momo = Inertia(price - K / 2, length);

# Squeeze definitions
def presqueeze   = LowerBandBB > LowerBandKCLow  and UpperBandBB < UpperBandKCLow;
def originalSqueeze = LowerBandBB > LowerBandKCMid and UpperBandBB < UpperBandKCMid;
def ExtrSqueeze  = LowerBandBB > LowerBandKCHigh and UpperBandBB < UpperBandKCHigh;

# Momentum states
def pos = momo >= 0;
def neg = momo < 0;
def up  = momo >= momo[1];
def dn  = momo < momo[1];

def PosUp = pos and up; #Cyan
def PosDn = pos and dn; # Blue
def NegDn = neg and dn; # Red
def NegUp = neg and up; # Yellow

def cyanup = PosUp and up[1];
def cyandn = PosUp and dn[1];
def blueup = posdn and up[1];
def bluedn = posdn and dn[1];
def redup = negdn and up[1];
def reddn = negdn and dn[1];
def yllwup = negup and up[1];
def yllwdn = negup and dn[1];




# Numeric output for watchlist sorting + display
def trendValue =
         if cyanup    then  4.0
    else if cyandn   then  3.0
    else if blueup   then  2.0
    else if bluedn   then  1.0   # Bullish but weakening
    else if redup   then -4.0
    else if reddn   then -3.0
    else if yllwup   then -2.0   # Bearish but improving (less negative)
    else if yllwdn   then -1.0   # Strong bearish (decreasing momentum)
    else  0.0;              # Neutral / flat

# Optional: tighter visual scale if you prefer
# def trendValue =
#     if PosUp then 2 else if PosDn then 1 else if NegUp then -1 else if NegDn then -2 else 0;

# Background coloring stays exactly the same
AssignBackgroundColor(
    if ExtrSqueeze then Color.DARK_RED
    else if originalSqueeze then Color.RED
    else if presqueeze then CreateColor(128, 128, 128)
    else Color.LIGHT_GREEN
);

AddLabel(yes,
    if trendValue == 4.0 then "C ▰🢅"
else if trendValue == 3.0 then "C ▰🢆"
else if trendValue == 2.0 then "B ▰🢅"
else if trendValue == 1.0 then "B ▰🢆"
else if trendValue == -4.0 then "R ▰🢅"
else if trendValue == -3.0 then "R ▰🢆"
else if trendValue == -2.0 then "Y ▰🢅"
else if trendValue == -1.0 then "Y ▰🢆"
else "0.0",
 
    if trendValue == 4.0 then CreateColor(0, 204, 204) # cyan
else if trendValue == 3.0 then CreateColor(0, 204, 204) # cyan
else if trendValue == 2.0 then Color.BLUE
else if trendValue == 1.0 then Color.BLUE
else if trendValue == -4.0 then CreateColor(204, 0, 0) # dark red
else if trendValue == -3.0 then CreateColor(204, 0, 0) # dark red
else if trendValue == -2.0 then Color.DARK_ORANGE # or Color.YELLOW
else if trendValue == -1.0 then Color.DARK_ORANGE
else Color.GRAY
);

This watchlist column displays two elements: the squeeze background color and the momentum label.

The squeeze background is produced by comparing the Bollinger Band envelope to three Keltner Channel envelopes of increasing width.

The momentum label is produced by evaluating the inertia‑based momentum engine, determining whether momentum is positive or negative, and then determining whether the current bar’s momentum is rising or falling relative to the prior bar.

The label encodes both direction and slope in a compact symbol, and the background encodes the volatility state.
BackgroundDisplayed Meaning
Dark RedBollinger Bands contracted inside the widest Keltner Channel
RedBollinger Bands contracted inside the mid‑width Keltner Channel
GrayBollinger Bands contracted inside the narrowest Keltner Channel
Light GreenBollinger Bands outside all Keltner Channels

The momentum label is generated by computing an inertia value from price relative to a composite level built from the highest high, lowest low, and an exponential average. The script then compares the current inertia value to the previous bar to determine slope direction. The combination of sign and slope produces eight possible states, each mapped to a specific label code.
Label CodeDisplayed Meaning
C ▰🢅Positive momentum with rising slope, cyan label
C ▰🢆Positive momentum with falling slope, cyan label
B ▰🢅Positive momentum with rising slope, blue label
B ▰🢆Positive momentum with falling slope, blue label
Y ▰🢅Negative momentum with rising slope, yellow label
Y ▰🢆Negative momentum with falling slope, yellow label
R ▰🢅Negative momentum with rising slope, red label
R ▰🢆Negative momentum with falling slope, red label
0.0Neutral momentum with no slope advantage

The column therefore functions as a combined volatility‑compression and momentum‑direction display, with the background conveying the state of the squeeze and the label conveying the state of momentum.
Thanks for the detailed info . . . 8^)
 

Similar threads

Not the exact question you're looking for?

Start a new thread and receive assistance from our community.

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