Mobius’ Momentum Squeeze for ThinkorSwim

J007RMC

Well-known member
2019 Donor
I came across this Mobius momentum squeeze today the first time ive seen it.

https://tos.mx/8q82Rb0
Code:
# Momentum Squeeze
# Mobius
# Added Squeeze Label with directional color
# Label is green when momentum is ascending, red when descending
declare lower;
input length = 20; #hint length: Length for average calculation
input price = close;
input SDmult = 2.0;
input ATRmult = 1.5;
   def K = (Highest(High, length) + Lowest(low, length)) /
2 + ExpAverage(close, length);
plot Momo = Inertia(price - K / 2, length);
Momo.setPaintingStrategy(PaintingStrategy.HISTOGRAM);
Momo.setLineWeight(3);
Momo.assignValueColor(if Momo > Momo[1] and Momo > 0
then Color.Cyan
else if Momo > 0 and Momo < Momo[1]
then Color.Blue
else if Momo < 0 and Momo < Momo[1]
then Color.Red
else Color.Yellow);
def SD = StDev(close, length);
def Avg = Average(close, length);
def ATR = Average(TrueRange(high, close, low), length);
def SDup = Avg + (SdMult * Sd);
def ATRup = Avg + (AtrMult * ATR);
plot Squeeze = if SDup < ATRup
then 0
else Double.NaN;
Squeeze.SetPaintingStrategy(PaintingStrategy.Points);
Squeeze.SetLineWeight(3);
Squeeze.SetDefaultColor(Color.Red);
plot zero = if IsNaN(close) or !IsNaN(Squeeze) then Double.NaN else 0;
zero.SetPaintingStrategy(PaintingStrategy.Points);
zero.SetLineWeight(3);
zero.SetDefaultColor(Color.Green);
AddLabel(!isNaN(Squeeze), "Squeeze", if isAscending(Momo)
then Color.Green
else Color.Red);
# End Code - Momentum Squeeze
 

tomsk

Well-known member
VIP
I saw that in TSL several years ago According to Mobius it precisely replicates the TOS TTM_Squeeze. At default settings the output is the same as the TTM_Squeeze.
 

tomsk

Well-known member
VIP
Wow absolutely identical but the label may in some way be helpful.

That was the reason why Mobius replicated it, and you're right, it allows coders to add ore info to suit the needs.
The standard TOS TTM Squeeze has the source code locked so that Mobius study was really helpful
 

tomsk

Well-known member
VIP
Thanks tomsk very interesting.

There is a commercial study called TTM Squeeze Pro that is being claimed to generate earlier signals than the regular TTM Squeeze.
As best as I can understand it they do some computation in the KeltnerChannel values by using 3 different "factors" - high, low and mid and some some relationship tests with the BollingerBand. The details escape me but that's how I understood it
 

J007RMC

Well-known member
2019 Donor
Took this off a website same updated indicator behind John Carter's famous $1.4 Million TSLA Trade
 

J007RMC

Well-known member
2019 Donor
Squeeze Momentum Indicator [LazyBear] For the Tradingview Platform

This is a derivative of John Carter's "TTM Squeeze" volatility indicator, as discussed in his book "Mastering the Trade" (chapter 11).

Black crosses on the midline show that the market just entered a squeeze (Bollinger Bands are with in Keltner Channel). This signifies low volatility, market preparing itself for an explosive move (up or down). Gray crosses signify "Squeeze release".

Mr.Carter suggests waiting till the first gray after a black cross, and taking a position in the direction of the momentum (for ex., if momentum value is above zero, go long). Exit the position when the momentum changes (increase or decrease --- signified by a color change). My (limited) experience with this shows, an additional indicator like ADX / WaveTrend, is needed to not miss good entry points. Also, Mr.Carter uses simple momentum indicator , while I have used a different method (linreg based) to plot the histogram.

More info:
- Book: Mastering The Trade by John F Carter
 
Last edited by a moderator:

Townsend

Active member
VIP
I was glad to find the Mobius’ Momentum Squeeze Indicator, as the ThinkorSwim TTM_SQueeze indicator has the the source code locked and hidden.

