import yfinance as yf import pandas as pd import gradio as gr import numpy as np import matplotlib.pyplot as plt from sklearn.ensemble import RandomForestRegressor from sklearn.model_selection import train_test_split from datetime import datetime # Function to fetch stock data def fetch_stock_data(ticker, start, end): try: start_date = datetime.strptime(start, "%Y-%m-%d") end_date = datetime.strptime(end, "%Y-%m-%d") except ValueError: return None, "Invalid date format. Please use YYYY-MM-DD." if start_date >= end_date: return None, "Start date must be before the end date." stock_data = yf.download(ticker, start=start, end=end) if stock_data.empty: return None, f"No stock data available for {ticker} from {start} to {end}." stock_data = stock_data[['Close']] return stock_data, None # Function to train model and predict stock prices def train_and_predict(ticker, start, end): data, error_message = fetch_stock_data(ticker, start, end) if error_message: return error_message, None, None, None, None, None, None, None, None, None data['Date'] = data.index.map(pd.Timestamp.timestamp) X = data['Date'].values.reshape(-1, 1) y = data['Close'].values # Train-test split X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42) model = RandomForestRegressor(n_estimators=100, random_state=42) model.fit(X_train, y_train) # Predict for the test set y_pred = model.predict(X_test) # Plot historical (actual) vs predicted values plt.figure(figsize=(12, 6)) # Plot actual historical prices plt.plot(data.index, data['Close'], label='Actual Prices', color='blue') # Sort test data by date for plotting sorted_test_index = X_test.flatten().argsort() plt.plot(pd.to_datetime(X_test.flatten()[sorted_test_index], unit='s'), y_pred[sorted_test_index], label='Predicted Prices (Test)', color='green') plt.xlabel('Date') plt.ylabel('Price') plt.title(f'{ticker} Stock Price Prediction') plt.legend() plt.grid() plt.savefig('stock_prediction.png') plt.close() # Close the plot to avoid display issues # Calculate additional metrics percentage_change = ((data['Close'].iloc[-1] - data['Close'].iloc[0]) / data['Close'].iloc[0]) * 100 highest_value = data['Close'].max() lowest_value = data['Close'].min() highest_accuracy = (1 - abs(y_pred.max() - highest_value) / highest_value) * 100 lowest_accuracy = (1 - abs(y_pred.min() - lowest_value) / lowest_value) * 100 decision = "Buy" if y_pred[-1] > data['Close'].iloc[-1] else "Sell" return (percentage_change, highest_value, lowest_value, y_pred.max(), y_pred.min(), highest_accuracy, lowest_accuracy, decision, 'stock_prediction.png') # Gradio interface function def gradio_interface(ticker, start, end): return train_and_predict(ticker, start, end) # Dropdown for stock tickers stock_tickers = ["AAPL", "GOOGL", "MSFT", "AMZN", "TSLA", "META", "NFLX", "NVDA", "BRK-B", "JPM"] # Gradio app iface = gr.Interface( fn=gradio_interface, inputs=[ gr.Dropdown(choices=stock_tickers, label="Select Stock Ticker"), gr.Textbox(label="Enter Start Date (YYYY-MM-DD)"), gr.Textbox(label="Enter End Date (YYYY-MM-DD)") ], outputs=[ gr.Textbox(label="Percentage Change"), gr.Textbox(label="Highest Value (Historical)"), gr.Textbox(label="Lowest Value (Historical)"), gr.Textbox(label="Predicted Highest Value"), gr.Textbox(label="Predicted Lowest Value"), gr.Textbox(label="Accuracy of Highest Prediction (%)"), gr.Textbox(label="Accuracy of Lowest Prediction (%)"), gr.Textbox(label="Buy/Sell Decision"), gr.Image(label="Stock Price Prediction Graph") ], title="Stock Price Prediction App", description="This app predicts stock prices and advises whether to buy or sell based on predictions from historical data." ) iface.launch()