-
Notifications
You must be signed in to change notification settings - Fork 36
/
Copy pathstocks_dashboard.py
150 lines (120 loc) · 5.49 KB
/
stocks_dashboard.py
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
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
# Source: @DeepCharts Youtube Channel (https://www.youtube.com/@DeepCharts)
import streamlit as st
import plotly.express as px
import plotly.graph_objects as go
import pandas as pd
import yfinance as yf
from datetime import datetime, timedelta
import pytz
import ta
##########################################################################################
## PART 1: Define Functions for Pulling, Processing, and Creating Techincial Indicators ##
##########################################################################################
# Fetch stock data based on the ticker, period, and interval
def fetch_stock_data(ticker, period, interval):
end_date = datetime.now()
if period == '1wk':
start_date = end_date - timedelta(days=7)
data = yf.download(ticker, start=start_date, end=end_date, interval=interval)
else:
data = yf.download(ticker, period=period, interval=interval)
return data
# Process data to ensure it is timezone-aware and has the correct format
def process_data(data):
if data.index.tzinfo is None:
data.index = data.index.tz_localize('UTC')
data.index = data.index.tz_convert('US/Eastern')
data.reset_index(inplace=True)
data.rename(columns={'Date': 'Datetime'}, inplace=True)
return data
# Calculate basic metrics from the stock data
def calculate_metrics(data):
last_close = data['Close'].iloc[-1]
prev_close = data['Close'].iloc[0]
change = last_close - prev_close
pct_change = (change / prev_close) * 100
high = data['High'].max()
low = data['Low'].min()
volume = data['Volume'].sum()
return last_close, change, pct_change, high, low, volume
# Add simple moving average (SMA) and exponential moving average (EMA) indicators
def add_technical_indicators(data):
data['SMA_20'] = ta.trend.sma_indicator(data['Close'], window=20)
data['EMA_20'] = ta.trend.ema_indicator(data['Close'], window=20)
return data
###############################################
## PART 2: Creating the Dashboard App layout ##
###############################################
# Set up Streamlit page layout
st.set_page_config(layout="wide")
st.title('Real Time Stock Dashboard')
# 2A: SIDEBAR PARAMETERS ############
# Sidebar for user input parameters
st.sidebar.header('Chart Parameters')
ticker = st.sidebar.text_input('Ticker', 'ADBE')
time_period = st.sidebar.selectbox('Time Period', ['1d', '1wk', '1mo', '1y', 'max'])
chart_type = st.sidebar.selectbox('Chart Type', ['Candlestick', 'Line'])
indicators = st.sidebar.multiselect('Technical Indicators', ['SMA 20', 'EMA 20'])
# Mapping of time periods to data intervals
interval_mapping = {
'1d': '1m',
'1wk': '30m',
'1mo': '1d',
'1y': '1wk',
'max': '1wk'
}
# 2B: MAIN CONTENT AREA ############
# Update the dashboard based on user input
if st.sidebar.button('Update'):
data = fetch_stock_data(ticker, time_period, interval_mapping[time_period])
data = process_data(data)
data = add_technical_indicators(data)
last_close, change, pct_change, high, low, volume = calculate_metrics(data)
# Display main metrics
st.metric(label=f"{ticker} Last Price", value=f"{last_close:.2f} USD", delta=f"{change:.2f} ({pct_change:.2f}%)")
col1, col2, col3 = st.columns(3)
col1.metric("High", f"{high:.2f} USD")
col2.metric("Low", f"{low:.2f} USD")
col3.metric("Volume", f"{volume:,}")
# Plot the stock price chart
fig = go.Figure()
if chart_type == 'Candlestick':
fig.add_trace(go.Candlestick(x=data['Datetime'],
open=data['Open'],
high=data['High'],
low=data['Low'],
close=data['Close']))
else:
fig = px.line(data, x='Datetime', y='Close')
# Add selected technical indicators to the chart
for indicator in indicators:
if indicator == 'SMA 20':
fig.add_trace(go.Scatter(x=data['Datetime'], y=data['SMA_20'], name='SMA 20'))
elif indicator == 'EMA 20':
fig.add_trace(go.Scatter(x=data['Datetime'], y=data['EMA_20'], name='EMA 20'))
# Format graph
fig.update_layout(title=f'{ticker} {time_period.upper()} Chart',
xaxis_title='Time',
yaxis_title='Price (USD)',
height=600)
st.plotly_chart(fig, use_container_width=True)
# Display historical data and technical indicators
st.subheader('Historical Data')
st.dataframe(data[['Datetime', 'Open', 'High', 'Low', 'Close', 'Volume']])
st.subheader('Technical Indicators')
st.dataframe(data[['Datetime', 'SMA_20', 'EMA_20']])
# 2C: SIDEBAR PRICES ############
# Sidebar section for real-time stock prices of selected symbols
st.sidebar.header('Real-Time Stock Prices')
stock_symbols = ['AAPL', 'GOOGL', 'AMZN', 'MSFT']
for symbol in stock_symbols:
real_time_data = fetch_stock_data(symbol, '1d', '1m')
if not real_time_data.empty:
real_time_data = process_data(real_time_data)
last_price = real_time_data['Close'].iloc[-1]
change = last_price - real_time_data['Open'].iloc[0]
pct_change = (change / real_time_data['Open'].iloc[0]) * 100
st.sidebar.metric(f"{symbol}", f"{last_price:.2f} USD", f"{change:.2f} ({pct_change:.2f}%)")
# Sidebar information section
st.sidebar.subheader('About')
st.sidebar.info('This dashboard provides stock data and technical indicators for various time periods. Use the sidebar to customize your view.')