-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathapp.py
More file actions
74 lines (63 loc) · 2.83 KB
/
app.py
File metadata and controls
74 lines (63 loc) · 2.83 KB
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
import yfinance as yf
import pandas as pd
from bokeh.io import curdoc
from bokeh.layouts import column, row
from bokeh.models import ColumnDataSource, Select, CheckboxGroup, Div
from bokeh.plotting import figure
from bokeh.models.tools import HoverTool
# Available stocks and indicators
stocks = ['AAPL', 'GOOGL', 'MSFT', 'TSLA', 'AMZN']
indicators = ['SMA_20', 'EMA_20', 'RSI']
# Widgets
stock_select = Select(title="Select Stock:", value=stocks[0], options=stocks)
indicator_check = CheckboxGroup(labels=indicators, active=[0, 1]) # SMA and EMA selected by default
status_div = Div(text='')
# Data source
source = ColumnDataSource(data=dict(date=[], close=[], SMA_20=[], EMA_20=[], RSI=[]))
# Plot setup
p = figure(title="Stock Price", x_axis_type='datetime', width=1000, height=400)
p.line('date', 'close', source=source, line_width=2, color='navy', legend_label='Close Price')
p.add_tools(HoverTool(tooltips=[("Date", "@date{%F}"), ("Close", "@close")],
formatters={'@date': 'datetime'}, mode='vline'))
# Indicator lines
sma_line = p.line('date', 'SMA_20', source=source, line_width=2, color='green', legend_label='SMA 20')
ema_line = p.line('date', 'EMA_20', source=source, line_width=2, color='orange', legend_label='EMA 20')
rsi_plot = figure(title="RSI", x_axis_type='datetime', width=1000, height=200)
rsi_line = rsi_plot.line('date', 'RSI', source=source, line_width=2, color='purple', legend_label='RSI')
def fetch_data():
try:
ticker = stock_select.value
df = yf.download(ticker, period='6mo', interval='1d')
df.reset_index(inplace=True)
df['SMA_20'] = df['Close'].rolling(window=20).mean()
df['EMA_20'] = df['Close'].ewm(span=20, adjust=False).mean()
delta = df['Close'].diff()
gain = (delta.where(delta > 0, 0)).rolling(window=14).mean()
loss = (-delta.where(delta < 0, 0)).rolling(window=14).mean()
rs = gain / loss
df['RSI'] = 100 - (100 / (1 + rs))
df.fillna(method='bfill', inplace=True)
source.data = {
'date': df['Date'],
'close': df['Close'],
'SMA_20': df['SMA_20'],
'EMA_20': df['EMA_20'],
'RSI': df['RSI']
}
status_div.text = f"<b>Data fetched successfully for {ticker}</b>"
except Exception as e:
status_div.text = f"<b>Error fetching data: {e}</b>"
def update_plot(attr, old, new):
active = indicator_check.active
sma_line.visible = 0 in active
ema_line.visible = 1 in active
rsi_plot.visible = 2 in active
stock_select.on_change('value', lambda attr, old, new: fetch_data())
indicator_check.on_change('active', update_plot)
# Initial load
fetch_data()
update_plot(None, None, None)
# Layout
layout = column(status_div, row(stock_select, indicator_check), p, rsi_plot)
curdoc().add_root(layout)
curdoc().title = "Real-Time Stock Dashboard"