John Carter's version is quite well know. The basis being Bollinger Bands dipping into a Kelter Channel. So I was surprised to see the Mobius code did not seem to use either Bollinger Bands or Keltner channels. But rather Average True Range. None the less, when the two versions, (TTM vs Mobius') are placed on the same chart they matched up identically.

Anyway, I try to avoid using too many lower window indicators, so I made some quick modifications and converted the Mobius version into a Paint Bar Indicator. The changes in direction are even more evident and the trending alert zones, (colored in gray) stand even better than the usual red dots. (See chart below.)

ml8PaDF.png


Though... one thing I can't figure out, the assignpriceColor() function at the bottom is supposed to display the up momentum bars as color.blue, but instead defaults to the system defined down bar color.

Another lesser problem: with the TOS TTM version, the input parameters are fairly clear. Bollinger deviation, Kelter deviation and the Alert Line Sensitivity. But Mobius uses only two inputs: SDmult and ATRmult. Haven't quite yet figured out how to optimized these values.

Code:
# Momentum Squeeze
# Mobius
# Added Squeeze Label with directional color
# Label is green when momentum is ascending, red when descending

input length = 20; #hint length: Length for average calculation
input price = close;
input SDmult = 2.0;
input ATRmult = 1.5;

def K = (Highest(High, length) + Lowest(low, length)) / 2 + ExpAverage(close, length);
def Momo = Inertia(price - K / 2, length);
def SD = StDev(close, length);
def Avg = Average(close, length);
def ATR = Average(TrueRange(high, close, low), length);
def SDup = Avg + (SdMult * Sd);
def ATRup = Avg + (AtrMult * ATR);

def Squeeze = if SDup < ATRup then 0 else Double.NaN;

assignpriceColor(if squeeze ==0 then color.gray else
if momo > momo[1] then color.blue else color.red
);

AddLabel(!isNaN(Squeeze), "Squeeze", if isAscending(Momo)
                                     then Color.Green
                                     else Color.Red);
 
Last edited by a moderator:

markos

Well-known member
VIP
@Townsend The SD in Mobius' script is for 2 std deviations, which is the usual for Bollys as it covers over 99% of occurrences.
The 1.5 ATR probably matches up with the Keltner Channel study numbers. To me, that makes sense.

I don't do Squeezes, to me it's a marketing ploy.
 

tomsk

Well-known member
VIP
@Townsend The SD in Mobius' script is for 2 std deviations, which is the usual for Bollys as it covers over 99% of occurrences.
The 1.5 ATR probably matches up with the Keltner Channel study numbers. To me, that makes sense.

I don't do Squeezes, to me it's a marketing ploy.

@markos Indeed - another method might be to look for expanding ATR. After all the base version of Mobius SuperTrend essentially is based on ATR, so there's got to be something there.
 

Kimberly

New member
There is a commercial study called TTM Squeeze Pro that is being claimed to generate earlier signals than the regular TTM Squeeze.
As best as I can understand it they do some computation in the KeltnerChannel values by using 3 different "factors" - high, low and mid and some some relationship tests with the BollingerBand. The details escape me but that's how I understood it

Found this comment regarding what is different with the TTM Squeeze Pro version:

https://www.tradingview.com/script/TAAt6eRX-Squeeze-PRO-Indicator-Makit0/#tc2691249
"The squeeze pro from John Carter uses 3 colors to identify the 3 different compression levels, black for 2xBB<2xKC, red for 2xBB<1.5xKC and yellow for 2xBB<1xKC (BB->bollinger bands, KC->keltner channles), I'm using orange, red and yellow since I like my charts background in black and for me those colors do the trick."
 

digitalml

New member
@Townsend - Love this indicator as I also dislike too many lower indicators, so thank you.

I was able to get the momentum paint to work with the following code. I'm not sure why your original way didn't work, as it looks correct and should have been good.

I replaced

Code:
assignpriceColor(if squeeze ==0 then color.gray else
if momo > momo[1] then color.blue else color.red
);

with

Code:
AssignPriceColor(if  momo > momo[1] then
color.blue else color.red);

AssignPriceColor(if squeeze ==0 then
color.gray else color.red);
 

Alkkkz

New member
I just found this script online. I'm not sure if it is already shared.

