dschandra commited on
Commit
ca8eb38
·
verified ·
1 Parent(s): 81d1809

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +147 -103
app.py CHANGED
@@ -1,123 +1,167 @@
 
1
  import yfinance as yf
2
- import gradio as gr
3
- import numpy as np
4
  import pandas as pd
 
 
 
 
5
  import matplotlib.pyplot as plt
6
- from datetime import datetime, timedelta
7
- from sklearn.preprocessing import MinMaxScaler
8
- from tensorflow.keras.models import Sequential
9
- from tensorflow.keras.layers import Dense, LSTM
10
-
11
- # Function to load stock data
12
- def load_stock_data(ticker, start, end):
13
- stock = yf.download(ticker, start=start, end=end)
14
- return stock
15
-
16
- # Function to preprocess the data for model training
17
- def preprocess_data(stock):
18
- data = stock[['Close']]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
19
  scaler = MinMaxScaler(feature_range=(0, 1))
20
- scaled_data = scaler.fit_transform(data)
21
-
22
- x_train, y_train = [], []
23
- for i in range(60, len(scaled_data)):
24
- x_train.append(scaled_data[i-60:i, 0])
25
- y_train.append(scaled_data[i, 0])
26
-
27
- x_train, y_train = np.array(x_train), np.array(y_train)
28
- x_train = np.reshape(x_train, (x_train.shape[0], x_train.shape[1], 1))
29
-
30
- return x_train, y_train, scaler
31
 
32
- # Function to build the LSTM model
33
  def build_model():
34
  model = Sequential()
35
  model.add(LSTM(units=50, return_sequences=True, input_shape=(60, 1)))
 
36
  model.add(LSTM(units=50, return_sequences=False))
37
- model.add(Dense(units=25))
38
- model.add(Dense(units=1))
39
-
40
  model.compile(optimizer='adam', loss='mean_squared_error')
41
  return model
42
 
43
- # Function to train the model
44
- def train_model(ticker, start, end):
45
- # Load stock data
46
- stock_data = load_stock_data(ticker, start, end)
47
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
48
  # Preprocess the data
49
- x_train, y_train, scaler = preprocess_data(stock_data)
50
-
51
- # Build and train the model
52
- model = build_model()
53
- model.fit(x_train, y_train, batch_size=1, epochs=1)
54
-
55
- return model, scaler, stock_data
56
-
57
- # Function to predict stock prices
58
- def predict_stock(model, scaler, stock_data):
59
- # Use the last 60 days of data for predictions
60
- test_data = stock_data[['Close']][-60:].values
61
- test_data_scaled = scaler.transform(test_data)
62
-
63
- x_test = []
64
- x_test.append(test_data_scaled)
65
 
66
- x_test = np.array(x_test)
67
- x_test = np.reshape(x_test, (x_test.shape[0], x_test.shape[1], 1))
68
-
69
- # Make predictions
70
- predictions = model.predict(x_test)
71
- predictions = scaler.inverse_transform(predictions)
72
-
73
- # Plot historical and predicted prices
74
- plt.figure(figsize=(10, 6))
75
- plt.plot(stock_data.index, stock_data['Close'], label="Historical Prices")
76
- future_dates = [stock_data.index[-1] + timedelta(days=i) for i in range(1, 91)]
77
- plt.plot(future_dates, predictions.flatten(), label="Predicted Prices")
78
- plt.title("Stock Price Prediction")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
79
  plt.xlabel('Date')
80
  plt.ylabel('Price')
81
  plt.legend()
82
  plt.show()
83
 
84
- return predictions[-1][0]
85
-
86
- # Gradio interface function
87
- def stock_prediction(ticker, start, end):
88
- model, scaler, stock_data = train_model(ticker, start, end)
89
- prediction = predict_stock(model, scaler, stock_data)
90
-
91
- start_price = stock_data['Close'].iloc[0]
92
- end_price = stock_data['Close'].iloc[-1]
93
- percent_change = ((end_price - start_price) / start_price) * 100
94
- highest_price = stock_data['Close'].max()
95
- lowest_price = stock_data['Close'].min()
96
 
