156 lines
3.9 KiB
Markdown
156 lines
3.9 KiB
Markdown
|
|
# IB Dashboard
|
||
|
|
|
||
|
|
Interactive Brokers dashboard with a small Flask backend and a vanilla JavaScript frontend.
|
||
|
|
|
||
|
|
The project currently uses two data paths:
|
||
|
|
- TWS / IB Gateway API for live positions and pricing
|
||
|
|
- IB Flex Web Service infrastructure for durable historical trade retrieval
|
||
|
|
|
||
|
|
The Flex path is important for lot history because the socket API execution stream is not reliable enough on its own to reconstruct all historical lots in every setup.
|
||
|
|
|
||
|
|
## Requirements
|
||
|
|
|
||
|
|
- Python 3.8+
|
||
|
|
- IB Gateway or TWS running locally on port `7496`
|
||
|
|
- For full historical lots: a saved IB Flex Query plus a Flex Web Service token
|
||
|
|
|
||
|
|
## Install
|
||
|
|
|
||
|
|
```bash
|
||
|
|
python -m pip install -r requirements.txt
|
||
|
|
```
|
||
|
|
|
||
|
|
## Run
|
||
|
|
|
||
|
|
```bash
|
||
|
|
python backend/app.py
|
||
|
|
```
|
||
|
|
|
||
|
|
Then open `http://127.0.0.1:8000` in your browser.
|
||
|
|
|
||
|
|
## Current API Endpoints
|
||
|
|
|
||
|
|
- `GET /api/quotes`
|
||
|
|
- `GET /api/positions`
|
||
|
|
- `GET /api/lots`
|
||
|
|
- `GET /api/executions-debug`
|
||
|
|
- `GET /api/flex/status`
|
||
|
|
- `POST /api/flex/sync`
|
||
|
|
|
||
|
|
## Flex Query Setup
|
||
|
|
|
||
|
|
This app now includes the infrastructure needed to pull historical trade data from IB Flex Web Service and save the raw XML locally. This is the recommended foundation for reconstructing lots regardless of how long ago they were acquired.
|
||
|
|
|
||
|
|
### 1. Create a Flex Query in IB Client Portal
|
||
|
|
|
||
|
|
In IB Client Portal:
|
||
|
|
|
||
|
|
1. Open `Performance & Reports`.
|
||
|
|
2. Go to `Flex Queries`.
|
||
|
|
3. Create a new query for trades / executions.
|
||
|
|
4. Include enough fields to reconstruct lots. At minimum, include:
|
||
|
|
- account
|
||
|
|
- symbol
|
||
|
|
- underlying symbol if available
|
||
|
|
- asset / security type
|
||
|
|
- trade date / trade time
|
||
|
|
- quantity
|
||
|
|
- trade price
|
||
|
|
- buy/sell side
|
||
|
|
- strike
|
||
|
|
- expiry
|
||
|
|
- put/call
|
||
|
|
- multiplier
|
||
|
|
- conid if available
|
||
|
|
- local symbol / trading class if available
|
||
|
|
5. Save the query and note the `Query ID`.
|
||
|
|
|
||
|
|
### 2. Create a Flex Web Service Token
|
||
|
|
|
||
|
|
In IB Client Portal:
|
||
|
|
|
||
|
|
1. Open the Flex Web Service section.
|
||
|
|
2. Generate or copy your Flex Web Service token.
|
||
|
|
3. Keep it secure. Treat it like a credential.
|
||
|
|
|
||
|
|
IB reference:
|
||
|
|
- Flex Web Service overview: `https://ibkrcampus.com/campus/glossary-terms/flex-web-service/`
|
||
|
|
|
||
|
|
### 3. Configure the App
|
||
|
|
|
||
|
|
Use the included `.env.example` as a template.
|
||
|
|
|
||
|
|
Set these environment variables before starting the backend:
|
||
|
|
|
||
|
|
- `IB_FLEX_TOKEN`
|
||
|
|
- `IB_FLEX_QUERY_ID`
|
||
|
|
- `IB_FLEX_DATA_DIR`
|
||
|
|
|
||
|
|
Example PowerShell session:
|
||
|
|
|
||
|
|
```powershell
|
||
|
|
$env:IB_FLEX_TOKEN="your-token"
|
||
|
|
$env:IB_FLEX_QUERY_ID="123456"
|
||
|
|
$env:IB_FLEX_DATA_DIR="data/flex"
|
||
|
|
python backend/app.py
|
||
|
|
```
|
||
|
|
|
||
|
|
### 4. Verify Configuration
|
||
|
|
|
||
|
|
Check the Flex status endpoint:
|
||
|
|
|
||
|
|
```text
|
||
|
|
GET /api/flex/status
|
||
|
|
```
|
||
|
|
|
||
|
|
If configured correctly, it returns:
|
||
|
|
- `configured: true`
|
||
|
|
- the configured query id
|
||
|
|
- the local data directory
|
||
|
|
- the latest downloaded file if one exists
|
||
|
|
|
||
|
|
### 5. Trigger a Flex Sync
|
||
|
|
|
||
|
|
Trigger a manual download of the saved Flex Query:
|
||
|
|
|
||
|
|
```text
|
||
|
|
POST /api/flex/sync
|
||
|
|
```
|
||
|
|
|
||
|
|
On success, the backend saves the raw XML file under `data/flex/` and returns:
|
||
|
|
- `ok: true`
|
||
|
|
- the saved file path
|
||
|
|
- the request reference code
|
||
|
|
|
||
|
|
## What The Flex Infrastructure Does Today
|
||
|
|
|
||
|
|
The current implementation provides:
|
||
|
|
|
||
|
|
- environment-driven Flex configuration
|
||
|
|
- a backend Flex client for `SendRequest` and `GetStatement`
|
||
|
|
- local persistence of the downloaded XML files under `data/flex/`
|
||
|
|
- Flask endpoints to inspect config and trigger a sync
|
||
|
|
|
||
|
|
Files added for this:
|
||
|
|
|
||
|
|
- [backend/flex_query.py](backend/flex_query.py)
|
||
|
|
- [.env.example](.env.example)
|
||
|
|
- [data/flex/.gitkeep](data/flex/.gitkeep)
|
||
|
|
|
||
|
|
## What Still Needs To Be Wired In
|
||
|
|
|
||
|
|
The Flex Query data is not yet merged into `/api/lots`.
|
||
|
|
|
||
|
|
The next implementation step is:
|
||
|
|
|
||
|
|
1. Parse the saved Flex XML.
|
||
|
|
2. Normalize trades into a local fill ledger.
|
||
|
|
3. Build lots from that persistent history.
|
||
|
|
4. Use that ledger as the primary source for `buy_time`, `cost_basis`, `CAGR`, and true open lots.
|
||
|
|
|
||
|
|
## Notes
|
||
|
|
|
||
|
|
- The frontend currently focuses on the lot table.
|
||
|
|
- The backend still uses the IB socket API for live positions and prices.
|
||
|
|
- The Flex path is intended to become the historical source of truth for lots.
|