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.
polymarket clob book <token>prints the bids and asks tables in raw API order (src/output/clob/books.rs:34-66). The API returns:bidsin ascending price order (lowest bid first)asksin descending price order (highest ask first)The CLI just iterates
result.bids.iter()/result.asks.iter()straight into atabled::Table, so what the user sees is:(reproduced against the BTC
$150k by June 30market; 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):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:
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.