akhaliq HF Staff commited on
Commit
7e53a19
Β·
verified Β·
1 Parent(s): 92f8ecb

Upload app.py with huggingface_hub

Browse files
Files changed (1) hide show
  1. app.py +112 -0
app.py ADDED
@@ -0,0 +1,112 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ import yfinance as yf
3
+ import pandas as pd
4
+ import plotly.graph_objects as go
5
+ from plotly.subplots import make_subplots
6
+ import datetime as dt
7
+
8
+ # Page config
9
+ st.set_page_config(
10
+ page_title="Stock Analysis Dashboard",
11
+ page_icon="πŸ“ˆ",
12
+ layout="wide"
13
+ )
14
+
15
+ # Sidebar
16
+ st.sidebar.header("Settings")
17
+ ticker = st.sidebar.text_input("Ticker Symbol", "AAPL").upper()
18
+ start = st.sidebar.date_input("Start Date", dt.date.today() - dt.timedelta(days=365))
19
+ end = st.sidebar.date_input("End Date", dt.date.today())
20
+
21
+ # Cache data
22
+ @st.cache_data
23
+ def fetch_data(ticker, start, end):
24
+ return yf.download(ticker, start=start, end=end)
25
+
26
+ # Main
27
+ st.title("πŸ“ˆ Stock Analysis Dashboard")
28
+ st.subheader(f"{ticker} ({start} – {end})")
29
+
30
+ # Fetch
31
+ data = fetch_data(ticker, start, end)
32
+
33
+ if data.empty:
34
+ st.error("No data found. Check ticker or date range.")
35
+ st.stop()
36
+
37
+ # KPIs
38
+ latest_close = data["Close"].iloc[-1]
39
+ prev_close = data["Close"].iloc[-2]
40
+ change = latest_close - prev_close
41
+ pct_change = (change / prev_close) * 100
42
+
43
+ col1, col2, col3, col4 = st.columns(4)
44
+ col1.metric("Close Price", f"${latest_close:,.2f}", f"{pct_change:+.2f}%")
45
+ col2.metric("Volume", f"{data['Volume'].iloc[-1]:,.0f}")
46
+ col3.metric("High", f"${data['High'].max():,.2f}")
47
+ col4.metric("Low", f"${data['Low'].min():,.2f}")
48
+
49
+ # Chart
50
+ fig = make_subplots(
51
+ rows=2, cols=1,
52
+ shared_xaxes=True,
53
+ vertical_spacing=0.03,
54
+ subplot_titles=("Price & Volume", "Volume"),
55
+ row_heights=[0.7, 0.3]
56
+ )
57
+
58
+ fig.add_trace(
59
+ go.Candlestick(
60
+ x=data.index,
61
+ open=data["Open"],
62
+ high=data["High"],
63
+ low=data["Low"],
64
+ close=data["Close"],
65
+ name="Candle"
66
+ ),
67
+ row=1, col=1
68
+ )
69
+
70
+ fig.add_trace(
71
+ go.Bar(
72
+ x=data.index,
73
+ y=data["Volume"],
74
+ name="Volume",
75
+ marker_color="#636EFA"
76
+ ),
77
+ row=2, col=1
78
+ )
79
+
80
+ fig.update_layout(
81
+ title=f"{ticker} Price & Volume",
82
+ xaxis_rangeslider_visible=False,
83
+ template="plotly_dark",
84
+ height=600,
85
+ showlegend=False
86
+ )
87
+
88
+ st.plotly_chart(fig, use_container_width=True)
89
+
90
+ # Moving averages
91
+ ma_window = st.sidebar.slider("Moving Average Window", 5, 200, 20)
92
+ data[f"MA{ma_window}"] = data["Close"].rolling(ma_window).mean()
93
+
94
+ st.subheader("Moving Average")
95
+ ma_fig = go.Figure()
96
+ ma_fig.add_trace(go.Scatter(x=data.index, y=data["Close"], name="Close"))
97
+ ma_fig.add_trace(go.Scatter(x=data.index, y=data[f"MA{ma_window}"], name=f"MA{ma_window}"))
98
+ ma_fig.update_layout(title=f"{ticker} Close vs MA{ma_window}", height=400)
99
+ st.plotly_chart(ma_fig, use_container_width=True)
100
+
101
+ # Download
102
+ @st.cache_data
103
+ def convert_df(df):
104
+ return df.to_csv().encode("utf-8")
105
+
106
+ csv = convert_df(data)
107
+ st.sidebar.download_button(
108
+ label="Download CSV",
109
+ data=csv,
110
+ file_name=f"{ticker}_{start}_{end}.csv",
111
+ mime="text/csv"
112
+ )