Build It WithMetricDuck APIPythonStock Comparison
Part of the Build It With MetricDuck series

Stock Showdown: Compare Stocks with Python — ROIC, FCF Yield, and 5 Metrics yfinance Can't Provide

Compare any two stocks across Valuation and Quality panels — ROIC, FCF Margin, EV/EBIT, FCF Yield, and Total Shareholder Yield that yfinance cannot provide. One API call, no signup. Clone the repo and run it in 60 seconds.

10 min read
Updated Feb 9, 2026

Compare NVDA vs AMD. AAPL vs MSFT. Any two stocks, head-to-head, in your terminal.

Five of seven metrics — ROIC, FCF Margin, FCF Yield, EV/EBIT, Total Shareholder Yield — are not available through yfinance or any free alternative.

======================================================================
                   STOCK SHOWDOWN: AAPL vs MSFT
======================================================================

PANEL 1: VALUATION  (Who's cheaper today?)
----------------------------------------------------------------------
                            AAPL           MSFT     Better Value
----------------------------------------------------------------------
PE Ratio                   37.18          24.99         MSFT ->
EV/EBITDA                  23.97          18.29         MSFT ->
EV/EBIT *                  26.08          23.70         MSFT ->
FCF Yield *                 2.7%           3.0%         MSFT ->
                                             Valuation: MSFT 4-0

PANEL 2: QUALITY  (Who's the better business?)
----------------------------------------------------------------------
                            AAPL           MSFT   Better Quality
----------------------------------------------------------------------
ROIC *                     52.3%          25.1%         <- AAPL
FCF Margin *               26.4%          33.2%         MSFT ->
Shareholder Yield *         3.8%           2.1%         <- AAPL
                                               Quality: AAPL 2-1

======================================================================
VERDICT
----------------------------------------------------------------------
Valuation: MSFT is clearly cheaper (4 of 4 metrics)
Quality:   AAPL is stronger (2 of 3 metrics) -- ROIC 52.3% vs 25.1%

AAPL has higher quality, MSFT is cheaper.
Classic value-vs-quality tradeoff.
----------------------------------------------------------------------
* = MetricDuck exclusive (not available in yfinance)
======================================================================

This is Stock Showdown — a Python tool that compares any two stocks using SEC-filed data from the MetricDuck API.

No API key required. No signup. Guest access gives you all 70 metrics and all 12 statistical dimensions. Just clone, install, run.

Quick Start

Python 3.10+ required.

git clone https://github.com/metric-duck/build-with-metricduck.git
cd build-with-metricduck/labs/02-stock-showdown
pip install -r requirements.txt
python showdown.py NVDA AMD

That's it. Works immediately — no API key, no config file, no signup.

Default comparison (no arguments): python showdown.py runs AAPL vs MSFT.

Why Two Panels

Most stock comparison tools show a flat list of ratios. The Stock Showdown splits the question in two:

Panel 1 — Valuation: Who is cheaper today?

MetricWhat It MeasuresPrefer
PE RatioPrice per $1 of earningsLower
EV/EBITDAEnterprise value per $1 of cash earningsLower
EV/EBIT *Enterprise value per $1 of operating incomeLower
FCF Yield *Free cash flow as % of market capHigher

Panel 2 — Quality: Who is the better business?

MetricWhat It MeasuresPrefer
ROIC *Return on Invested Capital — how efficiently the business uses capitalHigher
FCF Margin *Free cash flow as % of revenue — cash generation efficiencyHigher
Total Shareholder Yield *Dividends + buybacks + debt paydown as % of market capHigher

* = MetricDuck exclusive — not available in yfinance.

How It Works

One API Call

The showdown fetches both tickers with all 7 metrics in a single request:

import httpx

response = httpx.get(
    "https://api.metricduck.com/api/v1/data/metrics",
    params={
        "tickers": "NVDA,AMD",
        "metrics": "pe_ratio,ev_ebitda,ev_ebit,fcf_yield,roic,fcf_margin,total_shareholder_yield",
        "period": "ttm",
        "price": "current",
    },
)
data = response.json()

The price=current parameter recalculates valuation metrics at today's market price, not the stale price from the last SEC filing. One parameter — real-time valuations from SEC-filed fundamentals.

All data uses Trailing Twelve Months (TTM) — the sum of the last four quarters of SEC filings, giving you the most recent full-year picture.

The response is nested by ticker, then by metric:

{
  "data": {
    "NVDA": {
      "company_name": "NVIDIA Corporation",
      "metrics": {
        "roic": {
          "label": "Return on Invested Capital",
          "values": [
            {"period": "TTM", "end_date": "2025-01-26", "value": 0.8234, "dimension": null}
          ]
        },
        "pe_ratio": {
          "label": "PE Ratio",
          "values": [
            {"period": "TTM", "end_date": "2025-01-26", "value": 48.31, "dimension": null}
          ]
        }
      }
    },
    "AMD": {
      "company_name": "Advanced Micro Devices, Inc.",
      "metrics": { ... }
    }
  },
  "metadata": {
    "tickers": ["NVDA", "AMD"],
    "period": "ttm",
    "price": "current"
  }
}

Each metric's values array contains objects with dimension: null for the base value. When you add statistical dimensions later, additional entries appear with dimension: "Q.MED8" etc.

The Comparison Logic

Each metric has a "prefer" direction and an "exclusive" flag:

VALUATION_METRICS = [
    ("PE Ratio",  "pe_ratio",  "lower",  False),  # Available in yfinance
    ("EV/EBITDA", "ev_ebitda", "lower",  False),  # Available in yfinance
    ("EV/EBIT",   "ev_ebit",   "lower",  True),   # MetricDuck exclusive
    ("FCF Yield", "fcf_yield", "higher", True),   # MetricDuck exclusive
]

QUALITY_METRICS = [
    ("ROIC",              "roic",                     "higher", True),   # Exclusive
    ("FCF Margin",        "fcf_margin",               "higher", True),   # Exclusive
    ("Shareholder Yield", "total_shareholder_yield",  "higher", True),   # Exclusive
]

For each metric, the tool compares both stocks and awards a point to the winner within its panel. The verdict combines both panels: valuation winner, quality winner, and an overall synthesis.

The best outcomes are when one stock wins both panels. The most interesting outcomes are when the panels disagree — quality vs value tradeoffs that force you to think about what you're optimizing for.

Extracting Values from the API Response

The API returns a nested structure. Each metric's values array may contain multiple entries (base values and dimension values). The showdown extracts base values by filtering for dimension: null:

def extract_metric(api_data, ticker, metric_id):
    company = api_data.get("data", {}).get(ticker, {})
    metric = company.get("metrics", {}).get(metric_id, {})
    for v in metric.get("values", []):
        if v.get("dimension") is None and v.get("value") is not None:
            return v["value"]
    return None

This pattern is future-proof — it works even when you add statistical dimensions to the request later.

Optional: yfinance for Market Context

If yfinance is installed, the showdown adds a "Market Context" panel showing sector, beta, and 52-week range:

try:
    import yfinance as yf
    HAS_YFINANCE = True
except ImportError:
    HAS_YFINANCE = False

If yfinance isn't installed, the tool works fine without it. All 7 comparison metrics come from MetricDuck. yfinance adds supplementary context only.

# Optional: adds sector, beta, 52-week range
pip install yfinance

Build It with Claude Code

The showdown is a single Python file with no frameworks. This makes it ideal for AI-assisted development.

Here are some real modifications you can ask Claude Code (or any AI assistant) to make:

Add a metric to the quality panel:

"Add gross_margin to QUALITY_METRICS. It should prefer higher and is a MetricDuck exclusive."

Generate a sector comparison:

"Modify showdown.py to accept a list of tickers and run round-robin comparisons for AAPL, MSFT, GOOGL, AMZN, META. Output a summary table of win/loss records."

Add CSV export:

"After displaying the comparison, write the results to a CSV file with columns: metric, ticker_a_value, ticker_b_value, winner."

Combine with Lab 03:

"After the showdown, run a Stock Pulse check on the winning stock to see if it's trading above or below its 2-year median."

The full showdown.py is a single self-contained file with no class hierarchies and no abstractions. AI coding assistants can read the entire file, understand it, and extend it in one pass.

Try It Yourself

MatchupCommandWhat You'll See
NVDA vs AMDpython showdown.py NVDA AMDGPU rivals — who has better ROIC?
GOOGL vs METApython showdown.py GOOGL METAAd tech — quality vs valuation
V vs MApython showdown.py V MAPayment duopoly — who returns more to shareholders?
COST vs WMTpython showdown.py COST WMTRetail — membership model advantage
TSLA vs RIVNpython showdown.py TSLA RIVNEV makers — profitability gap
JPM vs GSpython showdown.py JPM GSBanks — ROIC may show N/A (financial companies)

Cross-sector comparisons are interesting too. Compare a tech stock to a utility, a growth stock to a value stock. The two-panel design makes the tradeoff explicit.

What about missing data?

Some stocks don't report all metrics. Banks typically don't have meaningful ROIC or EBITDA. Growth stocks may have negative FCF Yield. The tool handles this — missing values show as N/A and don't count toward the score.

What's Next

The showdown tells you who's cheaper and who's the better business today. But is the cheaper stock actually cheap by its own standards?

Lab 03: Stock Pulse — Value Trap Detector answers this by comparing any stock to its own 2-year history using MetricDuck's statistical dimensions (Q.MED8, Q.TREND8). Is NVDA's ROIC improving or declining? Is the cheaper stock actually cheap, or a value trap?

cd ../03-stock-pulse
python pulse.py NVDA

Browse all 70 available metrics at metricduck.com/metrics.

Full Source Code

The complete showdown.py is on GitHub:

github.com/metric-duck/build-with-metricduck/labs/02-stock-showdown

Clone it, read it, modify it. The only dependency is httpx.

API Access

TierDaily LimitMax TickersCost
Guest (no key)5 requests/day10 tickersFree
Free (registered)500 credits/day200 tickersFree
Builder200,000 credits/mo200 tickers$29/mo
Production1,000,000 credits/mo200 tickers$79/mo

Guest access works immediately — no signup required. Each showdown costs 14 credits. Register free for 500 credits/day — enough for ~35 showdowns every day. Builder tier unlocks serious development.

Get your API key

MetricDuck Team

Building financial intelligence you can trust. Sourced directly from SEC Edgar.