1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114
use chrono::{ DateTime, Utc }; use reqwest::Method; use serde::Deserialize; use snafu::{ ensure, ResultExt }; use crate::{ error, util, Alpaca, Result }; /// The status of the account /// /// Most likely, the account status is ACTIVE unless there is any problem. The account status /// may get in ACCOUNT_UPDATED when personal information is being updated from the dashboard, /// in which case you may not be allowed trading for a short period of time until the change /// is approved. #[derive(Debug, Deserialize, PartialEq)] #[serde(rename_all = "SCREAMING_SNAKE_CASE")] pub enum AccountStatus { /// The account information is being updated. AccountUpdated, /// The account is active for trading. Active, /// The final account approval is pending. ApprovalPending, /// The account is onboarding. Onboarding, /// The account application has been rejected. Rejected, /// The account application submission failed for some reason. SubmissionFailed, /// The account application has been submitted for review. Submitted } /// Important information related to an account. /// /// Including account status, funds available for trade, funds available for withdrawal, and /// various flags relevant to an account’s ability to trade. /// /// An account maybe be blocked for just for trades (trades_blocked flag) or for both trades and /// transfers (account_blocked flag) if Alpaca identifies the account to engaging in any suspicious /// activity. /// /// Also, in accordance with FINRA’s pattern day trading rule, an account may be flagged for /// pattern day trading (pattern_day_trader flag), which would inhibit an account from placing any /// further day-trades. #[derive(Debug, Deserialize)] pub struct Account { /// Account ID - a UUID pub id: String, /// Account number - a string different from the account ID #[serde(rename = "account_number")] pub number: String, /// Cash balance #[serde(deserialize_with = "util::to_f64")] pub cash: f64, /// The total equity in the account = cash + long_market_value + short_market_value #[serde(deserialize_with = "util::to_f64")] pub equity: f64, /// Real-time MtM value of all long positions held in the account #[serde(deserialize_with = "util::to_f64")] pub long_market_value: f64, /// Real-time MtM value of all short positions held in the account #[serde(deserialize_with = "util::to_f64")] pub short_market_value: f64, /// Current available $ buying power #[serde(deserialize_with = "util::to_f64")] pub buying_power: f64, /// Timestamp this account was created at #[serde(rename = "created_at")] pub created: DateTime<Utc>, /// If true, the account activity by user is prohibited. #[serde(rename = "account_blocked")] pub is_account_blocked: bool, /// If true, the account has been flagged as a pattern day trader #[serde(rename = "pattern_day_trader")] pub is_pattern_day_trader: bool, /// If true, the account is not allowed to place orders due to customer request. #[serde(rename = "trade_suspended_by_user")] pub is_trade_suspended: bool, /// If true, the account is not allowed to place orders. #[serde(rename = "trading_blocked")] pub is_trading_blocked: bool, /// If true, the account is not allowed to request money transfers. #[serde(rename = "transfers_blocked")] pub is_transfers_blocked: bool, /// Account status pub status: AccountStatus, } impl Account { /// Gets the current account information /// /// # Example /// /// To get your current account information: /// /// ``` no run /// let alpaca = Alpaca::live("KEY_ID", "SECRET").await.unwrap(); /// /// let account = Account::get(&alpaca).await.unwrap(); /// ``` pub async fn get(alpaca: &Alpaca) -> Result<Account> { let response = alpaca.request(Method::GET, "v2/account")? .send().await.context(error::RequestFailed)?; ensure!(response.status().is_success(), error::InvalidCredentials); Ok(response.json::<Account>().await.context(error::BadData)?) } }