Repaints MTF Moxie Indicator for ThinkorSwim

Repaints
@Slippage I really appreciate you taking the time to write out the scans. The way you laid it out was easy to input into TOS. Thanks again.

No problem. I'm glad it helped.

I took a look at a few other videos today. I noticed TG primarily uses the hourly and commonly enters trades when the Moxie Indicator goes positive on the hourly. I noticed on the posted scan that the Moxie Indicator is already positive. Do you think it's beneficial to include the situations where the indicator is just below zero so that the trade can potentially be entered as it crosses above.

A few things here:

1. To find stocks that haven't quite crossed yet you can change the Moxie pieces of the scan to whatever value you want. Where it has plot scan = moxie > 0; you can change the 0 to -0.1 or -0.2 or whatever you want.

2. The scan code in my most recent post that has all the indicator code, not the trampoline scan but the other one, will find when Moxie crosses over zero -- when the arrows first appear on the chart -- if you prefer that. You can add that as another study on the scan you already built and set it for whatever timeframe you want. Like the other Moxie pieces, it needs to be set for the higher timeframe compared to the chart you're thinking about. Watkins scans based on that trigger, at least in videos he recorded two years ago.

3. Remember that Watkins only enters trades in the last hour of the day. I think that's at least partly because Moxie repaints. Moxie may trigger at 10am but by 2pm the price fell and the trigger isn't there any more. He doesn't start scanning until 2pm.

4. MOST IMPORTANT.... I found through watching his videos from varying time periods his entries matured and became more conservative over time. In his oldest Moxie Trader videos he talked about entering on the hourly trigger, as long as the other criteria are met. In later videos he talked about entering half position on the hourly trigger and the other half after a retest of support, usually the 50 SMA on the hourly chart. In his most recent videos on YouTube he doesn't enter any trade until the retest happens. That's why I figured I'd set my scan to just make sure Moxie is above zero and not really care when it got there. And it's why my scan looks for stocks that are very close to SMA 50 on the hourly chart. That way either they retested very recently or they're probably about to retest. I'm sure I'll end up adjusting my scan as I get more experience in this, especially if it's not finding the stocks he calls trades on.

It all depends on your style, though. Watkins seems to keep a large list of stocks, in Excel or something rather than as watchlists in TOS, and he checks on them at regular intervals with the frequency depending on how close to ready they look. It seems sometimes he's watching a stock for several weeks before it sets up. I'm not really interested in spending my time that way. I'd rather not see them until they're ready to trade. He does enter early sometimes in anticipation of the final pieces of the setup falling into place so there is some benefit to spending that extra time. Since I'm new to the strategy I don't want to bend/break rules yet anyway.

Again, thanks for all you continue to do. Please don't take the above as criticism - I used the scanner all day and loved it. I was just thinking of a way to ensure we don't miss a potential entry point when the Moxie Indicator goes positive on the hourly.

Don't worry, I didn't find anything negative in your post and I'm not the emotional type anyway. And it's natural different people have different criteria for what they want to look at and potentially trade.
 
Last edited:

New Indicator: Buy the Dip

Check out our Buy the Dip indicator and see how it can help you find profitable swing trading ideas. Scanner, watchlist columns, and add-ons are included.

Download the indicator

@Slippage First and foremost, thank you for all your efforts.. they are truly appreciated.

I am not a coder so please forgive the nature of the question. Is it possible to have the indicator not repaint? Is there a minor code change I can make for that? Or is this not possible given the core nature of the indicator?

Thanks
By sticking with the use of the HTF Aggregation period adjustment its not possible, HOWEVER, it is possible to change the indicator slightly so that it won't repaint and still have an analogous effect. The re-painting comes from the use of HTF AggregationPeriod in the MA's, so rather than determining the HTF AggregationPeriod to use based on the current TF that the indicator/scanner is on, you would scale the MA periods based on that TF. So if you are on a specific TF, you would determine the Period scaler to use instead of the HTF AggregationPeriod, e.g. if on TF = m15 then the scaler would be either 2 or 4 depending on H1 or H2, if on H1 it would be 8 for D1, etc. AggregationPeriod would use the chart's TF.

So def vc1 = ExpAverage(price, 12*scaler) - ExpAverage(price, 26*scaler); va1 = ExpAverage(vc1, 9*scaler);
And while doing this it would be worthwhile to make the 3 periods external parameters, since these generally are useful to play around with a bit.
 
Last edited:
Here's Moxie with no higher timeframes. The resulting line is drawn slightly differently than the real Moxie, more or less arriving at the same result in most cases but it affects the shape of the line so the signals may be different from the real Moxie and may cause confusion in the Moxie Mastery trading room if you're talking about things you see in this one. I'll probably run both until I get a feel for which I like better but I'm going to use the arrows from this version so it shows only the trigger candle.

Ruby:
declare lower;

input showVerticalLines = yes;
input showTrampolines = yes;
input showSqueezeDots = no;
input showLabel = yes;

plot ZeroLine = 0;
ZeroLine.SetDefaultColor(Color.GRAY);
ZeroLine.SetLineWeight(2);
ZeroLine.HideBubble();
ZeroLine.HideTitle();

def currentAggPeriod = GetAggregationPeriod();
def multiplier =
  if currentAggPeriod <= AggregationPeriod.TWO_MIN then AggregationPeriod.FIVE_MIN / currentAggPeriod
  else if currentAggPeriod <= AggregationPeriod.THREE_MIN then AggregationPeriod.TEN_MIN / currentAggPeriod
  else if currentAggPeriod <= AggregationPeriod.FIVE_MIN then AggregationPeriod.FIFTEEN_MIN / currentAggPeriod
  else if currentAggPeriod <= AggregationPeriod.TEN_MIN then AggregationPeriod.THIRTY_MIN / currentAggPeriod
  else if currentAggPeriod <= AggregationPeriod.FIFTEEN_MIN then AggregationPeriod.HOUR / currentAggPeriod
  else if currentAggPeriod <= AggregationPeriod.THIRTY_MIN then AggregationPeriod.TWO_HOURS / currentAggPeriod
  else if currentAggPeriod <= AggregationPeriod.HOUR then 7
  else if currentAggPeriod <= AggregationPeriod.TWO_HOURS then 3
  else if currentAggPeriod <= AggregationPeriod.FOUR_HOURS then 3 # yes, weird, but this matches better
  else if currentAggPeriod <= AggregationPeriod.DAY then 5
  else if currentAggPeriod <= AggregationPeriod.WEEK then AggregationPeriod.MONTH / currentAggPeriod
  else AggregationPeriod.QUARTER / currentAggPeriod
;

script MoxieFunc {
  input factor = 1;
  def v = ExpAverage(close, 12*factor) - ExpAverage(close, 26*factor);
  def a = ExpAverage(v, 9*factor);
  plot m = (v - a) * 3;
}

plot Moxie = MoxieFunc(multiplier);

Moxie.SetLineWeight(2);
Moxie.DefineColor("Up", Color.UPTICK);
Moxie.DefineColor("Down", Color.RED);
Moxie.AssignValueColor(
  if Moxie < Moxie[1] then Moxie.Color("Down")
  else Moxie.Color("Up")
);
Moxie.HideBubble();
Moxie.HideTitle();

# Watkins uses a different setup for Moxie on his 15 minute charts.
# He uses two lines derived from two higher timeframes.
def secondMultiplier =
  if currentAggPeriod == AggregationPeriod.FIFTEEN_MIN then 7
  else currentAggPeriod
;

plot MoxieSecondLine =
  if currentAggPeriod == AggregationPeriod.FIFTEEN_MIN
  then MoxieFunc(secondMultiplier)
  else Double.NaN
;

MoxieSecondLine.SetLineWeight(2);
MoxieSecondLine.DefineColor("Up", Color.UPTICK);
MoxieSecondLine.DefineColor("Down", Color.RED);
MoxieSecondLine.AssignValueColor(
  if MoxieSecondLine < MoxieSecondLine[1] then MoxieSecondLine.Color("Down")
  else MoxieSecondLine.Color("Up")
);
MoxieSecondLine.HideBubble();
MoxieSecondLine.HideTitle();
MoxieSecondLine.SetHiding(currentAggPeriod != AggregationPeriod.FIFTEEN_MIN);

# Show vertical lines at crossovers
AddVerticalLine(showVerticalLines and Moxie[1] crosses above 0, "", CreateColor(0,150,0), Curve.SHORT_DASH);
AddVerticalLine(showVerticalLines and Moxie[1] crosses below 0, "", CreateColor(200,0,0), Curve.SHORT_DASH);

