competitions.algocracked
← Platforms

IMC Prosperity

A Python-based algorithmic trading competition by IMC Trading (one of the world's top HFT firms). You build trading bots that compete in a simulated virtual marke…

Open now

No open IMC Prosperity competitions in the feed right now.

Never miss a deadline

Add the competitions calendar to your phone

Subscribe once — every open competition's deadline shows up in your native calendar and auto-updates daily as new ones open and old ones close. No account needed.

Outlook / other: add a calendar “from URL” using the copied link.

How to win on IMC Prosperity

IMC Prosperity 4 — Trading Competition Guide

What Is It?

A Python-based algorithmic trading competition by IMC Trading (one of the world's top HFT firms). You build trading bots that compete in a simulated virtual market across 5 rounds. Combines algorithmic trading + market microstructure + strategy.

2026 Key Facts

  • Edition: Prosperity 4
  • Prize pool: $50,000 USD
  • Start: April 14, 2026
  • Format: 5 rounds, each with 1 algorithmic challenge + 1 manual challenge
  • Duration: Rounds 1–2 (72 hrs each), Rounds 3–5 (48 hrs each)
  • Eligibility: University students worldwide
  • Cost: Free

URL

prosperity.imc.com

What You Actually Build

A Python Trader class with a run() method. Each round introduces new tradeable products with different market dynamics. Your bot must:

  • Read the order book (bids/asks)
  • Decide what to buy/sell at what price
  • Manage positions within limits
  • Maximize "SeaShells" (the in-game currency = your score)

Core Concepts You Must Learn

ConceptWhy It Matters
Bid/Ask spreadHow markets work. You trade inside it to profit.
Order bookShows all pending orders at each price level
Market makingBuy at bid, sell at ask. Profit = spread.
Position limitsYou can't hold unlimited inventory — manage risk
Mean reversionPrices revert to fair value — exploit this
Pair tradingTwo correlated assets diverge → trade the spread

Winning Strategies — Deep Dive (From Top Solutions, Prosperity 2 & 3)

1. Market Making (Stable Assets — e.g., RainforestResin, Pearls ≈ 10,000)

Place bids just below fair value, asks just above. Simple. Reliable. Low-risk.

# If fair_value is known (stable asset):
orders.append(Order(product, fair_value - 1, buy_volume))   # bid
orders.append(Order(product, fair_value + 1, -sell_volume))  # ask

The "edge" is the distance between your trade price and true fair value. Maximize this consistently.

2. EMA Fair Value Estimation (Volatile Assets — e.g., Kelp)

When no fixed fair value exists, estimate it dynamically.

from collections import deque

class EMATrader:
    def __init__(self, window=8):
        self.prices = deque(maxlen=window)
        self.ema = None
        self.alpha = 2 / (window + 1)
    
    def update(self, mid_price):
        if self.ema is None:
            self.ema = mid_price
        else:
            self.ema = self.alpha * mid_price + (1 - self.alpha) * self.ema
    
    def signal(self, ask, bid):
        if ask < self.ema:   return "BUY"
        if bid > self.ema:   return "SELL"
        return "HOLD"

EMA window (~8 for Kelp) is a key tunable parameter — backtest it.

3. Mean Reversion with Z-Score (Squid Ink / High-Volatility Assets)

import numpy as np
from collections import deque

class ZScoreReversion:
    def __init__(self, short_window=5, long_window=20):
        self.short = deque(maxlen=short_window)
        self.long  = deque(maxlen=long_window)
    
    def update(self, price):
        self.short.append(price)
        self.long.append(price)
    
    def z_score(self):
        if len(self.long) < self.long.maxlen:
            return 0
        ema_short = np.mean(self.short)
        ema_long  = np.mean(self.long)
        std_long  = np.std(self.long) + 1e-9
        return (ema_short - ema_long) / std_long
    
    def signal(self, threshold=1.5):
        z = self.z_score()
        if z > threshold:   return "SELL"   # Overbought — reversion expected
        if z < -threshold:  return "BUY"    # Oversold — reversion expected
        return "HOLD"

4. Statistical / Index Arbitrage (Basket Products)

When a basket product trades at a price diverging from its components:

from sklearn.linear_model import LinearRegression
import numpy as np

# Fit weights of components to basket price
def fit_basket_weights(component_prices, basket_prices):
    model = LinearRegression(fit_intercept=True)
    model.fit(component_prices, basket_prices)
    return model

# At runtime: compute synthetic fair value
def basket_signal(model, component_prices, basket_mid, threshold=1.5):
    synthetic = model.predict(component_prices.reshape(1, -1))[0]
    spread = basket_mid - synthetic
    std = np.std(recent_spreads)  # rolling std of spread
    z = spread / (std + 1e-9)
    if z > threshold:   return "SELL basket"
    if z < -threshold:  return "BUY basket"
    return "HOLD"

Alpha Animals (2nd place USA, 9th globally, Prosperity 3) used this to achieve rank 2 in Round 2.

5. Options Pricing (Volcanic Rock Vouchers)

Treat competition vouchers as call options using Black-Scholes. Compute implied volatility from market prices and exploit deviations.

from scipy.stats import norm
import numpy as np

def black_scholes_call(S, K, T, r, sigma):
    """S=spot, K=strike, T=time to expiry, r=rate (0), sigma=IV"""
    d1 = (np.log(S/K) + (r + 0.5*sigma**2)*T) / (sigma*np.sqrt(T))
    d2 = d1 - sigma*np.sqrt(T)
    return S * norm.cdf(d1) - K * np.exp(-r*T) * norm.cdf(d2)

def implied_vol(market_price, S, K, T, r=0.0, tol=1e-5):
    """Invert Black-Scholes for IV using bisection."""
    lo, hi = 0.001, 5.0
    for _ in range(100):
        mid = (lo + hi) / 2
        if black_scholes_call(S, K, T, r, mid) > market_price:
            hi = mid
        else:
            lo = mid
        if hi - lo < tol:
            break
    return mid

6. Counterparty Anomaly Detection (Advanced — Round 5 Prosperity 3)

When counterparty data is revealed, track individual trader win rates.

  • Alpha Animals identified trader "Olivia" with a suspiciously high win rate in Squid Ink and Croissants
  • Copied her trades as a regime signal → significant P&L contribution
  • When you see a counterparty consistently profiting, follow them

Summary Table

StrategyAsset TypeRiskComplexity
Market makingStable (known fair value)LowLow
EMA fair valueModerately volatileMediumLow
Z-score mean reversionHighly volatileMediumMedium
Basket arbitrageIndex/basket productsMediumHigh
Options pricingVouchers/derivativesHighHigh
Counterparty copyingAnyMediumMedium

Python Skills Needed

  • Classes and object-oriented Python
  • Basic pandas / numpy
  • Understanding of deques (rolling windows)
  • Ability to write fast, stateless logic (no slow loops)

How Top Teams Approach Each Round

  1. Visualize first — clean and plot all price data with matplotlib; correlation heatmaps with seaborn before writing any strategy
  2. Backtest everything on historical data provided before deploying live
  3. Conservative position sizing first — many teams lost large amounts from bugs in position limit handling; test edge cases
  4. Beware 99% R² — suspiciously good linear regression = verify on held-out data immediately
  5. Implement hard risk controls — one position management bug can wipe rounds of profit (documented: 82,558 SeaShells lost in one round)
  6. Study prior-year repos — understand WHY those approaches worked, not just copy them
  7. Accept calculated risk — when trailing significantly, aggressive strategies are required for prize contention

Prosperity 3 — Round-by-Round Breakdown (Study This for P4)

Round 1: Rainforest Resin, Kelp, Squid Ink

ProductStrategyPnL (2nd place)
Rainforest ResinFixed fair value (~10,000) market making ±2.5 spread~39,000 SeaShells/round
Kelp8-period SMA as fair value; market make around deviation~5,000 SeaShells/round
Squid InkEMA z-score mean reversion OR volatility spike detection~8,000 SeaShells/round

2nd place (Frankfurt Hedgehogs) used "Wall Mid": (best_bid + best_ask)/2 as fair value proxy with inventory flattening when position skews.

Round 2: Basket Products (Picnic Basket 1 & 2, Croissants, Jams, Djembes)

  • Basket 1 = 6×Croissants + 3×Jams + 1×Djembe
  • Basket 2 = 4×Croissants + 2×Jams
  • Strategy: compute synthetic fair value → trade when basket diverges

Frankfurt Hedgehogs key insight: Baskets mean-revert vs synthetic value, but components do NOT move to match basket → trade baskets only, don't hedge with components.

def basket_arb(basket_mid, croissant_mid, jam_mid, djembe_mid, threshold=50):
    synthetic = 6*croissant_mid + 3*jam_mid + 1*djembe_mid
    spread = basket_mid - synthetic
    if spread > threshold:   return "SELL basket"
    if spread < -threshold:  return "BUY basket"
    return "HOLD"

Fixed threshold (±50) outperformed z-score for this product — stability over peak performance.

Round 3: Volcanic Rock + 5 Vouchers (Call Options)

This is the options round. Every top team used Black-Scholes.

from scipy.stats import norm
import numpy as np

def black_scholes_call(S, K, T, sigma, r=0.0):
    d1 = (np.log(S/K) + (r + 0.5*sigma**2)*T) / (sigma*np.sqrt(T) + 1e-9)
    d2 = d1 - sigma*np.sqrt(T)
    return S*norm.cdf(d1) - K*np.exp(-r*T)*norm.cdf(d2)

def implied_vol(market_price, S, K, T, r=0.0, tol=1e-5):
    lo, hi = 0.001, 5.0
    for _ in range(100):
        mid = (lo + hi) / 2
        if black_scholes_call(S, K, T, mid, r) > market_price: hi = mid
        else: lo = mid
        if hi - lo < tol: break
    return (lo + hi) / 2

# Greeks for risk management
def delta(S, K, T, sigma, r=0.0):
    d1 = (np.log(S/K) + (r + 0.5*sigma**2)*T) / (sigma*np.sqrt(T) + 1e-9)
    return norm.cdf(d1)

def gamma(S, K, T, sigma, r=0.0):
    d1 = (np.log(S/K) + (r + 0.5*sigma**2)*T) / (sigma*np.sqrt(T) + 1e-9)
    return norm.pdf(d1) / (S * sigma * np.sqrt(T) + 1e-9)

def vega(S, K, T, sigma, r=0.0):
    d1 = (np.log(S/K) + (r + 0.5*sigma**2)*T) / (sigma*np.sqrt(T) + 1e-9)
    return S * norm.pdf(d1) * np.sqrt(T)

Volatility smile exploitation (2nd place globally):

  1. Compute IV for each of the 5 strikes
  2. Plot IV vs moneyness ln(S/K)/√T → parabolic smile appears
  3. Fit parabola to the smile curve
  4. Trade vouchers whose IV deviates from the fitted curve (bet on reversion to the smile)

Round 4: Magnificent Macarons (Cross-Island Conversion)

  • Analyze local bid/ask vs foreign bid/ask accounting for transport fees + tariffs
  • Sunlight regime detection — low sunlight increases production costs → shift strategy:
    • Normal: two-way arbitrage
    • Low sunlight: accumulate long positions, minimize exports
  • Volume imbalance exploit: if best_bid_volume > 9 on local exchange, sell order at best ask guaranteed to fill

Round 5: All Products + Insider Detection

# Track counterparty win rate
class InsiderDetector:
    def __init__(self, window=50):
        self.trades = {}  # {trader_name: deque of (buy/sell, subsequent_price_move)}
        self.window = window
    
    def update(self, trader, direction, price_before, price_after):
        if trader not in self.trades:
            from collections import deque
            self.trades[trader] = deque(maxlen=self.window)
        profitable = (direction == 'BUY' and price_after > price_before) or \
                     (direction == 'SELL' and price_after < price_before)
        self.trades[trader].append(profitable)
    
    def win_rate(self, trader):
        if trader not in self.trades or len(self.trades[trader]) == 0:
            return 0.5
        return sum(self.trades[trader]) / len(self.trades[trader])
    
    def is_insider(self, trader, threshold=0.70):
        return self.win_rate(trader) > threshold

# Olivia had >70% win rate — copy her trades as regime signals

Backtesting Setup

Install the community-standard backtester:

pip install -U prosperity3bt
prosperity3bt algorithm.py 1             # all data from round 1
prosperity3bt algorithm.py 1 --vis       # auto-open visualizer
prosperity3bt algorithm.py 1 2 3         # multiple rounds

P3 Visualizer: jmerle.github.io/imc-prosperity-3-visualizer/


Prosperity 4 — Pre-Start Checklist (Before April 14)

[ ] pip install prosperity3bt and run all Prosperity 3 round data
[ ] Clone and read: github.com/TimoDiehm/imc-prosperity-3 (2nd globally)
[ ] Clone and read: github.com/CarterT27/imc-prosperity-3 (9th global, 2nd USA)
[ ] Implement Black-Scholes + Greeks from scratch (you will need this)
[ ] Implement implied vol solver (Newton-Raphson or bisection)
[ ] Build EMA + z-score mean reversion detector
[ ] Build market maker with inventory management
[ ] Build insider/counterparty win-rate tracker
[ ] Study Round 1 manual challenge patterns from Prosperity 2 and 3
[ ] Understand: basket fair value from components (linear regression)

Key Resources

ResourceURL
Frankfurt Hedgehogs — 2nd globally (code + blog)github.com/TimoDiehm/imc-prosperity-3
Alpha Animals — 9th global, 2nd USA (code)github.com/CarterT27/imc-prosperity-3
Community backtestergithub.com/jmerle/imc-prosperity-3-backtester
IMC Prosperity 3 writeup (Matius Chong)medium.com/@matius_chong/imc-prosperity-3-challenge-2025
IMC Prosperity 3 writeup (Martin Oravec, 73rd)medium.com/@oravec.martin01/imc-prosperity-3-be859180f133
Top 100 strategies explainedmedium.com/@shriyan.gosavi/how-i-placed-top-100-in-the-imc-trading-challenge
Official platformprosperity.imc.com

Career Value

  • IMC actively recruits from top performers
  • Converts to intern/full-time interviews at IMC Trading
  • Also recognized by Jane Street, Citadel, Two Sigma recruiters
  • Shows quant + engineering hybrid skillset

Preparation Checklist

  • Read "what is an order book" (15 min)
  • Study market making concept
  • Clone a past Prosperity GitHub repo and understand the structure
  • Practice: write a simple EMA-based bot
  • Form team of 2–3 people with different strengths (algo, manual trading, math)