Owner Earnings Yield on Swedish Stocks: 9.6% CAGR, +7.0% Over OMX Stockholm 30

Growth of $10,000 invested in Owner Earnings Yield on Swedish stocks vs OMX Stockholm 30 from 2000 to 2025.

We ran the same Owner Earnings Yield screen on Sweden's Stockholm exchange (STO) from 2000 to 2025. The strategy returned 9.59% annually vs 2.55% for the OMX Stockholm 30. That's +7.03% annual excess over the local benchmark. The win rate is 80%, the best of any exchange we tested. Sweden's deep industrial base produces exactly the kind of stocks this screen loves: capital-intensive businesses with high depreciation, moderate maintenance capex, and strong margins. The OMX30's max drawdown was -60.54%, far worse than the strategy's -40.56%.

Contents

  1. Method
  2. The Screen (SQL)
  3. What We Found
  4. 9.59% CAGR. 80% win rate. +7.0% annual excess over OMX30.
  5. Year-by-year returns
  6. The early years: cash was the right call
  7. 2007 was rough. 2008 recovered.
  8. 2018: the standout year
  9. 2020: both sides won
  10. Why Sweden fits this screen
  11. Backtest Methodology
  12. Limitations
  13. Takeaway
  14. Part of a Series
  15. References
  16. Run This Screen Yourself

For methodology and a full explanation of Owner Earnings, see the US flagship post.


Method

Parameter Value
Universe Stockholm (STO), market cap > 5B SEK (~$460M USD)
Signal OE Yield 5-50%, ROE > 10%, OPM > 10%
Portfolio Top 30 by OE Yield, equal weight
Rebalancing Annual (July)
Execution Next-day close (market-on-close after signal date)
Cash rule Hold cash if fewer than 10 qualify
Benchmark OMX Stockholm 30 (^OMXS30)
Period 2000-2025 (25 annual periods)
Data Point-in-time (45-day lag for FY filings)
Transaction costs Size-tiered (0.1-0.5% one-way by market cap)
Returns SEK (local currency, matching benchmark)

The Screen (SQL)

WITH income_latest AS (
    SELECT symbol, netIncome, depreciationAndAmortization,
        ROW_NUMBER() OVER (PARTITION BY symbol ORDER BY date DESC) AS rn
    FROM income_statement
    WHERE period = 'FY'
      AND netIncome IS NOT NULL
      AND depreciationAndAmortization IS NOT NULL
),
cashflow_latest AS (
    SELECT symbol, capitalExpenditure,
        ROW_NUMBER() OVER (PARTITION BY symbol ORDER BY date DESC) AS rn
    FROM cash_flow_statement
    WHERE period = 'FY'
      AND capitalExpenditure IS NOT NULL
),
calculated AS (
    SELECT
        i.symbol,
        i.netIncome + i.depreciationAndAmortization
            - LEAST(ABS(c.capitalExpenditure), i.depreciationAndAmortization)
            AS owner_earnings
    FROM income_latest i
    JOIN cashflow_latest c ON i.symbol = c.symbol AND c.rn = 1
    WHERE i.rn = 1
)
SELECT
    calc.symbol,
    p.companyName,
    ROUND(calc.owner_earnings / k.marketCap * 100, 2) AS oe_yield_pct,
    ROUND(k.freeCashFlowYieldTTM * 100, 2) AS fcf_yield_pct,
    ROUND(k.returnOnEquityTTM * 100, 1) AS roe_pct,
    ROUND(f.operatingProfitMarginTTM * 100, 1) AS op_margin_pct,
    ROUND(k.marketCap / 1e9, 1) AS market_cap_billions
FROM calculated calc
JOIN key_metrics_ttm k ON calc.symbol = k.symbol
JOIN financial_ratios_ttm f ON calc.symbol = f.symbol
JOIN profile p ON calc.symbol = p.symbol
WHERE calc.owner_earnings > 0
  AND calc.owner_earnings / k.marketCap > 0.05
  AND calc.owner_earnings / k.marketCap < 0.50
  AND k.returnOnEquityTTM > 0.10
  AND f.operatingProfitMarginTTM > 0.10
  AND k.marketCap > 5e9
  AND p.exchange IN ('STO')
