Moxie Indicator for ThinkorSwim

Has anyone been able to find the settings for the 15 min that TG uses? I was watching his live stream this morning and the standard Salty Moxie we are using follows on the Daily and Hourly perfectly, but the 15 min is very off.
 
Last edited:

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

@Sneaky_Swings Yes I have noticed the same thing. The 15 minute time frame TG has looks very different from what Salty Moxie shows for 15 minute. I thought it was just me:unsure:
 
@greg44 I am pretty sure I figured it out but not positive.

Here is the link to it: http://tos.mx/SSwjODc

Then here is the code: The only thing I changed was the TF's that were being used and the lengths of the pmoxie. The PMOXIE plot is based on the hourly and the pmoxie1 is based on what we used to have so I know it is still wrong, but we might be getting closer.

Code:
declare lower;

#MOXIE
def AP = GetAggregationPeriod();

def ap1;
if (AP == AggregationPeriod.MIN) {
    ap1 = AggregationPeriod.FIVE_MIN;
}
else if (AP == AggregationPeriod.THREE_MIN) {
    ap1 = AggregationPeriod.FIVE_MIN;
}
else if (AP == AggregationPeriod.FIVE_MIN) {
    ap1 = AggregationPeriod.FIFTEEN_MIN;
}
else if (AP == AggregationPeriod.FIFTEEN_MIN) {
    ap1 = AggregationPeriod.HOUR;
}
else if (AP == AggregationPeriod.THIRTY_MIN) {
    ap1 = AggregationPeriod.HOUR;
}
else if (AP == AggregationPeriod.HOUR) {
    ap1 = AggregationPeriod.DAY;
}
else if (AP == AggregationPeriod.TWO_HOURS) {
    ap1 = AggregationPeriod.DAY;
}
else if (AP == AggregationPeriod.FOUR_HOURS) {
    ap1 = AggregationPeriod.DAY;
}
else if (AP == AggregationPeriod.DAY) {
    ap1 = AggregationPeriod.WEEK;
}
else if (AP == AggregationPeriod.WEEK) {
    ap1 = AggregationPeriod.MONTH;
}
else {
    ap1 = AggregationPeriod.DAY;
}

script Moxie {
    input priceC = close;
    def vc1 = ExpAverage(priceC , 8) - ExpAverage(priceC , 17);
    def va1 = ExpAverage(vc1, 9);
    plot sData = (vc1 - va1) * 3;
}

def priceM = close(period = ap1);
def s2 = Moxie(priceM);

plot ZeroLine = 0;
plot pMoxie = s2;
pMoxie.SetLineWeight(2);
pMoxie.DefineColor("Positive and Up", Color.GREEN);
pMoxie.DefineColor("Positive and Down", Color.RED);
pMoxie.DefineColor("Negative and Down", Color.RED);
pMoxie.DefineColor("Negative and Up", Color.GREEN);
pMoxie.AssignValueColor(if pMoxie > pMoxie[1] then pMoxie.Color("Positive and Up") else if pMoxie == pMoxie[1] and pMoxie[1] > pMoxie[2] then pMoxie.Color("Positive and Up") else if pMoxie == pMoxie[1] and pMoxie[2] > pMoxie[3] then pMoxie.Color("Positive and Up") else if pMoxie == pMoxie[1] and pMoxie[3] > pMoxie[4] then pMoxie.Color("Positive and Up") else if pMoxie == pMoxie[1] and pMoxie[4] > pMoxie[5] then pMoxie.Color("Positive and Up") else if pMoxie == pMoxie[1] and pMoxie[4] < pMoxie [5] then  pMoxie.Color("Positive and Down") else if pMoxie == pMoxie[1] and pMoxie[5] > pMoxie[6] then pMoxie.Color("Positive and Up") else if pMoxie == pMoxie[1] and pMoxie[6] > pMoxie[7] then pMoxie.Color("Positive and Up") else if pMoxie <= pMoxie[1] then pMoxie.Color("Negative and Down") else pMoxie.Color("Negative and Up"));


