polyte_data/
types.rs

1use serde::{Deserialize, Serialize};
2
3/// User's total position value
4#[derive(Debug, Clone, Serialize, Deserialize)]
5pub struct UserValue {
6    /// User address
7    pub user: String,
8    /// Total value of positions
9    pub value: f64,
10}
11
12/// Open interest for a market
13#[derive(Debug, Clone, Serialize, Deserialize)]
14pub struct OpenInterest {
15    /// Market condition ID
16    pub market: String,
17    /// Open interest value
18    pub value: f64,
19}
20
21/// Sort field options for position queries
22#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
23#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
24pub enum PositionSortBy {
25    /// Sort by current value
26    Current,
27    /// Sort by initial value
28    Initial,
29    /// Sort by token count
30    Tokens,
31    /// Sort by cash P&L
32    CashPnl,
33    /// Sort by percentage P&L
34    PercentPnl,
35    /// Sort by market title
36    Title,
37    /// Sort by resolving status
38    Resolving,
39    /// Sort by price
40    Price,
41    /// Sort by average price
42    AvgPrice,
43}
44
45impl std::fmt::Display for PositionSortBy {
46    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
47        match self {
48            Self::Current => write!(f, "CURRENT"),
49            Self::Initial => write!(f, "INITIAL"),
50            Self::Tokens => write!(f, "TOKENS"),
51            Self::CashPnl => write!(f, "CASHPNL"),
52            Self::PercentPnl => write!(f, "PERCENTPNL"),
53            Self::Title => write!(f, "TITLE"),
54            Self::Resolving => write!(f, "RESOLVING"),
55            Self::Price => write!(f, "PRICE"),
56            Self::AvgPrice => write!(f, "AVGPRICE"),
57        }
58    }
59}
60
61/// Sort direction for queries
62#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, Default)]
63#[serde(rename_all = "UPPERCASE")]
64pub enum SortDirection {
65    /// Ascending order
66    Asc,
67    /// Descending order (default)
68    #[default]
69    Desc,
70}
71
72impl std::fmt::Display for SortDirection {
73    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
74        match self {
75            Self::Asc => write!(f, "ASC"),
76            Self::Desc => write!(f, "DESC"),
77        }
78    }
79}
80
81/// Sort field options for closed position queries
82#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, Default)]
83#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
84pub enum ClosedPositionSortBy {
85    /// Sort by realized P&L (default)
86    #[default]
87    RealizedPnl,
88    /// Sort by market title
89    Title,
90    /// Sort by price
91    Price,
92    /// Sort by average price
93    AvgPrice,
94    /// Sort by timestamp
95    Timestamp,
96}
97
98impl std::fmt::Display for ClosedPositionSortBy {
99    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
100        match self {
101            Self::RealizedPnl => write!(f, "REALIZEDPNL"),
102            Self::Title => write!(f, "TITLE"),
103            Self::Price => write!(f, "PRICE"),
104            Self::AvgPrice => write!(f, "AVGPRICE"),
105            Self::Timestamp => write!(f, "TIMESTAMP"),
106        }
107    }
108}
109
110/// Closed position record
111#[derive(Debug, Clone, Serialize, Deserialize)]
112#[serde(rename_all(deserialize = "camelCase"))]
113pub struct ClosedPosition {
114    /// Proxy wallet address
115    pub proxy_wallet: String,
116    /// Asset identifier (token ID)
117    pub asset: String,
118    /// Condition ID of the market
119    pub condition_id: String,
120    /// Average entry price
121    pub avg_price: f64,
122    /// Total amount bought
123    pub total_bought: f64,
124    /// Realized profit and loss
125    pub realized_pnl: f64,
126    /// Current market price
127    pub cur_price: f64,
128    /// Timestamp when position was closed
129    pub timestamp: i64,
130    /// Market title
131    pub title: String,
132    /// Market slug
133    pub slug: String,
134    /// Market icon URL
135    pub icon: Option<String>,
136    /// Event slug
137    pub event_slug: Option<String>,
138    /// Outcome name (e.g., "Yes", "No")
139    pub outcome: String,
140    /// Outcome index (0 or 1 for binary markets)
141    pub outcome_index: u32,
142    /// Opposite outcome name
143    pub opposite_outcome: String,
144    /// Opposite outcome asset ID
145    pub opposite_asset: String,
146    /// Market end date
147    pub end_date: Option<String>,
148}
149
150/// Trade side (buy or sell)
151#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
152#[serde(rename_all = "UPPERCASE")]
153pub enum TradeSide {
154    /// Buy order
155    Buy,
156    /// Sell order
157    Sell,
158}
159
160impl std::fmt::Display for TradeSide {
161    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
162        match self {
163            Self::Buy => write!(f, "BUY"),
164            Self::Sell => write!(f, "SELL"),
165        }
166    }
167}
168
169/// Filter type for trade queries
170#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
171#[serde(rename_all = "UPPERCASE")]
172pub enum TradeFilterType {
173    /// Filter by cash amount
174    Cash,
175    /// Filter by token amount
176    Tokens,
177}
178
179impl std::fmt::Display for TradeFilterType {
180    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
181        match self {
182            Self::Cash => write!(f, "CASH"),
183            Self::Tokens => write!(f, "TOKENS"),
184        }
185    }
186}
187
188/// Trade record
189#[derive(Debug, Clone, Serialize, Deserialize)]
190#[serde(rename_all(deserialize = "camelCase"))]
191pub struct Trade {
192    /// Proxy wallet address
193    pub proxy_wallet: String,
194    /// Trade side (BUY or SELL)
195    pub side: TradeSide,
196    /// Asset identifier (token ID)
197    pub asset: String,
198    /// Condition ID of the market
199    pub condition_id: String,
200    /// Trade size (number of shares)
201    pub size: f64,
202    /// Trade price
203    pub price: f64,
204    /// Trade timestamp
205    pub timestamp: i64,
206    /// Market title
207    pub title: String,
208    /// Market slug
209    pub slug: String,
210    /// Market icon URL
211    pub icon: Option<String>,
212    /// Event slug
213    pub event_slug: Option<String>,
214    /// Outcome name (e.g., "Yes", "No")
215    pub outcome: String,
216    /// Outcome index (0 or 1 for binary markets)
217    pub outcome_index: u32,
218    /// User display name
219    pub name: Option<String>,
220    /// User pseudonym
221    pub pseudonym: Option<String>,
222    /// User bio
223    pub bio: Option<String>,
224    /// User profile image URL
225    pub profile_image: Option<String>,
226    /// Optimized profile image URL
227    pub profile_image_optimized: Option<String>,
228    /// Transaction hash
229    pub transaction_hash: Option<String>,
230}
231
232/// Activity type
233#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
234#[serde(rename_all = "UPPERCASE")]
235pub enum ActivityType {
236    /// Trade activity
237    Trade,
238    /// Split activity
239    Split,
240    /// Merge activity
241    Merge,
242    /// Redeem activity
243    Redeem,
244    /// Reward activity
245    Reward,
246    /// Conversion activity
247    Conversion,
248}
249
250impl std::fmt::Display for ActivityType {
251    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
252        match self {
253            Self::Trade => write!(f, "TRADE"),
254            Self::Split => write!(f, "SPLIT"),
255            Self::Merge => write!(f, "MERGE"),
256            Self::Redeem => write!(f, "REDEEM"),
257            Self::Reward => write!(f, "REWARD"),
258            Self::Conversion => write!(f, "CONVERSION"),
259        }
260    }
261}
262
263/// Sort field options for activity queries
264#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, Default)]
265#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
266pub enum ActivitySortBy {
267    /// Sort by timestamp (default)
268    #[default]
269    Timestamp,
270    /// Sort by token amount
271    Tokens,
272    /// Sort by cash amount
273    Cash,
274}
275
276impl std::fmt::Display for ActivitySortBy {
277    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
278        match self {
279            Self::Timestamp => write!(f, "TIMESTAMP"),
280            Self::Tokens => write!(f, "TOKENS"),
281            Self::Cash => write!(f, "CASH"),
282        }
283    }
284}
285
286/// User activity record
287#[derive(Debug, Clone, Serialize, Deserialize)]
288#[serde(rename_all(deserialize = "camelCase"))]
289pub struct Activity {
290    /// Proxy wallet address
291    pub proxy_wallet: String,
292    /// Activity timestamp
293    pub timestamp: i64,
294    /// Condition ID of the market
295    pub condition_id: String,
296    /// Activity type
297    #[serde(rename = "type")]
298    pub activity_type: ActivityType,
299    /// Token quantity
300    pub size: f64,
301    /// USD value
302    pub usdc_size: f64,
303    /// On-chain transaction hash
304    pub transaction_hash: Option<String>,
305    /// Execution price
306    pub price: Option<f64>,
307    /// Asset identifier (token ID)
308    pub asset: Option<String>,
309    // ! Deserialize into String because the API can return an empty string
310    /// Trade side (BUY or SELL)
311    pub side: Option<String>,
312    /// Outcome index (0 or 1 for binary markets)
313    pub outcome_index: Option<u32>,
314    /// Market title
315    pub title: Option<String>,
316    /// Market slug
317    pub slug: Option<String>,
318    /// Market icon URL
319    pub icon: Option<String>,
320    /// Outcome name (e.g., "Yes", "No")
321    pub outcome: Option<String>,
322    /// User display name
323    pub name: Option<String>,
324    /// User pseudonym
325    pub pseudonym: Option<String>,
326    /// User bio
327    pub bio: Option<String>,
328    /// User profile image URL
329    pub profile_image: Option<String>,
330    /// Optimized profile image URL
331    pub profile_image_optimized: Option<String>,
332}
333
334/// User position in a market
335#[derive(Debug, Clone, Serialize, Deserialize)]
336#[serde(rename_all(deserialize = "camelCase"))]
337pub struct Position {
338    /// Proxy wallet address
339    pub proxy_wallet: String,
340    /// Asset identifier (token ID)
341    pub asset: String,
342    /// Condition ID of the market
343    pub condition_id: String,
344    /// Position size (number of shares)
345    pub size: f64,
346    /// Average entry price
347    pub avg_price: f64,
348    /// Initial value of position
349    pub initial_value: f64,
350    /// Current value of position
351    pub current_value: f64,
352    /// Cash profit and loss
353    pub cash_pnl: f64,
354    /// Percentage profit and loss
355    pub percent_pnl: f64,
356    /// Total amount bought
357    pub total_bought: f64,
358    /// Realized profit and loss
359    pub realized_pnl: f64,
360    /// Percentage realized P&L
361    pub percent_realized_pnl: f64,
362    /// Current market price
363    pub cur_price: f64,
364    /// Whether position is redeemable
365    pub redeemable: bool,
366    /// Whether position is mergeable
367    pub mergeable: bool,
368    /// Market title
369    pub title: String,
370    /// Market slug
371    pub slug: String,
372    /// Market icon URL
373    pub icon: Option<String>,
374    /// Event slug
375    pub event_slug: Option<String>,
376    /// Outcome name (e.g., "Yes", "No")
377    pub outcome: String,
378    /// Outcome index (0 or 1 for binary markets)
379    pub outcome_index: u32,
380    /// Opposite outcome name
381    pub opposite_outcome: String,
382    /// Opposite outcome asset ID
383    pub opposite_asset: String,
384    /// Market end date
385    pub end_date: Option<String>,
386    /// Whether this is a negative risk market
387    pub negative_risk: bool,
388}