# Indicate the Trampoline setup
def sma50 = Average(close, 50);
plot Trampoline =
  if showTrampolines and ((Moxie < -.01 and close > sma50) or (Moxie > .01 and close < sma50))
  then 0
  else Double.NaN
;
Trampoline.SetPaintingStrategy(PaintingStrategy.SQUARES);
Trampoline.DefineColor("Bullish", Color.LIGHT_GREEN);
Trampoline.DefineColor("Bearish", Color.PINK);
Trampoline.AssignValueColor(if close > sma50 then Trampoline.Color("Bearish") else Trampoline.Color("Bullish"));
Trampoline.HideBubble();
Trampoline.HideTitle();

# show squeeze dots on zero line
def bb = reference BollingerBands.LowerBand;
def squeezeLevel = 
  if bb > KeltnerChannels(factor = 1.0).Lower_Band then 3
  else if bb > KeltnerChannels(factor = 1.5).Lower_Band then 2
  else if bb > KeltnerChannels(factor = 2.0).Lower_Band then 1
  else 0
;

plot Squeeze = if !showSqueezeDots then Double.NaN else 0;
Squeeze.SetPaintingStrategy(PaintingStrategy.POINTS);
Squeeze.SetDefaultColor(Color.GRAY);
Squeeze.DefineColor("Loose Squeeze", Color.UPTICK);
Squeeze.DefineColor("Squeeze", Color.RED);
Squeeze.DefineColor("Tight Squeeze", Color.YELLOW);
Squeeze.DefineColor("No Squeeze", Color.GRAY);
Squeeze.AssignValueColor(
  if squeezeLevel == 3 then Squeeze.Color("Tight Squeeze")
  else if squeezeLevel == 2 then Squeeze.Color("Squeeze")
  else if squeezeLevel == 1 then Squeeze.Color("Loose Squeeze")
  else Squeeze.Color("No Squeeze")
);
Squeeze.HideTitle();
Squeeze.HideBubble();

AddLabel(
  showLabel,
  if currentAggPeriod == AggregationPeriod.WEEK then " W "
  else if currentAggPeriod == AggregationPeriod.DAY then " D "
  else if currentAggPeriod == AggregationPeriod.HOUR then " H "
  else if currentAggPeriod == AggregationPeriod.FIFTEEN_MIN then " 15 "
  else if currentAggPeriod == AggregationPeriod.FIVE_MIN then " 5 "
  else if currentAggPeriod == AggregationPeriod.TWO_MIN then " 2 "
  else " ",
  if Moxie < 0 then Color.RED else Color.GREEN
);

The upper study now shows only one arrow instead of a series of them. It's showing the candle that actually triggered instead of all the days that week or all the hours that day, etc. If you find it harder to notice the arrow in the chart you can modify the color and/or size to see if that helps. The arrow might still appear and disappear until the trigger candle closes but once that candle closes it won't change any more.

The upper study can now color your candles to match Moxie. Disabled by by default.

Upper study
Ruby:
declare upper;

input colorCandles = no;

def currentAggPeriod = GetAggregationPeriod();
def multiplier =
  if currentAggPeriod <= AggregationPeriod.TWO_MIN then AggregationPeriod.FIVE_MIN / currentAggPeriod
  else if currentAggPeriod <= AggregationPeriod.THREE_MIN then AggregationPeriod.TEN_MIN / currentAggPeriod
  else if currentAggPeriod <= AggregationPeriod.FIVE_MIN then AggregationPeriod.FIFTEEN_MIN / currentAggPeriod
  else if currentAggPeriod <= AggregationPeriod.TEN_MIN then AggregationPeriod.THIRTY_MIN / currentAggPeriod
  else if currentAggPeriod <= AggregationPeriod.FIFTEEN_MIN then AggregationPeriod.HOUR / currentAggPeriod
  else if currentAggPeriod <= AggregationPeriod.THIRTY_MIN then AggregationPeriod.TWO_HOURS / currentAggPeriod
  else if currentAggPeriod <= AggregationPeriod.HOUR then 7
  else if currentAggPeriod <= AggregationPeriod.TWO_HOURS then 3
  else if currentAggPeriod <= AggregationPeriod.FOUR_HOURS then 3 # yes, weird, but this matches better
  else if currentAggPeriod <= AggregationPeriod.DAY then 5
  else if currentAggPeriod <= AggregationPeriod.WEEK then AggregationPeriod.MONTH / currentAggPeriod
  else AggregationPeriod.QUARTER / currentAggPeriod
;

script MoxieFunc {
  input factor = 1;
  def v = ExpAverage(close, 12*factor) - ExpAverage(close, 26*factor);
  def a = ExpAverage(v, 9*factor);
  plot m = (v - a) * 3;
}

def Moxie = MoxieFunc(multiplier);

def longArrowPosition = if Moxie > 0 and Moxie[1] <= 0 then low else Double.NaN;
plot LongArrow = longArrowPosition;
LongArrow.SetPaintingStrategy(PaintingStrategy.ARROW_UP);
LongArrow.SetDefaultColor(Color.GREEN);
LongArrow.SetLineWeight(5);
LongArrow.HideBubble();
LongArrow.HideTitle();

def shortArrowPosition = if Moxie < 0 and Moxie[1] >= 0 then high else Double.NaN;
plot ShortArrow = shortArrowPosition;
ShortArrow.SetPaintingStrategy(PaintingStrategy.ARROW_DOWN);
ShortArrow.SetDefaultColor(Color.LIGHT_RED);
ShortArrow.SetLineWeight(5);
ShortArrow.HideBubble();
ShortArrow.HideTitle();

AssignPriceColor(if !colorCandles then Color.CURRENT else if Moxie < Moxie[1] then Color.RED else Color.UPTICK);
 
Last edited:
I was thinking... what if I trade squeezes using Moxie as the momentum indicator instead of Squeeze's momo? I browsed some charts and it seems, at first glance, to work well trading the squeeze directionally based on Moxie's color, ignoring whether it's above or below zero. So the next logical step is to merge the two. I'll be updating the latest code to plot the SqueezePro dots on Moxie's zero line. You'll be able to turn on or off the squeeze just like you can turn on or off the trampolines. Unfortunately turning them both on doesn't look great, though. Maybe I can come up with a different way to represent trampolines in the lower study. Here it is with just squeeze turned on (non-standard dot colors). This helps declutter my charts.

ctive-Trader-490509867-Main-thinkorswim-build-1967.png
 
@tradegeek IMO, I would just move on. Never buy an indicator. Find a system that works for you and keep working it. There are many hundred of them on this website to research. Start in the Tutorials as well as Look at the built in Strategies.

Code:
# Moxie_PriceChannel_Adjustable
# Built on 5/11/20
# For use on a All Time Frames

input channelLength = 34;
input averageType = AverageType.EXPONENTIAL;
input PriceChannel_Aggregation = AggregationPeriod.FIFTEEN_MIN;
input Moxie_highestAggregation = AggregationPeriod.TEN_MIN;
input Moxie_lowestAggregation = AggregationPeriod.FIVE_MIN;

def MovAvg_H = MovingAverage(averageType, high, channelLength);
def MovAvg_C = MovingAverage(averageType, close, channelLength);
def MovAvg_L = MovingAverage(averageType, low, channelLength);

def MovAvg_H1x = (MovAvg_H - MovAvg_L) + MovAvg_H;
def MovAvg_L1x = MovAvg_L - (MovAvg_H - MovAvg_L);

# HTF_Ergodic Momentum ----------------------------------------------
def diff = close(period=PriceChannel_Aggregation) - close(period=PriceChannel_Aggregation)[1];
def TSI  = (ExpAverage(ExpAverage(diff, 32), 5)) / (ExpAverage(ExpAverage(AbsValue(diff), 32), 5)) * 100;
def Signal = ExpAverage(TSI, 5);
def Momentum = TSI - Signal;
def LHMult = If (.01 <> 0, (1 / 0.01), 0);
def TSVBlues = If (Momentum >= 0, Momentum, 0);
def TSVMomentum_Pos = TSVBlues * LHMult;
def TSVReds = If (Momentum < 0, Momentum, 0);
def TSVMomentum_Neg = TSVReds * LHMult;

# HTF ERGODIC Price Channel Momentum Indicator ----------------------------------------
plot PC_H = MovAvg_H;
plot PC_L = MovAvg_L;

