#+TITLE: Interactive Brokers #+AUTHOR: Daniel Rostovtsev #+TEXINFO_DIR_CATEGORY: Trading #+TEXINFO_DIR_NAME: Interactive Brokers #+TEXINFO_DIR_DESC: Routing requests to the interactive brokers trading API * History Interactive Brokers is a publicly-traded broker dealer with an investment grade rating by Standard and Poor's. It started as a market maker with Thomas Peterffy, who bought a chair on AMEX in 1977 and founded "T.P. & Co." in 1978. In 1979, the company hired its first four employees, and wrote one of the first equity options trading algorithms, which they started using in 1982. By 1983, they created the first handheld computers to give traders recommendations on the floor, and in 1984 they began trading with a fully fledged electronic operation. After a period of rapid expansion in the late 1980s, the company rebrands as "Timber Hill" and grows to 150 employees, trading a variety of securities internationally as electronic trading is gaining wider adoption. In the late 1990s, the company expands from market making into brokerage services. In 1998, they begin to clear S&P futures for retail clients, and in 1999 they begin to offer "smart routing" services for multiple equity options. The company has continued to grow and add new retail and institutional clients since the early 2000s. More is available about interactive brokers at their site at: https://www.interactivebrokers.com/en/general/about/. * The Trading API Interactive Brokers offers a REST API for retail clients to send orders, query their accounts, and poll market data. Here we used the "Web API v1.0", which is documented at: https://www.interactivebrokers.com/campus/ibkr-api-page/cpapi-v1/#cpgw ** Connecting to the API #+CINDEX: Client Gateway Interactive Brokers expects clients to route orders through a "client gateway" which is a service run on the client's machine program which manages authenticating and forwarding requests to the actual Interactive Brokers API. #+CINDEX: Procyon The client gateway is written in Java, and the code can be decompiled with tools like "procyon". By default, the gateway is configured to forward requests send to port 5000 on the service machine. #+CINDEX: SSL By default, the client listens with SSL on port 5000. However, if you are comfortable that this connection is secure you can turn off SSL and connect to it directly. We currently provide a tool to start-up a connection and keep it alive. #+BEGIN_SRC bash ./scripts/run-gateway.bash & #+END_SRC After starting up a connection, the user can navigate to http://localhost:5000 and login. The connection logs are in ~gw.out~ and the connection errors are in ~gw.err~. If you want to use a paper trading session, be sure to select paper trading and login with your paper trading account details. For more details, read the scripts themselves. ** Idiosyncracies The IBKR API has a few idiosyncracies and patters specific to their implementation. One, their responses are untyped blobs, and the names for fixed values tend to change across different endpoints. As such, it is the responsibility of the user to normalize their interactions with the API and organize the data they use. In general, the API does not send reponses with return code not equal to 200 even when messages trigger errors or warnings that the user has to handle. It is up to the user to read the contents of messages to understand whether the response the result of normal behaviour or needs additional handling. Lastly, endpoints can return blobs of several "schemas". For instance, order messages can have standard reply messages, warning messages, or error messages, all of different "types". It is up to the user to handle this logic as well. ** Paper Trading #+CINDEX: Paper Trading "Paper trading" is the practice of sending mock trades and being filled at mock prices to exercise a trading system. Paper trading is good for getting a feel for how your system behaves before sending real orders. * Scheme Interface The IBKR interface really only accept GET and POST requests. GETs always have an empty body, and POSTs have a JSON body. The headers expected by the API the same across endpoints. To make requests easier, we expose the following helpers in scheme. #+FINDEX: ibkr-get ~ibkr-get~ (~uri~) Returns a GET request for an IBKR endpoint located at ~uri~. #+FINDEX: ibkr-post ~ibkr-post~ (~uri~) (~body~) Returns a POST request for an IBKR endpoint located at ~uri~ with body ~body~. The scheme interface helps build HTTP requests for common actions. All the helper methods take a ~base~ URI for the location of gateway. Extra information necessary for specific requests is passed in as additional arguments. For more details, see the ~(ibkr api)~ module. Useful data structures for interacting with IBKR like orders or accounts are defined in ~(ibkr types)~. Sometimes, it is helpful to make requests manually. For this we offer two helper functions in addition to ~ibkr-get~ and ~ibkr-post~. #+FINDEX: send-ibkr-request ~(send-ibkr-request request)~: sends a request (as constructed by either ~ibkr-get~ or ~ibkr-post~) to IBKR and returns a pair of the header and the contents of the response. #+FINDEX: v1-api ~(v1-api base)~: returns the "v1" API endpoint relative to the base URI. ** Authentication Status #+FINDEX: auth-status ~(auth-status base)~: This method simply checks if the current session is authenticated. ** Accounts #+FINDEX: accounts ~(accounts base)~: Returns as a list the accounts available to the session. ** Cash Balance #+FINDEX: ledger ~(ledger base account-id currency)~: Returns a "ledger" representing the cash balance of a current account available in a given session. Currency types include ~"BASE"~ and ~"USD"~. ** Positions #+FINDEX: positions ~(positions base account-id)~: Returns the open positions of an account as a list. ** Security Definitions #+FINDEX: stocks-by-symbol ~(stocks-by-symbol base symbol)~: Returns all contracts matching a given symbol. #+FINDEX: first-contract-on-exchange ~(first-contract-on-exchange stocks exchange)~: Returns the first stock contract on a given exchange. These two methods are useful in equity markets for determining the correct security associated with a given ticker (~symbol~). ** Market Data Snapshots The following methods are exposed to get snapshots of market data in real time. #+FINDEX: contract-snapshot ~(contract-snapshot base contract-id stat)~: Returns the latest snapshot value of a ~stat~ (as a symbol) for a given ~contract-id~. An example to get the latest trade in security "HBB:NYSE" is given below. #+BEGIN_SRC lisp (use-modules (ibkr api) (ibkr types)) (define base "http://localhost:5000") (define hbb (first-contract-on-exchange (stocks-by-symbol base "HBB") "NYSE")) (contract-snapshot base (contract-id hbb) 'last-trade) #+END_SRC #+FINDEX: snapshot-field ~(snapshot-field symbol)~: Returns the integer ID that IBKR associates with a given market data statistic. The supported market data snapshot values include: - Last Trade ~last-trade~ (31) ** Submitting Orders The "order" data structure helps with sending orders to IBKR. It requries the following fields: - ~account-id~: The ~account-id~ associated with the trade. - ~contract-id~: The ~contract-id~ of the symbol being traded. - ~type~: ("MARKET", "LIMIT", etc...) - ~side~: "BUY" or "SELL" - ~tif~: "time-in-force". "IOC" for immediate or cancel. - ~quantity~: The quantity associated with the order. The order can be constructed with the ~make-order~ method. #+FINDEX: make-order #+BEGIN_SRC lisp (define ord (make-order "ACCT1234" "5678" "MARKET" "BUY" "IOC" 20)) #+END_SRC This order represents a marketable immediate-or-cancel to purchase 20 shares of 5678 for account "ACCT1234". IBKR allows users to preview orders before sending them. #+FINDEX: order-preview ~(order-preview base account-id order)~: Previews the placement of ~order~ for ~account-id~. The signature to send an order is identical. #+FINDEX: order-submit ~(order-submit base account-id order)~: submit ~order~ for ~account-id~. Sometimes the server will respond with a warning when sending an order. The response message will come with an associated ~reply-id~. To acknowledge the warning and proceed, use the ~order-confirm~ method. #+FINDEX: order-confirm ~(order-confirm base reply-id)~: confirm the warnings associated with an order and submit. ** Reviewing Trades We expose the following methods to view the filled and open trades for a market session. #+FINDEX: refresh-live-orders ~(refresh-live-orders base)~: Tells the IBKR API to refresh its cached listing of live orders. #+FINDEX: list-live-orders ~(list-live-orders base)~: Lists the live orders (of all status types) for the current market session. #+FINDEX: set-default-account ~(set-default-account base account-id)~: Sets the account for which live orders are queried. * Indices ** Concepts :PROPERTIES: :INDEX: cp :END: ** Data Types :PROPERTIES: :INDEX: tp :END: ** Functions :PROPERTIES: :INDEX: fn :END: