Build a Stock Analysis Agent with AutoGPT (Fundamentals + News)
โก Quick Answer
Build a stock analysis AutoGPT agent that fetches fundamentals, summarizes financial news, and generates structured investment research reports automatically.
Get more content like this on Telegram!
Daily AI tips, notes & resources โ free
Advertisement
Financial research is one of the clearest use cases for autonomous AI agents. The task structure is perfect โ gather data from multiple sources, synthesize it, apply consistent analytical frameworks, and produce a structured output. That's exactly what AutoGPT does well.
This guide walks through building a stock analysis agent that fetches fundamental data from Yahoo Finance, summarizes recent news, applies basic analytical frameworks, and outputs a structured investment research report. We'll also be clear about where this approach falls short and what you should never rely on it for.
Disclaimer: Nothing in this article constitutes financial advice. The agent described here is a research tool. Automated analysis has significant limitations and can be wrong. Always consult a licensed financial advisor before making investment decisions.
What the Agent Will Do
Before writing any code, define the exact scope. This agent will:
- Accept a stock ticker symbol as input
- Fetch current price, fundamentals, and historical data via Yahoo Finance
- Pull and summarize recent news articles about the company
- Apply basic valuation checks (P/E, P/B, debt ratios)
- Generate a structured markdown report with a summary, data tables, and analyst notes
What it will explicitly not do: give buy/sell recommendations, predict prices, or access paid financial data sources.
Setting Up the Environment
pip install yfinance autogen-agentchat openai newspaper3k requests beautifulsoup4 pandas
Create your project structure:
stock_agent/
โโโ main.py
โโโ tools/
โ โโโ __init__.py
โ โโโ yahoo_finance.py
โ โโโ news_fetcher.py
โโโ prompts/
โ โโโ analyst_system.txt
โโโ output/
Building the Yahoo Finance Tool
The core data fetching module handles fundamentals, price history, and basic metrics:
# tools/yahoo_finance.py
import yfinance as yf
import pandas as pd
from typing import Dict, Any, Optional
import json
def get_stock_fundamentals(ticker: str) -> Dict[str, Any]:
"""Fetch key fundamental data for a stock ticker."""
try:
stock = yf.Ticker(ticker)
info = stock.info
# Extract key metrics with safe fallbacks
fundamentals = {
"ticker": ticker.upper(),
"company_name": info.get("longName", "Unknown"),
"sector": info.get("sector", "Unknown"),
"industry": info.get("industry", "Unknown"),
"market_cap": info.get("marketCap"),
"current_price": info.get("currentPrice") or info.get("regularMarketPrice"),
"52_week_high": info.get("fiftyTwoWeekHigh"),
"52_week_low": info.get("fiftyTwoWeekLow"),
"pe_ratio": info.get("trailingPE"),
"forward_pe": info.get("forwardPE"),
"pb_ratio": info.get("priceToBook"),
"ps_ratio": info.get("priceToSalesTrailing12Months"),
"ev_to_ebitda": info.get("enterpriseToEbitda"),
"profit_margin": info.get("profitMargins"),
"revenue_growth": info.get("revenueGrowth"),
"earnings_growth": info.get("earningsGrowth"),
"debt_to_equity": info.get("debtToEquity"),
"current_ratio": info.get("currentRatio"),
"return_on_equity": info.get("returnOnEquity"),
"return_on_assets": info.get("returnOnAssets"),
"dividend_yield": info.get("dividendYield"),
"analyst_target_price": info.get("targetMeanPrice"),
"recommendation": info.get("recommendationMean"),
"number_of_analysts": info.get("numberOfAnalystOpinions"),
"business_summary": info.get("longBusinessSummary", "")[:500],
}
return {"status": "success", "data": fundamentals}
except Exception as e:
return {"status": "error", "message": str(e)}
def get_price_history(ticker: str, period: str = "1y") -> Dict[str, Any]:
"""Get historical price data and calculate basic metrics."""
try:
stock = yf.Ticker(ticker)
hist = stock.history(period=period)
if hist.empty:
return {"status": "error", "message": "No price data found"}
# Calculate returns
start_price = float(hist["Close"].iloc[0])
end_price = float(hist["Close"].iloc[-1])
total_return = ((end_price - start_price) / start_price) * 100
# Volatility (annualized)
daily_returns = hist["Close"].pct_change().dropna()
annualized_volatility = float(daily_returns.std() * (252 ** 0.5) * 100)
# Average volume
avg_volume = float(hist["Volume"].mean())
summary = {
"period": period,
"start_price": round(start_price, 2),
"end_price": round(end_price, 2),
"total_return_pct": round(total_return, 2),
"annualized_volatility_pct": round(annualized_volatility, 2),
"average_daily_volume": int(avg_volume),
"data_points": len(hist),
}
return {"status": "success", "data": summary}
except Exception as e:
return {"status": "error", "message": str(e)}
def get_financial_statements(ticker: str) -> Dict[str, Any]:
"""Get simplified income statement and balance sheet data."""
try:
stock = yf.Ticker(ticker)
# Income statement (annual)
income_stmt = stock.income_stmt
balance_sheet = stock.balance_sheet
result = {}
if not income_stmt.empty:
latest_year = income_stmt.columns[0]
result["income_latest_year"] = str(latest_year.date())
result["total_revenue"] = _safe_float(income_stmt, "Total Revenue", latest_year)
result["gross_profit"] = _safe_float(income_stmt, "Gross Profit", latest_year)
result["operating_income"] = _safe_float(income_stmt, "Operating Income", latest_year)
result["net_income"] = _safe_float(income_stmt, "Net Income", latest_year)
if not balance_sheet.empty:
latest_quarter = balance_sheet.columns[0]
result["total_assets"] = _safe_float(balance_sheet, "Total Assets", latest_quarter)
result["total_debt"] = _safe_float(balance_sheet, "Total Debt", latest_quarter)
result["cash"] = _safe_float(balance_sheet, "Cash And Cash Equivalents", latest_quarter)
return {"status": "success", "data": result}
except Exception as e:
return {"status": "error", "message": str(e)}
def _safe_float(df, row_name: str, col) -> Optional[float]:
try:
val = df.loc[row_name, col]
return float(val) if pd.notna(val) else None
except (KeyError, TypeError):
return None
Building the News Fetcher
# tools/news_fetcher.py
import yfinance as yf
from typing import List, Dict
def get_stock_news(ticker: str, max_articles: int = 10) -> Dict:
"""Fetch recent news headlines for a stock ticker."""
try:
stock = yf.Ticker(ticker)
news = stock.news
articles = []
for item in (news or [])[:max_articles]:
articles.append({
"title": item.get("title", ""),
"publisher": item.get("publisher", ""),
"link": item.get("link", ""),
"published": item.get("providerPublishTime", 0),
"type": item.get("type", ""),
"summary": item.get("summary", "")[:300] if item.get("summary") else "",
})
return {
"status": "success",
"ticker": ticker.upper(),
"article_count": len(articles),
"articles": articles,
}
except Exception as e:
return {"status": "error", "message": str(e)}
Configuring the AutoGen Analyst Agent
Now build the actual AutoGen agent that uses these tools:
# main.py
import autogen
import json
import os
from datetime import datetime
from tools.yahoo_finance import get_stock_fundamentals, get_price_history, get_financial_statements
from tools.news_fetcher import get_stock_news
def analyze_stock(ticker: str, output_dir: str = "output") -> str:
os.makedirs(output_dir, exist_ok=True)
llm_config = {
"config_list": [
{
"model": "gpt-4o",
"api_key": os.getenv("OPENAI_API_KEY"),
}
],
"temperature": 0.1,
"functions": [
{
"name": "get_fundamentals",
"description": "Fetch fundamental financial data for a stock ticker",
"parameters": {
"type": "object",
"properties": {
"ticker": {"type": "string", "description": "Stock ticker symbol"}
},
"required": ["ticker"]
}
},
{
"name": "get_price_history",
"description": "Get 1-year price history and return metrics",
"parameters": {
"type": "object",
"properties": {
"ticker": {"type": "string"}
},
"required": ["ticker"]
}
},
{
"name": "get_news",
"description": "Get recent news articles about the stock",
"parameters": {
"type": "object",
"properties": {
"ticker": {"type": "string"},
"max_articles": {"type": "integer", "default": 8}
},
"required": ["ticker"]
}
},
{
"name": "get_financials",
"description": "Get income statement and balance sheet data",
"parameters": {
"type": "object",
"properties": {
"ticker": {"type": "string"}
},
"required": ["ticker"]
}
},
]
}
analyst = autogen.AssistantAgent(
name="StockAnalyst",
system_message="""You are a financial research analyst. Your job is to produce
structured research reports based on publicly available financial data.
IMPORTANT DISCLAIMER: You must always include a prominent disclaimer that your analysis
is for informational purposes only and does not constitute investment advice.
When analyzing a stock, follow this process:
1. Fetch fundamental data using get_fundamentals
2. Get 1-year price history using get_price_history
3. Get financial statements using get_financials
4. Fetch recent news using get_news
5. Synthesize all data into a structured markdown report
Your report must include:
- Company overview
- Key metrics table (P/E, P/B, debt ratios, margins)
- 1-year price performance summary
- Recent news summary (3-5 key themes)
- Basic valuation context (compare P/E to sector average if known)
- Risks and considerations
- Disclaimer
End your response with ANALYSIS_COMPLETE when done.""",
llm_config=llm_config,
)
# Function map for the user proxy
function_map = {
"get_fundamentals": lambda ticker: get_stock_fundamentals(ticker),
"get_price_history": lambda ticker: get_price_history(ticker),
"get_news": lambda ticker, max_articles=8: get_stock_news(ticker, max_articles),
"get_financials": lambda ticker: get_financial_statements(ticker),
}
user_proxy = autogen.UserProxyAgent(
name="ResearchCoordinator",
human_input_mode="NEVER",
max_consecutive_auto_reply=15,
is_termination_msg=lambda msg: "ANALYSIS_COMPLETE" in (msg.get("content") or ""),
function_map=function_map,
code_execution_config=False,
)
user_proxy.initiate_chat(
analyst,
message=f"Please conduct a comprehensive research analysis of {ticker.upper()} stock. Use all available tools to gather data and produce a structured report.",
)
# Extract the final report
messages = analyst.chat_messages.get(user_proxy, [])
final_report = ""
for msg in reversed(messages):
if msg.get("role") == "assistant" and msg.get("content"):
final_report = msg["content"].replace("ANALYSIS_COMPLETE", "").strip()
break
# Save the report
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
output_file = os.path.join(output_dir, f"{ticker.upper()}_analysis_{timestamp}.md")
with open(output_file, "w", encoding="utf-8") as f:
f.write(f"# Stock Analysis: {ticker.upper()}\n")
f.write(f"*Generated: {datetime.now().strftime('%Y-%m-%d %H:%M UTC')}*\n\n")
f.write("---\n\n")
f.write(final_report)
print(f"Analysis saved to: {output_file}")
return output_file
if __name__ == "__main__":
import sys
ticker = sys.argv[1] if len(sys.argv) > 1 else "AAPL"
analyze_stock(ticker)
Understanding the Output Format
A well-configured run produces output like this:
# Stock Analysis: AAPL
*Generated: 2026-05-31 14:30 UTC*
---
## Company Overview
Apple Inc. (AAPL) is a consumer electronics and software company...
## Key Metrics
| Metric | Value | Context |
|--------|-------|---------|
| P/E Ratio (TTM) | 28.4 | Above tech sector avg (~25) |
| Forward P/E | 25.1 | More reasonable on growth basis |
| P/B Ratio | 42.1 | Premium brand valuation |
| Debt/Equity | 1.73 | Moderate leverage |
| Profit Margin | 25.3% | Strong operating efficiency |
| Revenue Growth (YoY) | 4.2% | Moderate growth |
| Analyst Target | $198.50 | Based on 42 analyst estimates |
## 1-Year Price Performance
- Start: $165.23 โ Current: $182.41
- Total Return: +10.4%
- Annualized Volatility: 22.1%
## Recent News Themes
1. **AI Integration:** Multiple reports on Apple Intelligence rollout...
2. **Services Growth:** App Store revenue up in Q1 2026...
## โ ๏ธ DISCLAIMER
This report is generated by an AI system for informational purposes only.
It does not constitute investment advice...
Limitations You Need to Know
| Limitation | Impact | Mitigation |
|---|---|---|
| 15-minute data delay | Price data not real-time | Note timestamp in output |
| LLM hallucination risk | Agent may misstate ratios | Cross-check key figures manually |
| No analyst consensus detail | Shallow competitive analysis | Supplement with earnings call transcripts |
| No sentiment scoring | News summary is qualitative | Add NLP sentiment layer manually |
| No historical comparison | Can't benchmark against sector | Add sector ETF comparison |
| Token context limits | Long news articles get truncated | Summarize before passing to agent |
This type of structured research automation is discussed extensively in the AI research agent build guide, which covers more advanced patterns for handling data quality and fact verification.
Running the Agent
export OPENAI_API_KEY=sk-...
python main.py MSFT
Expected runtime: 2-4 minutes per ticker, depending on data availability and LLM response speed. Token usage typically runs 3,000-6,000 tokens per analysis using GPT-4o.
For batch analysis across a watchlist:
# Create a watchlist file
echo "AAPL\nMSFT\nGOOGL\nAMZN" > watchlist.txt
# Run analysis on each
while read ticker; do
python main.py $ticker
sleep 10 # Rate limit courtesy delay
done < watchlist.txt
The same principles that make this agent work well connect directly to Build AI agent with LangChain patterns โ structured tool use, clear termination conditions, and output validation are universal regardless of which framework you use.
Frequently Asked Questions
Is AutoGPT stock analysis accurate enough for real investment decisions? No. AutoGPT-generated stock analysis should be treated as a research starting point, not investment advice. The agent can make factual errors, misinterpret financial data, or miss critical context. Always verify outputs with authoritative sources and consult a licensed financial advisor before making investment decisions.
Can this agent access real-time stock prices? The Yahoo Finance integration via yfinance provides near-real-time quotes with a 15-minute delay for free tier access. For actual real-time data, you'd need a paid data provider like Alpha Vantage premium, Polygon.io, or a direct exchange data feed integrated as a custom AutoGPT plugin.
How do I run this agent on multiple stocks at once? Use a loop that creates a separate agent instance for each ticker, or build a multi-agent setup where a coordinator agent spawns individual analyst agents per stock. Running more than 5-10 simultaneous analysis tasks will hit API rate limits and increase costs significantly.
Advertisement
๐ฌ DiscussionPowered by GitHub Discussions
Frequently Asked Questions

AiTechWorlds Team
โ Verified WriterThe AiTechWorlds team is passionate about AI, technology, and education. We create high-quality, research-backed content to help you learn, grow, and succeed in the modern digital world.
Advertisement
Related Articles
5 AutoGen Agent Roles (Assistant, UserProxy, CodeExecutor)
Understand the 5 core AutoGen agent types โ AssistantAgent, UserProxyAgent, CodeExecutorAgent, and more โ with code examples and a comparison table for each role.
How to Deploy AutoGen Agents as APIs with FastAPI (2026)
Learn to serve AutoGen multi-agent systems as production REST APIs using FastAPI with async endpoints and real-time streaming responses.
How to Use AutoGen with Azure OpenAI (Enterprise Security)
Connect Microsoft AutoGen to Azure OpenAI for enterprise-grade AI agents. Step-by-step setup with private endpoints, OAI_CONFIG_LIST, and deployment config.
Build a Code Debugging Agent with AutoGen (Auto-Fix PRs)
Build an AutoGen agent that reviews code, analyzes PR diffs, suggests fixes, and automates code quality improvements with a full working implementation.