Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
|
@@ -12,13 +12,8 @@ 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",
|
|
@@ -43,54 +38,30 @@ sidebar_css = """
|
|
| 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 |
-
|
| 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}")
|
|
@@ -133,8 +104,6 @@ try:
|
|
| 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']
|
|
@@ -169,8 +138,6 @@ try:
|
|
| 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']
|
|
@@ -182,13 +149,8 @@ try:
|
|
| 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')
|
|
@@ -259,39 +221,6 @@ try:
|
|
| 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))
|
|
@@ -425,92 +354,5 @@ try:
|
|
| 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)}")
|
|
|
|
| 12 |
import plotly.express as px
|
| 13 |
from datetime import datetime
|
| 14 |
|
|
|
|
|
|
|
|
|
|
| 15 |
st.set_page_config(page_title='Regression Stocks Prediction', layout='wide', page_icon=':rocket:')
|
| 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",
|
|
|
|
| 38 |
</style>
|
| 39 |
"""
|
| 40 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 41 |
user_input = st.sidebar.text_input("Select a Stock", "MAPI.JK")
|
| 42 |
|
|
|
|
| 43 |
start_date = st.sidebar.date_input("Select start date:", datetime(2023, 1, 1))
|
| 44 |
end_date = st.sidebar.date_input("Select end date:", datetime(2023, 12, 1))
|
| 45 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 46 |
st.sidebar.markdown("Example Stock Tickers")
|
| 47 |
st.sidebar.markdown(stock_tickers)
|
| 48 |
|
| 49 |
+
st.title("IN-Depth Analysis")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 50 |
|
|
|
|
| 51 |
try:
|
| 52 |
stock_info = yf.Ticker(user_input).info
|
| 53 |
|
|
|
|
| 54 |
if 'longName' in stock_info:
|
| 55 |
stock_name = stock_info['longName']
|
| 56 |
else:
|
| 57 |
stock_name = user_input
|
| 58 |
|
|
|
|
| 59 |
news_data = yf.Ticker(user_input).news
|
| 60 |
|
| 61 |
+
title = f"<h1 style='color: while; font-size: 25px; text-align: center; '>{stock_name}'s Stock Fundamental Analysis</h1>"
|
|
|
|
| 62 |
st.markdown(title, unsafe_allow_html=True)
|
| 63 |
|
| 64 |
with st.expander("See Details"):
|
|
|
|
|
|
|
| 65 |
if 'longName' in stock_info:
|
| 66 |
company_name = stock_info['longName']
|
| 67 |
st.write(f"Company Name: {company_name}")
|
|
|
|
| 104 |
else:
|
| 105 |
st.write("Dividend Yield information not available for this stock.")
|
| 106 |
|
|
|
|
|
|
|
| 107 |
st.subheader('Financial Metrics')
|
| 108 |
if 'trailingEps' in stock_info:
|
| 109 |
trailing_eps = stock_info['trailingEps']
|
|
|
|
| 138 |
else:
|
| 139 |
st.write("Company Summary information not available for this stock.")
|
| 140 |
|
|
|
|
|
|
|
| 141 |
st.subheader('Company Officers')
|
| 142 |
if 'fullTimeEmployees' in stock_info:
|
| 143 |
FullTimeEmployees = stock_info['fullTimeEmployees']
|
|
|
|
| 149 |
officers = stock_info['companyOfficers']
|
| 150 |
officer_data = []
|
| 151 |
|
|
|
|
| 152 |
df = pd.DataFrame(columns=["Name", "Title", "Age"])
|
| 153 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 154 |
for officer in officers:
|
| 155 |
name = officer.get('name', 'N/A')
|
| 156 |
title = officer.get('title', 'N/A')
|
|
|
|
| 221 |
|
| 222 |
st.plotly_chart(fig, use_container_width=True)
|
| 223 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 224 |
### ............................................... ##
|
| 225 |
# Stock Price Over Time
|
| 226 |
g1, g2, g3 = st.columns((1.2,1.2,1))
|
|
|
|
| 354 |
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)
|
| 355 |
g15.plotly_chart(fig15, use_container_width=True)
|
| 356 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 357 |
except Exception as e:
|
| 358 |
st.error(f"An error fetching stock information: {str(e)}")
|