Python Intermediate

Company Financial Comparison

Compare financial metrics and key ratios across multiple companies side by side.

Note: The code examples in this tutorial have not yet been verified against the live API. If you encounter issues, please let us know.

What You'll Build

A command-line tool that fetches the latest financial data for two to five companies and displays a side-by-side comparison table. The tool pulls raw financial statements from SEC filings and calculates key ratios like profit margin, debt-to-equity, and free cash flow so you can quickly evaluate companies against each other.

All financial data comes from actual SEC filings (10-K and 10-Q reports), so the numbers match what companies officially report to the SEC.

Prerequisites

  • Python 3.8 or later
  • The requests library (pip install requests)
  • A stockdata.dev API key — get one free

The Code

Create a file called compare.py. This script takes two to five tickers as arguments, fetches their financial data, and prints a formatted comparison table.

Python
import sys
import requests

API_KEY = "your_api_key_here"
BASE_URL = "https://api.stockdata.dev/v1"
HEADERS = {"X-API-Key": API_KEY}


def format_billions(n):
    """Format a number as billions with one decimal place."""
    if n is None:
        return "N/A"
    return f"${n / 1e9:.1f}B"


def format_pct(n):
    """Format a number as a percentage with one decimal place."""
    if n is None:
        return "N/A"
    return f"{n * 100:.1f}%"


def fetch_financials(ticker):
    """Fetch the latest financials for a ticker."""
    resp = requests.get(
        f"{BASE_URL}/company/{ticker}/financials",
        headers=HEADERS,
    )
    if resp.status_code != 200:
        print(f"Error fetching {ticker}: {resp.json().get('error', resp.text)}")
        return None
    return resp.json()


def fetch_company(ticker):
    """Fetch company profile for the name."""
    resp = requests.get(
        f"{BASE_URL}/company/{ticker}",
        headers=HEADERS,
    )
    if resp.status_code != 200:
        return {"name": ticker}
    return resp.json()


def safe_get(data, key):
    """Safely get a numeric value from financials."""
    val = data.get(key)
    if val is None or val == 0:
        return None
    return val


def calculate_ratios(fin):
    """Calculate derived financial ratios from raw data."""
    revenue = safe_get(fin, "revenue")
    net_income = safe_get(fin, "net_income")
    operating_income = safe_get(fin, "operating_income")
    total_assets = safe_get(fin, "total_assets")
    total_debt = safe_get(fin, "total_debt")
    stockholders_equity = safe_get(fin, "stockholders_equity")
    operating_cash_flow = safe_get(fin, "operating_cash_flow")
    capex = safe_get(fin, "capital_expenditures")

    # Calculate ratios
    profit_margin = net_income / revenue if revenue and net_income else None
    operating_margin = operating_income / revenue if revenue and operating_income else None
    de_ratio = total_debt / stockholders_equity if stockholders_equity and total_debt else None
    roa = net_income / total_assets if total_assets and net_income else None

    # Free cash flow = operating cash flow - capital expenditures
    if operating_cash_flow and capex:
        free_cash_flow = operating_cash_flow - abs(capex)
    else:
        free_cash_flow = None

    return {
        "revenue": revenue,
        "net_income": net_income,
        "profit_margin": profit_margin,
        "operating_margin": operating_margin,
        "total_assets": total_assets,
        "total_debt": total_debt,
        "de_ratio": de_ratio,
        "free_cash_flow": free_cash_flow,
        "roa": roa,
    }


def print_comparison(tickers, all_ratios, fiscal_year):
    """Print a formatted side-by-side comparison table."""
    col_width = 14
    label_width = 22
    total_width = label_width + col_width * len(tickers) + 1

    print(f"\nFinancial Comparison (FY {fiscal_year})")
    print("=" * total_width)

    # Header row
    header = " " * label_width
    for t in tickers:
        header += f"{t:>{col_width}}"
    print(header)
    print("-" * total_width)

    # Rows: (label, key, formatter)
    rows = [
        ("Revenue", "revenue", format_billions),
        ("Net Income", "net_income", format_billions),
        ("Profit Margin", "profit_margin", format_pct),
        ("Operating Margin", "operating_margin", format_pct),
        ("Total Assets", "total_assets", format_billions),
        ("Total Debt", "total_debt", format_billions),
        ("D/E Ratio", "de_ratio", lambda x: f"{x:.2f}" if x else "N/A"),
        ("Free Cash Flow", "free_cash_flow", format_billions),
        ("ROA", "roa", format_pct),
    ]

    for label, key, fmt in rows:
        row = f"{label:<{label_width}}"
        for t in tickers:
            val = all_ratios[t].get(key)
            row += f"{fmt(val):>{col_width}}"
        print(row)

    print("-" * total_width)


if __name__ == "__main__":
    if len(sys.argv) < 3:
        print("Usage: python compare.py AAPL MSFT GOOGL")
        print("       (provide 2-5 tickers)")
        sys.exit(1)

    tickers = [t.upper() for t in sys.argv[1:6]]  # Max 5 tickers
    print(f"Fetching financials for: {', '.join(tickers)}...")

    all_ratios = {}
    fiscal_year = None

    for ticker in tickers:
        company = fetch_company(ticker)
        fin = fetch_financials(ticker)
        if fin is None:
            print(f"Skipping {ticker} - could not fetch financials.")
            continue

        # Use the fiscal year from the first company
        if fiscal_year is None and fin.get("fiscal_year"):
            fiscal_year = fin["fiscal_year"]

        all_ratios[ticker] = calculate_ratios(fin)

    if not all_ratios:
        print("No data retrieved. Check your API key and tickers.")
        sys.exit(1)

    valid_tickers = [t for t in tickers if t in all_ratios]
    print_comparison(valid_tickers, all_ratios, fiscal_year or "Latest")

How It Works

The script uses two API endpoints to build the comparison:

Company Profile: GET /v1/company/{ticker}

Fetches basic company information, including the company name. This is used for display purposes in the output.

Financial Statements: GET /v1/company/{ticker}/financials

Returns the latest annual financial data from the company's most recent 10-K filing. The response includes income statement items (revenue, net income, operating income), balance sheet items (total assets, total debt, stockholders' equity), and cash flow items (operating cash flow, capital expenditures).

HTTP
GET https://api.stockdata.dev/v1/company/AAPL/financials
X-API-Key: your_api_key_here

Calculating Ratios from Raw Data

SEC filings report raw numbers. The script derives the ratios that investors actually care about:

  • Profit Margin = Net Income / Revenue
  • Operating Margin = Operating Income / Revenue
  • Debt-to-Equity (D/E) = Total Debt / Stockholders' Equity
  • Return on Assets (ROA) = Net Income / Total Assets
  • Free Cash Flow = Operating Cash Flow - Capital Expenditures

Each calculation uses safe_get() to handle missing values gracefully. If a data point is missing from a filing, the ratio displays "N/A" instead of crashing.

Capital expenditures are sometimes reported as negative numbers in SEC filings. The script uses abs(capex) to handle both conventions correctly.

Running It

Install the dependency and run the comparison:

Shell
pip install requests

Compare three tech companies

Shell
$ python compare.py AAPL MSFT GOOGL
Fetching financials for: AAPL, MSFT, GOOGL...

Financial Comparison (FY 2025)
═══════════════════════════════════════════════════════════════
                        AAPL          MSFT         GOOGL
───────────────────────────────────────────────────────────────
Revenue              $383.3B       $245.1B       $350.0B
Net Income            $97.0B        $88.1B        $99.2B
Profit Margin          25.3%         35.9%         28.3%
Operating Margin       30.7%         44.6%         32.1%
Total Assets         $365.0B       $512.2B       $432.5B
Total Debt           $108.0B        $47.0B        $28.5B
D/E Ratio              1.38          0.42          0.11
Free Cash Flow        $93.0B        $70.2B        $69.5B
ROA                    26.6%         17.2%         23.0%
───────────────────────────────────────────────────────────────

You can compare any combination of two to five companies. The tool works best when comparing companies in the same industry, but cross-industry comparisons can also reveal interesting differences in business models.

Shell
# Compare automakers
$ python compare.py TSLA F GM

# Compare banks
$ python compare.py JPM BAC GS WFC

Understanding the Ratios

Here is a brief guide to each ratio and what to look for:

  • Profit Margin — What percentage of revenue becomes profit after all expenses. Higher is better. Software companies often exceed 20%; retailers may be under 5%. A declining margin over time can signal rising costs.
  • Operating Margin — Profitability from core operations, excluding interest and taxes. This is a cleaner measure of operational efficiency than profit margin. Values above 15% are generally strong.
  • Debt-to-Equity (D/E) Ratio — How much debt a company carries relative to shareholder equity. Below 1.0 is conservative; above 2.0 is aggressive. Compare within the same industry, since capital-intensive businesses naturally carry more debt.
  • Return on Assets (ROA) — How efficiently a company uses its assets to generate profit. Above 10% is strong for most industries. Asset-light businesses (like software) tend to have higher ROA than asset-heavy ones (like manufacturing).
  • Free Cash Flow — Cash generated from operations minus capital expenditures. This is the cash available for dividends, buybacks, acquisitions, or debt reduction. Consistently positive free cash flow is a sign of financial health.

No single ratio tells the whole story. Use the comparison table to spot patterns: a company with high margins but high debt may be riskier than one with moderate margins and no debt.

Enhancements

Here are several ways to extend the comparison tool:

  • Quarterly comparison — Pass a --quarterly flag to compare the most recent quarterly (10-Q) filings instead of annual data. Use the period=quarterly parameter on the financials endpoint.
  • Historical trends — Fetch multiple years of data and show how ratios have changed over time. Display year-over-year growth rates for revenue and net income.
  • Export to CSV — Add a --csv output.csv flag that writes the comparison table to a CSV file for use in spreadsheets.
  • Export to JSON — Add a --json flag that outputs the raw ratios as JSON, useful for piping into other tools or dashboards.
  • Color coding — Highlight the best and worst values in each row using ANSI color codes (green for best, red for worst).
  • Industry averages — Use the SIC code from the company profile to group companies by industry and show how each compares to the industry average.

Ready to build?

Get your free API key and start coding in minutes.

Get Free API Key