|
import yfinance as yf |
|
import pandas as pd |
|
import numpy as np |
|
import tensorflow as tf |
|
from tensorflow.keras import layers, models |
|
import matplotlib.pyplot as plt |
|
import gradio as gr |
|
from datetime import datetime, timedelta |
|
|
|
|
|
import matplotlib |
|
matplotlib.use('Agg') |
|
|
|
|
|
STOCK_TICKERS = [ |
|
'AAPL', 'GOOGL', 'MSFT', 'AMZN', 'TSLA', |
|
'FB', 'NVDA', 'JPM', 'V', 'DIS' |
|
] |
|
|
|
def fetch_data(ticker, start_date, end_date): |
|
""" |
|
Fetch historical stock data from yfinance. |
|
|
|
Args: |
|
ticker (str): Stock ticker symbol. |
|
start_date (str): Start date in 'YYYY-MM-DD'. |
|
end_date (str): End date in 'YYYY-MM-DD'. |
|
|
|
Returns: |
|
pd.DataFrame: Historical stock data. |
|
""" |
|
data = yf.download(ticker, start=start_date, end=end_date) |
|
return data |
|
|
|
def preprocess_data(data): |
|
""" |
|
Preprocess the stock data for model training. |
|
|
|
Args: |
|
data (pd.DataFrame): Raw stock data. |
|
|
|
Returns: |
|
np.ndarray, np.ndarray: Features and labels. |
|
""" |
|
|
|
data['MA10'] = data['Close'].rolling(window=10).mean() |
|
data['MA20'] = data['Close'].rolling(window=20).mean() |
|
|
|
|
|
data = data.dropna() |
|
|
|
|
|
features = data[['Close', 'MA10', 'MA20']].values |
|
|
|
|
|
data['Target'] = np.where(data['Close'].shift(-1) > data['Close'], 1, 0) |
|
labels = data['Target'].values[:-1] |
|
features = features[:-1] |
|
|
|
return features, labels |
|
|
|
def build_model(input_shape): |
|
""" |
|
Build and compile the TensorFlow model. |
|
|
|
Args: |
|
input_shape (int): Number of features. |
|
|
|
Returns: |
|
tf.keras.Model: Compiled model. |
|
""" |
|
model = models.Sequential([ |
|
layers.Dense(64, activation='relu', input_shape=(input_shape,)), |
|
layers.Dense(32, activation='relu'), |
|
layers.Dense(1, activation='sigmoid') |
|
]) |
|
|
|
model.compile(optimizer='adam', |
|
loss='binary_crossentropy', |
|
metrics=['accuracy']) |
|
return model |
|
|
|
|
|
models_dict = {} |
|
|
|
for ticker in STOCK_TICKERS: |
|
|
|
end = datetime.today() |
|
start = end - timedelta(days=5*365) |
|
data = fetch_data(ticker, start.strftime('%Y-%m-%d'), end.strftime('%Y-%m-%d')) |
|
|
|
if data.empty: |
|
print(f"No data found for {ticker}. Skipping...") |
|
continue |
|
|
|
features, labels = preprocess_data(data) |
|
model = build_model(features.shape[1]) |
|
model.fit(features, labels, epochs=10, batch_size=32, verbose=0) |
|
|
|
models_dict[ticker] = model |
|
print(f"Model trained for {ticker}") |
|
|
|
def predict_stock(ticker, start_date, end_date): |
|
""" |
|
Predict whether to Buy or Sell the stock based on user input. |
|
|
|
Args: |
|
ticker (str): Selected stock ticker. |
|
start_date (str): Training start date. |
|
end_date (str): Training end date. |
|
|
|
Returns: |
|
dict: Prediction results and graph. |
|
""" |
|
|
|
data = fetch_data(ticker, start_date, end_date) |
|
|
|
if data.empty: |
|
return { |
|
"Percentage Change": "No data available for the selected dates.", |
|
"Highest Price": "N/A", |
|
"Lowest Price": "N/A", |
|
"Prediction": "N/A", |
|
"Graph": None |
|
} |
|
|
|
|
|
features, labels = preprocess_data(data) |
|
|
|
if features.size == 0: |
|
return { |
|
"Percentage Change": "Insufficient data after preprocessing.", |
|
"Highest Price": "N/A", |
|
"Lowest Price": "N/A", |
|
"Prediction": "N/A", |
|
"Graph": None |
|
} |
|
|
|
|
|
latest_data = data[['Close', 'MA10', 'MA20']].values[-1].reshape(1, -1) |
|
|
|
|
|
model = models_dict.get(ticker) |
|
if not model: |
|
return { |
|
"Percentage Change": "Model not found for the selected ticker.", |
|
"Highest Price": "N/A", |
|
"Lowest Price": "N/A", |
|
"Prediction": "N/A", |
|
"Graph": None |
|
} |
|
|
|
prediction = model.predict(latest_data) |
|
prediction_label = "Buy" if prediction[0][0] > 0.5 else "Sell" |
|
|
|
|
|
start_close = data['Close'].iloc[0] |
|
latest_close = data['Close'].iloc[-1] |
|
percent_change = ((latest_close - start_close) / start_close) * 100 |
|
|
|
|
|
highest = data['Close'].max() |
|
lowest = data['Close'].min() |
|
|
|
|
|
plt.figure(figsize=(10,5)) |
|
plt.plot(data.index, data['Close'], label='Historical Close') |
|
|
|
|
|
future_days = 63 |
|
|
|
future_prices = [latest_close] |
|
for _ in range(future_days): |
|
change_percent = np.random.uniform(-0.02, 0.02) |
|
new_price = future_prices[-1] * (1 + change_percent) |
|
future_prices.append(new_price) |
|
|
|
future_dates = pd.date_range(data.index[-1] + timedelta(days=1), periods=future_days+1, freq='B') |
|
plt.plot(future_dates, future_prices[1:], label='Predicted Close') |
|
plt.xlabel('Date') |
|
plt.ylabel('Price') |
|
plt.title(f'{ticker} Historical and Predicted Performance') |
|
plt.legend() |
|
plt.tight_layout() |
|
plt.savefig('performance.png') |
|
plt.close() |
|
|
|
|
|
result = { |
|
"Percentage Change": f"{percent_change:.2f}%", |
|
"Highest Price": f"${highest:.2f}", |
|
"Lowest Price": f"${lowest:.2f}", |
|
"Prediction": prediction_label, |
|
"Graph": 'performance.png' |
|
} |
|
|
|
return result |
|
|
|
|
|
iface = gr.Interface( |
|
fn=predict_stock, |
|
inputs=[ |
|
gr.Dropdown(choices=STOCK_TICKERS, label="Select Stock Ticker"), |
|
gr.DatePicker(label="Start Date"), |
|
gr.DatePicker(label="End Date") |
|
], |
|
outputs=[ |
|
gr.Textbox(label="Percentage Change"), |
|
gr.Textbox(label="Highest Price"), |
|
gr.Textbox(label="Lowest Price"), |
|
gr.Textbox(label="Buy/Sell Prediction"), |
|
gr.Image(label="Performance Graph") |
|
], |
|
title="π Stock Buy/Sell Prediction App", |
|
description=( |
|
"Select a stock ticker and a date range to predict whether to **Buy** or **Sell** the stock. " |
|
"View the percentage change, highest and lowest prices, and a performance graph." |
|
) |
|
) |
|
|
|
|
|
iface.launch() |
|
from tensorflow.keras.models import Sequential |
|
from tensorflow.keras.layers import Dense, Input |
|
|
|
def create_model(input_shape): |
|
model = Sequential() |
|
model.add(Input(shape=(input_shape,))) |
|
model.add(Dense(64, activation='relu')) |
|
model.add(Dense(32, activation='relu')) |
|
model.add(Dense(1, activation='sigmoid')) |
|
|
|
model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy']) |
|
return model |
|
data.loc[:, 'Target'] = np.where(data['Close'].shift(-1) > data['Close'], 1, 0) |
|
import gradio as gr |
|
|
|
def predict_stock(ticker, start_date, end_date): |
|
|
|
return "Prediction result" |
|
|
|
interface = gr.Interface( |
|
fn=predict_stock, |
|
inputs=[ |
|
gr.inputs.Dropdown(['AAPL', 'MSFT', 'GOOG', 'AMZN', 'TSLA'], label="Stock Ticker"), |
|
gr.inputs.Date(label="Start Date"), |
|
gr.inputs.Date(label="End Date") |
|
], |
|
outputs="text" |
|
) |
|
|
|
interface.launch() |
|
|