Build a Stock Analysis Agent with AutoGPT (Fundamentals + News)
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
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.
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.
Related Articles
10 AutoGPT Command Line Arguments (Continuous Mode, Speak)
Complete reference for AutoGPT's 10 most powerful CLI arguments. Master continuous mode, headless operation, and CI/CD integration for automated agent workflows.
10 AutoGPT Configuration Tweaks for Better Performance
10 proven AutoGPT configuration tweaks to improve speed, cut costs, and boost task success. Model selection, temperature, token limits, and workspace settings.
Build a Content Research Agent with AutoGPT (Trends, Outlines)
Build an AutoGPT content research agent that finds trending topics, analyzes SERPs, and generates SEO-ready outlines automatically ā full workflow inside.
Build a Data Analysis Agent with AutoGPT (CSV, SQL, Plots)
Build a data analysis agent using AutoGPT that reads CSVs, queries SQL databases, and generates plots automatically. Full code with pandas and matplotlib.