97
- return {
98
- "Predicted Next Price": prediction,
99
- "Percentage Change": percent_change,
100
- "Highest Price": highest_price,
101
- "Lowest Price": lowest_price
102
- }
103
-
104
- # Define stock tickers and default dates
105
- tickers = ['AAPL', 'GOOG', 'MSFT', 'TSLA', 'AMZN', 'NFLX', 'META', 'NVDA', 'BABA', 'INTC']
106
- start_default = (datetime.now() - timedelta(days=365)).strftime("%Y-%m-%d")
107
- end_default = datetime.now().strftime("%Y-%m-%d")
108
-
109
- # Gradio interface
110
- iface = gr.Interface(
111
- fn=stock_prediction,
112
- inputs=[
113
- gr.Dropdown(choices=tickers, label="Select Stock Ticker"),
114
- gr.Date(label="Start Date", value=start_default),
115
- gr.Date(label="End Date", value=end_default),
116
- ],
117
- outputs=gr.JSON(label="Prediction and Analysis"),
118
- live=True
119
- )
120
-
121
- # Launch the Gradio app
122
- if __name__ == "__main__":
123
- iface.launch()
 
1
+ import os
2
  import yfinance as yf
 
 
3
  import pandas as pd
4
+ import numpy as np
5
+ import tensorflow as tf
6
+ from tensorflow.keras.models import Sequential, load_model
7
+ from tensorflow.keras.layers import LSTM, Dense, Dropout
8
  import matplotlib.pyplot as plt
9
+ import gradio as gr
10
+ from datetime import datetime
11
+
12
+ # Disable GPU usage and oneDNN optimizations
13
+ os.environ['CUDA_VISIBLE_DEVICES'] = '-1'
14
+ os.environ['TF_ENABLE_ONEDNN_OPTS'] = '0'
15
+
16
+ # Helper function to handle date adjustments and retries if data not found
17
+ def adjust_date_range_if_needed(stock_data, ticker, start_date, end_date):
18
+ retries = 3 # Number of retries for fetching data
19
+ while stock_data.empty and retries > 0:
20
+ start_date = (datetime.strptime(start_date, '%Y-%m-%d') - timedelta(days=1)).strftime('%Y-%m-%d')
21
+ end_date = (datetime.strptime(end_date, '%Y-%m-%d') - timedelta(days=1)).strftime('%Y-%m-%d')
22
+ print(f"Retrying with adjusted dates: {start_date} to {end_date}") # Debugging output
23
+ stock_data = yf.download(ticker, start=start_date, end=end_date)
24
+ retries -= 1
25
+ return stock_data, start_date, end_date
26
+
27
+ # Define function to validate stock ticker and get stock data
28
+ def get_stock_data(ticker, start_date, end_date):
29
+ try:
30
+ stock_data = yf.download(ticker, start=start_date, end=end_date)
31
+ print(f"Stock data downloaded: {stock_data.shape}") # Debugging output to check data download
32
+ except Exception as e:
33
+ print(f"Error fetching data: {e}") # Debugging output for data download error
34
+ return None, None, None
35
+
36
+ # If stock data is empty, attempt to adjust the date range
37
+ if stock_data.empty:
38
+ print("No data found for the original date range.") # Debugging output
39
+ stock_data, adjusted_start, adjusted_end = adjust_date_range_if_needed(stock_data, ticker, start_date, end_date)
40
+ if stock_data.empty:
41
+ return None, None, None # If still empty after retries, return None
42
+ return stock_data, adjusted_start, adjusted_end
43
+ return stock_data, start_date, end_date
44
+
45
+ # Preprocess the data for the LSTM model
46
+ def preprocess_data(stock_data):
47
+ # Closing prices
48
+ close_prices = stock_data['Close'].values
49
+ close_prices = close_prices.reshape(-1, 1)
50
+
51
+ # Normalize the data
52
+ from sklearn.preprocessing import MinMaxScaler
53
  scaler = MinMaxScaler(feature_range=(0, 1))
54
+ scaled_data = scaler.fit_transform(close_prices)
55
+
56
+ return scaled_data, scaler
 
 
 
 
 
 
 
 
57
 
58
+ # Build the LSTM model
59
  def build_model():
60
  model = Sequential()
61
  model.add(LSTM(units=50, return_sequences=True, input_shape=(60, 1)))
62
+ model.add(Dropout(0.2))
63
  model.add(LSTM(units=50, return_sequences=False))
64
+ model.add(Dropout(0.2))
65
+ model.add(Dense(units=1)) # Predicting the next closing price
 
66
  model.compile(optimizer='adam', loss='mean_squared_error')
67
  return model
68
 
69
+ # Save and load models to avoid re-training
70
+ def save_model(model, file_name):
71
+ model.save(file_name)
72
+
73
+ def load_trained_model(file_name):
74
+ if os.path.exists(file_name):
75
+ return load_model(file_name)
76
+ else:
77
+ return None
78
+
79
+ # Train and make predictions
80
+ def predict_stock(stock_data, scaler, model):
81
+ # Get the last 60 days of stock data for prediction
82
+ last_60_days = stock_data[-60:]
83
+ last_60_days_scaled = scaler.transform(last_60_days)
84
+
85
+ # Prepare the input for prediction
86
+ X_test = []
87
+ X_test.append(last_60_days_scaled)
88
+ X_test = np.array(X_test)
89
+ X_test = np.reshape(X_test, (X_test.shape[0], X_test.shape[1], 1))
90
+
91
+ # Predict
92
+ predicted_price = model.predict(X_test)
93
+ predicted_price = scaler.inverse_transform(predicted_price)
94
+
95
+ print(f"Predicted price: {predicted_price}") # Debugging output to verify predictions
96
+ return predicted_price
97
+
98
+ # Main app function
99
+ def stock_predictor(ticker, start_date, end_date):
100
+ # Validate if the ticker is available on Yahoo Finance
101
+ if not ticker:
102
+ return f"Invalid stock ticker: {ticker}"
103
+
104
+ # Get stock data
105
+ stock_data, adjusted_start, adjusted_end = get_stock_data(ticker, start_date, end_date)
106
+
107
+ if stock_data is None or stock_data.empty:
108
+ return f"No data found for {ticker} in the selected or adjusted date range."
109
+
110
  # Preprocess the data
111
+ scaled_data, scaler = preprocess_data(stock_data)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
112
 
113
+ # Try to load a pre-trained model
114
+ model_file = f"{ticker}_model.h5"
115
+ model = load_trained_model(model_file)
116
+
117
+ if model is None:
118
+ # Train the model if pre-trained model is not found
119
+ print("Training the model...") # Debugging output for training
120
+ model = build_model()
121
+ X_train, y_train = [], []
122
+ for i in range(60, len(scaled_data)):
123
+ X_train.append(scaled_data[i-60:i, 0])
124
+ y_train.append(scaled_data[i, 0])
125
+ X_train, y_train = np.array(X_train), np.array(y_train)
126
+ X_train = np.reshape(X_train, (X_train.shape[0], X_train.shape[1], 1))
127
+
128
+ # Train the model (reduced epochs for faster processing)
129
+ model.fit(X_train, y_train, epochs=2, batch_size=32) # Reduced epochs
130
+
131
+ # Save the trained model
132
+ save_model(model, model_file)
133
+
134
+ # Predict stock price for tomorrow
135
+ predicted_price = predict_stock(scaled_data, scaler, model)
136
+
137
+ # Historical vs Predicted
138
+ plt.figure(figsize=(14, 7))
139
+ plt.plot(stock_data['Close'], color="blue", label="Historical Prices")
140
+ plt.scatter(len(stock_data), predicted_price, color="red", label="Predicted Price for Tomorrow")
141
+ plt.title(f"{ticker} Stock Price Prediction")
142
  plt.xlabel('Date')
143
  plt.ylabel('Price')
144
  plt.legend()
145
  plt.show()
146
 
147
+ return f"Predicted Stock Price for {ticker} tomorrow: ${predicted_price[0][0]:.2f}"
 
 
 
 
 
 
 
 
 
 
 
148
 
149
+ # Gradio UI
150
+ def build_ui():
151
+ stock_tickers = ["AAPL", "TSLA", "AMZN", "MSFT", "GOOGL", "FB", "NFLX", "NVDA", "BABA", "JPM"]
152
+
153
+ # Use Textbox for manual date input (format: YYYY-MM-DD)
154
+ gr_interface = gr.Interface(
155
+ fn=stock_predictor,
156
+ inputs=[
157
+ gr.Dropdown(stock_tickers, label="Stock Ticker"),
158
+ gr.Textbox(label="Start Date (YYYY-MM-DD)", value="2022-01-01"), # Manual start date
159
+ gr.Textbox(label="End Date (YYYY-MM-DD)", value=datetime.today().strftime("%Y-%m-%d")) # Manual end date
160
+ ],
161
+ outputs="text",
162
+ title="Stock Price Prediction for Tomorrow"
163
+ )
164
+ gr_interface.launch()
165
+
166
+ # Run the app
167
+ build_ui()