Polymarket Bot Tutorial · Chapter 17 of 32

Use Polymarket order book imbalance as a short-term price signal: bid-ask volume ratio, microprice computation, signal half-life, and when imbalance bots beat random execution.

What this chapter covers

Order-book imbalance is the ratio of buy-side depth to sell-side depth on the limit order book. On Polymarket it has a real but short-lived predictive edge - typically 5-30 seconds before the mid moves. This chapter is the computation pattern and the conditions under which the signal lies.

  • What order book imbalance is
  • Microprice computation
  • Imbalance as a directional signal
  • Signal half-life on Polymarket
  • When imbalance signals lie
  • Code: compute imbalance every WS tick

What order book imbalance is

Order book imbalance is the ratio of total buy-side depth to total sell-side depth on the limit order book. Computed at the top-N levels (commonly N=5), it captures aggregate trader pressure that the mid-price has not yet reflected.

Formula: imbalance = (Σ bid[i].price × bid[i].size for i in [0..N]) − (Σ ask[i].price × ask[i].size) / (Σ both). Range -1 to +1; positive means more buy pressure, negative means more sell pressure.

The signal is empirically real on Polymarket but noisy. A single whale can fake-print imbalance for 30-60 seconds before being arbed out. Useful as one feature among several, dangerous as a sole trigger.

Microprice computation

The microprice is a refinement of the simple mid: a weighted average of best bid and best ask, weighted by their respective sizes.

microprice = (best_bid × ask_size + best_ask × bid_size) / (bid_size + ask_size)

When the bid-side queue is much larger than the ask side, the microprice sits closer to the ask. The intuition: more buyers waiting means the next trade is more likely to lift the ask, so fair value is closer to the ask.

Microprice is a 5-30 second leading indicator of the actual mid moving. Production bots use it as the reference price for take-profit decisions instead of the naive mid.

Imbalance as a directional signal

From production observation: when imbalance flips from -0.3 to +0.5 in 10 seconds without an accompanying news event, the mid moves up by 1-2 cents within the next 30-60 seconds about 65% of the time.

That's a real edge but it dissolves at small position sizes after fees. To monetize, the bot must size enough to capture the move minus fees, but small enough not to move the book itself. Polymarket's books are typically thin enough that anything over 50 shares moves the market.

Combine imbalance with other features: trade velocity (more trades = real signal), best-bid actually moving up (not just depth shifting), market not in news-driven mode.

Signal half-life on Polymarket

The imbalance signal decays. Production data from our trader: imbalance > 0.6 → expected mid move of 1.2c within 60s, half-life of ~30s. After 90 seconds the predictive value has gone to zero.

Implication for bot design: react quickly or skip. A bot that takes 15 seconds to decide is consuming half the edge before placing the order. Latency budget for imbalance strategies should be under 5 seconds from signal to FOK fired.

Strategies that hold positions for longer than the half-life (1-2 minutes) are gambling on the next signal, not the current one. Be explicit about this; don't accidentally hold imbalance-driven positions to resolution.

When imbalance signals lie

The signal misleads when one of three conditions holds.

  • News-driven move: the imbalance is a consequence of news that you have not seen. Trading against it loses; trading with it is news arbitrage, a different strategy.
  • Whale spoofing: a large order placed and quickly cancelled creates fake imbalance for the duration. Filter by checking that the imbalance persists for 10+ seconds before triggering.
  • End-of-period rebalancing: market makers pulling quotes for inventory reasons rather than information reasons. The imbalance reverses minutes later when MM re-quotes.

The combined filter is: imbalance > threshold AND trade velocity > baseline AND no news event in last 5 minutes. Each filter alone has too many false positives.

Code: compute imbalance every WS tick

Reference: subscribe to WebSocket book updates, recompute imbalance on every tick.

def on_book_message(msg):
    bids = msg.get("bids", [])[:5]
    asks = msg.get("asks", [])[:5]
    bid_usd = sum(float(b["price"]) * float(b["size"]) for b in bids)
    ask_usd = sum(float(a["price"]) * float(a["size"]) for a in asks)
    total = bid_usd + ask_usd
    if total < 100: return  # illiquid
    imb = (bid_usd - ask_usd) / total
    state[msg["asset_id"]] = {
        "imb": imb,
        "best_bid": float(bids[0]["price"]) if bids else 0,
        "best_ask": float(asks[0]["price"]) if asks else 1,
        "ts": time.time()
    }
    # decision logic with cooldown + filters
    if imb > 0.6 and time.time() - last_fired.get(msg["asset_id"], 0) > 60:
        check_filters_and_maybe_fire(msg["asset_id"])

State is per-token. Cooldown prevents over-firing on the same signal. Filters (news check, trade velocity) gate the actual trade.

Frequently asked questions

What is order book imbalance?
The ratio of bid volume to ask volume at the top of the book. A heavily bid-skewed book (more buyers than sellers near the touch) suggests upward price pressure in the very short term. The signal is well-known in crypto and equities; on Polymarket it works in liquid markets but disappears in thin ones.
How do I compute the microprice?
microprice = (best_ask * bid_size + best_bid * ask_size) / (bid_size + ask_size). It is a volume-weighted version of mid-price that leans toward the side with less volume - the side that is "running out" first. Bots use it as a fair-value estimate that incorporates imbalance.
What is the half-life of an imbalance signal on Polymarket?
In active markets, 5-30 seconds. In thin markets, longer (because new orders take longer to overwhelm the imbalance). If your bot reacts in under a second, you can capture some of it. If it reacts in 5+ seconds, you are usually too late.
When does imbalance lie?
When a single large order is sitting on one side waiting to be hit (one big resting bid, no other activity). The imbalance is real but it does not predict price - it just shows one motivated buyer. Filter by counting orders, not just volume: imbalance N orders to 1 order is more informative than 5x volume across 1 order each.
Is order book imbalance enough to trade alone?
Usually no. As a standalone signal it is weak and gets arbitraged. Combine with another signal (e.g., macroprice mean reversion, news flag, or sports state) for a more durable edge. Imbalance alone tends to underperform random execution after fees.
What Python library can compute imbalance from Polymarket WS?
No off-the-shelf library that we know of - it is a few dozen lines of code. Subscribe via py-clob-client to the market book, on each price_change event recompute top-of-book bid/ask sizes, and emit your imbalance metric. Cache the last value and only re-trigger on meaningful changes.