High Dividend Yield Screen: 12.25% CAGR With Quality Filters (25-Year Backtest)

We backtested a high dividend yield screen with quality filters (ROE, FCF, debt) across 25 years of US stock data. 12.25% CAGR vs 7.85% for the S&P 500, with near-zero down capture.

Growth of $1 invested in high dividend yield quality screen vs S&P 500 from 2000 to 2025 on US exchanges.

High dividend yield stocks get a bad reputation. And often deservedly so. Chasing yield without checking fundamentals leads to yield traps: companies paying unsustainable dividends right before they cut. But filtering for quality changes the picture. We backtested a high-yield screen with ROE, debt, and cash flow filters across 25 years of US stock data. The result: 12.25% CAGR vs 7.85% for the S&P 500, with near-zero down capture (+1.6%). The strategy was roughly flat during market downturns on average, while capturing 107% of the upside.

Contents

  1. Method
  2. Signal
  3. Why Quality Filters Matter
  4. Results
  5. Annual Returns
  6. When It Works
  7. When It Struggles
  8. The Simple Screen
  9. Limitations
  10. Takeaway
  11. Part of a Series
  12. Run This Screen Yourself
  13. References

Data: FMP financial data warehouse, 2000–2025. Updated March 2026.


Method

Data source: Ceta Research (FMP financial data, 70K+ stocks) Universe: All US stocks (NYSE + NASDAQ + AMEX) with market cap > $1B Period: 2000-2025 (25 years) Rebalancing: Annual (July) Transaction costs: Size-tiered (0.1% large cap, 0.3% mid cap, 0.5% small cap, one-way)

Signal

Filter Threshold Why
Dividend yield 4% to 15% Target high payers, cap at 15% to exclude distressed
Payout ratio 0% to 80% Sustainable dividends, room to reinvest
Free cash flow > 0 Cash backing the dividend
Return on equity > 8% Profitable business, not a dying one
Debt to equity < 2.0 Not overleveraged
Market cap > $1B Liquid, reliable data

Portfolio: Top 30 stocks by highest dividend yield. Equal weight. Hold cash if fewer than 10 qualify.

The yield floor of 4% targets stocks paying meaningfully above market average. The 15% cap filters out distressed situations where the price has collapsed, inflating the yield artificially. Quality filters (ROE, FCF, payout, debt) separate sustainable dividends from yield traps.


Why Quality Filters Matter

A high dividend yield can mean two things: 1. The company is shareholder-friendly and generating excess cash (opportunity) 2. The stock price has crashed and the dividend is about to be cut (trap)

Without filters, you're buying both. Dogs of the Dow works because the Dow 30 are already quality-filtered by index membership. When you screen the full market, you need to do the filtering yourself.

Our quality gates: - ROE > 8% eliminates struggling businesses. If a company can't earn 8% on equity, the high yield probably reflects poor fundamentals. - FCF > 0 ensures the dividend is backed by actual cash generation, not accounting tricks. - Payout < 80% means the company retains enough earnings to reinvest. A 95% payout ratio is a warning sign. - D/E < 2.0 screens out companies leveraging up to fund dividends.

Fama and French (1998) documented that high-yield stocks outperform as a value proxy across 13 international markets. But the raw signal is noisy. Quality filters clean it up.


Results

Metric Strategy S&P 500
CAGR 12.25% 7.85%
Total Return 1,700% 562%
Max Drawdown -26.36% -38.01%
Sharpe Ratio 0.598 0.352
Sortino Ratio 1.447 0.628
Calmar Ratio 0.465 0.207
Win Rate (vs SPY) 56% --
Up Capture 106.6% --
Down Capture +1.6% --
Beta 0.659 --
Alpha 4.40% --
Cash Periods 0/25 --
Avg Stocks 23.5 --

The headline numbers are strong. The down capture is the standout: +1.6%. The portfolio was roughly flat, on average, when the S&P 500 fell. Combined with 107% up capture, the strategy captured more than full upside while avoiding nearly all of the downside.

Zero cash periods across 25 years means the US market always had at least 10 qualifying high-yield stocks. The signal is well-calibrated for this market.

Cumulative growth of high dividend yield quality screen vs S&P 500
Cumulative growth of high dividend yield quality screen vs S&P 500

Annual Returns

