ibkr_flex_statement/
fifo_performance_summary.rs1use crate::statement_section::StatementSection;
2
3use super::node_utils::NodeWrapper;
4use super::time_utils;
5use anyhow::Result;
6
7#[derive(Debug, PartialEq)]
8pub struct FIFOPerformanceSummary {
9 pub account_id: String,
10 pub timestamp_eod_ms: i64,
11
12 pub ticker: Option<String>,
13 pub conid: Option<u32>,
14 pub listing_exchange: Option<String>,
15
16 pub realized_st_profit: f64,
17 pub realized_st_loss: f64,
18 pub unrealized_st_profit: f64,
19 pub unrealized_st_loss: f64,
20
21 pub realized_lt_profit: f64,
22 pub realized_lt_loss: f64,
23 pub unrealized_lt_profit: f64,
24 pub unrealized_lt_loss: f64,
25
26 pub total_realized_pnl: f64,
27 pub total_fifo_pnl: f64,
28}
29
30impl StatementSection for FIFOPerformanceSummary {
31 fn from_node(node: &NodeWrapper) -> Result<FIFOPerformanceSummary> {
32 Ok(FIFOPerformanceSummary {
33 account_id: node.get_attribute("accountId")?,
34 timestamp_eod_ms: time_utils::trading_eod_after_hours_timestamp_ms(
35 node.node.attribute("reportDate").unwrap(),
36 )?,
37
38 ticker: node.get_attribute_opt("symbol"),
39 conid: node.parse_attribute_opt("conid")?,
40 listing_exchange: node.get_attribute_opt("listingExchange"),
41
42 realized_st_profit: node.parse_attribute("realizedSTProfit")?,
43 realized_st_loss: node.parse_attribute("realizedSTLoss")?,
44 unrealized_st_profit: node.parse_attribute("unrealizedSTProfit")?,
45 unrealized_st_loss: node.parse_attribute("unrealizedSTLoss")?,
46
47 realized_lt_profit: node.parse_attribute("realizedLTProfit")?,
48 realized_lt_loss: node.parse_attribute("realizedLTLoss")?,
49 unrealized_lt_profit: node.parse_attribute("unrealizedLTProfit")?,
50 unrealized_lt_loss: node.parse_attribute("unrealizedLTLoss")?,
51
52 total_realized_pnl: node.parse_attribute("totalRealizedPnl")?,
53 total_fifo_pnl: node.parse_attribute("totalFifoPnl")?,
54 })
55 }
56}
57
58#[cfg(test)]
59mod tests {
60 use super::*;
61 use crate::Parser;
62 use anyhow::Result;
63
64 const PARTIAL_STATEMENT_EXAMPLE: &str = r##"
65 <FlexQueryResponse queryName="example-query" type="AF">
66 <FlexStatements count="1">
67 <FlexStatement accountId="U1234567" fromDate="2025-04-25" toDate="2025-04-25" period="LastBusinessDay" whenGenerated="2025-04-26;13:34:28 EDT">
68 <AccountInformation accountId="U1234567" accountType="Individual" customerType="Individual" accountCapabilities="Portfolio Margin" tradingPermissions="Stocks,Options,Warrants,Forex,Futures,Crypto Currencies,Mutual Funds,Fully Paid Stock Loan" />
69 <FIFOPerformanceSummaryInBase>
70 <FIFOPerformanceSummaryUnderlying accountId="U1234567" assetCategory="STK" symbol="ARGX" conid="276343981" listingExchange="NASDAQ" reportDate="2025-04-25" realizedSTProfit="0" realizedSTLoss="-636.4413056" realizedLTProfit="0" realizedLTLoss="0" totalRealizedPnl="-636.4413056" unrealizedProfit="0" unrealizedLoss="0" unrealizedSTProfit="0" unrealizedSTLoss="0" unrealizedLTProfit="0" unrealizedLTLoss="0" totalFifoPnl="-636.4413056" />
71 <FIFOPerformanceSummaryUnderlying accountId="U1234567" assetCategory="STK" symbol="GEO" conid="158655765" listingExchange="NYSE" reportDate="2025-04-25" realizedSTProfit="0" realizedSTLoss="-1375.50915991" realizedLTProfit="0" realizedLTLoss="0" totalRealizedPnl="-1375.50915991" unrealizedProfit="0" unrealizedLoss="0" unrealizedSTProfit="0" unrealizedSTLoss="0" unrealizedLTProfit="0" unrealizedLTLoss="0" totalFifoPnl="-1375.50915991" />
72 <FIFOPerformanceSummaryUnderlying accountId="U1234567" assetCategory="STK" symbol="GRPN" conid="426480582" listingExchange="NASDAQ" reportDate="2025-04-25" realizedSTProfit="0" realizedSTLoss="1607.307677" realizedLTProfit="0" realizedLTLoss="0" totalRealizedPnl="1607.307677" unrealizedProfit="77.771818" unrealizedLoss="-868.095492" unrealizedSTProfit="77.771818" unrealizedSTLoss="-868.095492" unrealizedLTProfit="0" unrealizedLTLoss="0" totalFifoPnl="816.984003" />
73 <FIFOPerformanceSummaryUnderlying accountId="U1234567" assetCategory="STK" symbol="META" conid="107113386" listingExchange="NASDAQ" reportDate="2025-04-25" realizedSTProfit="0" realizedSTLoss="0" realizedLTProfit="0" realizedLTLoss="0" totalRealizedPnl="0" unrealizedProfit="8598.681628" unrealizedLoss="-4398.965111" unrealizedSTProfit="8598.681628" unrealizedSTLoss="-4398.965111" unrealizedLTProfit="0" unrealizedLTLoss="0" totalFifoPnl="4199.716517" />
74 <FIFOPerformanceSummaryUnderlying accountId="U1234567" assetCategory="STK" symbol="NFLX" conid="15124833" listingExchange="NASDAQ" reportDate="2025-04-25" realizedSTProfit="0" realizedSTLoss="0" realizedLTProfit="0" realizedLTLoss="0" totalRealizedPnl="0" unrealizedProfit="18081.807156" unrealizedLoss="0" unrealizedSTProfit="18081.807156" unrealizedSTLoss="0" unrealizedLTProfit="0" unrealizedLTLoss="0" totalFifoPnl="18081.807156" />
75 <FIFOPerformanceSummaryUnderlying accountId="U1234567" assetCategory="STK" symbol="PLTR" conid="444857009" listingExchange="NASDAQ" reportDate="2025-04-25" realizedSTProfit="0" realizedSTLoss="0" realizedLTProfit="0" realizedLTLoss="0" totalRealizedPnl="0" unrealizedProfit="24855.882465" unrealizedLoss="0" unrealizedSTProfit="24855.882465" unrealizedSTLoss="0" unrealizedLTProfit="0" unrealizedLTLoss="0" totalFifoPnl="24855.882465" />
76 <FIFOPerformanceSummaryUnderlying accountId="U1234567" assetCategory="STK" symbol="TQQQ" conid="72539702" listingExchange="NASDAQ" reportDate="2025-04-25" realizedSTProfit="0" realizedSTLoss="0" realizedLTProfit="0" realizedLTLoss="0" totalRealizedPnl="0" unrealizedProfit="42178.328575" unrealizedLoss="-39340.67993" unrealizedSTProfit="42178.328575" unrealizedSTLoss="-39340.67993" unrealizedLTProfit="0" unrealizedLTLoss="0" totalFifoPnl="2837.648645" />
77 <FIFOPerformanceSummaryUnderlying accountId="U1234567" assetCategory="STK" symbol="TSLA" conid="76792991" listingExchange="NASDAQ" reportDate="2025-04-25" realizedSTProfit="0" realizedSTLoss="199.59291494" realizedLTProfit="0" realizedLTLoss="0" totalRealizedPnl="199.59291494" unrealizedProfit="33175.116277" unrealizedLoss="-226.596415" unrealizedSTProfit="33175.116277" unrealizedSTLoss="-226.596415" unrealizedLTProfit="0" unrealizedLTLoss="0" totalFifoPnl="33148.11277694" />
78 <FIFOPerformanceSummaryUnderlying
79 accountId="U1234567"
80 assetCategory="STK"
81 symbol="TTWO"
82 conid="6478131"
83 listingExchange="NASDAQ"
84 reportDate="2025-04-25"
85 realizedSTProfit="0"
86 realizedSTLoss="0"
87 realizedLTProfit="0"
88 realizedLTLoss="0"
89 totalRealizedPnl="0"
90 unrealizedProfit="4089.983554"
91 unrealizedLoss="0"
92 unrealizedSTProfit="4089.983554"
93 unrealizedSTLoss="0"
94 unrealizedLTProfit="0"
95 unrealizedLTLoss="0"
96 totalFifoPnl="4089.983554" />
97
98 <FIFOPerformanceSummaryUnderlying
99 accountId="U1234567"
100 assetCategory=""
101 symbol=""
102 conid=""
103 listingExchange=""
104 reportDate="2025-04-25"
105 realizedSTProfit="0"
106 realizedSTLoss="-205.04987357"
107 realizedLTProfit="0"
108 realizedLTLoss="0"
109 totalRealizedPnl="-205.04987357"
110 unrealizedProfit="131057.571473"
111 unrealizedLoss="-44834.337024864"
112 unrealizedSTProfit="131057.571473"
113 unrealizedSTLoss="-44834.337024864"
114 unrealizedLTProfit="0"
115 unrealizedLTLoss="0"
116 totalFifoPnl="86018.184574566" />
117 </FIFOPerformanceSummaryInBase>
118 </FlexStatement>
119 </FlexStatements>
120 </FlexQueryResponse>
121 "##;
122
123 #[test]
124 fn fifo_performance_summaries_parse() -> Result<()> {
125 let statements = Parser::new()?.parse_flex_query_response(PARTIAL_STATEMENT_EXAMPLE)?;
126 assert_eq!(statements.len(), 1);
127 let result = &statements[0];
128
129 assert_eq!(result.fifo_performance_summaries.len(), 10);
131
132 assert_eq!(
133 result.fifo_performance_summaries[8],
134 FIFOPerformanceSummary {
135 account_id: "U1234567".to_string(),
136 ticker: Some("TTWO".to_string()),
137 conid: Some(6478131),
138 listing_exchange: Some("NASDAQ".to_string()),
139 timestamp_eod_ms: result.fifo_performance_summaries[8].timestamp_eod_ms,
140 realized_st_profit: 0.0,
141 realized_st_loss: 0.0,
142 unrealized_st_profit: 4089.983554,
143 unrealized_st_loss: 0.0,
144 realized_lt_profit: 0.0,
145 realized_lt_loss: 0.0,
146 unrealized_lt_profit: 0.0,
147 unrealized_lt_loss: 0.0,
148 total_realized_pnl: 0.0,
149 total_fifo_pnl: 4089.983554,
150 }
151 );
152
153 assert_eq!(
154 result.fifo_performance_summaries[9],
155 FIFOPerformanceSummary {
156 account_id: "U1234567".to_string(),
157 ticker: None,
158 conid: None,
159 listing_exchange: None,
160 timestamp_eod_ms: result.fifo_performance_summaries[9].timestamp_eod_ms,
161 realized_st_profit: 0.0,
162 realized_st_loss: -205.04987357,
163 unrealized_st_profit: 131057.571473,
164 unrealized_st_loss: -44834.337024864,
165 realized_lt_profit: 0.0,
166 realized_lt_loss: 0.0,
167 unrealized_lt_profit: 0.0,
168 unrealized_lt_loss: 0.0,
169 total_realized_pnl: -205.04987357,
170 total_fifo_pnl: 86018.184574566,
171 }
172 );
173 Ok(())
174 }
175}