Skip to content

Instantly share code, notes, and snippets.

@yongkangc
Created January 27, 2026 16:15
Show Gist options
  • Select an option

  • Save yongkangc/c6bb844cb32ba807b0450a63e076132c to your computer and use it in GitHub Desktop.

Select an option

Save yongkangc/c6bb844cb32ba807b0450a63e076132c to your computer and use it in GitHub Desktop.
pm-mm-rs Paper Trading Fill Logic

Paper Trading Fill Logic - pm-mm-rs

Overview

The paper trading system simulates realistic order fills using PaperVenue which wraps MockVenue. Fills are triggered when real-time Polymarket book updates cross resting order prices.

Two Fill Types

1. Aggressive Fills (Crossing the Spread)

When your order is immediately marketable:

  • Buy fills when: order.price >= best_ask * (1 + slippage)
  • Sell fills when: order.price <= best_bid * (1 - slippage)

Fill price calculation (adverse selection):

// Buys get the WORSE of limit price or slipped ask
fill_price = min(order_price, ask * (1 + slip))

// Sells get the WORSE of limit price or slipped bid  
fill_price = max(order_price, bid * (1 - slip))

This models the reality that aggressive orders typically get worse execution than their limit.

2. Passive Fills (Providing Liquidity)

For orders that improve the book (set new best bid/ask):

  • Triggers if: random() < passive_fill_prob AND order improves book
  • Fill price: Your limit price (favorable execution)

This models the case where a market taker hits your resting order.

Latency Simulation

Both fill types wait latency_ms before executing, then re-check if the order is still marketable at the current book state. This prevents fills that would have been cancelled in real trading.

Configuration Parameters

Parameter Default Description
slippage_bps 10 Slippage in basis points for aggressive fills
passive_fill_prob 0.1 Probability (0-1) of passive fills when improving book
latency_ms 100 Simulated execution delay in milliseconds

Code References

  • Main matching loop: src/venue/paper.rs#L51-L126
  • Aggressive fill price calc: src/venue/paper.rs#L159-L170
  • Passive fill execution: src/venue/paper.rs#L175-L190
  • MockVenue state management: src/venue/mock.rs

Flow Diagram

BookUpdate (from Polymarket WS)
    │
    ▼
PaperVenue::on_book_update()
    │
    ├─► Check each resting order
    │       │
    │       ├─► Is marketable? (price crosses spread + slippage)
    │       │       │
    │       │       └─► Yes: Schedule aggressive fill after latency
    │       │
    │       └─► Is improving book AND random < passive_fill_prob?
    │               │
    │               └─► Yes: Schedule passive fill after latency
    │
    ▼
After latency_ms sleep:
    │
    ├─► Re-check if still marketable (book may have moved)
    │
    └─► Execute fill at calculated price
            │
            ▼
        Emit Event::Fill to engine
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment