# Set horizontal image position - adjusts too much
# knitr::opts_chunk$set(out.extra='style="float:left;"')
# knitr::opts_chunk$set(out.extra='style="float:right;"')
# knitr::opts_chunk$set(out.extra='style="display:block; margin:auto;"')
library(png)
library(grid)

Implementing a Hedge Fund in a Box

- In the past, only large institutional investors had the resources to implement real-time, algorithmic trading. - The second internet revolution and open-source software have recently given small investors the tools for creating a *Hedge Fund in a Box*, for real-time trading. - This presentation is a *technical demonstration* of how to implement real-time trading, using the *R* language and Interactive Brokers. - It will not be about potential market anomalies, nor about promising trading strategies. - **Disclosure:** I have a personal account with Interactive Brokers. But I do not have any other relationships with Interactive Brokers, and I do not endorse or recommend them.
The *R* Project for Statistical Computing

What is Package IBrokers2?

- *iBrokers2* is an open-source package written in *R*, derived from package *iBrokers*. - The package *IBrokers2* allows users to test their own trading strategies in paper trading, without having to program the IB API directly. - The package *IBrokers2* can be an element of a toolkit for developing trading strategies, and testing them in paper trading. - The package IBrokers2 is *NOT* a software product for inexperienced users, and it requires strong knowledge of *R* and the IB API. - The package *IBrokers2* does NOT provide realistic trading strategies. - The package *IBrokers2* comes with no warranty, and it is not affiliated or endorsed by Interactive Brokers.
wzxhzdk:1

Why the R Language?

- *R* is widely used for data science and machine learning. - *R* has a large user base of financial quants. - *R* provides higher order functions with the ability to *program on the language*. - Packages *xts* and *quantmod* for time series. - Package *Rcpp* for integrating *C++* code with *R*. - Package *shiny* for interactive plots. - Package *iBrokers* for Interactive Brokers.

Executing Real-time Trading Strategies

- Real-time trading requires running a programmatic loop: - A trading model is updated with streaming market data aqcuired via an API, - The model outputs are fed into an order management system to place trade orders via an API. - The package *IBrokers* contains *R* functions for downloading live market data via the API of Interactive Brokers (IB API), and for placing trade orders to Interactive Brokers. - The function `iBrokers::reqRealTimeBars()` downloads live (real-time) *OHLC* bars of market data from Interactive Brokers. - The function `IBrokers::twsOrder()` places trade orders to Interactive Brokers.

The Package IBrokers for Interactive Brokers

- The package *IBrokers* allows downloading live market data via the API of Interactive Brokers (IB API) - The function `twsConnect()` opens a connection to the *IB API* via the IB Trader Workstation (TWS). - The function `reqRealTimeBars()` downloads live (real-time) *OHLC* bars of market data. - `reqRealTimeBars()` relies on the functions `eWrapper.RealTimeBars.CSV()` and `twsCALLBACK` to process real-time market events (trades and quotes). - The function `eWrapper.RealTimeBars.CSV()` creates an *eWrapper* object designed for processing *OHLC* price data.
wzxhzdk:2

Market Event Processing Using Package IBrokers

- Market events can be either *trade events* or *market quotes*. - The *OHLC* market data arrives from Interactive Brokers in 5-second intervals. - Streaming market events are processed in a *callback loop* which runs inside the function `twsCALLBACK()`. - The function `twsCALLBACK()` first creates an *eWrapper* object by calling the function `eWrapper.RealTimeBars.CSV()`, and then passes it to the function `processMsg()`. - The function `twsCALLBACK()` then calls `processMsg()` in a *callback loop*. - The function `processMsg()` processes individual market events by calling the appropriate *eWrapper* *handlers* and saving the data into the *eWrapper* environment.

Trade Processing Using Package IBrokers2

- The trade processing framework is similar to that for downloading real-time *OHLC* market data using `reqRealTimeBars()`. - The main difference is the `trade_wrapper()` function, which creates a *trade wrapper* environment, containing the data handler `realtimeBars()` and the trading model `model_function()`. - The function `trade_realtime()` first calls `trade_wrapper()` to create a *trade wrapper* environment, and then calls `call_back()` to run a *callback loop*. - `call_back()` calls the `processMsg()` in a *callback loop*, which calls the *handler* `realtimeBars()`. - The function `realtimeBars()` updates the *trade wrapper* environment with new data and then runs the trading model `model_function()`.

Defining Contracts and Trading Parameters

- The instrument parameters specify the contract or security, the exchange, etc. - The trading instruments and their parameters are specified as lists to allow trading multiple instruments simultaneously. - The list of trading parameters contains the name of the trading model function, and a vector of its parameters. - The function `model_function()` is the trading model function, which reruns the trading model and places trade orders using `IBrokers2::twsOrder()`.
wzxhzdk:3

The Trading Model Function

- Users can define their own custom trading model function inside the `trade_wrapper()` function. - We can define a naive market-making strategy as follows: - Place a limit *buy* order at previous bar *Low* price minus *buy spread*, - Place a limit *sell* order at previous bar *High* price plus *sell spread*. - The function `make_markets()` is the trading model function, which reruns the market-making model and places limit trade orders using `twsOrder()`. - The function `make_markets()` first cancels the previous trade orders.
wzxhzdk:4

Placing Limit Trade Orders

- The *trade wrapper* environment maintains data about the state of the trading environment, such as trade IDs, positions, etc. - New limit orders are placed only if the current position doesn't exceed the limit.
wzxhzdk:5

Real-time Trading Using Package IBrokers2

- The function `trade_realtime()` first calls `trade_wrapper()` to create a *trade wrapper* environment, and then calls `call_back()` to run a *callback loop*. - Every time new data arrives, `model_function()` reruns the trading model and places trade orders using `IBrokers2::twsOrder()`. - Most of the code changes needed to implement a new trading strategy occur in the functions `trade_wrapper()`, the data handler `realtimeBars()`, and the trading model `model_function()`.
wzxhzdk:6

The EWMA Crossover Strategy

- The Exponentially Weighted Moving Average price (*EWMA*) is equal to the average of prices weighted by a decay parameter $\lambda$. - The parameter $\lambda$ determines the rate of decay of the exponential weights, with smaller values of $\lambda$ producing faster decay, giving more weight to recent prices, and vice versa.
wzxhzdk:7

The Crossover Strategy Model Function

- The function `crossover_strat()` is the trading model function for a crossover strategy.
wzxhzdk:8

Placing Market Trade Orders

- We can define a naive contrarian *EWMA* crossover strategy as follows: - Place a market *sell* order when the current price crosses above the *EWMA*, - Place a market *buy* order when the current price crosses below the *EWMA*. - Market orders are placed immediately after the *EWMA* price crosses the current price. - The *trade wrapper* environment maintains data about the state of the trading environment, such as trade IDs, positions, etc.
wzxhzdk:9

Running the EWMA Crossover Strategy

- The *EWMA* crossover strategy is run by calling the function `trade_realtime()`, in the same way as for other strategies. - The function `trade_realtime()` first calls `trade_wrapper()` to create a *trade wrapper* environment, and then calls `call_back()` to run a *callback loop*. - Every time new data arrives, `model_function()` reruns the trading model and places trade orders using `IBrokers2::twsOrder()`. - Most of the code changes needed to implement a new trading strategy occur in the functions `trade_wrapper()`, the data handler `realtimeBars()`, and the trading model `model_function()`.
wzxhzdk:10

The Pairs Trading Strategy

- In the pairs trading strategy, a regression of the prices is performed, over a rolling look-back window. - The parameter *look_back* is the number of data points in the look-back window. - The parameter *thresh_old* is the threshold at which a trade is triggered. - The parameter *siz_e* is the fixed number of shares of the first stock.
wzxhzdk:11

The Pairs Trading Strategy Model Function

