Hamza012bce21 commited on
Commit
1c03d2a
·
verified ·
1 Parent(s): 735eb6c

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +58 -12
app.py CHANGED
@@ -4,7 +4,7 @@ import pandas as pd
4
  import matplotlib.pyplot as plt
5
  import os
6
 
7
- # Optional imports for ML, but safely handled
8
  try:
9
  import tensorflow as tf
10
  from tensorflow.keras.models import load_model
@@ -16,10 +16,15 @@ except ImportError:
16
  MinMaxScaler = None
17
  joblib = None
18
 
19
- st.set_page_config(page_title="PSX Stock Predictor", layout="wide")
 
 
 
 
 
20
 
21
- st.title("📈 PSX Stock Predictor – HF Safe Version")
22
- st.write("This app works even if model or API is missing.")
23
 
24
  # ------------------------------
25
  # Load Model & Scaler
@@ -37,16 +42,53 @@ else:
37
  st.warning("Model not found. Using dummy predictions.")
38
 
39
  # ------------------------------
40
- # Dummy / Fallback Data
41
  # ------------------------------
42
- def get_dummy_data():
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
43
  dates = pd.date_range(end=pd.Timestamp.today(), periods=200)
44
  prices = np.linspace(100, 150, 200) + np.random.normal(0, 2, 200)
45
  df = pd.DataFrame({"Close": prices}, index=dates)
46
  return df
47
 
48
  # ------------------------------
49
- # Prediction function
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
50
  # ------------------------------
51
  def predict_next(df):
52
  if MODEL_LOADED:
@@ -56,7 +98,7 @@ def predict_next(df):
56
  pred_real = scaler.inverse_transform([[pred]])[0][0]
57
  return pred_real
58
  else:
59
- # Dummy prediction: next value + small random change
60
  return df["Close"].iloc[-1] * (1 + np.random.uniform(-0.01, 0.01))
61
 
62
  # ------------------------------
@@ -66,17 +108,21 @@ symbol = st.selectbox("Choose PSX Stock:", ["HBL", "UBL", "ENGRO", "PSO", "OGDC"
66
 
67
  if st.button("Fetch & Predict"):
68
  with st.spinner("Fetching data and predicting..."):
69
- df = get_dummy_data()
 
70
  prediction = predict_next(df)
 
 
71
 
72
  # Plot historical + predicted
73
  fig, ax = plt.subplots()
74
  ax.plot(df.index, df["Close"], label="Historical Price")
75
- ax.axhline(prediction, linestyle="--", color="red", label="Predicted Price")
76
  ax.set_title(f"{symbol} Stock Price Prediction")
77
  ax.legend()
78
  st.pyplot(fig)
79
 
80
- # Display result
81
  st.subheader("Prediction Result")
82
- st.write(f"**Predicted Price:** Rs {prediction:.2f}")
 
 
4
  import matplotlib.pyplot as plt
5
  import os
6
 
7
+ # Optional ML imports
8
  try:
9
  import tensorflow as tf
10
  from tensorflow.keras.models import load_model
 
16
  MinMaxScaler = None
17
  joblib = None
18
 
19
+ # Optional sentiment analysis
20
+ try:
21
+ from vaderSentiment.vaderSentiment import SentimentIntensityAnalyzer
22
+ analyzer = SentimentIntensityAnalyzer()
23
+ except ImportError:
24
+ analyzer = None
25
 
26
+ st.set_page_config(page_title="PSX Stock Predictor", layout="wide")
27
+ st.title("📈 PSX Stock Predictor HF Safe + Live Version")
28
 
29
  # ------------------------------
30
  # Load Model & Scaler
 
42
  st.warning("Model not found. Using dummy predictions.")
43
 
44
  # ------------------------------
45
+ # Fetch PSX Data
46
  # ------------------------------
47
+ API_KEY = os.getenv("ALPHAVANTAGE_API_KEY", None)
48
+
49
+ def get_psx_data(symbol="HBL"):
50
+ if API_KEY:
51
+ try:
52
+ import requests
53
+ url = f"https://www.alphavantage.co/query?function=TIME_SERIES_DAILY&symbol={symbol}.PSX&apikey={API_KEY}"
54
+ r = requests.get(url).json()
55
+ data = r.get("Time Series (Daily)", None)
56
+ if data:
57
+ df = pd.DataFrame(data).T
58
+ df.index = pd.to_datetime(df.index)
59
+ df = df.sort_index()
60
+ df = df[["4. close"]].rename(columns={"4. close": "Close"})
61
+ return df
62
+ except:
63
+ pass
64
+ # Fallback dummy data
65
  dates = pd.date_range(end=pd.Timestamp.today(), periods=200)
66
  prices = np.linspace(100, 150, 200) + np.random.normal(0, 2, 200)
67
  df = pd.DataFrame({"Close": prices}, index=dates)
68
  return df
69
 
70
  # ------------------------------
71
+ # News Sentiment
72
+ # ------------------------------
73
+ NEWS_KEY = os.getenv("NEWSAPI_KEY", None)
74
+
75
+ def get_sentiment(stock="HBL"):
76
+ if not analyzer or not NEWS_KEY:
77
+ return 0
78
+ try:
79
+ import requests
80
+ url = f"https://newsapi.org/v2/everything?q={stock}+Pakistan&apiKey={NEWS_KEY}"
81
+ r = requests.get(url).json()
82
+ articles = r.get("articles", [])[:5]
83
+ if not articles:
84
+ return 0
85
+ scores = [analyzer.polarity_scores(a["title"])['compound'] for a in articles]
86
+ return np.mean(scores) if scores else 0
87
+ except:
88
+ return 0
89
+
90
+ # ------------------------------
91
+ # Prediction
92
  # ------------------------------
93
  def predict_next(df):
94
  if MODEL_LOADED:
 
98
  pred_real = scaler.inverse_transform([[pred]])[0][0]
99
  return pred_real
100
  else:
101
+ # Dummy prediction: last value + small random change
102
  return df["Close"].iloc[-1] * (1 + np.random.uniform(-0.01, 0.01))
103
 
104
  # ------------------------------
 
108
 
109
  if st.button("Fetch & Predict"):
110
  with st.spinner("Fetching data and predicting..."):
111
+ df = get_psx_data(symbol)
112
+ sentiment = get_sentiment(symbol)
113
  prediction = predict_next(df)
114
+ # Adjust prediction with sentiment (2% weight)
115
+ sentiment_adj = prediction + (prediction * sentiment * 0.02)
116
 
117
  # Plot historical + predicted
118
  fig, ax = plt.subplots()
119
  ax.plot(df.index, df["Close"], label="Historical Price")
120
+ ax.axhline(sentiment_adj, linestyle="--", color="red", label="Predicted Price")
121
  ax.set_title(f"{symbol} Stock Price Prediction")
122
  ax.legend()
123
  st.pyplot(fig)
124
 
125
+ # Display results
126
  st.subheader("Prediction Result")
127
+ st.write(f"**Predicted Price:** Rs {sentiment_adj:.2f}")
128
+ st.write(f"**Sentiment Impact:** {sentiment:.3f}")