File size: 2,808 Bytes
7e53a19
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
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"
)