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

Stock Screener with Python: Rank 50 Stocks by ROIC, FCF Yield, and Quality Metrics No Free API Provides

Screen 50 stocks by ROIC, FCF Yield, and 3 other metrics yfinance cannot provide. Percentile-ranked composite score: Quality (60%) + Value (40%). One script, one API call, no signup.

12 min read

Mastercard. Visa. Adobe. The top 50 stocks by market cap, ranked by quality and value — not just PE ratio.

==========================================================================
                   STOCK SCREENER: TOP 10 OF 50 STOCKS
==========================================================================
Quality weight: 60% | Value weight: 40%

Rank  Ticker Company                 ROIC FCF Yld      PE  Score
--------------------------------------------------------------------------
   1  MA     Mastercard Inc        100.0%    3.3%   35.02   83.0  QUALITY
   2  BAC    BANK OF AMERICA CORP   11.4%   15.6%   15.20   75.8    VALUE
   3  BRK-B  BERKSHIRE HATHAWAY I   55.0%     N/A     N/A   70.6    VALUE
   4  V      VISA INC.              37.8%    3.4%   31.01   69.3  QUALITY
   5  PM     Philip Morris Intern   47.1%    4.3%   25.15   69.3  QUALITY
   6  MRK    Merck & Co., Inc.      26.4%    6.2%   16.11   67.4    VALUE
   7  LRCX   LAM RESEARCH CORP      75.9%    3.4%   50.66   64.7  QUALITY
   8  LLY    ELI LILLY & Co         52.4%    2.3%   51.64   64.6  QUALITY
   9  CAT    CATERPILLAR INC       388.4%    3.9%   37.09   64.4
  10  PG     PROCTER & GAMBLE Co    66.1%    4.1%   22.64   62.9
--------------------------------------------------------------------------
Screened 50 stocks | 5 metrics | ~250 credits
==========================================================================

This is Stock Screener — a Python tool that ranks stocks by composite Quality + Value score using SEC-filed data from the MetricDuck API.

Three of the five screening metrics — ROIC, FCF Yield, and FCF Margin — are not available in yfinance or any free alternative.

No API key required. No signup. Screening 50 stocks costs ~250 credits. Guest access works immediately — 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/04-stock-screener
pip install -r requirements.txt
python screener.py

That's it. Screens the top 50 companies by market cap and shows the top 10 by composite score.

Custom ticker list: python screener.py --tickers AAPL,MSFT,GOOGL,AMZN,META,NVDA

Why Screen on Quality, Not Just PE

Most stock screeners filter by PE ratio and dividend yield — metrics that yfinance provides. But a low PE tells you the stock is cheap. It doesn't tell you if the business is good.

ROIC (Return on Invested Capital) tells you how efficiently the business converts capital into profit. A company with 50% ROIC earns $50 for every $100 of capital it deploys. A company with 5% ROIC earns $5. One is a compounding machine. The other is destroying value.

FCF Yield (Free Cash Flow / Market Cap) tells you how much real cash the business generates relative to its price. Unlike earnings, free cash flow can't be inflated by accounting choices.

Screening by both — quality (ROIC + FCF Margin) and value (PE + FCF Yield + EV/EBITDA) — finds stocks that are strong businesses and reasonably priced.

What Most Screeners DoWhat This Screener Adds
PE Ratio (lower is cheaper)ROIC — is the business efficient?
Dividend YieldFCF Yield — how much real cash per dollar invested?
Market Cap filterFCF Margin — what % of revenue becomes free cash?
Sector filterComposite scoring — quality + value, percentile-ranked

How It Works

Step 1: Get the Ticker Universe

The screener starts by fetching the top N companies by market cap from the MetricDuck universe endpoint:

response = httpx.get(
    "https://api.metricduck.com/api/v1/companies/universe",
    params={"limit": 50},
)
companies = response.json()["companies"]
# [{"ticker": "AAPL", "company_name": "Apple Inc.", "rank": 1, "sic": "3571"}, ...]

Each company comes with its market cap rank and SIC code (for sector filtering). Or skip the universe and pass your own tickers with --tickers.

Step 2: Fetch Metrics for All 50 Stocks

One API call fetches all 5 metrics for all 50 tickers:

response = httpx.get(
    "https://api.metricduck.com/api/v1/data/metrics",
    params={
        "tickers": ",".join(tickers),  # "AAPL,MSFT,GOOGL,..."
        "metrics": "roic,fcf_yield,fcf_margin,pe_ratio,ev_ebitda",
        "period": "ttm",
        "price": "current",
        "years": 1,
    },
)

The response contains all 50 companies with all 5 metrics — a single request, not 50 separate calls. The price=current parameter recalculates valuation metrics at today's market price.

Step 3: Percentile Scoring