AddLabel(yes, pMoxie, if pMoxie > ZeroLine then Color.GREEN else Color.RED);
#END OF Moxie Salty Port for ThinkOrSwim


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

def priceM1 = close(period = AggregationPeriod.thirty_MIN);
def s21 = Moxie(priceM1);


plot pMoxie1 = s21;
pMoxie1.SetLineWeight(1);
pMoxie1.DefineColor("Positive and Up", Color.GREEN);
pMoxie1.DefineColor("Positive and Down", Color.RED);
pMoxie1.DefineColor("Negative and Down", Color.RED);
pMoxie1.DefineColor("Negative and Up", Color.GREEN);
pMoxie1.AssignValueColor(if pMoxie1 > pMoxie1[1] then pMoxie1.Color("Positive and Up") else if pMoxie1 == pMoxie1[1] and pMoxie1[1] > pMoxie1[2] then pMoxie1.Color("Positive and Up") else if pMoxie1 == pMoxie1[1] and pMoxie1[2] > pMoxie1[3] then pMoxie1.Color("Positive and Up") else if pMoxie1 == pMoxie1[1] and pMoxie1[3] > pMoxie1[4] then pMoxie1.Color("Positive and Up") else if pMoxie1 == pMoxie1[1] and pMoxie1[4] > pMoxie1[5] then pMoxie1.Color("Positive and Up") else if pMoxie1 == pMoxie1[1] and pMoxie1[4] < pMoxie1[5] then  pMoxie1.Color("Positive and Down") else if pMoxie1 == pMoxie1[1] and pMoxie1[5] > pMoxie1[6] then pMoxie1.Color("Positive and Up") else if pMoxie1 == pMoxie1[1] and pMoxie1[6] > pMoxie1[7] then pMoxie1.Color("Positive and Up") else if pMoxie1 <= pMoxie1[1] then pMoxie1.Color("Negative and Down") else pMoxie1.Color("Negative and Up"));

#AddCloud(pMoxie1, pMoxie, Color.GREEN, Color.RED, no);
 
Last edited:
@Sneaky_Swings Definitely looks like on the right track. Thank you for the hard work. I will see how it matches up with the TG videos both in the lines themselves and the coloring at various points.
 
@Sneaky_Swings Definitely looks like on the right track. Thank you for the hard work. I will see how it matches up with the TG videos both in the lines themselves and the coloring at various points.
I finally signed up so I can help out with this. I'm looking to combine some indicators for swing entries and Moxie looks pretty good. This Moxie clone seems to be working almost perfectly on the timeframes TG Watkins uses except for 15m. Even with the latest code above, which adds the second line, the plots are very far from correct. I don't think either of his two plots are using the same averages we're using on other timeframes.

Watkins posted another video on Jan 20 we can use to compare. I was looking just at GLD to play around with the averages trying to mimic his results but I gave up after a while. He has GLD on screen near the end of the video around the 29 minute mark. It's also while looking at GLD that he explains how he uses the two lines.


I found a help page at Simpler on how to configure Moxie but unfortunately it doesn't have any inputs, just colors. For now I'm thinking of using 30m rather than 15m since he clearly felt the default settings aren't good for 15m.

Here's a study I created to add the trigger arrows in the price chart.

Ruby:
# modified to show arrows in price chart
declare upper;

def AP = GetAggregationPeriod();

