Sector Mean Reversion on German Stocks (XETRA): 4.82% CAGR, -3.20% vs S&P 500

Sector mean reversion on XETRA large caps from 2000 to 2025: 4.82% CAGR vs 8.02% S&P 500. The strategy fires consistently (101 of 104 quarters) but underperforms by -3.20% annually. Consumer Defensive and Utilities dominate selection. Export-led sector structure explains the failure.

Growth of €10,000 in Sector Mean Reversion Germany (XETRA) vs S&P 500 from 2000 to 2025

We tested sector mean reversion on XETRA large caps from 2000 to 2025. The strategy ran cleanly: 101 of 104 quarters invested, an average of 79 stocks per period, and the signal firing almost every quarter without interruption. The result was 4.82% annualized in EUR against the S&P 500's 8.02%. A -3.20% annual gap over 26 years.

Contents

  1. Method
  2. What is Sector Mean Reversion?
  3. The Screen
  4. What We Found
  5. 26 years. -3.20% annual gap vs the S&P 500.
  6. Year-by-year returns
  7. 2000: One year where Germany helped
  8. 2002: The deepest year
  9. 2005: The best year
  10. 2008-2009: Crisis and uneven recovery
  11. 2013-2024: Persistent underperformance
  12. Backtest Methodology
  13. Limitations
  14. Takeaway
  15. Part of a Series
  16. References
  17. Run This Screen Yourself

Germany is one of the clearest failures in our 14-exchange study. Not because the strategy broke down mechanically, but because the sectors it kept selecting don't mean-revert in Germany the way they do elsewhere. Consumer Defensive showed up in 33% of quarters. The strategy kept finding "cheap" defensives that simply stayed cheap.


Method

Data source: Ceta Research (FMP financial data warehouse) Universe: XETRA (Frankfurt Stock Exchange), market cap > €500M Period: 2000-2025 (26 years, 104 quarterly periods) Rebalancing: Quarterly (January, April, July, October), equal weight all qualifying stocks in selected sectors Benchmark: S&P 500 Total Return (SPY) Cash rule: Hold cash if fewer than 5 stocks qualify across the bottom 2 sectors


What is Sector Mean Reversion?

The idea is straightforward. At each quarterly rebalance, rank all sectors by their equal-weighted 12-month trailing return. Buy every stock in the bottom 2. Re-rank and rotate each quarter.

The academic foundation is Moskowitz and Grinblatt (1999), who showed that much of the momentum anomaly operates at the industry level. The corollary: when industry-level momentum turns negative enough, mean reversion tends to follow. Sectors that underperform for a full year carry suppressed valuations and depressed sentiment. Both tend to normalize.

On US stocks, this works reliably. Beaten-down sectors recover as the dislocations that caused the underperformance resolve. The key word is "dislocation." The theory depends on the underperformance being cyclical, not structural.

Germany breaks that assumption. XETRA's largest sectors are export-led manufacturers: Volkswagen, BASF, Siemens, Deutsche Bank, Munich Re. When these sectors fall, it's rarely a sentiment dislocation. It's China slowing down. It's an energy crisis. It's a collapse in global trade. These are structural headwinds that the strategy can't distinguish from temporary weakness. The signal fires. The sector doesn't recover. The next quarter, it fires again.

The sectors that show up most often in XETRA's bottom two:

Sector Quarters Selected (of 101 invested)
Consumer Defensive 33 (33%)
Utilities 31 (31%)
Energy 27 (27%)
Basic Materials 23 (23%)
Real Estate 22 (22%)
Technology 18 (18%)

Consumer Defensive at 33% is striking. In the US, Consumer Defensive rarely falls hard enough to hit the bottom two. In Germany, it does, repeatedly, and then stays there. That's a symptom of a broader problem: XETRA's defensive sectors have had persistent structural headwinds (margin pressure, weak domestic demand, Euro-driven competitiveness constraints) that the mean reversion signal mistakes for temporary underperformance.


The Screen

The screen below runs live. It ranks sectors by their current 12-month equal-weighted return across XETRA large caps. The bottom rows are what the backtest would buy today.

WITH prices AS (
    SELECT e.symbol, e.adjClose, CAST(e.date AS DATE) AS trade_date
    FROM stock_eod e
    JOIN profile p ON e.symbol = p.symbol
    WHERE p.sector IS NOT NULL AND p.sector != ''
      AND p.marketCap > 500000000
      AND p.exchange IN ('XETRA')
      AND CAST(e.date AS DATE) >= CURRENT_DATE - INTERVAL '400' DAY
      AND e.adjClose IS NOT NULL AND e.adjClose > 0
),
recent AS (
    SELECT symbol, adjClose AS recent_price
    FROM prices
    QUALIFY ROW_NUMBER() OVER (PARTITION BY symbol ORDER BY trade_date DESC) = 1
),
year_ago AS (
    SELECT symbol, adjClose AS old_price
    FROM prices
    WHERE trade_date <= CURRENT_DATE - INTERVAL '252' DAY
    QUALIFY ROW_NUMBER() OVER (PARTITION BY symbol ORDER BY trade_date DESC) = 1
),
stock_returns AS (
    SELECT r.symbol, pr.sector, (r.recent_price / ya.old_price - 1) * 100 AS return_12m
    FROM recent r
    JOIN year_ago ya ON r.symbol = ya.symbol
    JOIN profile pr ON r.symbol = pr.symbol
    WHERE ya.old_price > 0 AND r.recent_price > 0
      AND (r.recent_price / ya.old_price - 1) BETWEEN -0.99 AND 5.0
)
SELECT pr.sector,
    ROUND(AVG(sr.return_12m), 2) AS avg_return_12m_pct,
    COUNT(DISTINCT sr.symbol) AS n_stocks,
    ROW_NUMBER() OVER (ORDER BY AVG(sr.return_12m) ASC) AS rank_worst
FROM stock_returns sr
JOIN profile pr ON sr.symbol = pr.symbol
GROUP BY pr.sector
HAVING COUNT(DISTINCT sr.symbol) >= 5
ORDER BY avg_return_12m_pct ASC

What We Found

Germany's sector rotation ran without interruption. 101 of 104 quarters invested. Consistent signal. Consistent underperformance.

Growth of €10,000 in Sector Mean Reversion Germany (XETRA) vs S&P 500 from 2000 to 2025
Growth of €10,000 in Sector Mean Reversion Germany (XETRA) vs S&P 500 from 2000 to 2025

26 years. -3.20% annual gap vs the S&P 500.

Metric Strategy S&P 500
CAGR 4.82% 8.02%
Excess vs SPY -3.20%
Volatility 21.27% 16.9%
Max Drawdown -61.8% -45.5%
Sharpe Ratio 0.133 0.357
Sortino Ratio 0.189
Calmar Ratio 0.078
Up Capture 89.73%
Down Capture 102.11%
Win Rate vs SPY 42.31%
Avg Stocks per Period 79.3
Cash Periods 3 of 104

A few numbers sit badly together. Down capture of 102.11% means the strategy absorbs slightly more downside than SPY despite lower volatility (21.27% vs 16.9%). That combination, absorbing extra downside while generating less upside (89.73% up capture), is how you end up with a Sharpe of 0.133 vs 0.357 for SPY. The Calmar ratio of 0.078 is the worst in the study. You're earning 4.82% in exchange for a -61.8% max drawdown potential. The math doesn't work in your favor.

The win rate of 42.31% means the strategy beats SPY in fewer than half of individual years. Sustained underperformance, not just a few bad years.

Year-by-year returns

XETRA sector mean reversion vs S&P 500 annual returns, 2000-2025
XETRA sector mean reversion vs S&P 500 annual returns, 2000-2025

Year Strategy S&P 500 Excess
2000 +7.10% -10.50% +17.60%
2001 -11.19% -9.17% -2.02%
2002 -45.64% -19.92% -25.72%
2003 +19.66% +24.12% -4.46%
2004 +9.74% +10.24% -0.50%
2005 +37.43% +7.17% +30.26%
2006 +22.47% +13.65% +8.82%
2007 +10.97% +4.40% +6.57%
2008 -39.71% -34.31% -5.40%
2009 +36.90% +24.73% +12.17%
2010 +7.15% +14.31% -7.16%
2011 -8.35% +2.46% -10.81%
2012 +9.69% +17.09% -7.40%
2013 +12.25% +27.77% -15.52%
2014 +12.37% +14.50% -2.13%
2015 +5.68% -0.12% +5.80%
2016 +20.91% +14.45% +6.46%
2017 +8.30% +21.64% -13.34%
2018 -13.55% -5.15% -8.40%
2019 +26.89% +32.31% -5.42%
2020 +17.61% +15.64% +1.97%
2021 +21.89% +31.26% -9.37%
2022 -17.70% -18.99% +1.29%
2023 +10.86% +26.00% -15.14%
2024 +9.41% +25.28% -15.87%
2025 +10.12% +17.88% -7.76%

