Skip to main content

polymarket_bindings/clob/
order_book.rs

1use polymarket_types::{CtfConditionId, DecimalString, TokenId};
2use serde::Deserialize;
3
4use crate::de::deserialize_decimalish;
5
6#[derive(Clone, Debug, PartialEq, Deserialize)]
7pub struct OrderBookLevel {
8    #[serde(deserialize_with = "deserialize_decimalish")]
9    pub price: Option<String>,
10    #[serde(deserialize_with = "deserialize_decimalish")]
11    pub size: Option<String>,
12}
13
14#[derive(Clone, Debug, PartialEq)]
15pub struct OrderBook {
16    pub market: CtfConditionId,
17    pub token_id: TokenId,
18    pub timestamp: Option<i64>,
19    pub bids: Vec<OrderBookLevel>,
20    pub asks: Vec<OrderBookLevel>,
21    pub min_order_size: DecimalString,
22    pub tick_size: DecimalString,
23    pub neg_risk: bool,
24    pub last_trade_price: Option<DecimalString>,
25    pub hash: String,
26}
27
28#[derive(Debug, Deserialize)]
29struct OrderBookRaw {
30    market: String,
31    asset_id: String,
32    timestamp: Option<String>,
33    bids: Vec<OrderBookLevel>,
34    asks: Vec<OrderBookLevel>,
35    #[serde(rename = "min_order_size", deserialize_with = "deserialize_decimalish")]
36    min_order_size: Option<String>,
37    #[serde(rename = "tick_size", deserialize_with = "deserialize_decimalish")]
38    tick_size: Option<String>,
39    neg_risk: bool,
40    #[serde(
41        rename = "last_trade_price",
42        default,
43        deserialize_with = "deserialize_decimalish"
44    )]
45    last_trade_price: Option<String>,
46    hash: String,
47}
48
49impl OrderBook {
50    fn from_raw(raw: OrderBookRaw) -> Result<Self, String> {
51        let market = CtfConditionId::parse(raw.market).map_err(|e| e.message)?;
52        let token_id = TokenId::parse(raw.asset_id).map_err(|e| e.message)?;
53        let timestamp = raw.timestamp.and_then(|t| t.parse().ok());
54        let min_order_size = raw
55            .min_order_size
56            .and_then(|v| DecimalString::parse(v).ok())
57            .ok_or_else(|| "missing min_order_size".to_string())?;
58        let tick_size = raw
59            .tick_size
60            .and_then(|v| DecimalString::parse(v).ok())
61            .ok_or_else(|| "missing tick_size".to_string())?;
62        let last_trade_price = raw
63            .last_trade_price
64            .and_then(|v| DecimalString::parse(v).ok());
65
66        Ok(Self {
67            market,
68            token_id,
69            timestamp,
70            bids: raw.bids,
71            asks: raw.asks,
72            min_order_size,
73            tick_size,
74            neg_risk: raw.neg_risk,
75            last_trade_price,
76            hash: raw.hash,
77        })
78    }
79}
80
81impl<'de> Deserialize<'de> for OrderBook {
82    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
83    where
84        D: serde::Deserializer<'de>,
85    {
86        let raw = OrderBookRaw::deserialize(deserializer)?;
87        Self::from_raw(raw).map_err(serde::de::Error::custom)
88    }
89}