Pullback To The 20EMA (SMA) or any other MA

cocojumbo

Member
Plus
Could any of you amazing coders translate my thoughts into a scanable code? I am trying to find some swing setups but don’t know how to work the scanner criteria. I want to find stocks that are on up trend on weekly/monthly aggregation and at same time pullback to rising 20EMA. Is that possible? Really appreciate any help from you pros!
 
#The following is a code that I created which will accomplish what you are looking for it is just a little more complicated. This has a SLM ribbon of the normal 8,13,21 exponential moving averages both on a longer time frame and shorter. It includes a cloud showing the longer term moving averages, and a pull back to the 13ema middle moving average. You could easily alter the middle setting to your 20 ema it will accomplish what you are looking for. One note on that though, if you adjust that 13 ema to a 20, you will also want to adjust the 21 ema of the shorter time frame to something larger like a 34 ema as this indicator is looking for a pullback to the middle 13 ema that is not past the longer 21 ema. There is a lot of flexibility in this code for defining your longer term trend. It would also not be hard to add in stacked EMAs on the shorter time frame as well if you want.

Code:
####SLM_MTF_PullBack


####Longterm Time Frame
input applyCloud = yes;
input LT_TimeFrame = AggregationPeriod.Week;

input lengthLT =8;
input averageTypeLT = { Simple, default Exponential, Weighted, Wilders,  Hull};
plot maLT = MovingAverage(averageType = averageTypeLT, close(period = LT_TimeFrame), lengthLT);
maLT.SetDefaultColor(COlor.Dark_green);
input lengthLT1 = 13;
input averageTypeLT1 = {Simple,default Exponential, Weighted, Wilders, Hull};

plot maLT1 = MovingAverage(averageType = averageTypeLT1, close(period = LT_TimeFrame), lengthLT1);
maLT1.SetDefaultColor(COlor.blue);

input lengthLT2 = 21;
input averageTypeLT2 = {Simple, default Exponential, Weighted, Wilders, Hull};
plot maLT2 = MovingAverage(averageType = averageTypeLT2, close(period = LT_TimeFrame), lengthLT2);
maLT2.SetDefaultColor(COlor.Dark_Red);
DefineGlobalColor("Bullish", Color.GREEN);
DefineGlobalColor("Neutral", Color.Gray);
DefineGlobalColor("Bearish", Color.RED);

#-------------- Define the Momentum
def bullishMomentum = maLT > maLT1 and maLT1 > maLT2 ;
def bearishMomentum = maLT < maLT1 and maLT1 < maLT2 ;

#-------------- do some plots
Plot Superfast = if applyCloud then maLT else Double.NaN;
Superfast.AssignValueColor(if bullishMomentum then GlobalColor("Bullish") else if bearishMomentum then GlobalColor("Bearish") else GlobalColor("Neutral"));
Superfast.HideBubble();
plot Fast = if applyCloud then maLT1 else Double.NaN;
Fast.AssignValueColor(if bullishMomentum then GlobalColor("Bullish") else if bearishMomentum then GlobalColor("Bearish") else GlobalColor("Neutral"));
Fast.HideBubble();
plot Slow = if applyCloud then maLT2 else Double.NaN;
Slow.AssignValueColor(if bullishMomentum then GlobalColor("Bullish") else if bearishMomentum then GlobalColor("Bearish") else GlobalColor("Neutral"));
Slow.HideBubble();

AddCloud(if applyCloud and bullishMomentum then Superfast else Fast, if bullishMomentum then Slow else Fast, GlobalColor("Bullish") , GlobalColor("Bearish"));
AddCloud(if applyCloud and bearishMomentum then Slow else Fast, if bearishMomentum then Superfast else Fast, GlobalColor("Bearish"), GlobalColor("Neutral"));
AddCloud(if applyCloud and !bullishMomentum and !bearishMomentum then max(max(Fast, Slow), SuperFast) else Fast, if !bullishMomentum and !bearishMomentum then min(min(Fast, Superfast), Slow) else Fast, GlobalColor("Neutral"), GlobalColor("Neutral"));



#####Shortterm Time Frame



input length =8;
input averageType = { Simple, default Exponential, Weighted, Wilders,  Hull};
plot ma = MovingAverage(averageType = averageType, close, length);
ma.SetDefaultColor(COlor.green);
input length1 = 13;
input averageType1 = {Simple,default Exponential, Weighted, Wilders, Hull};