def ap1;
if (ap == aggregationPeriod.MIN){ap1=AggregationPeriod.five_Min; }
else if (ap == AggregationPeriod.three_MIN){ ap1=AggregationPeriod.five_Min;}
else if (ap == AggregationPeriod.five_Min) {ap1=AggregationPeriod.fifteen_Min;}
else if (ap == AggregationPeriod.fifteen_Min) {ap1=AggregationPeriod.hour;}
else if (ap == AggregationPeriod.thirty_Min) {ap1= AggregationPeriod.hour;}
else if (ap == AggregationPeriod.hour) {ap1=AggregationPeriod.DAY;}
else if (ap == AggregationPeriod.TWO_HOURS) {ap1=AggregationPeriod.DAY;}
else if (ap == AggregationPeriod.FOUR_HOURS) {ap1=AggregationPeriod.DAY;}
else if (ap == AggregationPeriod.DAY) {ap1=AggregationPeriod.WEEK;}
else if (ap == AggregationPeriod.WEEK) {ap1=AggregationPeriod.MONTH;}
else {ap1=AggregationPeriod.DAY;}

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(period = ap1);
def s2 = MoxieFunc(price);
def Moxie = s2;

def longMoxie = if Moxie[1] <= 0 and Moxie > 0 then Moxie else Double.NaN;
def longHeight = if Moxie[1] <= 0 and Moxie > 0 then low[1] else Double.NaN;

def b = if Moxie == longMoxie and Moxie == Moxie[1] then b[1]
  else if Moxie == longMoxie then low
  else Double.NaN;
plot buy = b;
buy.SetPaintingStrategy(PaintingStrategy.ARROW_UP);
buy.SetDefaultColor(Color.GREEN);
buy.SetLineWeight(3);
buy.HideBubble();
buy.HideTitle();

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

Here's the lower study with my modifications to mimic the real Moxie's colors. This doesn't have the changes for two lines on 15m. I also added vertical lines at the trigger points to make it easier to see where it crossed over the zero line if not using the upper study with the arrows. And I added a plot on the zero line to show where conditions are met for what Watkins calls the "trampoline move" or "trampoline setup".

Ruby:
declare lower;

def AP = GetAggregationPeriod();

def ap1;
if (ap == aggregationPeriod.MIN){ap1=AggregationPeriod.five_Min; }
else if (ap == AggregationPeriod.three_MIN){ ap1=AggregationPeriod.five_Min;}
else if (ap == AggregationPeriod.five_Min) {ap1=AggregationPeriod.fifteen_Min;}
else if (ap == AggregationPeriod.fifteen_Min) {ap1=AggregationPeriod.thirty_min;}
else if (ap == AggregationPeriod.thirty_Min) {ap1= AggregationPeriod.hour;}
else if (ap == AggregationPeriod.hour) {ap1=AggregationPeriod.DAY;}
else if (ap == AggregationPeriod.TWO_HOURS) {ap1=AggregationPeriod.DAY;}
else if (ap == AggregationPeriod.FOUR_HOURS) {ap1=AggregationPeriod.DAY;}
else if (ap == AggregationPeriod.DAY) {ap1=AggregationPeriod.WEEK;}
else if (ap == AggregationPeriod.WEEK) {ap1=AggregationPeriod.MONTH;}
else {ap1=AggregationPeriod.DAY;}

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(period = ap1);
def s2 = MoxieFunc(price);

plot ZeroLine = 0;
ZeroLine.SetDefaultColor(Color.GRAY);

plot Moxie = s2;
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("Up") else Moxie.Color("Down"));

# Show vertical lines at crossovers
AddVerticalLine(Moxie[1] <= 0 and Moxie > 0, "", Color.GREEN, Curve.SHORT_DASH);
AddVerticalLine(Moxie[1] >= 0 and Moxie < 0, "", Color.LIGHT_RED, Curve.SHORT_DASH);

