Bayhaqy commited on
Commit
cfa93ad
β€’
1 Parent(s): 4170b86

Upload 3 files

Browse files
app.py CHANGED
@@ -1,518 +1,11 @@
1
- %%writefile app.py
2
- import pandas as pd
3
- import numpy as np
4
- import matplotlib.pyplot as plt
5
- import pandas_datareader.data as web
6
- import datetime as dt
7
- import yfinance as yf
8
- from sklearn.preprocessing import MinMaxScaler
9
- from keras.models import load_model
10
  import streamlit as st
11
- import streamlit as st
12
- import plotly.graph_objects as go
13
- import base64
14
- import plotly.express as px
15
- from datetime import datetime
16
-
17
-
18
- ## ............................................... ##
19
- # Set page configuration (Call this once and make changes as needed)
20
- st.set_page_config(page_title='Regression Stocks Prediction', layout='wide', page_icon=':rocket:')
21
-
22
- ## ............................................... ##
23
- # Add a dictonary of stock tickers and their company names and make a drop down menu to select the stock to predict
24
- stock_tickers = {
25
- "MAPI":"MAPI.JK","MAP Aktif": "MAPA.JK","MAP Boga": "MAPB.JK",
26
- "Tesla": "TSLA", "Apple": "AAPL", "Microsoft": "MSFT", "Google": "GOOGL",
27
- "Meta": "META", "Amazon": "AMZN", "Netflix": "NFLX", "Alphabet": "GOOG",
28
- "Nvidia": "NVDA", "Paypal": "PYPL", "Adobe": "ADBE", "Intel": "INTC",
29
- "Cisco": "CSCO", "Comcast": "CMCSA", "Pepsi": "PEP", "Costco": "COST",
30
- "Starbucks": "SBUX", "Walmart": "WMT", "Disney": "DIS", "Visa": "V",
31
- "Mastercard": "MA", "Boeing": "BA", "IBM": "IBM", "McDonalds": "MCD",
32
- "Nike": "NKE", "Exxon": "XOM", "Chevron": "CVX", "Verizon": "VZ",
33
- "AT&T": "T", "Home Depot": "HD", "Salesforce": "CRM", "Oracle": "ORCL",
34
- "Qualcomm": "QCOM", "AMD": "AMD"
35
- }
36
-
37
- st.sidebar.title("Stock Option")
38
- # Custom CSS to change the sidebar color
39
- sidebar_css = """
40
- <style>
41
- div[data-testid="stSidebar"] > div:first-child {
42
- width: 350px; # Adjust the width as needed
43
- background-color: #FF6969;
44
- }
45
- </style>
46
- """
47
-
48
- # User Input
49
- #default_index = stock_tickers.keys().index("MAPI.JK") if "MAPI.JK" in stock_tickers.keys() else 0
50
- #st.markdown(sidebar_css, unsafe_allow_html=True)
51
- #user_input = st.sidebar.selectbox("Select a Stock", list(stock_tickers.keys()), index=default_index , key="main_selectbox")
52
- #stock_name = user_input
53
- #user_input = stock_tickers[user_input]
54
-
55
- user_input = st.sidebar.text_input("Select a Stock", "MAPI.JK")
56
-
57
- # User input for start and end dates using calendar widget
58
- start_date = st.sidebar.date_input("Select start date:", datetime(2023, 1, 1))
59
- end_date = st.sidebar.date_input("Select end date:", datetime(2023, 12, 1))
60
-
61
-
62
- st.sidebar.markdown("----")
63
- st.sidebar.markdown("Β© 2023 Stocks Prediction App")
64
- st.sidebar.markdown("----")
65
- st.sidebar.markdown("Example Stock Tickers")
66
- st.sidebar.markdown(stock_tickers)
67
-
68
- ## ............................................... ##
69
- # Page Title and Description
70
- st.title("Stock Price Analysis and Prediction")
71
- st.write("Created by Bayhaqy")
72
- st.write("Using Dataset MAPI to Train and Test the Model")
73
-
74
- ## ............................................... ##
75
-
76
- # Try to fetch information from Yahoo Finance
77
- try:
78
- stock_info = yf.Ticker(user_input).info
79
-
80
- # Check if the 'longName' key exists in stock_info
81
- if 'longName' in stock_info:
82
- stock_name = stock_info['longName']
83
- else:
84
- stock_name = user_input
85
-
86
- # Fetch the latest news using yfinance
87
- news_data = yf.Ticker(user_input).news
88
-
89
- # Create a Streamlit app
90
- title = f"<h1 style='color: red; font-size: 25px; text-align: center; '>{stock_name}'s Stock Fundamental Analysis</h1>"
91
- st.markdown(title, unsafe_allow_html=True)
92
-
93
- with st.expander("See Details"):
94
- ## ............................................... ##
95
- # Display the retrieved stock information
96
- if 'longName' in stock_info:
97
- company_name = stock_info['longName']
98
- st.write(f"Company Name: {company_name}")
99
- else:
100
- st.write("Company name information not available for this stock.")
101
-
102
- if 'industry' in stock_info:
103
- Industry = stock_info['industry']
104
- st.write(f"Industry: {Industry}")
105
- else:
106
- st.write("Industry information not available for this stock.")
107
-
108
- if 'sector' in stock_info:
109
- Sector = stock_info['sector']
110
- st.write(f"Sector: {Sector}")
111
- else:
112
- st.write("Sector information not available for this stock.")
113
-
114
- if 'website' in stock_info:
115
- Website = stock_info['website']
116
- st.write(f"Sector: {Website}")
117
- else:
118
- st.write("Website information not available for this stock.")
119
-
120
- if 'marketCap' in stock_info:
121
- MarketCap = stock_info['marketCap']
122
- st.write(f"Market Cap: {MarketCap}")
123
- else:
124
- st.write("Market Cap information not available for this stock.")
125
-
126
- if 'previousClose' in stock_info:
127
- PreviousClose = stock_info['previousClose']
128
- st.write(f"Previous Close: {PreviousClose}")
129
- else:
130
- st.write("Previous Close information not available for this stock.")
131
-
132
- if 'dividendYield' in stock_info:
133
- dividend_yield = stock_info['dividendYield'] * 100 # Convert to percentage
134
- st.write(f"Dividend Yield: {dividend_yield:.2f}%")
135
- else:
136
- st.write("Dividend Yield information not available for this stock.")
137
-
138
- ## ............................................... ##
139
- # Display financial metrics
140
- st.subheader('Financial Metrics')
141
- if 'trailingEps' in stock_info:
142
- trailing_eps = stock_info['trailingEps']
143
- st.write(f"Earnings Per Share (EPS): {trailing_eps:.2f}")
144
- else:
145
- st.write("Earnings Per Share (EPS) information not available for this stock.")
146
-
147
- if 'trailingPE' in stock_info:
148
- trailing_pe = stock_info['trailingPE']
149
- st.write(f"Price-to-Earnings (P/E) Ratio: {trailing_pe:.2f}")
150
- else:
151
- st.write("Price-to-Earnings (P/E) Ratio information not available for this stock.")
152
-
153
- if 'priceToSalesTrailing12Months' in stock_info:
154
- priceToSalesTrailing_12Months = stock_info['priceToSalesTrailing12Months']
155
- st.write(f"Price-to-Sales (P/S) Ratio: {priceToSalesTrailing_12Months:.2f}")
156
- else:
157
- st.write("Price-to-Sales (P/S) Ratio information not available for this stock.")
158
-
159
- if 'priceToBook' in stock_info:
160
- price_ToBook = stock_info['priceToBook']
161
- st.write(f"Price-to-Book (P/B) Ratio: {price_ToBook:.2f}")
162
- else:
163
- st.write("Price-to-Book (P/B) Ratio information not available for this stock.")
164
-
165
- ## ............................................... ##
166
- # Display more detailed information
167
- st.subheader('Company Summary')
168
- if 'longBusinessSummary' in stock_info:
169
- LongBusinessSummary = stock_info['longBusinessSummary']
170
- st.write(f"Company Summary: {LongBusinessSummary}")
171
- else:
172
- st.write("Company Summary information not available for this stock.")
173
-
174
- ## ............................................... ##
175
- # Display information about company officers
176
- st.subheader('Company Officers')
177
- if 'fullTimeEmployees' in stock_info:
178
- FullTimeEmployees = stock_info['fullTimeEmployees']
179
- st.write(f"Full Time Employees: {FullTimeEmployees}")
180
- else:
181
- st.write("Full Time Employees information not available for this stock.")
182
-
183
- if 'companyOfficers' in stock_info:
184
- officers = stock_info['companyOfficers']
185
- officer_data = []
186
-
187
- # Create a DataFrame
188
- df = pd.DataFrame(columns=["Name", "Title", "Age"])
189
-
190
- # Populate the DataFrame with officer information
191
- #for officer in officers:
192
- # officer_data.append([officer['name'], officer['title'], officer['age']])
193
-
194
- for officer in officers:
195
- name = officer.get('name', 'N/A')
196
- title = officer.get('title', 'N/A')
197
- age = officer.get('age', 'N/A')
198
- officer_data.append([name, title, age])
199
-
200
-
201
- df = pd.concat([df, pd.DataFrame(officer_data, columns=["Name", "Title", "Age"])], ignore_index=True)
202
-
203
- # Display the DataFrame using Markdown without the index column
204
- st.markdown(df.to_markdown(index=False))
205
-
206
- else:
207
- st.write("Company Officers information not available for this stock.")
208
-
209
- ## ............................................... ##
210
- # Display the latest news
211
- st.subheader('Latest News')
212
-
213
- # Prepare the data for the DataFrame
214
- news_data_for_dataframe = []
215
- for news_item in news_data:
216
- news_title = news_item['title']
217
- news_link = f"[Link]({news_item['link']})"
218
- news_publisher = news_item['publisher']
219
- news_provider_publish_time = pd.to_datetime(news_item['providerPublishTime'], unit='s')
220
- news_type = news_item['type']
221
- news_data_for_dataframe.append([news_title, news_link, news_publisher, news_provider_publish_time, news_type])
222
-
223
- # Create a Pandas DataFrame
224
- df = pd.DataFrame(news_data_for_dataframe, columns=["Title", "Link", "Publisher", "Provider Publish Time", "Type"])
225
-
226
- # Display the DataFrame using Markdown without the index column
227
- st.markdown(df.to_markdown(index=False), unsafe_allow_html=True)
228
-
229
- ## ............................................... ##
230
- # Enhanced title with larger font size and a different color
231
- title = f"<h1 style='color: red; font-size: 25px; text-align: center; '>{stock_name}'s Stock Technical Analysis</h1>"
232
- st.markdown(title, unsafe_allow_html=True)
233
-
234
- with st.expander("See Details"):
235
- # Describing the data
236
- st.subheader(f'Data from {start_date} - {end_date}')
237
- data = yf.download(user_input, start_date, end_date)
238
-
239
- if data.empty:
240
- # Display a message to the user when no data is available
241
- st.warning(f"No data available for stock symbol {stock_name} in the specified date range.")
242
- else:
243
- # Reset the index to add the date column
244
- data = data.reset_index()
245
-
246
- # Display data in a Plotly table
247
- fig = go.Figure(data=[go.Table(
248
- header=dict(values=list(data.columns),
249
- font=dict(size=12, color='white'),
250
- fill_color='#264653',
251
- line_color='rgba(255,255,255,0.2)',
252
- align=['left', 'center'],
253
- height=20),
254
- cells=dict(values=[data[k].tolist() for k in data.columns],
255
- font=dict(size=12),
256
- align=['left', 'center'],
257
- line_color='rgba(255,255,255,0.2)',
258
- height=20))])
259
-
260
- fig.update_layout(title_text=f"Data for {stock_name}", title_font_color='#264653', title_x=0, margin=dict(l=0, r=10, b=10, t=30))
261
-
262
- st.plotly_chart(fig, use_container_width=True)
263
-
264
-
265
- st.markdown(f"<h2 style='text-align: center; color: #264653;'>Data Overview for {stock_name}</h2>", unsafe_allow_html=True)
266
- # Get the description of the data
267
- description = data.describe()
268
-
269
- # Dictionary of columns and rows to highlight
270
- highlight_dict = {
271
- "Open": ["mean", "min", "max", "std"],
272
- "High": ["mean", "min", "max", "std"],
273
- "Low": ["mean", "min", "max", "std"],
274
- "Close": ["mean", "min", "max", "std"],
275
- "Adj Close": ["mean", "min", "max", "std"]
276
- }
277
-
278
- # Colors for specific rows
279
- color_dict = {
280
- "mean": "lightgreen",
281
- "min": "salmon",
282
- "max": "lightblue",
283
- "std": "lightyellow"
284
- }
285
-
286
- # Function to highlight specific columns and rows based on the dictionaries
287
- def highlight_specific_cells(val, col_name, row_name):
288
- if col_name in highlight_dict and row_name in highlight_dict[col_name]:
289
- return f'background-color: {color_dict[row_name]}'
290
- return ''
291
-
292
- styled_description = description.style.apply(lambda row: [highlight_specific_cells(val, col, row.name) for col, val in row.items()], axis=1)
293
-
294
- # Display the styled table in Streamlit
295
- st.table(styled_description)
296
-
297
- ### ............................................... ##
298
- # Stock Price Over Time
299
- g1, g2, g3 = st.columns((1.2,1.2,1))
300
-
301
- fig1 = px.line(data, x='Date', y='Close', template='seaborn')
302
- fig1.update_traces(line_color='#264653')
303
- fig1.update_layout(title_text="Stock Price Over Time", title_x=0, margin=dict(l=20, r=20, b=20, t=30), yaxis_title=None, xaxis_title=None, height=400, width=700)
304
- g1.plotly_chart(fig1, use_container_width=True)
305
-
306
- # Volume of Stocks Traded Over Time
307
- fig2 = px.bar(data, x='Date', y='Volume', template='seaborn')
308
- fig2.update_traces(marker_color='#7A9E9F')
309
- fig2.update_layout(title_text="Volume of Stocks Traded Over Time", title_x=0, margin=dict(l=20, r=20, b=20, t=30), yaxis_title=None, xaxis_title=None, height=400, width=700)
310
- g2.plotly_chart(fig2, use_container_width=True)
311
-
312
- # Moving Averages
313
- short_window = 40
314
- long_window = 100
315
- data['Short_MA'] = data['Close'].rolling(window=short_window).mean()
316
- data['Long_MA'] = data['Close'].rolling(window=long_window).mean()
317
- fig3 = px.line(data, x='Date', y='Close', template='seaborn')
318
- fig3.add_scatter(x=data['Date'], y=data['Short_MA'], mode='lines', line=dict(color="red"), name=f'Short {short_window}D MA')
319
- fig3.add_scatter(x=data['Date'], y=data['Long_MA'], mode='lines', line=dict(color="blue"), name=f'Long {long_window}D MA')
320
- fig3.update_layout(title_text="Stock Price with Moving Averages", title_x=0, margin=dict(l=20, r=20, b=20, t=30), yaxis_title=None, xaxis_title=None, legend=dict(orientation="h", yanchor="bottom", y=0.9, xanchor="right", x=0.99), height=400, width=700)
321
- g3.plotly_chart(fig3, use_container_width=True)
322
-
323
- ## ............................................... ##
324
- # Daily Returns
325
- g4, g5, g6 = st.columns((1,1,1))
326
- data['Daily_Returns'] = data['Close'].pct_change()
327
- fig4 = px.line(data, x='Date', y='Daily_Returns', template='seaborn')
328
- fig4.update_traces(line_color='#E76F51')
329
- fig4.update_layout(title_text="Daily Returns", title_x=0, margin=dict(l=0, r=10, b=10, t=30), yaxis_title=None, xaxis_title=None)
330
- g4.plotly_chart(fig4, use_container_width=True)
331
-
332
- # Cumulative Returns
333
- data['Cumulative_Returns'] = (1 + data['Daily_Returns']).cumprod()
334
- fig5 = px.line(data, x='Date', y='Cumulative_Returns', template='seaborn')
335
- fig5.update_traces(line_color='#2A9D8F')
336
- fig5.update_layout(title_text="Cumulative Returns", title_x=0, margin=dict(l=0, r=10, b=10, t=30), yaxis_title=None, xaxis_title=None)
337
- g5.plotly_chart(fig5, use_container_width=True)
338
- # Stock Price Distribution
339
- fig6 = px.histogram(data, x='Close', template='seaborn', nbins=50)
340
- fig6.update_traces(marker_color='#F4A261')
341
- fig6.update_layout(title_text="Stock Price Distribution", title_x=0, margin=dict(l=0, r=10, b=10, t=30), yaxis_title=None, xaxis_title=None)
342
- g6.plotly_chart(fig6, use_container_width=True)
343
-
344
- ## ............................................... ##
345
-
346
- # Bollinger Bands
347
- g7, g8, g9 = st.columns((1,1,1))
348
- rolling_mean = data['Close'].rolling(window=20).mean()
349
- rolling_std = data['Close'].rolling(window=20).std()
350
- data['Bollinger_Upper'] = rolling_mean + (rolling_std * 2)
351
- data['Bollinger_Lower'] = rolling_mean - (rolling_std * 2)
352
- fig7 = px.line(data, x='Date', y='Close', template='seaborn')
353
- fig7.add_scatter(x=data['Date'], y=data['Bollinger_Upper'], mode='lines', line=dict(color="green"), name='Upper Bollinger Band')
354
- fig7.add_scatter(x=data['Date'], y=data['Bollinger_Lower'], mode='lines', line=dict(color="red"), name='Lower Bollinger Band')
355
- fig7.update_layout(title_text="Bollinger Bands", title_x=0, margin=dict(l=0, r=10, b=10, t=30), yaxis_title=None, xaxis_title=None)
356
- g7.plotly_chart(fig7, use_container_width=True)
357
-
358
- # Stock Price vs. Volume
359
- fig8 = px.line(data, x='Date', y='Close', template='seaborn')
360
- fig8.add_bar(x=data['Date'], y=data['Volume'], name='Volume')
361
- fig8.update_layout(title_text="Stock Price vs. Volume", title_x=0, margin=dict(l=0, r=10, b=10, t=30), yaxis_title=None, xaxis_title=None)
362
- g8.plotly_chart(fig8, use_container_width=True)
363
-
364
- # MACD
365
- data['12D_EMA'] = data['Close'].ewm(span=12, adjust=False).mean()
366
- data['26D_EMA'] = data['Close'].ewm(span=26, adjust=False).mean()
367
- data['MACD'] = data['12D_EMA'] - data['26D_EMA']
368
- data['Signal_Line'] = data['MACD'].ewm(span=9, adjust=False).mean()
369
- fig9 = px.line(data, x='Date', y='MACD', template='seaborn', title="MACD")
370
- fig9.add_scatter(x=data['Date'], y=data['Signal_Line'], mode='lines', line=dict(color="orange"), name='Signal Line')
371
- fig9.update_layout(title_text="MACD", title_x=0, margin=dict(l=0, r=10, b=10, t=30), yaxis_title=None, xaxis_title=None)
372
- g9.plotly_chart(fig9, use_container_width=True)
373
-
374
- ### ............................................... ##
375
-
376
- # Relative Strength Index (RSI)
377
- g10, g11, g12 = st.columns((1,1,1))
378
- delta = data['Close'].diff()
379
- gain = (delta.where(delta > 0, 0)).fillna(0)
380
- loss = (-delta.where(delta < 0, 0)).fillna(0)
381
- avg_gain = gain.rolling(window=14).mean()
382
- avg_loss = loss.rolling(window=14).mean()
383
- rs = avg_gain / avg_loss
384
- data['RSI'] = 100 - (100 / (1 + rs))
385
- fig10 = px.line(data, x='Date', y='RSI', template='seaborn')
386
- fig10.update_layout(title_text="Relative Strength Index (RSI)", title_x=0, margin=dict(l=0, r=10, b=10, t=30), yaxis_title=None, xaxis_title=None)
387
- g10.plotly_chart(fig10, use_container_width=True)
388
-
389
- # Candlestick Chart
390
- fig11 = go.Figure(data=[go.Candlestick(x=data['Date'],
391
- open=data['Open'],
392
- high=data['High'],
393
- low=data['Low'],
394
- close=data['Close'])])
395
- fig11.update_layout(title_text="Candlestick Chart", title_x=0, margin=dict(l=0, r=10, b=10, t=30))
396
- g11.plotly_chart(fig11, use_container_width=True)
397
-
398
- # Correlation Matrix
399
- corr_matrix = data[['Open', 'High', 'Low', 'Close', 'Volume']].corr()
400
- fig12 = px.imshow(corr_matrix, template='seaborn')
401
- fig12.update_layout(title_text="Correlation Matrix", title_x=0, margin=dict(l=0, r=10, b=10, t=30))
402
- g12.plotly_chart(fig12, use_container_width=True)
403
-
404
- ### ............................................... ##
405
- # Price Rate of Change (ROC)
406
- g13, g14, g15 = st.columns((1,1,1))
407
- n = 12
408
- data['ROC'] = ((data['Close'] - data['Close'].shift(n)) / data['Close'].shift(n)) * 100
409
- fig13 = px.line(data, x='Date', y='ROC', template='seaborn')
410
- fig13.update_layout(title_text="Price Rate of Change (ROC)", title_x=0, margin=dict(l=0, r=10, b=10, t=30), yaxis_title=None, xaxis_title=None)
411
- g13.plotly_chart(fig13, use_container_width=True)
412
-
413
- # Stochastic Oscillator
414
- low_min = data['Low'].rolling(window=14).min()
415
- high_max = data['High'].rolling(window=14).max()
416
- data['%K'] = (100 * (data['Close'] - low_min) / (high_max - low_min))
417
- data['%D'] = data['%K'].rolling(window=3).mean()
418
- fig14 = px.line(data, x='Date', y='%K', template='seaborn')
419
- fig14.add_scatter(x=data['Date'], y=data['%D'], mode='lines', line=dict(color="orange"), name='%D (3-day SMA of %K)')
420
- fig14.update_layout(title_text="Stochastic Oscillator", title_x=0, margin=dict(l=0, r=10, b=10, t=30), yaxis_title=None, xaxis_title=None)
421
- g14.plotly_chart(fig14, use_container_width=True)
422
-
423
- # Historical Volatility
424
- data['Log_Return'] = np.log(data['Close'] / data['Close'].shift(1))
425
- data['Historical_Volatility'] = data['Log_Return'].rolling(window=252).std() * np.sqrt(252)
426
- fig15 = px.line(data, x='Date', y='Historical_Volatility', template='seaborn')
427
- fig15.update_layout(title_text="Historical Volatility (252-day)", title_x=0, margin=dict(l=0, r=10, b=10, t=30), yaxis_title=None, xaxis_title=None)
428
- g15.plotly_chart(fig15, use_container_width=True)
429
-
430
- ### ............................................... ##
431
-
432
- # Visualizing the data and want to get the data when hovering over the graph
433
- st.subheader('Closing Price vs Time Chart')
434
- fig1 = go.Figure()
435
- fig1.add_trace(go.Scatter(x=data.index, y=data['Close'], mode='lines', name='Close'))
436
- fig1.layout.update(hovermode='x')
437
- # Display the figure in Streamlit
438
- st.plotly_chart(fig1,use_container_width=True)
439
-
440
- st.subheader('Closing Price vs Time Chart with 100MA')
441
- ma100 = data['Close'].rolling(100).mean()
442
- fig2 = go.Figure()
443
- # Add traces for 100MA and Closing Price
444
- fig2.add_trace(go.Scatter(x=data.index, y=ma100, mode='lines', name='100MA'))
445
- fig2.add_trace(go.Scatter(x=data.index, y=data['Close'], mode='lines', name='Closing Price'))
446
- fig2.layout.update(hovermode='x')
447
- # Display the figure in Streamlit
448
- st.plotly_chart(fig2,use_container_width=True)
449
-
450
- st.subheader('Closing Price vs Time Chart with 100MA and 200MA')
451
- ma100 = data['Close'].rolling(100).mean()
452
- ma200 = data['Close'].rolling(200).mean()
453
- fig3 = go.Figure()
454
- # Add traces for 100MA and Closing Price
455
- fig3.add_trace(go.Scatter(x=data.index, y=ma100, mode='lines', name='100MA'))
456
- fig3.add_trace(go.Scatter(x=data.index, y=ma200, mode='lines', name='200MA'))
457
- fig3.add_trace(go.Scatter(x=data.index, y=data['Close'], mode='lines', name='Closing Price'))
458
- fig3.layout.update(hovermode='x')
459
-
460
- # Display the figure in Streamlit
461
- st.plotly_chart(fig3,use_container_width=True)
462
-
463
- ## ............................................... ##
464
- # Enhanced title with larger font size and a different color
465
- title = f"<h1 style='color: red; font-size: 25px; text-align: center; '>{stock_name}'s Stock Prediction</h1>"
466
- st.markdown(title, unsafe_allow_html=True)
467
-
468
- with st.expander("See Details"):
469
- # Define the minimum number of days required for predictions
470
- minimum_days_for_predictions = 100
471
-
472
- # Check if the available data is less than the minimum required days
473
- if len(data) < minimum_days_for_predictions:
474
- st.warning(f"The available data for {stock_name} is less than {minimum_days_for_predictions} days, which is insufficient for predictions.")
475
- else:
476
- # Splitting the data into training and testing data
477
- data_training = pd.DataFrame(data['Close'][0:int(len(data)*0.70)])
478
- data_testing = pd.DataFrame(data['Close'][int(len(data)*0.70): int(len(data))])
479
-
480
- # Scaling the data
481
- scaler = MinMaxScaler(feature_range=(0,1))
482
- data_training_array = scaler.fit_transform(data_training)
483
-
484
- # load the model
485
- model = load_model('best_model_MAPI.h5')
486
-
487
- # Testing the model
488
- past_100_days = data_training.tail(100)
489
- final_df = pd.concat([past_100_days,data_testing], ignore_index=True)
490
- input_data = scaler.fit_transform(final_df)
491
-
492
- x_test = []
493
- y_test = []
494
- for i in range(100, input_data.shape[0]):
495
- x_test.append(input_data[i-100:i])
496
- y_test.append(input_data[i,0])
497
-
498
- x_test, y_test = np.array(x_test), np.array(y_test)
499
-
500
- y_predicted = model.predict(x_test)
501
-
502
- scaler = scaler.scale_
503
- scale_factor = 1/scaler[0]
504
- y_predicted = y_predicted * scale_factor
505
- y_test = y_test * scale_factor
506
 
