Dividend Sustainability on Chinese Stocks: 6.66% CAGR, +4.23% Over SSE Composite
A 5-factor dividend sustainability score backtested on Shanghai and Shenzhen from 2000-2025. 6.66% CAGR, +4.23% annual excess over SSE Composite, 76% win rate vs local benchmark. High volatility (31.66%) is the main cost.
China's stock market doesn't do anything quietly. From +131.1% in 2006 to -32.0% in 2008, the swings are massive. The question we wanted to answer: can a disciplined, multi-factor dividend screen tame that volatility and extract steady returns?
Contents
- Method
- The Screen (SQL)
- What We Found
- Zero cash years. +4.23% annual excess over SSE Composite. 76% win rate vs local benchmark.
- Year-by-year returns
- 2006: the outlier that defines the backtest
- 2008-2011: the sustainability score can't fix China's structural issues
- 2014-2015: another boom, another lesson
- 2018-2023: persistent drag
- Backtest Methodology
- Limitations
- Takeaway
- Part of a Series
- References
- Run This Screen Yourself
The answer, when benchmarked against the local market, is yes.
We ran our 5-component sustainability score on Shanghai (SHH) and Shenzhen (SHZ) stocks from 2000 to 2025. The result: 6.66% CAGR and 31.66% annualized volatility. When benchmarked against the SSE Composite Index (which returned just 2.43% CAGR over the period), the strategy beats the local market by 4.23% per year with a 76% win rate. The Sharpe ratio of 0.131 is still the lowest in our comparison, reflecting the volatility. But zero cash years and consistently outperforming the local benchmark is a different story than the old SPY-benchmarked reports told.
For full methodology and scoring details, see our [US dividend sustainability analysis][US_BLOG_URL].
Data: FMP financial data warehouse, 2000–2025. Updated March 2026.
Method
Data source: Ceta Research (FMP financial data warehouse) Universe: SHH + SHZ, market cap > 2B CNY (~$276M USD) Period: 2000-2025 (25 years, 25 annual periods) Rebalancing: Annual (July), equal weight top 30 by sustainability score descending (yield tiebreak) Benchmark: SSE Composite Index (Shanghai Composite, CNY) Execution: Next-day close (market-on-close after signal) Cash rule: Hold cash if fewer than 10 stocks qualify Transaction costs: Size-tiered model (0.1-0.5% one-way based on market cap)
The sustainability score combines five components (0-2 points each, total 0-10): Payout Ratio, Debt/Equity, FCF Coverage, ROE, and Piotroski F-Score. Minimum score of 7 with yield above 2%. Full scoring methodology is in the [US blog][US_BLOG_URL].
The Screen (SQL)
WITH latest_ratios AS (
SELECT r.symbol, r.dividendPayoutRatio, r.debtToEquityRatio,
r.dividendYield, r.date,
ROW_NUMBER() OVER (PARTITION BY r.symbol ORDER BY r.date DESC) AS rn
FROM financial_ratios r
JOIN profile p ON r.symbol = p.symbol
WHERE r.period = 'FY'
AND r.dividendPayoutRatio > 0
AND r.dividendYield IS NOT NULL
AND p.exchange IN ('SHZ', 'SHH')
),
latest_cf AS (
SELECT c.symbol, c.freeCashFlow, c.commonDividendsPaid, c.date,
ROW_NUMBER() OVER (PARTITION BY c.symbol ORDER BY c.date DESC) AS rn
FROM cash_flow_statement c
JOIN profile p ON c.symbol = p.symbol
WHERE c.period = 'FY'
AND c.commonDividendsPaid < 0
AND p.exchange IN ('SHZ', 'SHH')
),
latest_metrics AS (
SELECT k.symbol, k.returnOnEquity, k.marketCap, k.date,
ROW_NUMBER() OVER (PARTITION BY k.symbol ORDER BY k.date DESC) AS rn
FROM key_metrics k
JOIN profile p ON k.symbol = p.symbol
WHERE k.period = 'FY'
AND k.marketCap IS NOT NULL
AND p.exchange IN ('SHZ', 'SHH')
),
latest_scores AS (
SELECT symbol, piotroskiScore
FROM scores
),
scored AS (
SELECT r.symbol, r.date,
ROUND(r.dividendPayoutRatio * 100, 1) AS payout_pct,
ROUND(r.debtToEquityRatio, 2) AS debt_equity,
ROUND(c.freeCashFlow / NULLIF(ABS(c.commonDividendsPaid), 0), 2) AS fcf_coverage,
ROUND(k.returnOnEquity * 100, 1) AS roe_pct,
s.piotroskiScore AS piotroski,
ROUND(r.dividendYield * 100, 2) AS yield_pct,
ROUND(k.marketCap / 1e9, 1) AS mktcap_bn,
CASE WHEN r.dividendPayoutRatio < 0.5 THEN 2
WHEN r.dividendPayoutRatio < 0.8 THEN 1 ELSE 0 END AS c_payout,
CASE WHEN r.debtToEquityRatio >= 0 AND r.debtToEquityRatio < 0.5 THEN 2
WHEN r.debtToEquityRatio >= 0 AND r.debtToEquityRatio < 1.5 THEN 1
ELSE 0 END AS c_debt,
CASE WHEN c.freeCashFlow > 0 AND c.commonDividendsPaid < 0
AND c.freeCashFlow / ABS(c.commonDividendsPaid) > 2 THEN 2
WHEN c.freeCashFlow > 0 AND c.commonDividendsPaid < 0
AND c.freeCashFlow / ABS(c.commonDividendsPaid) > 1 THEN 1
ELSE 0 END AS c_fcf,
CASE WHEN k.returnOnEquity > 0.15 THEN 2
WHEN k.returnOnEquity > 0.08 THEN 1 ELSE 0 END AS c_roe,
CASE WHEN s.piotroskiScore >= 7 THEN 2
WHEN s.piotroskiScore >= 5 THEN 1 ELSE 0 END AS c_piotroski
FROM latest_ratios r
JOIN latest_cf c ON r.symbol = c.symbol AND c.rn = 1
JOIN latest_metrics k ON r.symbol = k.symbol AND k.rn = 1
LEFT JOIN latest_scores s ON r.symbol = s.symbol
WHERE r.rn = 1
AND r.dividendYield > 0.02
AND k.marketCap > 2e9
)
SELECT symbol, date, payout_pct, debt_equity, fcf_coverage, roe_pct, piotroski,
yield_pct, mktcap_bn,
c_payout + c_debt + c_fcf + c_roe + COALESCE(c_piotroski, 0) AS sustainability_score,
c_payout, c_debt, c_fcf, c_roe, COALESCE(c_piotroski, 0) AS c_piotroski
FROM scored
WHERE c_payout + c_debt + c_fcf + c_roe + COALESCE(c_piotroski, 0) >= 7
ORDER BY sustainability_score DESC, yield_pct DESC
LIMIT 30
[Run this query on Ceta Research][SUSTAINABILITY_CHINA_QUERY_URL]
What We Found

Zero cash years. +4.23% annual excess over SSE Composite. 76% win rate vs local benchmark.
| Metric | Sustainability (China) | SSE Composite |
|---|---|---|
| CAGR | 6.66% | 2.43% |
| Volatility | 31.66% | - |
| Max Drawdown | -39.79% | - |
| Sharpe Ratio | 0.131 | - |
| Sortino Ratio | 0.406 | - |
| Win Rate (annual) | 76% | - |
| Down Capture | 48.4% | - |
| Up Capture | 92.4% | - |
| Avg Stocks per Period | 23.4 | - |
| Cash Periods | 0 of 25 | - |
| Avg Sustainability Score | 8.9/10 | - |
The SSE Composite returned just 2.43% CAGR over this 25-year period. Against that benchmark, the sustainability screen's 4.23% annual excess and 76% win rate are a strong result. The strategy beat the local market in 19 of 25 years.
The volatility (31.66%) is still the highest in our comparison. Even with multi-factor quality filtering, Chinese stocks are volatile. But the 76% win rate shows the filter consistently adds value against the local benchmark. Zero cash years means the screen always found at least 10 qualifying stocks. The average sustainability score of 8.9/10 is tied with Hong Kong for the highest in our comparison.
Year-by-year returns

| Year | Sustainability | SSE Composite | Excess |
|---|---|---|---|
| 2000 | -9.1% | -14.8% | +5.7% |
| 2001 | -1.7% | -20.8% | +19.1% |
| 2002 | -13.2% | +3.3% | -16.5% |
| 2003 | +38.7% | +16.4% | +22.3% |
| 2004 | -6.2% | +7.9% | -14.1% |
| 2005 | +3.6% | +8.9% | -5.3% |
| 2006 | +131.1% | +20.9% | +110.2% |
| 2007 | +22.2% | -13.7% | +35.9% |
| 2008 | -32.0% | -26.1% | -5.9% |
| 2009 | +42.1% | +13.4% | +28.7% |
| 2010 | -15.1% | +32.9% | -48.0% |
| 2011 | -12.7% | +4.1% | -16.8% |
| 2012 | +10.1% | +20.9% | -10.8% |
| 2013 | +2.9% | +24.5% | -21.6% |
| 2014 | +36.9% | +7.4% | +29.5% |
| 2015 | +26.2% | +3.4% | +22.8% |
| 2016 | -4.0% | +17.7% | -21.7% |
| 2017 | +16.7% | +14.3% | +2.4% |
| 2018 | -14.9% | +10.9% | -25.8% |
| 2019 | +22.1% | +7.1% | +15.0% |
| 2020 | +13.7% | +40.7% | -27.0% |
| 2021 | -11.9% | -10.2% | -1.7% |
| 2022 | -6.1% | +18.3% | -24.4% |
| 2023 | +3.5% | +24.6% | -21.1% |
| 2024 | +19.1% | +14.7% | +4.4% |
2006: the outlier that defines the backtest
+131.1%. That single year accounts for a huge portion of the strategy's lifetime return. China's pre-Olympics bull run sent everything higher, and sustainable dividend payers with strong fundamentals were at the center of it. Banks, infrastructure companies, and industrials preparing for 2008 Beijing Olympics spending all qualified under the sustainability screen.
Without 2006, the 25-year CAGR drops substantially. This is the fundamental problem with Chinese equity backtests: a small number of extreme years drive the aggregate result.
2008-2011: the sustainability score can't fix China's structural issues
-32.0% in 2008, +42.1% in 2009, -15.1% in 2010, -12.7% in 2011. Massive swings in both directions. The sustainability filter selected companies with low leverage and strong cash flows, but it couldn't protect against the systemic sell-off in 2008 (GFC) or the policy-driven correction in 2010-2011 when China tightened monetary policy to combat inflation.
Chinese A-share markets are dominated by retail investors, which creates momentum-driven cycles that don't respond to fundamental quality signals. When retail panic selling kicks in, companies with Piotroski scores of 9 drop alongside companies scoring 3. The quality premium that works in developed markets gets overwhelmed by market microstructure.
2014-2015: another boom, another lesson
+36.9% in 2014, +26.2% in 2015. These look great, but remember what happened to Chinese markets in the summer of 2015: a 40%+ crash from June to August. The July rebalance timing saved the strategy from the worst of it. Annual rebalancing is usually a limitation, but in China's 2015 crash, the timing was lucky. The portfolio had been rebalanced into strong names before the crash and didn't need to sell during the panic.
2018-2023: persistent drag
Six out of these last six years underperformed SPY. The US-China trade war (2018), deleveraging campaigns, zero-COVID policy (2020-2022), and the property crisis all weighed on Chinese equities regardless of fundamental quality. The sustainability score filters for company-level health, but it can't neutralize macro and policy risks that affect every stock in the market.
Backtest Methodology
| Parameter | Choice |
|---|---|
| Universe | SHH + SHZ, Market Cap > 2B CNY (~$276M USD) |
| Signal | 5-component sustainability score (0-10), minimum 7 |
| Components | Payout Ratio + D/E + FCF Coverage + ROE + Piotroski F-Score |
| Filters | Dividend Yield > 2%, Market Cap > 2B CNY |
| Portfolio | Top 30 by score descending (yield tiebreak), equal weight |
| Rebalancing | Annual (July) |
| Cash rule | Hold cash if < 10 qualify |
| Benchmark | SSE Composite Index (CNY) |
| Execution | Next-day close (MOC after signal) |
| Period | 2000-2025 (25 years) |
| Data | Point-in-time (45-day lag for annual filings) |
| Costs | Size-tiered transaction costs applied |
| Piotroski | Computed from historical financial statements (9 binary signals) |
Limitations
Retail-driven market microstructure. Chinese A-share markets have a much higher retail investor share than developed markets. This creates momentum cycles, herding behavior, and volatility patterns that fundamental screens can't fully address. Quality premiums exist in China, but they're noisier.
Policy risk dominates. Government intervention in Chinese markets ranges from trading halts and margin restrictions to sector-specific regulatory crackdowns. No financial metric in the sustainability score captures these risks.
Accounting quality concerns. Chinese financial reporting standards have improved, but early-period data (2000-2005) may have inconsistencies in how payout ratios, free cash flow, and ROE were reported.
The 2006 outlier. A single +131.1% year materially influences the 25-year CAGR. The strategy's performance is less robust than the headline number suggests when you consider that removing one extreme year changes the result substantially.
Currency risk. Returns are in local currency (CNY). For international investors, RMB/USD movements add another layer of volatility.
Survivorship bias. Exchange membership uses current company profiles. Delisted and acquired companies aren't fully captured.
Takeaway
The dividend sustainability screen on Chinese stocks produced 6.66% CAGR and beat the SSE Composite by 4.23% annually across 25 years. A 76% win rate against the local benchmark is the highest in our entire comparison. When framed correctly, China becomes a genuine outperformer.
The volatility (31.66%) remains the highest in our comparison. That's the real cost here. The quality of individual holdings is strong (8.9/10 average score) and the screen consistently outperforms the local market. But Chinese stocks move in ways that company-level fundamentals can't fully explain. Retail-driven sentiment, government interventions, and geopolitical shocks affect even the strongest balance sheets.
China's sustainable dividend payers deliver alpha over the local market. Extracting that alpha requires tolerating volatility that most investors won't stomach. The data supports the screen. The question is whether you can hold through the swings.
Part of a Series
This analysis is part of our dividend sustainability global exchange comparison. We tested the same screen on 13 exchanges worldwide: - [Dividend Sustainability on US Stocks (NYSE, NASDAQ, AMEX)][US_BLOG_URL] - 12.03% CAGR, full methodology - [Dividend Sustainability on Indian Stocks (NSE)][INDIA_BLOG_URL] - 15.81% CAGR, the standout - [Dividend Sustainability on Hong Kong Stocks (HKSE)][HONGKONG_BLOG_URL] - 6.50% CAGR - [Dividend Sustainability on Japanese Stocks (JPX)][JAPAN_BLOG_URL] - 6.70% CAGR - [Dividend Sustainability: 13-Exchange Global Comparison][COMPARISON_BLOG_URL] - full comparison table
References
- DeAngelo, H., DeAngelo, L. & Skinner, D. (1992). "Dividends and Losses." Journal of Finance, 47(5), 1837-1863.
- Piotroski, J. (2000). "Value Investing: The Use of Historical Financial Statement Information to Separate Winners from Losers." Journal of Accounting Research, 38, 1-41.
- Carpenter, J., Lu, F. & Whitelaw, R. (2021). "The Real Value of China's Stock Market." Journal of Financial Economics, 139(3), 679-696.
Run This Screen Yourself
Via web UI: [Run the sustainability screen on Ceta Research][SUSTAINABILITY_CHINA_QUERY_URL]. The query is pre-loaded. 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 latest_ratios AS (
SELECT r.symbol, r.dividendPayoutRatio, r.debtToEquityRatio,
r.dividendYield, r.date,
ROW_NUMBER() OVER (PARTITION BY r.symbol ORDER BY r.date DESC) AS rn
FROM financial_ratios r
JOIN profile p ON r.symbol = p.symbol
WHERE r.period = 'FY' AND r.dividendPayoutRatio > 0
AND r.dividendYield IS NOT NULL
AND p.exchange IN ('SHZ', 'SHH')
),
latest_cf AS (
SELECT c.symbol, c.freeCashFlow, c.commonDividendsPaid, c.date,
ROW_NUMBER() OVER (PARTITION BY c.symbol ORDER BY c.date DESC) AS rn
FROM cash_flow_statement c
JOIN profile p ON c.symbol = p.symbol
WHERE c.period = 'FY' AND c.commonDividendsPaid < 0
AND p.exchange IN ('SHZ', 'SHH')
),
latest_metrics AS (
SELECT k.symbol, k.returnOnEquity, k.marketCap, k.date,
ROW_NUMBER() OVER (PARTITION BY k.symbol ORDER BY k.date DESC) AS rn
FROM key_metrics k
JOIN profile p ON k.symbol = p.symbol
WHERE k.period = 'FY' AND k.marketCap IS NOT NULL
AND p.exchange IN ('SHZ', 'SHH')
),
latest_scores AS (
SELECT symbol, piotroskiScore FROM scores
),
scored AS (
SELECT r.symbol,
CASE WHEN r.dividendPayoutRatio < 0.5 THEN 2
WHEN r.dividendPayoutRatio < 0.8 THEN 1 ELSE 0 END +
CASE WHEN r.debtToEquityRatio >= 0 AND r.debtToEquityRatio < 0.5 THEN 2
WHEN r.debtToEquityRatio >= 0 AND r.debtToEquityRatio < 1.5 THEN 1
ELSE 0 END +
CASE WHEN c.freeCashFlow > 0 AND c.commonDividendsPaid < 0
AND c.freeCashFlow / ABS(c.commonDividendsPaid) > 2 THEN 2
WHEN c.freeCashFlow > 0 AND c.commonDividendsPaid < 0
AND c.freeCashFlow / ABS(c.commonDividendsPaid) > 1 THEN 1
ELSE 0 END +
CASE WHEN k.returnOnEquity > 0.15 THEN 2
WHEN k.returnOnEquity > 0.08 THEN 1 ELSE 0 END +
COALESCE(CASE WHEN s.piotroskiScore >= 7 THEN 2
WHEN s.piotroskiScore >= 5 THEN 1 ELSE 0 END, 0)
AS score,
ROUND(r.dividendYield * 100, 2) AS yield_pct,
ROUND(k.marketCap / 1e9, 1) AS mktcap_bn
FROM latest_ratios r
JOIN latest_cf c ON r.symbol = c.symbol AND c.rn = 1
JOIN latest_metrics k ON r.symbol = k.symbol AND k.rn = 1
LEFT JOIN latest_scores s ON r.symbol = s.symbol
WHERE r.rn = 1 AND r.dividendYield > 0.02 AND k.marketCap > 2e9
)
SELECT symbol, score, yield_pct, mktcap_bn
FROM scored WHERE score >= 7
ORDER BY score DESC, yield_pct 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} score={r['score']}/10 yield={r['yield_pct']:.1f}%")
Get your API key at cetaresearch.com. The full backtest code (Python + DuckDB) is on GitHub.
Data: Ceta Research, FMP financial data warehouse. Universe: SHH + SHZ. Annual rebalance (July), equal weight top 30 by sustainability score, 2000-2025.