PC_H.DefineColor("SlopeUp", CreateColor(0, 153, 0)); #createColor(0,153,0)); GREEN
PC_H.DefineColor("NoSlope", Color.GRAY);
PC_H.DefineColor("SlopeDown", Color.RED);
PC_H.AssignValueColor(if TSVmomentum_Pos then PC_H.Color("SlopeUp") else if TSVmomentum_Neg then PC_L.Color("SlopeDown") else PC_H.Color("NoSlope"));
PC_H.SetLineWeight(2);
PC_H.HideBubble();

PC_L.DefineColor("SlopeUp", CreateColor(0, 153, 0));#createColor(0,153,0)); GREEN
PC_L.DefineColor("NoSlope", Color.GRAY);
PC_L.DefineColor("SlopeDown", Color.RED);
PC_L.AssignValueColor(if TSVmomentum_Pos then PC_L.Color("SlopeUp") else if TSVmomentum_Neg then PC_L.Color("SlopeDown") else PC_L.Color("NoSlope"));
PC_L.SetLineWeight(2);
PC_L.HideBubble();

# MOXIE - This section is for the medium term MACD ---------------------------------------------
def midTermFastAvg = ExpAverage(close(period = Moxie_lowestAggregation), 12);
def midTermSlowAvg = ExpAverage(close(period = Moxie_lowestAggregation), 26);
def midTermValue = midTermFastAvg - midTermSlowAvg;
def midTermAvg = ExpAverage(midTermValue, 9);
def midTermDiff = (midTermValue - midTermAvg)*3;

# MOXIE - This section is for the long term MACD -----------------------------------------------
def longTermFastAvg = ExpAverage(close(period = Moxie_highestAggregation), 12);
def longTermSlowAvg = ExpAverage(close(period = Moxie_highestAggregation) , 26);
def longTermValue = longTermFastAvg - longTermSlowAvg;
def longTermAvg = ExpAverage(longTermValue, 9);
def longTermDiff = (longTermValue - longTermAvg)*3;

# Signal Criteria -----------------------------------------------------------------------
def midTermLower = midTermDiff < 0 and midTermDiff < midTermDiff[1];
def midTermHigher = midTermDiff > 0 and midTermDiff > midTermDiff[1];

def longTermLower = longTermDiff < 0 and longTermDiff < longTermDiff[1];
def longTermHigher = longTermDiff > 0 and longTermDiff > longTermDiff[1];

#########################################################################
plot BuySignal = if midTermHigher and LongTermHigher then MovAvg_L1x else Double.NaN;
BuySignal.SetDefaultColor (Color.White); #(CreateColor(0, 153, 0));
BuySignal.SetPaintingStrategy(PaintingStrategy.POINTS);
BuySignal.SetLineWeight(2);
BuySignal.HideBubble();
BuySignal.HideTitle();

plot SellSignal = if midTermLower and LongTermLower then MovAvg_H1x else Double.NaN;
SellSignal.SetDefaultColor(Color.White);
SellSignal.SetPaintingStrategy(PaintingStrategy.POINTS);
SellSignal.SetLineWeight(2);
SellSignal.HideBubble();
SellSignal.HideTitle();

# Cloud Fill -----------------------------
AddCloud(MovAvg_H, MovAvg_L, Color.LIGHT_GRAY);

alert (close>BuySignal,"ChannelDotup", alert.bar,Sound.ding);
alert (close<SellSignal,"ChannelDotdown", alert.bar,Sound.ding);

#alert (close>BuySignal,"ChannelDotup", alert.once,Sound.ding);
#alert (close<SellSignal,"ChannelDotdown", alert.once,Sound.ding);
MUCHO THANKS, I'M USING THE MOXIE CHANNEL ALONG WITH THE MOXIE LOWER.
 
heres a fun way to look at things, if you push the moxie forward and backwards you can create the same effect that an ichimoku might produce when theres a cross over the cloud and the setpack of price, i tried different settings and so far 34 has been the best.

Code:
declare lower;

input showVerticalLines = yes;
input showTrampolines = yes;
input showSqueezeDots = no;
input showLabel = yes;

plot ZeroLine = 0;
ZeroLine.SetDefaultColor(Color.GRAY);
ZeroLine.SetLineWeight(2);
ZeroLine.HideBubble();
ZeroLine.HideTitle();

def currentAggPeriod = GetAggregationPeriod();
def multiplier =
  if currentAggPeriod <= AggregationPeriod.TWO_MIN then AggregationPeriod.FIVE_MIN / currentAggPeriod
  else if currentAggPeriod <= AggregationPeriod.THREE_MIN then AggregationPeriod.TEN_MIN / currentAggPeriod
  else if currentAggPeriod <= AggregationPeriod.FIVE_MIN then AggregationPeriod.FIFTEEN_MIN / currentAggPeriod
  else if currentAggPeriod <= AggregationPeriod.TEN_MIN then AggregationPeriod.THIRTY_MIN / currentAggPeriod
  else if currentAggPeriod <= AggregationPeriod.FIFTEEN_MIN then AggregationPeriod.HOUR / currentAggPeriod
  else if currentAggPeriod <= AggregationPeriod.THIRTY_MIN then AggregationPeriod.TWO_HOURS / currentAggPeriod
  else if currentAggPeriod <= AggregationPeriod.HOUR then 7
  else if currentAggPeriod <= AggregationPeriod.TWO_HOURS then 3
  else if currentAggPeriod <= AggregationPeriod.FOUR_HOURS then 3 # yes, weird, but this matches better
  else if currentAggPeriod <= AggregationPeriod.DAY then 5
  else if currentAggPeriod <= AggregationPeriod.WEEK then AggregationPeriod.MONTH / currentAggPeriod
  else AggregationPeriod.QUARTER / currentAggPeriod
;

script MoxieFunc {
  input factor = 1;
  def v = ExpAverage(close, 12*factor) - ExpAverage(close, 26*factor);
  def a = ExpAverage(v, 9*factor);
  plot m = (v - a) * 3;
}

plot Moxie = MoxieFunc(multiplier)[34];
plot Moxie2 = MoxieFunc(multiplier)[-34];
Moxie.SetLineWeight(2);
Moxie.DefineColor("Up", Color.UPTICK);
Moxie.DefineColor("Down", Color.RED);
Moxie.AssignValueColor(
  if Moxie < Moxie[1] then Moxie.Color("Down")
  else Moxie.Color("Up")
);
Moxie.HideBubble();
Moxie.HideTitle();

# Watkins uses a different setup for Moxie on his 15 minute charts.
# He uses two lines derived from two higher timeframes.
def secondMultiplier =
  if currentAggPeriod == AggregationPeriod.FIFTEEN_MIN then 7
  else currentAggPeriod
;

plot MoxieSecondLine =
  if currentAggPeriod == AggregationPeriod.FIFTEEN_MIN
  then MoxieFunc(secondMultiplier)
  else Double.NaN
;

MoxieSecondLine.SetLineWeight(2);
MoxieSecondLine.DefineColor("Up", Color.UPTICK);
MoxieSecondLine.DefineColor("Down", Color.RED);
MoxieSecondLine.AssignValueColor(
  if MoxieSecondLine < MoxieSecondLine[1] then MoxieSecondLine.Color("Down")
  else MoxieSecondLine.Color("Up")
);
MoxieSecondLine.HideBubble();
MoxieSecondLine.HideTitle();
MoxieSecondLine.SetHiding(currentAggPeriod != AggregationPeriod.FIFTEEN_MIN);

# Show vertical lines at crossovers
AddVerticalLine(showVerticalLines and Moxie[1] crosses above 0, "", CreateColor(0,150,0), Curve.SHORT_DASH);
AddVerticalLine(showVerticalLines and Moxie[1] crosses below 0, "", CreateColor(200,0,0), Curve.SHORT_DASH);

# Indicate the Trampoline setup
def sma50 = Average(close, 50);
plot Trampoline =
  if showTrampolines and ((Moxie < -.01 and close > sma50) or (Moxie > .01 and close < sma50))
  then 0
  else Double.NaN
;
Trampoline.SetPaintingStrategy(PaintingStrategy.SQUARES);
Trampoline.DefineColor("Bullish", Color.LIGHT_GREEN);
Trampoline.DefineColor("Bearish", Color.PINK);
Trampoline.AssignValueColor(if close > sma50 then Trampoline.Color("Bearish") else Trampoline.Color("Bullish"));
Trampoline.HideBubble();
Trampoline.HideTitle();

