| import streamlit as st |
| import plotly.graph_objects as go |
| import yfinance as yf |
| from transformers import pipeline |
|
|
| class AIDashboard: |
| def __init__(self): |
| self.sentiment_model = pipeline( |
| "sentiment-analysis", |
| model="yiyanghkust/finbert-tone" |
| ) |
| |
| def render(self): |
| st.title("π§ AI Stock Research Lab") |
| |
| tab1, tab2, tab3 = st.tabs([ |
| "π° News Sentiment", |
| "π Technical Analysis", |
| "π¬ AI Chat Analyst" |
| ]) |
| |
| with tab1: |
| self.news_sentiment_tab() |
| |
| with tab2: |
| self.technical_analysis_tab() |
| |
| with tab3: |
| self.ai_chat_tab() |
| |
| def news_sentiment_tab(self): |
| st.subheader("Financial News Sentiment Analysis") |
| |
| |
| symbols = st.text_input("Enter stock symbols (comma-separated):", |
| "AAPL, MSFT, NVDA, TSLA") |
| |
| if st.button("Analyze News Sentiment"): |
| symbol_list = [s.strip() for s in symbols.split(',')] |
| |
| for symbol in symbol_list[:5]: |
| with st.expander(f"π {symbol} News Analysis"): |
| try: |
| ticker = yf.Ticker(symbol) |
| news = ticker.news[:3] |
| |
| if news: |
| total_score = 0 |
| for item in news: |
| title = item.get('title', 'No title') |
| st.write(f"**Headline**: {title}") |
| |
| |
| result = self.sentiment_model(title[:512]) |
| sentiment = result[0]['label'] |
| score = result[0]['score'] |
| total_score += score if sentiment == 'Positive' else -score |
| |
| |
| if sentiment == 'Positive': |
| st.success(f"β
Positive ({score:.2%})") |
| elif sentiment == 'Negative': |
| st.error(f"β Negative ({score:.2%})") |
| else: |
| st.info(f"π Neutral ({score:.2%})") |
| |
| |
| avg_sentiment = total_score / len(news) |
| st.metric("Overall Sentiment Score", f"{avg_sentiment:.2%}") |
| else: |
| st.warning("No recent news available") |
| except Exception as e: |
| st.error(f"Error analyzing {symbol}: {str(e)}") |
| |
| def technical_analysis_tab(self): |
| st.subheader("AI-Powered Technical Analysis") |
| |
| symbol = st.text_input("Stock Symbol:", "AAPL") |
| period = st.selectbox("Time Period", ["1mo", "3mo", "6mo", "1y"]) |
| |
| if st.button("Generate AI Analysis"): |
| try: |
| |
| ticker = yf.Ticker(symbol) |
| hist = ticker.history(period=period) |
| |
| if len(hist) > 0: |
| |
| fig = go.Figure(data=[go.Candlestick( |
| x=hist.index, |
| open=hist['Open'], |
| high=hist['High'], |
| low=hist['Low'], |
| close=hist['Close'], |
| name='Price' |
| )]) |
| |
| |
| hist['SMA_20'] = hist['Close'].rolling(window=20).mean() |
| hist['SMA_50'] = hist['Close'].rolling(window=50).mean() |
| |
| fig.add_trace(go.Scatter( |
| x=hist.index, |
| y=hist['SMA_20'], |
| name='20-Day MA', |
| line=dict(color='orange', width=2) |
| )) |
| |
| fig.add_trace(go.Scatter( |
| x=hist.index, |
| y=hist['SMA_50'], |
| name='50-Day MA', |
| line=dict(color='blue', width=2) |
| )) |
| |
| fig.update_layout( |
| title=f"{symbol} Technical Analysis", |
| yaxis_title="Price ($)", |
| xaxis_title="Date", |
| template="plotly_dark" |
| ) |
| |
| st.plotly_chart(fig, use_container_width=True) |
| |
| |
| current_price = hist['Close'].iloc[-1] |
| sma_20 = hist['SMA_20'].iloc[-1] |
| sma_50 = hist['SMA_50'].iloc[-1] |
| |
| st.subheader("π€ AI Technical Insights") |
| |
| if current_price > sma_20 and current_price > sma_50: |
| st.success("**BULLISH SIGNAL**: Price above both moving averages") |
| st.write("AI Recommendation: Consider buying on pullbacks") |
| elif current_price < sma_20 and current_price < sma_50: |
| st.error("**BEARISH SIGNAL**: Price below both moving averages") |
| st.write("AI Recommendation: Consider selling or waiting") |
| else: |
| st.warning("**NEUTRAL/MIXED SIGNALS**") |
| st.write("AI Recommendation: Hold and monitor") |
| |
| except Exception as e: |
| st.error(f"Error: {str(e)}") |
| |
| def ai_chat_tab(self): |
| st.subheader("π¬ AI Stock Analyst Chat") |
| |
| |
| user_question = st.text_input("Ask about any stock or trading strategy:") |
| |
| if user_question: |
| |
| responses = { |
| "buy": "Based on technical analysis, consider buying when price is above 50-day moving average with increasing volume.", |
| "sell": "Consider selling if stock breaks below key support levels or shows bearish divergence.", |
| "hold": "Hold if fundamentals remain strong despite short-term volatility.", |
| "portfolio": "For your portfolio, focus on diversification and risk management." |
| } |
| |
| question_lower = user_question.lower() |
| |
| if "buy" in question_lower: |
| st.info(responses["buy"]) |
| elif "sell" in question_lower: |
| st.info(responses["sell"]) |
| elif "hold" in question_lower: |
| st.info(responses["hold"]) |
| elif "portfolio" in question_lower: |
| st.info(responses["portfolio"]) |
| else: |
| st.info("AI Analysis: Consider both technical and fundamental factors before making investment decisions.") |