Alexandre Dalban

Work · forecasting research · 9 min read

Phantom: distributional return forecasts for 362 cryptocurrencies

I wanted to know whether daily price and volume data says anything about which coins will beat their peers over the next month. The answer is a little, and it comes with a calibrated distribution. The most useful part of the project was the audit that corrected my own headline.

0.124out-of-sample rank IC at 10 days (Newey-West t = 8.9)
15 / 15test months with positive IC, January 2025 to March 2026
90.3%of realised returns landed inside the 90% prediction interval
√10Sharpe inflation I found and corrected in my July 2026 audit
Dates
Built 1 to 5 April 2026 (eight model versions and a public release), then audited and corrected on 24 July 2026
Status
Backtest research. A Polymarket strategy priced off its distributions had 21 live executions in April, too few to report a result
Role
Solo: data, model, training on an A100 cluster via SLURM, evaluation and the audit. I built it with Claude Code.
Code
github.com/ADnocap/phantom, public, with the v8 checkpoint and the data release

The question and the model

As far as this project could tell, absolute crypto returns can't be predicted from price and volume alone (versions 3 and 4 below). Relative returns are a different question. After subtracting the cross-sectional mean each day, I asked whether there's a signal about which of 362 Binance-listed coins will do better than the others over the next 1 to 30 days. Phantom answers that with a distribution instead of a single number. For every coin and every horizon it outputs the location, scale and tail weight of a Student-t.

The input is 120 days of six engineered channels per coin (log return, intraday range, body ratio, log volume ratio, trailing volatility, 10-day momentum). The model cuts that into 24 patches and runs them through an 8-layer pre-norm Transformer (512 dimensions, 8 heads). A 2-layer cross-attention decoder holds 30 learned horizon queries that attend to the encoded history in one pass, and a small MLP maps each decoded vector to (μ, σ, ν).

Condition dropout at p = 0.15 and a variance penalty on the encoder stop the decoder from ignoring its input. I diagnosed that collapse during the synthetic pretraining phase (versions 1 and 2), when zeroing the encoder output moved the predicted mean by only 0.018. The loss is negative log-likelihood plus 0.5 × CRPS plus a √h-weighted mean-squared term plus the variance penalty. Training has two stages: pretrain on 413 assets across crypto, equities, FX and commodities, then fine-tune on the 362-coin universe. The model has 31.7 million parameters and trains on one A100 in bf16.

Block diagram: 120 by 6 OHLCV input, patch embedding into 24 patches, an 8-layer 512-dimensional Transformer encoder, a 2-layer cross-attention decoder fed by 30 horizon embeddings, a Student-t head, and 30 output distributions.
The v8 architecture. The decoder's 30 horizon queries read the encoded 120-day history once and emit one Student-t per horizon. Source: my architecture diagram, unaffected by the audit.

Out-of-sample results

The test window runs from January 2025 to March 2026, 144,630 coin-days over 430 dates. None of them were seen in training or validation, with the caveat that windows next to the split share up to 30 days of context. The rank information coefficient (Spearman correlation between predicted and realised relative return across coins, averaged over dates) is 0.124 at the 10-day horizon. It rises monotonically with horizon, which is what a drift signal should do against noise that grows with √h.

Rank IC by forecast horizon on the test set. It rises from 0.080 at one day to 0.166 at thirty. The across-date standard deviation is 0.14 to 0.20, so the standard error over 430 dates is below 0.01 at every horizon before any overlap correction. Source: evaluation log of the v8 checkpoint.

The sign of the signal is stable but its size isn't. IC is positive in every one of the 15 test months, between 0.036 and 0.200.

Out-of-sample rank IC at the 10-day horizon, by month, January 2025 to March 2026. It's positive in all 15 months, so there is a signal, but it's far from constant. March 2026 is a six-day partial month. Source: the evaluation log of the released v8 checkpoint, post-audit. The July 2026 audit didn't change these values.

Sorting coins by the 10-day forecast gives monotonic realised returns across quintiles (Spearman 1.00) and near-monotonic returns across deciles (0.99, with D5 and D6 swapping places by 0.03 percentage points, inside their standard errors). On average the bottom decile loses 2.45% and the top gains 1.22% per 10-day window.

Mean realised relative return per 10-day holding window by forecast decile, D1 lowest to D10 highest. The ordering holds apart from a D5/D6 swap within noise. The payoff is asymmetric, since most of the spread sits in the bottom decile, which is also the hardest to short. Source: the repository's analysis script on the v8 checkpoint, standard errors 0.08 to 0.15 percentage points.

The distributional part holds up. The 50, 80, 90 and 95% prediction intervals contain 47.7, 79.2, 90.3 and 95.7% of realised 10-day returns, the probability integral transform is close to uniform, and the model drives ν to about 2. So it learned that crypto returns have very heavy tails, and priced them.

Three panels: a near-uniform PIT histogram at the 10-day horizon, a coverage calibration curve tracking the diagonal, and predicted sigma rising with horizon roughly as the square root of the horizon.
Distributional diagnostics at the 10-day horizon: PIT histogram, coverage against nominal level, and predicted scale by horizon against a √h reference. Source: the evaluation's calibration plots. The calibration metrics aren't annualised and the audit didn't affect them.

Against the baselines

Phantom has the highest IC among the directional baselines I built (momentum, mean reversion, volume, random). A naive low-volatility sort has a higher raw IC, 0.165, and is 0.63 rank-correlated with Phantom's signal. Phantom's independent contribution is significant only within the mid- and high-volatility terciles (spread t-statistics 2.6 and 4.1), and the two signals combined reach IC 0.157. The README describes it the same way.

Rank IC at the 10-day horizon, Phantom against simple baselines on the same test set. The low-volatility sort beats it on raw IC. Source: the baseline comparison in the evaluation, post-audit.