Trading Software: thinkorswim
Based on: TTM Squeeze (Bollinger Bands & Keltner Channels), Elliot Waves, & ParobolicSAR
Description: This study strives to emulate and optimize the TTM Squeeze study. The red squeeze indicator fires when the symbol’s Bollinger Bands are inside the symbol’s Keltner Channel. The green and red arrows are Parabolic SAR crossover indicators. The green/red waves are Wave A of the Elliot Waves, and the yellow/blue waves are Wave C of the Elliot Waves. The chart label outlines the squeeze resolution in an attempt to predict the breakout direction of the squeeze.

Optimal Long Sequence:
  1. Histogram shift from light red to dark red with values increasing toward the index line, confirming a shift from distribution to accumulation.
  2. Red Squeeze indicators firing indicating consolidation; Bollinger Band compression and volatility increase.
  3. A green up arrow indicating the Parabolic Stop and Reverse has made a bullish crossover.
Optimal Short Sequence is the reverse of the above (histogram from dark green to light green, red squeeze indicators firing, and red arrow for bearish Parabolic SAR crossover).

Code:
declare lower;

input price = CLOSE;
input ShortLength1 = 5;
input ShortLength2 = 14;
input ShortLength3 = 5;
input LongLength1 = 12;
input LongLength2 = 55;
input LongLength3 = 7;

# Momentum Oscillators

  plot MS = Average(Average(price, ShortLength1) - Average(price, ShortLength2), ShortLength3);
  plot MS2 = Average(Average(price, LongLength1) - Average(price, LongLength2), LongLength3);
# Wave A
  def MSGreens = if (MS >= 0, MS, 0);
  def MSReds = if (MS < 0, MS, 0);
# Wave C
  def MS2Blues = if (MS2 >= 0, MS2, 0);
  def MS2Yellows = if (MS2 < 0, MS2, 0);

  plot MS_Pos = MSGreens;
       MS_Pos.SetPaintingStrategy(PaintingStrategy.HISTOGRAM);
       MS_Pos.AssignValueColor(if MSGreens < MSGreens[1] then Color.GREEN else Color.DARK_GREEN);

  plot MS_Neg = MSReds;
       MS_Neg.SetPaintingStrategy(PaintingStrategy.HISTOGRAM);
       MS_Neg.AssignValueColor(if MSReds < MSReds[1] then CreateColor(255, 60, 60) else Color.DARK_RED);

  plot MS2_Pos = MS2Blues;
       MS2_Pos.SetPaintingStrategy(PaintingStrategy.HISTOGRAM);
       MS2_Pos.AssignValueColor(if MS2Blues < MS2Blues[1] then Color.BLUE else Color.CYAN);

  plot MS2_Neg = MS2Yellows;
       MS2_Neg.SetPaintingStrategy(PaintingStrategy.HISTOGRAM);
       MS2_Neg.AssignValueColor(if MS2Yellows < MS2Yellows[1] then Color.YELLOW else Color.LIGHT_RED);

# Squeeze Indicator

input length = 20;
input nK = 1.5;
input nBB = 2.0;

  def BBHalfWidth = stdev(price, length);
  def KCHalfWidth = nK * AvgTrueRange(high, close, low, length);
  plot isSqueezed = nBB * BBHalfWidth / KCHalfWidth < 1;
       isSqueezed.hide();
  plot BBS_Ind = if(isSqueezed, 0, Double.NAN);
       BBS_Ind.SetPaintingStrategy(PaintingStrategy.SQUARES);
       BBS_Ind.SetLineWeight(3);
       BBS_Ind.AssignValueColor(Color.RED);

# Bollinger Resolution

  def BBSMA = Average(price, length);
  def BBSMAL = BBSMA + (-nBB * BBHalfWidth);
  def BBSMAU = BBSMA + (nBB * BBHalfWidth);
  def PerB = roundUp((price - BBSMAL) / (BBSMAU - BBSMAL) * 100, 0);
  AddChartLabel(yes, concat("%B: ", PerB), if PerB < 0 then color.YELLOW else if PerB > 0 and PerB[1] < 0 then color.GREEN else color.WHITE);

# Parabolic SAR Signal

