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) | |