Strategy Based on EMAs, TSI, MACD, and Premarket Highs/Lows For ThinkOrSwim

I'm down for anything that would provide for a better exit. Maybe you could post some of the proposed code here and i will figure out how to add it all in to this strategy and test it.
One of the examples I have been using for safer exits is to use FullK from Stochastic RSI. For long positions it best to exit when FullK crosses below Overbought ((adjusted to 75) line down or f you would like some better options use oversold (25).
 
@fskhan I just looked at this using a 4 hour chart on TSLA and WOW it is a great indicator of reversal! I am definitely going to have to add this to my arsenal! Thanks for sharing!

I think if the stock crosses the purple or red line on the LRC study and starts reversing back towards it you could definitely buy some calls or puts for the strike at the white line level and do very well! If you paired that with my study and are in the take profit zone on the 10 minute and over the purple or red line on the 4 hour there is surely a reversal coming. I think I will test this out on Monday. More risky and would be against the trend at the time but dang the payoff would be huge!

Another study to be written!?!? 🤔

LRC channels are confidential and not displaying code. I am using Standard Deviation Channel study, then derive a trend from it if upline is greater than upline[1]. Add this to your bullish or bearish entry signal conditions and it will only enter bullish if thenr is up and bearish entry if trend is down.

I think for a day trades length of the trendline needs to be set from the pre-market open times (4am) to ensure we only worry about short term trend, otherwise we will loose lots of entry points.
 
I'm going to spend the time to re-write this into ninjatrader but I have a real suspicion that the backtests are not correct. When I zoom in and look at entries, it will enter and exit mid-candle. This is impossible to know unless you have order book data and run it tick by tick. I'll let you know when I've got it done but I can almost guarantee that those are not real strategy results. If they are real, I'll be buying an island in 5 months and thanks for the strategy.

EDIT: Just looking at how you're entering and exiting trades, I can see the backtests are completely false. It's impossible to know where it would enter / exit based on your logic. Let your thinkorswim run live with that strategy on a 10 minute chart for GME or another volitile stock and screen record. You'll see what I mean. I bet orders are placed then magically erased. I hope you prove me wrong, cause again, I'd love to buy and island.
 
Last edited:
I'm going to spend the time to re-write this into ninjatrader but I have a real suspicion that the backtests are not correct. When I zoom in and look at entries, it will enter and exit mid-candle. This is impossible to know unless you have order book data and run it tick by tick. I'll let you know when I've got it done but I can almost guarantee that those are not real strategy results. If they are real, I'll be buying an island in 5 months and thanks for the strategy.

EDIT: Just looking at how you're entering and exiting trades, I can see the backtests are completely false. It's impossible to know where it would enter / exit based on your logic. Let your thinkorswim run live with that strategy on a 10 minute chart for GME or another volitile stock and screen record. You'll see what I mean. I bet orders are placed then magically erased. I hope you prove me wrong, cause again, I'd love to buy and island.
The strategy is written to buy at the 5EMA so that can fall anywhere on the candle. I personally removed the CallBuy from the buy order so that the order will only be placed after the close of the trigger candle. (The first Blue or Green candle) The back test isn't quite as good buy still very profitable. So basically I have to wait till 9:10 to look for pullbacks to the 5 EMA.
 
The strategy is written to buy at the 5EMA so that can fall anywhere on the candle. I personally removed the CallBuy from the buy order so that the order will only be placed after the close of the trigger candle. (The first Blue or Green candle) The back test isn't quite as good buy still very profitable. So basically I have to wait till 9:10 to look for pullbacks to the 5 EMA.
But most of the trades buy and exit the same candle. It's impossible to know if the exit was reached before or after the 5EMA. If it's a case of a target price, ie. the 5ema to enter after the trigger candle, perhaps a limit order here is a good test? I'll try to remove the CallBuy and see what you're looking at.
 
But most of the trades buy and exit the same candle. It's impossible to know if the exit was reached before or after the 5EMA. If it's a case of a target price, ie. the 5ema to enter after the trigger candle, perhaps a limit order here is a good test? I'll try to remove the CallBuy and see what you're looking at.
Yes, well if you buy at the 5EMA and then that same candle turns red then yes sell at the close of that candle. Normally in that case it’s a small loss.
 
The signal is the dark blue candle. The entry is on the 5EMA. The order is not entering before the signal in a majority of cases.
 
Last edited by a moderator:
@Fluideng @chasebank @a1cturner
Upon further testing, the OP is correct. The dark blue candle as the signal and entry on the 5ema works and the order is not entered before the signal in the majority of cases.

While the results ARE slightly skewed toward the positive. Changing the signal to the next bar SIGNIFICANTLY skews the results unrealistically to the negative.

Therefore, the original script provides the better data.
 
And now for some exciting news...

After much debating with myself; I am not sure that I like the MACD aspect of this strategy. I have also been playing with the SuperTrend and I just overlayed it on top of this strategy. I think I am going to start working on a new strategy (will be a brand new post later on) which will rid the study of the MACD parameter and add the SuperTrend....if it works.

If any of the bright minds on here want to add it in you can just add this code to the bottom of the current strategy and let me know if you spot something, anything that would be of use. I personally think there will be better and much earlier entries.

I am also going to try to use much more visually appealing and easier to understand candle colors.

Stay tuned.

Code:
##################################################################
#                         SuperTrend                             #
##################################################################
def AtrMult = 5;
def nATR = 50;
input AvgType = AverageType.HULL;

def ATR = ATR("length" = nATR, "average type" = AvgType);
def UP_Band_Basic = HL2 + (AtrMult * ATR);
def LW_Band_Basic = HL2 + (-AtrMult * ATR);
def UP_Band = if ((UP_Band_Basic < UP_Band[1]) or (close[1] > UP_Band[1])) then UP_Band_Basic else UP_Band[1];
def LW_Band = if ((LW_Band_Basic > LW_Band[1]) or (close[1] < LW_Band[1])) then LW_Band_Basic else LW_Band[1];

def ST = if ((ST[1] == UP_Band[1]) and (close < UP_Band)) then UP_Band
else if ((ST[1] == UP_Band[1]) and (close > Up_Band)) then LW_Band
else if ((ST[1] == LW_Band[1]) and (close > LW_Band)) then LW_Band
else if ((ST[1] == LW_Band) and (close < LW_Band)) then UP_Band
else LW_Band;

plot Long = if close > ST then ST else Double.NaN;
Long.AssignValueColor(Color.GREEN);
Long.SetLineWeight(3);

plot Short = if close < ST then ST else Double.NaN;
Short.AssignValueColor(Color.RED);
Short.SetLineWeight(3);

def LongTrigger = isNaN(Long[1]) and !isNaN(Long);
def ShortTrigger = isNaN(Short[1]) and !isNaN(Short);

plot LongDot = if LongTrigger then ST else Double.NaN;
LongDot.SetPaintingStrategy(PaintingStrategy.POINTS);
LongDot.AssignValueColor(Color.GREEN);
LongDot.SetLineWeight(4);

plot ShortDot = if ShortTrigger then ST else Double.NaN;
ShortDot.SetPaintingStrategy(PaintingStrategy.POINTS);
ShortDot.AssignValueColor(Color.RED);
ShortDot.SetLineWeight(4);
 
And now for some exciting news...

After much debating with myself; I am not sure that I like the MACD aspect of this strategy. I have also been playing with the SuperTrend and I just overlayed it on top of this strategy. I think I am going to start working on a new strategy (will be a brand new post later on) which will rid the study of the MACD parameter and add the SuperTrend....if it works.

If any of the bright minds on here want to add it in you can just add this code to the bottom of the current strategy and let me know if you spot something, anything that would be of use. I personally think there will be better and much earlier entries.

I am also going to try to use much more visually appealing and easier to understand candle colors.

Stay tuned.

Code:
##################################################################
#                         SuperTrend                             #
##################################################################
def AtrMult = 5;
def nATR = 50;
input AvgType = AverageType.HULL;

def ATR = ATR("length" = nATR, "average type" = AvgType);
def UP_Band_Basic = HL2 + (AtrMult * ATR);
def LW_Band_Basic = HL2 + (-AtrMult * ATR);
def UP_Band = if ((UP_Band_Basic < UP_Band[1]) or (close[1] > UP_Band[1])) then UP_Band_Basic else UP_Band[1];
def LW_Band = if ((LW_Band_Basic > LW_Band[1]) or (close[1] < LW_Band[1])) then LW_Band_Basic else LW_Band[1];

def ST = if ((ST[1] == UP_Band[1]) and (close < UP_Band)) then UP_Band
else if ((ST[1] == UP_Band[1]) and (close > Up_Band)) then LW_Band
else if ((ST[1] == LW_Band[1]) and (close > LW_Band)) then LW_Band
else if ((ST[1] == LW_Band) and (close < LW_Band)) then UP_Band
else LW_Band;

plot Long = if close > ST then ST else Double.NaN;
Long.AssignValueColor(Color.GREEN);
Long.SetLineWeight(3);

plot Short = if close < ST then ST else Double.NaN;
Short.AssignValueColor(Color.RED);
Short.SetLineWeight(3);

def LongTrigger = isNaN(Long[1]) and !isNaN(Long);
def ShortTrigger = isNaN(Short[1]) and !isNaN(Short);

plot LongDot = if LongTrigger then ST else Double.NaN;
LongDot.SetPaintingStrategy(PaintingStrategy.POINTS);
LongDot.AssignValueColor(Color.GREEN);
LongDot.SetLineWeight(4);

plot ShortDot = if ShortTrigger then ST else Double.NaN;
ShortDot.SetPaintingStrategy(PaintingStrategy.POINTS);
ShortDot.AssignValueColor(Color.RED);
ShortDot.SetLineWeight(4);

Well then, Go all out and use a Triple super trend.....
Code:
##################################################################
#                         SuperTrend                             #
##################################################################
### SuperTrend #1
input AtrMult = 3.00;
input nATR = 12;
input AvgType = AverageType.HULL;

def ATR = ATR("length" = nATR, "average type" = AvgType);
def UP_Band_Basic = HL2 + (AtrMult * ATR);
def LW_Band_Basic = HL2 + (-AtrMult * ATR);
def UP_Band = if ((UP_Band_Basic < UP_Band[1]) or (close[1] > UP_Band[1])) then UP_Band_Basic else UP_Band[1];
def LW_Band = if ((LW_Band_Basic > LW_Band[1]) or (close[1] < LW_Band[1])) then LW_Band_Basic else LW_Band[1];

def ST = if ((ST[1] == UP_Band[1]) and (close < UP_Band)) then UP_Band
else if ((ST[1] == UP_Band[1]) and (close > Up_Band)) then LW_Band
else if ((ST[1] == LW_Band[1]) and (close > LW_Band)) then LW_Band
else if ((ST[1] == LW_Band) and (close < LW_Band)) then UP_Band
else LW_Band;

plot Long = if close > ST then ST else Double.NaN;
Long.AssignValueColor(Color.GREEN);
Long.SetLineWeight(2);

plot Short = if close < ST then ST else Double.NaN;
Short.AssignValueColor(Color.RED);
Short.SetLineWeight(3);

def LongTrigger = isNaN(Long[1]) and !isNaN(Long);
def ShortTrigger = isNaN(Short[1]) and !isNaN(Short);

plot LongDot = if LongTrigger then ST else Double.NaN;
LongDot.SetPaintingStrategy(PaintingStrategy.POINTS);
LongDot.AssignValueColor(Color.GREEN);
LongDot.SetLineWeight(4);

plot ShortDot = if ShortTrigger then ST else Double.NaN;
ShortDot.SetPaintingStrategy(PaintingStrategy.POINTS);
ShortDot.AssignValueColor(Color.RED);
ShortDot.SetLineWeight(4);

### SuperTrend #2
input AtrMult2 = 2.00;
input nATR2 = 11;

def ATR2 = ATR("length" = nATR2, "average type" = AvgType);
def UP_Band_Basic2 = HL2 + (AtrMult2 * ATR);
def LW_Band_Basic2 = HL2 + (-AtrMult2 * ATR);
def UP_Band2 = if ((UP_Band_Basic2 < UP_Band2[1]) or (close[1] > UP_Band2[1])) then UP_Band_Basic2 else UP_Band2[1];
def LW_Band2 = if ((LW_Band_Basic2 > LW_Band2[1]) or (close[1] < LW_Band2[1])) then LW_Band_Basic2 else LW_Band2[1];

def ST2 = if ((ST2[1] == UP_Band2[1]) and (close < UP_Band2)) then UP_Band2
else if ((ST2[1] == UP_Band2[1]) and (close > Up_Band2)) then LW_Band2
else if ((ST2[1] == LW_Band2[1]) and (close > LW_Band2)) then LW_Band2
else if ((ST2[1] == LW_Band2) and (close < LW_Band2)) then UP_Band2
else LW_Band2;

plot Long2 = if close > ST2 then ST2 else Double.NaN;
Long2.AssignValueColor(Color.GREEN);
Long2.SetLineWeight(2);

plot Short2 = if close < ST2 then ST2 else Double.NaN;
Short2.AssignValueColor(Color.RED);
Short2.SetLineWeight(3);

def LongTrigger2 = isNaN(Long2[1]) and !isNaN(Long2);
def ShortTrigger2 = isNaN(Short2[1]) and !isNaN(Short2);

plot LongDot2 = if LongTrigger2 then ST2 else Double.NaN;
LongDot2.SetPaintingStrategy(PaintingStrategy.POINTS);
LongDot2.AssignValueColor(Color.GREEN);
LongDot2.SetLineWeight(4);

plot ShortDot2 = if ShortTrigger2 then ST2 else Double.NaN;
ShortDot2.SetPaintingStrategy(PaintingStrategy.POINTS);
ShortDot2.AssignValueColor(Color.RED);
ShortDot2.SetLineWeight(4);

### SuperTrend #3
input AtrMult3 = 1.00;
input nATR3 = 10;

def ATR3 = ATR("length" = nATR3, "average type" = AvgType);
def UP_Band_Basic3 = HL2 + (AtrMult3 * ATR);
def LW_Band_Basic3 = HL2 + (-AtrMult3 * ATR);
def UP_Band3 = if ((UP_Band_Basic3 < UP_Band3[1]) or (close[1] > UP_Band3[1])) then UP_Band_Basic3 else UP_Band3[1];
def LW_Band3 = if ((LW_Band_Basic3 > LW_Band3[1]) or (close[1] < LW_Band3[1])) then LW_Band_Basic3 else LW_Band3[1];

def ST3 = if ((ST3[1] == UP_Band3[1]) and (close < UP_Band3)) then UP_Band3
else if ((ST3[1] == UP_Band3[1]) and (close > Up_Band3)) then LW_Band3
else if ((ST3[1] == LW_Band3[1]) and (close > LW_Band3)) then LW_Band3
else if ((ST3[1] == LW_Band3) and (close < LW_Band3)) then UP_Band3
else LW_Band3;

plot Long3 = if close > ST3 then ST3 else Double.NaN;
Long3.AssignValueColor(Color.GREEN);
Long3.SetLineWeight(2);

plot Short3 = if close < ST3 then ST3 else Double.NaN;
Short3.AssignValueColor(Color.RED);
Short3.SetLineWeight(3);

def LongTrigger3 = isNaN(Long3[1]) and !isNaN(Long3);
def ShortTrigger3 = isNaN(Short3[1]) and !isNaN(Short3);

plot LongDot3 = if LongTrigger3 then ST3 else Double.NaN;
LongDot3.SetPaintingStrategy(PaintingStrategy.POINTS);
LongDot3.AssignValueColor(Color.GREEN);
LongDot3.SetLineWeight(4);

plot ShortDot3 = if ShortTrigger3 then ST3 else Double.NaN;
ShortDot3.SetPaintingStrategy(PaintingStrategy.POINTS);
ShortDot3.AssignValueColor(Color.RED);
ShortDot3.SetLineWeight(4);
 
Last edited:
Well then, Go all out and use a Triple super trend.....
That's awesome! Maybe I will, haha. Already looks good as is. What faults do you see so I can try to exploit?

At first glance I see getting in when all three are red/green and exit the minute one of the three changes.
 
That's awesome! Maybe I will, haha. Already looks good as is. What faults do you see so I can try to exploit?

At first glance I see getting in when all three are red/green and exit the minute one of the three changes.
It was a strategy from barbaros to use 3 Supertrends. I just combined them.
Indicators and settings:
  • SuperTrend.
    • UseEmaCross: No
    • Show Bubbles: No
    • Paint Bars: No
    • SuperTrend #1
      • atr mult: 3
      • nAtr: 12
    • SuperTrend #2
      • atr mult: 2
      • nAtr: 11
    • SuperTrend #3
      • atr mult: 1
      • nAtr: 10
  • StochasticRSI is built into Thinkorswim with name "StochRSI".
    • RSI length: 14
    • K period: 14
    • D period: 3
    • Slowing period: 3
  • EMA is built into Thinkorswim with name "MovAvgExponential"
    • Period: 200
Long position rules:
  • Price is above EMA
  • Stochastic is in the oversold territory and crosses above
  • At least 2 SuperTrend is in long direction
Short position rules:
  • Price is below EMA
  • Stochastic is in the overbought territory and crosses below
  • At least 2 SuperTrend is in short direction
 
That's awesome! Maybe I will, haha. Already looks good as is. What faults do you see so I can try to exploit?

At first glance I see getting in when all three are red/green and exit the minute one of the three changes.
it works pretty solid, use it only to define a trend for that day and long ONLY if trend is up and short ONLY if trend is down. filters out lots of unnecessary entries.
 
@Fluideng @chasebank @a1cturner
Upon further testing, the OP is correct. The dark blue candle as the signal and entry on the 5ema works and the order is not entered before the signal in the majority of cases.

While the results ARE slightly skewed toward the positive. Changing the signal to the next bar SIGNIFICANTLY skews the results unrealistically to the negative.

Therefore, the original script provides the better data.
Are you sure? Look at this entry for MFA 10 minute chart.


Do you have a suggestion for how to get these entries to be realistic?
 
Are you sure? Look at this entry for MFA 10 minute chart.


Do you have a suggestion for how to get these entries to be realistic?

Look at the chart. You have a green bar in which close is higher than open. The very next bar opens right at the 5EMA and goes higher. That is your entry.

I don’t know why the strategies plot the up arrow on the next bar but you should have a sideways arrow pointing to your actual entry point from the bar before. (Can’t see on the screenshot, it is too blurry)

To answer your second question, I am working on the code to make sure there is no doubt about the signal.
 
Look at the chart. You have a green bar in which close is higher than open. The very next bar opens right at the 5EMA and goes higher. That is your entry.

I don’t know why the strategies plot the up arrow on the next bar but you should have a sideways arrow pointing to your actual entry point from the bar before. (Can’t see on the screenshot, it is too blurry)

To answer your second question, I am working on the code to make sure there is no doubt about the signal.
Yes, I understand that would be the entry, open with some sort of slippage, but what I'm not understanding is how in this particular case, and many other, you can see where the order is entering by the tiny green arrow far below the bar, where the dotted line starts. This is an impossible trade, correct?

If you're saying it should enter where the bar spits the signal, that's impossible to have a signal fire on the bar in-which the moving average was met. The moving average will not change until the bar has completed, hence why it needs to enter on the next bar. This would be future telling and it's a sure way to make a strategy look great but doesn't work in practice.

I very well could be wrong but after fooling with this, it looks like look ahead bias to me.
 
Yes, I understand that would be the entry, open with some sort of slippage, but what I'm not understanding is how in this particular case, and many other, you can see where the order is entering by the tiny green arrow far below the bar, where the dotted line starts. This is an impossible trade, correct?

If you're saying it should enter where the bar spits the signal, that's impossible to have a signal fire on the bar in-which the moving average was met. The moving average will not change until the bar has completed, hence why it needs to enter on the next bar. This would be future telling and it's a sure way to make a strategy look great but doesn't work in practice.

I very well could be wrong but after fooling with this, it looks like look ahead bias to me.

The code was originally written to enter on the first green bar in which the low was <= 5EMA for a long trade. The first green bar on this chart is well within the 5EMA but I moved the entry to the next bar which is where you are getting the signal (second green bar starting at the 5EMA). I did this because of the problem you are describing.
 
The code was originally written to enter on the first green bar in which the low was <= 5EMA for a long trade. The first green bar on this chart is well within the 5EMA but I moved the entry to the next bar which is where you are getting the signal (second green bar starting at the 5EMA). I did this because of the problem you are describing.

If you can figure this out, I'll automate this for Alpaca or Ninjatrader with a scanner for automatic entry. I think you might be moving the problem down to the next candle. Do you have an order entry examples you're working on that solve it? I'd love to take a look.
 
If you can figure this out, I'll automate this for Alpaca or Ninjatrader with a scanner for automatic entry. I think you might be moving the problem down to the next candle. Do you have an order entry examples you're working on that solve it? I'd love to take a look.

You can follow this thread that I just posted.

https://usethinkscript.com/threads/color-bars-when-buy-signal-until-sell-signal.11310/

I am hoping that @halcyonguy sees it so he can teach me his ways, lol

I’ll post version 10 on post 1 when all my changes are completed. I am cleaning up other parts of the code along with the colors to make it cleaner and more visually appealing too.

I am also trying to figure out why the first sell signal after the entry signal, which usually results in a loss, is almost always a false sell signal. I am pretty sure it has to do with the EMA separation parameter I have set since the price usually retest the 5 or 12 EMA before continuing to trend in the trade direction.
 
Look at the chart. You have a green bar in which close is higher than open. The very next bar opens right at the 5EMA and goes higher. That is your entry.

I don’t know why the strategies plot the up arrow on the next bar but you should have a sideways arrow pointing to your actual entry point from the bar before. (Can’t see on the screenshot, it is too blurry)

To answer your second question, I am working on the code to make sure there is no doubt about the signal.
The up arrow is a different strategy. @chasebank the green bar you circled looks like it pulled back to the 5 EMA where the buy signal starts. Are you saying the buy signal triggered before it touched the 5 EMA?
 

Join useThinkScript to post your question to a community of 21,000+ developers and traders.

Not the exact question you're looking for?

Start a new thread and receive assistance from our community.

87k+ Posts
277 Online
Create Post

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