IMC Prosperity 4: Top 1.2% Out of 22,000+ Teams
A few months ago, my teammates Gangula Bhuvan Reddy and Andrea Jose and I entered the IMC Prosperity 4 algorithmic trading challenge. We went in with modest expectations — more curious about the problem space than chasing a podium finish. We ended up performing far better than we anticipated.
🏆 Results
Out of 22,000+ participating teams worldwide, our team Gradient Exploders placed:
- 🥇 #266 Overall — Top 1.2% globally
- 🎯 #61 in Manual Trading — Top globally
- JP #2 in Country
- 💰 Team Total: 485,957 SeaShells (target was 200,000 — we more than doubled it)
We’re also in the top 15% of teams that qualified for the finals, so the competition isn’t over yet.
🎮 What Is IMC Prosperity?
IMC Prosperity is a multi-round algorithmic trading simulation run by IMC Trading. Each round introduces new financial instruments (products), and teams compete by writing a Python Trader class that submits orders against a live order book. There are two components per round:
- Algorithmic Trading — Your bot trades against a simulated market. You submit Python code that runs at every timestamp, making buy/sell decisions on the order book.
- Manual Trading — Game-theoretic puzzles where you analyze market scenarios and make one-shot decisions to maximize profit.
The challenge spans several rounds with increasing complexity: from simple mean-reversion on single products to multi-asset arbitrage, conversion arbitrage, and coordination games.
🧠 Our Approach
Algorithmic Trading
Our most successful algorithmic strategy was a Kalman filter-based adaptive market maker for INTARIAN_PEPPER_ROOT. Rather than using a fixed fair-value estimate, we continuously updated our price beliefs using the Kalman filter to adapt to market drift:
# Simplified core of our Kalman adaptive strategy
def kalman_update(self, mid_price: float) -> float:
# Predict step
self.x_est = self.x_est # no drift model
self.p_est = self.p_est + self.process_noise
# Update step
k_gain = self.p_est / (self.p_est + self.obs_noise)
self.x_est = self.x_est + k_gain * (mid_price - self.x_est)
self.p_est = (1 - k_gain) * self.p_est
return self.x_est
The key insight was that simple, structurally sound ideas consistently outperformed complex models. When we tried to layer on more sophisticated signals (momentum, regime detection), performance degraded — not because the ideas were wrong, but because the backtesting data wasn’t rich enough to tune them reliably.
Manual Trading
The manual rounds were pure game theory. Each puzzle presented a scenario (e.g., a bidding war, a prisoner’s dilemma-style coordination game, or an options payoff matrix) and asked you to commit to a strategy. Our #61 global manual rank was the highlight of the competition — it validated that thinking probabilistically and modeling other participants’ reasoning was more valuable than trying to find the “mathematically optimal” answer in isolation.
🛠️ The Backtester
To iterate on strategies quickly, we built our own Python backtester on top of jmerle’s Prosperity 3 backtester, rewriting it in a more modular OOP style for Prosperity 4’s data format.
GitHub: YashJayswal24/imc-prosperity-4-backtester
The backtester has three core components:
| Component | Role |
|---|---|
BackTester | Top-level driver — loads algorithm, iterates over rounds/days, merges results |
TestRunner | Daily simulator — replays each timestamp, feeds TradingState to your algorithm |
OrderMatchMaker | Simulates exchange mechanics — fills orders against the historical order book |
Usage:
# Run your algorithm against round data
python -m prosperity4bt algorithms/Round_2/trader_r1_kalman_adaptive_final.py 2
# Run against a specific day
python -m prosperity4bt algorithms/Round_2/trader_r1_kalman_adaptive_final.py 2--1
Having a local backtester was critical — the official platform only gives you feedback after submitting, so the ability to run hundreds of iterations locally and inspect per-timestamp P&L was invaluable.
💡 Key Takeaways
-
Simplicity wins. Every time we added complexity (multi-signal models, adaptive parameters, regime detection), we were more likely to overfit than to improve. The strategies that worked best had a clean, interpretable hypothesis.
-
Backtesting is a tool, not a truth. Backtest results are necessary but not sufficient. We learned to treat strong backtest performance with skepticism and focus on whether the reasoning behind a strategy held up.
-
Game theory is underrated in algo trading. The manual rounds made it clear: understanding how other participants reason is as important as finding the correct expected value. This applies to algorithmic trading too — if everyone runs the same strategy, the edge disappears.
-
Community resources are invaluable. Reading through open-source solutions from Prosperity 2 and 3 gave us a mental model of the problem space before Round 1 even started.
🔭 What’s Next
We’ve qualified for the finals and are looking forward to seeing how the competition evolves. The later rounds tend to introduce more complex instruments and deeper market microstructure — exactly the kind of problem space where we want to improve.
If you’re considering entering IMC Prosperity, I’d highly recommend it. The problems are well-designed, the community is active, and it’s one of the best practical environments to apply probability theory and market microstructure concepts outside of a live trading environment.