1use serde::{Deserialize, Serialize};
2use std::fmt;
3
4pub mod order_action {
9 pub const BUY: &str = "ORDER_ACTION_BUY";
10 pub const SELL: &str = "ORDER_ACTION_SELL";
11}
12
13pub mod order_type {
14 pub const LIMIT: &str = "ORDER_TYPE_LIMIT";
15}
16
17pub mod tif {
18 pub const GTC: &str = "TIME_IN_FORCE_GOOD_TILL_CANCEL";
19 pub const GTD: &str = "TIME_IN_FORCE_GOOD_TILL_DATE";
20 pub const FAK: &str = "TIME_IN_FORCE_IMMEDIATE_OR_CANCEL";
21 pub const FOK: &str = "TIME_IN_FORCE_FILL_OR_KILL";
22}
23
24pub mod outcome {
25 pub const LONG: &str = "LONG";
26 pub const SHORT: &str = "SHORT";
27}
28
29#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
35#[non_exhaustive]
36pub enum OrderAction {
37 #[serde(rename = "ORDER_ACTION_BUY")]
38 Buy,
39 #[serde(rename = "ORDER_ACTION_SELL")]
40 Sell,
41}
42
43impl fmt::Display for OrderAction {
44 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
45 match self {
46 Self::Buy => f.write_str("ORDER_ACTION_BUY"),
47 Self::Sell => f.write_str("ORDER_ACTION_SELL"),
48 }
49 }
50}
51
52#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
54#[non_exhaustive]
55pub enum OrderSide {
56 #[serde(rename = "LONG")]
57 Long,
58 #[serde(rename = "SHORT")]
59 Short,
60}
61
62impl fmt::Display for OrderSide {
63 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
64 match self {
65 Self::Long => f.write_str("LONG"),
66 Self::Short => f.write_str("SHORT"),
67 }
68 }
69}
70
71#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
73#[non_exhaustive]
74pub enum OrderType {
75 #[serde(rename = "ORDER_TYPE_LIMIT")]
76 Limit,
77}
78
79impl fmt::Display for OrderType {
80 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
81 f.write_str("ORDER_TYPE_LIMIT")
82 }
83}
84
85#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
87#[non_exhaustive]
88pub enum TimeInForce {
89 #[serde(rename = "TIME_IN_FORCE_GOOD_TILL_CANCEL")]
91 GoodTillCancel,
92 #[serde(rename = "TIME_IN_FORCE_GOOD_TILL_DATE")]
94 GoodTillDate,
95 #[serde(rename = "TIME_IN_FORCE_IMMEDIATE_OR_CANCEL")]
97 ImmediateOrCancel,
98 #[serde(rename = "TIME_IN_FORCE_FILL_OR_KILL")]
100 FillOrKill,
101}
102
103impl fmt::Display for TimeInForce {
104 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
105 let s = match self {
106 Self::GoodTillCancel => "TIME_IN_FORCE_GOOD_TILL_CANCEL",
107 Self::GoodTillDate => "TIME_IN_FORCE_GOOD_TILL_DATE",
108 Self::ImmediateOrCancel => "TIME_IN_FORCE_IMMEDIATE_OR_CANCEL",
109 Self::FillOrKill => "TIME_IN_FORCE_FILL_OR_KILL",
110 };
111 f.write_str(s)
112 }
113}
114
115#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
117#[serde(rename_all = "lowercase")]
118#[non_exhaustive]
119pub enum MarketStatus {
120 Open,
121 Closed,
122 Resolved,
123 #[serde(other)]
125 Unknown,
126}
127
128#[derive(Debug, Clone, Deserialize)]
133pub struct HealthResponse {
134 #[serde(default)]
135 pub status: String,
136 #[serde(default)]
137 pub timestamp: String,
138}
139
140#[derive(Debug, Clone, Deserialize)]
141pub struct MarketsResponse {
142 #[serde(default)]
143 pub markets: Vec<UsMarket>,
144}
145
146#[derive(Debug, Clone, Deserialize)]
147pub struct UsMarket {
148 #[serde(default)]
149 pub id: String,
150 #[serde(default)]
151 pub slug: String,
152 #[serde(default)]
153 pub question: String,
154 #[serde(default)]
155 pub status: String,
156 #[serde(default)]
157 pub category: String,
158 #[serde(default, rename = "startDate")]
159 pub start_date: String,
160 #[serde(default, rename = "endDate")]
161 pub end_date: String,
162 #[serde(default)]
163 pub description: String,
164 #[serde(default)]
165 pub active: bool,
166 #[serde(default)]
167 pub closed: bool,
168 #[serde(default, rename = "marketType")]
169 pub market_type: String,
170 #[serde(default, rename = "marketSides")]
171 pub market_sides: Vec<serde_json::Value>,
172 #[serde(default)]
173 pub instruments: Vec<serde_json::Value>,
174 #[serde(default)]
175 pub outcomes: Vec<serde_json::Value>,
176}
177
178#[derive(Debug, Clone, Deserialize)]
179pub struct MarketSide {
180 #[serde(default)]
181 pub id: String,
182 #[serde(default)]
183 pub identifier: String,
184 #[serde(default)]
185 pub description: String,
186 #[serde(default)]
187 pub price: String,
188 #[serde(default)]
189 pub long: bool,
190 #[serde(default, rename = "marketSideType")]
191 pub market_side_type: String,
192 #[serde(default)]
193 pub team: Option<serde_json::Value>,
194 #[serde(default)]
195 pub player: Option<serde_json::Value>,
196 #[serde(flatten)]
197 pub extra: std::collections::HashMap<String, serde_json::Value>,
198}
199
200#[derive(Debug, Clone, Serialize)]
201pub struct PlaceOrderRequest {
202 pub symbol: String,
203 pub action: OrderAction,
204 #[serde(rename = "outcomeSide")]
205 pub outcome_side: OrderSide,
206 #[serde(rename = "type")]
207 pub order_type: OrderType,
208 pub price: Money,
209 pub quantity: u64,
210 pub tif: TimeInForce,
211 #[serde(skip_serializing_if = "Option::is_none")]
212 pub client_order_id: Option<String>,
213 #[serde(skip_serializing_if = "std::ops::Not::not")]
214 pub post_only: bool,
215 #[serde(skip_serializing_if = "Option::is_none")]
216 pub expires_at: Option<u64>,
217}
218
219#[derive(Debug, Clone, Serialize, Deserialize)]
220pub struct Money {
221 pub value: String,
222 pub currency: String,
223}
224
225#[derive(Debug, Clone, Deserialize)]
226pub struct PlaceOrderResponse {
227 pub order_id: String,
228 #[serde(default)]
229 pub client_order_id: Option<String>,
230 #[serde(default)]
231 pub status: String,
232 #[serde(default)]
233 pub filled_quantity: u64,
234 #[serde(default)]
235 pub remaining_quantity: u64,
236 #[serde(default)]
237 pub created_at: String,
238}
239
240#[derive(Debug, Clone, Serialize)]
241pub struct BatchedOrderRequest {
242 pub orders: Vec<PlaceOrderRequest>,
243 pub atomic: bool,
244}
245
246#[derive(Debug, Clone, Deserialize)]
247pub struct BatchedOrderResponse {
248 #[serde(default)]
249 pub orders: Vec<PlaceOrderResponse>,
250}
251
252#[derive(Debug, Clone, Deserialize)]
253pub struct CancelOrderResponse {
254 pub order_id: String,
255 #[serde(default)]
256 pub status: String,
257 #[serde(default)]
258 pub cancelled_at: Option<String>,
259}
260
261#[derive(Debug, Clone, Deserialize)]
262pub struct PortfolioPositionsResponse {
263 #[serde(default)]
264 pub positions: std::collections::HashMap<String, UsPosition>,
265 #[serde(default)]
266 pub next_cursor: String,
267 #[serde(default)]
268 pub eof: bool,
269 #[serde(default, rename = "availablePositions")]
270 pub available_positions: Vec<UsPosition>,
271}
272
273#[derive(Debug, Clone, Deserialize)]
274pub struct UsPosition {
275 #[serde(default)]
276 pub symbol: String,
277 #[serde(default)]
278 pub quantity: i64,
279 #[serde(default, rename = "avgEntryPrice")]
280 pub avg_entry_price: String,
281 #[serde(default, rename = "unrealizedPnl")]
282 pub unrealized_pnl: Option<String>,
283}
284
285#[derive(Debug, Clone, Deserialize)]
286pub struct PortfolioActivitiesResponse {
287 #[serde(default)]
288 pub activities: Vec<serde_json::Value>,
289 #[serde(default)]
290 pub next_cursor: Option<String>,
291}
292
293#[derive(Debug, Clone, Deserialize)]
294pub struct AccountBalancesResponse {
295 #[serde(default)]
296 pub balances: Vec<UserBalance>,
297}
298
299#[derive(Debug, Clone, Deserialize)]
300pub struct UserBalance {
301 #[serde(default, rename = "currentBalance")]
302 pub current_balance: f64,
303 #[serde(default)]
304 pub currency: String,
305 #[serde(default, rename = "lastUpdated")]
306 pub last_updated: Option<String>,
307 #[serde(default, rename = "buyingPower")]
308 pub buying_power: f64,
309 #[serde(default, rename = "assetNotional")]
310 pub asset_notional: Option<f64>,
311 #[serde(default, rename = "assetAvailable")]
312 pub asset_available: Option<f64>,
313 #[serde(default, rename = "pendingCredit")]
314 pub pending_credit: Option<f64>,
315 #[serde(default, rename = "openOrders")]
316 pub open_orders: Option<f64>,
317 #[serde(default, rename = "unsettledFunds")]
318 pub unsettled_funds: Option<f64>,
319 #[serde(default, rename = "marginRequirement")]
320 pub margin_requirement: Option<f64>,
321 #[serde(default, rename = "balanceReservation")]
322 pub balance_reservation: Option<f64>,
323}
324
325#[derive(Debug, Clone, Serialize, Default)]
326pub struct CancelOrderParams {
327 #[serde(skip_serializing_if = "Option::is_none")]
328 pub quantity: Option<u64>,
329}
330
331#[derive(Debug, Clone, Serialize, Default)]
332pub struct CancelAllOrdersParams {
333 #[serde(skip_serializing_if = "Option::is_none")]
334 pub symbol: Option<String>,
335}
336
337#[derive(Debug, Clone, Deserialize)]
338pub struct CancelAllOrdersResponse {
339 #[serde(default)]
340 pub cancelled: Vec<String>,
341}
342
343#[derive(Debug, Clone, Serialize)]
344pub struct ModifyOrderRequest {
345 pub price: Money,
346 pub quantity: u64,
347}
348
349#[derive(Debug, Clone, Serialize)]
350pub struct PreviewOrderRequest {
351 pub symbol: String,
352 pub action: OrderAction,
353 #[serde(rename = "outcomeSide")]
354 pub outcome_side: OrderSide,
355 #[serde(rename = "type")]
356 pub order_type: OrderType,
357 pub price: Money,
358 pub quantity: u64,
359}
360
361#[derive(Debug, Clone, Deserialize)]
362pub struct PreviewOrderResponse {
363 #[serde(default)]
364 pub estimate: serde_json::Value,
365}
366
367#[derive(Debug, Clone, Serialize)]
368pub struct ClosePositionRequest {
369 pub symbol: String,
370 pub quantity: u64,
371}
372
373#[derive(Debug, Clone, Deserialize)]
374pub struct ClosePositionResponse {
375 #[serde(default)]
376 pub status: String,
377 #[serde(default)]
378 pub order_id: Option<String>,
379}
380
381#[derive(Debug, Clone, Deserialize)]
382pub struct GetOpenOrdersResponse {
383 #[serde(default)]
384 pub orders: Vec<PlaceOrderResponse>,
385}
386
387#[derive(Debug, Clone, Deserialize)]
389pub struct EventsResponse {
390 #[serde(default)]
391 pub events: Vec<UsEvent>,
392}
393
394#[derive(Debug, Clone, Deserialize)]
395pub struct UsEvent {
396 #[serde(default)]
397 pub id: String,
398 #[serde(default)]
399 pub slug: String,
400 #[serde(default)]
401 pub title: String,
402 #[serde(default)]
403 pub description: Option<String>,
404 #[serde(default)]
405 pub category: String,
406 #[serde(default)]
407 pub start_date: Option<String>,
408 #[serde(default)]
409 pub end_date: Option<String>,
410 #[serde(flatten)]
411 pub extra: std::collections::HashMap<String, serde_json::Value>,
412}
413
414#[derive(Debug, Clone, Deserialize)]
416pub struct OrderBook {
417 #[serde(default)]
418 pub bids: Vec<PriceLevel>,
419 #[serde(default)]
420 pub asks: Vec<PriceLevel>,
421}
422
423#[derive(Debug, Clone, Deserialize, Serialize)]
424pub struct PriceLevel {
425 pub price: String,
426 pub quantity: String,
427}
428
429#[derive(Debug, Clone, Deserialize)]
430pub struct BestBidOffer {
431 #[serde(default)]
432 pub bid: Option<PriceLevel>,
433 #[serde(default)]
434 pub ask: Option<PriceLevel>,
435}
436
437#[derive(Debug, Clone, Deserialize)]
438pub struct SettlementPrice {
439 #[serde(default)]
440 pub symbol: String,
441 #[serde(default)]
442 pub price: String,
443 #[serde(default)]
444 pub timestamp: String,
445}
446
447#[derive(Debug, Clone, Deserialize)]
449pub struct SearchResults {
450 #[serde(default)]
451 pub markets: Vec<UsMarket>,
452 #[serde(default)]
453 pub events: Vec<UsEvent>,
454}
455
456#[derive(Debug, Clone, Deserialize)]
458pub struct League {
459 #[serde(default)]
460 pub id: String,
461 #[serde(default)]
462 pub name: String,
463 #[serde(default)]
464 pub sport: String,
465}
466
467#[derive(Debug, Clone, Deserialize)]
468pub struct Team {
469 #[serde(default)]
470 pub id: String,
471 #[serde(default)]
472 pub name: String,
473 #[serde(default)]
474 pub league_id: Option<String>,
475}