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