ORDER BY calc.owner_earnings / k.marketCap DESC
LIMIT 30

Run this query on Ceta Research


What We Found

Growth of $10,000 invested in Owner Earnings Yield on Swedish stocks vs OMX Stockholm 30 from 2000 to 2025.
Growth of $10,000 invested in Owner Earnings Yield on Swedish stocks vs OMX Stockholm 30 from 2000 to 2025.

9.59% CAGR. 80% win rate. +7.0% annual excess over OMX30.

Metric OE Yield (STO) OMX Stockholm 30
CAGR 9.59% 2.55%
Max Drawdown -40.56% -60.54%
Sharpe Ratio 0.390 0.027
Sortino Ratio 0.799 0.040
Win Rate (annual) 80% -
Alpha 7.18% -
Beta 0.739 -
Up Capture 124.3% -
Down Capture 39.6% -
Cash Periods 4 of 25 -
Avg Stocks per Period 26.0 -

The OMX30 returned just 2.55% annually over 25 years, with a brutal -60.54% max drawdown. OE Yield's 0.390 Sharpe dwarfs the index's 0.027. The Sortino ratio of 0.799 confirms the strategy generates returns without proportionally increasing downside risk.

The capture ratios tell the rest of the story. Up capture of 124% means the portfolio rides $1.24 for every dollar the benchmark gains. Down capture of 40% means it absorbs less than half the losses. That asymmetry compounds over 25 years. The 80% win rate is the highest of any exchange we tested.

Year-by-year returns

OE Yield (Sweden) vs OMX Stockholm 30 annual returns from 2000 to 2024.
OE Yield (Sweden) vs OMX Stockholm 30 annual returns from 2000 to 2024.

Year OE Yield (STO) OMX30 Excess
2000 0.0% (cash) -33.2% +33.2%
2001 0.0% (cash) -33.5% +33.5%
2002 0.0% (cash) -11.1% +11.1%
2003 +18.9% +31.3% -12.5%
2004 0.0% (cash) +19.6% -19.6%
2005 +21.4% +15.5% +5.9%
2006 +36.2% +30.5% +5.7%
2007 -32.1% -32.3% +0.2%
2008 -12.5% -6.7% -5.7%
2009 +34.9% +24.1% +10.8%
2010 +23.6% +14.5% +9.1%
2011 -7.5% -9.0% +1.5%
2012 +19.7% +13.3% +6.4%
2013 +38.1% +19.5% +18.6%
2014 +16.3% +12.5% +3.7%
2015 +3.2% -15.1% +18.3%
2016 +25.1% +22.8% +2.4%
2017 -3.2% -5.3% +2.2%
2018 +33.3% +6.9% +26.4%
2019 +9.8% +3.4% +6.4%
2020 +41.5% +34.3% +7.2%
2021 -25.3% -17.3% -8.1%
2022 +3.9% +21.2% -17.3%
2023 +26.4% +11.3% +15.0%
2024 +12.2% -1.2% +13.5%

The early years: cash was the right call

The strategy sat in cash from 2000 through 2002, and again in 2004. Sweden's mid-cap universe was smaller back then. Fewer than 10 stocks passed all the filters. That matters, because 2000-2002 were devastating for the OMX30: -33.2%, -33.5%, and -11.1% in consecutive years. Sitting in cash while the index lost more than half its value gave the portfolio a head start that it never gave back.

By 2003 the universe had expanded enough to fill the portfolio. The strategy entered the market just in time for the bull run: +18.9% in 2003, +21.4% in 2005, +36.2% in 2006.

2007 was rough. 2008 recovered.

The worst single year was 2007: -32.1%, roughly matching the OMX30's -32.3%. Swedish industrial stocks got hit hard during the early stages of the global financial crisis. Many of Sweden's mid-cap industrials have global revenue exposure, and the market repriced them along with everything else.

But 2008 diverged. The OE Yield portfolio lost 12.5% while the OMX30 lost only 6.7%. The screen didn't protect in this particular downturn. Over the two-year period combined, both the strategy and the index took similar total damage, but recovery from 2009 onward was stronger for OE Yield: +34.9% vs the OMX30's +24.1%.

