esc

Search pages, or explore a browser-only workspace. Try help.

work / competitions

Competitions

IMC Prosperity 4, where Team SHDC placed 904th globally, and the Kaggle Pokémon TCG AI Battle, an agent for a card game with hidden information.

IMC Prosperity 4

Team of 3; coded the final two rounds2026Python · Kalman filter · Ornstein–Uhlenbeck models

904th
globally, with Team SHDC
18th
in Hong Kong

Lessons-learned write-up: imc-prosperity-4-shdc

The problem

IMC Prosperity is a multi-round algorithmic and manual trading competition. Each round adds new products, and each needs its own fair value, its own risk, and its own decision about when a signal is real. We were a team of 3: my teammates coded the early rounds and I coded the final two.

What I built

  • Kalman/OU fair values for market makingKalman filterA recursive estimator that tracks a hidden value, such as a fair price, from noisy observations, updating its belief with every new tick.. A Kalman filter replaced a fixed-window drift gate, so a drift signal is used only when its slope is clearly away from zero.
  • A gated one-lot relative-value trade across a product family, capped at one lot and run beside market making on a subset of products.
  • The team’s results check, plus a round-by-round review against nine public write-ups from teams placed 2nd to 583rd.

Result

904th globally and 18th in Hong Kong, with Team SHDC.

How it works

  1. 01Round recordsone template each
  2. 02Top-team ideasidea by idea
  3. 03Lessonsfrom our records
  4. 04Doc checkerlinks, structure
one template per round, so rounds compare like for like

The review names our main process mistake: we used a fast local replay as our filter but never set a go/no-go rule for it. It also records a costed decision. My teammates priced delta-hedging the vouchers and rejected it.

Limits

  • The team’s competition code is unpublished, so the strategy is described rather than shown.
  • Local backtests are not official scores and may overstate them.

Kaggle Pokémon TCG AI Battle

Team entry; author of this repositoryPython · PyTorch · NumPy · Rust · GPU

89,048
decisions from 926 games, split by game so validation never leaks into training

Repository: ptcg-ai-battle

The problem

In this card game, the set of legal moves changes at every prompt and half the board is hidden. Kaggle runs the agent in a sandbox with no guarantee that PyTorch is installed. The hardest problem turned out not to be playing well. It was knowing that the agent running in the sandbox is the one that was trained.

What I built

  • Policy learning on 89,048 decisions from 926 games. The split is by game, so positions from a validation game never leak into training.
  • A set-transformer policy that scores each legal option from typed board tokens, served with NumPy at inference so it does not depend on PyTorch.
  • Parity and packaging gates that test the built package itself, not the training code.
  • A batched Rust/GPU simulator prototype of a simplified game loop, with the GPU output checked against a CPU reference.

How it works

  1. 01Engine promptlegal options given
  2. 02Board tokenstyped, with edges
  3. 03Set transformerscores each option
  4. 04NumPy servingno torch needed
  5. 05Package gatesparity, fallbacks
the gates test the packaged artefact, the thing Kaggle actually runs
  • Imitation firstimitation learningTraining a policy to copy the decisions in recorded games before improving it any further., reinforcement learning only as a fine-tune.
  • The serving fallback counts and logs every exception instead of silently playing a random move, so a broken agent is visible.

designed and verified by Oscar, implemented with AI coding agents (Claude Code, Codex)

Limits

  • The simulator is a prototype of a simplified game loop, not a full engine port.
  • The final agent cannot be rebuilt from the repository alone: the weights, the game corpus and the licensed engine are not included.