Interactive Brokers API in Docker

While Interactive Brokers provide arguably the most extensive retail-level API available for trading, the software is quite frustrating to work with. Rather than IB offering you an API endpoint on their server to interact with, you must run their Gateway or TWS program on your host and interact with this program, which acts as an intermediary server. Further, both of these programs are point-and-click Java apps, which means setting them up on a VPS is pretty much a nightmare.

IBController

The IBController repository is a great project that allows you to control the IB programs in a headless environment. Even so, I feel there are a few drawbacks to this approach alone:

  • It can still take quite a while to get anything working,
  • The dependancies and extra files you need lying around on the host are messy,
  • If you mess up the configuration beyond repair (through updates, bug-hunting or any number of other honest mistakes), you might to start from scratch again.
Enter Docker

One of the primary motivations of Docker is to resolve the above issues. By storing application code & dependancies in an immutable container, you can build an image with everything necessary "baked in" and have it running in a couple of minutes.

When updating versions of the application within the container, you create a new immutable image, with the old one as a "known working" backup that can be spun up again in a matter of seconds.

IBController in Docker

I've put this repo together to improve what I felt were drawbacks in the default IBController-on-host approach. In full disclosure, all the hard work is done by IBController, and absolutely none of this would be possible without their work.

Your configuration files are mounted into the container at launch time, ensuring they can be easily changed without rebuilding the image.

Before doing this, you should (on a computer with a GUI) set up IB Gateway, login, and modify the settings according to your preferences. Save the jts.ini file (likely in a location such as ~/Jts/jts.ini), which has the IB settings in it, and upload that to your server.

tl;dr

0) Ensure you have Docker installed. I've written this with Ubuntu flavours of Linux in mind.

1) On your server, git clone git@github.com:ryankennedyio/ib-docker.git

2) cd ib-docker && sudo docker build -t ib-docker:<pick-a-version-number> .

3) Modify the docker-compose.yml file to add your own settings.

4) Copy your jts.ini file into the repository, overwriting the default.

5) Make any changes you wish to IBController.ini (also a settings file)

6) docker-compose up -d

After about 30 seconds, you should be able to interact with the IB API on localhost:4003 from any program running on the host machine.

You now have an immutable image with a particular version of IB and all dependancies maintained within. If you mess something up beyond repair (which is inevitable if you are a human), you can rebuild it from in a couple of minutes.

You should aim to be able to spin up a fresh server with your entire trading system from scratch in no more than a few hours, and Docker is an excellent tool to manage your infrastructure. Remember, you want services to be cattle, not pets.

N.B. Ports & Settings

If you require a different port, I'd suggest changing the hardcoded references to 4003 in the repository to a port of your choice. This is a workaround hack, made necessary by the IBController program having no direct control on the IP address and port that the IB Gateway or TWS program binds itself to. In order to expose a network address from docker to the host, a service must be bound to 0.0.0.0:<port>. This doesn't happen by default, and we have no control over it, so we use the socat command inside runscript.sh to effectively duplicate the IB network stream and bind it to 0.0.0.0:4003.

There are also a few todo statements littered around, where some settings are duplicated in either IBController.ini and jts.ini. Some of the default settings in IBController.ini might not be suitable for every use case (though they are fine for me), so I suggest reading their documentation for more information.

comments powered by Disqus