# show squeeze dots on zero line
def squeezeLevel =
  if TTM_Squeeze(nK=1.0).SqueezeAlert == 0 then 3
  else if TTM_Squeeze(nK=1.5).SqueezeAlert == 0 then 2
  else if TTM_Squeeze(nK=2.0).SqueezeAlert == 0 then 1
  else 0
;

plot Squeeze = if !showSqueezeDots then Double.NaN else 0;
Squeeze.SetPaintingStrategy(PaintingStrategy.POINTS);
Squeeze.SetDefaultColor(Color.GRAY);
Squeeze.DefineColor("Loose Squeeze", Color.UPTICK);
Squeeze.DefineColor("Squeeze", Color.RED);
Squeeze.DefineColor("Tight Squeeze", Color.YELLOW);
Squeeze.DefineColor("No Squeeze", Color.GRAY);
Squeeze.AssignValueColor(
  if squeezeLevel == 3 then Squeeze.Color("Tight Squeeze")
  else if squeezeLevel == 2 then Squeeze.Color("Squeeze")
  else if squeezeLevel == 1 then Squeeze.Color("Loose Squeeze")
  else Squeeze.Color("No Squeeze")
);
Squeeze.HideTitle();
Squeeze.HideBubble();

AddLabel(
  showLabel,
  if currentAggPeriod == AggregationPeriod.WEEK then " W "
  else if currentAggPeriod == AggregationPeriod.DAY then " D "
  else if currentAggPeriod == AggregationPeriod.HOUR then " H "
  else if currentAggPeriod == AggregationPeriod.FIFTEEN_MIN then " 15 "
  else if currentAggPeriod == AggregationPeriod.FIVE_MIN then " 5 "
  else if currentAggPeriod == AggregationPeriod.TWO_MIN then " 2 "
  else " ",
  if Moxie < 0 then Color.RED else Color.GREEN
);

AddLabel(
  yes,
  if currentAggPeriod == AggregationPeriod.WEEK then " W "
  else if currentAggPeriod == AggregationPeriod.Day then " D "
  else if currentAggPeriod == AggregationPeriod.HOUR then " H "
  else if currentAggPeriod == AggregationPeriod.FIFTEEN_MIN then " 15 "
  else if currentAggPeriod == AggregationPeriod.FIVE_MIN then " 5 "
  else if currentAggPeriod == AggregationPeriod.TWO_MIN then " 2 "
  else " ",
  if Moxie < 0 then Color.RED else Color.GREEN
);
 
Is someone able to create a Moxie Upper with arrows that correlate with the squeeze types?? I was looking through the thread and don't know if this has been done yet. I think color-coordinated arrows would be best served for this purpose, rather than a down arrow be standard Red and an up arrow be standard Green. The squeeze helped me stay out of some potentially nasty whipsaws and chop today around 11:30-12:00 EST on the ES and I'd like to do whatever possible to highlight those potentially dangerous trades.
 
Is someone able to create a Moxie Upper with arrows that correlate with the squeeze types?? I was looking through the thread and don't know if this has been done yet. I think color-coordinated arrows would be best served for this purpose, rather than a down arrow be standard Red and an up arrow be standard Green. The squeeze helped me stay out of some potentially nasty whipsaws and chop today around 11:30-12:00 EST on the ES and I'd like to do whatever possible to highlight those potentially dangerous trades.

Arrows are directional and would be misleading but you can use my SqueezePro Clouds, inspired by whoever posted the MTF Squeeze Clouds on this site a while ago. I overlapped two of each cloud to make them less transparent. If you want them less bold you can delete the extra two AddCloud() statements for each squeeze type.

Ruby:
def bbu = reference BollingerBands().UpperBand;
def bbl = BollingerBands().LowerBand;

def kc1u = KeltnerChannels(factor = 1.0).Upper_Band;
def kc1l = KeltnerChannels(factor = 1.0).Lower_Band;

def kc2u = KeltnerChannels(factor = 1.5).Upper_Band;
def kc2l = KeltnerChannels(factor = 1.5).Lower_Band;

def kc3u = KeltnerChannels(factor = 2.0).Upper_Band;
def kc3l = KeltnerChannels(factor = 2.0).Lower_Band;

# loose squeeze
def cloudBUSqz3 = if bbu < kc3u then bbu else Double.NaN;
def cloudKC2USqz3 = if bbu < kc3u then kc3u else Double.NaN;
def cloudBLSqz3 = if bbl > kc3l then bbl else Double.NaN;
def cloudKC2LSqz3 = if bbl > kc3l then kc3l else Double.NaN;

AddCloud(cloudBUSqz3, cloudKC2USqz3, Color.DARK_GREEN, Color.DARK_GREEN);
AddCloud(cloudBLSqz3, cloudKC2LSqz3, Color.DARK_GREEN, Color.DARK_GREEN);

AddCloud(cloudBUSqz3, cloudKC2USqz3, Color.DARK_GREEN, Color.DARK_GREEN);
AddCloud(cloudBLSqz3, cloudKC2LSqz3, Color.DARK_GREEN, Color.DARK_GREEN);

# normal squeeze
def cloudBUSqz2 = if bbu < kc2u then bbu else Double.NaN;
def cloudKC2USqz2 = if bbu < kc2u then kc2u else Double.NaN;
def cloudBLSqz2 = if bbl > kc2l then bbl else Double.NaN;
def cloudKC2LSqz2 = if bbl > kc2l then kc2l else Double.NaN;

AddCloud(cloudBUSqz2, cloudKC2USqz2, Color.RED, Color.RED);
AddCloud(cloudBLSqz2, cloudKC2LSqz2, Color.RED, Color.RED);

AddCloud(cloudBUSqz2, cloudKC2USqz2, Color.RED, Color.RED);
AddCloud(cloudBLSqz2, cloudKC2LSqz2, Color.RED, Color.RED);

# tightest squeeze
def cloudBUSqz1 = if bbu < kc1u then bbu else Double.NaN;
def cloudKC2USqz1 = if bbu < kc1u then kc1u else Double.NaN;
def cloudBLSqz1 = if bbl > kc1l then bbl else Double.NaN;
def cloudKC2LSqz1 = if bbl > kc1l then kc1l else Double.NaN;

AddCloud(cloudBUSqz1, cloudKC2USqz1, Color.YELLOW, Color.YELLOW);
AddCloud(cloudBLSqz1, cloudKC2LSqz1, Color.YELLOW, Color.YELLOW);

AddCloud(cloudBUSqz1, cloudKC2USqz1, Color.YELLOW, Color.YELLOW);
AddCloud(cloudBLSqz1, cloudKC2LSqz1, Color.YELLOW, Color.YELLOW);
 
Arrows are directional and would be misleading but you can use my SqueezePro Clouds, inspired by whoever posted the MTF Squeeze Clouds on this site a while ago. I overlapped two of each cloud to make them less transparent. If you want them less bold you can delete the extra two AddCloud() statements for each squeeze type.

Ruby:
def bbu = reference BollingerBands().UpperBand;
def bbl = BollingerBands().LowerBand;

def kc1u = KeltnerChannels(factor = 1.0).Upper_Band;
def kc1l = KeltnerChannels(factor = 1.0).Lower_Band;

def kc2u = KeltnerChannels(factor = 1.5).Upper_Band;
def kc2l = KeltnerChannels(factor = 1.5).Lower_Band;

def kc3u = KeltnerChannels(factor = 2.0).Upper_Band;
def kc3l = KeltnerChannels(factor = 2.0).Lower_Band;

# loose squeeze
def cloudBUSqz3 = if bbu < kc3u then bbu else Double.NaN;
def cloudKC2USqz3 = if bbu < kc3u then kc3u else Double.NaN;
def cloudBLSqz3 = if bbl > kc3l then bbl else Double.NaN;
def cloudKC2LSqz3 = if bbl > kc3l then kc3l else Double.NaN;

AddCloud(cloudBUSqz3, cloudKC2USqz3, Color.DARK_GREEN, Color.DARK_GREEN);
AddCloud(cloudBLSqz3, cloudKC2LSqz3, Color.DARK_GREEN, Color.DARK_GREEN);

AddCloud(cloudBUSqz3, cloudKC2USqz3, Color.DARK_GREEN, Color.DARK_GREEN);
AddCloud(cloudBLSqz3, cloudKC2LSqz3, Color.DARK_GREEN, Color.DARK_GREEN);

# normal squeeze
def cloudBUSqz2 = if bbu < kc2u then bbu else Double.NaN;
def cloudKC2USqz2 = if bbu < kc2u then kc2u else Double.NaN;
def cloudBLSqz2 = if bbl > kc2l then bbl else Double.NaN;
def cloudKC2LSqz2 = if bbl > kc2l then kc2l else Double.NaN;

