Skip to content

polymarket clob book: orderbook table shows worst prices first (best bid/ask buried at bottom) #75

Description

@Nexory

polymarket clob book <token> prints the bids and asks tables in raw API order (src/output/clob/books.rs:34-66). The API returns:

  • bids in ascending price order (lowest bid first)
  • asks in descending price order (highest ask first)

The CLI just iterates result.bids.iter() / result.asks.iter() straight into a tabled::Table, so what the user sees is:

Bids:
┌───────┬────────────┐
│ Price │ Size       │
├───────┼────────────┤
│ 0.001 │ 1218691.83 │   ← worst bid (top)
│ 0.002 │ 538822.20  │
│ ...   │            │
│ 0.008 │ 3905.98    │   ← BEST bid (bottom)
└───────┴────────────┘

Asks:
┌───────┬────────────┐
│ Price │ Size       │
├───────┼────────────┤
│ 0.999 │ 3139845.17 │   ← worst ask (top)
│ ...   │            │
│ 0.009 │ 312.07     │   ← BEST ask (bottom)
└───────┴────────────┘

(reproduced against the BTC $150k by June 30 market; same ordering verified against 2 other high-volume markets — the API behavior is consistent.)

Both best prices end up at the bottom of their respective tables, which is the opposite of what a CLI user usually wants to see first. The non-obvious ordering is also documented in Polymarket/rs-clob-client#330, which calls out the same mismatch in the V1 Rust SDK.

JSON output (OutputFormat::Json) should keep the API order so programmatic consumers stay backward-compatible — this is only about the human-facing table.

Suggested fix

Option A — minimal change (best-first per side): reverse bids (already-correct asks stay as-is so the best ask sits at the bottom adjacent to the best bid):

let rows: Vec<Row> = result.bids.iter().rev()  // best bid first
    .map(|o| Row { price: ..., size: ... })
    .collect();

Option B — depth-ladder layout: print asks first (descending → best ask at bottom of asks), then bids reversed (descending → best bid at top of bids), so the spread sits in the middle:

Asks:
  0.999
  ...
  0.009   ← best ask
──────── spread
Bids:
  0.008   ← best bid
  ...
  0.001

This matches the convention used by TradingView, Binance, Kraken, and most other exchange UIs.

Happy to send a small PR with whichever option fits the project direction.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions