Daily stock dip detector
This notebook will determine whether stocks in your portfolio are in a "dip" by comparing the prices to 200 day moving average, and send you an email with the result afterwards. Note that this does not take into account market cap (stock splits, dilutions), so be careful! (and, please don't consider this an investment advice.)
How to use it?
The best way is to duplicate this notebook (it's free), update credentials and schedule it on weekly or daily basic.
Fetch data and compare to 200 day moving average
# List of tickers in our portfolio
tickers = ['GOOGL', 'BABA', 'STOR', 'MSFT', 'BRK-B', 'VZ', 'CSCO']
from pandas_datareader import data
from datetime import datetime
end = datetime.now()
start = datetime(end.year-1, end.month, end.day)
results = []
for ticker in tickers:
df = data.DataReader(ticker, 'yahoo', start, end)
# Let's calculate last 200d moving average
last_200d = df.tail(200)
last_200d_average = last_200d["Close"].mean()
current_price = df.tail(1).iloc[0]["Close"]
diff = current_price - last_200d_average
diff_relative = (diff / current_price) * 100
if diff > 0:
results.append({ 'ticker': ticker, 'diff_relative': diff_relative })
else:
results.append({ 'ticker': ticker, 'diff_relative': diff_relative })
results
Send emails
Replace following with a list of email addresses to which you would like to send the notification.
emails = ['youremail@email.com', 'anotheremail@email.com']
Create email content
from jinja2 import Environment, PackageLoader, select_autoescape
env = Environment()
template = env.from_string("""
<html>
<body>
Hello! There is/are {{dip_count}} dip(s) in your portfolio comparing to 200 day moving average.<br>
<ul>
{% for result in results | sort(attribute='diff_relative') %}
<li><b>{{ result.ticker }}</b> {{"%.2f"|format(result.diff_relative)}}%</li>
{% endfor %}
</ul>
</body>
</html>
""")
p = filter(lambda res: (res['diff_relative'] < 0), results)
dip_count = len(list(p))
html = template.render(dip_count=dip_count, results=results)
print(html)
<html>
<body>
Hello! There is/are 2 dip(s) in your portfolio comparing to 200 day moving average.<br>
<ul>
<li><b>BABA</b> -12.79%</li>
<li><b>VZ</b> -0.39%</li>
<li><b>MSFT</b> 11.30%</li>
<li><b>CSCO</b> 12.89%</li>
<li><b>STOR</b> 15.20%</li>
<li><b>BRK-B</b> 17.79%</li>
<li><b>GOOGL</b> 23.36%</li>
</ul>
</body>
</html>
Send emails
import smtplib, ssl
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
# Note: secure web apps login needs to be turned off in Google settings. For production usage, replace this with OAuth flow.
# Enable the setting here: https://myaccount.google.com/u/2/lesssecureapps
smtp_server = "smtp.gmail.com"
port = 587 # For starttls
sender_email = "your-google-email-here"
password = "password-here" # Replace this with a real value
# Create a secure SSL context
context = ssl.create_default_context()
message = MIMEMultipart("alternative")
message["Subject"] = "Stock dip detector"
message["From"] = sender_email
# Note: we should also include a text version for email. For the simplicity of this, I omit this for now.
part = MIMEText(html, "html")
message.attach(part)
try:
server = smtplib.SMTP(smtp_server, port)
server.starttls(context=context)
server.login(sender_email, password)
server.sendmail(sender_email, emails, message.as_string())
except Exception as e:
# Throw the exception, so the scheduled run is stopped and we recieve a notification in our inbox.
raise e
finally:
server.quit()
Last but not least, don't forget to schedule the notebook. Here in Deepnote, you can do it by simply clicking on the Schedule button. Duplicate the notebook and try it out for free!