AddCloud(cloudBUSqz2, cloudKC2USqz2, Color.RED, Color.RED);
AddCloud(cloudBLSqz2, cloudKC2LSqz2, Color.RED, Color.RED);

AddCloud(cloudBUSqz2, cloudKC2USqz2, Color.RED, Color.RED);
AddCloud(cloudBLSqz2, cloudKC2LSqz2, Color.RED, Color.RED);

# tightest squeeze
def cloudBUSqz1 = if bbu < kc1u then bbu else Double.NaN;
def cloudKC2USqz1 = if bbu < kc1u then kc1u else Double.NaN;
def cloudBLSqz1 = if bbl > kc1l then bbl else Double.NaN;
def cloudKC2LSqz1 = if bbl > kc1l then kc1l else Double.NaN;

AddCloud(cloudBUSqz1, cloudKC2USqz1, Color.YELLOW, Color.YELLOW);
AddCloud(cloudBLSqz1, cloudKC2LSqz1, Color.YELLOW, Color.YELLOW);

AddCloud(cloudBUSqz1, cloudKC2USqz1, Color.YELLOW, Color.YELLOW);
AddCloud(cloudBLSqz1, cloudKC2LSqz1, Color.YELLOW, Color.YELLOW);
@Slippage Thanks! I believe that will do just fine.
 
Here's Moxie with no higher timeframes. The resulting line is drawn slightly differently than the real Moxie, more or less arriving at the same result in most cases but it affects the shape of the line so the signals may be different from the real Moxie and may cause confusion in the Moxie Mastery trading room if you're talking about things you see in this one. I'll probably run both until I get a feel for which I like better but I'm going to use the arrows from this version so it shows only the trigger candle.

Ruby:
declare lower;

input showVerticalLines = yes;
input showTrampolines = yes;
input showSqueezeDots = no;
input showLabel = yes;

plot ZeroLine = 0;
ZeroLine.SetDefaultColor(Color.GRAY);
ZeroLine.SetLineWeight(2);
ZeroLine.HideBubble();
ZeroLine.HideTitle();

def currentAggPeriod = GetAggregationPeriod();
def multiplier =
  if currentAggPeriod <= AggregationPeriod.TWO_MIN then AggregationPeriod.FIVE_MIN / currentAggPeriod
  else if currentAggPeriod <= AggregationPeriod.THREE_MIN then AggregationPeriod.TEN_MIN / currentAggPeriod
  else if currentAggPeriod <= AggregationPeriod.FIVE_MIN then AggregationPeriod.FIFTEEN_MIN / currentAggPeriod
  else if currentAggPeriod <= AggregationPeriod.TEN_MIN then AggregationPeriod.THIRTY_MIN / currentAggPeriod
  else if currentAggPeriod <= AggregationPeriod.FIFTEEN_MIN then AggregationPeriod.HOUR / currentAggPeriod
  else if currentAggPeriod <= AggregationPeriod.THIRTY_MIN then AggregationPeriod.TWO_HOURS / currentAggPeriod
  else if currentAggPeriod <= AggregationPeriod.HOUR then 7
  else if currentAggPeriod <= AggregationPeriod.TWO_HOURS then 3
  else if currentAggPeriod <= AggregationPeriod.FOUR_HOURS then 3 # yes, weird, but this matches better
  else if currentAggPeriod <= AggregationPeriod.DAY then 5
  else if currentAggPeriod <= AggregationPeriod.WEEK then AggregationPeriod.MONTH / currentAggPeriod
  else AggregationPeriod.QUARTER / currentAggPeriod
;

script MoxieFunc {
  input factor = 1;
  def v = ExpAverage(close, 12*factor) - ExpAverage(close, 26*factor);
  def a = ExpAverage(v, 9*factor);
  plot m = (v - a) * 3;
}

plot Moxie = MoxieFunc(multiplier);

Moxie.SetLineWeight(2);
Moxie.DefineColor("Up", Color.UPTICK);
Moxie.DefineColor("Down", Color.RED);
Moxie.AssignValueColor(
  if Moxie < Moxie[1] then Moxie.Color("Down")
  else Moxie.Color("Up")
);
Moxie.HideBubble();
Moxie.HideTitle();

# Watkins uses a different setup for Moxie on his 15 minute charts.
# He uses two lines derived from two higher timeframes.
def secondMultiplier =
  if currentAggPeriod == AggregationPeriod.FIFTEEN_MIN then 7
  else currentAggPeriod
;

plot MoxieSecondLine =
  if currentAggPeriod == AggregationPeriod.FIFTEEN_MIN
  then MoxieFunc(secondMultiplier)
  else Double.NaN
;

MoxieSecondLine.SetLineWeight(2);
MoxieSecondLine.DefineColor("Up", Color.UPTICK);
MoxieSecondLine.DefineColor("Down", Color.RED);
MoxieSecondLine.AssignValueColor(
  if MoxieSecondLine < MoxieSecondLine[1] then MoxieSecondLine.Color("Down")
  else MoxieSecondLine.Color("Up")
);
MoxieSecondLine.HideBubble();
MoxieSecondLine.HideTitle();
MoxieSecondLine.SetHiding(currentAggPeriod != AggregationPeriod.FIFTEEN_MIN);

# Show vertical lines at crossovers
AddVerticalLine(showVerticalLines and Moxie[1] crosses above 0, "", CreateColor(0,150,0), Curve.SHORT_DASH);
AddVerticalLine(showVerticalLines and Moxie[1] crosses below 0, "", CreateColor(200,0,0), Curve.SHORT_DASH);

# Indicate the Trampoline setup
def sma50 = Average(close, 50);
plot Trampoline =
  if showTrampolines and ((Moxie < -.01 and close > sma50) or (Moxie > .01 and close < sma50))
  then 0
  else Double.NaN
;
Trampoline.SetPaintingStrategy(PaintingStrategy.SQUARES);
Trampoline.DefineColor("Bullish", Color.LIGHT_GREEN);
Trampoline.DefineColor("Bearish", Color.PINK);
Trampoline.AssignValueColor(if close > sma50 then Trampoline.Color("Bearish") else Trampoline.Color("Bullish"));
Trampoline.HideBubble();
Trampoline.HideTitle();

# show squeeze dots on zero line
def bb = reference BollingerBands.LowerBand;
def squeezeLevel =
  if bb > KeltnerChannels(factor = 1.0).Lower_Band then 3
  else if bb > KeltnerChannels(factor = 1.5).Lower_Band then 2
  else if bb > KeltnerChannels(factor = 2.0).Lower_Band then 1
  else 0
;

plot Squeeze = if !showSqueezeDots then Double.NaN else 0;
Squeeze.SetPaintingStrategy(PaintingStrategy.POINTS);
Squeeze.SetDefaultColor(Color.GRAY);
Squeeze.DefineColor("Loose Squeeze", Color.UPTICK);
Squeeze.DefineColor("Squeeze", Color.RED);
Squeeze.DefineColor("Tight Squeeze", Color.YELLOW);
Squeeze.DefineColor("No Squeeze", Color.GRAY);
Squeeze.AssignValueColor(
  if squeezeLevel == 3 then Squeeze.Color("Tight Squeeze")
  else if squeezeLevel == 2 then Squeeze.Color("Squeeze")
  else if squeezeLevel == 1 then Squeeze.Color("Loose Squeeze")
  else Squeeze.Color("No Squeeze")
);
Squeeze.HideTitle();
Squeeze.HideBubble();

AddLabel(
  showLabel,
  if currentAggPeriod == AggregationPeriod.WEEK then " W "
  else if currentAggPeriod == AggregationPeriod.DAY then " D "
  else if currentAggPeriod == AggregationPeriod.HOUR then " H "
  else if currentAggPeriod == AggregationPeriod.FIFTEEN_MIN then " 15 "
  else if currentAggPeriod == AggregationPeriod.FIVE_MIN then " 5 "
  else if currentAggPeriod == AggregationPeriod.TWO_MIN then " 2 "
  else " ",
  if Moxie < 0 then Color.RED else Color.GREEN
);

The upper study now shows only one arrow instead of a series of them. It's showing the candle that actually triggered instead of all the days that week or all the hours that day, etc. If you find it harder to notice the arrow in the chart you can modify the color and/or size to see if that helps. The arrow might still appear and disappear until the trigger candle closes but once that candle closes it won't change any more.