Raw metric values aren't comparable. ROIC is a percentage (0-100%+), PE is a ratio (5-100+), FCF Yield is a small percentage (0-10%). To combine them, the screener converts each metric to a percentile rank within the screened universe:

def compute_percentile_ranks(values, direction):
    valid = {t: v for t, v in values.items() if v is not None}
    # Sort: highest value = highest percentile for "higher" metrics
    #        lowest value = highest percentile for "lower" metrics
    reverse = direction == "lower"
    sorted_tickers = sorted(valid, key=lambda t: valid[t], reverse=reverse)
    n = len(sorted_tickers)
    return {
        ticker: (i / (n - 1)) * 100 if n > 1 else 50.0
        for i, ticker in enumerate(sorted_tickers)
    }

If you're ranked 90th percentile in ROIC, you have higher ROIC than 90% of the screened stocks. If you're 90th percentile in PE (where lower is better), you have lower PE than 90% of the screened stocks.

Step 4: Composite Score

The composite score is a weighted average of two category averages:

q_avg = average of [ROIC percentile, FCF Margin percentile]
v_avg = average of [PE percentile, FCF Yield percentile, EV/EBITDA percentile]

composite = 0.6 * q_avg + 0.4 * v_avg  # Quality 60%, Value 40%

The 60/40 split favors quality over value — the tool finds great businesses first, then considers price. Change the weights in the config to match your investment thesis.

Signal labels highlight the stock's strength:

  • QUALITY — top 30% in quality metrics
  • VALUE — top 30% in value metrics
  • BALANCED — top 30% in both

Handling Missing Data

Not every stock reports every metric. Banks may lack ROIC. Recently listed companies may lack FCF history. The screener handles this by scoring each stock only on the metrics it has — missing metrics are excluded from the average, not penalized.

Usage Budget

Screening costs scale linearly: tickers × metrics × years.

ModeWhat You Can Do
Guest (no key)Screen top 10 stocks, 5 requests/day
Free (registered)Screen 50 stocks, 500 credits/day (~2 screens/day)
Builder ($29/mo)Screen 200 stocks, 200,000 credits/month
Screen SizeCredits
10 stocks × 5 metrics × 1yr50
50 stocks × 5 metrics × 1yr250
100 stocks × 5 metrics × 1yr500
200 stocks × 5 metrics × 1yr1,000

Guest access (no signup) screens the top 10 stocks immediately. Register free for 500 credits/day — enough for two full 50-stock screens every day.

Build It with Claude Code

The screener is a single Python file with no frameworks. AI assistants can read, understand, and extend it in one pass.

Change the scoring weights:

"Set QUALITY_WEIGHT to 0.4 and VALUE_WEIGHT to 0.6. I want to find cheap stocks first, quality second."

Add more metrics:

"Add gross_margin and total_shareholder_yield to QUALITY_METRICS. I want to see capital return efficiency."

Add dimensions for trend analysis:

"Add dimensions=Q.TREND8 to the API call. Then add a column showing whether ROIC is rising or falling. Flag stocks where ROIC is rising AND PE is falling — the same OPPORTUNITY signal from Lab 03."

Chain with Lab 03 (Value Trap Detection):

"After screening, pipe the top 5 through pulse.py to check for value traps: python screener.py --top 5 --json | ..."

Export to CSV:

"After displaying the results, write them to a CSV file with columns: rank, ticker, company, roic, fcf_yield, pe_ratio, composite_score, signal."

The full screener.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

CommandWhat You Get
python screener.pyTop 10 of 50 largest companies by composite score
python screener.py --count 100 --top 20Screen 100 companies, show top 20
python screener.py --tickers AAPL,MSFT,GOOGL,AMZN,META,NVDAScreen specific stocks
python screener.py --jsonMachine-readable output for piping to other tools

The scoring reveals interesting patterns. Payment processors (MA, V) score high on quality — near-100% ROIC from asset-light models. Banks (BAC) score high on value — low PE and high FCF Yield. Drug makers (MRK, LLY) split between value and quality depending on pipeline stage.

What's Next

The screener tells you which stocks score highest. But are any of them value traps?

Lab 03: Stock Pulse — Value Trap Detector answers this by checking any stock against its own 2-year history. Screen with Lab 04, then pulse the top picks with Lab 03.

# Screen the top 50, then check the #1 pick for value traps
python screener.py
python ../03-stock-pulse/pulse.py MA

And if you want to compare two top picks head-to-head, use Lab 02: Stock Showdown:

python ../02-stock-showdown/showdown.py MA V

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

Full Source Code

The complete screener.py is on GitHub:

github.com/metric-duck/build-with-metricduck/labs/04-stock-screener

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 screens the top 10 stocks immediately — no signup required. Register free for 500 credits/day and full 50-stock screening. Builder tier unlocks serious screening at scale.

Get your API key

MetricDuck Team

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