Moxie Indicator for ThinkorSwim

tradegeek

Active member
2019 Donor
VIP
I don't know if anyone has come across this neat indicator called the "Moxie Indicator". It seems the creator of this indicator has it developed for Ninjatrader and Thinkorswim but he's not releasing the TOS version because he doesn't want the code shared. He has partnered up with John Carter from SimplerTrading to provide alerts based on this indicator.

You can check it out here...

It would be nice if something like this can be replicated. I am not a programmer so I wouldn't know where to start. Can it be reversed engineered from a NinjaTrader script?

Much success to all!

Edit #1: @diazlaz converted a TradingView script that mimicked the Moxie script: https://usethinkscript.com/threads/moxie-indicator-for-thinkorswim.369/post-36862

Edit #2: Check out @Slippage version of the Moxie Indicator here: https://usethinkscript.com/threads/moxie-indicator-for-thinkorswim.369/post-53789

Edit #3: @Slippage reviews of the paid Moxie indicator https://usethinkscript.com/threads/moxie-indicator-for-thinkorswim.369/post-53751
 

Slippage

Active member
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
 
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

Active member
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:

Slippage

Active member
I still want to post some cleaned up code soon and I'll probably share some customizations. In the meantime I've been trying to learn all the criteria for the strategies using this indicator. I've documented a chunk of that and I'll post once I think it's complete.

It turns out Watkins had his own YouTube channel for Moxie before he joined Simpler Trading and in those old videos he's less secretive about what he shares. Some of those videos would have made reverse engineering the indicator easier, but oh well. At least they help with defining the strategies. You can find those videos here: https://www.youtube.com/c/MoxieTrader/playlists
 

Slippage

Active member
Here's my final code all cleaned up. Since Watkins only uses the second line on 15m charts, in order to avoid impacting performance on other timeframes I made it use the current timeframe's data to calculate the second line. The second line is useless now on other timeframes. It will be the same as first line. If we're following the Moxie strategy we don't need the second line on other timeframes anyway.

When you're switching through symbols and trying to scan with your eyes across multiple charts quickly the zero line can be hard to notice when it's at the top or bottom. I added a label to the lower study so it's easier to see, at a glance, if a particular timeframe is above (green) or below (red) zero. I was thinking about also creating an MTF study to add labels for higher timeframes so if you're maximized on the 1H chart you can still see if Moxie is above zero on D and W charts.

That said, I'm setting Moxie aside for now while I do some testing with a Squeeze Pro clone. I'm keeping the Moxie lower study on my charts for now as the only visible momentum indicator since I've customized Squeeze Pro to give signal arrows when both its built in momentum and the TTM_Wave move together in the same direction. I may or may not keep Moxie along with Squeeze Pro depending on if it's redundant or if it's later to correctly signal direction changes.

Here's the Moxie upper study for the arrows
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 price =
  if currentAggPeriod == AggregationPeriod.FIFTEEN_MIN then high(period = higherAggPeriod)
  else close(period = higherAggPeriod)
;
def Moxie = MoxieFunc(price);

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();

And here's the Moxie lower study
Ruby:
declare lower;

input showVerticalLines = yes;
input showTrampolines = yes;

plot ZeroLine = 0;
ZeroLine.SetDefaultColor(Color.GRAY);
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;
}

# Watkins uses the high for 15m charts and the close for other timeframes
def price = 
  if currentAggPeriod == AggregationPeriod.FIFTEEN_MIN
  then high(period = higherAggPeriod)
  else close(period = higherAggPeriod)
;

