/docker-tws

Primary LanguagePythonOtherNOASSERTION

docker-tws

Docker image for Interactive Brokers TWS hosted by IBC running under TightVNC.

  • User configuration is cleanly separated, allowing one computer to serve many accounts, store configuration in Kubernetes secrets, and for one-size-fits-all images to exist on Docker Hub.

  • In line with Kubernetes best practice, IBC and TWS logs are redirected to container stdout.

  • Docker Hub images are completely transparent, except for upload credentials. CI configuration is checked in, and the build log for each cryptographic image digest can be audited via GitHub Actions.

  • TWS auto-restart is supported. If TWS exits, the container will search for a replacement Java process and continue running when one is found.

  • krallin/tini is used to avoid stray TWS zombie processes accumulating over auto-restarts.

  • Running multiple TWS containers within one Kubernetes pod is supported, to allow real time market data to be shared between live and paper trading accounts.

Usage

docker run \
    --rm -it \
    -e VNC_PASSWORD=123 \
    -p 127.0.0.1:5900:5900 \
    -p 127.0.0.1:7496:7496 \
    dockertws/dockertws:ci

Optionally supply credentials using:

    -e IBC_USERNAME=myuser123
    -e IBC_PASSWORD=OpenSesame

Optionally supply jts.ini and tws.xml from an existing TWS installation using:

    -v /path/to/jts.ini:/conf/jts.ini:ro
    -v /path/to/tws.xml:/conf/tws.xml:ro

Extracting jts.ini and tws.xml

For each account you intend to use the image with, login to TWS from a desktop computer, or simply start the container and login through it. Repeat for each desired account. Now grab jts.ini from your installation, which will contain a list of encoded account usernames docker-tws needs to know where to copy tws.xml to.

Simply grab tws.xml after you have finished customizing it. If you created the files inside a Docker image, use something like docker cp to extract them.

Exposed Ports

Port Description
5900 / 5901 VNC display (modify using VNC_DISPLAY option)
7462 / 7463 IBC telnet server
7496 TWS API live trading account
7497 TWS API paper trading account (modify using TWS_API_PORT)

Volumes

All paths are optional.

Path Description
/conf Read-only directory of configuration files to install. Usable as a Docker or Kubernetes volume
/conf/jts.ini File to install as ~tws/Jts/jts.ini
/conf/tws.xml or tws.xml.gz or tws.xml.zst File to install as ~tws/Jts/[profile]/tws.xml. If provided, jts.ini must also be provided, as it is needed to detect the profile name.

To fit the XML in a Kubernetes secret it is likely necessary to compress it. The image supports zstd specifically for this task, which outperforms gzip by a factor of 2, which in some cases may be required. Recommended command line: zstd -19 tws.xml
/home/tws Home directory that can be mapped to a shared volume such as a Kubernetes emptyDir. On initial startup, the directory is locked and a pristine TWS is copied into it, if it was previously empty. See Simultaneous Live/Paper Containers for details.
/home/tws/Jts Per-container application directory that can be mapped to a private volume such as a Kubernetes emptyDir. On initial startup, the directory is populated with a pristine copy of TWS, if it was previously empty. pristine TWS is copied into it, if it was previously empty. See Simultaneous Live/Paper Containers for details.

 

Avoid storing this volume persistently, as the TWS program code is copied into it, complicating the task of upgrading TWS version in use.

Simultaneous Live/Paper Containers

Your live account and the paper account associated with it may be used simultaneously, with both receiving real-time market data, so long as both are used on the same computer. TWS uses a fingerprinting mechanism to verify this, which breaks if the accounts run in different pods, possibly due to changes in container IP or MAC addresses.

However, by hosting both instances as containers within the same Kubernetes pod, with a shared volume mapped over /home/tws, and a per-container private emptyDir volume mapped over /home/tws/Jts, the check succeeds and it becomes possible to host this configuration with unattended logins, VNC and restarts for both accounts.

The emptyDir mapping over /home/tws/Jts is necessary since it seems impossible to change the location of /home/tws/Jts/jts.ini, causing a race at startup as the copies of IBC running in each pod update this file to configure their associated trading mode.

Example

An example "combined live/paper" Kubernetes configuration as described below is supplied in example/tws-combined.yml.

Paper Account Setup

Ensure your paper trading account is configured to share real-time market data.

  1. From the Interactive Brokers web app, click the burger menu in the top left
  2. Choose "Settings" from near the bottom
  3. Choose "Account Settings" from the sub-menu
  4. Click the gear icon next to "Paper Trading Account" in the right-hand column about one third of the way down
  5. Enable the option to share real-time market data
  6. Wait a few hours for the configuration change to take effect

Container / Volume / Environment Variable Setup

When docker-tws starts, if /home/tws or /home/tws/Jts are empty, they are initialized from a pristine TWS installation stored in the image. The volumes required are:

  • /home/tws: an emptyDir shared volume mounted in both containers. This volume will contain at least a magic .hwid file that appears to be part of the fingerprinting process.

  • /home/tws/Jts: an emptyDir volume that is private to each container, needed to avoid a startup race condition.

  • VNC_DISPLAY should be set to 1 for the paper trading container, so that both VNC servers can share the pod IP address.

  • TWS_API_PORT should be set to 7497 for the paper trading container, so that both API servers can share the pod IP address.

Environment Variables

See the IBC documentation for a description of IBC settings.

Key Default Description
JVM_HEAP_SIZE 4096m Value of `-Xmx` JVM flag in `tws.vmoptions`
IBC_USERNAME
IBC_PASSWORD
IBC_FIX no
IBC_FIX_USERNAME
IBC_FIX_PASSWORD
IBC_TRADING_MODE live
IBC_SEND_TWS_LOGS_TO_CONSOLE yes If `true`, TWS diagnostic logs will also be sent to the container's stdout
IBC_STORE_SETTINGS_ON_SERVER no
IBC_MINIMIZE_MAIN_WINDOW no
IBC_MAXIMIZE_MAIN_WINDOW yes
IBC_EXISTING_SESSION_DETECTED manual
IBC_ACCEPT_INCOMING_CONNECTION accept
IBC_SHOW_ALL_TRADES no
IBC_READONLY_LOGIN no
IBC_READONLY_API
IBC_ACCEPT_NON_BROKERAGE_WARNING yes
IBC_AUTO_CLOSEDOWN yes
IBC_CLOSEDOWN_AT
IBC_ALLOW_BLIND_TRADING no
IBC_DISMISS_PASSWORD_EXPIRY no
IBC_DISMISS_NSE_COMPLIANCE yes
IBC_SAVE_TWS_SETTINGS_AT
IBC_CONTROL_FROM 172.17.0.1
IBC_COMMAND_PROMPT IBC>
IBC_SUPPRESS_INFO_MESSAGES yes
IBC_LOG_COMPONENTS never
TWS_API_PORT If set, the provided tws.xml is rewritten during container startup, to replace its API port with the specified value. This allows you to manage a single tws.xml, with the conflicting setting preventing it running multiple times within a single Kubernetes pod handled automatically.
TWS_LOGOFF_TIME If set, the provided tws.xml is rewritten during container startup, to replace its auto-logoff time with the specified value. This may help avoid a race during startup where both paper and live TWS instances attempt to write their authentication tokens to the same file on disk, causing one or the other instance to attempt to log in using the incorrect mode, or reusing an expired token. This allows your to manage a single tws.xml, with the conflicting setting preventing it running multiple times within a single Kubernetes pod handled automatically.
JDWP_PORT Enable JDWP on port.
TZ America/New_York Container timezone, used by TWS to render timestamps
VNC_DISPLAY 0 VNC X11 display. This is exposed to allow running multiple TWS instances within one Kubernetes pod, where the network interface is shared.
VNC_PASSWORD (random) VNC server password. If unspecified, a random password is logged to stdout
VNC_NAME tws-tradingmode-username VNC desktop name
VNC_DEPTH 24 VNC desktop color depth
VNC_GEOMETRY 1920x1080 VNC desktop resolution
X11_ROOT_COLOR #36648B xsetroot background color

Base System

Ubuntu 20.04

Package Description
wget Used to fetch TWS installer
ca-certificates Inherited from original docker-tws reop
tightvncserver The VNC server
openbox The window manager
xterm Terminal emulator
google-chrome-stable Allows account management, audit trail, 3D volatility surface to be opened
unzip Used to extract IBC
openjfx Needed at least for online help, "No toolkit found" exception in logs otherwise
openjdk-8-jre Possibly optional, or required otherwise data feeds fail to connect
libnss3 Required for Google Chrome
libnspr4 Required for Google Chrome
fonts-liberation Required for Google Chrome
fonts-dejavu-core Required for TWS
fonts-dejavu-extra Required for TWS
libasound2 Required for sound playback
libavcodec58 Required for sound playback
libavformat58 Required for sound playback
libappindicator3-1 Required for Google Chrome
libgbm1 Required for Google Chrome
libxslt1.1 Required for JavaFX WebKit (iBot, various other TWS embedded web views)
libxss1 Required for Google Chrome
xdg-utils Required for Google Chrome
zstd Settings file decompression