Future roll

23 July 2021

In this article, we will outline the maturity date approach to future rolling and to building a continuous stream of using our API within our web cloud-based JupyterLab environment. A step-by-step explanation of tick data requests, technical indicators and continuous price stream creation.

Futures are a form of contract between two parties for a sale or a purchase of a quantity of an underlying asset at a specified date in the future: delivery or expiration date. For a given underlying, we continually have a variety of future contracts with different dates of expiry. At any point-in-time we are dealing with overlapping set of time series rather than as continuous stream.

As per future contracts lifecycle and their expiration dates, we need to handle swapping from a front future to a back. In this article, we will focus on determining future roll dates and building a continuous price stream based on the future maturity approach using our API within Ganymede, our web and cloud-based JupyterLab environment.

In an upcoming article, we will enrich the future rolling with a market activity indicator approach and analyze its impact on future roll dates by comparing the two approaches.

Getting started

The overall approach followed in this article is as follows:

  • Select a look-back period and a future contract
  • Determine future roll dates based on maturity dates
  • Retrieve tick prices, build a continuous stream and visualize results

We will be using a set of Systemathics modules in addition to Opensource modules. For this sample, we chose to use Python with the following Systemathics package:

PyPI version

Select inputs and get matching futures

  • WBS, WTI crude oil future contract
  • 6-months look back period over the year 2020
  • 1-hour tick bars computed on-the-fly from raw tick data

# select future, WTI Crude future for example
future = "WBS"

# set the look back period, we are using Google date format
start = date.Date(year = 2020, month = 2, day = 1)
end = date.Date(year = 2020, month = 7, day = 31)

We call get_futures method to return WTI crude oil future maturities matching our input parameters:

# filter future contracts according to contract code and time period inputs
selected_futures = get_futures(future, start, end)

Define roll dates using maturity date approach

Our rolling method is based in the maturity date. Therefore, we can compute our rolling date by removing N days from the future maturity date. As per consequence, we obtain different time periods with their respective future tickers. To get a continuous price stream, we need to build data requests for each time period and its corresponsing future ticker.

The following code snippet enables to generate all the roll dates, according to the given days delta, and generates the time constraints for the upcoming tick data requests required to get the price stream.

# define number of days before future rolling
days_delta = 2

identifiers, starts, ends = [],[],[]

# define variables we will use to define the period for each future ticker
begin_date, end_date = start, end 

for i in range(count):
    current_future = selected_futures[i]
    maturity = datetime(current_future.maturity.year, current_future.maturity.month,current_future.maturity.day)
    
    # deal with the first (resp. last) futures differently since the start (resp. end) dates is determined by the input time period
    if i == 0:
        # handle first future: specific begin_date
        begin_date =start
        end_date = maturity - timedelta(days=days_delta)
        identifiers.append(current_future.identifier)
        starts.append(begin_date)
        ends.append(end_date)
    elif i == count-1:
        # handle last future: specific end_date
        begin_date = end_date + timedelta(days=1) # set the new begin_date for that future to the previous end_date + one day
        end_date = end
        identifiers.append(current_future.identifier)
        starts.append(begin_date)
        ends.append(end_date)
    else:
        # handle the default case
        begin_date = end_date + timedelta(days=1) # set the new begin_date for that future to the previous end_date + one day
        end_date = maturity - timedelta(days=days_delta)
        identifiers.append(current_future.identifier)
        starts.append(begin_date)
        ends.append(end_date)

The previous code snippet gives us the pandas dataframe below:

Note that the end date is the roll date from one ticker to another, and that the date slots will be used to define a continuous tick price stream.

Build a continuous price stream

We use the TickBarsService with the parameters of the dataframe above to generate 1-hour bars, computed on the fly, and plot the close price:

Notes:

  • Vertical lines represent maturity dates
  • Visible discontinuities (between two portions) are inherent to a roll occurring during a week-end

For more detailes tick bars service, please refer to our step-by-step explanation available in this article. and explore the full API documentation to learn more about our extensive list of analytics.

Reach out to try our solutions

In this article, we request tick data and use strategy samples 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 →