rahilv commited on
Commit
d24035a
·
verified ·
1 Parent(s): 0a02bff

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +93 -58
app.py CHANGED
@@ -1,76 +1,111 @@
1
  import streamlit as st
 
 
2
  import pandas as pd
3
- import feedparser
4
  from transformers import AutoTokenizer, AutoModelForSequenceClassification
5
  import torch
 
6
 
7
- # Load the trained model and tokenizer
8
- MODEL_NAME = "rahilv/financial-sentiment-model"
9
- model = AutoModelForSequenceClassification.from_pretrained(MODEL_NAME)
10
- tokenizer = AutoTokenizer.from_pretrained(MODEL_NAME)
11
-
12
- LABEL_MAP = {0: "Bullish", 1: "Bearish", 2: "Neutral"}
13
-
14
- # RSS Feed URLs
15
- rss_feeds = {
16
- "Benzinga": ["https://www.benzinga.com/feeds/news", "https://www.benzinga.com/feeds/analysis"],
17
- "Yahoo News": ["https://finance.yahoo.com/rss/topstories"]
18
- }
19
-
20
- def fetch_rss_feed(url):
21
- """Fetch articles from an RSS feed."""
22
- feed = feedparser.parse(url)
23
- articles = []
24
- for entry in feed.entries:
25
- articles.append({"title": entry.title, "link": entry.link})
26
- return articles
27
-
28
- def analyze_sentiment(text):
29
- """Analyze sentiment of a given text."""
30
- inputs = tokenizer(text, return_tensors="pt", truncation=True, padding="max_length", max_length=128)
 
 
 
 
31
  with torch.no_grad():
32
- outputs = model(**inputs)
33
  predictions = torch.argmax(outputs.logits, dim=-1).item()
34
  return LABEL_MAP[predictions]
35
 
36
- def main():
37
- st.set_page_config(page_title="Financial News Sentiment", layout="wide")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
38
 
39
- st.title("\U0001F4C8 Financial News Sentiment Analysis")
40
- st.write("Analyze sentiment from the latest financial news articles.")
 
 
 
 
 
 
 
 
 
41
 
42
- # Sidebar: Feed Selection
43
- st.sidebar.header("Settings")
44
- selected_feeds = st.sidebar.multiselect("Select RSS Feeds:", options=rss_feeds.keys(), default=list(rss_feeds.keys()))
 
 
 
 
 
 
 
45
 
46
- if not selected_feeds:
47
- st.warning("Please select at least one RSS feed.")
48
- return
49
 
50
- st.sidebar.markdown("---")
51
- st.sidebar.info(
52
- "This app fetches financial news from RSS feeds and analyzes the sentiment (Bullish, Bearish, Neutral) of news titles."
53
- )
54
 
55
- # Fetch and Display Articles
56
- st.header("\U0001F4F0 Latest Financial News")
 
 
 
57
 
58
- articles = []
59
- for feed_name in selected_feeds:
60
- for url in rss_feeds[feed_name]:
61
- articles.extend(fetch_rss_feed(url))
62
 
63
- if not articles:
64
- st.write("No articles found.")
65
- return
 
66
 
67
- # Display articles in a clean layout
68
- for article in articles:
69
- sentiment = analyze_sentiment(article["title"])
70
- st.subheader(article["title"])
71
- st.write(f"Sentiment: **{sentiment}**")
72
- st.markdown(f"[Read more]({article['link']})", unsafe_allow_html=True)
73
- st.markdown("---")
74
 
75
- if __name__ == "__main__":
76
- main()
 
1
  import streamlit as st
2
+ import requests
3
+ import yfinance as yf
4
  import pandas as pd
5
+ import datetime
6
  from transformers import AutoTokenizer, AutoModelForSequenceClassification
7
  import torch
8
+ from plotly import graph_objs as go
9
 