plot ma1 = MovingAverage(averageType = averageType1, close, length1);
ma1.SetDefaultColor(COlor.cyan);
input length2 = 21;
input averageType2 = {Simple, default Exponential, Weighted, Wilders, Hull};
plot ma2 = MovingAverage(averageType = averageType2, close, length2);
ma2.SetDefaultColor(COlor.Red);




input alertonclose = yes;
def state = {default flat, long, short};

switch (state[1]) {
case flat:
    state = if MA1 > MA2 and low[1] > MA1
    and low <= MA1 and low >= MA2 then state.long
    else if MA2 > MA1 and high[1] < MA1 and high >= MA1 and high <= MA2 then state.short else state.flat;

case long:
 
state = if maLT > maLT1 and maLT1 > maLT2 and low <= MA2 then state.flat else state.long;

case short:

state = if maLT < maLT1 and maLT1 < maLT2 and high >= MA2 then state.flat else state.short;
}




plot BuyDot = if  maLT > maLT1 and maLT1 > maLT2 and state==state.long and state[1] != state.long

or maLT > maLT1 and maLT1 > maLT2 and ma > ma1 and ma1 > ma2 and low <= ma1 and low > ma2

then low else Double.NaN;
BuyDot.SetPaintingStrategy(PaintingStrategy.arroW_Up);
BuyDot.SetLineWeight(3);
BuyDot.SetDefaultColor(Color.Dark_GREEN);
BuyDot.HideBubble();
AddVerticalLine (BuyDot, "", Color.Dark_Green);
Alert(BuyDot, "SLM_MTF_PullBack Down", Alert.BAR, Sound.Ring);




plot SellDot = if maLT < maLT1 and maLT1 < maLT2 and state==state.short and state[1] != state.short

or maLT < maLT1 and maLT1 < maLT2 and ma < ma1 and ma1 < ma2 and high >= ma1 and high < ma2

then high else Double.NaN;
SellDot.SetPaintingStrategy(PaintingStrategy.arroW_DOWN);
SellDot.SetLineWeight(3);
SellDot.SetDefaultColor(Color.Dark_Red);
SellDot.HideBubble();
AddVerticalLine (SellDot, "", Color.Dark_Red);
Alert(SellDot, "SLM_MTF_PullBack Down", Alert.BAR, Sound.Chimes);
 
Last edited:
#I also created the following code for a watchlist.

Code:
####Longterm Time Frame
input LT_TimeFrame = AggregationPeriod.Week;

input lengthLT =8;
input averageTypeLT = { Simple, default Exponential, Weighted, Wilders,  Hull};
def maLT = MovingAverage(averageType = averageTypeLT, close(period = LT_TimeFrame), lengthLT);

input lengthLT1 = 13;
input averageTypeLT1 = {Simple,default Exponential, Weighted, Wilders, Hull};

def maLT1 = MovingAverage(averageType = averageTypeLT1, close(period = LT_TimeFrame), lengthLT1);

input lengthLT2 = 21;
input averageTypeLT2 = {Simple, default Exponential, Weighted, Wilders, Hull};
def maLT2 = MovingAverage(averageType = averageTypeLT2, close(period = LT_TimeFrame), lengthLT2);

#####Shortterm Time Frame

input length =8;
input averageType = { Simple, default Exponential, Weighted, Wilders,  Hull};
def ma = MovingAverage(averageType = averageType, close, length);
input length1 = 13;
input averageType1 = {Simple,default Exponential, Weighted, Wilders, Hull};

plot ma1 = MovingAverage(averageType = averageType1, close, length1);
input length2 = 21;
input averageType2 = {Simple, default Exponential, Weighted, Wilders, Hull};
def ma2 = MovingAverage(averageType = averageType2, close, length2);


input alertonclose = yes;
def state = {default flat, long, short};

switch (state[1]) {
case flat:
    state = if MA1 > MA2 and low[1] > MA1
    and low <= MA1 and low >= MA2 then state.long
    else if MA2 > MA1 and high[1] < MA1 and high >= MA1 and high <= MA2 then state.short else state.flat;

case long:
   
state = if maLT > maLT1 and maLT1 > maLT2 and low <= MA2 then state.flat else state.long;

case short:
  
state = if maLT < maLT1 and maLT1 < maLT2 and high >= MA2 then state.flat else state.short;
}

