I watched the handful of video Watkins posted since Dec 2 to get a feel for how he's using Moxie and the other indicators and to learn his strategies. It seems he mostly isn't entering a trade quickly after Moxie triggers but often waiting for a pullback to a moving average or other support. Anecdotally, other types of triggers that occur immediately after the Moxie trigger look like they usually work though frequently go up a few ATR and then pull back all the way to entry before continuing higher.
I'd recommend watching a couple of his videos to get a feel for how he's trading with these indicators. Here's Simpler Trading's youtube channel filtered to show just Watkins videos.
https://www.youtube.com/c/SimplerTrading/search?query=watkins
I set up some charts matching his to make it easier to follow along in TOS while watching his videos. If anyone's interested in mimicking the rest of his indicators:
For 15m, 1h, 1D, 1W he's using:
8 and 21 EMA (cyan and reddish)
50 and 200 SMA (magenta and salmon-ish)
Two sets of Keltner channels.
1) One with either 1.5 or 2.0 factor (gray dashed lines)
2) One with factor of 3.0 (light gray dashed lines)
SqueezePro. Can use TOS's built in TTM_Squeeze or a clone from this forum. He doesn't use squeeze in his strategy.
StochasticSlow (not on 15m chart) with k=12 and d=3 and those plots are green and dark gray
Volume is set to overlapping and dark gray
He set his candle colors to light gray for both up and down candles
On weekly he's also got 30 SMA as green.
Sometimes I notice dark gray horizontal lines on his daily, weekly and monthly charts. I'm not sure if those are drawings or if it's VolumeProfile. If it's VolumeProfile, set "on expansion" to no. Set POC, VAHigh and VALow colors to gray. In the Globals at the bottom, set all 3 colors to match your chart's background (black in my case).
On monthly charts he uses just the 10 SMA (cyan) and 50 SMA (magenta). The lower study on that chart is only there to make that chart's scaling feel like the others versus having no lower studies. He doesn't use that lower study so you can put whatever you want there.
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
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.
updated version https://usethinkscript.com/threads/mtf-moxie-indicator-for-thinkorswim.369/page-2#post-53789
non-mtf version:
https://usethinkscript.com/threads/mtf-moxie-indicator-for-thinkorswim.369/page-3#post-54662
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
);