Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
@@ -1,76 +1,111 @@
|
|
1 |
import streamlit as st
|
|
|
|
|
2 |
import pandas as pd
|
3 |
-
import
|
4 |
from transformers import AutoTokenizer, AutoModelForSequenceClassification
|
5 |
import torch
|
|
|
6 |
|
7 |
-
# Load the
|
8 |
-
|
9 |
-
|
10 |
-
|
11 |
-
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
def
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
|
|
|
|
|
|
|
|
31 |
with torch.no_grad():
|
32 |
-
outputs =
|
33 |
predictions = torch.argmax(outputs.logits, dim=-1).item()
|
34 |
return LABEL_MAP[predictions]
|
35 |
|
36 |
-
|
37 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
38 |
|
39 |
-
|
40 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
41 |
|
42 |
-
|
43 |
-
|
44 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
45 |
|
46 |
-
|
47 |
-
|
48 |
-
return
|
49 |
|
50 |
-
|
51 |
-
|
52 |
-
"This app fetches financial news from RSS feeds and analyzes the sentiment (Bullish, Bearish, Neutral) of news titles."
|
53 |
-
)
|
54 |
|
55 |
-
|
56 |
-
|
|
|
|
|
|
|
57 |
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
articles.extend(fetch_rss_feed(url))
|
62 |
|
63 |
-
|
64 |
-
|
65 |
-
|
|
|
66 |
|
67 |
-
|
68 |
-
|
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 |
-
|
76 |
-
|
|
|
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.")
|