Skip to content

Filtered order book view with binary market support #3559

@cjdsellers

Description

@cjdsellers

Problem Statement

When trading binary prediction markets (e.g. Polymarket), the public order book reflects liquidity from both YES and NO sides due to price parity (YES + NO = $1.00). To see true available liquidity, you need to filter out your own orders — including orders on the opposite token, transformed via the parity relationship.

Currently, OrderBook only offers bids_filtered_as_map() / asks_filtered_as_map() which return raw IndexMaps. This means you lose access to all utility methods on the filtered result (get_avg_px_for_quantity(), simulate_fills(), spread(), midpoint(), etc.).

PR #3495 attempts to solve this with a BinaryMarketBookView struct, but it conflates two concerns (combining own books + filtering the public book) into a single binary-market-specific type (this was an initial suggestion from myself).

Proposed Solution

Separate into two composable pieces:

1. OrderBook::filtered_view() — general purpose, useful for any market

Returns a new OrderBook with own orders subtracted from the public book.

impl OrderBook {
    pub fn filtered_view(
        &self,
        own_book: Option<&OwnOrderBook>,
        depth: Option<usize>,
        status: Option<AHashSet<OrderStatus>>,
        accepted_buffer_ns: Option<u64>,
        now: Option<u64>,
    ) -> OrderBook
}

2. OwnOrderBook::combined_with_opposite() — binary market specific

Combines own orders from both tokens, transforming the opposite side's prices using (1 - price) parity.

impl OwnOrderBook {
    pub fn combined_with_opposite(&self, opposite: &OwnOrderBook) -> OwnOrderBook
}

Example Usage

// Combine own orders from both sides (YES + transformed NO)
let combined_own = own_book_yes.combined_with_opposite(&own_book_no);

// Get filtered view of public book
let filtered = public_book.filtered_view(Some(&combined_own), depth, ...);

// Now use any utility method on the result
let avg_px = filtered.get_avg_px_for_quantity(side, quantity);
let fills = filtered.simulate_fills(order);

Alternatives Considered

  • BinaryMarketBookView struct (PR Add synthetic book support for binary markets #3495) — combines both concerns into a single binary-market-specific type. Rejected because filtered_view() is generally useful for any market, and the reconstruction cost is harder to optimize when the concerns are coupled.
  • Returning filtered IndexMaps (current approach) — works but loses access to all OrderBook utility methods, forcing users to reimplement common calculations.

Additional Context

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    Status

    Backlog

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions