How To Scan Mark Minervini’s Trend Template Using Python

mei 4, 2020 | Trading

So I’m a big fan of Mark Minervini and call myself a student of his work.

I’ve read all his books multiple times. And even summarize them every now and then for myself to dive really deep into the content.

Then I don’t always have to read his writing but can read my own understanding of it.

In my trading routine I’ve incorporated checking stocks that meet his Trend Template criteria.

I used to do that in Think or Swim as explained earlier in this post. The downside of that is that I’m not able to use the IBD rating in scanning in Think or Swim.

To further improve my trading analysis I’ve started to look into programming Python lately. Since I’m in an IT job I do already have a lot of technical feeling that makes adopting it somewhat easier.

Following you’ll find the exact Python code for Mark Minervini’s Trend Template. It uses an export of IBD’s new Stock Screener as import and than scans all the stocks on the criteria.

After the scan it outputs the stocks that meet all criteria in an Excel including some additional useful data rows.

I’m always looking at improving it and already got some things on my to-do list.

  1. import / export using Google Drive instead of Excel
  2. Including some additional output e.g. pivot points that can be used as buy point
  3. Export stocks that meeting a subset of the criteria.

Since I use Google Drive for most of my file storage I prefer that over Excel. It also add some flexibility to run the program from other machines as well.

By including more output information I can cut out some more manual actions out of my routine. Off course I’ll always do the analysis manually afterwards because I think it is important to get more feeling and understanding of the charts than only running some code to validate.

Some of the best super performance stocks don’t match all criteria. They might lack one, or more, of the criteria but still turn out to become big movers. Currently I would miss them by only looking at the output that currently only shows stocks that match all.

These changes will help me further improve my trading.

Mark Minervini Books

 

The Trend Template

In Mark’s first book; Trade Like A Stock Market Wizard he has published his Trend Template.

He uses that to filter out stocks using some technical criteria before doing an additional research on them.

The following rules are used:

  1. The current stock price is above both the 150-day and 200-day moving average
  2. The 150-day moving average is above the 200-day moving average
  3. The 200-day moving average is trending up for at least 1 month
  4. The 50-day moving average is above both the 150-day and 200-day moving average
  5. The current stock price is trading above the 50-day moving average
  6. The current stock price is at least 30% above it’s 52-week low
  7. The current stock price is within at least 25% of it’s 52-week high
  8. The relative strength ranking (in IBD) is no less than 70, preferably in the 80’s or 90’s

They link to the exact Python code that validates the criteria.

At the bottom of this post you can download the python file itself.

 

The Trend Template in Python Code

import datetime as dt
import pandas as pd
from pandas_datareader import data as pdr
import yfinance as yf
from tkinter import Tk
from tkinter.filedialog import askopenfilename
import os
from pandas import ExcelWriter

yf.pdr_override()
start =dt.datetime(2018,12,1)
now = dt.datetime.now()

root = Tk()
ftypes = [(".xlsm","*.xlsx",".xls")]
ttl = "Title"
dir1 = 'C:\\'
filePath = askopenfilename(filetypes = ftypes, initialdir = dir1, title = ttl)
#Pop-up screen where you can select the input file you want to scan

stocklist = pd.read_excel(filePath)
stocklist=stocklist.head()

exportList= pd.DataFrame(columns=['Stock', "RS_Rating", "50 Day MA", "150 Day Ma", "200 Day MA", "52 Week Low", "52 week High"])

for i in stocklist.index:
stock=str(stocklist["Symbol"][i])
RS_Rating=stocklist["RS Rating"][i]

try:
df = pdr.get_data_yahoo(stock, start, now)

#Define Trend Template criteria
smaUsed=[50,150,200]

for x in smaUsed:
sma=x
df["SMA_"+str(sma)]=round(df.iloc[:,4].rolling(window=sma).mean(),2)

currentClose=df["Adj Close"][-1]
moving_average_50=df["SMA_50"][-1]
moving_average_150=df["SMA_150"][-1]
moving_average_200=df["SMA_200"][-1]
low_of_52week=min(df["Adj Close"][-260:])
high_of_52week=max(df["Adj Close"][-260:])
try:
moving_average_200_20 = df["SMA_200"][-20]

except Exception:
moving_average_200_20=0

#Condition 1: Current Price > 150 SMA and > 200 SMA
if(currentClose>moving_average_150>moving_average_200):
cond_1=True
else:
cond_1=False

#Condition 2: 150 SMA and > 200 SMA
if(moving_average_150>moving_average_200):
cond_2=True
else:
cond_2=False

#Condition 3: 200 SMA trending up for at least 1 month
if(moving_average_200>moving_average_200_20):
cond_3=True
else:
cond_3=False

#Condition 4: 50 SMA> 150 SMA and 50 SMA> 200 SMA
if(moving_average_50>moving_average_150>moving_average_200):
#print("Condition 4 met")
cond_4=True
else:
#print("Condition 4 not met")
cond_4=False

#Condition 5: Current Price > 50 SMA
if(currentClose>moving_average_50):
cond_5=True
else:
cond_5=False

#Condition 6: Current Price is at least 30% above 52 week low
if(currentClose>=(1.3*low_of_52week)):
cond_6=True
else:
cond_6=False

#Condition 7: Current Price is within 25% of 52 week high
if(currentClose>=(.75*high_of_52week)):
cond_7=True
else:
cond_7=False

#Condition 8: IBD RS rating >70 and the higher the better
#Need IBD data  tables including the RS rating for this, or export stocks form IBD Stock Screener with RS >70

if(RS_Rating>70):
cond_8=True
else:
cond_8=False

if(cond_1 and cond_2 and cond_3 and cond_4 and cond_5 and cond_6 and cond_7 and cond_8):
exportList = exportList.append({'Stock': stock, "RS_Rating": RS_Rating, "50 Day MA": moving_average_50, "150 Day Ma": moving_average_150, "200 Day MA": moving_average_200, "52 Week Low": low_of_52week, "52 week High": high_of_52week}, ignore_index=True)
except Exception:
print("No data on "+stock)

print(exportList)

newFile=os.path.dirname(filePath)+"/ScreenOutput.xlsx"

writer= ExcelWriter(newFile)
exportList.to_excel(writer,"Sheet1")
writer.save()

 

Click here to download the Python file