Building a Financial Analysis Agent: Balance Sheets, Ratios, and Forecasting
Learn to build an AI agent that parses financial statements, calculates key ratios like current ratio and ROE, performs trend analysis across quarters, and generates risk assessments with forward-looking forecasts.
Why Financial Analysis Needs AI Agents
Reading a balance sheet is straightforward for a trained analyst. Comparing five years of quarterly data across three competitors while calculating 15 different financial ratios, spotting anomalies, and projecting trends — that is where humans slow down and AI agents excel. A financial analysis agent takes raw financial data, computes every relevant metric, flags risks, and produces an investment-grade summary in seconds.
The agent we build here handles three core tasks: parsing financial statements into structured data, computing standard financial ratios, and projecting future performance based on historical trends.
Financial Data Parser
Financial data comes in many formats — SEC filings, CSV exports from accounting software, or API responses. This tool normalizes financial statement data into a standard structure:
import json
from agents import Agent, Runner, function_tool
_financial_data: dict[str, dict] = {}
@function_tool
def load_financials(company: str, data_json: str) -> str:
"""Load financial statement data for a company.
Expects JSON with keys: revenue, cogs, gross_profit, operating_expenses,
net_income, total_assets, total_liabilities, equity, current_assets,
current_liabilities, cash, inventory, receivables, period."""
try:
data = json.loads(data_json)
except json.JSONDecodeError as e:
return f"Invalid JSON: {e}"
required = ["revenue", "net_income", "total_assets", "total_liabilities", "equity"]
missing = [k for k in required if k not in data]
if missing:
return f"Missing required fields: {', '.join(missing)}"
if company not in _financial_data:
_financial_data[company] = {"periods": []}
_financial_data[company]["periods"].append(data)
return f"Loaded {data.get('period', 'unknown period')} for {company}. Total periods: {len(_financial_data[company]['periods'])}"
Ratio Calculation Engine
Financial ratios are the language of fundamental analysis. This tool calculates all major categories — liquidity, profitability, efficiency, and leverage:
@function_tool
def calculate_ratios(company: str, period_index: int = -1) -> str:
"""Calculate financial ratios for a company's specified period.
Use period_index -1 for the most recent period."""
if company not in _financial_data:
return f"No data loaded for {company}."
periods = _financial_data[company]["periods"]
if abs(period_index) > len(periods):
return f"Only {len(periods)} periods available."
d = periods[period_index]
ratios = {}
# Liquidity ratios
if d.get("current_assets") and d.get("current_liabilities"):
ca, cl = d["current_assets"], d["current_liabilities"]
ratios["Current Ratio"] = round(ca / cl, 2) if cl else None
quick_assets = ca - d.get("inventory", 0)
ratios["Quick Ratio"] = round(quick_assets / cl, 2) if cl else None
# Profitability ratios
if d.get("revenue"):
rev = d["revenue"]
ratios["Net Profit Margin"] = f"{round(d['net_income'] / rev * 100, 1)}%"
if d.get("gross_profit"):
ratios["Gross Margin"] = f"{round(d['gross_profit'] / rev * 100, 1)}%"
# Return ratios
if d.get("total_assets") and d["total_assets"] > 0:
ratios["ROA"] = f"{round(d['net_income'] / d['total_assets'] * 100, 1)}%"
if d.get("equity") and d["equity"] > 0:
ratios["ROE"] = f"{round(d['net_income'] / d['equity'] * 100, 1)}%"
# Leverage ratios
if d.get("equity") and d["equity"] > 0:
ratios["Debt-to-Equity"] = round(d["total_liabilities"] / d["equity"], 2)
period_label = d.get("period", f"index {period_index}")
lines = [f"Financial Ratios for {company} ({period_label}):"]
for name, value in ratios.items():
lines.append(f" {name}: {value}")
return "\n".join(lines)
Trend Analysis Tool
Comparing ratios across periods reveals whether a company's financial health is improving or deteriorating:
See AI Voice Agents Handle Real Calls
Book a free demo or calculate how much you can save with AI voice automation.
@function_tool
def analyze_trends(company: str) -> str:
"""Analyze financial trends across all loaded periods for a company."""
if company not in _financial_data:
return f"No data for {company}."
periods = _financial_data[company]["periods"]
if len(periods) < 2:
return "Need at least 2 periods for trend analysis."
metrics = ["revenue", "net_income", "total_assets", "total_liabilities"]
trends = []
for metric in metrics:
values = [p.get(metric) for p in periods if p.get(metric) is not None]
if len(values) < 2:
continue
changes = []
for i in range(1, len(values)):
pct = ((values[i] - values[i - 1]) / abs(values[i - 1])) * 100
changes.append(round(pct, 1))
avg_change = round(sum(changes) / len(changes), 1)
direction = "growing" if avg_change > 0 else "declining"
trends.append(f" {metric}: {direction} (avg {avg_change}% per period)")
return f"Trends for {company}:\n" + "\n".join(trends)
Risk Assessment and Forecasting
The agent can flag financial red flags and project future values using simple linear extrapolation:
import numpy as np
@function_tool
def forecast_metric(company: str, metric: str, periods_ahead: int = 4) -> str:
"""Forecast a financial metric using linear regression on historical data."""
if company not in _financial_data:
return f"No data for {company}."
values = [
p.get(metric)
for p in _financial_data[company]["periods"]
if p.get(metric) is not None
]
if len(values) < 3:
return f"Need at least 3 data points. Have {len(values)}."
x = np.arange(len(values))
coeffs = np.polyfit(x, values, 1)
slope, intercept = coeffs
forecasts = []
for i in range(len(values), len(values) + periods_ahead):
projected = slope * i + intercept
forecasts.append(round(projected, 2))
trend = "upward" if slope > 0 else "downward"
return (
f"Forecast for {company} - {metric}:\n"
f" Historical trend: {trend} (slope: {round(slope, 2)} per period)\n"
f" Next {periods_ahead} periods: {forecasts}"
)
Assembling the Financial Agent
financial_agent = Agent(
name="Financial Analyst",
instructions="""You are a financial analysis agent. When given financial data:
1. Load all periods using load_financials.
2. Calculate ratios for each period with calculate_ratios.
3. Run analyze_trends to identify trajectory.
4. Use forecast_metric for key metrics (revenue, net_income).
5. Assess risk: flag current ratio below 1.5, debt-to-equity above 2.0,
declining revenue, or negative net income trends.
6. Produce a report: Overview, Key Ratios, Trends, Risk Flags, Forecast.""",
tools=[load_financials, calculate_ratios, analyze_trends, forecast_metric],
)
FAQ
Where can I get real financial data to feed this agent?
The SEC EDGAR API provides free access to public company filings. The sec-api Python package simplifies fetching 10-K and 10-Q reports. For market data, Yahoo Finance (yfinance package) provides historical prices and basic financials.
How reliable is linear forecasting for financial metrics?
Linear extrapolation is useful for identifying directional trends but should not be used for precise predictions. For more accurate forecasting, integrate ARIMA or Prophet models. The agent can call a specialized forecasting tool that uses these methods internally.
Can this agent compare multiple companies side by side?
Yes. Load financial data for each company, then instruct the agent to calculate ratios for all of them and produce a comparative table. The trend analysis tool works per-company, so the agent can highlight which competitor is growing fastest or has the strongest balance sheet.
#FinancialAnalysis #Ratios #Forecasting #Python #AIAgents #AgenticAI #LearnAI #AIEngineering
CallSphere Team
Expert insights on AI voice agents and customer communication automation.
Try CallSphere AI Voice Agents
See how AI voice agents work for your industry. Live demo available -- no signup required.