├── requirements.txt ├── README.md └── financial_agent.py /requirements.txt: -------------------------------------------------------------------------------- 1 | phidata 2 | python-dotenv 3 | yfinance 4 | packaging 5 | duckduckgo-search 6 | fastapi 7 | uvicorn 8 | groq 9 | openai 10 | streamlit 11 | pandas 12 | plotly 13 | googlesearch-python 14 | pycountry 15 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | First Of All A Big Thanks To Krish Naik Sir! 2 | 3 | # **🌟 Financial Agentic AI: Your Ultimate Stock Market Companion 🌟** 4 | 5 | **Financial Agentic AI** redefines financial analysis by integrating cutting-edge AI with real-time web search capabilities. This multi-agent system brings together financial insights and web intelligence to deliver precise, actionable, and up-to-date stock market information, all tailored to your needs. 6 | 7 | --- 8 | 9 | ## **✨ Highlights** 10 | 11 | - **🤖 Intelligent Agents**: A robust team of AI agents designed for specialized roles, ensuring accurate and comprehensive results. 12 | - **📊 Financial Insights**: Dive deep into stock prices, company news, analyst recommendations, and historical trends with advanced tools. 13 | - **🌐 Real-Time Web Search**: Augment your financial knowledge with live updates from Google Search and DuckDuckGo, ensuring nothing escapes your radar. 14 | - **📈 Unified System**: Experience seamless integration of financial and web-based intelligence, empowering your stock market decisions like never before. 15 | 16 | --- 17 | 18 | ## **🔧 Features** 19 | 20 | ### **1. Web Search Agent** 21 | - **Purpose**: Scours the web for relevant, real-time data. 22 | - **Tools**: 23 | - **Google Search**: Fixed language and results for consistency. 24 | - **DuckDuckGo**: Privacy-conscious searches with maximum results tailored to your query. 25 | - **Capabilities**: 26 | - Always includes sources for transparency. 27 | - Displays results in Markdown format for readability. 28 | 29 | ### **2. Financial Insights Agent** 30 | - **Purpose**: Analyzes stock market trends and financial data. 31 | - **Tools**: 32 | - **YFinanceTools**: Tracks stock prices, company news, analyst recommendations, and historical prices. 33 | - **Capabilities**: 34 | - Provides structured insights in easy-to-read tables. 35 | - Combines data visualization and textual summaries for clarity. 36 | 37 | ### **3. Multi-Agent Integration** 38 | - **Purpose**: Combines the power of Web Search and Financial Insights agents. 39 | - **Capabilities**: 40 | - Delivers a holistic view of the stock market. 41 | - Responds to queries with multi-dimensional insights for better decision-making. 42 | 43 | --- 44 | 45 | ## **🔍 How It Works** 46 | 47 | 1. **Agent-Based Architecture**: 48 | - Build highly specialized AI agents using the `phi.agent` framework. 49 | 50 | 2. **Real-Time Data Processing**: 51 | - Access live financial and web-based information using APIs. 52 | 53 | 3. **Intuitive Interaction**: 54 | - Get responses enriched with tables, Markdown formatting, and always backed by credible sources. 55 | 56 | 4. **Query Example**: 57 | - **Question**: "Summarize analyst recommendations and share the latest news for Nvidia." 58 | - **Response**: A structured table highlighting analyst sentiments, news trends, and real-time updates. 59 | 60 | --- 61 | 62 | ## **🚀 Quickstart** 63 | 64 | ### **Step 1: Clone the Repository** 65 | ```bash 66 | git clone https://github.com/yourusername/financial-agentic-ai.git 67 | cd financial-agentic-ai 68 | ``` 69 | 70 | ### **Step 2: Install Dependencies** 71 | ```bash 72 | pip install -r requirements.txt 73 | ``` 74 | 75 | ### **Step 3: Set Up Environment Variables** 76 | - Create a `.env` file with the following keys: 77 | ```env 78 | GROQ_API_KEY=your_groq_api_key 79 | ``` 80 | 81 | ### **Step 4: Run the Script** 82 | ```bash 83 | python financial_agent.py 84 | ``` 85 | 86 | --- 87 | 88 | ## **📚 Key Technologies** 89 | - **phi.agent**: Modular AI agent framework. 90 | - **Groq Model**: AI model powering intelligent decision-making. 91 | - **YFinanceTools**: Real-time financial data analysis. 92 | - **Google Search & DuckDuckGo APIs**: Live web search integration. 93 | 94 | --- 95 | 96 | ## **🎯 Use Cases** 97 | - Financial analysts seeking reliable and actionable insights. 98 | - Stock market enthusiasts looking for real-time updates. 99 | - AI researchers exploring multi-agent architectures. 100 | 101 | --- 102 | 103 | ## **💡 Why Choose Financial Agentic AI?** 104 | - **Dynamic Intelligence**: Combines financial and web insights in a single response. 105 | - **Transparency**: Always includes sources and structured outputs for trustworthiness. 106 | - **Customizable**: Fully adaptable to various financial scenarios. 107 | 108 | -------------------------------------------------------------------------------- /financial_agent.py: -------------------------------------------------------------------------------- 1 | import streamlit as st 2 | import pandas as pd 3 | import plotly.graph_objects as go 4 | import plotly.express as px 5 | from datetime import datetime, timedelta 6 | from phi.agent.agent import Agent 7 | from phi.model.groq import Groq 8 | from phi.tools.yfinance import YFinanceTools 9 | from phi.tools.duckduckgo import DuckDuckGo 10 | from phi.tools.googlesearch import GoogleSearch 11 | import yfinance as yf 12 | 13 | # Get API key from Streamlit secrets 14 | GROQ_API_KEY = st.secrets["GROQ_API_KEY"] 15 | 16 | # Enhanced stock symbol mappings 17 | COMMON_STOCKS = { 18 | # US Stocks 19 | 'NVIDIA': 'NVDA', 20 | 'APPLE': 'AAPL', 21 | 'GOOGLE': 'GOOGL', 22 | 'MICROSOFT': 'MSFT', 23 | 'TESLA': 'TSLA', 24 | 'AMAZON': 'AMZN', 25 | 'META': 'META', 26 | 'NETFLIX': 'NFLX', 27 | # Indian Stocks - NSE 28 | 'TCS': 'TCS.NS', 29 | 'RELIANCE': 'RELIANCE.NS', 30 | 'INFOSYS': 'INFY.NS', 31 | 'WIPRO': 'WIPRO.NS', 32 | 'HDFC': 'HDFCBANK.NS', 33 | 'TATAMOTORS': 'TATAMOTORS.NS', 34 | 'ICICIBANK': 'ICICIBANK.NS', 35 | 'SBIN': 'SBIN.NS', 36 | 'MARUTI': 'MARUTI.NS', 37 | 'BHARTIARTL': 'BHARTIARTL.NS', 38 | 'HCLTECH': 'HCLTECH.NS', 39 | 'ITC': 'ITC.NS', 40 | 'AXISBANK': 'AXISBANK.NS' 41 | } 42 | 43 | # Page configuration 44 | st.set_page_config( 45 | page_title="Advanced Stock Market Analysis", 46 | page_icon="📈", 47 | layout="wide", 48 | initial_sidebar_state="expanded" 49 | ) 50 | 51 | # Custom CSS with improved styling 52 | st.markdown(""" 53 | 104 | """, unsafe_allow_html=True) 105 | 106 | # Initialize session state 107 | if 'agents_initialized' not in st.session_state: 108 | st.session_state.agents_initialized = False 109 | st.session_state.watchlist = set() 110 | st.session_state.analysis_history = [] 111 | st.session_state.last_refresh = None 112 | 113 | def initialize_agents(): 114 | """Initialize all agent instances with improved error handling""" 115 | if not st.session_state.agents_initialized: 116 | try: 117 | st.session_state.web_agent = Agent( 118 | name="Web Search Agent", 119 | role="Search the web for the information", 120 | model=Groq(api_key=GROQ_API_KEY), 121 | tools=[ 122 | GoogleSearch(fixed_language='english', fixed_max_results=5), 123 | DuckDuckGo(fixed_max_results=5) 124 | ], 125 | instructions=['Always include sources and verification'], 126 | show_tool_calls=True, 127 | markdown=True 128 | ) 129 | 130 | st.session_state.finance_agent = Agent( 131 | name="Financial AI Agent", 132 | role="Providing financial insights", 133 | model=Groq(api_key=GROQ_API_KEY), 134 | tools=[ 135 | YFinanceTools( 136 | stock_price=True, 137 | company_news=True, 138 | analyst_recommendations=True, 139 | historical_prices=True 140 | ) 141 | ], 142 | instructions=["Provide detailed analysis with data visualization"], 143 | show_tool_calls=True, 144 | markdown=True 145 | ) 146 | 147 | st.session_state.multi_ai_agent = Agent( 148 | name='A Stock Market Agent', 149 | role='A comprehensive assistant specializing in stock market analysis', 150 | model=Groq(api_key=GROQ_API_KEY), 151 | team=[st.session_state.web_agent, st.session_state.finance_agent], 152 | instructions=["Provide comprehensive analysis with multiple data sources"], 153 | show_tool_calls=True, 154 | markdown=True 155 | ) 156 | 157 | st.session_state.agents_initialized = True 158 | return True 159 | except Exception as e: 160 | st.error(f"Error initializing agents: {str(e)}") 161 | return False 162 | 163 | def get_symbol_from_name(stock_name): 164 | """Enhanced function to fetch stock symbol from full stock name""" 165 | try: 166 | # Clean up input 167 | stock_name = stock_name.strip().upper() 168 | 169 | # First check if it's in our common stocks dictionary 170 | if stock_name in COMMON_STOCKS: 171 | return COMMON_STOCKS[stock_name] 172 | 173 | # Check if it's already a valid symbol 174 | ticker = yf.Ticker(stock_name) 175 | try: 176 | info = ticker.info 177 | if info and 'symbol' in info: 178 | return stock_name 179 | except: 180 | pass 181 | 182 | # Try Indian stock market (NSE) 183 | try: 184 | indian_symbol = f"{stock_name}.NS" 185 | ticker = yf.Ticker(indian_symbol) 186 | info = ticker.info 187 | if info and 'symbol' in info: 188 | return indian_symbol 189 | except: 190 | # Try BSE 191 | try: 192 | bse_symbol = f"{stock_name}.BO" 193 | ticker = yf.Ticker(bse_symbol) 194 | info = ticker.info 195 | if info and 'symbol' in info: 196 | return bse_symbol 197 | except: 198 | pass 199 | 200 | st.error(f"Could not find valid symbol for {stock_name}") 201 | return None 202 | except Exception as e: 203 | st.error(f"Error processing {stock_name}: {str(e)}") 204 | return None 205 | 206 | def get_stock_data(symbol, period="1y"): 207 | """Enhanced function to fetch stock data with proper cache handling""" 208 | try: 209 | # Create a new ticker instance 210 | stock = yf.Ticker(symbol) 211 | 212 | # Fetch data with error handling 213 | try: 214 | info = stock.info 215 | if not info: 216 | raise ValueError("No data retrieved for symbol") 217 | except Exception as info_error: 218 | # If .NS suffix is missing for Indian stocks, try adding it 219 | if not symbol.endswith('.NS') and not symbol.endswith('.BO'): 220 | try: 221 | indian_symbol = f"{symbol}.NS" 222 | stock = yf.Ticker(indian_symbol) 223 | info = stock.info 224 | symbol = indian_symbol 225 | except: 226 | # Try Bombay Stock Exchange 227 | try: 228 | bse_symbol = f"{symbol}.BO" 229 | stock = yf.Ticker(bse_symbol) 230 | info = stock.info 231 | symbol = bse_symbol 232 | except: 233 | raise info_error 234 | else: 235 | raise info_error 236 | 237 | # Fetch historical data 238 | hist = stock.history(period=period, interval="1d", auto_adjust=True) 239 | 240 | if hist.empty: 241 | raise ValueError("No historical data available") 242 | 243 | return info, hist 244 | except Exception as e: 245 | st.error(f"Error fetching data for {symbol}: {str(e)}") 246 | return None, None 247 | 248 | def create_price_chart(hist_data, symbol): 249 | """Create an interactive price chart using plotly""" 250 | fig = go.Figure() 251 | 252 | # Add candlestick chart 253 | fig.add_trace(go.Candlestick( 254 | x=hist_data.index, 255 | open=hist_data['Open'], 256 | high=hist_data['High'], 257 | low=hist_data['Low'], 258 | close=hist_data['Close'], 259 | name='Price' 260 | )) 261 | 262 | # Add moving averages 263 | ma20 = hist_data['Close'].rolling(window=20).mean() 264 | ma50 = hist_data['Close'].rolling(window=50).mean() 265 | 266 | fig.add_trace(go.Scatter(x=hist_data.index, y=ma20, name='20 Day MA', line=dict(color='orange'))) 267 | fig.add_trace(go.Scatter(x=hist_data.index, y=ma50, name='50 Day MA', line=dict(color='blue'))) 268 | 269 | fig.update_layout( 270 | title=f'{symbol} Stock Price', 271 | yaxis_title='Price', 272 | template='plotly_white', 273 | xaxis_rangeslider_visible=False, 274 | height=600 275 | ) 276 | 277 | return fig 278 | 279 | def create_volume_chart(hist_data): 280 | """Create enhanced volume chart using plotly""" 281 | # Calculate volume moving average 282 | volume_ma = hist_data['Volume'].rolling(window=20).mean() 283 | 284 | fig = go.Figure() 285 | 286 | # Add volume bars 287 | fig.add_trace(go.Bar( 288 | x=hist_data.index, 289 | y=hist_data['Volume'], 290 | name='Volume', 291 | marker_color='rgba(31, 119, 180, 0.3)' 292 | )) 293 | 294 | # Add volume moving average 295 | fig.add_trace(go.Scatter( 296 | x=hist_data.index, 297 | y=volume_ma, 298 | name='20 Day Volume MA', 299 | line=dict(color='red') 300 | )) 301 | 302 | fig.update_layout( 303 | title='Trading Volume Analysis', 304 | yaxis_title='Volume', 305 | template='plotly_white', 306 | height=400 307 | ) 308 | 309 | return fig 310 | 311 | def format_large_number(number): 312 | """Format large numbers into readable format""" 313 | if number >= 1e12: 314 | return f"${number/1e12:.2f}T" 315 | elif number >= 1e9: 316 | return f"${number/1e9:.2f}B" 317 | elif number >= 1e6: 318 | return f"${number/1e6:.2f}M" 319 | else: 320 | return f"${number:,.2f}" 321 | 322 | def display_metrics(info): 323 | """Display enhanced key metrics in a grid""" 324 | col1, col2, col3, col4 = st.columns(4) 325 | 326 | with col1: 327 | st.markdown('
{news_item['summary']}
530 | Source: {news_item.get('source', 'Unknown')} | 531 | {datetime.fromtimestamp(news_item['providerPublishTime']).strftime('%Y-%m-%d %H:%M:%S')} 532 |