geethareddy commited on
Commit
e72394f
·
verified ·
1 Parent(s): cf7976c

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +230 -0
app.py ADDED
@@ -0,0 +1,230 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import yfinance as yf
2
+ import pandas as pd
3
+ import numpy as np
4
+ from sklearn.ensemble import RandomForestRegressor
5
+ from sklearn.metrics import mean_squared_error
6
+ from sklearn.model_selection import train_test_split
7
+ import gradio as gr
8
+ import matplotlib.pyplot as plt
9
+ from datetime import datetime, timedelta
10
+
11
+ # Define stock tickers
12
+ STOCK_TICKERS = [
13
+ "AAPL", # Apple
14
+ "GOOGL", # Alphabet
15
+ "MSFT", # Microsoft
16
+ "AMZN", # Amazon
17
+ "TSLA", # Tesla
18
+ "META", # Meta Platforms
19
+ "NVDA", # NVIDIA
20
+ "JPM", # JPMorgan Chase
21
+ "V", # Visa
22
+ "NFLX" # Netflix
23
+ ]
24
+
25
+ def fetch_stock_data(ticker: str, start_date: str, end_date: str) -> pd.DataFrame:
26
+ """
27
+ Fetches historical stock data from Yahoo Finance.
28
+
29
+ Parameters:
30
+ - ticker (str): Stock ticker symbol.
31
+ - start_date (str): Start date in 'YYYY-MM-DD' format.
32
+ - end_date (str): End date in 'YYYY-MM-DD' format.
33
+
34
+ Returns:
35
+ - pd.DataFrame: DataFrame containing stock data.
36
+ """
37
+ stock = yf.Ticker(ticker)
38
+ data = stock.history(start=start_date, end=end_date)
39
+ return data
40
+
41
+ def preprocess_data(data: pd.DataFrame) -> (np.ndarray, np.ndarray):
42
+ """
43
+ Preprocesses the stock data for Random Forest Regressor.
44
+
45
+ Parameters:
46
+ - data (pd.DataFrame): DataFrame containing stock data.
47
+
48
+ Returns:
49
+ - X (np.ndarray): Feature array.
50
+ - y (np.ndarray): Target array.
51
+ """
52
+ # Use 'Close' price for prediction
53
+ data['Target'] = data['Close'].shift(-1) # Predict next day's close price
54
+
55
+ # Drop the last row as it will have NaN target
56
+ data = data[:-1]
57
+
58
+ # Features can include current and past prices. Here, we'll use previous 5 days' close prices.
59
+ for i in range(1, 6):
60
+ data[f'Close_{i}'] = data['Close'].shift(i)
61
+
62
+ data.dropna(inplace=True)
63
+
64
+ feature_cols = [f'Close_{i}' for i in range(1, 6)]
65
+ X = data[feature_cols].values
66
+ y = data['Target'].values
67
+
68
+ return X, y
69
+
70
+ def train_model(X: np.ndarray, y: np.ndarray) -> RandomForestRegressor:
71
+ """
72
+ Trains the Random Forest Regressor model.
73
+
74
+ Parameters:
75
+ - X (np.ndarray): Feature array.
76
+ - y (np.ndarray): Target array.
77
+
78
+ Returns:
79
+ - model (RandomForestRegressor): Trained Random Forest model.
80
+ """
81
+ # Split the data into training and testing sets
82
+ X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, shuffle=False)
83
+
84
+ # Initialize the model
85
+ model = RandomForestRegressor(n_estimators=100, random_state=42)
86
+
87
+ # Train the model
88
+ model.fit(X_train, y_train)
89
+
90
+ # Evaluate the model
91
+ predictions = model.predict(X_test)
92
+ mse = mean_squared_error(y_test, predictions)
93
+ print(f"Model Mean Squared Error: {mse}")
94
+
95
+ return model
96
+
97
+ def make_prediction(model: RandomForestRegressor, recent_data: pd.DataFrame) -> float:
98
+ """
99
+ Makes a prediction for the next day's closing price.
100
+
101
+ Parameters:
102
+ - model (RandomForestRegressor): Trained Random Forest model.
103
+ - recent_data (pd.DataFrame): Recent stock data.
104
+
105
+ Returns:
106
+ - predicted_price (float): Predicted closing price.
107
+ """
108
+ # Use the last 5 days' close prices as features
109
+ recent_close = recent_data['Close'].values[-5:]
110
+ if len(recent_close) < 5:
111
+ raise ValueError("Not enough data to make a prediction.")
112
+
113
+ X_new = recent_close[::-1].reshape(1, -1) # Reverse to match feature order
114
+ predicted_price = model.predict(X_new)[0]
115
+ return predicted_price
116
+
117
+ def buy_or_sell(current_price: float, predicted_price: float) -> str:
118
+ """
119
+ Determines whether to buy or sell based on price prediction.
120
+
121
+ Parameters:
122
+ - current_price (float): Current closing price.
123
+ - predicted_price (float): Predicted closing price.
124
+
125
+ Returns:
126
+ - decision (str): 'Buy' if predicted price is higher, else 'Sell'.
127
+ """
128
+ if predicted_price > current_price:
129
+ return "Buy"
130
+ else:
131
+ return "Sell"
132
+
133
+ def stock_prediction_app(ticker: str, start_date: str, end_date: str):
134
+ """
135
+ Main function to handle stock prediction and return outputs.
136
+
137
+ Parameters:
138
+ - ticker (str): Selected stock ticker.
139
+ - start_date (str): Training start date.
140
+ - end_date (str): Training end date.
141
+
142
+ Returns:
143
+ - percentage_change (str): Percentage change from start to end date.
144
+ - highest_price (float): Highest closing price in the period.
145
+ - lowest_price (float): Lowest closing price in the period.
146
+ - decision (str): Buy or Sell decision.
147
+ - plot (matplotlib.figure.Figure): Plot of historical prices with tomorrow's prediction.
148
+ """
149
+ # Fetch data
150
+ data = fetch_stock_data(ticker, start_date, end_date)
151
+
152
+ if data.empty:
153
+ return "N/A", "N/A", "N/A", "No Data Available", None
154
+
155
+ # Calculate percentage change, highest and lowest
156
+ start_price = data['Close'].iloc[0]
157
+ end_price = data['Close'].iloc[-1]
158
+ percentage_change = ((end_price - start_price) / start_price) * 100
159
+ highest_price = data['Close'].max()
160
+ lowest_price = data['Close'].min()
161
+
162
+ # Preprocess data
163
+ try:
164
+ X, y = preprocess_data(data)
165
+ except Exception as e:
166
+ return f"Error in preprocessing data: {e}", "N/A", "N/A", "Error", None
167
+
168
+ if len(X) == 0:
169
+ return f"{percentage_change:.2f}%", highest_price, lowest_price, "No Prediction", None
170
+
171
+ # Train the model
172
+ try:
173
+ model = train_model(X, y)
174
+ except Exception as e:
175
+ return f"Error in training model: {e}", highest_price, lowest_price, "Error", None
176
+
177
+ # Make prediction
178
+ try:
179
+ predicted_price = make_prediction(model, data)
180
+ except Exception as e:
181
+ return f"Error in making prediction: {e}", highest_price, lowest_price, "Error", None
182
+
183
+ # Current price is the last closing price
184
+ current_price = data['Close'].iloc[-1]
185
+ decision = buy_or_sell(current_price, predicted_price)
186
+
187
+ # Plotting historical prices and predicted tomorrow's price
188
+ plt.figure(figsize=(10,5))
189
+ plt.plot(data['Close'], label='Historical Close Price')
190
+
191
+ # Add predicted price for tomorrow
192
+ tomorrow_date = data.index[-1] + timedelta(days=1)
193
+ # Ensure tomorrow is a business day
194
+ while tomorrow_date.weekday() >= 5: # Saturday=5, Sunday=6
195
+ tomorrow_date += timedelta(days=1)
196
+
197
+ plt.scatter(tomorrow_date, predicted_price, color='red', label='Predicted Close Price (Tomorrow)')
198
+ plt.title(f'{ticker} Price Prediction for Tomorrow')
199
+ plt.xlabel('Date')
200
+ plt.ylabel('Price ($)')
201
+ plt.legend()
202
+ plt.tight_layout()
203
+ fig = plt.gcf()
204
+ plt.close()
205
+
206
+ # Formatting outputs
207
+ percentage_change_str = f"{percentage_change:.2f}%"
208
+
209
+ return percentage_change_str, highest_price, lowest_price, decision, fig
210
+
211
+ # Define the Gradio interface
212
+ iface = gr.Interface(
213
+ fn=stock_prediction_app,
214
+ inputs=[
215
+ gr.Dropdown(choices=STOCK_TICKERS, label="Select Stock Ticker"),
216
+ gr.DatePicker(label="Select Start Date", value="2020-01-01"), # Changed default start date
217
+ gr.DatePicker(label="Select End Date", value=datetime.today().strftime('%Y-%m-%d'))
218
+ ],
219
+ outputs=[
220
+ gr.Textbox(label="Percentage Change"),
221
+ gr.Number(label="Highest Closing Price"),
222
+ gr.Number(label="Lowest Closing Price"),
223
+ gr.Textbox(label="Decision (Buy/Sell)"),
224
+ gr.Plot(label="Stock Performance")
225
+ ],
226
+ title="Stock Prediction App",
227
+ description="Predict whether to buy or sell a stock based on historical data."
228
+ )
229
+
230
+ iface.launch()