2018: the standout year

The portfolio returned +33.3% while the OMX30 gained just 6.9%. That's +26.4% excess in a single year. This July 2018 to July 2019 period was strong for Swedish industrials and consumer companies with pricing power. While the broader market wobbled through the Q4 2018 sell-off, mid-caps with high owner earnings yields held up and then rallied into mid-2019. The OE Yield screen naturally concentrates in these types of businesses.

2020: both sides won

+41.5% for OE Yield vs +34.3% for OMX30. The strategy outperformed by 7.2 points in a year where everything rallied. Swedish mid-caps with strong fundamentals captured the post-COVID recovery fully, outpacing the large-cap dominated OMX30.

Why Sweden fits this screen

Sweden punches above its weight in capital-intensive industries. Companies like Volvo, Atlas Copco, Sandvik, SKF, and Alfa Laval have high depreciation charges from extensive manufacturing operations, but their maintenance capex is often well below total D&A. That gap between depreciation and maintenance capex is exactly what Owner Earnings captures. These businesses spend on growth, and the OE Yield screen doesn't penalize them for it.

The 5B SEK market cap threshold (~$460M USD) filters out micro-caps while still accessing Sweden's deep bench of industrial mid-caps. The average of 26.0 stocks per period confirms that the Swedish universe is large enough to populate the portfolio consistently once you get past the early 2000s data gap.


Backtest Methodology

Parameter Choice
Universe STO exchange, Market Cap > 5B SEK (~$460M USD)
Signal OE Yield 5-50%, ROE > 10%, OPM > 10%
Portfolio Top 30 by OE Yield, equal weight
Rebalancing Annual (July)
Execution Next-day close (market-on-close after signal date)
Cash rule Hold cash if < 10 qualify
Benchmark OMX Stockholm 30 (^OMXS30)
Period 2000-2025 (25 annual periods)
Data Point-in-time (45-day lag for FY filings)
Transaction costs Size-tiered (0.1-0.5% one-way by market cap)

Full methodology details: backtests/METHODOLOGY.md


Limitations

Four cash periods. The portfolio was empty from 2000 to 2002 and in 2004. Those years are effectively a zero-return placeholder, not a test of the strategy's stock-picking ability. The effective invested period starts in 2003 (with a gap in 2004). The cash years happened to coincide with the OMX30's worst stretch (-33.2%, -33.5%, -11.1%), which flatters the relative performance.

Concentrated portfolio. 26.0 stocks on average. A single bad pick carries meaningful weight in an equal-weight portfolio of this size.

2007 drawdown. -32.1% is the worst single year and -40.56% is the max drawdown. Swedish industrials have global cyclical exposure. In a global recession, this portfolio won't protect you.

Survivorship bias. Current exchange listings are used to define the universe. Delisted companies and M&A targets aren't fully captured in the historical universe.

Small-market depth. The STO universe is smaller than NYSE or BSE. In the early 2000s, it was too small for the strategy to invest at all. If Swedish market listings shrink in the future, the cash rule could activate more often.


Takeaway

OE Yield on Swedish stocks delivers 9.59% CAGR with +7.03% annual excess over the OMX Stockholm 30. The 80% win rate is the highest of any exchange we tested. Down capture of 40% means the portfolio absorbs less than half the benchmark's losses.

Sweden's industrial structure is a natural fit for this screen. High depreciation, moderate maintenance capex, and strong margins are the hallmarks of Swedish manufacturing. The OE Yield formula rewards exactly those characteristics.

The honest caveat: the 2000-2002 cash periods flatter the track record because the OMX30 was collapsing during those years. But even excluding the cash periods, the strategy beat the index in 16 of 21 invested years. A 0.390 Sharpe vs the OMX30's 0.027 isn't close. If you want OE Yield exposure in the Nordics, Sweden is where the data points.


Part of a Series