plot Moxie = MoxieFunc(price);
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.
# We'll hide the second Moxie line by default. You should enable it
# on 15 minute charts.
# 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
  # on the next line it seems like we should be able to use AggregationPeriod.TWO_HOURS
  # instead of the secondAggPeriod variable holding that value but for some reason that
  # causes the main Moxie plot on 1 hour chart to render nothing.
  then MoxieFunc(high(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.Hide();

# Show vertical lines at crossovers
AddVerticalLine(showVerticalLines and Moxie[1] <= 0 and Moxie > 0, "", CreateColor(0,150,0), Curve.SHORT_DASH);
AddVerticalLine(showVerticalLines and Moxie[1] >= 0 and Moxie < 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();

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 Moxie < 0 then Color.RED else Color.GREEN
);
 

Slippage

Active member
@Slippage Awesome, thanks. is there a way on TOS to setup auto trade based on this indicator ? also do you have script for backtesting it ?
No, there's not. And you wouldn't want that anyway unless you like to lose money. The strategy isn't as simple as just entering when you get the signal. You should watch some videos here to learn the strategy: https://www.youtube.com/channel/UCFfJ8sb-sXpaQhvd28G_qMg And due to the subjective nature of how to enter trades from those signals, depending a lot on chart patterns, it's not something that could easily be scripted for back-testing.
 

markos

Well-known member
VIP
@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);
 

skynetgen

Well-known member
I liked his explanation. Seems to me its some custom indicator based on RSI like criteria (e.g. momentum based indicator). Very likely he uses multiple timeframe cross to generate signal (e.g. change colors). Its even clear he has multiple timeframe setup (daily/monthly) for it

It is unbounded and not percentage based ( so more like stochastics/macd in this way).
 

tiburon

New member
VIP
guys I was watching several videos on this Moxie indicator itreally works in showing divergence an entry signals on the 60 min if the daily is align in trend if someone can get this script will be great
 

tradegeek

Active member
2019 Donor
VIP
I don't have the ninjascript for this but I'm sure you can get your hands on the encrypted ninjascript. However, the thinkscript version isn't being released because it can't be encrypted. TG Watkins is using it to create a subscription service with SimplerTrading.

TradeGeek isn't TG Watkins...LOL! I'm really not TG Watkins. Good catch though. I didn't notice until you brought it to my attention.
 

Monopod

New member
VIP
Trading is time consuming and, if you know what you're doing, lucrative. When I see someone who puts all his time into selling indicators, making you tube videos, maintaining mailing lists and a website, doing seminars, and paying for marketing / SEO services, then I pretty much know one thing: dude doesn't trade much and probably can't be consistently profitable as a trader. That has been proven to me many times in the course of my life.

I live on Jupiter Island. Three doors down from me there lives a veteran trader of commodities and derivatives. The man trades every day (as I do). He has no presence online, no website, no you tube videos. He's a pro and the last thing in the world he would do is share his methodology with the general public for any price.
 

tradegeek

Active member
2019 Donor
VIP
Hopefully that's true but I don't think he's selling the indicator for TOS as he specifically mentioned he doesn't want to disclose the unencrypted script.
 

Maya

New member
@tradegeek is correct. No way to replicate this as the source code is not available. It would be useless if you purchase it. You're out of your mind if you spend $697 on an indicator.

@tiburon An alternative to the Moxie indicator would be the Coppock indicator that @BenTen shared https://usethinkscript.com/threads/...and-and-coppock-indicator-for-thinkorswim.22/. Default is weekly, but you can change to any timeframe, and it should work. It works for me modestly. No reason to spend big $$$ on this bullsh** Moxie.

Very good point @Monopod.
 

tradegeek

Active member
2019 Donor
VIP
It looks like he will be offering the Moxie Indicator for the first time. Do you guys think the code can be encrypted in TOS?

@cherif I'm not sure. That why I asked if it's possible for the code to be encrypted because as far as I know, thinkscript code cannot be encrypted unless it's done by Thinkorswim internally. I don't know if there has been some new tech that may be able to do it outside of Thinkorswim.
 

BenTen's Watchlist + Setup + Trade Recaps

Get access to Ben's watchlist, swing trading strategy, ThinkorSwim setup, and trade examples.

Learn more

Similar threads

Top