Year Strategy S&P 500 Excess
2000 +22.7% -14.8% +37.5%
2001 +10.0% -22.4% +32.4%
2002 +10.9% +6.9% +4.0%
2003 +29.2% +14.9% +14.3%
2004 +35.6% +8.9% +26.7%
2005 +23.8% +8.0% +15.8%
2006 +35.1% +20.9% +14.2%
2007 +3.1% -15.2% +18.3%
2008 -26.4% -26.9% +0.5%
2009 +25.1% +16.0% +9.1%
2010 +31.2% +33.5% -2.3%
2011 +0.5% +4.2% -3.7%
2012 +14.2% +20.7% -6.5%
2013 +19.9% +24.7% -4.9%
2014 -1.7% +7.2% -8.9%
2015 +5.8% +2.7% +3.1%
2016 +12.8% +18.6% -5.8%
2017 +2.0% +14.3% -12.3%
2018 +13.3% +11.2% +2.1%
2019 -14.4% +7.4% -21.8%
2020 +51.9% +41.0% +11.0%
2021 -10.9% -10.7% -0.2%
2022 +11.8% +18.1% -6.2%
2023 +13.7% +25.4% -11.7%
2024 +18.4% +14.4% +4.0%

Annual returns comparison
Annual returns comparison


When It Works

2000-2007 (the golden era): The strategy crushed the S&P 500 for eight straight years. During the dot-com bust, it returned +22.7% while SPY dropped -14.8%. High-yield stocks were the anti-tech play. Dividend payers held value while speculative growth imploded. From 2000-2007, cumulative excess return was over 170 percentage points.

2008 (crisis resilience): Even during the financial crisis, the strategy only lost -26.4% vs SPY's -26.9%. Quality filters kept the worst financial stocks out of the portfolio.

2020 (post-COVID bounce): The strategy returned +51.9% as beaten-down dividend payers recovered. Many high-yield stocks had been oversold during 2019 and the COVID crash. The rebound was sharp.

Pattern: the strategy works best coming out of market stress, when cheap, quality dividend payers get repriced upward.


When It Struggles

2010-2014 (growth dominance): Five consecutive years of underperformance. Not losing money, the strategy was still positive 4 of 5 years. But SPY was running harder. Growth stocks led the recovery and momentum-driven markets left dividend payers behind.

2017 (FAANG rally): Only +2.0% vs SPY's +14.3%. The market was driven by a handful of mega-cap tech stocks that don't pay meaningful dividends.

2019 (value drought): The worst single year at -14.4% vs SPY's +7.4%. A 22 percentage point gap. Growth and momentum dominated while dividend stocks lagged badly.

Pattern: the strategy struggles during extended growth rallies when investors chase momentum and ignore yield.


The Simple Screen

Find high-yield stocks passing all quality filters.

SELECT r.symbol, p.companyName, p.sector,
    ROUND(r.dividendYieldTTM * 100, 2) AS yield_pct,
    ROUND(r.dividendPayoutRatioTTM * 100, 1) AS payout_pct,
    ROUND(k.returnOnEquityTTM * 100, 1) AS roe_pct,
    ROUND(r.debtToEquityRatioTTM, 2) AS debt_equity,
    ROUND(k.marketCap / 1e9, 1) AS mktcap_bn
FROM financial_ratios_ttm r
JOIN key_metrics_ttm k ON r.symbol = k.symbol
JOIN profile p ON r.symbol = p.symbol
WHERE r.dividendYieldTTM BETWEEN 0.04 AND 0.15
  AND r.dividendPayoutRatioTTM BETWEEN 0 AND 0.80
  AND k.returnOnEquityTTM > 0.08
  AND (r.debtToEquityRatioTTM < 2.0
       OR r.debtToEquityRatioTTM IS NULL)
  AND k.marketCap > 1000000000
  AND p.exchange IN ('NYSE', 'NASDAQ', 'AMEX')
ORDER BY r.dividendYieldTTM DESC
LIMIT 30

Try this screen →

What this does: - dividendYieldTTM BETWEEN 0.04 AND 0.15 targets 4-15% yield. Below 4% isn't "high yield." Above 15% is almost certainly distressed. - dividendPayoutRatioTTM BETWEEN 0 AND 0.80 ensures the dividend is sustainable. - returnOnEquityTTM > 0.08 filters out businesses that can't earn a decent return. - debtToEquityRatioTTM < 2.0 keeps leverage manageable.


Limitations

Sector concentration: High-yield portfolios naturally overweight REITs, utilities, energy, and financials. These sectors pay higher dividends structurally. You're partly making a sector bet.

Interest rate sensitivity: High-yield stocks often behave like bond proxies. When rates rise, they can underperform as investors rotate into actual bonds. The 2013 "taper tantrum" and 2017-2019 rate cycle both hurt.

Dividend cuts not modeled: The backtest rebalances annually. If a company cuts its dividend mid-year, we don't exit until the next rebalance. In practice, you might want to monitor for cuts.

Survivorship bias: FMP data includes many delisted companies, but coverage of delistings is less complete than active companies. Some failed high-yield stocks may be missing from the dataset.

Point-in-time data: We use a 45-day filing lag assumption for annual data. The July rebalance date aligns with most companies having filed their annual reports, but exact availability varies.


Takeaway

