bohmian's picture
Update app.py
58d5310
import streamlit as st # for overall GUI
from streamlit_calendar import calendar # to show calendar
from dateutil.relativedelta import relativedelta # for addition to dates
import datetime
import os # for extracting environment variable
from urllib.request import urlopen # for getting data from FMP API
import json # for parsing data from FMP API
# For parsing data from API from JSON to a Python Dictionary
def get_jsonparsed_data(url):
response = urlopen(url)
data = response.read().decode("utf-8")
return json.loads(data)
# Get FMP API stored as environment variable
apiKey = os.environ['FMP_API_KEY']
# Financialmodelingprep (FMP) api base url
base_url = "https://financialmodelingprep.com/api/v3/"
# Get today's date and add 3 months to it
# Convert both today's date and the 3 months later date to strings (for input into API endpoint URL later)
# This is the date range within which we want to get our earnings dates
today = datetime.datetime.today()
today_string = today.strftime('%Y-%m-%d')
future_string = (today + relativedelta(months=3)).strftime('%Y-%m-%d')
# This is the full API endpoint to get the earnings dates from today to 6 months after
url = f"{base_url}earning_calendar?from={today_string}&to={future_string}&apikey={apiKey}"
# This decorator ensures that the call to the FMP API will only run once at the start of this app
# The data returned will be cached after the function runs
# Without this decorator, the API will be called each time you click something in the streamlit app
@st.cache_resource
def get_earnings_dates(url):
events = get_jsonparsed_data(url)
return events
events = get_earnings_dates(url)
with st.sidebar:
st.title("Stock Earnings πŸ“† App")
st.header("Choose Tickers of Interest")
#tickers = ['GOOG', 'META', 'TSLA', 'NET', 'V', 'MA', 'BA', 'C']
# For users to enter tickers of interest
tickers_string = st.text_area('Enter all stock tickers to be included in calendar, separated by commas \
e.g. "MA, META, V, AMZN, JPM, BA"',
value = 'GOOG, META, AAPL, MSFT, NVDA, NFLX, V, MA, AMZN, TSLA, JPM, BAC, BA, MMM, NET, C, CRM, PLTR, BABA').upper()
st.write("Note: Earnings dates are shown for the next 3 months")
st.write('')
st.markdown("## [Explanatory Article](https://medium.datadriveninvestor.com/build-a-stock-earnings-calendar-of-your-favorite-stocks-in-python-36bba1950a61)")
st.write('')
# Where the data came from
st.markdown("## [Financial Modeling Prep API](https://intelligence.financialmodelingprep.com/pricing-plans?couponCode=damianboh&utm_campaign=damianboh&utm_medium=blog&utm_source=medium)\
\n\nEarnings Dates for all tickers are obtained from the FinancialModelingPrep API, feel free to sign up\
[here](https://intelligence.financialmodelingprep.com/pricing-plans?couponCode=damianboh&utm_campaign=damianboh&utm_medium=blog&utm_source=medium)\
if you wish.")
# Parse user input into a list
tickers_string = tickers_string.replace(' ', '')
tickers = tickers_string.split(',')
# Converts the parsed json from FMP API into a list of events to be passed into streamlit_calendar
calendar_events = []
for event in events:
if event['symbol'] in tickers:
calendar_event = {}
calendar_event['title'] = event['symbol']
if event['time'] == 'bmo': # before market opens, add sunrise symbol
calendar_event['title'] = 'β˜€ ' + calendar_event['title']
elif event['time'] == 'amc': # after market closes, add sunset symbol
calendar_event['title'] = 'πŸŒ… ' + calendar_event['title']
calendar_event['start'] = event['date']
calendar_events.append(calendar_event)
st.header("Stock Earnings Calendar πŸ“†")
calendar_options = {
"editable": "true",
"navLinks": "true",
"headerToolbar": {
"left": "today prev,next",
"center": "title",
"right": "dayGridDay,dayGridWeek,dayGridMonth,listMonth",
},
#"initialDate": today.strftime('%Y-%m-%d'),
"initialView": "dayGridMonth"
}
custom_css="""
.fc-event-past {
opacity: 0.8;
}
.fc-event-time {
font-style: italic;
}
.fc-event-title {
font-weight: 700;
}
.fc-toolbar-title {
font-size: 2rem;
}
"""
calendar = calendar(events=calendar_events, options=calendar_options, custom_css=custom_css)