webull_rs/endpoints/
orders.rs1use crate::auth::AuthManager;
2use crate::endpoints::base::BaseEndpoint;
3use crate::error::WebullResult;
4use crate::models::order::{
5 OptionOrderPreviewRequest, OptionOrderPreviewResponse, OptionOrderRequest, Order,
6 OrderQueryParams, OrderRequest, OrderResponse,
7};
8use reqwest::Client;
9use std::sync::Arc;
10
11pub struct OrderEndpoints {
13 base: BaseEndpoint,
15}
16
17impl OrderEndpoints {
18 pub fn new(client: Client, base_url: String, auth_manager: Arc<AuthManager>) -> Self {
20 Self {
21 base: BaseEndpoint::new(client, base_url, auth_manager),
22 }
23 }
24
25 pub async fn place_order(&self, order: &OrderRequest) -> WebullResult<OrderResponse> {
27 self.base.post("/api/trade/order", order).await
28 }
29
30 pub async fn cancel_order(&self, order_id: &str) -> WebullResult<()> {
32 let path = format!("/api/trade/cancel/{}", order_id);
33 self.base.delete(&path).await
34 }
35
36 pub async fn get_order(&self, order_id: &str) -> WebullResult<Order> {
38 let path = format!("/api/trade/order/{}", order_id);
39 self.base.get(&path).await
40 }
41
42 pub async fn get_orders(&self, params: &OrderQueryParams) -> WebullResult<Vec<Order>> {
44 self.base.post("/api/trade/orders", params).await
45 }
46
47 pub async fn get_active_orders(&self) -> WebullResult<Vec<Order>> {
49 self.base.get("/api/trade/active").await
50 }
51
52 pub async fn get_filled_orders(&self) -> WebullResult<Vec<Order>> {
54 self.base.get("/api/trade/filled").await
55 }
56
57 pub async fn modify_order(
59 &self,
60 order_id: &str,
61 order: &OrderRequest,
62 ) -> WebullResult<OrderResponse> {
63 let path = format!("/api/trade/modify/{}", order_id);
64 self.base.put(&path, order).await
65 }
66
67 pub async fn get_open_orders(&self, account_id: &str) -> WebullResult<Vec<Order>> {
69 let path = format!("/api/trade/account/{}/orders/open", account_id);
70 self.base.get(&path).await
71 }
72
73 pub async fn get_open_orders_paged(
75 &self,
76 account_id: &str,
77 page_size: u32,
78 last_order_id: Option<&str>,
79 ) -> WebullResult<Vec<Order>> {
80 #[derive(serde::Serialize)]
81 struct OpenOrdersRequest {
82 account_id: String,
83 page_size: u32,
84 #[serde(skip_serializing_if = "Option::is_none")]
85 last_client_order_id: Option<String>,
86 }
87
88 let mut request = OpenOrdersRequest {
89 account_id: account_id.to_string(),
90 page_size,
91 last_client_order_id: None,
92 };
93
94 if let Some(order_id) = last_order_id {
95 request.last_client_order_id = Some(order_id.to_string());
96 }
97
98 self.base.post("/api/trade/orders/open", &request).await
99 }
100
101 pub async fn get_today_orders(&self, account_id: &str) -> WebullResult<Vec<Order>> {
103 let path = format!("/api/trade/account/{}/orders/today", account_id);
104 self.base.get(&path).await
105 }
106
107 pub async fn get_today_orders_paged(
109 &self,
110 account_id: &str,
111 page_size: u32,
112 last_order_id: Option<&str>,
113 ) -> WebullResult<Vec<Order>> {
114 #[derive(serde::Serialize)]
115 struct TodayOrdersRequest {
116 account_id: String,
117 page_size: u32,
118 #[serde(skip_serializing_if = "Option::is_none")]
119 last_client_order_id: Option<String>,
120 }
121
122 let mut request = TodayOrdersRequest {
123 account_id: account_id.to_string(),
124 page_size,
125 last_client_order_id: None,
126 };
127
128 if let Some(order_id) = last_order_id {
129 request.last_client_order_id = Some(order_id.to_string());
130 }
131
132 self.base.post("/api/trade/orders/today", &request).await
133 }
134
135 pub async fn preview_option_order(
137 &self,
138 preview_request: &OptionOrderPreviewRequest,
139 ) -> WebullResult<OptionOrderPreviewResponse> {
140 self.base
141 .post("/api/trade/option/preview", preview_request)
142 .await
143 }
144
145 pub async fn place_option_order(
147 &self,
148 account_id: &str,
149 orders: &[OptionOrderRequest],
150 ) -> WebullResult<Vec<OrderResponse>> {
151 #[derive(serde::Serialize)]
152 struct PlaceOptionRequest<'a> {
153 account_id: &'a str,
154 new_orders: &'a [OptionOrderRequest],
155 }
156
157 let request = PlaceOptionRequest {
158 account_id,
159 new_orders: orders,
160 };
161
162 self.base.post("/api/trade/option/place", &request).await
163 }
164
165 pub async fn replace_option_order(
167 &self,
168 account_id: &str,
169 orders: &[OptionOrderRequest],
170 ) -> WebullResult<Vec<OrderResponse>> {
171 #[derive(serde::Serialize)]
172 struct ReplaceOptionRequest<'a> {
173 account_id: &'a str,
174 modify_orders: &'a [OptionOrderRequest],
175 }
176
177 let request = ReplaceOptionRequest {
178 account_id,
179 modify_orders: orders,
180 };
181
182 self.base.post("/api/trade/option/replace", &request).await
183 }
184
185 pub async fn cancel_option_order(
187 &self,
188 account_id: &str,
189 client_order_id: &str,
190 ) -> WebullResult<()> {
191 #[derive(serde::Serialize)]
192 struct CancelOptionRequest<'a> {
193 account_id: &'a str,
194 client_order_id: &'a str,
195 }
196
197 let request = CancelOptionRequest {
198 account_id,
199 client_order_id,
200 };
201
202 self.base.post("/api/trade/option/cancel", &request).await
203 }
204}