- The function `pairs_strat()` is the trading model function for a pairs trading strategy. - In the pairs trading strategy, a regression of the prices is performed, over a rolling look-back window. - The regression can be performed very efficiently in *C++* using the package *Rcpp* for integrating *C++* code with *R*. - The residual z-score of the regression determines the trade decision.
wzxhzdk:12

Placing Market Trade Orders

- We can define a naive contrarian pairs trading strategy as follows: - Place a market pairs *sell* order when the z-score is above the trade threshold, - Place a market pairs *buy* order when the z-score is below the trade threshold. - The *trade wrapper* environment maintains data about the state of the trading environment, such as trade IDs, positions, etc.
wzxhzdk:13

Running the Pairs Trading Strategy

- The pairs trading strategy is run by calling the function `trade_realtime()`, in the same way as for other strategies. - The function `trade_realtime()` first calls `trade_wrapper()` to create a *trade wrapper* environment, and then calls `call_back()` to run a *callback loop*. - Every time new data arrives, `model_function()` reruns the trading model and places trade orders using `IBrokers2::twsOrder()`. - Most of the code changes needed to implement a new trading strategy occur in the functions `trade_wrapper()`, the data handler `realtimeBars()`, and the trading model `model_function()`.
wzxhzdk:14

The eWrapper Object

- An *eWrapper* object consists of a *data environment* and *handlers* (methods) for formatting and adding new data to the *data environment*. - The function `eWrapper()` creates a generic *eWrapper* object. - The function `eWrapper.RealTimeBars.CSV()` creates an *eWrapper* object designed for processing *OHLC* price data. - The functionality of package *IBrokers* can easily be extended by writing new *eWrapper* objects, designed for processing different types of data and performing different tasks.

The Trade Wrapper Environment

- The functionality of package *IBrokers* can easily be extended to trading by writing a new *eWrapper* object. - The function `IBrokers2::trade_wrapper()` creates a *trade wrapper* environment (a modified *eWrapper*) designed for real-time trading. - The *trade wrapper* data environment contains buffers for *OHLC* market data, trading model parameters, instrument positions, open trade orders, etc. - The *trade wrapper* contains the data handler `realtimeBars()` and the trading model `model_function()`. - The function `IBrokers2::trade_wrapper()` can be modified to support different market instruments and trading models.

Functions in Package IBrokers2

- Most of the functions in package *IBrokers2* were derived from those in *IBrokers*. - `IBrokers2::trade_realtime()` initiates real-time trading. - `IBrokers2::trade_wrapper()` creates a *trade wrapper* environment, containing the data handler `realtimeBars()` and the trading model `model_function()`. - The function `realtimeBars()` is a *trade wrapper* handler which updates the data environment with new data and then runs the trading model `model_function()`. - `model_function()` reruns the trading model using updated market data, and places trade orders using `IBrokers2::twsOrder()`. - The function `IBrokers2::call_back()` performs the *callback loop*.

Future Development of Package IBrokers2

### Current state - The package *IBrokers2* is currently an initial proof of concept, rather than a working application. - The package *IBrokers2* is derived from the package *IBrokers*, and is fully backward compatible with it. - All the *IBrokers* functions and variables are preserved exactly in *IBrokers2*, while some additional functions have been added to provide functionality for real-time trading. ### Future development - Rewrite critical functions using *Rcpp* and the C++ API of Interactive Brokers.
### Applications - Education and trading competitions: Interactive Brokers has been kind to provide student *paper trading* accounts, together with market data. - Crowd-sourced hedge fund: the package *IBrokers2* could become the foundation for a system similar to *Quantopian*. ### Disclaimer - This software comes with no warranty and should not be used in live trading with real capital at risk. This software is not affiliated or endorsed by Interactive Brokers.

Thank You

Contact information

NYU email: jp3900@nyu.edu

LinkedIn profile:
https://www.linkedin.com/in/jerzypawlowski



algoquant/IBrokers2 documentation built on Nov. 3, 2021, 10:18 p.m.