The upper study can now color your candles to match Moxie. Disabled by by default.

Upper study
Ruby:
declare upper;

input colorCandles = no;

def currentAggPeriod = GetAggregationPeriod();
def multiplier =
  if currentAggPeriod <= AggregationPeriod.TWO_MIN then AggregationPeriod.FIVE_MIN / currentAggPeriod
  else if currentAggPeriod <= AggregationPeriod.THREE_MIN then AggregationPeriod.TEN_MIN / currentAggPeriod
  else if currentAggPeriod <= AggregationPeriod.FIVE_MIN then AggregationPeriod.FIFTEEN_MIN / currentAggPeriod
  else if currentAggPeriod <= AggregationPeriod.TEN_MIN then AggregationPeriod.THIRTY_MIN / currentAggPeriod
  else if currentAggPeriod <= AggregationPeriod.FIFTEEN_MIN then AggregationPeriod.HOUR / currentAggPeriod
  else if currentAggPeriod <= AggregationPeriod.THIRTY_MIN then AggregationPeriod.TWO_HOURS / currentAggPeriod
  else if currentAggPeriod <= AggregationPeriod.HOUR then 7
  else if currentAggPeriod <= AggregationPeriod.TWO_HOURS then 3
  else if currentAggPeriod <= AggregationPeriod.FOUR_HOURS then 3 # yes, weird, but this matches better
  else if currentAggPeriod <= AggregationPeriod.DAY then 5
  else if currentAggPeriod <= AggregationPeriod.WEEK then AggregationPeriod.MONTH / currentAggPeriod
  else AggregationPeriod.QUARTER / currentAggPeriod
;

script MoxieFunc {
  input factor = 1;
  def v = ExpAverage(close, 12*factor) - ExpAverage(close, 26*factor);
  def a = ExpAverage(v, 9*factor);
  plot m = (v - a) * 3;
}

def Moxie = MoxieFunc(multiplier);

def longArrowPosition = if Moxie > 0 and Moxie[1] <= 0 then low else Double.NaN;
plot LongArrow = longArrowPosition;
LongArrow.SetPaintingStrategy(PaintingStrategy.ARROW_UP);
LongArrow.SetDefaultColor(Color.GREEN);
LongArrow.SetLineWeight(5);
LongArrow.HideBubble();
LongArrow.HideTitle();

def shortArrowPosition = if Moxie < 0 and Moxie[1] >= 0 then high else Double.NaN;
plot ShortArrow = shortArrowPosition;
ShortArrow.SetPaintingStrategy(PaintingStrategy.ARROW_DOWN);
ShortArrow.SetDefaultColor(Color.LIGHT_RED);
ShortArrow.SetLineWeight(5);
ShortArrow.HideBubble();
ShortArrow.HideTitle();

AssignPriceColor(if !colorCandles then Color.CURRENT else if Moxie < Moxie[1] then Color.RED else Color.UPTICK);
@Slippage I find the smooth moxie lower to lag in changing its direction vs your other version
 
I find the smooth moxie lower to lag in changing its direction vs your other version

There's a couple of reasons that may happen...

The real Moxie, with the stair steps, rewrites history. It's using data from a higher timeframe. On a daily chart, it's looking at weekly. Each horizontal step is a week (5 days). If a stock spikes up on Friday, the whole step moves up and it looks like it happened Monday. It didn't. It's playing tricks on you. If a stock does nothing for 4 days and then spikes up on the 5th day, that higher closing price affects the whole week. And, for instance, in one of the calculations it's used in a 12 period average. That will become relevant in the next paragraph.

The smooth version, instead of using the higher timeframe, increases the number of periods it calculates averages on. Instead of 12 weeks it averages 60 days. If a stock does nothing for 4 days and then spikes up on the 5th day, that higher closing price affects only the current day. And, for instance, in one of the calculations it's used in a 60 period average (12 times 5 days in a week). Being 1 day out of 60 instead of 1 week out of 12, it has smaller impact on the average than in the weekly calculation.

The smooth one is experimental. It exists. You can use it if you want. I don't make any recommendation for or against it. I have both versions on my daily and hourly charts so I can compare and see which seems more accurate/useful. With the vertical lines on crossovers enabled, the results are very close and often the same. Without the crossover line, which I put at the end of the stair step period, the real Moxie tricks you into thinking it saw the move before it happened.
 
Last edited:
What is the indicator with stops and targets in your image? Is it auto fibonacci? Could you share where we could get that? Thanks so much!
Public Domain:

Code:
#This script will calculate and plot the stop loss and first profit target when the stock breaks out above the previous day's high or opening range high (whichever is higher) or vice versa to the low-side. This may be used with a 2 min chart as he described in his original post for a more aggressive entry point, or, as he recommended to me, on a 5 min chart for a more conservative entry point.

#Robert Payne   06/17/2014
#Public Domain


#This script will calculate and plot the stop loss and first profit target when the stock breaks out above the previous day's high or opening range high (whichever is higher) or vice versa to the low-side. This may be used with a 2 min chart as he described in his original post for a more aggressive entry point, or, as he recommended to me, on a 5 min chart for a more conservative entry point.

#---------------------------------------------------------------------------------------------


script OpenRange {
    input ORtime = 5;

    def FirstBar = GetDay() != GetDay()[1];
    def RangeTime = SecondsFromTime(0930) >= 0 and SecondsFromTime(0930) < 60 * ORtime;
    def Rhigh = if FirstBar then high else if RangeTime and high > Rhigh[1] then high else Rhigh[1];
    def Rlow = if FirstBar then low else if RangeTime and low < Rlow[1] then low else Rlow[1];

    plot h = if RangeTime then Double.NaN else Rhigh;
    plot l = if RangeTime then Double.NaN else Rlow;
}

def first30 = SecondsFromTime(0930) >= 0 and SecondsTillTime(1000) >= 0;
def today = GetLastDay() == GetDay();
def ATR = Average(TrueRange(high,  close,  low),  10);

plot yHigh = if !today then Double.NaN else high(period = "day" )[1];
yHigh.SetDefaultColor(Color.CYAN);
plot yLow = if !today then Double.NaN else low(period = "day" )[1];
yLow.SetDefaultColor(Color.PINK);

plot h5 = if !today then Double.NaN else if !first30 then Double.NaN else OpenRange(5).h;
h5.SetDefaultColor(Color.YELLOW);
plot l5 = if !today then Double.NaN else if !first30 then Double.NaN else OpenRange(5).l;
l5.SetDefaultColor(Color.YELLOW);
plot h30 = if !today then Double.NaN else OpenRange(30).h;
h30.SetDefaultColor(Color.YELLOW);
plot l30 = if !today then Double.NaN else OpenRange(30).l;
l30.SetDefaultColor(Color.YELLOW);

def lowConf = if first30 then Min(yLow, l5) - ATR else Min(yLow, l30) - ATR;
def highConf = if first30 then Max(yHigh, h5) + ATR else Max(yHigh, h30) + ATR;

plot lc1 = if first30 then lowConf else Double.NaN;
lc1.SetDefaultColor(Color.ORANGE);
plot lc2 = if !first30 then lowConf else Double.NaN;
lc2.SetDefaultColor(Color.ORANGE);
plot hc1 = if first30 then highConf else Double.NaN;
hc1.SetDefaultColor(Color.ORANGE);
plot hc2 = if !first30 then highConf else Double.NaN;
hc2.SetDefaultColor(Color.ORANGE);

def decisionL = if close > lowConf then Double.NaN else if close crosses below lowConf then low else decisionL[1];
def decisionH = if close < highConf then Double.NaN else if close crosses above highConf then high else decisionH[1];

plot dL = if !today then Double.NaN else decisionL;
dL.SetDefaultColor(Color.WHITE);
plot dH = if !today then Double.NaN else decisionH;
dH.SetDefaultColor(Color.WHITE);

def TL = CompoundValue(1, if IsNaN(dL) then Double.NaN else if !IsNaN(TL[1]) then TL[1] else if close crosses below dL then dL - 2 * ATR else Double.NaN, Double.NaN);
def SL = CompoundValue(1, if IsNaN(dL) then Double.NaN else if !IsNaN(SL[1]) then SL[1] else if close crosses below dL then dL + 2 * ATR else Double.NaN, Double.NaN);

plot Target1Low = if !today then Double.NaN else TL;
Target1Low.SetDefaultColor(Color.GREEN);
Target1Low.SetStyle(Curve.SHORT_DASH);
plot Stop1Low = if !today then Double.NaN else SL;
Stop1Low.SetDefaultColor(Color.RED);
Stop1Low.SetLineWeight(2);

