Skip to main content

ibkr_flex_statement/
account_info.rs

1use crate::node_utils::NodeWrapper;
2use crate::statement_section::StatementSection;
3use anyhow::Result;
4
5#[derive(Debug, PartialEq)]
6pub enum PositionSide {
7    Long,
8    Short,
9}
10
11#[derive(Clone, Debug, PartialEq)]
12pub struct AccountInfo {
13    pub account_id: String,
14}
15
16impl<'a> TryFrom<&'a str> for PositionSide {
17    type Error = anyhow::Error;
18
19    fn try_from(s: &'a str) -> Result<Self> {
20        match s {
21            "Long" => Ok(Self::Long),
22            "Short" => Ok(Self::Short),
23            _ => Err(anyhow::Error::msg(format!("unknown position side {}", s))),
24        }
25    }
26}
27
28impl StatementSection for AccountInfo {
29    fn from_node(node: &NodeWrapper) -> Result<AccountInfo> {
30        Ok(AccountInfo {
31            account_id: node.get_attribute("accountId")?,
32        })
33    }
34}
35
36#[cfg(test)]
37mod tests {
38    use super::*;
39    use crate::Parser;
40    use anyhow::Result;
41
42    const PARTIAL_STATEMENT_EXAMPLE: &str = r##"
43        <FlexQueryResponse queryName="example-query" type="AF">
44            <FlexStatements count="1">
45                <FlexStatement accountId="U1234567" fromDate="2025-04-25" toDate="2025-04-25" period="LastBusinessDay" whenGenerated="2025-04-26;13:34:28 EDT">
46                    <AccountInformation 
47                        accountId="U1234567"
48                        accountType="Individual"
49                        customerType="Individual"
50                        accountCapabilities="Portfolio Margin"
51                        tradingPermissions="Stocks,Options,Warrants,Forex,Futures,Crypto Currencies,Mutual Funds,Fully Paid Stock Loan" />
52                    <AccountSummary accountId="U1234567" accountType="Individual" customerType="Individual" accountCapabilities="Portfolio Margin" tradingPermissions="Stocks,Options,Warrants,Forex,Futures,Crypto Currencies,Mutual Funds,Fully Paid Stock Loan" accountBaseCurrency="USD" accountBaseCurrencySymbol="$" accountBaseCurrencyRate="1.0" accountBaseCurrencyRateDateTime="2025-04-26;13:34:28 EDT" accountBaseCurrencyRateSource="IBKR" accountBaseCurrencyRateSourceDescription="IBKR" accountBaseCurrencyRateSourceDateTime="2025-04-26;13:34:28 EDT" />
53                </FlexStatement>
54            </FlexStatements>
55        </FlexQueryResponse>
56        "##;
57
58    #[test]
59    fn account_info_parses() -> Result<()> {
60        let statements = Parser::new()?.parse_flex_query_response(PARTIAL_STATEMENT_EXAMPLE)?;
61        assert_eq!(statements.len(), 1);
62        let result = &statements[0];
63
64        assert_eq!(
65            result.account_info,
66            AccountInfo {
67                account_id: "U1234567".to_string(),
68            }
69        );
70        Ok(())
71    }
72}