High dividend yield investing works when you filter for quality. The raw signal (just buy high yield) is dangerous. Yield traps destroy returns. But adding ROE, FCF, payout, and debt filters transforms the strategy.

The US results are strong: +4.40% annual alpha, 0.598 Sharpe, and near-zero down capture (+1.6%). The strategy captured more than full upside while staying roughly flat during downturns.

The tradeoff is extended periods of underperformance during growth-driven markets. The 2010-2014 stretch tested patience. The 2017-2019 period was worse. You need conviction to hold through those stretches.

If you can handle the tracking error, this is one of the simpler factor strategies to implement and maintain.


A note on data sources: The screens above use TTM (trailing twelve months) tables, which reflect current snapshots. The backtest numbers use historical tables (financial_ratios, key_metrics, cash_flow_statement) with point-in-time methodology, only using data available at the time of each simulated trade. These are different data sources: TTM for live screening, historical for backtesting.


Data: Ceta Research (FMP financial data warehouse). Universe: NYSE + NASDAQ + AMEX, market cap > $1B. Backtest: 2000-2025, annual July rebalance, next-day close execution (MOC), equal weight top 30 by yield. Transaction costs: size-tiered (0.1-0.5% one-way). Quality filters: dividend yield 4-15%, payout 0-80%, FCF > 0, ROE > 8%, D/E < 2.0. Past performance does not guarantee future results. This is educational content, not investment advice.


Part of a Series

This is the US analysis. We also ran the same screen on global exchanges: - High Yield Quality on Indian Stocks (NSE) - 5.92% CAGR, NSE-only run (60% cash periods) - High Yield Quality on German Stocks (XETRA) - 10.00% CAGR, +4.96% excess vs DAX - High Yield Quality on Hong Kong Stocks (HKSE) - 7.93% CAGR, +6.29% excess vs Hang Seng - High Yield Quality on Canadian Stocks (TSX) - 6.78% CAGR, +2.83% excess vs TSX Composite - High Yield Quality on UK Stocks (LSE) - 5.67% CAGR, +4.45% excess vs FTSE 100 - High Yield Quality Across Global Exchanges - full comparison


Run This Screen Yourself

Via web UI: Run the High Yield Quality screen on Ceta Research. The query is pre-loaded. Hit "Run" and see what passes today.

Via Python:

import requests, os

API_KEY = os.environ["CR_API_KEY"]
BASE = "https://api.cetaresearch.com/api/v1"

query = """
SELECT r.symbol, p.companyName, p.sector,
    ROUND(r.dividendYieldTTM * 100, 2) AS yield_pct,
    ROUND(r.dividendPayoutRatioTTM * 100, 1) AS payout_pct,
    ROUND(k.returnOnEquityTTM * 100, 1) AS roe_pct,
    ROUND(r.debtToEquityRatioTTM, 2) AS debt_equity,
    ROUND(k.marketCap / 1e9, 1) AS mktcap_bn
FROM financial_ratios_ttm r
JOIN key_metrics_ttm k ON r.symbol = k.symbol
JOIN profile p ON r.symbol = p.symbol
WHERE r.dividendYieldTTM BETWEEN 0.04 AND 0.15
  AND r.dividendPayoutRatioTTM BETWEEN 0 AND 0.80
  AND k.returnOnEquityTTM > 0.08
  AND (r.debtToEquityRatioTTM < 2.0
       OR r.debtToEquityRatioTTM IS NULL)
  AND k.marketCap > 1000000000
  AND p.exchange IN ('NYSE', 'NASDAQ', 'AMEX')
ORDER BY r.dividendYieldTTM DESC
LIMIT 30
"""

resp = requests.post(f"{BASE}/data-explorer/execute",
    headers={"X-API-Key": API_KEY, "Content-Type": "application/json"},
    json={"query": query, "options": {"format": "json", "timeout": 600}})
task_id = resp.json()["taskId"]

import time
while True:
    status = requests.get(f"{BASE}/tasks/data-query/{task_id}",
        headers={"X-API-Key": API_KEY}).json()
    if status["status"] in ("completed", "failed"):
        break
    time.sleep(2)

results = requests.get(f"{BASE}{status['resultUrl']}",
    headers={"X-API-Key": API_KEY}).json()
for r in results[:10]:
    print(f"{r['symbol']:8s} Yield={r['yield_pct']:.1f}% ROE={r['roe_pct']:.1f}% D/E={r['debt_equity']:.2f}")

Get your API key at cetaresearch.com.

The full backtest code (Python + DuckDB) is available in our GitHub repository.


References

  • Fama, E. & French, K. (1998). "Value versus Growth: The International Evidence." Journal of Finance, 53(6), 1975-1999.
  • Arnott, R. et al. (2005). "Fundamental Indexation." Financial Analysts Journal, 61(2), 83-99.