webull_rs/models/
order.rs

1use serde::{Deserialize, Serialize};
2use chrono::{DateTime, Utc};
3
4/// Order information from Webull.
5#[derive(Debug, Clone, Serialize, Deserialize)]
6pub struct Order {
7    /// Order ID
8    pub id: String,
9    
10    /// Symbol of the security
11    pub symbol: String,
12    
13    /// Quantity of shares
14    pub quantity: f64,
15    
16    /// Filled quantity of shares
17    pub filled_quantity: f64,
18    
19    /// Price of the order (for limit orders)
20    pub price: Option<f64>,
21    
22    /// Stop price (for stop orders)
23    pub stop_price: Option<f64>,
24    
25    /// Order status
26    pub status: OrderStatus,
27    
28    /// Order side (buy/sell)
29    pub side: OrderSide,
30    
31    /// Order type
32    pub order_type: OrderType,
33    
34    /// Time in force
35    pub time_in_force: TimeInForce,
36    
37    /// Whether the order is for extended hours trading
38    pub extended_hours: bool,
39    
40    /// When the order was created
41    pub created_at: DateTime<Utc>,
42    
43    /// When the order was last updated
44    pub updated_at: DateTime<Utc>,
45    
46    /// Commission charged for the order
47    pub commission: f64,
48    
49    /// Rejected reason (if the order was rejected)
50    pub rejected_reason: Option<String>,
51    
52    /// Average fill price
53    pub average_fill_price: Option<f64>,
54}
55
56/// Status of an order.
57#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
58#[serde(rename_all = "UPPERCASE")]
59pub enum OrderStatus {
60    /// Order is new
61    New,
62    
63    /// Order is partially filled
64    PartiallyFilled,
65    
66    /// Order is filled
67    Filled,
68    
69    /// Order is canceled
70    Canceled,
71    
72    /// Order is rejected
73    Rejected,
74    
75    /// Order is pending cancel
76    PendingCancel,
77    
78    /// Order is pending new
79    PendingNew,
80    
81    /// Order is pending replace
82    PendingReplace,
83    
84    /// Order is replaced
85    Replaced,
86    
87    /// Order is suspended
88    Suspended,
89    
90    /// Order is expired
91    Expired,
92}
93
94/// Side of an order.
95#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
96#[serde(rename_all = "UPPERCASE")]
97pub enum OrderSide {
98    /// Buy order
99    Buy,
100    
101    /// Sell order
102    Sell,
103    
104    /// Sell short order
105    SellShort,
106    
107    /// Buy to cover order
108    BuyToCover,
109}
110
111/// Type of an order.
112#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
113#[serde(rename_all = "UPPERCASE")]
114pub enum OrderType {
115    /// Market order
116    Market,
117    
118    /// Limit order
119    Limit,
120    
121    /// Stop order
122    Stop,
123    
124    /// Stop limit order
125    StopLimit,
126    
127    /// Trailing stop order
128    TrailingStop,
129    
130    /// Trailing stop limit order
131    TrailingStopLimit,
132}
133
134/// Time in force for an order.
135#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
136#[serde(rename_all = "UPPERCASE")]
137pub enum TimeInForce {
138    /// Day order
139    Day,
140    
141    /// Good till canceled order
142    Gtc,
143    
144    /// Good till date order
145    Gtd,
146    
147    /// Immediate or cancel order
148    Ioc,
149    
150    /// Fill or kill order
151    Fok,
152}
153
154/// Request to place an order.
155#[derive(Debug, Clone, Serialize, Deserialize)]
156pub struct OrderRequest {
157    /// Symbol of the security
158    pub symbol: String,
159    
160    /// Quantity of shares
161    pub quantity: f64,
162    
163    /// Price of the order (for limit orders)
164    pub price: Option<f64>,
165    
166    /// Stop price (for stop orders)
167    pub stop_price: Option<f64>,
168    
169    /// Order side (buy/sell)
170    pub side: OrderSide,
171    
172    /// Order type
173    pub order_type: OrderType,
174    
175    /// Time in force
176    pub time_in_force: TimeInForce,
177    
178    /// Whether the order is for extended hours trading
179    pub extended_hours: bool,
180}
181
182impl OrderRequest {
183    /// Create a new order request.
184    pub fn new() -> Self {
185        Self {
186            symbol: String::new(),
187            quantity: 0.0,
188            price: None,
189            stop_price: None,
190            side: OrderSide::Buy,
191            order_type: OrderType::Market,
192            time_in_force: TimeInForce::Day,
193            extended_hours: false,
194        }
195    }
196    
197    /// Set the symbol.
198    pub fn symbol(mut self, symbol: impl Into<String>) -> Self {
199        self.symbol = symbol.into();
200        self
201    }
202    
203    /// Set the quantity.
204    pub fn quantity(mut self, quantity: f64) -> Self {
205        self.quantity = quantity;
206        self
207    }
208    
209    /// Set the price.
210    pub fn price(mut self, price: f64) -> Self {
211        self.price = Some(price);
212        self
213    }
214    
215    /// Set the stop price.
216    pub fn stop_price(mut self, stop_price: f64) -> Self {
217        self.stop_price = Some(stop_price);
218        self
219    }
220    
221    /// Set the order side.
222    pub fn side(mut self, side: OrderSide) -> Self {
223        self.side = side;
224        self
225    }
226    
227    /// Set the order type.
228    pub fn order_type(mut self, order_type: OrderType) -> Self {
229        self.order_type = order_type;
230        self
231    }
232    
233    /// Set the time in force.
234    pub fn time_in_force(mut self, time_in_force: TimeInForce) -> Self {
235        self.time_in_force = time_in_force;
236        self
237    }
238    
239    /// Set whether the order is for extended hours trading.
240    pub fn extended_hours(mut self, extended_hours: bool) -> Self {
241        self.extended_hours = extended_hours;
242        self
243    }
244}
245
246impl Default for OrderRequest {
247    fn default() -> Self {
248        Self::new()
249    }
250}
251
252/// Response from placing an order.
253#[derive(Debug, Clone, Serialize, Deserialize)]
254pub struct OrderResponse {
255    /// Order ID
256    pub id: String,
257    
258    /// Order status
259    pub status: OrderStatus,
260    
261    /// Symbol of the security
262    pub symbol: String,
263    
264    /// Quantity of shares
265    pub quantity: f64,
266    
267    /// Price of the order (for limit orders)
268    pub price: Option<f64>,
269    
270    /// Stop price (for stop orders)
271    pub stop_price: Option<f64>,
272    
273    /// Order side (buy/sell)
274    pub side: OrderSide,
275    
276    /// Order type
277    pub order_type: OrderType,
278    
279    /// Time in force
280    pub time_in_force: TimeInForce,
281    
282    /// Whether the order is for extended hours trading
283    pub extended_hours: bool,
284    
285    /// When the order was created
286    pub created_at: DateTime<Utc>,
287}
288
289/// Parameters for querying orders.
290#[derive(Debug, Clone, Serialize, Deserialize)]
291pub struct OrderQueryParams {
292    /// Status of orders to query
293    pub status: Option<OrderStatus>,
294    
295    /// Symbol to filter by
296    pub symbol: Option<String>,
297    
298    /// Start date for the query
299    pub start_date: Option<DateTime<Utc>>,
300    
301    /// End date for the query
302    pub end_date: Option<DateTime<Utc>>,
303    
304    /// Maximum number of orders to return
305    pub limit: Option<u32>,
306}
307
308impl OrderQueryParams {
309    /// Create new order query parameters.
310    pub fn new() -> Self {
311        Self {
312            status: None,
313            symbol: None,
314            start_date: None,
315            end_date: None,
316            limit: None,
317        }
318    }
319    
320    /// Set the status filter.
321    pub fn status(mut self, status: OrderStatus) -> Self {
322        self.status = Some(status);
323        self
324    }
325    
326    /// Set the symbol filter.
327    pub fn symbol(mut self, symbol: impl Into<String>) -> Self {
328        self.symbol = Some(symbol.into());
329        self
330    }
331    
332    /// Set the start date filter.
333    pub fn start_date(mut self, start_date: DateTime<Utc>) -> Self {
334        self.start_date = Some(start_date);
335        self
336    }
337    
338    /// Set the end date filter.
339    pub fn end_date(mut self, end_date: DateTime<Utc>) -> Self {
340        self.end_date = Some(end_date);
341        self
342    }
343    
344    /// Set the limit.
345    pub fn limit(mut self, limit: u32) -> Self {
346        self.limit = Some(limit);
347        self
348    }
349}
350
351impl Default for OrderQueryParams {
352    fn default() -> Self {
353        Self::new()
354    }
355}