How I Got IBKR TWS & Gateway Working with C++ on Ubuntu 22 (WSL) — Full Setup, Build, Run, and Troubleshooting
- Bryan Downing
- Aug 13
- 9 min read
Introduction
If you’re trying to run Interactive Brokers (IBKR) software and the IB API from a Windows 11 host using Ubuntu 22 under WSL, this is a practical, experience-based guide that will save you hours of debugging. In this article I cover why I favored IBKR TWS over the Gateway GUI for development, how to configure TWS for API access, running the TWS process in the background inside WSL, building and running a C++ demo that downloads live or historical market data, and common issues (including subscription fallbacks and segmentation faults). Keywords: Interactive Brokers, TWS, IBKR Gateway, IB API C++, Ubuntu 22, WSL, Windows 11, historical data, live data.
Why this setup?
There are three common deployment patterns for IB API development:
Native Windows using Trader Workstation (TWS) or IB Gateway.
Linux server (headless) running IB Gateway for production/cloud deployments.
Windows host with WSL (Ubuntu) for Linux-oriented development and builds, while still using Windows for GUI access or other tools.
I used Windows 11 as the host with Ubuntu 22 running under WSL for development in C++. This gives the convenience of Linux toolchains, package managers, and a consistent development environment while keeping Windows for screen recording, desktop utilities, or other Windows-only tools. The IB API examples (C++, Java, Python) are available in the IB download packages and can be built on Linux. The challenge is ensuring TWS (or Gateway) can accept API connections from the WSL environment reliably.
TWS vs Gateway: Which should you use for development?
Short answer: for development and debugging, TWS (Trader Workstation) is usually easier. Reasons:
TWS provides a GUI that makes enabling API access and testing straightforward.
TWS includes configuration options (classic mode) for API ports, trusted IPs, and toggling read-only mode.
The Gateway can run headless for production, but the gateway GUI and headless variants can be more fragile to configure across WSL and cloud environments.
IB Gateway/minimal GUI headless setups are often required for cloud deployments, but for local development you’ll likely be faster with TWS.
I spent a lot of time experimenting with the IB Gateway GUI on Linux, but ultimately I moved to TWS (running from WSL) because it was simpler to configure and to iterate on the C++ demo.
Prerequisites & assumptions
Windows 11 host, WSL2 installed and configured.
Ubuntu 22 distribution installed under WSL.
Java runtime available in Ubuntu (TWS is a Java app). WSLg in Windows 11 can display Linux GUI apps if needed; but TWS can be launched and run without active display using nohup or as a service in the background.
Basic familiarity with Linux command line, building C++ projects, and editing files.
An Interactive Brokers account (paper or live) and, if necessary, market data subscriptions for real-time feeds. Historical data is available without subscription for many instruments.
High-level workflow
Download IBKR TWS (or IB Gateway) and the IB API package (contains C++ sample).
Configure TWS for API access (classic settings): enable ActiveX & socket clients, set trusted IPs, set port and read-only flags.
Install and configure Java in WSL if needed.
Launch TWS inside WSL; run it in the background with nohup or configure a systemd service.
Unpack the IB API package, run the build script for the C++ demo (or manually compile).
Run the demo against the running TWS. If real-time subscription fails due to missing market data subscription, the demo should fall back to historical data.
Troubleshoot common errors: connection refused, no market data, segmentation faults, missing libraries.
Step-by-step: Downloading and preparing files
Obtain the IB API package and TWS from Interactive Brokers. On Linux, you can wget the package if you have the direct URL:
Example placeholder: wget https://www.interactivebrokers.com/path/to/IBKR_API_Linux.zip
Unzip into your workspace:
unzip IBKR_API_Linux.zip -d ~/ibkr_api
Inspect the package. Typical layout:
include/ (headers for C++ API)
source/ (sample C++, Java, Python)
lib/ (native libraries)
readme and build scripts (e.g., build.sh)
Make build scripts executable:
chmod +x build.sh
If your package includes a demo runner (e.g., build_ibkr_demo), that script should compile/produce the demo binary.
Configuring TWS for API access
Before your C++ application can connect, TWS must be configured to allow API clients.
Launch TWS and open Settings → Global Configuration → API → Settings (or use the classic mode configuration if you prefer the older layout).
Enable:
"Enable ActiveX and Socket Clients"
Make sure “Read-Only API” is unchecked if you plan to place orders.
Trusted IPs:
Add 127.0.0.1 (or the WSL host IP if connecting cross-host). For most WSL setups use 127.0.0.1.
Port:
Default API port for TWS: 7496 (live) and 7497 (paper) in many setups. Historically these are the standard ports; verify your TWS configuration and adapt accordingly.
Apply and save. If TWS is restarted it will listen on the configured port.
Running TWS inside WSL (background/service)
You can run TWS inside WSL in a few ways:
Foreground with GUI (WSLg): If you have WSLg enabled on Windows 11 you can run TWS and it will display its GUI window.
Background with nohup: For many setups, running TWS in the background inside WSL is sufficient:
nohup /path/to/tws &>/dev/null &
This runs TWS detached from your shell. Note: some TWS startup scripts require a display; but if TWS runs headless without a display you may need Java headless mode or use a headless gateway instead.
Systemd service: Windows 11 now supports systemd in WSL (if enabled). Create a service unit to start TWS automatically. This is useful if you want TWS to start whenever the WSL distro starts.
Example: launching TWS with nohup
Navigate to your TWS installation directory and run:
nohup ./tws &
If you plan to run TWS every time WSL boots, create a systemd unit (if systemd is supported in your WSL distro) or add a startup script that runs when WSL launches.
Building the C++ demo
Most IB API packages include example source code and a build script. The transcript’s demo used a build.sh. Typical steps:
Make the build script executable:
chmod +x build.sh
Run it:
./build.sh
If the build script fails, inspect it to see the compiler flags and libraries it uses. You may need to:
Install developer tools: sudo apt update && sudo apt install build-essential g++ make
Ensure you have the correct include and lib paths for the IB API (point compiler to include/ and lib/ inside the IB API package).
For linking, you may need to specify -L/path/to/ibapi/lib and -l<ibLibraryName> or link the necessary .so files.
Basic compile example (conceptual)
g++ -std=c++17 -I~/ibkr_api/include -L~/ibkr_api/lib -o ibkr_demo src/main.cpp -llibname
Note: the actual library name and linking flags depend on the package.
Running the demo: live vs paper vs historical fallback
Once TWS is running and your demo binary is built, run the demo and watch the console/logs. Typical behavior:
The demo will connect to TWS on the configured API port and attempt to subscribe to real-time market data for symbols such as AAPL, MSFT, TSLA, GOOGL.
If your IB account does not have subscriptions for live market data, the API returns no market data events. A robust demo will detect this and fall back to historical data requests (which are often available without subscription).
Historical data calls return OHLCV series for requested symbols and time ranges. The demo should process these and print or store results.
Key runtime considerations:
Ensure TWS is started before attempting to connect.
Double-check port and trusted IP settings.
If you intend to place orders in live mode, make sure “Read-only API” is unchecked and your account permissions allow trading.
Running in paper trading mode is safer for testing order placement.
A note about segmentation faults and C++
C++ is unforgiving. The transcript mentioned segmentation faults at the end of runs. Common causes:
Dereferencing null pointers returned by the API when a call failed.
Race conditions where the demo tries to access API objects after disconnect.
Improper binary/library mismatches (ABI), such as linking against the wrong version of a library.
Missing exception handling around API callbacks.
Fixes:
Add robust error handling in your C++ callbacks.
Check return values before using data.
Use smart pointers and RAII patterns to manage resource lifetimes.
Compile with debugging symbols (g++ -g) and use gdb to trace segmentation faults.
Run the binary under valgrind (if possible in WSL) to catch memory issues.
Troubleshooting common issues
Connection refused or cannot connect:
Ensure TWS is running.
Confirm API port matches the demo's port.
Confirm trusted IP includes 127.0.0.1.
Confirm no firewall is blocking the port.
“No market data” messages:
You likely lack a market data subscription for the requested symbols.
The demo should fall back to historical data; if it doesn’t, add fallback logic.
Try requesting historical data for the same symbols; historical data is often available.
Wrong port or confusion between live/paper:
Double-check: default TWS ports are typically 7496 (live) and 7497 (paper). Confirm in TWS configuration.
Library linking errors at runtime:
Ensure your LD_LIBRARY_PATH includes the directory containing IB API .so files.
Example: export LD_LIBRARY_PATH=~/ibkr_api/lib:$LD_LIBRARY_PATH
GUI-related errors when launching TWS in WSL:
Use WSLg to display GUI apps; if you want headless, consider IB Gateway headless configs or launch TWS with nohup and Java headless flags if necessary.
Demo stops with exceptions or segmentation faults:
Run with gdb for stack trace.
Compile with -fsanitize=address for memory sanitizer (if supported) to detect buffer overflows or use-after-free bugs.
Designing robust API clients: recommended practices
Retry logic: If a subscription fails, implement retries with exponential backoff for transient network issues.
Fallbacks: Implement historical-data fallback when subscription data isn’t available to ensure you still have usable OHLCV series.
Logging: Log API requests, responses, error codes, and timestamps. This helps debug disconnections or missing data.
Resource management: Cleanly disconnect and deregister callbacks on program exit.
Testing in paper mode: Use paper trading to validate order placement without risking capital.
Version control: Keep the IB API version consistent between sample code and the server-side (TWS/Gateway).
Security & production considerations
When you move to production or cloud deployment, running a headless Gateway is common, but be careful:
Headless cloud VMs often don't have a desktop environment; Gateway must run in headless mode.
Protect API ports—open them only to trusted networks or localhost via tunnels.
Store credentials securely. Do not hardcode plain text credentials in source.
Consider running IB Gateway on a dedicated machine or container with limited access.
Why IBKR is not for high-frequency trading (HFT) in most setups
Interactive Brokers is great for many systematic strategies, but not optimized for the ultra-low latency requirements of HFT:
IB's normal API and execution stacks add latency compared to direct market access (DMA) offered by exchanges/CME direct solutions.
Commission structures and exchange fees can make HFT prohibitively expensive for small accounts.
If your plan is low-latency or HFT at scale, consider colocated or direct market access solutions and account sizes that support those costs.
Cloud deployment and headless Gateway
If you plan to deploy a headless Gateway in the cloud, anticipate the following:
Many cloud providers do not offer a GUI. Use IB Gateway headless or a containerized solution.
You’ll need to ensure TWS/Gateway can still accept API connections and that you’ve configured trusted IPs and secure tunnels as needed.
Running Gateway behind a VPN or with strict firewall rules is recommended.
The production environment should be reproducible: automated start scripts, systemd service units, container images, etc.
Sample troubleshooting checklist
TWS running? Yes → proceed. No → start TWS.
Port configured? Match demo config and TWS.
Trusted IP includes 127.0.0.1? Yes.
Read-only unchecked if placing orders? Yes.
Build completed without errors? Yes → run binary.
LD_LIBRARY_PATH set? Yes.
Logs show connection established? Great. If not, inspect logs and increase verbosity.
Example: simple command summary
Fallback & historical data flow (design notes)
A robust client should attempt subscription first, evaluate whether any ticks or snapshot data arrive within a short timeout, and if none do, fall back to historical data:
Request market data subscription for target symbols.
Start a short timer (e.g., 2–5 seconds) to detect first tick/snapshot.
If no data, cancel subscription and request historical data for required resolution/time-range.
Continue with strategy logic using historical series until real-time subscription becomes available.
This approach ensures your strategies can continue to run even without real-time market subscriptions.
Documenting and sharing your work
In my case I put the demo, README, and scripts into a fileshare for my Quant Elite membership (Get In Touch to find out more details) so members can download and test the same setup. If you plan to share code publicly:
Include a README with step-by-step setup instructions for the exact distribution/version.
Include sample config files for trusted IPs, ports, and environment variables.
Provide example run logs demonstrating success and fallback behavior.
Conclusion & next steps
Running IBKR TWS and the IB API from a C++ client inside Ubuntu 22 on WSL is absolutely feasible, but it requires attention to configuration details: enabling the API in TWS, setting trusted IPs and correct ports, running TWS in the background (or as a service), and building/linking the C++ demo properly. Expect to spend time debugging library and pointer issues typical of C++ development. The biggest functional gotcha for many users is not having market data subscriptions, so implementing a historical data fallback gives you a robust demo experience.
.
Visit quantabsnet.com for more resources, the membership fileshare (demo source & README), and a free C++ eBook that covers infrastructure patterns used by professional trading shops. If you leave questions or describe a specific error, I can provide targeted troubleshooting steps or a sample systemd unit and build commands tailored to your IB API release.
Appendix: Quick reference
Default TWS ports (verify in your settings): 7496 (live), 7497 (paper).
Trusted IP: 127.0.0.1 for WSL local connections.
Enable: ActiveX & Socket Clients; uncheck “Read-only API” if placing orders.
Background run: nohup ./tws & or systemd service.
Export libs: export LD_LIBRARY_PATH=~/ibkr_api/lib:$LD_LIBRARY_PATH
Thanks for reading — happy coding and safe trading.