AddChartBubble(IsNaN(TL[1]) and !IsNaN(TL), TL, "Target 1\n" + Round(TL, 2), Color.GREEN, no);
AddChartBubble(IsNaN(SL[1]) and !IsNaN(SL), SL, "Stop\n" + Round(SL, 2), Color.RED);

def TH = CompoundValue(1, if IsNaN(dH) then Double.NaN else if !IsNaN(TH[1]) then TH[1] else if close crosses above dH then dH + 2 * ATR else Double.NaN, Double.NaN);
def SH = CompoundValue(1, if IsNaN(dH) then Double.NaN else if !IsNaN(SH[1]) then SH[1] else if close crosses above dH then dH - 2 * ATR else Double.NaN, Double.NaN);

plot Target1High = if !today then Double.NaN else TH;
Target1High.SetDefaultColor(Color.GREEN);
Target1High.SetStyle(Curve.SHORT_DASH);
plot Stop1High = if !today then Double.NaN else SH;
Stop1High.SetDefaultColor(Color.RED);
Stop1High.SetLineWeight(2);

AddChartBubble(IsNaN(TH[1]) and !IsNaN(TH), TH, "Target 1\n" + Round(TH, 2), Color.GREEN);
AddChartBubble(IsNaN(SH[1]) and !IsNaN(SH), SH, "Stop\n" + Round(SH, 2), Color.RED, no);


def alertup = close[1] crosses above hc1 or close[1] crosses above hc2;
def alertdn = close[1] crosses below lc1 or close[1] crosses below lc2;
alert(alertup, getsymbol() + " UP", alert.bar, sound.bell);
alert(alertdn, getsymbol() + " DOWN", alert.bar, sound.bell);
 
I am new here but just tried it out the one that is posted by slippage, and It looks identical to MACD, when I have them side by side in my charts.

The only advantage I see here is maybe easier to see crossovers and a little easier to follow? And looks like the bigger the steps in the stairs the stronger the momentum. I am glad I did not buy this indicator, I was looking at it before I found this thread. I don't think I would have much use for it and would prefer MACD over this.
 
I am new here but just tried it out the one that is posted by slippage, and It looks identical to MACD, when I have them side by side in my charts.

The only advantage I see here is maybe easier to see crossovers and a little easier to follow? And looks like the bigger the steps in the stairs the stronger the momentum. I am glad I did not buy this indicator, I was looking at it before I found this thread. I don't think I would have much use for it and would prefer MACD over this.

Yes, it's been stated in this thread a few times Moxie is really just a MACD histogram of a higher timeframe drawn as a line instead of a histogram.

As a line, I find it easier to see divergences. Crossovers are also easier to see clearly. And, yes, taller steps are bigger increases in momentum. I guess it's like putting the histogram under a magnifying glass or microscope. The details are more visible this way, in my opinion. But it doesn't offer any information that we didn't already have in the stock indicators on every platform for free. Just a new way of looking at it.
 
I won't be updating the full indicator code here any more. If you want the trampoline arrows, you can replace that part of the code with the code below. Just replace the lines from the trampoline comment to the squeeze comment. Comments start with #. Adjust the arrowBuffer input to change the vertical padding between the arrows and the zero line. Higher is more space.

Ruby:
# Indicate the Trampoline setup
input showTrampolineArrows = yes;
input arrowBuffer = .05;
def sma50 = Average(close, 50);
def isTrampoline = Moxie > 0 and close < sma50;
def isInvertedTrampoline = Moxie < 0 and close > sma50;
plot Trampoline =
  if showTrampolines and (isTrampoline or isInvertedTrampoline) then 0
  else Double.NaN
;
Trampoline.SetPaintingStrategy(PaintingStrategy.SQUARES);
Trampoline.DefineColor("Bullish", Color.LIGHT_GREEN);
Trampoline.DefineColor("Bearish", Color.PINK);
Trampoline.AssignValueColor(if close > sma50 then Trampoline.Color("Bearish") else Trampoline.Color("Bullish"));
Trampoline.HideBubble();
Trampoline.HideTitle();

plot TrampolineArrowUp =
  if showTrampolineArrows and isTrampoline then -AbsValue(HighestAll(Moxie)) * arrowBuffer
  else Double.NaN
;
TrampolineArrowUp.SetPaintingStrategy(PaintingStrategy.ARROW_UP);
TrampolineArrowUp.SetDefaultColor(Color.UPTICK);
TrampolineArrowUp.HideTitle();
TrampolineArrowUp.HideBubble();

plot TrampolineArrowDown =
  if showTrampolineArrows and isInvertedTrampoline then 0 + AbsValue(HighestAll(Moxie)) * arrowBuffer
  else Double.NaN
;
TrampolineArrowDown.SetPaintingStrategy(PaintingStrategy.ARROW_DOWN);
TrampolineArrowDown.SetDefaultColor(Color.RED);
TrampolineArrowDown.HideTitle();
TrampolineArrowDown.HideBubble();
 
Last edited:
Hopefully this will be the final code. The code for the scans have not changed since they were posted earlier. I just wanted to bring all the pieces together in this post as the (hopefully) final and complete package.

1. This resolves a bug for 15m. It should use close price rather than high price.
2. This makes it so the second line is shown by default on 15m and no other timeframes. I changed this to stop the confusion some members ran into with why the second line didn't appear automatically on 15m.

Moxie Upper:
Ruby:
declare upper;

def currentAggPeriod = GetAggregationPeriod();
def higherAggPeriod =
  if currentAggPeriod <= AggregationPeriod.TWO_MIN then AggregationPeriod.FIVE_MIN
  else if currentAggPeriod <= AggregationPeriod.THREE_MIN then AggregationPeriod.TEN_MIN
  else if currentAggPeriod <= AggregationPeriod.FIVE_MIN then AggregationPeriod.FIFTEEN_MIN
  else if currentAggPeriod <= AggregationPeriod.TEN_MIN then AggregationPeriod.THIRTY_MIN
  else if currentAggPeriod <= AggregationPeriod.FIFTEEN_MIN then AggregationPeriod.HOUR
  else if currentAggPeriod <= AggregationPeriod.THIRTY_MIN then AggregationPeriod.TWO_HOURS
  else if currentAggPeriod <= AggregationPeriod.TWO_HOURS then AggregationPeriod.DAY
  else if currentAggPeriod <= AggregationPeriod.FOUR_HOURS then AggregationPeriod.TWO_DAYS
  else if currentAggPeriod <= AggregationPeriod.DAY then AggregationPeriod.WEEK
  else if currentAggPeriod <= AggregationPeriod.WEEK then AggregationPeriod.MONTH
  else AggregationPeriod.QUARTER
;

script MoxieFunc {
  input price = close;
  def vc1 = ExpAverage(price, 12) - ExpAverage(price , 26);
  def va1 = ExpAverage(vc1, 9);
  plot data = (vc1 - va1) * 3;
}

def Moxie = MoxieFunc(close(period = higherAggPeriod));

def longTrigger = if Moxie > 0 and Moxie[1] <= 0 then Moxie else Double.NaN;
def longArrowPosition =
  # first arrow
  if Moxie == longTrigger and Moxie != Moxie[1] then low
  # consecutive arrows at same position
  else if Moxie == longTrigger and Moxie == Moxie[1] then longArrowPosition[1]
  else Double.NaN;
plot long = longArrowPosition;
long.SetPaintingStrategy(PaintingStrategy.ARROW_UP);
long.SetDefaultColor(Color.GREEN);
long.SetLineWeight(3);
long.HideBubble();
long.HideTitle();

def shortTrigger = if Moxie < 0 and Moxie[1] >= 0 then Moxie else Double.NaN;
def shortArrowPosition =
  # first arrow
  if Moxie == shortTrigger and Moxie != Moxie[1] then high
  # consecutive arrows at same position
  else if Moxie == shortTrigger and Moxie == Moxie[1] then shortArrowPosition[1]
  else Double.NaN;
plot short = shortArrowPosition;
short.SetPaintingStrategy(PaintingStrategy.ARROW_DOWN);
short.SetDefaultColor(Color.LIGHT_RED);
short.SetLineWeight(3);
short.HideBubble();
short.HideTitle();

Moxie Lower:
Ruby:
declare lower;

input showVerticalLines = yes;
input showTrampolines = yes;
input showSqueezeDots = no;

