Spaces:
Running
Running
app
Browse files- Trading_App.py +52 -0
- pages/Stock_Analysis.py +326 -0
- pages/stock_prediction.py +161 -0
- stock_image.jpg +0 -0
Trading_App.py
ADDED
@@ -0,0 +1,52 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import streamlit as st
|
2 |
+
|
3 |
+
# Page configuration
|
4 |
+
st.set_page_config(
|
5 |
+
page_title="Trading App",
|
6 |
+
page_icon="๐",
|
7 |
+
layout="wide"
|
8 |
+
)
|
9 |
+
|
10 |
+
# Title and Header
|
11 |
+
st.title("Trading App ๐")
|
12 |
+
st.header("Empowering Your Investment Journey")
|
13 |
+
|
14 |
+
# Introduction with quotes
|
15 |
+
st.subheader("โAn investment in knowledge pays the best interest.โ โ Benjamin Franklin")
|
16 |
+
st.write("Welcome to the **Trading App**, your trusted companion in navigating the financial markets. Whether you're a seasoned investor or just starting, our platform offers all the tools and insights you need to make informed decisions.")
|
17 |
+
|
18 |
+
# Stock Image
|
19 |
+
st.image('stock_image.jpg', use_column_width=True)
|
20 |
+
|
21 |
+
# Overview of App Features
|
22 |
+
st.markdown("## What We Offer")
|
23 |
+
st.write("""
|
24 |
+
Our app is designed to cater to every step of your investment process:
|
25 |
+
- **Stock Information Page**: Learn about key financial metrics, historical data, and current stock trends.
|
26 |
+
- **Stock Analysis Page**: Dive deep into stock fundamentals and explore technical analysis tools.
|
27 |
+
- **Stock Prediction Page**: Use advanced machine learning models to predict future stock performance.
|
28 |
+
""")
|
29 |
+
|
30 |
+
# Add a motivational quote
|
31 |
+
st.markdown("### ๐ Quote of the Day")
|
32 |
+
st.info("โThe stock market is filled with individuals who know the price of everything but the value of nothing.โ โ Philip Fisher")
|
33 |
+
|
34 |
+
|
35 |
+
st.markdown("### ๐ Did You Know?")
|
36 |
+
st.write("""
|
37 |
+
The New York Stock Exchange (NYSE) is the largest stock exchange in the world by market capitalization,
|
38 |
+
with a total value exceeding **$25 trillion**! Understanding the markets begins with knowing the incredible scale of global finance.
|
39 |
+
""")
|
40 |
+
|
41 |
+
# App Navigation Details
|
42 |
+
st.markdown("### How to Get Started")
|
43 |
+
st.write("""
|
44 |
+
1. Navigate to the **Stock Information** page to explore comprehensive stock details.
|
45 |
+
2. Move to the **Stock Analysis** page for in-depth analysis of your favorite stocks.
|
46 |
+
3. Visit the **Stock Prediction** page to forecast stock prices using cutting-edge technology.
|
47 |
+
""")
|
48 |
+
|
49 |
+
# Footer
|
50 |
+
st.markdown("---")
|
51 |
+
st.markdown("### Ready to take charge of your financial future? ๐")
|
52 |
+
st.markdown("โThe best time to invest was yesterday. The second-best time is today!โ")
|
pages/Stock_Analysis.py
ADDED
@@ -0,0 +1,326 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import dateutil.relativedelta
|
2 |
+
import streamlit as st
|
3 |
+
import pandas as pd
|
4 |
+
import yfinance as yf
|
5 |
+
import plotly.graph_objects as go
|
6 |
+
import datetime
|
7 |
+
import dateutil
|
8 |
+
import ta
|
9 |
+
import plotly.express as px
|
10 |
+
import pandas_ta as pta
|
11 |
+
import numpy as np
|
12 |
+
npNaN = np.nan
|
13 |
+
st.set_page_config(
|
14 |
+
page_title="Stock Analysis",
|
15 |
+
page_icon="page_with_curl",
|
16 |
+
layout='wide'
|
17 |
+
)
|
18 |
+
|
19 |
+
st.title("Stock Analysis")
|
20 |
+
|
21 |
+
col1,col2,col3 =st.columns(3)
|
22 |
+
|
23 |
+
today= datetime.date.today()
|
24 |
+
|
25 |
+
with col1:
|
26 |
+
ticker =st.text_input("Stocker Ticker","TSLA")
|
27 |
+
with col2:
|
28 |
+
start_date = st.date_input("choose Start Date",datetime.date(today.year -1,today.month,today.day))
|
29 |
+
with col3:
|
30 |
+
end_date = st.date_input("choose End Date",datetime.date(today.year,today.month,today.day))
|
31 |
+
|
32 |
+
st.subheader(ticker)
|
33 |
+
stock = yf.Ticker(ticker)
|
34 |
+
try:
|
35 |
+
info = stock.get_info()
|
36 |
+
st.write(stock.info['longBusinessSummary'])
|
37 |
+
st.write("**Sector:**",stock.info['sector'])
|
38 |
+
st.write("**Full Time Employees:**",stock.info['fullTimeEmployees'])
|
39 |
+
st.write("**Website:**",stock.info['website'])
|
40 |
+
except Exception as e:
|
41 |
+
print(f"Error: {e}")
|
42 |
+
|
43 |
+
col1= st.columns(1)[0]
|
44 |
+
with col1:
|
45 |
+
df = pd.DataFrame({
|
46 |
+
"Metric": ["Market Cap", "Beta", "EPS", "PE Ratio","profitMargins",'revenuePerShare','financialCurrency'],
|
47 |
+
"Value": [
|
48 |
+
stock.info['marketCap'],
|
49 |
+
stock.info['beta'],
|
50 |
+
stock.info['trailingEps'],
|
51 |
+
stock.info['trailingPE'],
|
52 |
+
stock.info['profitMargins'],
|
53 |
+
stock.info['revenuePerShare'],
|
54 |
+
stock.info['financialCurrency']
|
55 |
+
|
56 |
+
|
57 |
+
]
|
58 |
+
})
|
59 |
+
st.dataframe(df.style.set_properties(**{'font-size': '20px'}),width=1000)
|
60 |
+
|
61 |
+
data = yf.download(ticker,start=start_date,end= end_date)
|
62 |
+
|
63 |
+
col1,col2,col3 = st.columns(3)
|
64 |
+
daily_change = data['Close'].iloc[-1] - data['Close'].iloc[-2]
|
65 |
+
col1.metric("Daily Change",str(round(data['Close'].iloc[-1],2)),str(round(daily_change,2)))
|
66 |
+
|
67 |
+
# Display historical data based on start and end date
|
68 |
+
filtered_data = data[(data.index >= pd.to_datetime(start_date)) & (data.index <= pd.to_datetime(end_date))]
|
69 |
+
|
70 |
+
st.title(f"Historical Data ({start_date} to {end_date})")
|
71 |
+
st.dataframe(filtered_data.sort_index(ascending=False).round(3).style.set_properties(**{'font-size': '20px'}), width=1000)
|
72 |
+
|
73 |
+
col1,col2,col3,col4,col5,col6,col7=st.columns([1,1,1,1,1,1,1])
|
74 |
+
|
75 |
+
num_period=''
|
76 |
+
with col1:
|
77 |
+
if st.button("5D"):
|
78 |
+
num_period="5d"
|
79 |
+
with col2:
|
80 |
+
if st.button("1M"):
|
81 |
+
num_period="1mo"
|
82 |
+
with col3:
|
83 |
+
if st.button("6M"):
|
84 |
+
num_period="6mo"
|
85 |
+
with col4:
|
86 |
+
if st.button("YTD"):
|
87 |
+
num_period='ytd'
|
88 |
+
with col5:
|
89 |
+
if st.button("1Y"):
|
90 |
+
num_period='1y'
|
91 |
+
with col6:
|
92 |
+
if st.button("5Y"):
|
93 |
+
num_period='5y'
|
94 |
+
with col7:
|
95 |
+
if st.button("MAX"):
|
96 |
+
num_period= 'max'
|
97 |
+
|
98 |
+
##
|
99 |
+
def filter_data(dataframe,num_period):
|
100 |
+
if num_period =='1mo':
|
101 |
+
date = dataframe.index[-1] + dateutil.relativedelta.relativedelta(months=-1)
|
102 |
+
elif num_period == '5d':
|
103 |
+
date =dataframe.index[-1] + dateutil.relativedelta.relativedelta(days=-5)
|
104 |
+
elif num_period == '6mo':
|
105 |
+
date =dataframe.index[-1] + dateutil.relativedelta.relativedelta(months=-6)
|
106 |
+
elif num_period == '1y':
|
107 |
+
date =dataframe.index[-1] + dateutil.relativedelta.relativedelta(years=-1)
|
108 |
+
elif num_period == '5y':
|
109 |
+
date =dataframe.index[-1] + dateutil.relativedelta.relativedelta(years=-5)
|
110 |
+
elif num_period == 'ytd':
|
111 |
+
date = datetime.datetime(dataframe.index[-1].year,1,1).strftime("%Y-%m-%d")
|
112 |
+
else:
|
113 |
+
date = dataframe.index[0]
|
114 |
+
dataframe_reset = dataframe.reset_index() # Reset index to create a 'Date' column
|
115 |
+
return dataframe_reset[dataframe_reset['Date'] > date]
|
116 |
+
|
117 |
+
def close_chart(dataframe,num_period=False):
|
118 |
+
if num_period:
|
119 |
+
dataframe =filter_data(dataframe,num_period)
|
120 |
+
fig =go.Figure()
|
121 |
+
fig.add_trace(go.Scatter(
|
122 |
+
x=dataframe['Date'],y= dataframe['Open'],
|
123 |
+
mode='lines',
|
124 |
+
name ='Open',line =dict(width=2,color='#5ab7ff')
|
125 |
+
))
|
126 |
+
fig.add_trace(go.Scatter(
|
127 |
+
x=dataframe['Date'],y= dataframe['Close'],
|
128 |
+
mode='lines',
|
129 |
+
name ='Close',line =dict(width=2,color='black')
|
130 |
+
))
|
131 |
+
fig.add_trace(go.Scatter(
|
132 |
+
x=dataframe["Date"],y= dataframe['High'],
|
133 |
+
mode='lines',
|
134 |
+
name ='High',line =dict(width=2,color='#0078ff')
|
135 |
+
))
|
136 |
+
|
137 |
+
fig.add_trace(go.Scatter(
|
138 |
+
x=dataframe["Date"],y= dataframe['Low'],
|
139 |
+
mode='lines',
|
140 |
+
name ='Low',line =dict(width=2,color='red')
|
141 |
+
))
|
142 |
+
fig.update_xaxes(rangeslider_visible = True)
|
143 |
+
fig.update_layout(
|
144 |
+
height=500,
|
145 |
+
margin=dict(l=0, r=20, t=20, b=0),
|
146 |
+
plot_bgcolor='white',
|
147 |
+
paper_bgcolor='#E1EFFF',
|
148 |
+
legend=dict(yanchor='top', xanchor='right'),
|
149 |
+
xaxis_title="Date", # Add this
|
150 |
+
yaxis_title="Price", # Add this
|
151 |
+
)
|
152 |
+
|
153 |
+
return fig
|
154 |
+
|
155 |
+
|
156 |
+
def candlestick(dataframe,num_period):
|
157 |
+
dataframe = filter_data(dataframe,num_period)
|
158 |
+
fig=go.Figure()
|
159 |
+
fig.add_trace(go.Candlestick(x=dataframe['Date'],
|
160 |
+
open =dataframe['Open'],high=dataframe['High'],
|
161 |
+
low = dataframe['Low'],close=dataframe['Close']
|
162 |
+
))
|
163 |
+
fig.update_layout(
|
164 |
+
xaxis_title="Date", # Add this
|
165 |
+
yaxis_title="Price", # Add this
|
166 |
+
showlegend=False,
|
167 |
+
height=500,
|
168 |
+
margin=dict(l=0, r=20, t=20, b=0),
|
169 |
+
plot_bgcolor='white',
|
170 |
+
paper_bgcolor='#E1EFFF'
|
171 |
+
)
|
172 |
+
|
173 |
+
return fig
|
174 |
+
|
175 |
+
def RSI(dataframe,num_period):
|
176 |
+
dataframe['RSI']= pta.rsi(dataframe['Close'])
|
177 |
+
dataframe = filter_data(dataframe,num_period)
|
178 |
+
fig = go.Figure()
|
179 |
+
fig.add_trace(go.Scatter(
|
180 |
+
x=dataframe['Date'],
|
181 |
+
y=dataframe.RSI,name='RSI',marker_color='orange',line= dict(width=2,color ='orange'),
|
182 |
+
))
|
183 |
+
fig.add_trace(go.Scatter(
|
184 |
+
x=dataframe['Date'],
|
185 |
+
y=[70]*len(dataframe),name='Overbought',marker_color='red',line= dict(width=2,color ='red',dash='dash'),
|
186 |
+
))
|
187 |
+
fig.add_trace(go.Scatter(
|
188 |
+
x=dataframe['Date'],
|
189 |
+
y=[30]*len(dataframe),fill='tonexty',name='Oversold',marker_color='#79da84',
|
190 |
+
line= dict(width=2,color ='#79da84',dash='dash')
|
191 |
+
))
|
192 |
+
fig.update_layout(
|
193 |
+
xaxis_title='Date',
|
194 |
+
yaxis_title='RSI',
|
195 |
+
height=500,
|
196 |
+
margin=dict(l=0, r=20, t=20, b=0),
|
197 |
+
plot_bgcolor='white',
|
198 |
+
paper_bgcolor='#E1EFFF'
|
199 |
+
)
|
200 |
+
return fig
|
201 |
+
|
202 |
+
|
203 |
+
def Moving_average(dataframe,num_period):
|
204 |
+
dataframe['SMA_50']=pta.sma(dataframe['Close'],50)
|
205 |
+
dataframe = filter_data(dataframe,num_period)
|
206 |
+
if dataframe['SMA_50'].isna().sum() > 0:
|
207 |
+
st.warning("Not enough data to calculate the moving average.")
|
208 |
+
fig=go.Figure()
|
209 |
+
fig.add_trace(go.Scatter(
|
210 |
+
x=dataframe['Date'],y= dataframe['Open'],
|
211 |
+
mode='lines',
|
212 |
+
name ='Open',line =dict(width=2,color='#5ab7ff')
|
213 |
+
))
|
214 |
+
fig.add_trace(go.Scatter(
|
215 |
+
x=dataframe['Date'],y= dataframe['Close'],
|
216 |
+
mode='lines',
|
217 |
+
name ='Open',line =dict(width=2,color='black')
|
218 |
+
))
|
219 |
+
fig.add_trace(go.Scatter(
|
220 |
+
x=dataframe["Date"],y= dataframe['High'],
|
221 |
+
mode='lines',
|
222 |
+
name ='Open',line =dict(width=2,color='#0078ff')
|
223 |
+
))
|
224 |
+
|
225 |
+
fig.add_trace(go.Scatter(
|
226 |
+
x=dataframe["Date"],y= dataframe['Low'],
|
227 |
+
mode='lines',
|
228 |
+
name ='Open',line =dict(width=2,color='red')
|
229 |
+
))
|
230 |
+
fig.add_traces(go.Scatter(
|
231 |
+
x=dataframe["Date"],y= dataframe['SMA_50'],
|
232 |
+
mode='lines',
|
233 |
+
name ='SMA 50',line =dict(width=2,color='purple')
|
234 |
+
))
|
235 |
+
fig.update_xaxes(rangeslider_visible = True)
|
236 |
+
fig.update_layout(
|
237 |
+
xaxis_title="Date", # Add this
|
238 |
+
yaxis_title="Price", # Add this
|
239 |
+
height=500,
|
240 |
+
margin=dict(l=0, r=20, t=20, b=0),
|
241 |
+
plot_bgcolor='white',
|
242 |
+
paper_bgcolor='#E1EFFF',
|
243 |
+
legend=dict(yanchor='top', xanchor='right')
|
244 |
+
)
|
245 |
+
|
246 |
+
return fig
|
247 |
+
|
248 |
+
|
249 |
+
def MACD(dataframe,num_period):
|
250 |
+
macd = pta.macd(dataframe['Close']).iloc[:,0]
|
251 |
+
macd_signal = pta.macd(dataframe['Close']).iloc[:,1]
|
252 |
+
macd_hist =pta.macd(dataframe['Close']).iloc[:,2]
|
253 |
+
dataframe['MACD'] = macd
|
254 |
+
dataframe['MACD-Signal']=macd_signal
|
255 |
+
dataframe['MACD-Hist']=macd_hist
|
256 |
+
dataframe = filter_data(dataframe,num_period)
|
257 |
+
fig = go.Figure()
|
258 |
+
fig.add_trace(go.Scatter(
|
259 |
+
x=dataframe['Date'],
|
260 |
+
y=dataframe['MACD'],name='RSI',marker_color='orange',line=dict(width=2,color='orange'),
|
261 |
+
))
|
262 |
+
fig.add_trace(go.Scatter(
|
263 |
+
x=dataframe['Date'],
|
264 |
+
y=dataframe['MACD-Signal'],name='Overbought',marker_color ='red',line =dict(width=2,color='red',dash='dash'),
|
265 |
+
))
|
266 |
+
c=['red' if cl<0 else 'green' for cl in macd_hist]
|
267 |
+
|
268 |
+
return fig
|
269 |
+
|
270 |
+
|
271 |
+
col1,col2,col3 = st.columns([1,1,4])
|
272 |
+
|
273 |
+
with col1:
|
274 |
+
char_type =st.selectbox('',('Candle','line'))
|
275 |
+
with col2:
|
276 |
+
if char_type == 'Candle':
|
277 |
+
|
278 |
+
indicators = st.selectbox('',('RSI','MACD'))
|
279 |
+
else:
|
280 |
+
indicators = st.selectbox('',('RSI','Moving Average','MACD'))
|
281 |
+
|
282 |
+
ticker_ = yf.Ticker(ticker)
|
283 |
+
new_df1=ticker_.history(period='max')
|
284 |
+
data1= ticker_.history(period='max')
|
285 |
+
if num_period == '':
|
286 |
+
|
287 |
+
if char_type == 'Candle' and indicators == 'RSI':
|
288 |
+
st.plotly_chart(candlestick(new_df1,'1y'),use_container_width=True)
|
289 |
+
st.plotly_chart(RSI(new_df1,'1y'),use_container_width=True)
|
290 |
+
|
291 |
+
if char_type == 'Candle' and indicators == 'MACD':
|
292 |
+
st.plotly_chart(candlestick(new_df1,'1y'),use_container_width=True)
|
293 |
+
st.plotly_chart(MACD(new_df1,'1y'),use_container_width=True)
|
294 |
+
|
295 |
+
if char_type == 'line' and indicators == 'RSI':
|
296 |
+
st.plotly_chart(close_chart(new_df1,'1y'),use_container_width=True)
|
297 |
+
st.plotly_chart(RSI(new_df1,'1y'),use_container_width=True)
|
298 |
+
|
299 |
+
if char_type == 'line' and indicators == 'Moving Average':
|
300 |
+
st.plotly_chart(Moving_average(new_df1,'1y'),use_container_width=True)
|
301 |
+
|
302 |
+
if char_type == 'line' and indicators == 'MACD':
|
303 |
+
st.plotly_chart(close_chart(new_df1,'1y'),use_container_width=True)
|
304 |
+
st.plotly_chart(MACD(new_df1,'1y'),use_container_width=True)
|
305 |
+
|
306 |
+
else:
|
307 |
+
if char_type == 'Candle' and indicators == 'RSI':
|
308 |
+
st.plotly_chart(candlestick(new_df1,num_period),use_container_width=True)
|
309 |
+
st.plotly_chart(RSI(new_df1,num_period),use_container_width=True)
|
310 |
+
|
311 |
+
if char_type == 'Candle' and indicators == 'MACD':
|
312 |
+
st.plotly_chart(candlestick(new_df1,num_period),use_container_width=True)
|
313 |
+
st.plotly_chart(MACD(new_df1,num_period),use_container_width=True)
|
314 |
+
|
315 |
+
if char_type == 'line' and indicators == 'RSI':
|
316 |
+
st.plotly_chart(close_chart(new_df1,num_period),use_container_width=True)
|
317 |
+
st.plotly_chart(RSI(new_df1,num_period),use_container_width=True)
|
318 |
+
|
319 |
+
if char_type == 'line' and indicators == 'Moving Average':
|
320 |
+
st.plotly_chart(Moving_average(new_df1,num_period),use_container_width=True)
|
321 |
+
|
322 |
+
if char_type == 'line' and indicators == 'MACD':
|
323 |
+
st.plotly_chart(close_chart(new_df1,num_period),use_container_width=True)
|
324 |
+
st.plotly_chart(MACD(new_df1,num_period),use_container_width=True)
|
325 |
+
|
326 |
+
|
pages/stock_prediction.py
ADDED
@@ -0,0 +1,161 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import yfinance as yf
|
2 |
+
from statsmodels.tsa.stattools import adfuller
|
3 |
+
from sklearn.metrics import mean_squared_error,r2_score
|
4 |
+
from statsmodels.tsa.arima.model import ARIMA
|
5 |
+
import numpy as np
|
6 |
+
from sklearn.preprocessing import StandardScaler
|
7 |
+
from datetime import datetime, timedelta
|
8 |
+
import pandas as pd
|
9 |
+
import streamlit as st
|
10 |
+
import plotly.graph_objects as go
|
11 |
+
import plotly.express as px
|
12 |
+
|
13 |
+
st.set_page_config(
|
14 |
+
page_title="Stock Prediction",
|
15 |
+
page_icon="chart_with_upwords_trend",
|
16 |
+
layout= "wide"
|
17 |
+
)
|
18 |
+
|
19 |
+
st.title("Stock Prediction")
|
20 |
+
col1,clo2,clo3 = st.columns(3)
|
21 |
+
|
22 |
+
with col1:
|
23 |
+
ticker = st.text_input('Stock Ticker','AAPL')
|
24 |
+
|
25 |
+
def get_data(ticker):
|
26 |
+
stock_data = yf.download(ticker,start='2024-01-01')
|
27 |
+
return stock_data[['Close']]
|
28 |
+
|
29 |
+
|
30 |
+
def get_rollng_mean(close_price):
|
31 |
+
rolling_price = close_price.rolling(window=7).mean().dropna()
|
32 |
+
return rolling_price
|
33 |
+
|
34 |
+
def stationary_check(close_price):
|
35 |
+
adf_test=adfuller(close_price)
|
36 |
+
p_value=round(adf_test[1],3)
|
37 |
+
return p_value
|
38 |
+
|
39 |
+
|
40 |
+
def get_differencing_order(close_price):
|
41 |
+
p_value = stationary_check(close_price)
|
42 |
+
d=0
|
43 |
+
while True:
|
44 |
+
if p_value > 0.05:
|
45 |
+
d=d+1
|
46 |
+
close_price=close_price.diff().dropna()
|
47 |
+
p_value = stationary_check(close_price)
|
48 |
+
else:
|
49 |
+
break
|
50 |
+
return d
|
51 |
+
|
52 |
+
|
53 |
+
def scaling(close_price):
|
54 |
+
scaler = StandardScaler()
|
55 |
+
scaled_data = scaler.fit_transform(np.array(close_price).reshape(-1,1))
|
56 |
+
return scaled_data,scaler
|
57 |
+
|
58 |
+
rmse =0
|
59 |
+
st.subheader('Predicting Next 30 days Close Price for :-'+ticker)
|
60 |
+
close_price = get_data(ticker)
|
61 |
+
rolling_price = get_rollng_mean(close_price)
|
62 |
+
|
63 |
+
differencing_order= get_differencing_order(rolling_price)
|
64 |
+
|
65 |
+
def fit_model(data,differencing_order):
|
66 |
+
model =ARIMA(data,order=(7,differencing_order,7))
|
67 |
+
model_fit =model.fit()
|
68 |
+
forcast_steps=30
|
69 |
+
forcast = model_fit.get_forecast(steps=forcast_steps)
|
70 |
+
predictions = forcast.predicted_mean
|
71 |
+
return predictions
|
72 |
+
|
73 |
+
def evaluate_model(original_price,differencing_order):
|
74 |
+
train_data, test_data =original_price[:-30], original_price[-30:]
|
75 |
+
predictions = fit_model(train_data,differencing_order)
|
76 |
+
rmse= np.sqrt(mean_squared_error(test_data,predictions))
|
77 |
+
return round(rmse,2)
|
78 |
+
|
79 |
+
scaled_data,scaler=scaling(rolling_price)
|
80 |
+
rmse = evaluate_model(scaled_data,differencing_order)
|
81 |
+
|
82 |
+
def get_forecast(orignal_price,differencing_order):
|
83 |
+
predictions = fit_model(orignal_price,differencing_order)
|
84 |
+
start_date = datetime.now().strftime('%Y-%m-%d')
|
85 |
+
end_date = (datetime.now() + timedelta(days=29)).strftime('%Y-%m-%d')
|
86 |
+
forecast_index = pd.date_range(start=start_date,end=end_date,freq='D')
|
87 |
+
forecast_df= pd.DataFrame(predictions,index=forecast_index,columns= ['Close'])
|
88 |
+
return forecast_df
|
89 |
+
|
90 |
+
def inverse_scaling(scaler,scaled_data):
|
91 |
+
close_price = scaler.inverse_transform(np.array(scaled_data).reshape(-1,1))
|
92 |
+
return close_price
|
93 |
+
|
94 |
+
|
95 |
+
st.write("**Model RMSE Score**",rmse)
|
96 |
+
|
97 |
+
forecast= get_forecast(scaled_data,differencing_order)
|
98 |
+
|
99 |
+
forecast['Close']= inverse_scaling(scaler,forecast['Close'])
|
100 |
+
|
101 |
+
st.write('#### Forecast Data (Next 30 days)')
|
102 |
+
|
103 |
+
df_1=forecast.sort_index(ascending=True).round(3)
|
104 |
+
st.dataframe(df_1.style.set_properties(**{'font-size': '20px'}),width=1000)
|
105 |
+
|
106 |
+
forecast = pd.concat([rolling_price,forecast])
|
107 |
+
|
108 |
+
|
109 |
+
# def Moving_average_forecast(forecast):
|
110 |
+
# # Ensure enough data exists
|
111 |
+
# if len(forecast) <= 30:
|
112 |
+
# return "Not enough data to plot."
|
113 |
+
|
114 |
+
# # Convert index to datetime if needed
|
115 |
+
# if not isinstance(forecast.index, pd.DatetimeIndex):
|
116 |
+
# forecast.index = pd.to_datetime(forecast.index)
|
117 |
+
|
118 |
+
# fig = go.Figure()
|
119 |
+
|
120 |
+
# # First trace: Past close prices
|
121 |
+
# if len(forecast.index[:-30]) > 0:
|
122 |
+
# fig.add_trace(go.Scatter(
|
123 |
+
# x=forecast.index[:-30],
|
124 |
+
# y=forecast['Close'].iloc[:-30],
|
125 |
+
# mode='lines',
|
126 |
+
# name='Close Price',
|
127 |
+
# line=dict(width=2, color='blue')
|
128 |
+
# ))
|
129 |
+
# else:
|
130 |
+
# st.warning("No data available for past close prices.")
|
131 |
+
|
132 |
+
# # Second trace: Future close prices
|
133 |
+
# if len(forecast.index[-31:]) > 0:
|
134 |
+
# fig.add_trace(go.Scatter(
|
135 |
+
# x=forecast.index[-31:],
|
136 |
+
# y=forecast['Close'].iloc[-31:],
|
137 |
+
# mode='lines',
|
138 |
+
# name='Future Close Price',
|
139 |
+
# line=dict(width=2, color='red')
|
140 |
+
# ))
|
141 |
+
# else:
|
142 |
+
# st.warning("No data available for future close prices.")
|
143 |
+
|
144 |
+
# fig.update_layout(
|
145 |
+
# title="Moving Average Forecast",
|
146 |
+
# xaxis_title="Date",
|
147 |
+
# yaxis_title="Close Price",
|
148 |
+
# height=500,
|
149 |
+
# plot_bgcolor='white',
|
150 |
+
# paper_bgcolor='#E1EFFF',
|
151 |
+
# legend=dict(yanchor='top', xanchor='right')
|
152 |
+
# )
|
153 |
+
|
154 |
+
# return fig
|
155 |
+
|
156 |
+
# # Plot with debug checks
|
157 |
+
# fig = Moving_average_forecast(forecast.iloc[150:])
|
158 |
+
# if isinstance(fig, str):
|
159 |
+
# st.warning(fig)
|
160 |
+
# else:
|
161 |
+
# st.plotly_chart(fig, use_container_width=True)
|
stock_image.jpg
ADDED
![]() |