stock-analysis / app.py
akhaliq's picture
akhaliq HF Staff
Upload app.py with huggingface_hub
7e53a19 verified
import streamlit as st
import yfinance as yf
import pandas as pd
import plotly.graph_objects as go
from plotly.subplots import make_subplots
import datetime as dt
# Page config
st.set_page_config(
page_title="Stock Analysis Dashboard",
page_icon="πŸ“ˆ",
layout="wide"
)
# Sidebar
st.sidebar.header("Settings")
ticker = st.sidebar.text_input("Ticker Symbol", "AAPL").upper()
start = st.sidebar.date_input("Start Date", dt.date.today() - dt.timedelta(days=365))
end = st.sidebar.date_input("End Date", dt.date.today())
# Cache data
@st.cache_data
def fetch_data(ticker, start, end):
return yf.download(ticker, start=start, end=end)
# Main
st.title("πŸ“ˆ Stock Analysis Dashboard")
st.subheader(f"{ticker} ({start} – {end})")
# Fetch
data = fetch_data(ticker, start, end)
if data.empty:
st.error("No data found. Check ticker or date range.")
st.stop()
# KPIs
latest_close = data["Close"].iloc[-1]
prev_close = data["Close"].iloc[-2]
change = latest_close - prev_close
pct_change = (change / prev_close) * 100
col1, col2, col3, col4 = st.columns(4)
col1.metric("Close Price", f"${latest_close:,.2f}", f"{pct_change:+.2f}%")
col2.metric("Volume", f"{data['Volume'].iloc[-1]:,.0f}")
col3.metric("High", f"${data['High'].max():,.2f}")
col4.metric("Low", f"${data['Low'].min():,.2f}")
# Chart
fig = make_subplots(
rows=2, cols=1,
shared_xaxes=True,
vertical_spacing=0.03,
subplot_titles=("Price & Volume", "Volume"),
row_heights=[0.7, 0.3]
)
fig.add_trace(
go.Candlestick(
x=data.index,
open=data["Open"],
high=data["High"],
low=data["Low"],
close=data["Close"],
name="Candle"
),
row=1, col=1
)
fig.add_trace(
go.Bar(
x=data.index,
y=data["Volume"],
name="Volume",
marker_color="#636EFA"
),
row=2, col=1
)
fig.update_layout(
title=f"{ticker} Price & Volume",
xaxis_rangeslider_visible=False,
template="plotly_dark",
height=600,
showlegend=False
)
st.plotly_chart(fig, use_container_width=True)
# Moving averages
ma_window = st.sidebar.slider("Moving Average Window", 5, 200, 20)
data[f"MA{ma_window}"] = data["Close"].rolling(ma_window).mean()
st.subheader("Moving Average")
ma_fig = go.Figure()
ma_fig.add_trace(go.Scatter(x=data.index, y=data["Close"], name="Close"))
ma_fig.add_trace(go.Scatter(x=data.index, y=data[f"MA{ma_window}"], name=f"MA{ma_window}"))
ma_fig.update_layout(title=f"{ticker} Close vs MA{ma_window}", height=400)
st.plotly_chart(ma_fig, use_container_width=True)
# Download
@st.cache_data
def convert_df(df):
return df.to_csv().encode("utf-8")
csv = convert_df(data)
st.sidebar.download_button(
label="Download CSV",
data=csv,
file_name=f"{ticker}_{start}_{end}.csv",
mime="text/csv"
)