import streamlit as st import requests import yfinance as yf import pandas as pd import datetime from transformers import AutoTokenizer, AutoModelForSequenceClassification import torch from plotly import graph_objs as go # Load the Hugging Face model and tokenizer @st.cache_resource def load_model(): model_name = "rahilv/financial-sentiment-model-roberta-3" model = AutoModelForSequenceClassification.from_pretrained(model_name) tokenizer = AutoTokenizer.from_pretrained(model_name) return model, tokenizer sentiment_model, sentiment_tokenizer = load_model() LABEL_MAP = {0: "bullish", 1: "bearish", 2: "neutral"} # Function to fetch stock news def get_stock_news(ticker): api_key = "d651109fae5346cbbb6812912c801e73" url = f'https://newsapi.org/v2/everything?q={ticker}&apiKey={api_key}' response = requests.get(url) if response.status_code == 200: articles = response.json().get('articles', []) return articles else: st.error(f"Error fetching news: {response.status_code}") return [] # Function to analyze sentiment def classify_sentiment(news_title): inputs = sentiment_tokenizer(news_title, return_tensors="pt", truncation=True, padding="max_length", max_length=128) with torch.no_grad(): outputs = sentiment_model(**inputs) predictions = torch.argmax(outputs.logits, dim=-1).item() return LABEL_MAP[predictions] # Function to fetch stock data from Yahoo Finance def fetch_stock_data(ticker): stock = yf.Ticker(ticker) end_date = datetime.date.today() start_date = end_date - datetime.timedelta(days=365) # 1 year of data data = stock.history(start=start_date, end=end_date) return data # Streamlit UI st.title("Stock Analysis and Sentiment App") # User input for stock ticker symbol ticker_symbol = st.text_input("Enter a Stock Ticker Symbol (e.g., AAPL, TSLA, GOOGL):") if ticker_symbol: st.subheader(f"Analysis for {ticker_symbol.upper()}") # Fetch news articles = get_stock_news(ticker_symbol) if articles: # Create a DataFrame for chart points news_points = [] st.write("## Stock Price Chart") # Fetch and plot stock data stock_data = fetch_stock_data(ticker_symbol) if not stock_data.empty: fig = go.Figure() fig.add_trace(go.Scatter(x=stock_data.index, y=stock_data['Close'], mode='lines', name='Close Price')) for article in articles: date = article['publishedAt'][:10] # Extract date title = article['title'] sentiment = classify_sentiment(title) news_points.append({'date': date, 'title': title, 'sentiment': sentiment}) color = 'green' if sentiment == 'bullish' else 'red' if sentiment == 'bearish' else 'gray' if date in stock_data.index: fig.add_trace(go.Scatter(x=[date], y=[stock_data['Close'][date]], mode='markers', marker=dict(color=color, size=10))) fig.update_layout(title=f"{ticker_symbol.upper()} Stock Price & News Sentiment", xaxis_title="Date", yaxis_title="Price") st.plotly_chart(fig) else: st.write("No stock data available.") st.write("## News Analysis") for point in news_points: color = 'green' if point['sentiment'] == 'bullish' else 'red' if point['sentiment'] == 'bearish' else 'gray' st.markdown(f"
" f"{point['title']}
{point['date']}
", unsafe_allow_html=True) # Recommendation based on sentiment sentiments = [p['sentiment'] for p in news_points] recommendation = "hold" if sentiments.count('bullish') > sentiments.count('bearish'): recommendation = "buy" elif sentiments.count('bearish') > sentiments.count('bullish'): recommendation = "sell" color_map = {"buy": "green", "sell": "red", "hold": "gray"} st.markdown(f"### Recommendation: {recommendation.upper()}", unsafe_allow_html=True) else: st.write("No news articles found.")