The audit

Retracted, 24 July 2026
The April release reported a long-short Sharpe of 11.8 to 13.0, a 925% annualised return, a "74.7% daily win rate" and a 336 basis-point break-even cost. The long-short series was made of overlapping 10-day returns sampled daily, and I'd annualised it as if each observation were a day, which inflates Sharpe by about √10. The corrected numbers are a gross, horizon-corrected Sharpe of about 4.1 (an upper bound), about 93% annualised gross, and a break-even of about 34 basis points one way. The 74.7% is the share of positive 10-day windows.

I found this three and a half months after the release, while preparing the work for applications. The Sharpe looked too high to believe, so I audited the evaluation code and traced it to the long-short series being 10-day forward returns sampled daily and annualised as if each observation were a day. The fix in the repository is a √10 rescale of that overlapping-series Sharpe, which is equivalent up to residual autocorrelation to recomputing on non-overlapping 10-day blocks.

The same pass documented some other problems. The universe is survivor-biased (I only fetched pairs still trading in March 2026, so coins delisted during the test period are missing from training, testing and from the cross-sectional mean itself). The short leg is partly unimplementable, because much of the bottom quintile has no margin or perpetual-futures market. And the Newey-West lag I used under-corrects for the MA(9) overlap, though conservative lags still leave the IC t-statistic above 6. I corrected the README, the experiment log and the evaluation code, and left the old numbers visible as errata.

After realistic frictions I think a net Sharpe of 1 to 2 is plausible. The cost table below is the corrected one. The results figures in the repository's plots directory were generated before the audit and still carry pre-correction labels. That's why the IC, decile and baseline charts on this page are drawn from the underlying data instead of embedding those figures. The architecture and calibration figures above contain no annualised numbers and are unaffected.

ScenarioOne-way costGross/net Sharpe, horizon-corrected
Gross0 bps≈ 4.1
Standard exchange fee10 bps≈ 2.9
Conservative30 bps≈ 0.4
Break-even≈ 34 bps0
Equal-weighted quintile long-short (top 20% minus bottom 20% by predicted 10-day mean), rebalanced daily on overlapping 10-day holding windows, quintile-membership turnover 37.8% per day, survivor-biased universe. Every figure here is an upper bound.

Eight versions, mostly failures

I ran the project as an ablation, and the experiment log records each version's hypothesis and result. Five of the eight versions were negative.

VersionChangeIC (10d)Sharpe, correctedFinding
v1, v2Pretrain on synthetic SDE paths (GBM, Merton, Kou, Bates, GARCH)Reached the oracle CRPS on synthetic data (0.064 versus 0.065 theoretical) but transferred nothing to real assets.
v3Pretrain on real multi-asset data0.00Well-calibrated uncertainty and no directional signal.
v4Multi-horizon absolute returns0.00Memorised training directions and didn't generalise.
v5Predict cross-sectionally demeaned returns0.09≈ 1.5This unlocked the signal. It was concentrated in crypto (IC 0.144) versus commodities 0.084, FX 0.007, equities 0.003.
v6Add funding-rate and taker-buy features, fine-tune on crypto only0.14≈ 1.7The features added under 0.002 IC each. The gain came from training on crypto only.
v74-hour bars0.10≈ 0.8It did worse. Adjacent windows share 99.7% of their bars, so 476k "samples" are about 80k daily windows.
v8Widen from 60 to 362 coins0.12≈ 4.1The extra breadth diversified the long-short portfolio, while mean IC fell slightly from v6.
Sharpe ratios are gross, equal-weighted, survivor-biased and horizon-corrected. The pre-audit values in the repository's log were about √10 larger.

A binary-option test of whether it could be traded

In a two-day follow-up I asked whether the same distributions price Polymarket's daily "BTC above $X" markets better than the market does. I used 7,982 resolved BTC and ETH markets from August 2025 to March 2026, with each side's price read from its own order book. At four to six days to expiry the model's probabilities were better calibrated than the ask price (root-mean-square calibration error 0.035 against the market's 0.068). At two to three days they were overconfident by about five points, which set a minimum-horizon rule.

Buying the side with edge and holding to settlement, with entry prices between 0.15 and 0.85, a 20% edge cap and ETH range markets excluded, turned $1,000 into $3,885 in the 7-month backtest (68% win rate, 1,120 trades, weekly Sharpe 2.05, drawdown −48%). The trading page quotes a delta-aware-sizing variant of the same backtest: 1,118 trades, 67% win rate, weekly Sharpe 2.2, drawdown −36%. That variant has no edge cap and ends at $3,925.

The caveats are big enough that I present this as a calibration result, not a strategy. It's one seven-month window during which BTC fell about 42% while the strategy was structurally short BTC (it mostly buys NO on "above" markets). The backtest assumes fills at the full displayed ask and values positions at cost until settlement. The most instructive caveat is an uncapped variant of the run (no 20% edge cap, $4,714 at the ask). Executed as mid-price limit orders it lost money to adverse selection, with the win rate going from 67% to 54% and the account ending at $787. I quote the capped run above because the cap is in the documented parameters.

Six calibration panels comparing the model (blue circles) and the Polymarket ask price (orange diamonds) against the diagonal, by days to expiry 2 to 3, 4 to 6 and 7 to 14, before and after a settlement-time adjustment. The model tracks the diagonal better at 4 or more days and is overconfident at 2 to 3 days.
Model versus market calibration on Polymarket BTC and ETH daily binaries by days to expiry (top row raw horizons, bottom row horizons adjusted to the 5 pm UTC settlement). At four days and beyond the model is closer to the diagonal than the ask. At two to three days it's overconfident. Source: the follow-up repository's calibration analysis, 6 April 2026.

What I'd do differently