2000: One year where Germany helped

The strategy's best early moment came from circumstance. In 2000, XETRA returned +7.10% while SPY fell -10.50%. The dot-com crash burned heavily tech-weighted US markets. XETRA's industrial and financial structure meant less direct exposure to US tech valuations, and the beaten-down sectors the strategy selected held up better.

The +17.60% excess was real, but it wasn't a signal that Germany would systematically outperform. It was a one-year rotation pattern that happened to work.

2002: The deepest year

2002 was -45.64% vs SPY's -19.92%. The -25.72% gap is the worst single-year miss in the record. The tech bubble's unwind hit XETRA hard. German industrial and financial stocks that had been caught up in the late-1990s expansion cycle collapsed as global demand evaporated. The strategy bought beaten-down sectors throughout 2001 and into 2002, and those sectors kept falling.

The 2003 partial recovery (+19.66%) still trailed SPY (+24.12%). Germany didn't catch the post-crash bounce as cleanly as the US did.

2005: The best year

2005 was +37.43% vs SPY's +7.17%, a +30.26% excess. German industrial stocks had been cheap after years of underperformance, and global demand came back. XETRA's manufacturing base, which had been a drag in prior years, led the recovery as export demand accelerated and German companies repriced off multi-year lows.

This is the strategy working correctly: structural cheapness meeting a genuine recovery in the underlying drivers. 2005 and 2006 (+22.47%) were the strongest two-year stretch in the record.

2008-2009: Crisis and uneven recovery

2008 was -39.71% vs SPY -34.31%. The financial crisis hit German banks and industrials hard. Deutsche Bank, Allianz, and the large manufacturers sold off as global trade contracted.

The 2009 recovery was strong in absolute terms (+36.90%) and beat SPY by +12.17%. But the crisis had been deep enough that the two-year sequence still left a cumulative hole.

2013-2024: Persistent underperformance

The more damaging part of the record is quiet. It's not one catastrophic year. It's a decade of consistent trailing.

From 2013 to 2024, Germany underperformed SPY in 7 of 10 full years. The misses compound: -15.52% in 2013, -13.34% in 2017, -9.37% in 2021, -15.14% in 2023, -15.87% in 2024. In each of those years, the strategy was holding a portfolio of cheap German stocks in lagging sectors, and US markets were running on tech-driven multiple expansion that XETRA simply doesn't have.

That structural divergence, XETRA's weight in old-economy sectors vs the US market's shift toward software and platform companies, is what mean reversion can't fix. You can't buy XETRA's Consumer Defensive sector and expect it to catch a Nasdaq bull run. The sectors don't correlate.


Backtest Methodology

Parameter Choice
Universe XETRA (Frankfurt), market cap > €500M
Signal Bottom 2 sectors by equal-weighted 12-month trailing return
Portfolio All qualifying stocks in selected sectors, equal weight
Rebalancing Quarterly (January, April, July, October)
Cash rule Hold cash if < 5 stocks qualify
Benchmark S&P 500 Total Return (SPY)
Period 2000-2025 (26 years, 104 quarters)
Data Ceta Research (FMP financial data warehouse)

Limitations

Structural vs cyclical weakness. The core assumption of sector mean reversion is that underperformance is temporary. XETRA's most-selected sectors, Consumer Defensive, Utilities, and Energy, have faced persistent structural pressures over the study period: Euro-currency competitiveness constraints, Germany's energy transition costs, and a domestic economy structurally slower than the US post-2010. The strategy can't distinguish a cheap sector from a broken one.

EUR returns vs USD benchmark. All XETRA returns are in EUR. SPY is in USD. EUR/USD moves affect the comparison. The euro weakened notably against the dollar in 2014-2015 and again in 2022. Currency effects amplify the underperformance in certain years.

Down capture above 100%. A down capture of 102.11% means the strategy falls slightly harder than the market on average. The combination of sub-market up capture (89.73%) and above-market down capture defines why the Sharpe ratio is so low (0.133).

Calmar of 0.078. The worst in this study. You're taking on a -61.8% max drawdown to earn 4.82% annualized. That's not a viable risk budget for most investors.

No transaction costs. The backtest doesn't include costs. With 79 stocks on average and quarterly rebalancing, real-world execution would reduce already thin returns further.

Survivorship bias. Exchange membership uses current profiles, not historical. Delisted companies aren't tracked over time.


Takeaway

Germany's sector mean reversion doesn't fail because the strategy is wrong. It fails because XETRA's market structure isn't built for it.

The strategy ran cleanly. 101 of 104 quarters invested, 79 stocks on average, clear signal throughout. What it kept buying were sectors that, in Germany specifically, don't mean-revert reliably. Consumer Defensive in 33% of quarters. Utilities in 31%. These aren't sentiment dislocations. They're sectors facing structural headwinds that a 12-month trailing return signal will keep identifying as cheap.

The result is 4.82% CAGR in EUR over 26 years, a -3.20% annual gap against the S&P 500, and the worst Calmar ratio in the 14-exchange study. If you want exposure to German large caps, a passive XETRA index would have served better than this rotation approach over this period.

The one period where Germany shone was 2005-2007, when the global industrial cycle turned in its favor. That's when mean reversion on XETRA actually worked, because the underperformance had been sentiment-driven and the structural tailwinds were real. Those conditions aren't the norm. They were the exception.


Part of a Series

This analysis is part of our Sector Mean Reversion global exchange comparison. We tested the same strategy across multiple exchanges:


References

  • Moskowitz, T. & Grinblatt, M. (1999). "Do Industries Explain Momentum?" Journal of Finance, 54(4), 1249-1290.

Run This Screen Yourself

Via Python:

import requests, time

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

query = """
WITH prices AS (
    SELECT e.symbol, e.adjClose, CAST(e.date AS DATE) AS trade_date
    FROM stock_eod e
    JOIN profile p ON e.symbol = p.symbol
    WHERE p.sector IS NOT NULL AND p.sector != ''
      AND p.marketCap > 500000000
      AND p.exchange IN ('XETRA')
      AND CAST(e.date AS DATE) >= CURRENT_DATE - INTERVAL '400' DAY
      AND e.adjClose IS NOT NULL AND e.adjClose > 0
),
recent AS (
    SELECT symbol, adjClose AS recent_price
    FROM prices
    QUALIFY ROW_NUMBER() OVER (PARTITION BY symbol ORDER BY trade_date DESC) = 1
),
year_ago AS (
    SELECT symbol, adjClose AS old_price
    FROM prices
    WHERE trade_date <= CURRENT_DATE - INTERVAL '252' DAY
    QUALIFY ROW_NUMBER() OVER (PARTITION BY symbol ORDER BY trade_date DESC) = 1
),
stock_returns AS (
    SELECT r.symbol, pr.sector,
        (r.recent_price / ya.old_price - 1) * 100 AS return_12m
    FROM recent r
    JOIN year_ago ya ON r.symbol = ya.symbol
    JOIN profile pr ON r.symbol = pr.symbol
    WHERE ya.old_price > 0 AND r.recent_price > 0
      AND (r.recent_price / ya.old_price - 1) BETWEEN -0.99 AND 5.0
)
SELECT pr.sector,
    ROUND(AVG(sr.return_12m), 2) AS avg_return_12m_pct,
    COUNT(DISTINCT sr.symbol) AS n_stocks,
    ROW_NUMBER() OVER (ORDER BY AVG(sr.return_12m) ASC) AS rank_worst
FROM stock_returns sr
JOIN profile pr ON sr.symbol = pr.symbol
GROUP BY pr.sector
HAVING COUNT(DISTINCT sr.symbol) >= 5
ORDER BY avg_return_12m_pct ASC
"""

resp = requests.post(f"{BASE}/data-explorer/execute", headers={
    "X-API-Key": API_KEY, "Content-Type": "application/json"
}, json={
    "query": query,
    "options": {"format": "json", "limit": 100},
    "resources": {"memoryMb": 16384, "threads": 6}
})
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)

print("Sector rankings (worst to best, 12-month return):")
for r in result["result"]["rows"]:
    flag = " <-- BUY" if r["rank_worst"] <= 2 else ""
    print(f"#{r['rank_worst']} {r['sector']:30s} {r['avg_return_12m_pct']:+.1f}%  ({r['n_stocks']} stocks){flag}")

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


Data: Ceta Research, FMP financial data warehouse. Universe: XETRA (Frankfurt Stock Exchange), market cap > €500M. Returns in EUR. Quarterly rebalance, equal weight, 2000-2025. Benchmark: SPY (USD). Past performance does not guarantee future results.