jjgp's picture
Streamlit app
de3b428
import re
import time
from datetime import datetime
import pandas as pd
import plotly.graph_objects as go
import streamlit as st
from PIL import Image
from plotly.subplots import make_subplots
# Read CSV file into pandas and extract timestamp data
dfSentiment = pd.read_csv("./sentiment_data.csv", index_col=0)
dfSentiment["timestamp"] = [
datetime.strptime(dt, "%Y-%m-%d") for dt in dfSentiment["timestamp"].tolist()
]
# Multi-select columns to build chart
col_list = list(dfSentiment.columns)
r_sentiment = re.compile(".*sentiment")
sentiment_cols = [col for col in col_list if r_sentiment.match(col)]
r_post = re.compile(".*post")
post_list = [col for col in col_list if r_post.match(col)]
r_perc = re.compile(".*perc")
perc_list = list(filter(r_perc.match, col_list))
r_close = re.compile(".*close")
close_list = list(filter(r_close.match, col_list))
r_volume = re.compile(".*volume")
volume_list = list(filter(r_volume.match, col_list))
sentiment_cols = sentiment_cols + post_list
stocks_cols = perc_list + close_list + volume_list
# Config for page
st.set_page_config(
page_title="TSLA Stock Sentiment Analysis",
page_icon="✅",
layout="wide",
)
with st.sidebar:
# FourthBrain logo to sidebar
fourthbrain_logo = Image.open("./images/fourthbrain_logo.png")
st.image([fourthbrain_logo], width=300)
# Date selection filters
start_date_filter = st.date_input(
"Start Data",
min(dfSentiment["timestamp"]),
min_value=min(dfSentiment["timestamp"]),
max_value=max(dfSentiment["timestamp"]),
)
end_date_filter = st.date_input(
"End Date",
max(dfSentiment["timestamp"]),
min_value=min(dfSentiment["timestamp"]),
max_value=max(dfSentiment["timestamp"]),
)
sentiment_select = st.selectbox(
"Select Sentiment",
sentiment_cols,
index=0,
)
stock_select = st.selectbox(
"Select Stock Data",
stocks_cols,
index=0,
)
# Banner with TSLA and Reddit images
tsla_logo = Image.open("./images/tsla_logo.png")
reddit_logo = Image.open("./images/reddit_logo.png")
st.image([tsla_logo, reddit_logo], width=200)
# dashboard title
st.title("TSLA Stock Sentiment Analysis")
## dataframe filter
# start date
dfSentiment = dfSentiment[
dfSentiment["timestamp"]
>= datetime(start_date_filter.year, start_date_filter.month, start_date_filter.day)
]
# end date
dfSentiment = dfSentiment[
dfSentiment["timestamp"]
<= datetime(end_date_filter.year, end_date_filter.month, end_date_filter.day)
]
dfSentiment = dfSentiment.reset_index(drop=True)
# creating a single-element container
placeholder = st.empty()
# near real-time / live feed simulation
for i in range(1, len(dfSentiment) - 1):
# creating KPIs
last_close = dfSentiment["close"][i]
last_close_lag1 = dfSentiment["close"][i - 1]
last_sentiment = dfSentiment["sentiment_score"][i]
last_sentiment_lag1 = dfSentiment["sentiment_score"][i - 1]
with placeholder.container():
# create columns
kpi1, kpi2, kpi3 = st.columns(3)
# fill in those three columns with respective metrics or KPIs
kpi1.metric(
label="Sentiment Score",
value=round(last_sentiment, 3),
delta=round(last_sentiment_lag1, 3),
)
kpi2.metric(
label="Last Closing Price",
value=round(last_close),
delta=round(last_close - last_close_lag1),
)
# create two columns for charts
fig_col1, fig_col2 = st.columns(2)
with fig_col1:
# Add traces
fig = make_subplots(specs=[[{"secondary_y": True}]])
fig.add_trace(
go.Scatter(
x=dfSentiment["timestamp"][0:i],
y=dfSentiment[sentiment_select][0:i],
name=sentiment_select,
mode="lines",
hoverinfo="none",
)
)
if sentiment_select.startswith("perc"):
yaxis_label = "Percent Change Sentiment"
elif sentiment_select in sentiment_cols:
yaxis_label = "Sentiment Score"
elif sentiment_select in post_list:
yaxis_label = "Volume"
fig.layout.yaxis.title = yaxis_label
if stock_select.startswith("perc"):
fig.add_trace(
go.Scatter(
x=dfSentiment["timestamp"][0:i],
y=dfSentiment[stock_select][0:i],
name=stock_select,
mode="lines",
hoverinfo="none",
yaxis="y2",
)
)
fig.layout.yaxis2.title = "% Change Stock Price ($US)"
elif stock_select == "volume":
fig.add_trace(
go.Scatter(
x=dfSentiment["timestamp"][0:i],
y=dfSentiment[stock_select][0:i],
name=stock_select,
mode="lines",
hoverinfo="none",
yaxis="y2",
)
)
fig.layout.yaxis2.title = "Shares Traded"
else:
fig.add_trace(
go.Scatter(
x=dfSentiment["timestamp"][0:i],
y=dfSentiment[stock_select][0:i],
name=stock_select,
mode="lines",
hoverinfo="none",
yaxis="y2",
)
)
fig.layout.yaxis2.title = "Stock Price ($USD)"
fig.layout.xaxis.title = "Timestamp"
# write the figure throught streamlit
st.write(fig)
st.markdown("### Detailed Data View")
st.dataframe(dfSentiment.iloc[:, 1:][0:i])
time.sleep(1)