-
Notifications
You must be signed in to change notification settings - Fork 0
/
technical_analysis_app.py
152 lines (128 loc) · 4.07 KB
/
technical_analysis_app.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
149
150
151
152
import yfinance as yf
import streamlit as st
import datetime
import pandas as pd
import cufflinks as cf
from plotly.offline import iplot
# set offline mode for cufflinks
cf.go_offline()
## Data Functions
@st.cache_data
def get_sp500_components():
df = pd.read_html("https://en.wikipedia.org/wiki/List_of_S%26P_500_companies")
df = df[0]
tickers = df["Symbol"].to_list()
tickers_companies_dict = dict(
zip(df["Symbol"], df["Security"])
)
return tickers, tickers_companies_dict
@st.cache_data
def load_data(symbol, start, end):
return yf.download(symbol, start, end)
@st.cache_data
def convert_df_to_csv(df):
return df.to_csv().encode("utf-8")
## UI Functions
# inputs for downloading data
st.sidebar.header("Stock Parameters")
available_tickers, tickers_companies_dict = get_sp500_components()
ticker = st.sidebar.selectbox(
"Ticker",
available_tickers,
format_func=tickers_companies_dict.get
)
start_date = st.sidebar.date_input(
"Start date",
datetime.date(2019, 1, 1)
)
end_date = st.sidebar.date_input(
"End date",
datetime.date.today()
)
if start_date > end_date:
st.sidebar.error("The end date must fall after the start date")
# inputs for technical analysis
st.sidebar.header("Technical Analysis Parameters")
volume_flag = st.sidebar.checkbox(label="Add volume")
# Simple Moving Average
exp_sma = st.sidebar.expander("SMA")
sma_flag = exp_sma.checkbox(label="Add SMA")
sma_periods= exp_sma.number_input(
label="SMA Periods",
min_value=1,
max_value=50,
value=20,
step=1
)
# Bollinger Bands
exp_bb = st.sidebar.expander("Bollinger Bands")
bb_flag = exp_bb.checkbox(label="Add Bollinger Bands")
bb_periods = exp_bb.number_input(label="BB Periods",
min_value=1, max_value=50,
value=20, step=1)
bb_std = exp_bb.number_input(label="# of standard deviations",
min_value=1, max_value=4,
value=2, step=1)
# Relative Strength Index
exp_rsi = st.sidebar.expander("Relative Strength Index")
rsi_flag = exp_rsi.checkbox(label="Add RSI")
rsi_periods = exp_rsi.number_input(
label="RSI Periods",
min_value=1,
max_value=50,
value=20,
step=1
)
rsi_upper = exp_rsi.number_input(label="RSI Upper",
min_value=50,
max_value=90, value=70,
step=1)
rsi_lower = exp_rsi.number_input(label="RSI Lower",
min_value=10,
max_value=50, value=30,
step=1)
## Main Panel
st.title("A simple web app for technical analysis")
st.write("""
### User manual
* you can select any of the companies that is a component of the S&P index
* you can select the time period of your interest
* you can download the selected data as a CSV file
* you can add the following Technical Indicators to the plot: Simple Moving
Average, Bollinger Bands, Relative Strength Index
* you can experiment with different parameters of the indicators
""")
df = load_data(ticker, start_date, end_date)
# data preview
data_exp = st.expander("Preview data")
available_cols = df.columns.tolist()
columns_to_show = data_exp.multiselect(
"Columns",
available_cols,
default=available_cols
)
data_exp.dataframe(df[columns_to_show])
csv_file = convert_df_to_csv(df[columns_to_show])
data_exp.download_button(
label="Download selected as CSV",
data=csv_file,
file_name=f"{ticker}_stock_prices.csv",
mime="text/csv",
)
# technical analysis plot
title_str = f"{tickers_companies_dict[ticker]}'s stock price"
qf = cf.QuantFig(df, title=title_str)
if volume_flag:
qf.add_volume()
if sma_flag:
qf.add_sma(periods=sma_periods)
if bb_flag:
qf.add_bollinger_bands(periods=bb_periods,
boll_std=bb_std)
if rsi_flag:
qf.add_rsi(periods=rsi_periods,
rsi_upper=rsi_upper,
rsi_lower=rsi_lower,
showbands=True)
fig = qf.iplot(asFigure=True)
st.plotly_chart(fig)