1use chrono::{DateTime, Utc};
2use serde::{Deserialize, Serialize};
3use std::fmt;
4use std::str::FromStr;
5
6#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
13#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
14#[serde(rename_all = "lowercase")]
15pub enum OrderType {
16 Gtc,
17 Ioc,
18 Fok,
19}
20
21impl FromStr for OrderType {
22 type Err = String;
23
24 fn from_str(s: &str) -> Result<Self, Self::Err> {
25 match s.trim().to_ascii_lowercase().as_str() {
26 "gtc" => Ok(Self::Gtc),
27 "ioc" => Ok(Self::Ioc),
28 "fok" => Ok(Self::Fok),
29 other => Err(format!(
30 "invalid order_type '{other}' (allowed: gtc, ioc, fok)"
31 )),
32 }
33 }
34}
35
36impl fmt::Display for OrderType {
37 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
38 match self {
39 Self::Gtc => f.write_str("gtc"),
40 Self::Ioc => f.write_str("ioc"),
41 Self::Fok => f.write_str("fok"),
42 }
43 }
44}
45
46#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
47#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
48#[serde(rename_all = "lowercase")]
49pub enum OrderSide {
50 Buy,
51 Sell,
52}
53
54#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
55#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
56#[serde(rename_all = "lowercase")]
57pub enum LiquidityRole {
58 Maker,
59 Taker,
60}
61
62#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
63#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
64#[serde(rename_all = "snake_case")]
65pub enum OrderStatus {
66 Pending,
67 Open,
68 Filled,
69 PartiallyFilled,
70 Cancelled,
71 Rejected,
72}
73
74#[derive(Debug, Clone, Serialize, Deserialize)]
75#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
76pub struct Order {
81 pub id: String,
82 pub market_id: String,
83 pub outcome: String,
84 pub side: OrderSide,
85 pub price: f64,
86 pub size: f64,
87 pub filled: f64,
88 pub status: OrderStatus,
89 pub created_at: DateTime<Utc>,
90 #[serde(default)]
91 pub updated_at: Option<DateTime<Utc>>,
92}
93
94impl Order {
95 pub fn remaining(&self) -> f64 {
96 self.size - self.filled
97 }
98
99 pub fn is_active(&self) -> bool {
100 matches!(
101 self.status,
102 OrderStatus::Open | OrderStatus::PartiallyFilled
103 )
104 }
105
106 pub fn is_filled(&self) -> bool {
107 self.status == OrderStatus::Filled || self.filled >= self.size
108 }
109
110 pub fn fill_percentage(&self) -> f64 {
111 if self.size == 0.0 {
112 return 0.0;
113 }
114 self.filled / self.size
115 }
116}
117
118#[derive(Debug, Clone, Serialize, Deserialize)]
120#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
121pub struct Fill {
122 pub fill_id: String,
123 pub order_id: String,
124 pub market_id: String,
125 pub outcome: String,
126 pub side: OrderSide,
127 pub price: f64,
128 pub size: f64,
129 pub is_taker: bool,
130 pub fee: f64,
131 pub created_at: DateTime<Utc>,
132}
133
134