This analysis is part of our Owner Earnings Yield global exchange comparison. We tested the same screen on 13 exchanges worldwide: - OE Yield on US Stocks (NYSE + NASDAQ + AMEX) - 12.3% CAGR, the flagship analysis - OE Yield on Indian Stocks (BSE + NSE) - 17.2% CAGR, +5.1% vs Sensex - OE Yield on Hong Kong Stocks (HKSE) - 10.4% CAGR, +8.8% vs Hang Seng - OE Yield on Chinese Stocks (SHZ + SHH) - 9.6% CAGR, +7.2% vs SSE Composite - OE Yield: 13-Exchange Global Comparison - full comparison table


References

  • Buffett, W. (1986). "Berkshire Hathaway Annual Letter to Shareholders."
  • Greenwald, B., Kahn, J., Sonkin, P. & van Biema, M. (2001). Value Investing: From Graham to Buffett and Beyond. John Wiley & Sons.
  • Greenblatt, J. (2006). The Little Book That Beats the Market. John Wiley & Sons.

Run This Screen Yourself

Via web UI: Run the Owner Earnings Yield screen on Ceta Research. The query is pre-loaded with the STO exchange filter. Hit "Run" and see what passes today.

Via Python:

import requests, time

API_KEY = "your_api_key"  # get one at cetaresearch.com
BASE = "https://tradingstudio.finance/api/v1"

resp = requests.post(f"{BASE}/data-explorer/execute", headers={
    "X-API-Key": API_KEY, "Content-Type": "application/json"
}, json={
    "query": """
        WITH income_latest AS (
            SELECT symbol, netIncome, depreciationAndAmortization,
                ROW_NUMBER() OVER (PARTITION BY symbol ORDER BY date DESC) AS rn
            FROM income_statement WHERE period = 'FY'
              AND netIncome IS NOT NULL AND depreciationAndAmortization IS NOT NULL
        ),
        cashflow_latest AS (
            SELECT symbol, capitalExpenditure,
                ROW_NUMBER() OVER (PARTITION BY symbol ORDER BY date DESC) AS rn
            FROM cash_flow_statement WHERE period = 'FY' AND capitalExpenditure IS NOT NULL
        ),
        calculated AS (
            SELECT i.symbol,
                i.netIncome + i.depreciationAndAmortization
                    - LEAST(ABS(c.capitalExpenditure), i.depreciationAndAmortization) AS owner_earnings
            FROM income_latest i JOIN cashflow_latest c ON i.symbol = c.symbol AND c.rn = 1
            WHERE i.rn = 1
        )
        SELECT calc.symbol, p.companyName,
            ROUND(calc.owner_earnings / k.marketCap * 100, 2) AS oe_yield_pct,
            ROUND(k.returnOnEquityTTM * 100, 1) AS roe_pct,
            ROUND(f.operatingProfitMarginTTM * 100, 1) AS op_margin_pct,
            ROUND(k.marketCap / 1e9, 1) AS market_cap_billions
        FROM calculated calc
        JOIN key_metrics_ttm k ON calc.symbol = k.symbol
        JOIN financial_ratios_ttm f ON calc.symbol = f.symbol
        JOIN profile p ON calc.symbol = p.symbol
        WHERE calc.owner_earnings > 0
          AND calc.owner_earnings / k.marketCap > 0.05
          AND calc.owner_earnings / k.marketCap < 0.50
          AND k.returnOnEquityTTM > 0.10
          AND f.operatingProfitMarginTTM > 0.10
          AND k.marketCap > 5e9
          AND p.exchange IN ('STO')
        ORDER BY calc.owner_earnings / k.marketCap DESC
        LIMIT 30
    """,
    "options": {"format": "json", "limit": 100}
})
task_id = resp.json()["taskId"]

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

for r in result["result"]["rows"][:10]:
    print(f"{r['symbol']:8s} OE Yield={r['oe_yield_pct']}% ROE={r['roe_pct']}% MCap={r['market_cap_billions']}B SEK")

Get your API key at cetaresearch.com. The full backtest code (Python + DuckDB) is on GitHub.


Data: Ceta Research, FMP financial data warehouse. Universe: STO exchange, market cap > 5B SEK. Benchmark: OMX Stockholm 30. Annual rebalance (July), equal weight top 30, 2000-2025. Next-day close execution. Returns in SEK. Transaction costs included.

Read more