Type-safe Rust parser for Interactive Brokers FLEX XML statements with comprehensive coverage and financial precision.
- High performance - Fast XML parsing with quick-xml and serde
- Financial precision - rust_decimal for all monetary values (no floating point errors)
- Type-safe - 15 enums with 100+ variants for comprehensive coverage
- Comprehensive - Supports all major FLEX sections and 20 asset categories
- Well-tested - Integration tests, property-based tests, edge case coverage
- Edge case handling - Warrants, T-Bills, CFDs, fractional shares, cancelled trades
- Optional API client - Fetch FLEX statements programmatically from IB
Add this to your Cargo.toml:
[dependencies]
ib-flex = "0.1"use ib_flex::{parse_activity_flex, detect_statement_type, StatementType};
fn main() -> Result<(), Box<dyn std::error::Error>> {
let xml = std::fs::read_to_string("flex_statement.xml")?;
// Automatically detect statement type
match detect_statement_type(&xml)? {
StatementType::Activity => {
let statement = parse_activity_flex(&xml)?;
println!("Account: {}", statement.account_id);
println!("Trades: {}", statement.trades.items.len());
}
StatementType::TradeConfirmation => {
let statement = ib_flex::parse_trade_confirmation(&xml)?;
println!("Account: {}", statement.account_id);
println!("Trades: {}", statement.trades.items.len());
}
}
Ok(())
}Interactive Brokers FLEX queries must be configured in the IB Client Portal:
- Navigate to: Reports → Flex Queries → Create Activity Flex Query
- Select required sections (Trades, Positions, Cash Transactions, etc.)
- Choose date format: ISO-8601 (
yyyy-MM-dd) or compact (yyyyMMdd) - Set output format to XML
- Save query and note the Query ID
Important: European date formats (dd/MM/yyyy) are NOT supported by the IB FLEX API.
📘 For comprehensive setup instructions, see FLEX_SETUP.md which covers all 21 recommended sections, field selections, and configuration options.
The api-client feature provides programmatic access to fetch FLEX statements directly from Interactive Brokers without manual downloads.
[dependencies]
ib-flex = { version = "0.1", features = ["api-client"] }- Log in to IB Account Management
- Navigate to: Reports → Settings → FlexWeb Service
- Generate a FLEX Web Service token (keep it secure!)
- Note your FLEX Query ID from the Flex Queries page
use ib_flex::api::FlexApiClient;
use std::time::Duration;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// Create client with your token
let client = FlexApiClient::new("YOUR_TOKEN");
// Step 1: Send request with your query ID
let reference_code = client.send_request("123456").await?;
// Step 2: Get statement with automatic retry
let xml = client.get_statement_with_retry(
&reference_code,
10, // max retries
Duration::from_secs(2) // delay between retries
).await?;
// Step 3: Parse the statement
let statement = ib_flex::parse_activity_flex(&xml)?;
println!("Trades: {}", statement.trades.items.len());
Ok(())
}Run the API examples (requires IB credentials):
export IB_FLEX_TOKEN="your_token"
export IB_FLEX_QUERY_ID="your_query_id"
cargo run --example fetch_flex_statement --features api-client
cargo run --example api_simple_usage --features api-client
cargo run --example api_with_retry --features api-client- ✅ Trades - Executions with 40+ fields including P&L, commissions, dates, security details
- ✅ Open Positions - Current holdings with 30+ fields
- ✅ Cash Transactions - Deposits, withdrawals, interest, fees, dividends
- ✅ Corporate Actions - Splits, mergers, spinoffs, dividends (36 action types)
- ✅ Securities Info - Reference data for all traded instruments
- ✅ FX Conversion Rates - Currency conversion rates for multi-currency accounts
- ✅ Account Information - Account metadata and configuration
- ✅ Change in NAV - Net asset value changes with transfers and P&L breakdown
- ✅ Equity Summary - Asset allocation by category (cash, stocks, options, bonds)
- ✅ Cash Report - Detailed cash flow by currency
- ✅ Trade Confirmations - Real-time trade execution confirmations
- ✅ Option EAE - Option exercises, assignments, and expirations
- ✅ FX Transactions - Foreign exchange conversions
- ✅ Dividend Accruals - Accrued and open dividend tracking
- ✅ Interest Accruals - Interest accrual tracking by currency
- ✅ Transfers - Security transfers (ACATS, ATON, FOP, etc.)
- ✅ Stocks (STK) - Including fractional shares
- ✅ Options (OPT) - Calls, puts, assignments, expirations
- ✅ Futures (FUT) - All major contracts (ES, NQ, CL, GC, etc.)
- ✅ Forex (CASH) - FX trades and positions
- ✅ Bonds (BOND) - Treasuries, corporate, municipal
- ✅ Treasury Bills (BILL) - With maturity handling
- ✅ Warrants (WAR) - Equity warrants
- ✅ CFDs - Contract for difference
- ✅ Funds, Commodities, and more - 20 asset categories total
- ✅ Trade Confirmations - Real-time trade execution data
- ✅ All trade fields - Full support for all trade attributes
- ✅ Automatic detection - Detect statement type from XML
Benchmarked on M1 MacBook Pro:
| Statement Type | Transactions | Parse Time |
|---|---|---|
| Minimal | 1 trade | ~6.5 µs |
| Options | 4 trades | ~65 µs |
| Cash | 15 transactions | ~71 µs |
Memory efficient with approximately 200 bytes per trade. Parsing 10,000 trades uses ~2MB of memory.
All financial values use rust_decimal::Decimal for precise calculations without floating-point errors. The library includes comprehensive enums with 100+ variants covering:
- AssetCategory (20 variants) - STK, OPT, FUT, CASH, BOND, BILL, WAR, CFD, etc.
- CorporateActionType (36 variants) - All corporate action types (formerly Reorg)
- TransactionCode (50+ variants) - Transaction classification codes (formerly Code)
- CashTransactionType (13 variants) - Cash transaction types (formerly CashAction)
- DerivativeInfo - Consolidated derivative metadata for options, futures, and warrants
- OrderType (13 variants) - Market, limit, stop, etc.
- SecurityIdType - CUSIP, ISIN, FIGI, SEDOL identifier types
- SubCategory - ETF, ADR, REIT, Preferred, Common, and more
- LevelOfDetail - Summary, Detail, Execution, Lot reporting granularity
- BuySell, OpenClose, PutCall, LongShort, TradeType, OptionAction, and more
The repository includes several complete example programs:
- parse_activity_statement.rs - Basic Activity FLEX parsing and display
- filter_trades.rs - Filter by asset class, side, symbol, quantity, P&L, date range
- calculate_commissions.rs - Analyze commission costs by category
- parse_trade_confirmation.rs - Trade Confirmation FLEX parsing
Run parsing examples:
cargo run --example parse_activity_statement
cargo run --example parse_trade_confirmation
cargo run --example filter_trades
cargo run --example calculate_commissions- backfill_summary.rs - Parse multi-statement FLEX XML and display comprehensive summary
To use this example:
- Create a FLEX query with Period: Last 180 Calendar Days (or similar) in IBKR Client Portal - see FLEX_SETUP.md
- Download the XML file manually or via API
- Run the summary:
cargo run --example backfill_summary -- path/to/your/backfill.xmlOutput includes:
- NAV over time with returns, high/low, drawdown
- Trading activity by symbol with P&L attribution
- Cash transaction breakdown (dividends, interest, fees)
- Current positions from latest statement
- Monthly returns table
- fetch_flex_statement.rs - Complete API workflow with detailed output
- api_simple_usage.rs - Minimal API client usage
- api_with_retry.rs - API client with automatic retry logic
Run API examples:
export IB_FLEX_TOKEN="your_token"
export IB_FLEX_QUERY_ID="your_query_id"
cargo run --example fetch_flex_statement --features api-clientcargo buildcargo testcargo benchcargo fmtcargo clippy -- -D warningsThe library has comprehensive test coverage including:
- Integration tests covering all asset classes and edge cases
- Extended types tests for FLEX sections
- Error tests for malformed XML and invalid data
- Unit tests for custom deserializers
- Doc tests in inline documentation
- XML fixtures including extended types, warrants, T-Bills, CFDs, fractional shares, cancelled trades
The library includes comprehensive reliability tests using:
- Property-based testing with proptest for random inputs
- Stress tests for large XML files
- Concurrency tests for thread safety
- Memory efficiency tests for repeated parsing
- Edge case fuzzing for malformed inputs
Run tests with:
cargo test # All tests
cargo test --doc # Documentation tests onlyContributions welcome! This is an open-source project designed to benefit the Rust trading community.
Before submitting a PR:
- Ensure all tests pass:
cargo test - Run clippy:
cargo clippy -- -D warnings - Format code:
cargo fmt - Add tests for new features
- Update CHANGELOG.md
Bug reports and feature requests are appreciated. When reporting bugs, please include:
- Anonymized XML sample demonstrating the issue
- Expected vs actual behavior
- Rust version and platform
- API Documentation
- Implementation Plan - Full implementation details and statistics
- Project Guide for Claude Code - Development guide
- Edge Cases Summary - Comprehensive edge case analysis
- Types Analysis - Type system breakdown
Licensed under either of:
- Apache License, Version 2.0 (LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0)
- MIT license (LICENSE-MIT or http://opensource.org/licenses/MIT)
at your option.
- Inspired by csingley/ibflex (Python) - Comprehensive enum research
- Built with quick-xml - Fast XML parsing with serde
- rust_decimal - Financial precision
- chrono - Date/time handling
See PLAN.md for detailed implementation statistics and EDGE_CASES_SUMMARY.md for edge case coverage.