Skip to main content

px_core/models/
trade.rs

1use chrono::{DateTime, Utc};
2use serde::{Deserialize, Serialize};
3
4#[derive(Debug, Clone, Serialize, Deserialize)]
5pub struct PublicTrade {
6    pub proxy_wallet: String,
7    pub side: String,
8    pub asset: String,
9    pub condition_id: String,
10    pub size: f64,
11    pub price: f64,
12    pub timestamp: DateTime<Utc>,
13    #[serde(default, skip_serializing_if = "Option::is_none")]
14    pub title: Option<String>,
15    #[serde(default, skip_serializing_if = "Option::is_none")]
16    pub slug: Option<String>,
17    #[serde(default, skip_serializing_if = "Option::is_none")]
18    pub icon: Option<String>,
19    #[serde(default, skip_serializing_if = "Option::is_none")]
20    pub event_slug: Option<String>,
21    #[serde(default, skip_serializing_if = "Option::is_none")]
22    pub outcome: Option<String>,
23    #[serde(default, skip_serializing_if = "Option::is_none")]
24    pub outcome_index: Option<u32>,
25    #[serde(default, skip_serializing_if = "Option::is_none")]
26    pub name: Option<String>,
27    #[serde(default, skip_serializing_if = "Option::is_none")]
28    pub pseudonym: Option<String>,
29    #[serde(default, skip_serializing_if = "Option::is_none")]
30    pub bio: Option<String>,
31    #[serde(default, skip_serializing_if = "Option::is_none")]
32    pub profile_image: Option<String>,
33    #[serde(default, skip_serializing_if = "Option::is_none")]
34    pub profile_image_optimized: Option<String>,
35    #[serde(default, skip_serializing_if = "Option::is_none")]
36    pub transaction_hash: Option<String>,
37}
38
39/// A public trade off the market tape.
40#[derive(Debug, Clone, Serialize, Deserialize)]
41#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
42pub struct MarketTrade {
43    /// Globally-unique exchange trade id (e.g. `"t-9c2..."`).
44    pub id: String,
45    /// Trade price as YES probability in `[0, 1]` (e.g. `0.62`).
46    pub price: f64,
47    /// Filled size in contracts (e.g. `25.0`).
48    pub size: f64,
49    /// Direction of the taker relative to YES. Options: `buy`, `sell`; `null` when unknown.
50    #[serde(default, skip_serializing_if = "Option::is_none")]
51    pub aggressor_side: Option<String>,
52    /// Upstream trade time in UTC (e.g. `"2026-04-25T12:00:00Z"`).
53    pub exchange_ts: DateTime<Utc>,
54    /// Wall-clock time OpenPX served the trade (UTC).
55    pub openpx_ts: DateTime<Utc>,
56    /// Outcome label (e.g. `"Yes"`, `"No"`); `null` when not exposed.
57    #[serde(default, skip_serializing_if = "Option::is_none")]
58    pub outcome: Option<String>,
59    /// YES-side reference price for binary markets (e.g. `0.62`).
60    #[serde(default, skip_serializing_if = "Option::is_none")]
61    pub yes_price: Option<f64>,
62    /// NO-side reference price for binary markets (e.g. `0.38`).
63    #[serde(default, skip_serializing_if = "Option::is_none")]
64    pub no_price: Option<f64>,
65    /// Polymarket taker wallet address (e.g. `"0x..."`); `null` on Kalshi.
66    #[serde(default, skip_serializing_if = "Option::is_none")]
67    pub taker_address: Option<String>,
68}