Spaces:
Sleeping
Sleeping
import streamlit as st | |
from transformers import pipeline | |
import yfinance as yf | |
import requests | |
from bs4 import BeautifulSoup | |
import xml.etree.ElementTree as ET | |
import re # Add this import at the top of your code | |
# Set up the models for Named Entity Recognition, Sentiment Analysis, and Text Generation | |
ner_model = "Cassie-0121/fin-bert-finetuned-ner" | |
sentiment_model = "yiyanghkust/finbert-tone" | |
text_gen_model = "gpt2" | |
ner = pipeline("ner", model=ner_model) | |
sentiment_analyzer = pipeline("sentiment-analysis", model=sentiment_model) | |
text_generator = pipeline("text-generation", model=text_gen_model) | |
# App title | |
st.title("AI-Powered Financial Analysis App") | |
# Sidebar for selecting stock | |
st.sidebar.header("Select Stock for Analysis") | |
top_25_stocks = [ | |
"AAPL", "MSFT", "GOOGL", "AMZN", "TSLA", "META", "NVDA", "BRK-B", "JNJ", "JPM", | |
"V", "PG", "UNH", "DIS", "MA", "HD", "BAC", "XOM", "VZ", "PFE", | |
"KO", "PEP", "MRK", "WMT", "CSCO" | |
] | |
selected_stock = st.sidebar.selectbox("Choose a stock for analysis:", top_25_stocks) | |
# Function to fetch latest stock data using yfinance | |
def get_stock_data(ticker): | |
stock = yf.Ticker(ticker) | |
stock_info = stock.history(period="1d") | |
return stock_info | |
# Function to fetch latest news from Yahoo Finance or fallback to Google News RSS feed | |
def get_latest_news(ticker): | |
try: | |
# Attempt to fetch from Yahoo Finance | |
url = f"https://finance.yahoo.com/quote/{ticker}?p={ticker}" | |
page = requests.get(url) | |
soup = BeautifulSoup(page.content, "html.parser") | |
headlines = soup.find_all('h3', class_="Mb(5px)") | |
news = [headline.text for headline in headlines[:5]] | |
if news: | |
return news | |
except Exception as e: | |
st.warning("Yahoo Finance news not available. Switching to Google News.") | |
# Fallback to Google News RSS if Yahoo Finance fails | |
rss_url = f"https://news.google.com/rss/search?q={ticker}" | |
response = requests.get(rss_url) | |
root = ET.fromstring(response.content) | |
news = [item.find('title').text for item in root.findall(".//item")][:5] | |
return news | |
# Display stock data | |
st.header(f"Latest Stock Data for {selected_stock}") | |
stock_data = get_stock_data(selected_stock) | |
st.write(stock_data) | |
# Display latest news | |
st.header(f"Latest News for {selected_stock}") | |
news = get_latest_news(selected_stock) | |
if news: | |
for article in news: | |
st.write(f"- {article}") | |
else: | |
st.write("No news available for this stock at the moment.") | |
# Extract key financial entities with filtering | |
st.header("Extracted Key Financial Entities") | |
if news: | |
entities = ner(" ".join(news)) | |
# Set a confidence threshold for filtering | |
confidence_threshold = 0.8 | |
extracted_entities = [] | |
for entity in entities: | |
# Filter entities with score above threshold and check for sub-word tokens | |
if entity['score'] >= confidence_threshold and not entity['word'].startswith("##"): | |
# Append only unique entities | |
extracted_entities.append((entity['word'], entity['entity'], entity['score'])) | |
if extracted_entities: | |
for word, label, score in extracted_entities: | |
st.write(f"Entity: {word}, Label: {label}, Score: {score:.2f}") | |
else: | |
st.write("No high-confidence financial entities detected.") | |
else: | |
st.write("Entity extraction requires news data.") | |
# Sentiment analysis on news | |
st.header("Sentiment Analysis") | |
if news: | |
sentiment = sentiment_analyzer(" ".join(news)) | |
if sentiment: | |
for result in sentiment: | |
st.write(f"Sentiment: {result['label']}, Score: {result['score']:.2f}") | |
else: | |
st.write("No sentiment detected.") | |
else: | |
st.write("Sentiment analysis requires news data.") | |
# Investment advice for a specific stock | |
st.header("Investment Advice or Strategy") | |
# Get user input for stock symbol (e.g., "AAPL", "GOOGL", "MSFT") | |
stock_symbol = selected_stock # input("Enter the stock symbol (e.g., AAPL, GOOGL, MSFT): ").upper() | |
# Fetch stock data for the selected symbol | |
stock = yf.Ticker(stock_symbol) | |
# Get historical data for the last month | |
data = stock.history(period="1mo") | |
# Debugging: Show the data to check if it's being fetched correctly | |
st.write(data) | |
# Ensure data is available | |
if len(data) < 2: | |
st.warning(f"Not enough data available for {stock_symbol}. Please check the stock symbol.") | |
else: | |
# Get the latest closing price | |
latest_close = data['Close'][-1] | |
# Get the 50-day moving average (optional, can be adjusted) | |
moving_avg_50 = data['Close'].rolling(window=50).mean().iloc[-1] if len(data) > 50 else None | |
# Calculate stock volatility (standard deviation of returns) | |
returns = data['Close'].pct_change() | |
volatility = returns.std() | |
# Prepare the investment advice based on the stock data and trends | |
investment_advice = f""" | |
Investment Strategy for {stock_symbol}: | |
- Latest Closing Price: ${latest_close:.2f} | |
""" | |
# Add the 50-day moving average only if it's not None | |
if moving_avg_50 is not None: | |
investment_advice += f"- 50-Day Moving Average: {moving_avg_50:.2f}\n" | |
else: | |
investment_advice += "- 50-Day Moving Average: Not available (insufficient data)\n" | |
investment_advice += f""" | |
- Stock Volatility (1-Month): {volatility:.2%} | |
Based on recent stock data, {stock_symbol} is currently trading at ${latest_close:.2f}. The stock has shown a recent uptrend and is supported by strong fundamentals, making it a solid investment for long-term growth. However, the volatility (standard deviation of returns) indicates some price fluctuations in the short term, so investors should be cautious of potential short-term risks. | |
### Suggested Actions: | |
1. **Consider Buying** if the stock is trading below its 50-day moving average, as this may indicate an undervalued opportunity for long-term investors. | |
2. **Watch for Volatility**: If the stock experiences significant price swings, it may indicate market uncertainty or external factors affecting the stock. | |
3. **Monitor Earnings Reports**: {stock_symbol}'s quarterly earnings report will provide important insights into its revenue streams and future prospects. | |
4. **Long-term Investment**: Due to its strong market position and potential growth, {stock_symbol} remains a good candidate for long-term portfolios. | |
### Risks: | |
- **Market Volatility**: As indicated by the volatility of returns, there could be some short-term price swings. | |
- **Competition**: The competitive landscape in the industry is constantly evolving, which could impact future performance. | |
### Expected Benefits: | |
- **Growth Potential**: {stock_symbol}'s growth in its core business or new ventures should continue to drive long-term stock price appreciation. | |
- **Strong Cash Flow**: The company’s significant cash reserves may allow for innovation, stock buybacks, and dividend payments to shareholders. | |
In conclusion, {stock_symbol} is a strong stock with long-term growth potential, but investors should monitor market trends and the stock's volatility to time their investments effectively. | |
""" | |
# Display the generated investment strategy | |
st.write(investment_advice) | |