Automated Capital Gains & Dividend Tax Calculator for Polish Residents using Interactive Brokers.
- Privacy First: All financial data is stored in a local SQLCipher (AES-256) encrypted database.
The SQLCipher driver and a non-empty
SQLCIPHER_KEYare required; the application refuses plaintext SQLite. - Universal Parser: Supports both Activity Statements and Flex Queries.
- Smart NBP Rates: T-1 rule compliant, using Batch Caching logic.
- FIFO Algorithm: Strictly follows tax laws for Cost Basis.
- PIT-38 Ready: Generates a PDF report compatible with Polish tax forms.
-
Clone:
git clone [https://github.com/your-repo/ibkr-tax-gemini.git](https://github.com/your-repo/ibkr-tax-gemini.git) cd ibkr-tax-gemini -
Install:
pip install -r requirements.txt
This installs the
sqlcipher3driver required for encrypted database access. -
Setup Security: Create
.env:SQLCIPHER_KEY=your_secret_key DATABASE_PATH=db/ibkr_history.db.enc
The main.py script is now the single entry point for all operations.
# 1. Import Data
# Automatically scans the project 'data/' folder and adds only new records.
# Repeated imports are idempotent and report inserted/skipped counts.
python main.py --import-data
# 2. Generate Report
# Calculates taxes for the specific year using FIFO and NBP rates.
python main.py --target-year 2024 --export-pdf --export-excelCheck whether imported history contains enough FIFO inventory for planned sales. This is evidence for a preflight review only: it does not calculate tax, create a sale, or persist any transaction.
python main.py --planned-sale AAPL:10:2024-12-31 --coverage-output json
python main.py --coverage-file planned-sales.jsonThe JSON file contains an array of objects with ticker, quantity, and as_of.
The report includes per-asset status, available and missing quantity, and FIFO
lot evidence. NOT_COVERED with history_found: false means no broker history
was imported for that asset; it is distinct from an imported history with zero
remaining holdings.
Calculations stop with a diagnostic if an NBP rate is unavailable or a sale cannot be matched to inventory. Export failures are also reported as errors; the application does not present incomplete tax totals as valid reports.
Install Python dependencies, then start the Electron dashboard:
cd gui
npm install
npm startThe GUI starts a local backend on 127.0.0.1:8000, waits for its /health
endpoint, and uses the same encrypted database and report output as the CLI.
CSV import from data/ remains the default and required workflow. A
read-only live connection to Interactive Brokers TWS/IB Gateway is available
as an opt-in alternative/supplement for pulling recent executed trades
directly from a running Gateway session.
Setup requirements:
- Install and run IB Gateway (recommended) or TWS, and log in to a paper trading account (recommended for testing) or live account.
- In IB Gateway/TWS, enable API access: Configure → Settings → API →
Enable ActiveX and Socket Clients, and add
127.0.0.1to trusted IPs. - Note the socket port shown in the API settings. Defaults used by this
project:
4002(paper Gateway),4001(live Gateway),7497(paper TWS),7496(live TWS). - Add to your
.envto opt in (live sync is disabled unless set):Each concurrent connection to the same Gateway must use a distinctIB_LIVE_ENABLED=True IB_HOST=127.0.0.1 IB_PORT=4002 IB_CLIENT_ID=1
IB_CLIENT_ID. - In the desktop GUI, use Check IB Connection to verify connectivity and Live Sync to pull and store new executions. Both actions report success/failure in place; neither blocks CSV import if Gateway is down.
Operational limits of read-only access:
- Only executed trades (fills), positions, account summary, and open orders are requested. The connector never places, modifies, or cancels orders.
- Dividends, withholding taxes, and corporate actions are not available through this live path; they still require CSV/Flex Query import.
- Fills reflect executions visible to the current API session. For full historical trade history, use CSV import instead.
- If IB Gateway/TWS is not running, not configured, or the session is lost, the live sync reports a clear error and CSV import continues to work unaffected.
The Client Portal Web API is a separate, HTTPS-based alternative to the socket connector above. It is disabled by default and requires a locally running Client Portal Gateway (CPGW) with a manually authenticated IBKR browser session.
Setup requirements:
- Download and unpack the Client Portal Gateway from Interactive Brokers. Install a supported Java runtime if the Gateway does not include one.
- Start CPGW using its bundled launch script and configuration. Its default
local URL is
https://localhost:5000. - Open that URL in a browser, log in with IBKR credentials, and complete 2FA. The application does not handle credentials, start CPGW, or automate 2FA.
- Add the following to
.envto opt in:CPGW uses a local self-signed certificate by default. KeepIB_WEB_API_ENABLED=True IB_WEB_BASE_URL=https://localhost:5000/v1/api IB_WEB_VERIFY_SSL=False IB_WEB_REQUEST_TIMEOUT=10
IB_WEB_VERIFY_SSL=Falseonly for that local default; set it toTruewhen CPGW is configured with a trusted certificate. - In the desktop GUI, use Check CPGW Connection to inspect the browser session, then Web API Sync to import the available recent executions. A "log in via the browser" message means CPGW needs a fresh manual login.
Operational limits of read-only access:
- The connector requests account data, open positions, and recent trade confirmations only. It never creates, modifies, or cancels orders.
- The Web API trade endpoint is not a complete historical statement. Use the CSV/Flex Query import for historical executions, dividends, withholding tax, and corporate actions.
- CPGW sessions expire and must be kept alive; a later expiry requires another browser login with 2FA. Permission and rate-limit responses are reported as actionable sync errors.
- The Web API connector, the TWS/Gateway connector, and CSV import are independent. A failure in one does not block either of the others.
Educational purpose only. Not financial advice.