input accelerationFactor = 0.0275;
input accelerationLimit = 0.2;

  def SAR = ParabolicSAR(accelerationFactor = accelerationFactor, accelerationLimit = accelerationLimit);

  plot bearishCross = Crosses(SAR, price, CrossingDirection.ABOVE);
       bearishCross.hide();
  plot signalDown = if(bearishCross, 0, Double.NAN);
       signalDown.SetPaintingStrategy(PaintingStrategy.Arrow_Down);
       signalDown.SetLineWeight(3);
       signalDown.AssignValueColor(Color.DOWNTICK);

  plot bullishCross = Crosses(SAR, price, CrossingDirection.BELOW);
       bullishCross.hide();
  plot signalUp =  if(bullishCross, 0, Double.NAN);
       signalUp.SetPaintingStrategy(PaintingStrategy.Arrow_Up);
       signalUp.SetLineWeight(3);
       signalUp.AssignValueColor(Color.UPTICK);
 

je®emy

New member
I just found this script online. I'm not sure if it is already shared.

Trading Software: thinkorswim
Based on: TTM Squeeze (Bollinger Bands & Keltner Channels), Elliot Waves, & ParobolicSAR
Description: This study strives to emulate and optimize the TTM Squeeze study. The red squeeze indicator fires when the symbol’s Bollinger Bands are inside the symbol’s Keltner Channel. The green and red arrows are Parabolic SAR crossover indicators. The green/red waves are Wave A of the Elliot Waves, and the yellow/blue waves are Wave C of the Elliot Waves. The chart label outlines the squeeze resolution in an attempt to predict the breakout direction of the squeeze.

Optimal Long Sequence:
  1. Histogram shift from light red to dark red with values increasing toward the index line, confirming a shift from distribution to accumulation.
  2. Red Squeeze indicators firing indicating consolidation; Bollinger Band compression and volatility increase.
  3. A green up arrow indicating the Parabolic Stop and Reverse has made a bullish crossover.
Optimal Short Sequence is the reverse of the above (histogram from dark green to light green, red squeeze indicators firing, and red arrow for bearish Parabolic SAR crossover).

Code:
declare lower;

input price = CLOSE;
input ShortLength1 = 5;
input ShortLength2 = 14;
input ShortLength3 = 5;
input LongLength1 = 12;
input LongLength2 = 55;
input LongLength3 = 7;

# Momentum Oscillators

  plot MS = Average(Average(price, ShortLength1) - Average(price, ShortLength2), ShortLength3);
  plot MS2 = Average(Average(price, LongLength1) - Average(price, LongLength2), LongLength3);
# Wave A
  def MSGreens = if (MS >= 0, MS, 0);
  def MSReds = if (MS < 0, MS, 0);
# Wave C
  def MS2Blues = if (MS2 >= 0, MS2, 0);
  def MS2Yellows = if (MS2 < 0, MS2, 0);

  plot MS_Pos = MSGreens;
       MS_Pos.SetPaintingStrategy(PaintingStrategy.HISTOGRAM);
       MS_Pos.AssignValueColor(if MSGreens < MSGreens[1] then Color.GREEN else Color.DARK_GREEN);

  plot MS_Neg = MSReds;
       MS_Neg.SetPaintingStrategy(PaintingStrategy.HISTOGRAM);
       MS_Neg.AssignValueColor(if MSReds < MSReds[1] then CreateColor(255, 60, 60) else Color.DARK_RED);

  plot MS2_Pos = MS2Blues;
       MS2_Pos.SetPaintingStrategy(PaintingStrategy.HISTOGRAM);
       MS2_Pos.AssignValueColor(if MS2Blues < MS2Blues[1] then Color.BLUE else Color.CYAN);

  plot MS2_Neg = MS2Yellows;
       MS2_Neg.SetPaintingStrategy(PaintingStrategy.HISTOGRAM);
       MS2_Neg.AssignValueColor(if MS2Yellows < MS2Yellows[1] then Color.YELLOW else Color.LIGHT_RED);

# Squeeze Indicator

