An app that allows the user to input a list of interested stock tickers and stores them in a database and then notifies the user when any of the stocks in the database hits 52 week, 6 month or 1 month highs and lows.
To upload files, please first save the app
import streamlit as st
import yfinance as yf
import pandas as pd
from datetime import datetime, timedelta
from sqlalchemy import create_engine, Column, String, Float, DateTime
from sqlalchemy.orm import DeclarativeBase, Session
import time
# Database setup
class Base(DeclarativeBase):
pass
class StockAlert(Base):
__tablename__ = 'stock_alerts'
ticker = Column(String, primary_key=True)
last_high_52w = Column(Float)
last_high_6m = Column(Float)
last_high_1m = Column(Float)
last_low_52w = Column(Float)
last_low_6m = Column(Float)
last_low_1m = Column(Float)
last_updated = Column(DateTime)
engine = create_engine('sqlite:///stocks.sqlite')
Base.metadata.create_all(bind=engine)
def get_stock_data(ticker):
try:
stock = yf.Ticker(ticker)
hist_52w = stock.history(period="1y")
hist_6m = stock.history(period="6mo")
hist_1m = stock.history(period="1mo")
current_price = hist_52w['Close'][-1]
data = {
'high_52w': hist_52w['High'].max(),
'high_6m': hist_6m['High'].max(),
'high_1m': hist_1m['High'].max(),
'low_52w': hist_52w['Low'].min(),
'low_6m': hist_6m['Low'].min(),
'low_1m': hist_1m['Low'].min(),
'current_price': current_price
}
return data
except Exception as e:
st.error(f"Error fetching data for {ticker}: {str(e)}")
return None
st.title("Stock Price Alerts")
# Input for new stock ticker
new_ticker = st.text_input("Add new stock ticker (e.g., AAPL)").upper()
if st.button("Add Ticker"):
if new_ticker:
data = get_stock_data(new_ticker)
if data:
with Session(engine) as session:
alert = StockAlert(
ticker=new_ticker,
last_high_52w=data['high_52w'],
last_high_6m=data['high_6m'],
last_high_1m=data['high_1m'],
last_low_52w=data['low_52w'],
last_low_6m=data['low_6m'],
last_low_1m=data['low_1m'],
last_updated=datetime.now()
)
session.merge(alert)
session.commit()
st.success(f"Added {new_ticker} to watchlist!")
# Display current watchlist and alerts
st.subheader("Your Watchlist")
with Session(engine) as session:
stocks = session.query(StockAlert).all()
if not stocks:
st.info("No stocks in watchlist. Add some tickers above!")
else:
alerts = []
for stock in stocks:
data = get_stock_data(stock.ticker)
if data:
current_price = data['current_price']
# Check for new highs
if current_price > stock.last_high_52w:
alerts.append(f"🔔 {stock.ticker} hit new 52-week high: ${current_price:.2f}")
if current_price > stock.last_high_6m:
alerts.append(f"🔔 {stock.ticker} hit new 6-month high: ${current_price:.2f}")
if current_price > stock.last_high_1m:
alerts.append(f"🔔 {stock.ticker} hit new 1-month high: ${current_price:.2f}")
# Check for new lows
if current_price < stock.last_low_52w:
alerts.append(f"⚠️ {stock.ticker} hit new 52-week low: ${current_price:.2f}")
if current_price < stock.last_low_6m:
alerts.append(f"⚠️ {stock.ticker} hit new 6-month low: ${current_price:.2f}")
if current_price < stock.last_low_1m:
alerts.append(f"⚠️ {stock.ticker} hit new 1-month low: ${current_price:.2f}")
# Update the database with new values
stock.last_high_52w = max(stock.last_high_52w, current_price)
stock.last_high_6m = max(stock.last_high_6m, current_price)
stock.last_high_1m = max(stock.last_high_1m, current_price)
stock.last_low_52w = min(stock.last_low_52w, current_price)
stock.last_low_6m = min(stock.last_low_6m, current_price)
stock.last_low_1m = min(stock.last_low_1m, current_price)
stock.last_updated = datetime.now()
session.merge(stock)
session.commit()
# Display alerts
if alerts:
st.subheader("Recent Alerts")
for alert in alerts:
st.markdown(alert)
# Display watchlist table
watchlist_data = []
for stock in stocks:
data = get_stock_data(stock.ticker)
if data:
watchlist_data.append({
"Ticker": stock.ticker,
"Current Price": f"${data['current_price']:.2f}",
"52w High": f"${stock.last_high_52w:.2f}",
"52w Low": f"${stock.last_low_52w:.2f}",
"Last Updated": stock.last_updated.strftime("%Y-%m-%d %H:%M:%S")
})
if watchlist_data:
st.table(pd.DataFrame(watchlist_data))
# Add a button to remove stocks
if stocks:
st.subheader("Remove Stocks")
stock_to_remove = st.selectbox("Select stock to remove", [stock.ticker for stock in stocks])
if st.button("Remove Selected Stock"):
with Session(engine) as session:
session.query(StockAlert).filter(StockAlert.ticker == stock_to_remove).delete()
session.commit()
st.success(f"Removed {stock_to_remove} from watchlist!")
st.rerun()
# Auto-refresh every 5 minutes
time.sleep(300)
st.rerun()
Hi! I can help you with any questions about Streamlit and Python. What would you like to know?