507
- # Visualizing the results
508
- st.subheader('Predictions vs Actual')
509
- fig4 = go.Figure()
510
- # Add traces for Actual and Predicted Price
511
- fig4.add_trace(go.Scatter(x=data.index[-len(y_test):], y=y_test, mode='lines', name='Actual Price'))
512
- fig4.add_trace(go.Scatter(x=data.index[-len(y_predicted):], y=y_predicted[:,0], mode='lines', name='Predicted Price'))
513
- fig4.layout.update(hovermode='x')
514
- # Display the figure in Streamlit
515
- st.plotly_chart(fig4,use_container_width=True)
516
 
517
- except Exception as e:
518
- st.error(f"An error fetching stock information: {str(e)}")
 
 
 
 
 
 
1
+ from pathlib import Path
 
 
 
 
 
 
 
 
2
  import streamlit as st
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3
 
 
 
 
 
 
 
 
 
 
4
 
5
+ st.set_page_config(page_title='Regression Stocks Prediction', layout='wide', page_icon='πŸ“ˆ')
6
+ st.title("πŸ“ˆ Stock Analysis and Prediction")
7
+ st.write(
8
+ """
9
+ Welcome to the **πŸ“ˆ Stock Analysis and Prediction**!
10
+ """
11
+ )
pages/πŸ“ˆ_Stock_Analysis.py ADDED
@@ -0,0 +1,516 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import pandas as pd
2
+ import numpy as np
3
+ import matplotlib.pyplot as plt
4
+ import pandas_datareader.data as web
5
+ import datetime as dt
6
+ import yfinance as yf
7
+ from sklearn.preprocessing import MinMaxScaler
8
+ from keras.models import load_model
9
+ import streamlit as st
10
+ import plotly.graph_objects as go
11
+ import base64
12
+ import plotly.express as px
13
+ from datetime import datetime
14
+
15
+
16
+ ## ............................................... ##
17
+ # Set page configuration (Call this once and make changes as needed)
18
+ st.set_page_config(page_title='Regression Stocks Prediction', layout='wide', page_icon=':rocket:')
19
+
20
+ ## ............................................... ##
21
+ # Add a dictonary of stock tickers and their company names and make a drop down menu to select the stock to predict
22
+ stock_tickers = {
23
+ "MAPI":"MAPI.JK","MAP Aktif": "MAPA.JK","MAP Boga": "MAPB.JK",
24
+ "Tesla": "TSLA", "Apple": "AAPL", "Microsoft": "MSFT", "Google": "GOOGL",
25
+ "Meta": "META", "Amazon": "AMZN", "Netflix": "NFLX", "Alphabet": "GOOG",
26
+ "Nvidia": "NVDA", "Paypal": "PYPL", "Adobe": "ADBE", "Intel": "INTC",
27
+ "Cisco": "CSCO", "Comcast": "CMCSA", "Pepsi": "PEP", "Costco": "COST",
28
+ "Starbucks": "SBUX", "Walmart": "WMT", "Disney": "DIS", "Visa": "V",
29
+ "Mastercard": "MA", "Boeing": "BA", "IBM": "IBM", "McDonalds": "MCD",
30
+ "Nike": "NKE", "Exxon": "XOM", "Chevron": "CVX", "Verizon": "VZ",
31
+ "AT&T": "T", "Home Depot": "HD", "Salesforce": "CRM", "Oracle": "ORCL",
32
+ "Qualcomm": "QCOM", "AMD": "AMD"
33
+ }
34
+
35
+ st.sidebar.title("Stock Option")
36
+ # Custom CSS to change the sidebar color
37
+ sidebar_css = """
38
+ <style>
39
+ div[data-testid="stSidebar"] > div:first-child {
40
+ width: 350px; # Adjust the width as needed
41
+ background-color: #FF6969;
42
+ }
43
+ </style>
44
+ """
45
+
46
+ # User Input
47
+ #default_index = stock_tickers.keys().index("MAPI.JK") if "MAPI.JK" in stock_tickers.keys() else 0
48
+ #st.markdown(sidebar_css, unsafe_allow_html=True)
49
+ #user_input = st.sidebar.selectbox("Select a Stock", list(stock_tickers.keys()), index=default_index , key="main_selectbox")
50
+ #stock_name = user_input
51
+ #user_input = stock_tickers[user_input]
52
+
53
+ user_input = st.sidebar.text_input("Select a Stock", "MAPI.JK")
54
+
55
+ # User input for start and end dates using calendar widget
56
+ start_date = st.sidebar.date_input("Select start date:", datetime(2023, 1, 1))
57
+ end_date = st.sidebar.date_input("Select end date:", datetime(2023, 12, 1))
58
+
59
+
60
+ st.sidebar.markdown("----")
61
+ st.sidebar.markdown("Β© 2023 Stocks Prediction App")
62
+ st.sidebar.markdown("----")
63
+ st.sidebar.markdown("Example Stock Tickers")
64
+ st.sidebar.markdown(stock_tickers)
65
+
66
+ ## ............................................... ##
67
+ # Page Title and Description
68
+ st.title("Stock Price Analysis and Prediction")
69
+ st.write("Created by Bayhaqy")
70
+ st.write("Using Dataset MAPI to Train and Test the Model")
71
+
72
+ ## ............................................... ##
73
+
74
+ # Try to fetch information from Yahoo Finance
75
+ try:
76
+ stock_info = yf.Ticker(user_input).info
77
+
78
+ # Check if the 'longName' key exists in stock_info
79
+ if 'longName' in stock_info:
80
+ stock_name = stock_info['longName']
81
+ else:
82
+ stock_name = user_input
83
+
84
+ # Fetch the latest news using yfinance
85
+ news_data = yf.Ticker(user_input).news
86
+
87
+ # Create a Streamlit app
88
+ title = f"<h1 style='color: red; font-size: 25px; text-align: center; '>{stock_name}'s Stock Fundamental Analysis</h1>"
89
+ st.markdown(title, unsafe_allow_html=True)
90
+
91
+ with st.expander("See Details"):
92
+ ## ............................................... ##
93
+ # Display the retrieved stock information
94
+ if 'longName' in stock_info:
95
+ company_name = stock_info['longName']
96
+ st.write(f"Company Name: {company_name}")
97
+ else:
98
+ st.write("Company name information not available for this stock.")
99
+
100
+ if 'industry' in stock_info:
101
+ Industry = stock_info['industry']
102
+ st.write(f"Industry: {Industry}")
103
+ else:
104
+ st.write("Industry information not available for this stock.")
105
+
106
+ if 'sector' in stock_info:
107
+ Sector = stock_info['sector']
108
+ st.write(f"Sector: {Sector}")
109
+ else:
110
+ st.write("Sector information not available for this stock.")
111
+
112
+ if 'website' in stock_info:
113
+ Website = stock_info['website']
114
+ st.write(f"Sector: {Website}")
115
+ else:
116
+ st.write("Website information not available for this stock.")
117
+
118
+ if 'marketCap' in stock_info:
119
+ MarketCap = stock_info['marketCap']
120
+ st.write(f"Market Cap: {MarketCap}")
121
+ else:
122
+ st.write("Market Cap information not available for this stock.")
123
+
124
+ if 'previousClose' in stock_info:
125
+ PreviousClose = stock_info['previousClose']
126
+ st.write(f"Previous Close: {PreviousClose}")
127
+ else:
128
+ st.write("Previous Close information not available for this stock.")
129
+
130
+ if 'dividendYield' in stock_info:
131
+ dividend_yield = stock_info['dividendYield'] * 100 # Convert to percentage
132
+ st.write(f"Dividend Yield: {dividend_yield:.2f}%")
133
+ else:
134
+ st.write("Dividend Yield information not available for this stock.")
135
+
136
+ ## ............................................... ##
137
+ # Display financial metrics
138
+ st.subheader('Financial Metrics')
139
+ if 'trailingEps' in stock_info:
140
+ trailing_eps = stock_info['trailingEps']
141
+ st.write(f"Earnings Per Share (EPS): {trailing_eps:.2f}")
142
+ else:
143
+ st.write("Earnings Per Share (EPS) information not available for this stock.")
144
+
145
+ if 'trailingPE' in stock_info:
146
+ trailing_pe = stock_info['trailingPE']
147
+ st.write(f"Price-to-Earnings (P/E) Ratio: {trailing_pe:.2f}")
148
+ else:
149
+ st.write("Price-to-Earnings (P/E) Ratio information not available for this stock.")
150
+
151
+ if 'priceToSalesTrailing12Months' in stock_info:
152
+ priceToSalesTrailing_12Months = stock_info['priceToSalesTrailing12Months']
153
+ st.write(f"Price-to-Sales (P/S) Ratio: {priceToSalesTrailing_12Months:.2f}")
154
+ else:
155
+ st.write("Price-to-Sales (P/S) Ratio information not available for this stock.")
156
+
157
+ if 'priceToBook' in stock_info:
158
+ price_ToBook = stock_info['priceToBook']
159
+ st.write(f"Price-to-Book (P/B) Ratio: {price_ToBook:.2f}")
160
+ else:
161
+ st.write("Price-to-Book (P/B) Ratio information not available for this stock.")
162
+
163
+ ## ............................................... ##
164
+ # Display more detailed information
165
+ st.subheader('Company Summary')
166
+ if 'longBusinessSummary' in stock_info:
167
+ LongBusinessSummary = stock_info['longBusinessSummary']
168
+ st.write(f"Company Summary: {LongBusinessSummary}")
169
+ else:
170
+ st.write("Company Summary information not available for this stock.")
171
+
172
+ ## ............................................... ##
173
+ # Display information about company officers
174
+ st.subheader('Company Officers')
175
+ if 'fullTimeEmployees' in stock_info:
176
+ FullTimeEmployees = stock_info['fullTimeEmployees']
177
+ st.write(f"Full Time Employees: {FullTimeEmployees}")
178
+ else:
179
+ st.write("Full Time Employees information not available for this stock.")
180
+
181
+ if 'companyOfficers' in stock_info:
182
+ officers = stock_info['companyOfficers']
183
+ officer_data = []
184
+
185
+ # Create a DataFrame
186
+ df = pd.DataFrame(columns=["Name", "Title", "Age"])
187
+
188
+ # Populate the DataFrame with officer information
189
+ #for officer in officers:
190
+ # officer_data.append([officer['name'], officer['title'], officer['age']])
191
+
192
+ for officer in officers:
193
+ name = officer.get('name', 'N/A')
194
+ title = officer.get('title', 'N/A')
195
+ age = officer.get('age', 'N/A')
196
+ officer_data.append([name, title, age])
197
+
198
+
199
+ df = pd.concat([df, pd.DataFrame(officer_data, columns=["Name", "Title", "Age"])], ignore_index=True)
200
+
201
+ # Display the DataFrame using Markdown without the index column
202
+ st.markdown(df.to_markdown(index=False))
203
+
204
+ else:
205
+ st.write("Company Officers information not available for this stock.")
206
+
207
+ ## ............................................... ##
208
+ # Display the latest news
209
+ st.subheader('Latest News')
210
+
211
+ # Prepare the data for the DataFrame
212
+ news_data_for_dataframe = []
213
+ for news_item in news_data:
214
+ news_title = news_item['title']
215
+ news_link = f"[Link]({news_item['link']})"
216
+ news_publisher = news_item['publisher']
217
+ news_provider_publish_time = pd.to_datetime(news_item['providerPublishTime'], unit='s')
218
+ news_type = news_item['type']
219
+ news_data_for_dataframe.append([news_title, news_link, news_publisher, news_provider_publish_time, news_type])
220
+
221
+ # Create a Pandas DataFrame
222
+ df = pd.DataFrame(news_data_for_dataframe, columns=["Title", "Link", "Publisher", "Provider Publish Time", "Type"])
223
+
224
+ # Display the DataFrame using Markdown without the index column
225
+ st.markdown(df.to_markdown(index=False), unsafe_allow_html=True)
226
+
227
+ ## ............................................... ##
228
+ # Enhanced title with larger font size and a different color
229
+ title = f"<h1 style='color: red; font-size: 25px; text-align: center; '>{stock_name}'s Stock Technical Analysis</h1>"
230
+ st.markdown(title, unsafe_allow_html=True)
231
+
232
+ with st.expander("See Details"):
233
+ # Describing the data
234
+ st.subheader(f'Data from {start_date} - {end_date}')
235
+ data = yf.download(user_input, start_date, end_date)
236
+
237
+ if data.empty:
238
+ # Display a message to the user when no data is available
239
+ st.warning(f"No data available for stock symbol {stock_name} in the specified date range.")
240
+ else:
241
+ # Reset the index to add the date column
242
+ data = data.reset_index()
243
+
244
+ # Display data in a Plotly table
245
+ fig = go.Figure(data=[go.Table(
246
+ header=dict(values=list(data.columns),
247
+ font=dict(size=12, color='white'),
248
+ fill_color='#264653',
249
+ line_color='rgba(255,255,255,0.2)',
250
+ align=['left', 'center'],
251
+ height=20),
252
+ cells=dict(values=[data[k].tolist() for k in data.columns],
253
+ font=dict(size=12),
254
+ align=['left', 'center'],
255
+ line_color='rgba(255,255,255,0.2)',
256
+ height=20))])
257
+
258
+ fig.update_layout(title_text=f"Data for {stock_name}", title_font_color='#264653', title_x=0, margin=dict(l=0, r=10, b=10, t=30))
259
+
260
+ st.plotly_chart(fig, use_container_width=True)
261
+
262
+
263
+ st.markdown(f"<h2 style='text-align: center; color: #264653;'>Data Overview for {stock_name}</h2>", unsafe_allow_html=True)
264
+ # Get the description of the data
265
+ description = data.describe()
266
+
267
+ # Dictionary of columns and rows to highlight
268
+ highlight_dict = {
269
+ "Open": ["mean", "min", "max", "std"],
270
+ "High": ["mean", "min", "max", "std"],
271
+ "Low": ["mean", "min", "max", "std"],
272
+ "Close": ["mean", "min", "max", "std"],
273
+ "Adj Close": ["mean", "min", "max", "std"]
274
+ }
275
+
276
+ # Colors for specific rows
277
+ color_dict = {
278
+ "mean": "lightgreen",
279
+ "min": "salmon",
280
+ "max": "lightblue",
281
+ "std": "lightyellow"
282
+ }
283
+
284
+ # Function to highlight specific columns and rows based on the dictionaries
285
+ def highlight_specific_cells(val, col_name, row_name):
286
+ if col_name in highlight_dict and row_name in highlight_dict[col_name]:
287
+ return f'background-color: {color_dict[row_name]}'
288
+ return ''
289
+
290
+ styled_description = description.style.apply(lambda row: [highlight_specific_cells(val, col, row.name) for col, val in row.items()], axis=1)
291
+
292
+ # Display the styled table in Streamlit
293
+ st.table(styled_description)
294
+
295
+ ### ............................................... ##
296
+ # Stock Price Over Time
297
+ g1, g2, g3 = st.columns((1.2,1.2,1))
298
+
299
+ fig1 = px.line(data, x='Date', y='Close', template='seaborn')
300
+ fig1.update_traces(line_color='#264653')
301
+ fig1.update_layout(title_text="Stock Price Over Time", title_x=0, margin=dict(l=20, r=20, b=20, t=30), yaxis_title=None, xaxis_title=None, height=400, width=700)
302
+ g1.plotly_chart(fig1, use_container_width=True)
303
+
304
+ # Volume of Stocks Traded Over Time
305
+ fig2 = px.bar(data, x='Date', y='Volume', template='seaborn')
306
+ fig2.update_traces(marker_color='#7A9E9F')
307
+ fig2.update_layout(title_text="Volume of Stocks Traded Over Time", title_x=0, margin=dict(l=20, r=20, b=20, t=30), yaxis_title=None, xaxis_title=None, height=400, width=700)
308
+ g2.plotly_chart(fig2, use_container_width=True)
309
+
310
+ # Moving Averages
311
+ short_window = 40
312
+ long_window = 100
313
+ data['Short_MA'] = data['Close'].rolling(window=short_window).mean()
314
+ data['Long_MA'] = data['Close'].rolling(window=long_window).mean()
315
+ fig3 = px.line(data, x='Date', y='Close', template='seaborn')
316
+ fig3.add_scatter(x=data['Date'], y=data['Short_MA'], mode='lines', line=dict(color="red"), name=f'Short {short_window}D MA')
317
+ fig3.add_scatter(x=data['Date'], y=data['Long_MA'], mode='lines', line=dict(color="blue"), name=f'Long {long_window}D MA')
318
+ fig3.update_layout(title_text="Stock Price with Moving Averages", title_x=0, margin=dict(l=20, r=20, b=20, t=30), yaxis_title=None, xaxis_title=None, legend=dict(orientation="h", yanchor="bottom", y=0.9, xanchor="right", x=0.99), height=400, width=700)
319
+ g3.plotly_chart(fig3, use_container_width=True)
320
+
321
+ ## ............................................... ##
322
+ # Daily Returns
323
+ g4, g5, g6 = st.columns((1,1,1))
324
+ data['Daily_Returns'] = data['Close'].pct_change()
325
+ fig4 = px.line(data, x='Date', y='Daily_Returns', template='seaborn')
326
+ fig4.update_traces(line_color='#E76F51')
327
+ fig4.update_layout(title_text="Daily Returns", title_x=0, margin=dict(l=0, r=10, b=10, t=30), yaxis_title=None, xaxis_title=None)
328
+ g4.plotly_chart(fig4, use_container_width=True)
329
+
330
+ # Cumulative Returns
331
+ data['Cumulative_Returns'] = (1 + data['Daily_Returns']).cumprod()
332
+ fig5 = px.line(data, x='Date', y='Cumulative_Returns', template='seaborn')
333
+ fig5.update_traces(line_color='#2A9D8F')
334
+ fig5.update_layout(title_text="Cumulative Returns", title_x=0, margin=dict(l=0, r=10, b=10, t=30), yaxis_title=None, xaxis_title=None)
335
+ g5.plotly_chart(fig5, use_container_width=True)
336
+ # Stock Price Distribution
337
+ fig6 = px.histogram(data, x='Close', template='seaborn', nbins=50)
338
+ fig6.update_traces(marker_color='#F4A261')
339
+ fig6.update_layout(title_text="Stock Price Distribution", title_x=0, margin=dict(l=0, r=10, b=10, t=30), yaxis_title=None, xaxis_title=None)
340
+ g6.plotly_chart(fig6, use_container_width=True)
341
+
342
+ ## ............................................... ##
343
+
344
+ # Bollinger Bands
345
+ g7, g8, g9 = st.columns((1,1,1))
346
+ rolling_mean = data['Close'].rolling(window=20).mean()
347
+ rolling_std = data['Close'].rolling(window=20).std()
348
+ data['Bollinger_Upper'] = rolling_mean + (rolling_std * 2)
349
+ data['Bollinger_Lower'] = rolling_mean - (rolling_std * 2)
350
+ fig7 = px.line(data, x='Date', y='Close', template='seaborn')
351
+ fig7.add_scatter(x=data['Date'], y=data['Bollinger_Upper'], mode='lines', line=dict(color="green"), name='Upper Bollinger Band')
352
+ fig7.add_scatter(x=data['Date'], y=data['Bollinger_Lower'], mode='lines', line=dict(color="red"), name='Lower Bollinger Band')
353
+ fig7.update_layout(title_text="Bollinger Bands", title_x=0, margin=dict(l=0, r=10, b=10, t=30), yaxis_title=None, xaxis_title=None)
354
+ g7.plotly_chart(fig7, use_container_width=True)
355
+
356
+ # Stock Price vs. Volume
357
+ fig8 = px.line(data, x='Date', y='Close', template='seaborn')
358
+ fig8.add_bar(x=data['Date'], y=data['Volume'], name='Volume')
359
+ fig8.update_layout(title_text="Stock Price vs. Volume", title_x=0, margin=dict(l=0, r=10, b=10, t=30), yaxis_title=None, xaxis_title=None)
360
+ g8.plotly_chart(fig8, use_container_width=True)
361
+
362
+ # MACD
363
+ data['12D_EMA'] = data['Close'].ewm(span=12, adjust=False).mean()
364
+ data['26D_EMA'] = data['Close'].ewm(span=26, adjust=False).mean()
365
+ data['MACD'] = data['12D_EMA'] - data['26D_EMA']
366
+ data['Signal_Line'] = data['MACD'].ewm(span=9, adjust=False).mean()
367
+ fig9 = px.line(data, x='Date', y='MACD', template='seaborn', title="MACD")
368
+ fig9.add_scatter(x=data['Date'], y=data['Signal_Line'], mode='lines', line=dict(color="orange"), name='Signal Line')
369
+ fig9.update_layout(title_text="MACD", title_x=0, margin=dict(l=0, r=10, b=10, t=30), yaxis_title=None, xaxis_title=None)
370
+ g9.plotly_chart(fig9, use_container_width=True)
371
+
372
+ ### ............................................... ##
373
+
374
+ # Relative Strength Index (RSI)
375
+ g10, g11, g12 = st.columns((1,1,1))
376
+ delta = data['Close'].diff()
377
+ gain = (delta.where(delta > 0, 0)).fillna(0)
378
+ loss = (-delta.where(delta < 0, 0)).fillna(0)
379
+ avg_gain = gain.rolling(window=14).mean()
380
+ avg_loss = loss.rolling(window=14).mean()
381
+ rs = avg_gain / avg_loss
382
+ data['RSI'] = 100 - (100 / (1 + rs))
383
+ fig10 = px.line(data, x='Date', y='RSI', template='seaborn')
384
+ fig10.update_layout(title_text="Relative Strength Index (RSI)", title_x=0, margin=dict(l=0, r=10, b=10, t=30), yaxis_title=None, xaxis_title=None)
385
+ g10.plotly_chart(fig10, use_container_width=True)
386
+
387
+ # Candlestick Chart
388
+ fig11 = go.Figure(data=[go.Candlestick(x=data['Date'],
389
+ open=data['Open'],
390
+ high=data['High'],
391
+ low=data['Low'],
392
+ close=data['Close'])])
393
+ fig11.update_layout(title_text="Candlestick Chart", title_x=0, margin=dict(l=0, r=10, b=10, t=30))
394
+ g11.plotly_chart(fig11, use_container_width=True)
395
+
396
+ # Correlation Matrix
397
+ corr_matrix = data[['Open', 'High', 'Low', 'Close', 'Volume']].corr()
398
+ fig12 = px.imshow(corr_matrix, template='seaborn')
399
+ fig12.update_layout(title_text="Correlation Matrix", title_x=0, margin=dict(l=0, r=10, b=10, t=30))
400
+ g12.plotly_chart(fig12, use_container_width=True)
401
+
402
+ ### ............................................... ##
403
+ # Price Rate of Change (ROC)
404
+ g13, g14, g15 = st.columns((1,1,1))
405
+ n = 12
406
+ data['ROC'] = ((data['Close'] - data['Close'].shift(n)) / data['Close'].shift(n)) * 100
407
+ fig13 = px.line(data, x='Date', y='ROC', template='seaborn')
408
+ fig13.update_layout(title_text="Price Rate of Change (ROC)", title_x=0, margin=dict(l=0, r=10, b=10, t=30), yaxis_title=None, xaxis_title=None)
409
+ g13.plotly_chart(fig13, use_container_width=True)
410
+
411
+ # Stochastic Oscillator
412
+ low_min = data['Low'].rolling(window=14).min()
413
+ high_max = data['High'].rolling(window=14).max()
414
+ data['%K'] = (100 * (data['Close'] - low_min) / (high_max - low_min))
415
+ data['%D'] = data['%K'].rolling(window=3).mean()
416
+ fig14 = px.line(data, x='Date', y='%K', template='seaborn')
417
+ fig14.add_scatter(x=data['Date'], y=data['%D'], mode='lines', line=dict(color="orange"), name='%D (3-day SMA of %K)')
418
+ fig14.update_layout(title_text="Stochastic Oscillator", title_x=0, margin=dict(l=0, r=10, b=10, t=30), yaxis_title=None, xaxis_title=None)
419
+ g14.plotly_chart(fig14, use_container_width=True)
420
+
421
+ # Historical Volatility
422
+ data['Log_Return'] = np.log(data['Close'] / data['Close'].shift(1))
423
+ data['Historical_Volatility'] = data['Log_Return'].rolling(window=252).std() * np.sqrt(252)
424
+ fig15 = px.line(data, x='Date', y='Historical_Volatility', template='seaborn')
425
+ fig15.update_layout(title_text="Historical Volatility (252-day)", title_x=0, margin=dict(l=0, r=10, b=10, t=30), yaxis_title=None, xaxis_title=None)
426
+ g15.plotly_chart(fig15, use_container_width=True)
427
+
428
+ ### ............................................... ##
429
+
430
+ # Visualizing the data and want to get the data when hovering over the graph
431
+ st.subheader('Closing Price vs Time Chart')
432
+ fig1 = go.Figure()
433
+ fig1.add_trace(go.Scatter(x=data.index, y=data['Close'], mode='lines', name='Close'))
434
+ fig1.layout.update(hovermode='x')
435
+ # Display the figure in Streamlit
436
+ st.plotly_chart(fig1,use_container_width=True)
437
+
438
+ st.subheader('Closing Price vs Time Chart with 100MA')
439
+ ma100 = data['Close'].rolling(100).mean()
440
+ fig2 = go.Figure()
441
+ # Add traces for 100MA and Closing Price
442
+ fig2.add_trace(go.Scatter(x=data.index, y=ma100, mode='lines', name='100MA'))
443
+ fig2.add_trace(go.Scatter(x=data.index, y=data['Close'], mode='lines', name='Closing Price'))
444
+ fig2.layout.update(hovermode='x')
445
+ # Display the figure in Streamlit
446
+ st.plotly_chart(fig2,use_container_width=True)
447
+
448
+ st.subheader('Closing Price vs Time Chart with 100MA and 200MA')
449
+ ma100 = data['Close'].rolling(100).mean()
450
+ ma200 = data['Close'].rolling(200).mean()
451
+ fig3 = go.Figure()
452
+ # Add traces for 100MA and Closing Price
453
+ fig3.add_trace(go.Scatter(x=data.index, y=ma100, mode='lines', name='100MA'))
454
+ fig3.add_trace(go.Scatter(x=data.index, y=ma200, mode='lines', name='200MA'))
455
+ fig3.add_trace(go.Scatter(x=data.index, y=data['Close'], mode='lines', name='Closing Price'))
456
+ fig3.layout.update(hovermode='x')
457
+
458
+ # Display the figure in Streamlit
459
+ st.plotly_chart(fig3,use_container_width=True)
460
+
461
+ ## ............................................... ##
462
+ # Enhanced title with larger font size and a different color
463
+ title = f"<h1 style='color: red; font-size: 25px; text-align: center; '>{stock_name}'s Stock Prediction</h1>"
464
+ st.markdown(title, unsafe_allow_html=True)
465
+
466
+ with st.expander("See Details"):
467
+ # Define the minimum number of days required for predictions
468
+ minimum_days_for_predictions = 100
469
+
470
+ # Check if the available data is less than the minimum required days
471
+ if len(data) < minimum_days_for_predictions:
472
+ st.warning(f"The available data for {stock_name} is less than {minimum_days_for_predictions} days, which is insufficient for predictions.")
473
+ else:
474
+ # Splitting the data into training and testing data
475
+ data_training = pd.DataFrame(data['Close'][0:int(len(data)*0.70)])
476
+ data_testing = pd.DataFrame(data['Close'][int(len(data)*0.70): int(len(data))])
477
+
478
+ # Scaling the data
479
+ scaler = MinMaxScaler(feature_range=(0,1))
480
+ data_training_array = scaler.fit_transform(data_training)
481
+
482
+ # load the model
483
+ model = load_model('best_model_MAPI.h5')
484
+
485
+ # Testing the model
486
+ past_100_days = data_training.tail(100)
487
+ final_df = pd.concat([past_100_days,data_testing], ignore_index=True)
488
+ input_data = scaler.fit_transform(final_df)
489
+
490
+ x_test = []
491
+ y_test = []
492
+ for i in range(100, input_data.shape[0]):
493
+ x_test.append(input_data[i-100:i])
494
+ y_test.append(input_data[i,0])
495
+
496
+ x_test, y_test = np.array(x_test), np.array(y_test)
497
+
498
+ y_predicted = model.predict(x_test)
499
+
500
+ scaler = scaler.scale_
501
+ scale_factor = 1/scaler[0]
502
+ y_predicted = y_predicted * scale_factor
503
+ y_test = y_test * scale_factor
504
+
505
+ # Visualizing the results
506
+ st.subheader('Predictions vs Actual')
507
+ fig4 = go.Figure()
508
+ # Add traces for Actual and Predicted Price
509
+ fig4.add_trace(go.Scatter(x=data.index[-len(y_test):], y=y_test, mode='lines', name='Actual Price'))
510
+ fig4.add_trace(go.Scatter(x=data.index[-len(y_predicted):], y=y_predicted[:,0], mode='lines', name='Predicted Price'))
511
+ fig4.layout.update(hovermode='x')
512
+ # Display the figure in Streamlit
513
+ st.plotly_chart(fig4,use_container_width=True)
514
+
515
+ except Exception as e:
516
+ st.error(f"An error fetching stock information: {str(e)}")
pages/πŸ“Š_Stock_Comparison.py ADDED
@@ -0,0 +1,63 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import pandas as pd
2
+ import numpy as np
3
+ import matplotlib.pyplot as plt
4
+ import pandas_datareader.data as web
5
+ import datetime as dt
6
+ import yfinance as yf
7
+ from sklearn.preprocessing import MinMaxScaler
8
+ from keras.models import load_model
9
+ import streamlit as st
10
+ import plotly.graph_objects as go
11
+ import base64
12
+ import plotly.express as px
13
+ from datetime import datetime
14
+
15
+ st.set_page_config(page_title='Stock Comparison', layout='wide', page_icon='πŸ“Š')
16
+
17
+ stock_tickers = {
18
+ "MAPI":"MAPI.JK","MAP Aktif": "MAPA.JK","MAP Boga": "MAPB.JK",
19
+ "Tesla": "TSLA", "Apple": "AAPL", "Microsoft": "MSFT", "Google": "GOOGL",
20
+ "Facebook": "FB", "Amazon": "AMZN", "Netflix": "NFLX", "Alphabet": "GOOG",
21
+ "Nvidia": "NVDA", "Paypal": "PYPL", "Adobe": "ADBE", "Intel": "INTC",
22
+ "Cisco": "CSCO", "Comcast": "CMCSA", "Pepsi": "PEP", "Costco": "COST",
23
+ "Starbucks": "SBUX", "Walmart": "WMT", "Disney": "DIS", "Visa": "V",
24
+ "Mastercard": "MA", "Boeing": "BA", "IBM": "IBM", "McDonalds": "MCD",
25
+ "Nike": "NKE", "Exxon": "XOM", "Chevron": "CVX", "Verizon": "VZ",
26
+ "AT&T": "T", "Home Depot": "HD", "Salesforce": "CRM", "Oracle": "ORCL",
27
+ "Qualcomm": "QCOM", "AMD": "AMD"
28
+ }
29
+
30
+ st.title("Stock Comparison and Analysis")
31
+
32
+ # Sidebar for stock selection and date range specification
33
+ st.sidebar.header("Select Stocks and Date Ranges")
34
+
35
+ #stock1 = st.sidebar.selectbox("Select Stock 1", list(stock_tickers.keys()), key="stock1_selectbox")
36
+ #stock2 = st.sidebar.selectbox("Select Stock 2", list(stock_tickers.keys()), key="stock2_selectbox")
37
+
38
+ stock1 = st.sidebar.text_input("Select a Stock", "MAPI.JK")
39
+ stock2 = st.sidebar.text_input("Select a Stock", "MAPA.JK")
40
+
41
+ start_date_stock1 = st.sidebar.date_input(f"Start date for {stock1}", datetime(2018, 1, 1), key=f"start_date_{stock1}")
42
+ end_date_stock1 = st.sidebar.date_input(f"End date for {stock1}", datetime(2023, 12, 1), key=f"end_date_{stock1}")
43
+ start_date_stock2 = st.sidebar.date_input(f"Start date for {stock2}", datetime(2018, 1, 1), key=f"start_date_{stock2}")
44
+ end_date_stock2 = st.sidebar.date_input(f"End date for {stock2}", datetime(2023, 12, 1), key=f"end_date_{stock2}")
45
+
46
+ # Button to trigger the comparison
47
+ if st.sidebar.button("Compare"):
48
+ # Load data for both stocks
49
+ data_stock1 = yf.download(stock1, start=start_date_stock1, end=end_date_stock1)
50
+ data_stock2 = yf.download(stock2, start=start_date_stock2, end=end_date_stock2)
51
+
52
+ # Plotting the data
53
+ fig = go.Figure()
54
+
55
+ fig.add_trace(go.Scatter(x=data_stock1.index, y=data_stock1['Close'], mode='lines', name=f'{stock1}'))
56
+ fig.add_trace(go.Scatter(x=data_stock2.index, y=data_stock2['Close'], mode='lines', name=f'{stock2}'))
57
+
58
+ fig.update_layout(title=f"Comparison of {stock1} and {stock2}", xaxis_title="Date", yaxis_title="Closing Price")
59
+
60
+ st.plotly_chart(fig)
61
+
62
+ st.sidebar.markdown("----")
63
+ st.sidebar.markdown("Β© 2023 Stock Comparison and Analysis")