#plot BuyDot = if  maLT > maLT1 and maLT1 > maLT2 and state==state.long and state[1] != state.long or maLT > maLT1 and maLT1 > maLT2 and ma > ma1 and ma1 > ma2 and low <= ma1 and low > ma2  then low else Double.NaN;

#plot SellDot = if maLT < maLT1 and maLT1 < maLT2 and state==state.short and state[1] != state.short or maLT < maLT1 and maLT1 < maLT2 and ma < ma1 and ma1 < ma2 and high >= ma1 and high < ma2 then high else Double.NaN;


AssignBackgroundColor(if  maLT > maLT1 and maLT1 > maLT2 and state==state.long and state[1] != state.long or maLT > maLT1 and maLT1 > maLT2 and ma > ma1 and ma1 > ma2 and low <= ma1 and low > ma2 then color.Green else if  maLT < maLT1 and maLT1 < maLT2 and state==state.short and state[1] != state.short or maLT < maLT1 and maLT1 < maLT2 and ma < ma1 and ma1 < ma2 and high >= ma1 and high < ma2  then Color.Red else color.Current);
 
Wow this looks pretty intense. Is this the scanner or indicator that could work as scanner or ?
Fernwood,

Just take that second code and place it as a custom watchlist. Then you can easily see which symbols are meeting the pullback criteria. I would definitely add other indicators as filters like momentum, cycle, volume, support and resistance. Yet this definitely gets you in the ball park. It would not be hard to create a scan if that is what you want. I just prefer to go through watchlists. Also, make sure that your watchlist is set on the daily time frame for this custom script. It will allow you then to see trend on the weekly and a pullback on the daily. Of course you could easily alter the time frame in the script and then place your watchlist to a lower time frame. For example, in the watchlist script, you could change it to a four hour then put your watchlist at an hour.

I just now set my watchlist to the S&P 100 and it came up with 3 symbols that are meeting this criteria. You will know if it is meeting the criteria because that portion of the watchlist will be highlighted green for bullish stocks or red for bearish. The number that you see listed in that column is the EMA's current level which you are watching for a pullback to.
 
You're welcome Fernwood. I am glad that you like it; and I hope that you do well! Just to reiterate though, this is not a stand alone trading system, other variables need to be factored in otherwise you are apt to lose a lot of money! Yet with other factors like volume, support and resistance, momentum, cycles, etc., not to mention what you plan on using for stops, targets, and whether you are trading futures, forex stocks, or option spreads, duration, strike selection, etc. All of those things can make a huge difference in whether this works. But added to those things, I think this can definitely help. So again, best of luck!
 
#I also created the following code for a watchlist.

Code:
####Longterm Time Frame
input LT_TimeFrame = AggregationPeriod.Week;

input lengthLT =8;
input averageTypeLT = { Simple, default Exponential, Weighted, Wilders,  Hull};
def maLT = MovingAverage(averageType = averageTypeLT, close(period = LT_TimeFrame), lengthLT);

input lengthLT1 = 13;
input averageTypeLT1 = {Simple,default Exponential, Weighted, Wilders, Hull};

def maLT1 = MovingAverage(averageType = averageTypeLT1, close(period = LT_TimeFrame), lengthLT1);

input lengthLT2 = 21;
input averageTypeLT2 = {Simple, default Exponential, Weighted, Wilders, Hull};
def maLT2 = MovingAverage(averageType = averageTypeLT2, close(period = LT_TimeFrame), lengthLT2);

#####Shortterm Time Frame

input length =8;
input averageType = { Simple, default Exponential, Weighted, Wilders,  Hull};
def ma = MovingAverage(averageType = averageType, close, length);
input length1 = 13;
input averageType1 = {Simple,default Exponential, Weighted, Wilders, Hull};

plot ma1 = MovingAverage(averageType = averageType1, close, length1);
input length2 = 21;
input averageType2 = {Simple, default Exponential, Weighted, Wilders, Hull};
def ma2 = MovingAverage(averageType = averageType2, close, length2);


input alertonclose = yes;
def state = {default flat, long, short};