10
+ # Load the Hugging Face model and tokenizer
11
+ @st.cache_resource
12
+ def load_model():
13
+ model_name = "rahilv/financial-sentiment-model"
14
+ model = AutoModelForSequenceClassification.from_pretrained(model_name)
15
+ tokenizer = AutoTokenizer.from_pretrained(model_name)
16
+ return model, tokenizer
17
+
18
+ sentiment_model, sentiment_tokenizer = load_model()
19
+
20
+ LABEL_MAP = {0: "bullish", 1: "bearish", 2: "neutral"}
21
+
22
+ # Function to fetch stock news
23
+ def get_stock_news(ticker):
24
+ api_key = 'd651109fae5346cbbb6812912c801e73'
25
+ url = f'https://newsapi.org/v2/everything?q={ticker}&apiKey={api_key}'
26
+
27
+ response = requests.get(url)
28
+ if response.status_code == 200:
29
+ articles = response.json().get('articles', [])
30
+ return articles
31
+ else:
32
+ st.error(f"Error fetching news: {response.status_code}")
33
+ return []
34
+
35
+ # Function to analyze sentiment
36
+ def classify_sentiment(news_title):
37
+ inputs = sentiment_tokenizer(news_title, return_tensors="pt", truncation=True, padding="max_length", max_length=128)
38
  with torch.no_grad():
39
+ outputs = sentiment_model(**inputs)
40
  predictions = torch.argmax(outputs.logits, dim=-1).item()
41
  return LABEL_MAP[predictions]
42
 
43
+ # Function to fetch stock data from Yahoo Finance
44
+ def fetch_stock_data(ticker):
45
+ stock = yf.Ticker(ticker)
46
+ end_date = datetime.date.today()
47
+ start_date = end_date - datetime.timedelta(days=365) # 1 year of data
48
+ data = stock.history(start=start_date, end=end_date)
49
+ return data
50
+
51
+ # Streamlit UI
52
+ st.title("Stock Analysis and Sentiment App")
53
+
54
+ # User input for stock ticker symbol
55
+ ticker_symbol = st.text_input("Enter a Stock Ticker Symbol (e.g., AAPL, TSLA, GOOGL):")
56
+
57
+ if ticker_symbol:
58
+ st.subheader(f"Analysis for {ticker_symbol.upper()}")
59
+
60
+ # Fetch news
61
+ articles = get_stock_news(ticker_symbol)
62
 
63
+ if articles:
64
+ # Create a DataFrame for chart points
65
+ news_points = []
66
+
67
+ st.write("## Stock Price Chart")
68
+ # Fetch and plot stock data
69
+ stock_data = fetch_stock_data(ticker_symbol)
70
+
71
+ if not stock_data.empty:
72
+ fig = go.Figure()
73
+ fig.add_trace(go.Scatter(x=stock_data.index, y=stock_data['Close'], mode='lines', name='Close Price'))
74
 
75
+ for article in articles:
76
+ date = article['publishedAt'][:10] # Extract date
77
+ title = article['title']
78
+ sentiment = classify_sentiment(title)
79
+ news_points.append({'date': date, 'title': title, 'sentiment': sentiment})
80
+
81
+ color = 'green' if sentiment == 'bullish' else 'red' if sentiment == 'bearish' else 'gray'
82
+ if date in stock_data.index:
83
+ fig.add_trace(go.Scatter(x=[date], y=[stock_data['Close'][date]],
84
+ mode='markers', marker=dict(color=color, size=10)))
85
 
86
+ fig.update_layout(title=f"{ticker_symbol.upper()} Stock Price & News Sentiment", xaxis_title="Date", yaxis_title="Price")
87
+ st.plotly_chart(fig)
 
88
 
89
+ else:
90
+ st.write("No stock data available.")
 
 
91
 
92
+ st.write("## News Analysis")
93
+ for point in news_points:
94
+ color = 'green' if point['sentiment'] == 'bullish' else 'red' if point['sentiment'] == 'bearish' else 'gray'
95
+ st.markdown(f"<div style='border-left: 5px solid {color}; padding: 10px; margin: 10px 0;'>"
96
+ f"<b>{point['title']}</b><br>{point['date']}</div>", unsafe_allow_html=True)
97
 
98
+ # Recommendation based on sentiment
99
+ sentiments = [p['sentiment'] for p in news_points]
100
+ recommendation = "hold"
 
101
 
102
+ if sentiments.count('bullish') > sentiments.count('bearish'):
103
+ recommendation = "buy"
104
+ elif sentiments.count('bearish') > sentiments.count('bullish'):
105
+ recommendation = "sell"
106
 
107
+ color_map = {"buy": "green", "sell": "red", "hold": "gray"}
108
+ st.markdown(f"### Recommendation: <span style='color: {color_map[recommendation]}; font-size: 1.5em;'>{recommendation.upper()}</span>", unsafe_allow_html=True)
 
 
 
 
 
109
 
110
+ else:
111
+ st.write("No news articles found.")