Spaces:
Runtime error
Runtime error
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 | |
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) | |