webull_rs/models/
account.rs

1use chrono::{DateTime, Utc};
2use serde::{Deserialize, Serialize};
3
4/// Account information from Webull.
5#[derive(Debug, Clone, Serialize, Deserialize)]
6pub struct Account {
7    /// Account ID
8    pub id: String,
9
10    /// Account number
11    pub account_number: String,
12
13    /// Account type
14    pub account_type: AccountType,
15
16    /// Account status
17    pub status: AccountStatus,
18
19    /// When the account was created
20    pub created_at: DateTime<Utc>,
21
22    /// Currency of the account
23    pub currency: String,
24
25    /// Whether the account is a paper trading account
26    pub paper_trading: bool,
27
28    /// Account region
29    pub region: Option<String>,
30
31    /// Account name
32    pub name: Option<String>,
33
34    /// Account email
35    pub email: Option<String>,
36
37    /// Account phone number
38    pub phone: Option<String>,
39}
40
41/// Type of account.
42#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
43#[serde(rename_all = "UPPERCASE")]
44pub enum AccountType {
45    /// Cash account
46    Cash,
47
48    /// Margin account
49    Margin,
50
51    /// IRA account
52    Ira,
53
54    /// Other account type
55    Other,
56}
57
58/// Status of an account.
59#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
60#[serde(rename_all = "UPPERCASE")]
61pub enum AccountStatus {
62    /// Account is active
63    Active,
64
65    /// Account is closed
66    Closed,
67
68    /// Account is pending approval
69    Pending,
70
71    /// Account is suspended
72    Suspended,
73}
74
75/// Account balance information.
76#[derive(Debug, Clone, Serialize, Deserialize)]
77pub struct AccountBalance {
78    /// Cash balance
79    pub cash: f64,
80
81    /// Buying power
82    pub buying_power: f64,
83
84    /// Market value of holdings
85    pub market_value: f64,
86
87    /// Total account value
88    pub total_value: f64,
89
90    /// Unrealized profit/loss
91    pub unrealized_profit_loss: f64,
92
93    /// Unrealized profit/loss percentage
94    pub unrealized_profit_loss_percentage: f64,
95
96    /// Currency of the balance
97    pub currency: String,
98
99    /// Settled cash
100    pub settled_cash: Option<f64>,
101
102    /// Unsettled cash
103    pub unsettled_cash: Option<f64>,
104
105    /// Cash available for withdrawal
106    pub withdrawable_cash: Option<f64>,
107
108    /// Cash available for trading
109    pub tradable_cash: Option<f64>,
110
111    /// Margin buying power
112    pub margin_buying_power: Option<f64>,
113
114    /// Option buying power
115    pub option_buying_power: Option<f64>,
116
117    /// Day trading buying power
118    pub day_trading_buying_power: Option<f64>,
119}
120
121/// Position in an account.
122#[derive(Debug, Clone, Serialize, Deserialize)]
123pub struct Position {
124    /// Symbol of the position
125    pub symbol: String,
126
127    /// Instrument ID
128    pub instrument_id: String,
129
130    /// Quantity of shares
131    pub quantity: f64,
132
133    /// Average cost basis
134    pub cost_basis: f64,
135
136    /// Current market value
137    pub market_value: f64,
138
139    /// Unrealized profit/loss
140    pub unrealized_profit_loss: f64,
141
142    /// Unrealized profit/loss percentage
143    pub unrealized_profit_loss_percentage: f64,
144
145    /// Current price
146    pub current_price: f64,
147
148    /// When the position was opened
149    pub opened_at: DateTime<Utc>,
150
151    /// Security name
152    pub name: Option<String>,
153
154    /// Security type
155    pub security_type: Option<String>,
156
157    /// Exchange
158    pub exchange: Option<String>,
159
160    /// Currency
161    pub currency: Option<String>,
162
163    /// Position side (LONG or SHORT)
164    pub side: Option<String>,
165
166    /// Position status
167    pub status: Option<String>,
168
169    /// Quantity available for trading
170    pub tradable_quantity: Option<f64>,
171
172    /// Quantity not yet settled
173    pub unsettled_quantity: Option<f64>,
174}
175
176/// Account profile information.
177#[derive(Debug, Clone, Serialize, Deserialize)]
178pub struct AccountProfile {
179    /// Account ID
180    pub id: String,
181
182    /// Account number
183    pub account_number: String,
184
185    /// Account type
186    pub account_type: AccountType,
187
188    /// Account status
189    pub status: AccountStatus,
190
191    /// Account region
192    pub region: String,
193
194    /// Account name
195    pub name: String,
196
197    /// Account email
198    pub email: Option<String>,
199
200    /// Account phone number
201    pub phone: Option<String>,
202
203    /// Account currency
204    pub currency: String,
205
206    /// Whether the account is a paper trading account
207    pub paper_trading: bool,
208
209    /// Account creation date
210    pub created_at: DateTime<Utc>,
211
212    /// Account KYC status
213    pub kyc_status: Option<String>,
214
215    /// Account risk level
216    pub risk_level: Option<String>,
217
218    /// Account permissions
219    pub permissions: Option<Vec<String>>,
220}
221
222/// Trade history entry.
223#[derive(Debug, Clone, Serialize, Deserialize)]
224pub struct TradeHistory {
225    /// Trade ID
226    pub id: String,
227
228    /// Symbol of the security
229    pub symbol: String,
230
231    /// Instrument ID
232    pub instrument_id: String,
233
234    /// Security name
235    pub name: Option<String>,
236
237    /// Trade action (BUY or SELL)
238    pub action: String,
239
240    /// Quantity of shares
241    pub quantity: f64,
242
243    /// Price per share
244    pub price: f64,
245
246    /// Total amount of the trade
247    pub amount: f64,
248
249    /// Trade fees
250    pub fees: Option<f64>,
251
252    /// Trade date and time
253    pub trade_time: DateTime<Utc>,
254
255    /// Trade status
256    pub status: String,
257
258    /// Order ID associated with the trade
259    pub order_id: Option<String>,
260
261    /// Trade currency
262    pub currency: Option<String>,
263
264    /// Exchange where the trade was executed
265    pub exchange: Option<String>,
266
267    /// Security type
268    pub security_type: Option<String>,
269}
270
271/// Parameters for querying account positions.
272#[derive(Debug, Clone, Serialize, Deserialize)]
273pub struct PositionParams {
274    /// Account ID
275    #[serde(rename = "account_id")]
276    pub account_id: String,
277
278    /// Page size (max 100)
279    #[serde(rename = "page_size")]
280    pub page_size: u32,
281
282    /// Last instrument ID for pagination
283    #[serde(rename = "last_instrument_id", skip_serializing_if = "Option::is_none")]
284    pub last_instrument_id: Option<String>,
285}
286
287impl PositionParams {
288    /// Create new position query parameters.
289    pub fn new(account_id: impl Into<String>, page_size: u32) -> Self {
290        Self {
291            account_id: account_id.into(),
292            page_size,
293            last_instrument_id: None,
294        }
295    }
296
297    /// Set the last instrument ID for pagination.
298    pub fn last_instrument_id(mut self, last_instrument_id: impl Into<String>) -> Self {
299        self.last_instrument_id = Some(last_instrument_id.into());
300        self
301    }
302}
303
304/// Parameters for querying account balance.
305#[derive(Debug, Clone, Serialize, Deserialize)]
306pub struct BalanceParams {
307    /// Account ID
308    #[serde(rename = "account_id")]
309    pub account_id: String,
310
311    /// Currency for total assets
312    #[serde(rename = "total_asset_currency")]
313    pub total_asset_currency: String,
314}
315
316impl BalanceParams {
317    /// Create new balance query parameters.
318    pub fn new(account_id: impl Into<String>, total_asset_currency: impl Into<String>) -> Self {
319        Self {
320            account_id: account_id.into(),
321            total_asset_currency: total_asset_currency.into(),
322        }
323    }
324
325    /// Create new balance query parameters with default currency (HKD).
326    pub fn new_with_default_currency(account_id: impl Into<String>) -> Self {
327        Self::new(account_id, "HKD")
328    }
329}