# Indicate the Trampoline setup
def sma50 = SimpleMovingAvg(close, 50);
plot Trampoline = if ((Moxie < -0.1 and close > sma50) or (Moxie > 0.1 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"));

And here's code for scans to find symbols that are currently triggering. Note the comments regarding timeframes.

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;
 
Last edited:
@Slippage Thank you. Your codes are looking great and I just changed all of my charts to incorporate these new scripts. The addition of the dots for trampoline moves is awesome btw.

Additionally, I wanted to share that on the upper chart I have messed with TFs and have found that using a "four_hour" aggregation period on the 1 hour gives great entries if you wanna try it out. I set my chart for the hourly with the original moxie underneath and I have my arrows set to the four_hour aggregation period.

In regards to adapting to get a similar 15 min, do you think we should mess with the lengths used in the Moxie calculation?

Here is a trampoline move scan for upwards trampolines.

Code:
# 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);
 
Last edited:
I've got the 15m two lines thing figured out.

He's using the same calculations but getting them from 2 different timeframes -- the 1-hour and the 2-hour. He's also using the high rather than the close. I noticed his study name in the video is Moxie_15_High so that's what tipped me off for that part. I've got the code updated as well as a general cleanup/reformatting of the entire thing and I made the trampoline and the vertical lines configurable. Sorry to add code churn for those following along.

Now this will access two additional timeframes on every chart instead of just one. We probably should split this into two scripts like Simpler did, for performance reasons. I don't have time/ambition to do that right now but maybe before the weekend.

Anyway, here's the latest code. The second moxie line is hidden by default. You need to enable it on your 15m charts.
Ruby:
declare lower;

input showVerticalLines = yes;
input showTrampolines = yes;

plot ZeroLine = 0;
ZeroLine.SetDefaultColor(Color.GRAY);

def currentAggPeriod = GetAggregationPeriod();
def higherAggPeriod = if currentAggPeriod == AggregationPeriod.MIN then AggregationPeriod.FIVE_MIN
  else if currentAggPeriod == AggregationPeriod.THREE_MIN then AggregationPeriod.FIVE_MIN
  else if currentAggPeriod == AggregationPeriod.FIVE_MIN then AggregationPeriod.FIFTEEN_MIN
  else if currentAggPeriod == AggregationPeriod.FIFTEEN_MIN then AggregationPeriod.HOUR
  else if currentAggPeriod == AggregationPeriod.THIRTY_MIN then AggregationPeriod.HOUR
  else if currentAggPeriod == AggregationPeriod.HOUR then AggregationPeriod.DAY
  else if currentAggPeriod == AggregationPeriod.TWO_HOURS then AggregationPeriod.DAY
  else if currentAggPeriod == AggregationPeriod.FOUR_HOURS then AggregationPeriod.DAY
  else if currentAggPeriod == AggregationPeriod.DAY then AggregationPeriod.WEEK
  else if currentAggPeriod == AggregationPeriod.WEEK then AggregationPeriod.MONTH
  else AggregationPeriod.DAY
;

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

# Watkins uses the high for 15m charts and 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 2 different higher timeframes.
# We'll hide the second Moxie line by default
def secondAggPeriod = if currentAggPeriod == AggregationPeriod.MIN then AggregationPeriod.FIFTEEN_MIN
  else if currentAggPeriod == AggregationPeriod.THREE_MIN then AggregationPeriod.FIFTEEN_MIN
  else if currentAggPeriod == AggregationPeriod.FIVE_MIN then AggregationPeriod.THIRTY_MIN
  else if currentAggPeriod == AggregationPeriod.FIFTEEN_MIN then AggregationPeriod.TWO_HOURS
  else if currentAggPeriod == AggregationPeriod.THIRTY_MIN then AggregationPeriod.TWO_HOURS
  else if currentAggPeriod == AggregationPeriod.HOUR then AggregationPeriod.TWO_DAYS
  else if currentAggPeriod == AggregationPeriod.TWO_HOURS then AggregationPeriod.TWO_DAYS
  else if currentAggPeriod == AggregationPeriod.FOUR_HOURS then AggregationPeriod.TWO_DAYS
  else if currentAggPeriod == AggregationPeriod.DAY then AggregationPeriod.MONTH
  else AggregationPeriod.YEAR
;

plot MoxieSecondLine = MoxieFunc(high(period = secondAggPeriod));
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, "", Color.GREEN, Curve.SHORT_DASH);
AddVerticalLine(showVerticalLines and Moxie[1] >= 0 and Moxie < 0, "", Color.LIGHT_RED, Curve.SHORT_DASH);

# Indicate the Trampoline setup
def sma50 = SimpleMovingAvg(close, 50);
plot Trampoline = if showTrampolines and ((Moxie < -0.1 and close > sma50) or (Moxie > 0.1 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"));
 
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.
 
Last edited:
Hi all. Beginner and new member here. Stumbled upon this forum and can't believe all the wonderful information and help here. I see a lot of code snippets in regards to the moxie indicator here. Can someone please point me to the latest version of the indicator on this forum that you are using for your trading .. so that i can attempt to try it/learn it. Thanks a bunch.
 
Hi all. Beginner and new member here. Stumbled upon this forum and can't believe all the wonderful information and help here. I see a lot of code snippets in regards to the moxie indicator here. Can someone please point me to the latest version of the indicator on this forum that you are using for your trading .. so that i can attempt to try it/learn it. Thanks a bunch.
The most recent post by Slippage is the best.
 
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
 
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 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.
 
I finally signed up so I can help out with this. I'm looking to combine some indicators for swing entries and Moxie looks pretty good. This Moxie clone seems to be working almost perfectly on the timeframes TG Watkins uses except for 15m. Even with the latest code above, which adds the second line, the plots are very far from correct. I don't think either of his two plots are using the same averages we're using on other timeframes.

Watkins posted another video on Jan 20 we can use to compare. I was looking just at GLD to play around with the averages trying to mimic his results but I gave up after a while. He has GLD on screen near the end of the video around the 29 minute mark. It's also while looking at GLD that he explains how he uses the two lines.


I found a help page at Simpler on how to configure Moxie but unfortunately it doesn't have any inputs, just colors. For now I'm thinking of using 30m rather than 15m since he clearly felt the default settings aren't good for 15m.

Here's a study I created to add the trigger arrows in the price chart.

Ruby:
# modified to show arrows in price chart
declare upper;

def AP = GetAggregationPeriod();

def ap1;
if (ap == aggregationPeriod.MIN){ap1=AggregationPeriod.five_Min; }
else if (ap == AggregationPeriod.three_MIN){ ap1=AggregationPeriod.five_Min;}
else if (ap == AggregationPeriod.five_Min) {ap1=AggregationPeriod.fifteen_Min;}
else if (ap == AggregationPeriod.fifteen_Min) {ap1=AggregationPeriod.hour;}
else if (ap == AggregationPeriod.thirty_Min) {ap1= AggregationPeriod.hour;}
else if (ap == AggregationPeriod.hour) {ap1=AggregationPeriod.DAY;}
else if (ap == AggregationPeriod.TWO_HOURS) {ap1=AggregationPeriod.DAY;}
else if (ap == AggregationPeriod.FOUR_HOURS) {ap1=AggregationPeriod.DAY;}
else if (ap == AggregationPeriod.DAY) {ap1=AggregationPeriod.WEEK;}
else if (ap == AggregationPeriod.WEEK) {ap1=AggregationPeriod.MONTH;}
else {ap1=AggregationPeriod.DAY;}

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(period = ap1);
def s2 = MoxieFunc(price);
def Moxie = s2;

def longMoxie = if Moxie[1] <= 0 and Moxie > 0 then Moxie else Double.NaN;
def longHeight = if Moxie[1] <= 0 and Moxie > 0 then low[1] else Double.NaN;

def b = if Moxie == longMoxie and Moxie == Moxie[1] then b[1]
  else if Moxie == longMoxie then low
  else Double.NaN;
plot buy = b;
buy.SetPaintingStrategy(PaintingStrategy.ARROW_UP);
buy.SetDefaultColor(Color.GREEN);
buy.SetLineWeight(3);
buy.HideBubble();
buy.HideTitle();

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

Here's the lower study with my modifications to mimic the real Moxie's colors. This doesn't have the changes for two lines on 15m. I also added vertical lines at the trigger points to make it easier to see where it crossed over the zero line if not using the upper study with the arrows. And I added a plot on the zero line to show where conditions are met for what Watkins calls the "trampoline move" or "trampoline setup".

Ruby:
declare lower;

def AP = GetAggregationPeriod();

def ap1;
if (ap == aggregationPeriod.MIN){ap1=AggregationPeriod.five_Min; }
else if (ap == AggregationPeriod.three_MIN){ ap1=AggregationPeriod.five_Min;}
else if (ap == AggregationPeriod.five_Min) {ap1=AggregationPeriod.fifteen_Min;}
else if (ap == AggregationPeriod.fifteen_Min) {ap1=AggregationPeriod.thirty_min;}
else if (ap == AggregationPeriod.thirty_Min) {ap1= AggregationPeriod.hour;}
else if (ap == AggregationPeriod.hour) {ap1=AggregationPeriod.DAY;}
else if (ap == AggregationPeriod.TWO_HOURS) {ap1=AggregationPeriod.DAY;}
else if (ap == AggregationPeriod.FOUR_HOURS) {ap1=AggregationPeriod.DAY;}
else if (ap == AggregationPeriod.DAY) {ap1=AggregationPeriod.WEEK;}
else if (ap == AggregationPeriod.WEEK) {ap1=AggregationPeriod.MONTH;}
else {ap1=AggregationPeriod.DAY;}

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(period = ap1);
def s2 = MoxieFunc(price);

plot ZeroLine = 0;
ZeroLine.SetDefaultColor(Color.GRAY);

plot Moxie = s2;
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("Up") else Moxie.Color("Down"));

# Show vertical lines at crossovers
AddVerticalLine(Moxie[1] <= 0 and Moxie > 0, "", Color.GREEN, Curve.SHORT_DASH);
AddVerticalLine(Moxie[1] >= 0 and Moxie < 0, "", Color.LIGHT_RED, Curve.SHORT_DASH);

# Indicate the Trampoline setup
def sma50 = SimpleMovingAvg(close, 50);
plot Trampoline = if ((Moxie < -0.1 and close > sma50) or (Moxie > 0.1 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"));

And here's code for scans to find symbols that are currently triggering. Note the comments regarding timeframes.

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;

I finally signed up so I can help out with this. I'm looking to combine some indicators for swing entries and Moxie looks pretty good. This Moxie clone seems to be working almost perfectly on the timeframes TG Watkins uses except for 15m. Even with the latest code above, which adds the second line, the plots are very far from correct. I don't think either of his two plots are using the same averages we're using on other timeframes.

Watkins posted another video on Jan 20 we can use to compare. I was looking just at GLD to play around with the averages trying to mimic his results but I gave up after a while. He has GLD on screen near the end of the video around the 29 minute mark. It's also while looking at GLD that he explains how he uses the two lines.


I found a help page at Simpler on how to configure Moxie but unfortunately it doesn't have any inputs, just colors. For now I'm thinking of using 30m rather than 15m since he clearly felt the default settings aren't good for 15m.

Here's a study I created to add the trigger arrows in the price chart.

Ruby:
# modified to show arrows in price chart
declare upper;

def AP = GetAggregationPeriod();

def ap1;
if (ap == aggregationPeriod.MIN){ap1=AggregationPeriod.five_Min; }
else if (ap == AggregationPeriod.three_MIN){ ap1=AggregationPeriod.five_Min;}
else if (ap == AggregationPeriod.five_Min) {ap1=AggregationPeriod.fifteen_Min;}
else if (ap == AggregationPeriod.fifteen_Min) {ap1=AggregationPeriod.hour;}
else if (ap == AggregationPeriod.thirty_Min) {ap1= AggregationPeriod.hour;}
else if (ap == AggregationPeriod.hour) {ap1=AggregationPeriod.DAY;}
else if (ap == AggregationPeriod.TWO_HOURS) {ap1=AggregationPeriod.DAY;}
else if (ap == AggregationPeriod.FOUR_HOURS) {ap1=AggregationPeriod.DAY;}
else if (ap == AggregationPeriod.DAY) {ap1=AggregationPeriod.WEEK;}
else if (ap == AggregationPeriod.WEEK) {ap1=AggregationPeriod.MONTH;}
else {ap1=AggregationPeriod.DAY;}

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(period = ap1);
def s2 = MoxieFunc(price);
def Moxie = s2;

def longMoxie = if Moxie[1] <= 0 and Moxie > 0 then Moxie else Double.NaN;
def longHeight = if Moxie[1] <= 0 and Moxie > 0 then low[1] else Double.NaN;

def b = if Moxie == longMoxie and Moxie == Moxie[1] then b[1]
  else if Moxie == longMoxie then low
  else Double.NaN;
plot buy = b;
buy.SetPaintingStrategy(PaintingStrategy.ARROW_UP);
buy.SetDefaultColor(Color.GREEN);
buy.SetLineWeight(3);
buy.HideBubble();
buy.HideTitle();

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

Here's the lower study with my modifications to mimic the real Moxie's colors. This doesn't have the changes for two lines on 15m. I also added vertical lines at the trigger points to make it easier to see where it crossed over the zero line if not using the upper study with the arrows. And I added a plot on the zero line to show where conditions are met for what Watkins calls the "trampoline move" or "trampoline setup".

Ruby:
declare lower;

def AP = GetAggregationPeriod();

def ap1;
if (ap == aggregationPeriod.MIN){ap1=AggregationPeriod.five_Min; }
else if (ap == AggregationPeriod.three_MIN){ ap1=AggregationPeriod.five_Min;}
else if (ap == AggregationPeriod.five_Min) {ap1=AggregationPeriod.fifteen_Min;}
else if (ap == AggregationPeriod.fifteen_Min) {ap1=AggregationPeriod.thirty_min;}
else if (ap == AggregationPeriod.thirty_Min) {ap1= AggregationPeriod.hour;}
else if (ap == AggregationPeriod.hour) {ap1=AggregationPeriod.DAY;}
else if (ap == AggregationPeriod.TWO_HOURS) {ap1=AggregationPeriod.DAY;}
else if (ap == AggregationPeriod.FOUR_HOURS) {ap1=AggregationPeriod.DAY;}
else if (ap == AggregationPeriod.DAY) {ap1=AggregationPeriod.WEEK;}
else if (ap == AggregationPeriod.WEEK) {ap1=AggregationPeriod.MONTH;}
else {ap1=AggregationPeriod.DAY;}

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(period = ap1);
def s2 = MoxieFunc(price);

plot ZeroLine = 0;
ZeroLine.SetDefaultColor(Color.GRAY);

plot Moxie = s2;
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("Up") else Moxie.Color("Down"));

# Show vertical lines at crossovers
AddVerticalLine(Moxie[1] <= 0 and Moxie > 0, "", Color.GREEN, Curve.SHORT_DASH);
AddVerticalLine(Moxie[1] >= 0 and Moxie < 0, "", Color.LIGHT_RED, Curve.SHORT_DASH);

# Indicate the Trampoline setup
def sma50 = SimpleMovingAvg(close, 50);
plot Trampoline = if ((Moxie < -0.1 and close > sma50) or (Moxie > 0.1 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"));

And here's code for scans to find symbols that are currently triggering. Note the comments regarding timeframes.

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;
ruby thanks for the code . i have copied and paste indicator codes but where or how do you post scan codes ? i have never used tos scanner i dont know anything about it . thanks
 

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

Similar threads

Not the exact question you're looking for?

Start a new thread and receive assistance from our community.

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