Mobius' Momentum Squeeze Experiment for ThinkorSwim

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.
 

digitalml

New member
VIP
@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
VIP
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?
 

Similar threads

Top