Skip to main content
Glama
PORTFOLIO.md11.5 kB
# Portfolio Streaming and Account Data Complete guide to accessing account information, positions, and P&L through the IB TWS API. ## Overview The TWS API provides several ways to access portfolio data: 1. **Account Summary** - Snapshot of account metrics (cash, buying power, etc.) 2. **Positions** - Current holdings with P&L 3. **Portfolio Streaming** - Real-time updates to positions and account values 4. **P&L Tracking** - Account and position-level profit/loss ## Quick Start ```javascript // Connect first await ibkr_connect(); // Get snapshot const summary = await ibkr_get_account_summary({account: "U1234567"}); const positions = await ibkr_get_positions(); // Start streaming await ibkr_start_portfolio_resource({account: "U1234567"}); subscribe("ibkr://portfolio/U1234567"); // Monitor P&L const pnl = await ibkr_get_pnl({account: "U1234567"}); ``` --- ## Account Summary ### Get Account Metrics **Request:** ```javascript await ibkr_get_account_summary({ account: "U1234567" // optional, defaults to all accounts }); ``` **Response:** ```json { "TotalCashValue": "50000.00", "NetLiquidation": "75000.00", "GrossPositionValue": "25000.00", "BuyingPower": "100000.00", "AvailableFunds": "50000.00", "ExcessLiquidity": "45000.00", "Cushion": "0.60" } ``` ### Available Tags | Tag | Description | |-----|-------------| | `TotalCashValue` | Total cash in account | | `NetLiquidation` | Total account value | | `GrossPositionValue` | Total value of positions | | `BuyingPower` | Available buying power | | `AvailableFunds` | Funds available for withdrawal | | `ExcessLiquidity` | Excess liquidity | | `Cushion` | Equity with loan value / Net liquidation | ### Use Cases - Account health checks - Available cash for trading - Margin calculations - Risk assessment --- ## Positions ### Get Current Positions **Request:** ```javascript await ibkr_get_positions({ account: "U1234567" // optional }); ``` **Response:** ```json [ { "account": "U1234567", "symbol": "AAPL", "secType": "STK", "position": 100, "avgCost": 150.50, "marketPrice": 152.30, "marketValue": 15230.00, "unrealizedPNL": 180.00, "realizedPNL": 0.00 }, { "account": "U1234567", "symbol": "MSFT", "secType": "STK", "position": 50, "avgCost": 300.00, "marketPrice": 305.50, "marketValue": 15275.00, "unrealizedPNL": 275.00, "realizedPNL": 0.00 } ] ``` ### Position Fields | Field | Description | |-------|-------------| | `account` | Account ID | | `symbol` | Contract symbol | | `secType` | Security type (STK, FUT, OPT, etc.) | | `position` | Number of shares/contracts (negative = short) | | `avgCost` | Average cost per share | | `marketPrice` | Current market price | | `marketValue` | Total position value | | `unrealizedPNL` | Unrealized profit/loss | | `realizedPNL` | Realized profit/loss for the day | ### Use Cases - Portfolio analysis - Rebalancing decisions - Risk management - Tax planning --- ## Portfolio Streaming ### Real-Time Updates Stream live updates to positions and account values. **Start:** ```javascript await ibkr_start_portfolio_resource({ account: "U1234567" // required }); ``` **Response:** ```json { "status": "subscribed", "resource_uri": "ibkr://portfolio/U1234567", "account": "U1234567", "message": "Portfolio streaming started" } ``` **Subscribe:** ```javascript subscribe("ibkr://portfolio/U1234567"); ``` **Updates:** ```json { "timestamp": 1697654321, "positions": [ { "symbol": "AAPL", "position": 100, "avgCost": 150.50, "marketPrice": 152.50, // Price changed "marketValue": 15250.00, "unrealizedPNL": 200.00 // P&L updated } ], "account_values": { "NetLiquidation": "75200.00", // Account value changed "UnrealizedPnL": "200.00", "RealizedPnL": "0.00" } } ``` **Stop:** ```javascript await ibkr_stop_portfolio_resource({account: "U1234567"}); ``` ### What Triggers Updates - Price changes (position values update) - New trades (positions added/modified) - Account deposits/withdrawals - Dividends/interest - Margin changes ### Event-Driven Architecture Portfolio streaming uses IB's event system: ```python # Setup self.ib.client.reqAccountUpdates(True, account) # Event handlers self.ib.updatePortfolioEvent += on_portfolio_update self.ib.accountValueEvent += on_account_value_update # Main loop while True: await self.ib.updateEvent # Wait for IB events # Process updates await send_resource_updated(uri) ``` ### Key Features - **Non-blocking:** Event-driven, doesn't poll - **Real-time:** Updates as they happen - **Efficient:** Only changed data sent - **Reliable:** Uses IB's native event system ### Use Cases - Real-time portfolio monitoring - Automated rebalancing triggers - Risk management alerts - Live P&L tracking --- ## P&L Tracking ### Account-Level P&L **Request:** ```javascript await ibkr_get_pnl({ account: "U1234567" // required }); ``` **Response:** ```json { "account": "U1234567", "dailyPnL": 450.50, "unrealizedPnL": 1200.00, "realizedPnL": -100.25 } ``` ### Position-Level P&L **Request:** ```javascript await ibkr_get_pnl_single({ account: "U1234567", symbol: "AAPL", secType: "STK", // optional exchange": "SMART", // optional currency: "USD" // optional }); ``` **Response:** ```json { "account": "U1234567", "symbol": "AAPL", "position": 100, "dailyPnL": 200.00, "unrealizedPnL": 180.00, "realizedPnL": 20.00, "value": 15230.00 } ``` ### P&L Fields | Field | Description | |-------|-------------| | `dailyPnL` | Total P&L for the day (realized + unrealized) | | `unrealizedPnL` | Open position P&L | | `realizedPnL` | Closed position P&L for the day | | `value` | Current market value | ### Use Cases - Daily performance tracking - Tax lot management - Performance attribution - Trading strategy evaluation --- ## Comparison: Snapshot vs Streaming | Feature | Snapshot | Streaming | |---------|----------|-----------| | **Method** | `ibkr_get_positions` | `ibkr_start_portfolio_resource` | | **Updates** | Manual (call each time) | Automatic (real-time) | | **Overhead** | Higher (repeated calls) | Lower (one subscription) | | **Use for** | Periodic checks | Continuous monitoring | | **Latency** | On-demand | Real-time | **Choose Streaming When:** - Need real-time updates - Monitoring active positions - Automated systems - Live dashboards **Choose Snapshot When:** - Periodic checks - Historical analysis - One-time queries - Reporting --- ## Complete Example Workflow ### Initial Setup ```javascript // 1. Connect await ibkr_connect(); // 2. Get account snapshot const summary = await ibkr_get_account_summary({ account: "U1234567" }); console.log(`Net Liquidation: $${summary.NetLiquidation}`); console.log(`Buying Power: $${summary.BuyingPower}`); // 3. Get positions const positions = await ibkr_get_positions(); for (const pos of positions) { console.log(`${pos.symbol}: ${pos.position} shares @ $${pos.marketPrice}`); console.log(` Unrealized P&L: $${pos.unrealizedPNL}`); } ``` ### Start Streaming ```javascript // 4. Start portfolio streaming await ibkr_start_portfolio_resource({account: "U1234567"}); // 5. Subscribe to resource subscribe("ibkr://portfolio/U1234567"); // Now you'll receive real-time updates ``` ### Monitor P&L ```javascript // 6. Check account P&L const accountPnL = await ibkr_get_pnl({account: "U1234567"}); console.log(`Daily P&L: $${accountPnL.dailyPnL}`); // 7. Check position P&L const applPnL = await ibkr_get_pnl_single({ account: "U1234567", symbol: "AAPL" }); console.log(`AAPL P&L: $${applPnL.dailyPnL}`); ``` ### Cleanup ```javascript // 8. Stop streaming when done await ibkr_stop_portfolio_resource({account: "U1234567"}); ``` --- ## Multiple Accounts ### List All Accounts ```javascript // Get all accounts const summary = await ibkr_get_account_summary(); // No account param // Returns data for all managed accounts ``` ### Stream Multiple Accounts ```javascript // Start streams for each account const accounts = ["U1234567", "U7654321"]; for (const account of accounts) { await ibkr_start_portfolio_resource({account}); subscribe(`ibkr://portfolio/${account}`); } // Monitor all accounts simultaneously ``` ### Check Active Streams ```javascript const streams = await ibkr_list_active_resource_streams(); console.log(streams.portfolio); // [ // {account: "U1234567", resource_uri: "ibkr://portfolio/U1234567", ...}, // {account: "U7654321", resource_uri: "ibkr://portfolio/U7654321", ...} // ] ``` --- ## Troubleshooting ### No Portfolio Updates **Check:** 1. Verify account ID correct 2. Ensure positions exist 3. Check connection status 4. Verify streaming started **Solution:** ```javascript // Verify connection const status = await ibkr_get_status(); // Check active streams const streams = await ibkr_list_active_resource_streams(); // Restart if needed await ibkr_stop_portfolio_resource({account: "U1234567"}); await ibkr_start_portfolio_resource({account: "U1234567"}); ``` ### Incorrect P&L Values **Causes:** - Positions still settling - Corporate actions not reflected - Different base currency - Commissions not included **Solution:** - Wait for settlement - Check position details - Verify currency settings - Include commission in calculations ### Missing Positions **Causes:** - Position just opened (not settled) - Different account - Filtered by security type **Solution:** ```javascript // Get all positions (no filter) const allPositions = await ibkr_get_positions(); // Check account summary const summary = await ibkr_get_account_summary({account: "U1234567"}); ``` --- ## Best Practices ### Streaming 1. **One stream per account** - Don't start multiple streams for same account 2. **Stop when done** - Clean up unused streams 3. **Monitor status** - Use `ibkr_list_active_resource_streams` 4. **Handle disconnects** - Reconnect and restart streams ### Performance 1. **Use streaming for real-time** - More efficient than repeated snapshots 2. **Batch queries** - Get all positions at once, not one by one 3. **Cache data** - Store position snapshots, update from stream ### Risk Management 1. **Monitor margin** - Track cushion and excess liquidity 2. **Set P&L alerts** - Trigger on daily P&L thresholds 3. **Track exposure** - Monitor gross position value 4. **Verify orders** - Check positions after trades ### Reporting 1. **Daily snapshots** - Capture end-of-day positions 2. **P&L tracking** - Log daily P&L for records 3. **Performance attribution** - Track per-position P&L 4. **Tax reporting** - Monitor realized P&L --- ## Event Loop Fix (Technical Note) Portfolio streaming uses `self.ib.client.reqAccountUpdates()` directly instead of async wrappers to avoid event loop conflicts: ```python # ✅ CORRECT - Direct client API self.ib.client.reqAccountUpdates(True, account) # ❌ WRONG - Async wrapper causes event loop issues await self.ib.reqAccountUpdatesAsync(True, account) ``` This ensures: - No event loop blocking - Proper event handler attachment - Reliable streaming --- ## See Also - [TOOLS.md](TOOLS.md) - Complete tools reference - [DESIGN.md](DESIGN.md) - Architecture overview - [MARKET_DATA.md](MARKET_DATA.md) - Market data streaming - [NEWS.md](NEWS.md) - News streaming - [IB Portfolio API](https://interactivebrokers.github.io/tws-api/account_updates.html)

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/haymant/tws-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server