├── .gitignore ├── run.sh ├── README.md ├── LICENSE ├── .github └── workflows │ └── docker.yml ├── Dockerfile └── ibc_config.ini /.gitignore: -------------------------------------------------------------------------------- 1 | venv/ -------------------------------------------------------------------------------- /run.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | set -o errexit 5 | 6 | rm -f /tmp/.X0-lock 7 | 8 | Xvfb :0 & 9 | sleep 1 10 | 11 | x11vnc -rfbport $VNC_PORT -display :0 -usepw -forever & 12 | socat TCP-LISTEN:$TWS_PORT,fork TCP:localhost:4001,forever & 13 | 14 | # Start this last and directly, so that if the gateway terminates for any reason, the container will stop as well. 15 | # Retry behavior can be implemented by re-running the container. 16 | /opt/ibc/scripts/ibcstart.sh $(ls ~/Jts/ibgateway) --gateway "--mode=$TRADING_MODE" "--user=$TWSUSERID" "--pw=$TWSPASSWORD" 17 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ib-gateway-docker 2 | 3 | This builds a Docker image with the latest version of [Interactive Brokers](https://interactivebrokers.com)' [IB Gateway](https://www.interactivebrokers.com/en/index.php?f=5041), the modern [IbcAlpha/IBC](https://github.com/IbcAlpha/IBC) for automation, and a VNC server for debugging purposes. 4 | 5 | **Currently, the API is only enabled in read-only mode**, for testing purposes. 6 | 7 | ## Building 8 | 9 | ```sh 10 | docker build . -t ib-gateway-docker 11 | ``` 12 | 13 | ## Running 14 | 15 | ```sh 16 | docker run -p 4002:4002 -p 5900:5900 \ 17 | --env TWSUSERID=YOUR_USER_ID \ 18 | --env TWSPASSWORD=YOUR_PASSWORD \ 19 | ib-gateway-docker:latest 20 | ``` 21 | 22 | This will expose port 4002 for the TWS API (usable with, e.g., [ib_insync](https://github.com/erdewit/ib_insync)) and 5900 for VNC (with default password `1358`). **Neither are secure for public internet access**, as the expectation is that private, secure services will sit on top and be the only open interface to the internet. 23 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Justin Spahr-Summers 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 all 13 | 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 THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /.github/workflows/docker.yml: -------------------------------------------------------------------------------- 1 | name: Docker 2 | 3 | on: 4 | push: 5 | branches: 6 | - master 7 | 8 | tags: 9 | - v* 10 | 11 | pull_request: 12 | 13 | jobs: 14 | build: 15 | if: github.event_name != 'push' 16 | runs-on: ubuntu-latest 17 | 18 | steps: 19 | - uses: actions/checkout@v1 20 | 21 | - name: Build Docker image 22 | run: docker build . -t image 23 | 24 | gpr: 25 | name: Push to GitHub Package Registry 26 | if: github.event_name == 'push' 27 | runs-on: ubuntu-latest 28 | 29 | steps: 30 | - uses: actions/checkout@v1 31 | - uses: antequant/docker-push-action@v0.3 32 | with: 33 | docker_server: docker.pkg.github.com 34 | docker_password: ${{ secrets.GITHUB_TOKEN }} 35 | image_path: docker.pkg.github.com/${{ github.repository }} 36 | 37 | dockerhub: 38 | name: Push to Docker Hub 39 | if: github.event_name == 'push' 40 | runs-on: ubuntu-latest 41 | 42 | steps: 43 | - uses: actions/checkout@v1 44 | - uses: antequant/docker-push-action@v0.3 45 | with: 46 | docker_username: antequantsvcuser 47 | docker_password: ${{ secrets.DOCKER_TOKEN }} 48 | image_path: antequantmirror 49 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | # Builder 2 | FROM ubuntu:latest AS builder 3 | 4 | RUN apt-get update 5 | RUN apt-get install -y unzip dos2unix wget 6 | 7 | WORKDIR /root 8 | 9 | RUN wget -q --progress=bar:force:noscroll --show-progress https://download2.interactivebrokers.com/installers/ibgateway/latest-standalone/ibgateway-latest-standalone-linux-x64.sh -O install-ibgateway.sh 10 | RUN chmod a+x install-ibgateway.sh 11 | 12 | RUN wget -q --progress=bar:force:noscroll --show-progress https://github.com/IbcAlpha/IBC/releases/download/3.8.2/IBCLinux-3.8.2.zip -O ibc.zip 13 | RUN unzip ibc.zip -d /opt/ibc 14 | RUN chmod a+x /opt/ibc/*.sh /opt/ibc/*/*.sh 15 | 16 | COPY run.sh run.sh 17 | RUN dos2unix run.sh 18 | 19 | # Application 20 | FROM ubuntu:latest 21 | 22 | RUN apt-get update 23 | RUN apt-get install -y x11vnc xvfb socat 24 | 25 | WORKDIR /root 26 | 27 | COPY --from=builder /root/install-ibgateway.sh install-ibgateway.sh 28 | RUN yes n | ./install-ibgateway.sh 29 | 30 | RUN mkdir .vnc 31 | RUN x11vnc -storepasswd 1358 .vnc/passwd 32 | 33 | COPY --from=builder /opt/ibc /opt/ibc 34 | COPY --from=builder /root/run.sh run.sh 35 | 36 | COPY ibc_config.ini ibc/config.ini 37 | 38 | ENV DISPLAY :0 39 | ENV TRADING_MODE paper 40 | ENV TWS_PORT 4002 41 | ENV VNC_PORT 5900 42 | 43 | EXPOSE $TWS_PORT 44 | EXPOSE $VNC_PORT 45 | 46 | CMD ./run.sh 47 | -------------------------------------------------------------------------------- /ibc_config.ini: -------------------------------------------------------------------------------- 1 | # Note that in the comments in this file, TWS refers to either the Trader 2 | # Workstation or the Gateway for the IB API. 3 | # 4 | # When referred to below, the default value for a setting is the value 5 | # assumed if either the setting is included but no value is specified, or 6 | # the setting is not included at all. 7 | # 8 | # IBC may also be used to start the FIX CTCI Gateway. All settings 9 | # relating to this have names prefixed with FIX. 10 | # 11 | # The IB API Gateway and the FIX CTCI Gateway share the same code. Which 12 | # gateway actually runs is governed by an option on the initial gateway 13 | # login screen. The FIX setting described under IBC Startup 14 | # Settings below controls this. 15 | 16 | 17 | # 1. IBC Startup Settings 18 | # ------------------------- 19 | 20 | 21 | # IBC may be used to start the IB Gateway for the FIX CTCI. This 22 | # setting must be set to 'yes' if you want to run the FIX CTCI gateway. The 23 | # default is 'no'. 24 | 25 | FIX=no 26 | 27 | 28 | # 2. Authentication Settings 29 | # ---------------------------- 30 | # 31 | # TWS and the IB API gateway require a single username and password. 32 | # You may specify the username and password using the following settings: 33 | # 34 | # IbLoginId 35 | # IbPassword 36 | # 37 | # Alternatively, you can specify the username and password in the command 38 | # files used to start TWS or the Gateway, but this is not recommended for 39 | # security reasons. 40 | # 41 | # If you don't specify them, you will be prompted for them in the usual 42 | # login dialog when TWS starts (but whatever you have specified will be 43 | # included in the dialog automatically: for example you may specify the 44 | # username but not the password, and then you will be prompted for the 45 | # password via the login dialog). Note that if you specify either 46 | # the username or the password (or both) in the command file, then 47 | # IbLoginId and IbPassword settings defined in this file are ignored. 48 | # 49 | # 50 | # The FIX CTCI gateway requires one username and password for FIX order 51 | # routing, and optionally a separate username and password for market 52 | # data connections. You may specify the usernames and passwords using 53 | # the following settings: 54 | # 55 | # FIXLoginId 56 | # FIXPassword 57 | # IbLoginId (optional - for market data connections) 58 | # IbPassword (optional - for market data connections) 59 | # 60 | # Alternatively you can specify the FIX username and password in the 61 | # command file used to start the FIX CTCI Gateway, but this is not 62 | # recommended for security reasons. 63 | # 64 | # If you don't specify them, you will be prompted for them in the usual 65 | # login dialog when FIX CTCI gateway starts (but whatever you have 66 | # specified will be included in the dialog automatically: for example 67 | # you may specify the usernames but not the passwords, and then you will 68 | # be prompted for the passwords via the login dialog). Note that if you 69 | # specify either the FIX username or the FIX password (or both) on the 70 | # command line, then FIXLoginId and FIXPassword settings defined in this 71 | # file are ignored; he same applies to the market data username and 72 | # password. 73 | 74 | # IB API Authentication Settings 75 | # ------------------------------ 76 | 77 | # Your TWS username: 78 | 79 | IbLoginId=edemo 80 | 81 | 82 | # Your TWS password: 83 | 84 | IbPassword=demouser 85 | 86 | 87 | # FIX CTCI Authentication Settings 88 | # -------------------------------- 89 | 90 | # Your FIX CTCI username: 91 | 92 | FIXLoginId= 93 | 94 | 95 | # Your FIX CTCI password: 96 | 97 | FIXPassword= 98 | 99 | 100 | # Trading Mode 101 | # ------------ 102 | # 103 | # TWS 955 introduced a new Trading Mode combo box on its login 104 | # dialog. This indicates whether the live account or the paper 105 | # trading account corresponding to the supplied credentials is 106 | # to be used. The allowed values are 'live' (the default) and 107 | # 'paper'. For earlier versions of TWS this setting has no 108 | # effect. 109 | 110 | #TradingMode=live 111 | 112 | 113 | # 3. TWS Startup Settings 114 | # ------------------------- 115 | # 116 | # Path to the directory where TWS should store its settings. This is 117 | # normally the folder in which TWS is installed. However you may set 118 | # it to some other location if you wish (for example if you want to 119 | # run multiple instances of TWS with different settings). 120 | # 121 | # It is recommended for clarity that you use an absolute path. The 122 | # effect of using a relative path is undefined. 123 | # 124 | # Linux and OS X users should use the appropriate path syntax. 125 | # 126 | # Note that, for Windows users, you MUST use double separator 127 | # characters to separate the elements of the folder path: for 128 | # example, IbDir=C:\\IBLiveSettings is valid, but 129 | # IbDir=C:\IBLiveSettings is NOT valid and will give unexpected 130 | # results. Linux and OS X users need not use double separators, 131 | # but they are acceptable. 132 | # 133 | # The default is the current working directory when IBC is 134 | # started. 135 | 136 | IbDir= 137 | 138 | 139 | # If you wish to store a copy of your TWS settings on IB's 140 | # servers as well as locally on your computer, set this to 141 | # 'yes': this enables you to run TWS on different computers 142 | # with the same configuration, market data lines, etc. If set 143 | # to 'no', running TWS on different computers will not share the 144 | # same settings. If no value is specified, TWS will obtain its 145 | # settings from the same place as the last time this user logged 146 | # in (whether manually or using IBC). 147 | 148 | StoreSettingsOnServer=no 149 | 150 | 151 | # Set to 'yes' to minimise TWS when it starts: 152 | 153 | MinimizeMainWindow=no 154 | 155 | 156 | # When a user logs on to an IBKR account for trading purposes by any means, the 157 | # IBKR account server checks to see whether the account is already logged in 158 | # elsewhere. If so, a dialog is displayed to both the users that enables them 159 | # to determine what happens next. The `ExistingSessionDetectedAction` setting 160 | # instructs TWS how to proceed when it displays one of these dialogs: 161 | # 162 | # * If the existing TWS session is set to 'primary', the existing session 163 | # continues and the new session is not permitted to proceed. 164 | # 165 | # * If the existing TWS session is set to 'primaryoverride', the existing 166 | # session terminates and the new session is permitted to proceed. 167 | # 168 | # * If the new session is via TWS with 169 | # `ExistingSessionDetectedAction=secondary', the new TWS exits so that the 170 | # existing session is unaffected. 171 | # 172 | # * If the existing TWS session is set to 'manual', the user must handle the 173 | # dialog. 174 | # 175 | # The difference between `primary` and `primaryoverride` is that a 176 | # `primaryoverride` session can be taken over by a new `primary` or 177 | # `primaryoverride` session, but a `primary` session cannot be taken over by 178 | # any other session. 179 | # 180 | # When set to 'primary', if another TWS session is started and manually told to 181 | # end the `primary` session, the `primary` session is automatically reconnected. 182 | # 183 | # The default is 'manual'. 184 | 185 | ExistingSessionDetectedAction=primaryoverride 186 | 187 | 188 | # If set to 'accept', IBC automatically accepts incoming 189 | # API connection dialogs. If set to 'reject', IBC 190 | # automatically rejects incoming API connection dialogs. If 191 | # set to 'manual', the user must decide whether to accept or reject 192 | # incoming API connection dialogs. The default is 'manual'. 193 | # NB: it is recommended to set this to 'reject', and to explicitly 194 | # configure which IP addresses can connect to the API in TWS's API 195 | # configuration page, as this is much more secure (in this case, no 196 | # incoming API connection dialogs will occur for those IP addresses). 197 | 198 | AcceptIncomingConnectionAction=accept 199 | 200 | 201 | # If OverrideTwsApiPort is set to an integer, IBC changes the 202 | # 'Socket port' in TWS's API configuration to that number shortly 203 | # after startup. Leaving the setting blank will make no change to 204 | # the current setting. This setting is only intended for use in 205 | # certain specialized situations where the port number needs to 206 | # be set dynamically at run-time: most users will never need it, 207 | # so don't use it unless you know you need it. 208 | 209 | OverrideTwsApiPort=4001 210 | 211 | 212 | # If ReadOnlyLogin is set to 'yes', and the user is enrolled in IB's 213 | # account security programme, the user will not be asked to supply 214 | # the security code, and login to TWS will occur automatically in 215 | # read-only mode: in this mode, placing or managing orders is not 216 | # allowed. If set to 'no', and the user is enrolled in IB's account 217 | # security programme, the user must supply the relevant security 218 | # code to complete the login. If the user is not enrolled in IB's 219 | # account security programme, this setting is ignored. The default 220 | # is 'no'. 221 | 222 | ReadOnlyLogin=yes 223 | 224 | 225 | # If ReadOnlyApi is set to 'yes', API programs cannot submit, modify 226 | # or cancel orders. If set to 'no', API programs can do these things. 227 | # If not set, the existing TWS/Gateway configuration is unchanged. 228 | # NB: this setting is really only supplied for the benefit of new TWS 229 | # or Gateway instances that are being automatically installed and 230 | # started without user intervention (eg Docker containers). Where 231 | # a user is involved, they should use the Global Configuration to 232 | # set the relevant checkbox (this only needs to be done once) and 233 | # not provide a value for this setting. 234 | 235 | ReadOnlyApi=yes 236 | 237 | # Logging in to a paper-trading account results in TWS displaying 238 | # a dialog asking the user to confirm that they are aware that this 239 | # is not a brokerage account. Until this dialog has been accepted, 240 | # TWS will not allow API connections to succeed. Setting this 241 | # to 'yes' (the default) will cause IBC to automatically 242 | # confirm acceptance. Setting it to 'no' will leave the dialog 243 | # on display, and the user will have to deal with it manually. 244 | 245 | AcceptNonBrokerageAccountWarning=yes 246 | 247 | 248 | # 4. TWS Auto-Closedown 249 | # ----------------------- 250 | # 251 | # Set to yes or no (lower case). Only affects TWS, not the Gateway. 252 | # 253 | # yes means allow TWS to shut down automatically at its 254 | # specified shutdown time, which is set via the TWS 255 | # configuration menu. 256 | # 257 | # no means TWS never shuts down automatically. 258 | # 259 | # NB: IB recommends that you do not keep TWS running 260 | # continuously. If you set this setting to 'no', you may 261 | # experience incorrect TWS operation. 262 | # 263 | # Starting with TWS 974, this setting no longer works properly, 264 | # because IB have changed the way TWS handles its autologoff 265 | # mechanism. You should now configure the TWS autologoff time 266 | # to something convenient for you, and restart IBC each day. 267 | # Alternatively, discontinue use of IBC and use the autorestart 268 | # mechanism within TWS 974 and later versions. 269 | 270 | IbAutoClosedown=yes 271 | 272 | 273 | 274 | # 5. TWS Tidy Closedown Time 275 | # ---------------------------- 276 | # 277 | # NB: starting with TWS 974 this is no longer a useful option 278 | # for TWS, because of changes in TWS 974's autologoff handling. 279 | # However it can still be useful with the Gateway. 280 | # 281 | # To tell IBC to tidily close TWS at a specified time every 282 | # day, set this value to , for example: 283 | # ClosedownAt=22:00 284 | # 285 | # To tell IBC to tidily close TWS at a specified day and time 286 | # each week, set this value to , for example: 287 | # ClosedownAt=Friday 22:00 288 | # 289 | # Note that the day of the week must be specified using your 290 | # default locale. Also note that Java will only accept 291 | # characters encoded to ISO 8859-1 (Latin-1). This means that 292 | # if the day name in your default locale uses any non-Latin-1 293 | # characters you need to encode them using Unicode escapes 294 | # (see http://java.sun.com/docs/books/jls/third_edition/html/lexical.html#3.3 295 | # for details). For example, to tidily close TWS at 12:00 on 296 | # Saturday where the default locale is Simplified Chinese, 297 | # use the following: 298 | # #ClosedownAt=\u661F\u671F\u516D 12:00 299 | 300 | ClosedownAt= 301 | 302 | 303 | 304 | # 6. Other TWS Settings 305 | # ----------------------- 306 | # 307 | # If you attempt to place an order for a contract for which 308 | # you have no market data subscription, TWS displays a dialog 309 | # to warn you against such blind trading. 310 | # 311 | # yes means the dialog is dismissed as though the user had 312 | # clicked the 'Ok' button: this means that you accept 313 | # the risk and want the order to be submitted. 314 | # 315 | # no means the dialog remains on display and must be 316 | # handled by the user. 317 | 318 | AllowBlindTrading=yes 319 | 320 | 321 | # Indian versions of TWS may display a password expiry 322 | # notification dialog and a NSE Compliance dialog. These can be 323 | # dismissed by setting the following to yes. By default the 324 | # password expiry notice is not dismissed, but the NSE Compliance 325 | # notice is dismissed. 326 | 327 | # Warning: setting DismissPasswordExpiryWarning=yes will mean 328 | # you will not be notified when your password is about to expire. 329 | # You must then take other measures to ensure that your password 330 | # is changed within the expiry period, otherwise IBC will 331 | # not be able to login successfully. 332 | 333 | DismissPasswordExpiryWarning=yes 334 | DismissNSEComplianceNotice=yes 335 | 336 | 337 | # You can tell TWS to automatically save its settings on a schedule 338 | # of your choosing. You can specify one or more specific times, 339 | # like this: 340 | # 341 | # SaveTwsSettingsAt=HH:MM [ HH:MM]... 342 | # 343 | # for example: 344 | # SaveTwsSettingsAt=08:00 12:30 17:30 345 | # 346 | # Or you can specify an interval at which settings are to be saved, 347 | # optionally starting at a specific time and continuing until another 348 | # time, like this: 349 | # 350 | #SaveTwsSettingsAt=Every n [{mins | hours}] [hh:mm] [hh:mm] 351 | # 352 | # where the first hh:mm is the start time and the second is the end 353 | # time. If you don't specify the end time, settings are saved regularly 354 | # from the start time till midnight. If you don't specify the start time. 355 | # settings are saved regularly all day, beginning at 00:00. Note that 356 | # settings will always be saved at the end time, even if that is not 357 | # exactly one interval later than the previous time. If neither 'mins' 358 | # nor 'hours' is specified, 'mins' is assumed. Examples: 359 | # 360 | # To save every 30 minutes all day starting at 00:00 361 | #SaveTwsSettingsAt=Every 30 362 | #SaveTwsSettingsAt=Every 30 mins 363 | # 364 | # To save every hour starting at 08:00 and ending at midnight 365 | #SaveTwsSettingsAt=Every 1 hours 08:00 366 | #SaveTwsSettingsAt=Every 1 hours 08:00 00:00 367 | # 368 | # To save every 90 minutes starting at 08:00 up to and including 17:43 369 | #SaveTwsSettingsAt=Every 90 08:00 17:43 370 | 371 | SaveTwsSettingsAt= 372 | 373 | 374 | 375 | # 6. IBC Command Server Settings 376 | # -------------------------------- 377 | # 378 | # Do NOT CHANGE THE FOLLOWING SETTINGS unless you 379 | # intend to issue commands to IBC (for example 380 | # using telnet). Note that these settings have nothing to 381 | # do with running programs that use the TWS API. 382 | 383 | # The port that IBC listens on for commands 384 | # such as "STOP". DO NOT set this to the port number 385 | # used for TWS API connections. There is no good reason 386 | # to change this setting unless the port is used by 387 | # some other application (typically another instance of 388 | # IBC). The default value is 0, which tells IBC not to 389 | # start the command server 390 | 391 | #CommandServerPort=7462 392 | 393 | 394 | # A comma separated list of ip addresses, or host names, 395 | # which are allowed addresses for sending commands to 396 | # IBC. Commands can always be sent from the 397 | # same host as IBC is running on. 398 | 399 | ControlFrom= 400 | 401 | 402 | # Specifies the IP address on which the Command Server 403 | # is to listen. For a multi-homed host, this can be used 404 | # to specify that connection requests are only to be 405 | # accepted on the specified address. The default is to 406 | # accept connection requests on all local addresses. 407 | 408 | BindAddress= 409 | 410 | 411 | # The specified string is output by the server when 412 | # the connection is first opened and after the completion 413 | # of each command. This can be useful if sending commands 414 | # using an interactive program such as telnet. The default 415 | # is that no prompt is output. 416 | # For example: 417 | # 418 | # CommandPrompt=> 419 | 420 | CommandPrompt= 421 | 422 | 423 | # Some commands can return intermediate information about 424 | # their progress. This setting controls whether such 425 | # information is sent. The default is that such information 426 | # is not sent. 427 | 428 | SuppressInfoMessages=yes 429 | 430 | 431 | 432 | # 7. Diagnostic Settings 433 | # ------------------------ 434 | 435 | # If LogComponents is set to 'open' or 'yes' or 'true', 436 | # IBC logs information about the structure of each 437 | # TWS window it detects the first time it is encountered. If 438 | # set to 'activate', the information is logged every time 439 | # a TWS window is made active. If set to 'never' or 'no' or 440 | # 'false', this information is never logged. The default is 441 | # 'never'. 442 | # 443 | # The logged information shows the hierarchical organisation 444 | # of all the components of the window, and includes the 445 | # current values of text boxes and labels. 446 | # 447 | # Note that when set to 'open', 'activate' or 'yes', there is 448 | # a small performance impact due to the extra logging. Also 449 | # logfile size may be significantly increased, especially if 450 | # set to 'activate' and the user is actively using TWS. It 451 | # is therefore recommended that the setting be left at 'no' 452 | # unless there is a specific reason that this information is 453 | # needed. 454 | 455 | LogComponents=never 456 | 457 | --------------------------------------------------------------------------------