backtest-overfit · source on GitHub

How much of a good backtest is luck?

112 parameterizations of four textbook strategy families were backtested on the 49 Kenneth French industry portfolios (1969-07 to 2026-08, 686 months, 10 bps costs, 10.0% volatility target). The best one is then put through the standard overfitting diagnostics. All numbers on this page are read from results/summary.json.

Selected, in-sample
0.68
annualized net Sharpe
Walk-forward OOS
0.36
same selection rule, pseudo out-of-sample
PBO (CSCV)
0.02
12,870 splits
Deflated Sharpe
0.893
sign-aligned Var[SR], N = 112
Permutation p-value
0.005
200 shuffles

The selected strategy

xsmom(lookback=12,skip=0,quantile=0.2)|vol12 has the highest full-sample net Sharpe ratio, 0.68 (95% block-bootstrap CI 0.41 to 0.95; the interval treats this trial as if it had been fixed in advance and does not account for having picked it from 112). Its Sharpe was 0.90 before 1998-02 and 0.46 after.

On month-shuffled data the best of the same grid averaged 0.22 (max 0.54, p = 0.005). Shuffling also removes the volatility clustering that volatility targeting uses, so the same test was repeated without volatility targeting: the selected signal then has a Sharpe of 0.52, the best of 56 unscaled signals 0.52, against a shuffled best-of-grid mean of 0.20 (p = 0.005).

Distribution of net Sharpe ratios across the grid.
Distribution of net Sharpe ratios across the grid.
Best-of-grid Sharpe on month-shuffled data vs the observed best.
Best-of-grid Sharpe on month-shuffled data vs the observed best.

The Deflated Sharpe Ratio compares the selected Sharpe with the expected best of N skill-less trials, which depends on N and on the variance of Sharpe ratios across trials. Sign-aligning flips families whose median Sharpe is negative (reversal); the effective N is the participation ratio of the eigenvalues of the trial correlation matrix.

Var[SR] and N usedNStd of SRE[max SR]DSR
Raw trial Sharpes (paper recipe)112.00.350.900.049
Sign-aligned families112.00.200.510.893
Sign-aligned, effective N3.10.200.181.000
No-signal variance from shuffles112.00.130.340.994
Trials assumed (N), sign-aligned Var[SR]DSR
11.000
41.000
100.997
300.976
1120.893
Cost per unit turnoverSharpe
0 bps0.76
10 bps0.68
25 bps0.56
50 bps0.37

Probability of Backtest Overfitting

CSCV splits the 672 months into 16 blocks and evaluates all 12,870 half/half splits. The in-sample winner lands below the out-of-sample median in 2.4% of splits and loses money out of sample in 0.9%. Median Sharpe of the winner: 0.66 in sample, 0.54 out of sample. Across splits, the OOS Sharpe of the winner falls as its IS Sharpe rises (OLS slope -0.67); part of this is mechanical, because the two halves are complements of one fixed sample.

Logit of the out-of-sample rank of the in-sample winner across CSCV splits.
Logit of the out-of-sample rank of the in-sample winner across CSCV splits.
CSCV: in-sample Sharpe of each split's in-sample winner vs its out-of-sample Sharpe (the winner changes from split to split).
CSCV: in-sample Sharpe of each split's in-sample winner vs its out-of-sample Sharpe (the winner changes from split to split).
FamilyTrialsBest SharpeMedian SharpePBO
xsmom480.680.380.02
tsmom140.390.210.32
ma_cross380.360.220.34
reversal12-0.52-0.740.01

Walk-forward selection

Every 12 months, pick the trial with the best Sharpe over the trailing 120 months and hold it. Over 48 windows this chose 18 distinct trials.

Growth of $1 over the walk-forward test months.
Growth of $1 over the walk-forward test months.
Series (same months)SharpeAnn. return
Walk-forward OOS0.364.2%
Hindsight best, same months0.576.6%
Equal weight of all trials0.302.1%

Walk-forward OOS Sharpe 95% bootstrap CI: 0.05 to 0.68.

Factor-adjusted alpha

OLS on Fama-French factors with Newey-West standard errors.

SeriesModelAlpha (ann.)t (NW)Lags
Selected (hindsight)FF39.6%5.666
Selected (hindsight)FF59.5%5.176
Walk-forward OOSFF34.4%2.465
Walk-forward OOSFF53.8%2.045

Top 10 trials

TrialSharpeAnn. retAnn. volMax DDTurnover/yr
xsmom(lookback=12,skip=0,quantile=0.2)|vol120.688.1%11.9%-34.7%9.4
xsmom(lookback=12,skip=0,quantile=0.3)|vol120.647.6%11.9%-31.0%9.8
xsmom(lookback=12,skip=1,quantile=0.2)|vol120.637.4%11.8%-24.5%9.5
xsmom(lookback=12,skip=0,quantile=0.2)|vol360.627.1%11.4%-33.0%7.4
xsmom(lookback=12,skip=1,quantile=0.3)|vol120.617.3%11.8%-24.6%10.2
xsmom(lookback=12,skip=0,quantile=0.1)|vol120.607.1%11.9%-29.9%7.9
xsmom(lookback=12,skip=0,quantile=0.3)|vol360.586.6%11.3%-27.6%7.7
xsmom(lookback=12,skip=1,quantile=0.2)|vol360.566.3%11.2%-31.4%7.6
xsmom(lookback=12,skip=0,quantile=0.1)|vol360.566.3%11.2%-30.2%6.4
xsmom(lookback=9,skip=0,quantile=0.2)|vol120.566.7%12.0%-29.5%10.9

Data and methods