plot ZeroLine = if !IsNaN(open) and !showSqueezeDots then 0 else Double.NaN;
ZeroLine.SetDefaultColor(Color.GRAY);
ZeroLine.SetLineWeight(2);
ZeroLine.HideBubble();
ZeroLine.HideTitle();

def currentAggPeriod = GetAggregationPeriod();
def higherAggPeriod =
  if currentAggPeriod <= AggregationPeriod.TWO_MIN then AggregationPeriod.FIVE_MIN
  else if currentAggPeriod <= AggregationPeriod.THREE_MIN then AggregationPeriod.TEN_MIN
  else if currentAggPeriod <= AggregationPeriod.FIVE_MIN then AggregationPeriod.FIFTEEN_MIN
  else if currentAggPeriod <= AggregationPeriod.TEN_MIN then AggregationPeriod.THIRTY_MIN
  else if currentAggPeriod <= AggregationPeriod.FIFTEEN_MIN then AggregationPeriod.HOUR
  else if currentAggPeriod <= AggregationPeriod.THIRTY_MIN then AggregationPeriod.TWO_HOURS
  else if currentAggPeriod <= AggregationPeriod.TWO_HOURS then AggregationPeriod.DAY
  else if currentAggPeriod <= AggregationPeriod.FOUR_HOURS then AggregationPeriod.TWO_DAYS
  else if currentAggPeriod <= AggregationPeriod.DAY then AggregationPeriod.WEEK
  else if currentAggPeriod <= AggregationPeriod.WEEK then AggregationPeriod.MONTH
  else AggregationPeriod.QUARTER
;

script MoxieFunc {
  input price = close;
  def vc1 = ExpAverage(price, 12) - ExpAverage(price , 26);
  def va1 = ExpAverage(vc1, 9);
  plot data = (vc1 - va1) * 3;
}

plot Moxie = MoxieFunc(close(period = higherAggPeriod));
Moxie.SetLineWeight(2);
Moxie.DefineColor("Up", Color.GREEN);
Moxie.DefineColor("Down", Color.RED);
def lastChange = if Moxie < Moxie[1] then 1 else 0;
Moxie.AssignValueColor(
  if lastChange == 1 then Moxie.Color("Down")
  else Moxie.Color("Up")
);

# Watkins uses a different setup for Moxie on his 15 minute charts.
# He uses two lines derived from two higher timeframes.
# For timeframes other than 15 minutes we'll use the same data as
# first Moxie line to reduce data requested from the server and
# improve performance.
def secondAggPeriod =
  if currentAggPeriod == AggregationPeriod.FIFTEEN_MIN
  then AggregationPeriod.TWO_HOURS
  else currentAggPeriod
;

plot MoxieSecondLine =
  if currentAggPeriod == AggregationPeriod.FIFTEEN_MIN
  then MoxieFunc(close(period = secondAggPeriod))
  else Double.NaN
;

MoxieSecondLine.SetLineWeight(2);
MoxieSecondLine.DefineColor("Up", Color.GREEN);
MoxieSecondLine.DefineColor("Down", Color.RED);
def lastChangeSecondLine = if MoxieSecondLine < MoxieSecondLine[1] then 1 else 0;
MoxieSecondLine.AssignValueColor(
  if lastChangeSecondLine == 1 then MoxieSecondLine.Color("Down")
  else MoxieSecondLine.Color("Up")
);
MoxieSecondLine.SetHiding(currentAggPeriod != AggregationPeriod.FIFTEEN_MIN);

# Show vertical lines at crossovers
AddVerticalLine(showVerticalLines and Moxie[1] crosses above 0, "", CreateColor(0,150,0), Curve.SHORT_DASH);
AddVerticalLine(showVerticalLines and Moxie[1] crosses below 0, "", CreateColor(200,0,0), Curve.SHORT_DASH);

# Indicate the Trampoline setup
def sma50 = Average(close, 50);
plot Trampoline =
  if showTrampolines and ((Moxie < -.01 and close > sma50) or (Moxie > .01 and close < sma50))
  then 0
  else Double.NaN
;
Trampoline.SetPaintingStrategy(PaintingStrategy.SQUARES);
Trampoline.DefineColor("Bullish", Color.LIGHT_GREEN);
Trampoline.DefineColor("Bearish", Color.PINK);
Trampoline.AssignValueColor(if close > sma50 then Trampoline.Color("Bearish") else Trampoline.Color("Bullish"));
Trampoline.HideBubble();
Trampoline.HideTitle();

# show squeeze dots on zero line
def bb = reference BollingerBands.LowerBand;
def squeezeLevel =
  if bb > KeltnerChannels(factor = 1.0).Lower_Band then 3
  else if bb > KeltnerChannels(factor = 1.5).Lower_Band then 2
  else if bb > KeltnerChannels(factor = 2.0).Lower_Band then 1
  else 0
;

plot Squeeze = if !showSqueezeDots then Double.NaN else if !IsNaN(open) then 0 else Double.NaN;
Squeeze.SetPaintingStrategy(PaintingStrategy.POINTS);
Squeeze.SetDefaultColor(Color.GRAY);
Squeeze.DefineColor("Loose Squeeze", Color.UPTICK);
Squeeze.DefineColor("Squeeze", Color.RED);
Squeeze.DefineColor("Tight Squeeze", Color.YELLOW);
Squeeze.DefineColor("No Squeeze", Color.GRAY);
Squeeze.AssignValueColor(
  if squeezeLevel == 3 then Squeeze.Color("Tight Squeeze")
  else if squeezeLevel == 2 then Squeeze.Color("Squeeze")
  else if squeezeLevel == 1 then Squeeze.Color("Loose Squeeze")
  else Squeeze.Color("No Squeeze")
);
Squeeze.SetLineWeight(2);
Squeeze.HideTitle();
Squeeze.HideBubble();

AddLabel(
  yes,
  if currentAggPeriod == AggregationPeriod.WEEK then " W "
  else if currentAggPeriod == AggregationPeriod.Day then " D "
  else if currentAggPeriod == AggregationPeriod.HOUR then " H "
  else if currentAggPeriod == AggregationPeriod.FIFTEEN_MIN then " 15 "
  else if currentAggPeriod == AggregationPeriod.FIVE_MIN then " 5 "
  else if currentAggPeriod == AggregationPeriod.TWO_MIN then " 2 "
  else " ",
  if Moxie < 0 then Color.RED else Color.GREEN
);

Trigger scan:
Ruby:
# because Moxie calculates from higher time frame
# to find daily entries, run this scan on weekly
# to find hourly entries, run this on daily
script Moxie {
    input priceC = close;
    def vc1 = ExpAverage(priceC , 12) - ExpAverage(priceC , 26);
    def va1 = ExpAverage(vc1, 9);
    plot sData = (vc1 - va1) * 3;
}
def m = Moxie();
def moxieUpArrow = m > 0 and m[1] <= 0;
plot scan = moxieUpArrow within 1 bars;

Trampoline scan from @Sneaky_Swings earlier in this thread:
Ruby:
# because Moxie calculates from higher time frame
# to find daily entries, run this scan on weekly
# to find hourly entries, run this on daily

def ap1 = close;

script MoxieFunc {
    input priceC = close;
    def vc1 = ExpAverage(priceC , 12) - ExpAverage(priceC , 26);
    def va1 = ExpAverage(vc1, 9);
    plot sData = (vc1 - va1) * 3;
}

def price = close;
def s2 = MoxieFunc(price);

def ZeroLine = 0;
def Moxie = s2;

# Indicate the Trampoline setup
def sma50 = SimpleMovingAvg(close, 50);

plot trampoline = (Moxie > 0.1 and close < sma50);

EDIT 3/1/21 to add squeeze dots on zero line
I am new to this group and a developer by trade. Your code is amazingly clean and well put together. I am impressed, thank you for the time it took to perfect this.
 
That's my new way to show trampolines since I'm using squeeze dots on the zero line. It needs more work, though. The arrow tips cover the squeeze dots if I position the arrows at 0. So I have to offset them a bit. Moxie's range is different on every symbol and every timeframe so if I hard code a specific offset sometimes it's perfect, sometimes not enough and sometimes way too much. So, I changed it to calculate the offset dynamically. It's working better but still needs some tweaking.
What does the trampoline show?
 

Volatility Trading Range

VTR is a momentum indicator that shows if a stock is overbought or oversold based on its Weekly and Monthly average volatility trading range.

Download the indicator

Similar threads

Not the exact question you're looking for?

Start a new thread and receive assistance from our community.

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