switch (state[1]) {
case flat:
    state = if MA1 > MA2 and low[1] > MA1
    and low <= MA1 and low >= MA2 then state.long
    else if MA2 > MA1 and high[1] < MA1 and high >= MA1 and high <= MA2 then state.short else state.flat;

case long:
  
state = if maLT > maLT1 and maLT1 > maLT2 and low <= MA2 then state.flat else state.long;

case short:
 
state = if maLT < maLT1 and maLT1 < maLT2 and high >= MA2 then state.flat else state.short;
}

#plot BuyDot = if  maLT > maLT1 and maLT1 > maLT2 and state==state.long and state[1] != state.long or maLT > maLT1 and maLT1 > maLT2 and ma > ma1 and ma1 > ma2 and low <= ma1 and low > ma2  then low else Double.NaN;

#plot SellDot = if maLT < maLT1 and maLT1 < maLT2 and state==state.short and state[1] != state.short or maLT < maLT1 and maLT1 < maLT2 and ma < ma1 and ma1 < ma2 and high >= ma1 and high < ma2 then high else Double.NaN;


AssignBackgroundColor(if  maLT > maLT1 and maLT1 > maLT2 and state==state.long and state[1] != state.long or maLT > maLT1 and maLT1 > maLT2 and ma > ma1 and ma1 > ma2 and low <= ma1 and low > ma2 then color.Green else if  maLT < maLT1 and maLT1 < maLT2 and state==state.short and state[1] != state.short or maLT < maLT1 and maLT1 < maLT2 and ma < ma1 and ma1 < ma2 and high >= ma1 and high < ma2  then Color.Red else color.Current);
Great job. I'm running out of watchlist column, Could you make me a watchlist column TOS script name for me to download?!
 
I've done studies like this in the past. It is too security specific to use points, but I did experiment with percentages of price proximity (i.e. within .5%, .1%, .05%, etc. of the indicator), and that seemed to work well. I would also suggest absolute value so that crosses would be counted. Sorry I don't have any recent algorithms to help you any further. Good luck.
 
May I just add that I totally agree with @rad14733 that it will be difficult to create this. You will need to define how far away price is from the MA before the move toward the MA is considered, how close (as I said above) is considered a "bounce," what angle the bounce occurs, i.e. if price is just moving "along" the MA (flat market), etc. All these considerations can be coded, but at what cost of your time, and of what benefit? Again, good luck, and please share your work so that we can see how you did it.....SD
 
Thanks for the input guys. I have messed around with the scanner on TOS no luck really. So parts of what I would like to define would continue as follows.

* A stock that has pulled back/ crossed below 1%/ bounced at least 1% above to an SMA after meeting a new 52 week high
May I just add that I totally agree with @rad14733 that it will be difficult to create this. You will need to define how far away price is from the MA before the move toward the MA is considered, how close (as I said above) is considered a "bounce," what angle the bounce occurs, i.e. if price is just moving "along" the MA (flat market), etc. All these considerations can be coded, but at what cost of your time, and of what benefit? Again, good luck, and please share your work so that we can see how you did it.....SD
Hey man thanks for
@Dirtymiguel Your term "pullback" is too subjective to be coded... You would need to logically define "pullback" in a manner that can be logically coded because all languages are based on logic, not on subjective concepts...
Hey thanks for the response. I am very new to this so be gentle.
On TOS, how can I locate a stock that is at a max 2.5% above or below a 20 SMA or a 50 SMA?
How do I scan for a stock that has hit a new 52 week high?
(this part might be a little bit to broad but I feel as if I ask this question your answer might be able to help me break down what I really should be asking) How can I scan for a stock that has recently retraced back to a SMA from a 52 week high after 5-7 days?
 
Hi guys
Im looking to create a scanner that scan pullback to 20 ma on daily for overextended or moment stocks
Thanks
@yman I moved your post here because it provides a lot of information about finding stocks that pull back to a moving average.
The suggestions given seem to fit what you want. You may have to modify the moving average length to fit your needs.

If the two pages here don't fit your needs, here is another take on a Pullback Indicator:
https://usethinkscript.com/threads/indicator-that-find-stocks-that-pullback-to-moving-average.385/

Personally, as many in this thread suggest it tends to be better to scan for getting within a certain percentage of the moving average rather than hitting it exactly. That is why this thread has so many more pages of suggestions:
https://usethinkscript.com/threads/percent-distance-between-emas-or-any-2-plots.1345/
 
Last edited:

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

Similar threads

Not the exact question you're looking for?

Start a new thread and receive assistance from our community.

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