input length = 20;
input nK = 1.5;
input nBB = 2.0;

  def BBHalfWidth = stdev(price, length);
  def KCHalfWidth = nK * AvgTrueRange(high, close, low, length);
  plot isSqueezed = nBB * BBHalfWidth / KCHalfWidth < 1;
       isSqueezed.hide();
  plot BBS_Ind = if(isSqueezed, 0, Double.NAN);
       BBS_Ind.SetPaintingStrategy(PaintingStrategy.SQUARES);
       BBS_Ind.SetLineWeight(3);
       BBS_Ind.AssignValueColor(Color.RED);

# Bollinger Resolution

  def BBSMA = Average(price, length);
  def BBSMAL = BBSMA + (-nBB * BBHalfWidth);
  def BBSMAU = BBSMA + (nBB * BBHalfWidth);
  def PerB = roundUp((price - BBSMAL) / (BBSMAU - BBSMAL) * 100, 0);
  AddChartLabel(yes, concat("%B: ", PerB), if PerB < 0 then color.YELLOW else if PerB > 0 and PerB[1] < 0 then color.GREEN else color.WHITE);

# Parabolic SAR Signal

input accelerationFactor = 0.0275;
input accelerationLimit = 0.2;

  def SAR = ParabolicSAR(accelerationFactor = accelerationFactor, accelerationLimit = accelerationLimit);

  plot bearishCross = Crosses(SAR, price, CrossingDirection.ABOVE);
       bearishCross.hide();
  plot signalDown = if(bearishCross, 0, Double.NAN);
       signalDown.SetPaintingStrategy(PaintingStrategy.Arrow_Down);
       signalDown.SetLineWeight(3);
       signalDown.AssignValueColor(Color.DOWNTICK);

  plot bullishCross = Crosses(SAR, price, CrossingDirection.BELOW);
       bullishCross.hide();
  plot signalUp =  if(bullishCross, 0, Double.NAN);
       signalUp.SetPaintingStrategy(PaintingStrategy.Arrow_Up);
       signalUp.SetLineWeight(3);
       signalUp.AssignValueColor(Color.UPTICK);
Interesting script @Alkkkz. Can you share the site, were there more similar to this one?
 

MerryDay

Administrative
Staff member
Staff
VIP
Lifetime
MOBIUS MOMENTUM SQUEEZE V02 dated 4/1/2020
Ruby:
# Momentum Squeeze V02
# Mobius
# V02.04.01.2020
# New faster Momentum Oscillator with outer band markers. New more accurate Squeeze indication.

declare lower;

input n = 20;

def c = close;
def mean = Inertia(c, n);
def SD = Sqrt((fold i = 0 to n
               with s
               do s + Sqr(mean - GetValue(c, i))) / n);
plot Momo = Inertia((c - mean) / SD, Floor(n ));
     Momo.SetPaintingStrategy(PaintingStrategy.HISTOGRAM);
     Momo.assignValueColor(if Momo > Momo[1] and Momo > 0
                           then Color.Cyan
                           else if Momo > 0 and Momo < Momo[1]
                           then Color.Blue
                           else if Momo < 0 and Momo < Momo[1]
                           then Color.dark_Red
                           else Color.Yellow);
def upper = mean + (2 * SD);
def lower = mean - (2 * SD);
def W = (upper - lower) / mean;
def B = Highest(W, n * 2);
def Sq = Lowest(W, n * 2);
plot Squeeze = if ((W - Sq) / (B - Sq)) <= .01
               then 0
               else Double.NaN;
     Squeeze.SetStyle(Curve.POINTS);
     Squeeze.SetLineWeight(3);
     Squeeze.SetDefaultColor(Color.YELLOW);
AddLabel(Squeeze, "Squeeze", Color.YELLOW);
plot "0" = if !IsNaN(Squeeze) or IsNaN(c) then Double.NaN else 0;
     "0".SetStyle(Curve.Points);
     "0".SetDefaultColor(Color.GRAY);
plot "1" = if IsNaN(c) then Double.NaN else 1;
     "1".SetDefaultColor(Color.GREEN);
plot "-1" = if IsNaN(c) then Double.NaN else -1;
     "-1".SetDefaultColor(Color.dark_RED);
# End Code V02 Momentum Squeeze
@Jonas99 shared this on Discord. He provided this image with the comparison of the indicator which is the one on the very bottom.
a4.png
 

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.
Top