├── .gitignore ├── Dockerfile ├── LICENSE ├── README.md ├── docker-compose.yml ├── docs └── ib_gateway_vnc.jpg ├── ib ├── IBController.ini └── jts.ini ├── runscript.sh └── vnc ├── vnc_init ├── xvfb-daemon-run └── xvfb_init /.gitignore: -------------------------------------------------------------------------------- 1 | .project 2 | .classpath 3 | .settings/ 4 | .groovy/ 5 | .idea/ 6 | 7 | bin/ 8 | target/ 9 | 10 | *.pyc 11 | 12 | Logs/* 13 | 14 | node_modules/ 15 | 16 | *.local 17 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM ubuntu:16.04 2 | 3 | LABEL maintainer="Mike Ehrenberg " 4 | 5 | RUN apt-get update \ 6 | && apt-get install -y wget \ 7 | && apt-get install -y unzip \ 8 | && apt-get install -y xvfb \ 9 | && apt-get install -y libxtst6 \ 10 | && apt-get install -y libxrender1 \ 11 | && apt-get install -y libxi6 \ 12 | && apt-get install -y x11vnc \ 13 | && apt-get install -y socat \ 14 | && apt-get install -y software-properties-common \ 15 | && apt-get install -y dos2unix 16 | 17 | # Setup IB TWS 18 | RUN mkdir -p /opt/TWS 19 | WORKDIR /opt/TWS 20 | RUN wget -q http://cdn.quantconnect.com/interactive/ibgateway-latest-standalone-linux-x64-v974.4g.sh 21 | RUN chmod a+x ibgateway-latest-standalone-linux-x64-v974.4g.sh 22 | 23 | # Setup IBController 24 | RUN mkdir -p /opt/IBController/ && mkdir -p /opt/IBController/Logs 25 | WORKDIR /opt/IBController/ 26 | RUN wget -q http://cdn.quantconnect.com/interactive/IBController-QuantConnect-3.2.0.5.zip 27 | RUN unzip ./IBController-QuantConnect-3.2.0.5.zip 28 | RUN chmod -R u+x *.sh && chmod -R u+x Scripts/*.sh 29 | 30 | WORKDIR / 31 | 32 | # Install TWS 33 | RUN yes n | /opt/TWS/ibgateway-latest-standalone-linux-x64-v974.4g.sh 34 | 35 | ENV DISPLAY :0 36 | 37 | ADD runscript.sh runscript.sh 38 | ADD ./vnc/xvfb_init /etc/init.d/xvfb 39 | ADD ./vnc/vnc_init /etc/init.d/vnc 40 | ADD ./vnc/xvfb-daemon-run /usr/bin/xvfb-daemon-run 41 | 42 | RUN chmod -R u+x runscript.sh \ 43 | && chmod -R 777 /usr/bin/xvfb-daemon-run \ 44 | && chmod 777 /etc/init.d/xvfb \ 45 | && chmod 777 /etc/init.d/vnc 46 | 47 | RUN dos2unix /usr/bin/xvfb-daemon-run \ 48 | && dos2unix /etc/init.d/xvfb \ 49 | && dos2unix /etc/init.d/vnc \ 50 | && dos2unix runscript.sh 51 | 52 | # Below files copied during build to enable operation without volume mount 53 | COPY ./ib/IBController.ini /root/IBController/IBController.ini 54 | COPY ./ib/jts.ini /root/Jts/jts.ini 55 | 56 | CMD bash runscript.sh 57 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Manuel Martínez-Almeida 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Interactive Brokers Gateway Docker 2 | 3 | IB Gateway running in Docker with [IB Controller](https://github.com/ib-controller/ib-controller/) and VNC 4 | 5 | * TWS Gateway: v974.4g 6 | * IB Controller: v3.2.0 7 | 8 | ### Docker Hub image 9 | 10 | * https://hub.docker.com/r/mvberg/ib-gateway-docker 11 | 12 | ### Getting Started 13 | 14 | ```bash 15 | > git clone 16 | > cd ib-gateway-docker 17 | > docker build . 18 | > docker-compose up 19 | ``` 20 | 21 | #### Expected output 22 | 23 | ```bash 24 | Creating ibgatewaydocker_tws_1 ... 25 | Creating ibgatewaydocker_tws_1 ... done 26 | Attaching to ibgatewaydocker_tws_1 27 | tws_1 | Starting virtual X frame buffer: Xvfb. 28 | tws_1 | find: '/opt/IBController/Logs': No such file or directory 29 | tws_1 | stored passwd in file: /.vnc/passwd 30 | tws_1 | Starting x11vnc. 31 | tws_1 | 32 | tws_1 | +============================================================================== 33 | tws_1 | + 34 | tws_1 | + IBController version 3.2.0 35 | tws_1 | + 36 | tws_1 | + Running GATEWAY 960 37 | tws_1 | + 38 | tws_1 | + Diagnostic information is logged in: 39 | tws_1 | + 40 | tws_1 | + /opt/IBController/Logs/ibc-3.2.0_GATEWAY-960_Tuesday.txt 41 | tws_1 | + 42 | tws_1 | + 43 | tws_1 | Forking :::4001 onto 0.0.0.0:4003\n 44 | ``` 45 | 46 | You will now have the IB Gateway app running on port 4003 and VNC on 5901. 47 | 48 | See [docker-compose.yml](docker-compose.yml) for configuring VNC password, accounts and trading mode. 49 | 50 | Please do not open your box to the internet. 51 | 52 | ### Testing VNC 53 | 54 | * localhost:5901 55 | 56 | ![vnc](docs/ib_gateway_vnc.jpg) 57 | 58 | ### Demo Accounts 59 | 60 | It seems that all of the `demo` accounts are dead for good: 61 | 62 | * edemo 63 | * fdemo 64 | * pmdemo 65 | 66 | ### Troubleshooting 67 | 68 | Sometimes, when running in non-daemon mode, you will see this: 69 | 70 | ```java 71 | Exception in thread "main" java.awt.AWTError: Can't connect to X11 window server using ':0' as the value of the DISPLAY variable. 72 | ``` 73 | 74 | You will have to remove the container `docker rm container_id` and run `docker-compose up` again. 75 | -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '2' 2 | services: 3 | tws: 4 | build: . 5 | ports: 6 | - "4003:4003" 7 | - "5901:5900" 8 | volumes: 9 | - ./ib/IBController.ini:/root/IBController/IBController.ini 10 | - ./ib/jts.ini:/root/Jts/jts.ini 11 | environment: 12 | - TZ=America/Chicago 13 | # Variables pulled from /IBController/IBControllerGatewayStart.sh 14 | - VNC_PASSWORD=1234 # CHANGEME 15 | - TWS_MAJOR_VRSN=974 16 | - IBC_INI=/root/IBController/IBController.ini 17 | - IBC_PATH=/opt/IBController 18 | - TWS_PATH=/root/Jts 19 | - TWS_CONFIG_PATH=/root/Jts 20 | - LOG_PATH=/opt/IBController/Logs 21 | - JAVA_PATH=/opt/i4j_jres/1.8.0_152/bin # JRE is bundled starting with TWS 952 22 | - TRADING_MODE=paper # either paper or live 23 | - TWSUSERID=fdemo # IB account 24 | - TWSPASSWORD=demouser # IB account password 25 | - FIXUSERID= 26 | - FIXPASSWORD= 27 | - APP=GATEWAY -------------------------------------------------------------------------------- /docs/ib_gateway_vnc.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mvberg/ib-gateway-docker/e4e454bd921f754673fdd89b68a9791c0af099cd/docs/ib_gateway_vnc.jpg -------------------------------------------------------------------------------- /ib/IBController.ini: -------------------------------------------------------------------------------- 1 | # Original source: https://github.com/ib-controller/ib-controller/blob/master/resources/IBController.ini 2 | 3 | LogToConsole=yes 4 | FIX=no 5 | 6 | # IB API Authentication Settings 7 | # ------------------------------ 8 | #IbLoginId=fdemo 9 | #IbPassword=demouser 10 | PasswordEncrypted=no 11 | TradingMode=paper 12 | 13 | # 3. TWS Startup Settings 14 | # ------------------------- 15 | # IMPORTANT -- Docker-compose mounts this from host FS into Docker 16 | # for persistence. You likely shouldn't change this. 17 | IbDir= 18 | # TODO 19 | 20 | StoreSettingsOnServer=no 21 | 22 | MinimizeMainWindow=no 23 | ExistingSessionDetectedAction=primary 24 | AcceptIncomingConnectionAction=accept 25 | ShowAllTrades=no 26 | ForceTwsApiPort=4001 27 | ReadOnlyLogin=no 28 | AcceptNonBrokerageAccountWarning=yes 29 | 30 | # 5. TWS Tidy Closedown Time 31 | # ---------------------------- 32 | # TODO - DECIDE IF THIS IS GOOD IN DOCKER 33 | # To tell IBController to tidily close TWS at a 34 | # specified day of the week and time, set this value 35 | # to 36 | # for example: 37 | # ClosedownAt=Friday 22:00 38 | # 39 | # Note that the day of the week must be specified using your 40 | # default locale. Also note that Java will only accept 41 | # characters encoded to ISO 8859-1 (Latin-1). This means that 42 | # if the day name in your default locale uses any non-Latin-1 43 | # characters you need to encode them using Unicode escapes 44 | # (see http://java.sun.com/docs/books/jls/third_edition/html/lexical.html#3.3 45 | # for details). For example, to tidily close TWS at 12:00 on 46 | # Saturday where the default locale is Simplified Chinese, 47 | # use the following: 48 | # #ClosedownAt=\u661F\u671F\u516D 12:00 49 | ClosedownAt= 50 | IbAutoClosedown=yes 51 | 52 | AllowBlindTrading=no 53 | DismissPasswordExpiryWarning=no 54 | DismissNSEComplianceNotice=yes 55 | 56 | # TODO - set up appropriate docker default 57 | SaveTwsSettingsAt= 58 | 59 | IbControllerPort=7462 60 | IbControlFrom= 61 | IbBindAddress= 62 | CommandPrompt= 63 | SuppressInfoMessages=yes 64 | LogComponents=never 65 | -------------------------------------------------------------------------------- /ib/jts.ini: -------------------------------------------------------------------------------- 1 | [IBGateway] 2 | WriteDebug=false 3 | TrustedIPs=127.0.0.1 4 | MainWindow.Height=550 5 | RemoteHostOrderRouting=hdc1.ibllc.com 6 | RemotePortOrderRouting=4000 7 | LocalServerPort=4000 8 | ApiOnly=true 9 | MainWindow.Width=700 10 | 11 | [Logon] 12 | useRemoteSettings=false 13 | TimeZone=America/Chicago 14 | tradingMode=p 15 | colorPalletName=dark 16 | Steps=6 17 | Locale=en 18 | SupportsSSL=gdc1.ibllc.com:4000,true,20190521,false 19 | UseSSL=true 20 | os_titlebar=false 21 | s3store=true 22 | 23 | [ns] 24 | darykq=1 25 | 26 | [Communication] 27 | SettingsDir=/root/Jts 28 | Peer=gdc1.ibllc.com:4001 29 | Region=hk 30 | 31 | -------------------------------------------------------------------------------- /runscript.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | xvfb-daemon-run /opt/IBController/Scripts/DisplayBannerAndLaunch.sh & 4 | # Tail latest in log dir 5 | sleep 1 6 | tail -f $(find $LOG_PATH -maxdepth 1 -type f -printf "%T@ %p\n" | sort -n | tail -n 1 | cut -d' ' -f 2-) & 7 | 8 | # Give enough time for a connection before trying to expose on 0.0.0.0:4003 9 | sleep 30 10 | echo "Forking :::4001 onto 0.0.0.0:4003\n" 11 | socat TCP-LISTEN:4003,fork TCP:127.0.0.1:4001 12 | -------------------------------------------------------------------------------- /vnc/vnc_init: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | 3 | VNC=/usr/bin/x11vnc 4 | VNCARGS="-forever -rfbport 5900 -rfbauth /.vnc/passwd \ 5 | -o /.vnc/x11vnc.log -display $DISPLAY" 6 | PIDFILE=/var/vnc.pid 7 | case "$1" in 8 | start) 9 | echo -n "Starting x11vnc" 10 | /sbin/start-stop-daemon --start --quiet --pidfile $PIDFILE --make-pidfile --background --exec $VNC -- $VNCARGS 11 | echo "." 12 | ;; 13 | stop) 14 | echo -n "Stopping x11vnc" 15 | /sbin/start-stop-daemon --stop --quiet --pidfile $PIDFILE 16 | echo "." 17 | ;; 18 | restart) 19 | $0 stop 20 | $0 start 21 | ;; 22 | *) 23 | echo "Usage: /etc/init.d/xvfb {start|stop|restart}" 24 | exit 1 25 | esac 26 | exit 0 27 | -------------------------------------------------------------------------------- /vnc/xvfb-daemon-run: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | /etc/init.d/xvfb start 3 | sleep 1 4 | 5 | # start VNC if password exists 6 | if [ "$VNC_PASSWORD" ]; then 7 | mkdir /.vnc 8 | x11vnc -storepasswd "$VNC_PASSWORD" /.vnc/passwd > /dev/null 9 | /etc/init.d/vnc start 10 | fi 11 | 12 | $@ 13 | exit_value=$? 14 | 15 | [ "$VNC_PASSWORD" ] && /etc/init.d/vnc stop 16 | /etc/init.d/xvfb stop 17 | 18 | exit $exit_value 19 | -------------------------------------------------------------------------------- /vnc/xvfb_init: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | 3 | XVFB=/usr/bin/Xvfb 4 | XVFBARGS="$DISPLAY -ac -screen 0 1024x768x16 +extension RANDR" 5 | PIDFILE=/var/xvfb_${DISPLAY:1}.pid 6 | case "$1" in 7 | start) 8 | echo -n "Starting virtual X frame buffer: Xvfb" 9 | /sbin/start-stop-daemon --start --quiet --pidfile $PIDFILE --make-pidfile --background --exec $XVFB -- $XVFBARGS 10 | echo "." 11 | ;; 12 | stop) 13 | echo -n "Stopping virtual X frame buffer: Xvfb" 14 | /sbin/start-stop-daemon --stop --quiet --pidfile $PIDFILE 15 | echo "." 16 | ;; 17 | restart) 18 | $0 stop 19 | $0 start 20 | ;; 21 | *) 22 | echo "Usage: /etc/init.d/xvfb {start|stop|restart}" 23 | exit 1 24 | esac 25 | exit 0 26 | --------------------------------------------------------------------------------