shaikfakruddin18's picture
Create app.py
6fea57c verified
import os
import io
import requests
import joblib
import pandas as pd
import streamlit as st
import plotly.graph_objects as go
from datetime import datetime
from supabase import create_client, Client
import yfinance as yf
# =====================================
# βœ… CONFIGURATION
# =====================================
MODEL_URL = "https://huggingface.co/shaikfakruddin18/stock-predictor-model/resolve/main/rf_model.joblib"
ALPHA_VANTAGE_API_KEY = " IY2HMVXFHXE83LB5" # Replace with your API key
SUPABASE_URL = "https://rrvsbizwikocatkdhyfs.supabase.co"
SUPABASE_KEY = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6InJydnNiaXp3aWtvY2F0a2RoeWZzIiwicm9sZSI6ImFub24iLCJpYXQiOjE3NTI5NjExNDAsImV4cCI6MjA2ODUzNzE0MH0.YWP65KQvwna1yQlhjksyT9Rhpyn5bBw5MDlMVHTF62Q"
supabase: Client = create_client(SUPABASE_URL, SUPABASE_KEY)
# Cache model so it's loaded only once
@st.cache_resource
def load_model_from_hf():
"""Download model from Hugging Face and load it"""
model_path = "rf_model.joblib"
if not os.path.exists(model_path):
st.info("πŸ“₯ Downloading ML model from Hugging Face...")
r = requests.get(MODEL_URL)
with open(model_path, "wb") as f:
f.write(r.content)
return joblib.load(model_path)
model = load_model_from_hf()
# =====================================
# βœ… FETCH STOCK DATA
# =====================================
def fetch_yahoo_data(ticker, period="3mo"):
"""Fetch historical daily data from Yahoo Finance"""
df = yf.download(ticker, period=period, interval="1d")
if df.empty:
return None
df.reset_index(inplace=True)
return df
def fetch_alpha_vantage_intraday(ticker, interval="5min"):
"""Fetch intraday data from Alpha Vantage"""
url = (
f"https://www.alphavantage.co/query?function=TIME_SERIES_INTRADAY"
f"&symbol={ticker}&interval={interval}&apikey={ALPHA_VANTAGE_API_KEY}&datatype=json"
)
r = requests.get(url).json()
key = f"Time Series ({interval})"
if key not in r:
return None
df = pd.DataFrame(r[key]).T
df.columns = ["Open", "High", "Low", "Close", "Volume"]
df.index = pd.to_datetime(df.index)
df = df.sort_index()
df.reset_index(inplace=True)
df.rename(columns={"index": "Datetime"}, inplace=True)
df[["Open", "High", "Low", "Close", "Volume"]] = df[["Open", "High", "Low", "Close", "Volume"]].astype(float)
return df
def fetch_supabase_csv(ticker):
"""Fetch saved stock CSV from Supabase storage"""
try:
base_url = "https://rrvsbizwikocatkdhyfs.supabase.co/storage/v1/object/public/prediction/stock_data_with_indicators"
csv_url = f"{base_url}/{ticker}.csv"
df = pd.read_csv(csv_url)
return df
except:
return None
# =====================================
# βœ… PREDICTION + CHARTS
# =====================================
def predict_stock(df):
"""Predict UP/DOWN using the loaded ML model"""
if df is None or df.empty:
return None, None
features = df[["Open", "High", "Low", "Close", "Volume"]].tail(1) # Last row
pred = model.predict(features)[0]
confidence = model.predict_proba(features).max() * 100
prediction = "UP" if pred == 1 else "DOWN"
return prediction, confidence
def plot_candlestick(df, title="Stock Price"):
fig = go.Figure(
data=[
go.Candlestick(
x=df[df.columns[0]],
open=df["Open"],
high=df["High"],
low=df["Low"],
close=df["Close"],
)
]
)
fig.update_layout(title=title, xaxis_rangeslider_visible=False, height=400)
return fig
def save_prediction_to_supabase(stock, prediction, confidence, source):
"""Save prediction to Supabase DB"""
try:
created_at = datetime.utcnow().isoformat()
data = {
"created_at": created_at,
"stock": stock,
"prediction": prediction,
"confidence": f"{confidence:.2f}%",
"source": source
}
response = supabase.table("predictions").insert(data).execute()
if response.data:
st.success("βœ… Prediction saved to Supabase!")
else:
st.error(f"❌ Failed to save prediction: {response}")
except Exception as e:
st.error(f"❌ Supabase error: {e}")
def load_prediction_history_supabase():
"""Load previous predictions"""
try:
response = supabase.table("predictions").select("*").order("created_at", desc=True).execute()
return pd.DataFrame(response.data) if response.data else pd.DataFrame()
except Exception as e:
st.error(f"❌ Failed to load history: {e}")
return pd.DataFrame()
# =====================================
# βœ… STREAMLIT UI
# =====================================
st.set_page_config(page_title="AI Stock Predictor", layout="wide")
st.sidebar.title("πŸ“Š Navigation")
st.sidebar.subheader("Select Data Source")
data_source = st.sidebar.radio(
"Fetch data from:",
["Yahoo Finance (Daily)", "Alpha Vantage (Intraday)", "Supabase CSV"]
)
ticker = st.sidebar.text_input("Enter Stock Ticker (e.g. AAPL, RELIANCE.BSE)", "AAPL")
if data_source == "Yahoo Finance (Daily)":
period = st.sidebar.selectbox("Select Period", ["1mo", "3mo", "6mo", "1y", "2y"], index=1)
elif data_source == "Alpha Vantage (Intraday)":
interval = st.sidebar.selectbox("Intraday Interval", ["1min", "5min", "15min", "30min", "60min"], index=1)
st.title("πŸ“ˆ AI Stock Predictor Dashboard")
if st.sidebar.button("Fetch Data & Predict"):
if data_source == "Yahoo Finance (Daily)":
df = fetch_yahoo_data(ticker, period)
source_name = "YahooFinance"
elif data_source == "Alpha Vantage (Intraday)":
df = fetch_alpha_vantage_intraday(ticker, interval)
source_name = "AlphaVantage"
else:
df = fetch_supabase_csv(ticker)
source_name = "Supabase CSV"
if df is None or df.empty:
st.error("❌ No data returned. Check ticker or date range.")
else:
st.subheader(f"Stock Data: {ticker} ({source_name})")
st.plotly_chart(plot_candlestick(df, f"{ticker} Price Chart"), use_container_width=True)
prediction, confidence = predict_stock(df)
if prediction:
st.markdown(f"### Prediction: **{prediction}**")
st.markdown(f"### Confidence: **{confidence:.2f}%**")
save_prediction_to_supabase(ticker, prediction, confidence, source_name)
else:
st.warning("⚠️ Could not generate prediction.")
# Show Prediction History
st.subheader("πŸ“œ Prediction History (Cloud)")
history_df = load_prediction_history_supabase()
if not history_df.empty:
st.dataframe(history_df[["created_at", "stock", "prediction", "confidence", "source"]])
else:
st.info("No prediction history yet.")