Eight signals, each with a learned weight, scored every trading day against what the market did. The engine gives a probability and a range for one week, two weeks and a month. It only calls a direction when its own recent track record beats a coin flip; most days it does not, and it says so.
| Signal | Today | 1 week | 2 weeks | 1 month | trust |
|---|---|---|---|---|---|
Season | 10 Nov | ↓ 47% | ↓ 46% | ↓ 43% | 12% |
Trend (20 and 60 days) | 20d -0.2σ · 60d +1.1σ | ↑ 54% | ↑ 53% | ↑ 54% | 11% |
Reversal (5 days) | 5d -0.9σ | ↓ 48% | ↑ 51% | ↓ 50% | 11% |
Asia pull (TTF − JKM) | spread -1.7σ vs 6 months | ↓ 43% | ↓ 44% | ↓ 46% | 11% |
EU storage vs 5-year | 72.0% vs 89.3% normal | ↑ 64% | ↑ 70% | ↑ 75% | 12% |
US departures to Europe | 57% to Europe vs 83% normal | ↑ 57% | ↑ 61% | ↑ 60% | 10% |
Weather forecast revision live only: no backtest, learning from now | 138 HDD next 15 days (was 138), normal 134 | ↑ 51% | ↑ 51% | ↑ 51% | 11% |
Forward curve slope live only: no backtest, learning from now | 2027-02 at €84.0 vs front €84.7 | · 50% | ↓ 49% | ↓ 49% | 11% |
Arrows show what each signal says on its own; trust is its weight in the one-week mix, set by how it scored over the last ~250 forecasts (a signal that scores like a coin flip gets the same weight as the 50/50 anchor). Hover for details.
| Horizon | resolved | direction right | Brier | calls | calls right |
|---|---|---|---|---|---|
| 1 week | 3 | 0% | 0.280 | 0 | – |
| 2 weeks | 0 | – | – | 0 | – |
| 1 month | 0 | – | – | 0 | – |
| Horizon | forecasts | direction right | Brier (coin 0.250) | calls | calls right | move per call |
|---|---|---|---|---|---|---|
| 1 week | 1,452 | 57% | 0.246 | 171 (12%) | 63% | +2.0% |
| 2 weeks | 1,447 | 59% | 0.242 | 259 (18%) | 65% | +2.9% |
| 1 month | 1,436 | 60% | 0.238 | 483 (34%) | 64% | +6.5% |
| year | 1 week | 2 weeks | 1 month |
|---|---|---|---|
| 2021 | 63% | 64% | 65% |
| 2022 | 57% | 62% | 61% |
| 2023 | 64% | 69% | 82% |
| 2024 | 50% | 52% | 49% |
| 2025 | 46% | 42% | 37% |
| 2026 | 62% | 64% | 68% |
What this says, plainly: direction over one week to one month is right 57%–60% of the time, the probabilities are honest (a stated 55–60% comes true about 58% of the time), and the Brier score beats both a coin flip and the seasonal climatology at every horizon, by a sliver: the bootstrap interval for that skill clears zero only at 2 weeks, and only just. The edge sits in the slow signals, storage against its seasonal normal and the time of year; it was strong in 2021 and 2023 and absent in 2024 and 2025. The two forward-looking signals, forecast revisions and the curve, could not be backtested and start learning now; the live track record above is the only test that counts.
Every design choice re-run through the same walk-forward backtest (2021–2026), next to an independent re-implementation in Python (batch logistic regression, refit every 20 trading days on everything known at the time). Brier: lower is better; a coin flip scores 0.250 and the seasonal climatology 0.251 / 0.251 / 0.256. The bracket is the 95% block-bootstrap interval of the skill over a coin flip: it has to sit wholly above zero before anyone may call it skill.
| variant | 1 week | 2 weeks | 1 month |
|---|---|---|---|
| production: season and storage batch-fitted, near-equal weights (κ 10) | 0.246 57% · [+0.000, +0.007] | 0.242 59% · [+0.001, +0.015] | 0.238 60% · [-0.002, +0.027] |
| all signals SGD (no batch expert) | 0.249 55% · [-0.001, +0.004] | 0.246 56% · [+0.000, +0.008] | 0.247 56% · [-0.003, +0.010] |
| all backtestable signals batch-fitted | 0.245 58% · [+0.001, +0.009] | 0.243 59% · [-0.001, +0.015] | 0.239 60% · [-0.008, +0.030] |
| storage batch-fitted only (season SGD) | 0.247 56% · [+0.000, +0.006] | 0.244 56% · [+0.001, +0.012] | 0.242 57% · [-0.002, +0.017] |
| storage not lagged (optimistic) | 0.246 57% · [+0.000, +0.007] | 0.242 58% · [+0.001, +0.015] | 0.238 60% · [-0.002, +0.027] |
| departures with DOE publication lag (60 d) | 0.246 55% · [+0.000, +0.008] | 0.242 59% · [+0.001, +0.015] | 0.239 58% · [-0.003, +0.026] |
| without departures signal | 0.245 56% · [+0.001, +0.008] | 0.241 59% · [+0.002, +0.017] | 0.238 59% · [-0.003, +0.029] |
| plus joint logistic expert | 0.247 57% · [-0.001, +0.007] | 0.242 57% · [+0.001, +0.016] | 0.240 58% · [-0.005, +0.027] |
| joint logistic only | 0.249 55% · [-0.003, +0.005] | 0.244 55% · [-0.001, +0.013] | 0.247 53% · [-0.011, +0.019] |
| kappa 30 (sharper weights, previous) | 0.246 56% · [+0.000, +0.008] | 0.243 59% · [-0.002, +0.014] | 0.244 59% · [-0.010, +0.023] |
| kappa 3 (almost equal weights) | 0.246 57% · [+0.001, +0.007] | 0.241 59% · [+0.002, +0.015] | 0.236 61% · [+0.000, +0.029] |
| lr 0.06 | 0.249 55% · [-0.003, +0.005] | 0.244 57% · [-0.002, +0.013] | 0.243 58% · [-0.008, +0.024] |
| l2 0.001 (longer memory) | 0.246 57% · [+0.000, +0.008] | 0.242 59% · [+0.001, +0.015] | 0.238 59% · [-0.003, +0.028] |
| l2 0.01 (shorter memory) | 0.246 56% · [+0.000, +0.007] | 0.242 59% · [+0.001, +0.014] | 0.238 60% · [-0.001, +0.026] |
| loss half-life 120 | 0.246 57% · [+0.000, +0.007] | 0.243 58% · [+0.000, +0.014] | 0.240 59% · [-0.005, +0.025] |
| loss half-life 500 | 0.246 57% · [+0.001, +0.007] | 0.242 59% · [+0.002, +0.015] | 0.237 60% · [-0.001, +0.028] |
| call threshold 0.04 | 234 calls 62% right · same odds | 340 calls 61% right · same odds | 590 calls 62% right · same odds |
| call threshold 0.10 | 52 calls 56% right · same odds | 151 calls 68% right · same odds | 295 calls 64% right · same odds |
| breaker half-life 150, scaled by horizon (150/300/630, previous) | 181 calls 60% right · same odds | 341 calls 64% right · same odds | 541 calls 64% right · same odds |
| breaker half-life 100, not scaled | 174 calls 62% right · same odds | 270 calls 64% right · same odds | 436 calls 61% right · same odds |
| breaker half-life 60, not scaled | 171 calls 63% right · same odds | 236 calls 69% right · same odds | 378 calls 60% right · same odds |
| breaker half-life 40, not scaled | 182 calls 64% right · same odds | 220 calls 72% right · same odds | 330 calls 64% right · same odds |
| model | 1 week | 2 weeks | 1 month |
|---|---|---|---|
| batch logistic, base signals, no intercept | 0.254 56% | 0.257 59% | 0.259 61% |
| batch logistic, base signals, with intercept | 0.256 55% | 0.262 58% | 0.266 59% |
| batch logistic, strong L2 (lam 10) | 0.253 56% | 0.254 58% | 0.256 61% |
| batch logistic, kitchen sink | 0.253 56% | 0.260 58% | 0.270 60% |
| seasonality only | 0.248 55% | 0.248 57% | 0.243 61% |
| storage only | 0.245 58% | 0.243 59% | 0.241 59% |
| trend only | 0.253 52% | 0.254 51% | 0.253 57% |
| climatology (trailing-year up share) | 0.248 55% | 0.249 56% | 0.262 53% |
The second implementation ranks the signals the same way: storage is the one signal with a measurable edge, seasonality is second, trend and the Asian spread add nothing. A plain regression on all signals at once is overconfident: it gets the direction right 58–61% of the time yet scores worse than a coin flip, because it states 20% or 80% when 40% or 60% would be true. That overconfidence is what the ensemble's slope calibration and gentle weighting remove.
What the grid says: the gain over the first version comes from fitting the two slow signals on their whole memory instead of nudging them forecast by forecast, and from weighting the signals almost equally; chasing recent performance (sharper weights, a shorter memory) costs. Leaving the cargo-departures signal out changes nothing measurable at these horizons: the research effect is real but slow. All of this is thin. The skill intervals touch zero, the good years were 2021 and 2023, and 2024 and 2025 were coin flips. Anything better has to come from data that looks forward: forecast revisions, the curve, outage notices, positioning.
Sources: Yahoo Finance (TTF=F, JKM=F, EURUSD=X, NYMEX TTF months), GIE AGSI+, U.S. DOE cargo list (backtest) and own AIS departures (live), ECMWF ensemble via Open-Meteo. Outcome = TTF front-month close after 5/10/21 trading days versus the close on the forecast day; contract rolls are included in that, as traders experience them.