Pair trading strategy

12 July 2021

In this article we are going through a pair trading strategy sample using our API within our web cloud-based JupyterLab environment. A step-by-step explanation of tick data requests, technical indicators and trading signals generation.

Pair trading strategy is a standard mean reversion model; two stocks that normally trade in the same direction become temporally uncorrelated and eventually will revert back to the mean. It is a market-neutral strategy, when we identify a deviation in the price relationship of these instruments, we expect a mean reversion:

  • we buy the underperforming instrument
  • and simultaneously sell the outperforming one

In this article we are going through a step-by-step explanation of how to compute technical indicators and generate trading signals using our API within Ganymede, our web and cloud-based JupyterLab environment.

Alpha generation relies on the input data quality and consistency. We use tick by tick data to make sure that we process each and every market event.

Getting started

We assume that the strategy will trade a pair of equities of the same industrial sector that are historically highly correlated. To illustrate the price relationship between pair instruments and to generate trading signals as explained above, we use the following ratio: $$ Ratio = \frac{Last_1}{Last_2} $$ Where:

  • Last_1 is the Last price of the instrument 1
  • Last_2 is the Last price of the instrument 2

The overall approach followed in this article is as follows:

  • Retrieve historical tick data for the pair instruments over the chosen look back period
  • Build strategy indicators
  • Generate buy/sell trading signals for each instrument
  • Compute portfolio profit and loss

For this sample, we assume you will use Python with the following Systemathics package:

PyPI version

We will be using a set of Systemathics modules in addition to Opensource modules as follows:

# open source modules
import os
import grpc
import pandas as pd
import matplotlib.pyplot as plt
from datetime import datetime
import google.protobuf.duration as duration
# systemathics modules to handle input parameters' types
import systemathics.apis.type.shared.identifier as identifier
# systemathics modules to instantiate the tick bars service
import systemathics.apis.services.tick_analytics.tick_bars as tick_bars
import systemathics.apis.services.tick_analytics.tick_bars_grpc as tick_bars_service

Retrieve tick data

We assume for this pair trading strategy, we will use:

  • 1-min bars directly computed from tick data
  • Apple and Microsoft equities from BATS exchange

We will use TickBarsService to compute and request on-the-fly tick bars with customizable bar duration and field calculation. Explore the full API documentation to learn more about our extensive list of analytics.

# set the instruments: tickers and exchange
exchange = "BATS"
ticker_1 = "AAPL"
ticker_2 = "MSFT"

# set the bar duration in seconds
sampling = 60

# set the bar calculation field: trade, bid or ask
field = tick_bars.BAR_PRICE_TRADE 

# set the look back period, we are using Google date format
start = date.Date(year = 2021, month = 3, day = 5)
end = date.Date(year = 2020, month = 3, day = 5)

To learn more about tick bars request creation, please refer to the dedicated step-by-step explanation available in this article.

We are displaying 1-min bar close prices for each pair instrument and strategy ratio computed on-the-fly from raw tick data. Note that you can use libraries of your choice for graph plotting, in this example we are using an open-source library matplotlib.

Build strategy indicators

Our strategy aims to generate buy or sell signals when the spread between the pair tends to broaden. For that purpose, we need to generate an indicator that highlights when this situation occurs. As the z-score is defined as the number of standard deviations a datapoint is from the mean, we will use this metric to generate our signals.

To generate trading signals, we will track z-score movements and identify points where it reverts back to the mean. In addition to the previous z-score, we chose to compute a specific z-score on top of the ratio metrics related to the mean:

  • 60-days moving average of strategy ratio
  • 5-days moving average of strategy ratio

Generate trading signals

We now generate buy/sell trading signals based on z-score movements:

  • if z-score < -1 : we buy the ratio
  • if z-score > 1 : we sell the ratio

We previously identified the trading signals based on the ratio. We now have to match signals in order to determine which instrument to buy/sell in each case. Since the ratio was previously defined as Price1/Price2, the decision will be made following the rules below:

  • When buying the ratio, we buy Instrument 1 and sell Instrument 2
  • When selling the ratio, we sell Instrument 1 and buy Instrument 2

Reach out to try our solutions

In this article, we request tick data and financial indicators by calling a dedicated API service within Ganymede, our web and cloud-based JupyterLab environment, and our API. You can use it as-is and/or call directly our API within your internal tools and start immediately retrieving on-demand financial data.

To get the full sample and discover more data analytics samples and building blocks navigate to our public Github →