truevis commited on
Commit
182c84d
1 Parent(s): b077ed8

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +201 -2
app.py CHANGED
@@ -1,4 +1,203 @@
1
  import streamlit as st
 
 
 
 
2
 
3
- x = st.slider('Select a value')
4
- st.write(x, 'squared is', x * x)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  import streamlit as st
2
+ import yfinance as yf
3
+ import pandas as pd
4
+ import matplotlib.pyplot as plt
5
+ import streamlit.components.v1 as components
6
 
7
+ # Set the page to wide mode and specify a title
8
+ st.set_page_config(layout="wide", page_title="Stock Insight Explorer", page_icon=":chart_with_upwards_trend:")
9
+
10
+ # Display the application title in the app itself
11
+ st.title('Stock Insight Explorer: Visual Analytics & Dividend Overview')
12
+ # Input field for stock symbol
13
+ stock_symbol = st.text_input('Enter Stock Symbol', value='JEPI')
14
+
15
+ # Fetch stock data
16
+ stock_data = yf.Ticker(stock_symbol)
17
+
18
+ # Get historical data for the past year
19
+ end_date = pd.Timestamp.today()
20
+ start_date = end_date - pd.DateOffset(years=1)
21
+ historical_data = stock_data.history(start=start_date, end=end_date)
22
+
23
+ # Display company name and current stock price in bold
24
+ company_name = stock_data.info['longName']
25
+ current_price = historical_data['Close'].iloc[-1]
26
+ # st.markdown(f"**Company Name:** {company_name}")
27
+ # https://finance.yahoo.com/quote/JEPQ?.tsrc=fin-srch
28
+ company_url = f"https://finance.yahoo.com/quote/{stock_symbol}?.tsrc=fin-srch"
29
+
30
+ # Use HTML anchor tag to create a hyperlink
31
+ st.markdown(f"**Company Name:** <a href='{company_url}' target='_blank'>{company_name}</a>", unsafe_allow_html=True)
32
+
33
+ st.markdown(f"**Current Price:** ${current_price:.2f}")
34
+
35
+ # Creating 3 columns for the charts
36
+ col1, col2, col3, col4 = st.columns(4)
37
+
38
+
39
+ # Closing prices chart
40
+ with col1:
41
+ st.subheader('Closing Prices Over The Past Year')
42
+ st.line_chart(historical_data['Close'])
43
+
44
+ # Volume of stock trades chart
45
+ with col2:
46
+ st.subheader('Volume of Stock Trades Over The Past Year')
47
+ st.bar_chart(historical_data['Volume'])
48
+
49
+ # Calculate 20 day and 50 day moving averages
50
+ historical_data['20 Day MA'] = historical_data['Close'].rolling(window=20).mean()
51
+ historical_data['50 Day MA'] = historical_data['Close'].rolling(window=50).mean()
52
+
53
+ # Line chart for closing price, 20 day MA, and 50 day MA
54
+ with col3:
55
+ st.subheader('Closing Price and Moving Averages')
56
+ plt.figure(figsize=(10, 5))
57
+ plt.plot(historical_data.index, historical_data['Close'], label='Close Price')
58
+ plt.plot(historical_data.index, historical_data['20 Day MA'], label='20 Day MA')
59
+ plt.plot(historical_data.index, historical_data['50 Day MA'], label='50 Day MA')
60
+ plt.legend()
61
+ plt.xlabel('Date')
62
+ plt.ylabel('Price')
63
+ plt.title('Closing Price, 20 Day MA, and 50 Day MA')
64
+ st.pyplot(plt)
65
+
66
+ # Get the dividend data
67
+ # Assuming stock_data is your Ticker object from yfinance
68
+ dividends = stock_data.dividends
69
+
70
+ # Check if there are any dividends
71
+ if not dividends.empty:
72
+ last_dividend_value = dividends.iloc[-1] # Get the last dividend value from the dividends history
73
+ else:
74
+ # Fallback to the lastDividendValue from the .info attribute if no historical dividends are found
75
+ last_dividend_value = stock_data.info.get('lastDividendValue', 0)
76
+
77
+ with col4:
78
+ st.subheader('Dividends')
79
+
80
+ markdown_output = "" # Initialize an empty string to accumulate messages
81
+
82
+ # Ensure dividends.index is in the correct format
83
+ dividends.index = pd.to_datetime(dividends.index).date
84
+
85
+ if not dividends.empty:
86
+ plt.figure(figsize=(10, 5))
87
+ dividends.plot(kind='bar')
88
+ plt.title(f'Dividends of {stock_symbol} Over Time')
89
+ plt.ylabel('Dividend Amount')
90
+ plt.xlabel('Date')
91
+ plt.xticks(rotation=45)
92
+ plt.tight_layout()
93
+ st.pyplot(plt)
94
+
95
+ # Calculate total annual dividends
96
+ today = pd.to_datetime("today")
97
+ last_year_dividends = dividends.loc[dividends.index > (today - pd.DateOffset(years=1)).date()]
98
+ total_annual_dividends = last_year_dividends.sum()
99
+
100
+ if current_price and current_price > 0:
101
+ annual_dividend_yield = (total_annual_dividends / current_price) * 100
102
+ markdown_output += f"**Annual Dividend Yield:** {annual_dividend_yield:.2f}%.\n"
103
+ else:
104
+ markdown_output += "Current price not available. Cannot calculate annual dividend yield.\n"
105
+ else:
106
+ markdown_output += "This stock does not have any dividend data available.\n"
107
+ total_annual_dividends = 0 # Define it as 0 if there are no dividends
108
+
109
+ if current_price and current_price > 0 and last_dividend_value:
110
+ dividend_yield = (last_dividend_value / current_price) * 100
111
+ markdown_output += f"**Last Dividend Yield:** {dividend_yield:.2f}%, ${last_dividend_value:.2f} per share."
112
+ else:
113
+ markdown_output += "Cannot calculate last dividend yield."
114
+
115
+ # Display all collected information in one markdown output
116
+
117
+ st.markdown(markdown_output, unsafe_allow_html=True)
118
+
119
+
120
+
121
+
122
+
123
+ # components.iframe("https://duckduckgo.com/?q=ZIM&va=i&t=hd&iar=news&df=w&ia=news")
124
+
125
+ # components.iframe("https://news.google.com/rss/search?q=ZIM&hl=en-US&gl=US&ceid=US%3Aen", height=800, scrolling=True)
126
+ # components.iframe("https://truevis.com", height=800, scrolling=True)
127
+
128
+
129
+ from unicodedata import normalize
130
+ from bs4 import BeautifulSoup
131
+ from feedparser import parse as parse_feed
132
+
133
+ def flatten_unicode_keys(entry_properties):
134
+ """Ensures passing unicode keywords to **kwargs."""
135
+ new_properties = {}
136
+ for key, value in entry_properties.items():
137
+ key_str = key.decode('utf-8') if isinstance(key, bytes) else key
138
+ new_key = normalize('NFKD', key_str).encode('ascii', 'ignore').decode('ascii') # Decode the bytes object to string
139
+ new_properties[new_key] = value
140
+ return new_properties
141
+
142
+ TEMPLATE = """
143
+ <h2 class='title'>{title}</h2>
144
+ <a class='link' href='{link}'>{title}</a>
145
+ <span class='description'>{description}</span>
146
+ """
147
+
148
+ def entry_to_html(entry_id, **kwargs):
149
+ new_kwargs = flatten_unicode_keys(kwargs)
150
+ new_kwargs.setdefault('title', 'No title')
151
+ new_kwargs.setdefault('link', 'No link')
152
+ new_kwargs.setdefault('description', '')
153
+ accordion_item = f"""
154
+ <div class="card">
155
+ <div class="card-header" id="heading{entry_id}">
156
+ <h5 class="mb-0">
157
+ <button class="btn btn-link" data-toggle="collapse" data-target="#collapse{entry_id}" aria-expanded="true" aria-controls="collapse{entry_id}">
158
+ {new_kwargs['title']}
159
+ </button>
160
+ </h5>
161
+ </div>
162
+ <div id="collapse{entry_id}" class="collapse {'show' if entry_id == 0 else ''}" aria-labelledby="heading{entry_id}" data-parent="#accordion">
163
+ <div class="card-body">
164
+ <a href='{new_kwargs['link']}' target='_blank'>{new_kwargs['title']}</a>
165
+ <p>{new_kwargs['description']}</p>
166
+ </div>
167
+ </div>
168
+ </div>
169
+ """
170
+ return accordion_item
171
+
172
+ def convert_feed_to_accordion(url):
173
+ feed = parse_feed(url)
174
+ accordion_html = '<div id="accordion">'
175
+ for i, entry in enumerate(feed.entries):
176
+ accordion_html += entry_to_html(i, **entry)
177
+ accordion_html += '</div>'
178
+ return accordion_html
179
+
180
+ # Bootstrap CSS and JS must be included in the output HTML to style the accordion correctly
181
+ bootstrap_includes = """
182
+ <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css">
183
+ <script src="https://code.jquery.com/jquery-3.2.1.slim.min.js"></script>
184
+ <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js"></script>
185
+ """
186
+
187
+ # Fetch and display the accordion
188
+ url = f"https://news.google.com/rss/search?q={stock_symbol}&hl=en-US&gl=US&ceid=US%3Aen"
189
+ # print(url)
190
+ feed_accordion_html = bootstrap_includes + convert_feed_to_accordion(url)
191
+ st.markdown(f"Latest news on **{stock_symbol}**")
192
+ components.html(feed_accordion_html, height=800, scrolling=True)
193
+
194
+ # def convert_feed_to_raw_data(url):
195
+ # feed = parse_feed(url)
196
+ # raw_data = [entry for entry in feed.entries]
197
+ # return raw_data
198
+
199
+ # Fetch and display the raw RSS data
200
+ # url = f"https://news.google.com/rss/search?q={stock_symbol}&hl=en-US&gl=US&ceid=US%3Aen"
201
+ # raw_data = convert_feed_to_raw_data(url)
202
+ # print(raw_data)
203
+ # st.write(raw_data)