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) | |