Forecasting
We state probabilities for questions about our own results, then score ourselves against a coin flip.
Superforecasting in plain words
We state probabilities about our own results, then score ourselves. The method comes from the book Superforecasting: The Art and Science of Prediction by Philip Tetlock and Dan Gardner (2015). The idea is simple. Profit alone is a slow, noisy scorekeeper. A forecast that was written down first, with a number on it, can be checked one question at a time.
Start from base rates
A base rate is how often something happened in comparable past cases. If a strategy beat SPY in 4 of its last 10 comparable months, 40% is where the forecast starts. Only then do we ask whether anything today is different. This habit (Tetlock calls it the outside view) keeps a good story from talking us into 90%.
Say a precise number
"Probably" cannot be scored. "68%" can. Our forecasts are numbers between 0.01 and 0.99, written down before the answer is known and kept in git, so they cannot be edited afterward. Every question names the strategy, the event, the window and how it resolves.
Brier score, with an example
The Brier score is the squared miss: (probability minus what happened) squared, where what happened is 1 for yes and 0 for no. 0 is perfect. Lower is better.
A worked example
We say 70% that a strategy beats SPY over the next 20 trading days.
- It does beat SPY: (0.7 - 1) squared = 0.09. A small miss.
- It does not: (0.7 - 0) squared = 0.49. A big miss, because we were confident.
- Always saying 50% scores 0.25 whatever happens.
If our 70% calls really come true 7 times in 10, the average is 0.7 x 0.09 + 0.3 x 0.49 = 0.210, better than 0.25. If they come true only half the time, we score worse than the coin flip, and the scoreboard will say so.
Why compare against a coin flip
A forecaster who always says 50% is never overconfident and never useful. Any real skill has to beat that, so every question we ask is also issued as a coin-flip twin at 0.50. If our Brier score is not lower than the twin's, the forecasts add nothing.
Why we wait for 30 forecasts
Until 30 forecasts have resolved, we do not call the result. One forecast at 90% that fails scores 0.81. With 5 resolved forecasts that one miss moves the average by 0.16; with 30 it moves it by 0.027. Small samples are mostly noise. Repeats of the same question (for example a rerun of the same window) count once, because they are not new evidence.
The two kinds of forecast
Forward questions (every Monday)
For each strategy in the forward test we ask three questions over the next 20 trading days: does it beat SPY, does it beat textbook momentum, and does it fall more than 10% from its starting value. The probability is the base rate over that strategy's own point-in-time backtest of about the previous 9.5 years (rolling 20-day windows). Because the champion was fitted on that history, its base rates are in-sample, so read them with care.
Run questions (every evolution run)
Before a run looks at its unseen days, it forecasts three things about its own champion: beats the benchmark, beats textbook momentum, and ranks at or above the 90th percentile of fair random portfolios. The probability is (hits + 1) / (n + 2) over that arena's earlier scoreboard rows, so a first-ever run starts at 50%. The two families are scored apart.
No AI is involved in these forecasts. They are the strategies' own statistics, written down first.
Scorecard
Mean Brier score of our base-rate forecasts against coin-flip forecasts of the same questions (lower is better; a coin flip scores 0.25). Fewer than 30 resolved forecasts is too few to say anything.
| Family | Resolved | Our Brier | Coin-flip Brier | Status |
|---|---|---|---|---|
| forward | 0 | n/a | n/a | not enough yet (<30) |
| run | 21 | 0.220 | 0.250 | not enough yet (<30) |
| combined | 21 | 0.220 | 0.250 | not enough yet (<30) |
Run forecasts by arena
| Arena | Forecaster | Resolved | Mean Brier | Status |
|---|---|---|---|---|
| nasdaq100 | run-base-rate-v1 | 3 | 0.354 | not enough yet |
| nasdaq100 | run-coin-flip | 3 | 0.250 | not enough yet |
| smallcap | run-base-rate-v1 | 3 | 0.354 | not enough yet |
| smallcap | run-coin-flip | 3 | 0.250 | not enough yet |
| sp500 | run-base-rate-v1 | 3 | 0.125 | not enough yet |
| sp500 | run-coin-flip | 3 | 0.250 | not enough yet |
| walkforward-sp500 | run-base-rate-v1 | 12 | 0.176 | not enough yet |
| walkforward-sp500 | run-coin-flip | 12 | 0.250 | not enough yet |
Calibration
How to read the calibration chart
Calibration asks: of the times we said 30%, did it happen about 30% of the time? The chart below groups our forecasts into bins of stated probability (0.0 to 0.1, 0.1 to 0.2, and so on). Each dot is one bin. Across is what we said, up is how often it came true.
- A dot on the dashed diagonal means the stated odds matched reality.
- A dot below the diagonal means we were overconfident: it happened less often than we said.
- A dot above it means we were too timid.
- A bin with 2 or 3 forecasts can land anywhere by chance. The table under the chart gives each count.
Takeaway: 21 resolved forecasts in 4 bins; dots near the dashed diagonal mean the stated odds matched reality, but 21 is not enough yet (<30).
Show table
| Bin | Count | Mean forecast | Hit rate |
|---|---|---|---|
| 0.2-0.3 | 3 | 0.25 | 0.33 |
| 0.5-0.6 | 13 | 0.50 | 0.85 |
| 0.7-0.8 | 1 | 0.75 | 0.00 |
| 0.8-0.9 | 4 | 0.83 | 1.00 |
Recent forecasts
20 most recent forecasts.
| Issued | Subject | Question | Forecaster | p | Outcome | Brier |
|---|---|---|---|---|---|---|
| 2026-10-15 | run:walkforward-sp500 | Will the walkforward-sp500 run wf-sp500-20261014-192650-w0 see its champion beat the benchmark on its unseen holdout starting 2024-10-10? | base rate | 0.83 | yes | 0.028 |
| 2026-10-15 | run:walkforward-sp500 | Will the walkforward-sp500 run wf-sp500-20261014-192650-w0 see its champion beat the benchmark on its unseen holdout starting 2024-10-10? | coin flip | 0.50 | yes | 0.250 |
| 2026-10-15 | run:walkforward-sp500 | Will the walkforward-sp500 run wf-sp500-20261014-192650-w0 see its champion beat textbook momentum on its unseen holdout starting 2024-10-10? | base rate | 0.50 | yes | 0.250 |
| 2026-10-15 | run:walkforward-sp500 | Will the walkforward-sp500 run wf-sp500-20261014-192650-w0 see its champion beat textbook momentum on its unseen holdout starting 2024-10-10? | coin flip | 0.50 | yes | 0.250 |
| 2026-10-15 | run:walkforward-sp500 | Will the walkforward-sp500 run wf-sp500-20261014-192650-w0 see its champion ranked at or above the 90th percentile of fair random portfolios on its unseen holdout starting 2024-10-10? | base rate | 0.50 | yes | 0.250 |
| 2026-10-15 | run:walkforward-sp500 | Will the walkforward-sp500 run wf-sp500-20261014-192650-w0 see its champion ranked at or above the 90th percentile of fair random portfolios on its unseen holdout starting 2024-10-10? | coin flip | 0.50 | yes | 0.250 |
| 2026-10-15 | run:walkforward-sp500 | Will the walkforward-sp500 run wf-sp500-20261014-192650-w1 see its champion beat the benchmark on its unseen holdout starting 2025-04-14? | base rate | 0.83 | yes | 0.028 |
| 2026-10-15 | run:walkforward-sp500 | Will the walkforward-sp500 run wf-sp500-20261014-192650-w1 see its champion beat the benchmark on its unseen holdout starting 2025-04-14? | coin flip | 0.50 | yes | 0.250 |
| 2026-10-15 | run:walkforward-sp500 | Will the walkforward-sp500 run wf-sp500-20261014-192650-w1 see its champion beat textbook momentum on its unseen holdout starting 2025-04-14? | base rate | 0.50 | yes | 0.250 |
| 2026-10-15 | run:walkforward-sp500 | Will the walkforward-sp500 run wf-sp500-20261014-192650-w1 see its champion beat textbook momentum on its unseen holdout starting 2025-04-14? | coin flip | 0.50 | yes | 0.250 |
| 2026-10-15 | run:walkforward-sp500 | Will the walkforward-sp500 run wf-sp500-20261014-192650-w1 see its champion ranked at or above the 90th percentile of fair random portfolios on its unseen holdout starting 2025-04-14? | base rate | 0.50 | yes | 0.250 |
| 2026-10-15 | run:walkforward-sp500 | Will the walkforward-sp500 run wf-sp500-20261014-192650-w1 see its champion ranked at or above the 90th percentile of fair random portfolios on its unseen holdout starting 2025-04-14? | coin flip | 0.50 | yes | 0.250 |
| 2026-10-15 | run:walkforward-sp500 | Will the walkforward-sp500 run wf-sp500-20261014-192650-w2 see its champion beat the benchmark on its unseen holdout starting 2025-10-14? | base rate | 0.83 | yes | 0.028 |
| 2026-10-15 | run:walkforward-sp500 | Will the walkforward-sp500 run wf-sp500-20261014-192650-w2 see its champion beat the benchmark on its unseen holdout starting 2025-10-14? | coin flip | 0.50 | yes | 0.250 |
| 2026-10-15 | run:walkforward-sp500 | Will the walkforward-sp500 run wf-sp500-20261014-192650-w2 see its champion beat textbook momentum on its unseen holdout starting 2025-10-14? | base rate | 0.50 | yes | 0.250 |
| 2026-10-15 | run:walkforward-sp500 | Will the walkforward-sp500 run wf-sp500-20261014-192650-w2 see its champion beat textbook momentum on its unseen holdout starting 2025-10-14? | coin flip | 0.50 | yes | 0.250 |
| 2026-10-15 | run:walkforward-sp500 | Will the walkforward-sp500 run wf-sp500-20261014-192650-w2 see its champion ranked at or above the 90th percentile of fair random portfolios on its unseen holdout starting 2025-10-14? | base rate | 0.50 | yes | 0.250 |
| 2026-10-15 | run:walkforward-sp500 | Will the walkforward-sp500 run wf-sp500-20261014-192650-w2 see its champion ranked at or above the 90th percentile of fair random portfolios on its unseen holdout starting 2025-10-14? | coin flip | 0.50 | yes | 0.250 |
| 2026-10-15 | run:walkforward-sp500 | Will the walkforward-sp500 run wf-sp500-20261014-192650-w3 see its champion beat the benchmark on its unseen holdout starting 2026-04-16? | base rate | 0.83 | yes | 0.028 |
| 2026-10-15 | run:walkforward-sp500 | Will the walkforward-sp500 run wf-sp500-20261014-192650-w3 see its champion beat the benchmark on its unseen holdout starting 2026-04-16? | coin flip | 0.50 | yes | 0.250 |