Spaces:
Running
Running
Benjamin Consolvo
commited on
Commit
·
cf6c896
1
Parent(s):
6e28fc5
alpaca news
Browse files
app.py
CHANGED
|
@@ -129,10 +129,20 @@ class NewsSentiment:
|
|
| 129 |
self.newsapi = NewsApiClient(api_key=API_KEY)
|
| 130 |
self.sia = SentimentIntensityAnalyzer()
|
| 131 |
self.alpha_vantage_api_key = st.secrets.get("ALPHA_VANTAGE_API_KEY")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 132 |
|
| 133 |
def get_sentiment_and_headlines(self, symbol):
|
| 134 |
"""
|
| 135 |
-
Try NewsAPI first, fallback to Alpha Vantage if needed.
|
| 136 |
Returns (sentiment, headlines, source, avg_score).
|
| 137 |
"""
|
| 138 |
# Try NewsAPI
|
|
@@ -151,28 +161,40 @@ class NewsSentiment:
|
|
| 151 |
|
| 152 |
# Fallback to Alpha Vantage
|
| 153 |
try:
|
| 154 |
-
if
|
| 155 |
-
|
| 156 |
-
|
| 157 |
-
|
| 158 |
-
|
| 159 |
-
|
| 160 |
-
|
| 161 |
-
|
| 162 |
-
|
| 163 |
-
|
| 164 |
-
|
| 165 |
-
|
| 166 |
-
|
| 167 |
-
|
| 168 |
-
|
| 169 |
-
else:
|
| 170 |
-
logger.warning(f"Alpha Vantage returned no headlines for {symbol}.")
|
| 171 |
except Exception as e:
|
| 172 |
logger.error(f"Alpha Vantage error for {symbol}: {e}")
|
| 173 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 174 |
logger.info(
|
| 175 |
-
f"No sentiment/headlines available for {symbol} from
|
| 176 |
)
|
| 177 |
return None, [], None, None
|
| 178 |
|
|
@@ -205,12 +227,12 @@ class NewsSentiment:
|
|
| 205 |
sentiment[symbol] = (s, "NewsAPI")
|
| 206 |
else:
|
| 207 |
# fallback to Alpha Vantage
|
| 208 |
-
s, _, src = self.get_sentiment_and_headlines(symbol)
|
| 209 |
sentiment[symbol] = (s, src)
|
| 210 |
except Exception as e:
|
| 211 |
logger.error(f"Error getting news for {symbol}: {e}")
|
| 212 |
# fallback to Alpha Vantage
|
| 213 |
-
s, _, src = self.get_sentiment_and_headlines(symbol)
|
| 214 |
sentiment[symbol] = (s, src)
|
| 215 |
return sentiment
|
| 216 |
|
|
|
|
| 129 |
self.newsapi = NewsApiClient(api_key=API_KEY)
|
| 130 |
self.sia = SentimentIntensityAnalyzer()
|
| 131 |
self.alpha_vantage_api_key = st.secrets.get("ALPHA_VANTAGE_API_KEY")
|
| 132 |
+
# Try to get Alpaca API for news fallback
|
| 133 |
+
try:
|
| 134 |
+
self.alpaca_api = alpaca.REST(
|
| 135 |
+
st.secrets.get("ALPACA_API_KEY"),
|
| 136 |
+
st.secrets.get("ALPACA_SECRET_KEY"),
|
| 137 |
+
"https://paper-api.alpaca.markets"
|
| 138 |
+
)
|
| 139 |
+
except Exception as e:
|
| 140 |
+
logger.error(f"Could not initialize Alpaca API for news fallback: {e}")
|
| 141 |
+
self.alpaca_api = None
|
| 142 |
|
| 143 |
def get_sentiment_and_headlines(self, symbol):
|
| 144 |
"""
|
| 145 |
+
Try NewsAPI first, fallback to Alpha Vantage, then Alpaca news if needed.
|
| 146 |
Returns (sentiment, headlines, source, avg_score).
|
| 147 |
"""
|
| 148 |
# Try NewsAPI
|
|
|
|
| 161 |
|
| 162 |
# Fallback to Alpha Vantage
|
| 163 |
try:
|
| 164 |
+
if self.alpha_vantage_api_key:
|
| 165 |
+
import requests
|
| 166 |
+
url = (
|
| 167 |
+
f"https://www.alphavantage.co/query?function=NEWS_SENTIMENT&tickers={symbol}"
|
| 168 |
+
f"&apikey={self.alpha_vantage_api_key}"
|
| 169 |
+
)
|
| 170 |
+
resp = requests.get(url)
|
| 171 |
+
data = resp.json()
|
| 172 |
+
headlines = [item.get("title") for item in data.get("feed", [])[:5] if item.get("title")]
|
| 173 |
+
if headlines:
|
| 174 |
+
sentiment, avg_score = self._calculate_sentiment(headlines, return_score=True)
|
| 175 |
+
logger.info(f"Alpha Vantage sentiment for {symbol}: {sentiment} | Headlines: {headlines}")
|
| 176 |
+
return sentiment, headlines, "AlphaVantage", avg_score
|
| 177 |
+
else:
|
| 178 |
+
logger.warning(f"Alpha Vantage returned no headlines for {symbol}.")
|
|
|
|
|
|
|
| 179 |
except Exception as e:
|
| 180 |
logger.error(f"Alpha Vantage error for {symbol}: {e}")
|
| 181 |
|
| 182 |
+
# Fallback to Alpaca News API
|
| 183 |
+
try:
|
| 184 |
+
if self.alpaca_api:
|
| 185 |
+
news_items = self.alpaca_api.get_news(symbol, limit=5)
|
| 186 |
+
headlines = [item.headline for item in news_items if hasattr(item, "headline")]
|
| 187 |
+
if headlines:
|
| 188 |
+
sentiment, avg_score = self._calculate_sentiment(headlines, return_score=True)
|
| 189 |
+
logger.info(f"Alpaca News sentiment for {symbol}: {sentiment} | Headlines: {headlines}")
|
| 190 |
+
return sentiment, headlines, "AlpacaNews", avg_score
|
| 191 |
+
else:
|
| 192 |
+
logger.warning(f"Alpaca News returned no headlines for {symbol}.")
|
| 193 |
+
except Exception as e:
|
| 194 |
+
logger.error(f"Alpaca News error for {symbol}: {e}")
|
| 195 |
+
|
| 196 |
logger.info(
|
| 197 |
+
f"No sentiment/headlines available for {symbol} from NewsAPI, Alpha Vantage, or Alpaca News."
|
| 198 |
)
|
| 199 |
return None, [], None, None
|
| 200 |
|
|
|
|
| 227 |
sentiment[symbol] = (s, "NewsAPI")
|
| 228 |
else:
|
| 229 |
# fallback to Alpha Vantage
|
| 230 |
+
s, _, src, _ = self.get_sentiment_and_headlines(symbol)
|
| 231 |
sentiment[symbol] = (s, src)
|
| 232 |
except Exception as e:
|
| 233 |
logger.error(f"Error getting news for {symbol}: {e}")
|
| 234 |
# fallback to Alpha Vantage
|
| 235 |
+
s, _, src, _ = self.get_sentiment_and_headlines(symbol)
|
| 236 |
sentiment[symbol] = (s, src)
|
| 237 |
return sentiment
|
| 238 |
|