Quantopian's community platform is shutting down. Please read this post for more information and download your code.
Back to Community
Brent/WTI Spread Fetcher Example

Brent and West Texas Intermediate (WTI) are the two most commonly cited crude oil benchmarks. Brent is the light, sweet crude found in the North Sea, while WTI is the light, sweet crude refined in the US Midwest and gulf coast.

This strategy uses that spread to trade USO and BNO, two exchange-traded funds linked to futures for the WTI and Brent respectively (United States Oil Fund and United States Brent Oil Fund). For years, Brent and WTI traded at very similar prices in a highly correlated fashion. In mid-2010 Brent started trading at a premium to WTI. Speculation abounds about not only what is driving the divergence, but also about when, if, and how this imbalance will unwind and of course, how to best profit from possible scenarios. In the meantime I wanted to see how a very simplistic strategy of buying BNO and selling USO based on the spread would have fared over the last few years.

I put this algorithm together by using Quantopian's Fetcher (https://www.quantopian.com/posts/new-feature-fetcher) to query the price data from Quandl. The handle_data evaluates the crude oil prices each day. If Brent is trading at premium to WTI, the algorithm buys 1,000 shares of BNO and sells 1,000 share of USO. If the premium is reversed, reverse the trades.

As just one of the many disclaimers I can already think of to mention here, BNO only started trading in June of 2010, so lots of the interesting prior history of this relationship is not open to backtesting with that instrument.

This example needs to be extended. I'd love to see other people press the clone button on this algorithm and improve it. From the comments below, I was thinking about:
1) a rolling condition like, buy BNO/sell USO when the spread is above trailing 30 day avg (lots of possible variations on that) and vice versa
2) market neutral implementation (this isn't constrained to be market neutral, it does the easiest first thing which is to buy / sell equal share amounts)
3) other ideas for tradeable instruments in Quantopian's data set that capture more history than BNO (which started trading in June 2010)

Disclaimer

The material on this website is provided for informational purposes only and does not constitute an offer to sell, a solicitation to buy, or a recommendation or endorsement for any security or strategy, nor does it constitute an offer to provide investment advisory services by Quantopian. In addition, the material offers no opinion with respect to the suitability of any security or specific investment. No information contained herein should be regarded as a suggestion to engage in or refrain from any investment-related course of action as none of Quantopian nor any of its affiliates is undertaking to provide investment advice, act as an adviser to any plan or entity subject to the Employee Retirement Income Security Act of 1974, as amended, individual retirement account or individual retirement annuity, or give advice in a fiduciary capacity with respect to the materials presented herein. If you are an individual retirement or other investor, contact your financial advisor or other fiduciary unrelated to Quantopian about whether any given investment idea, strategy, product or service described herein may be appropriate for your circumstances. All investments involve risk, including loss of principal. Quantopian makes no guarantees as to the accuracy or completeness of the views expressed in the website. The views are subject to change, and may have become unreliable for various reasons, including changes in market conditions or economic circumstances.

14 responses

You're not alone if you're wondering why there is a spread at all: http://www.zerohedge.com/news/2013-02-13/guest-post-explaining-wti-brent-spread-divergence

Disclaimer

The material on this website is provided for informational purposes only and does not constitute an offer to sell, a solicitation to buy, or a recommendation or endorsement for any security or strategy, nor does it constitute an offer to provide investment advisory services by Quantopian. In addition, the material offers no opinion with respect to the suitability of any security or specific investment. No information contained herein should be regarded as a suggestion to engage in or refrain from any investment-related course of action as none of Quantopian nor any of its affiliates is undertaking to provide investment advice, act as an adviser to any plan or entity subject to the Employee Retirement Income Security Act of 1974, as amended, individual retirement account or individual retirement annuity, or give advice in a fiduciary capacity with respect to the materials presented herein. If you are an individual retirement or other investor, contact your financial advisor or other fiduciary unrelated to Quantopian about whether any given investment idea, strategy, product or service described herein may be appropriate for your circumstances. All investments involve risk, including loss of principal. Quantopian makes no guarantees as to the accuracy or completeness of the views expressed in the website. The views are subject to change, and may have become unreliable for various reasons, including changes in market conditions or economic circumstances.

Perhaps unrelated, but the GLD vs. GDX trading pair relationship shifted recently, as well (see https://www.quantopian.com/posts/fixed-version-of-ernie-chans-gold-vs-gold-miners-stat-arb).

@Anony - would you be willing to flesh out the intuition for the quad strategy a bit? Is the value-add purely a currency hedge? Curious if you're coming from a technical perspective or a fundamental one.

There are quite a number of modifications that could be made to this algorithm to make it more realistic - currently it doesn't address risk envelope at all, and frankly, its a bit of a buy and hold from mid/late 2010 on as implemented (because I just set a one-time threshold of the premium condition to (brent - WTI) > 0). So even worse than your point of unequal divergence, there is no attempt to capture fluctuations in the spread once its positive (which we've seen plenty of lately, including a switch from 'narrowing' to 'widening' storyline on Reuters in the last 24 hours: http://www.reuters.com/article/2013/04/09/markets-oil-idUSL3N0CW0RD20130409 )

Ideally I'd like to extend this to look at (or have anyone build on this to show):
(1) a rolling condition like, buy BNO/sell USO when the spread is above trailing 30 day avg (lots of possible variations on that) and vice versa

(2) market neutral implementation (this isn't constrained to be market neutral, it does the easiest first thing which is to buy / sell equal share amounts)

(3) other ideas for tradeable instruments in Quantopian's data set that capture more history than BNO (which started trading in June 2010)

Hi, I'm new to algorithmic trading and to Quantopian, and after cloning your algorithm and inspecting the code, there's one part of it that I'm a little confused about and was wondering if you could help me out.

In your handle_data method, you have a for loop that calculates the price and notional for each of your two stocks. However, since you're using the same variable names for both of them, won't the price and notational for BNO just overwrite the ones for USO, making the former useless? There must be something I've missed here, I look forward to hearing you reply!

Hi Sean:

Welcome to Quantopian!

In the following excerpt:

    # Initializing the position as zero at the start of each frame  
    notional=0  
    # This runs through each stock.  It computes  
    # our position at the start of each frame.  
    for stock in context.stocks:  
        price = data[stock].price  
        notional = notional + context.portfolio.positions[stock].amount * price  

the for loop is going through the list of two stocks, and accumulating each position value in the "notional" variable. (notional = notional + [new stuff]) Thus, at the end of the for loop, notional is the sum of all the position values. Hope that helps.

thanks,
Jean

Disclaimer

The material on this website is provided for informational purposes only and does not constitute an offer to sell, a solicitation to buy, or a recommendation or endorsement for any security or strategy, nor does it constitute an offer to provide investment advisory services by Quantopian. In addition, the material offers no opinion with respect to the suitability of any security or specific investment. No information contained herein should be regarded as a suggestion to engage in or refrain from any investment-related course of action as none of Quantopian nor any of its affiliates is undertaking to provide investment advice, act as an adviser to any plan or entity subject to the Employee Retirement Income Security Act of 1974, as amended, individual retirement account or individual retirement annuity, or give advice in a fiduciary capacity with respect to the materials presented herein. If you are an individual retirement or other investor, contact your financial advisor or other fiduciary unrelated to Quantopian about whether any given investment idea, strategy, product or service described herein may be appropriate for your circumstances. All investments involve risk, including loss of principal. Quantopian makes no guarantees as to the accuracy or completeness of the views expressed in the website. The views are subject to change, and may have become unreliable for various reasons, including changes in market conditions or economic circumstances.

Hi Jean,

Thanks a lot for you reply, I see what is going on now. I didn't pay attention to the fact that the notional value was cumulative. That's cleared up for me now.

is Fetcher opensource? part of zipline?

Hi,

Fetcher is not part of zipline, it is a datasource we built, similar to the trade history datasource. At the moment, the datasources are pretty dependent on quantopian infrastructure, so we don't have a plan to opensource them.

thanks,
fawce

@Anony - very cool - thanks for sharing.
How did you set the weights? Tuning on prior historical data?

It kind of sucks, but here's an example of a dynamic linear model(beta is a random walk) that regresses the brent trade-able stock on the data.

@Anony Mole: spectral analysis isn't part of the basic theory of pairs trading.

edit: I screwed this up. I'll fix it and make it a new thread. Sorry about the threadjack.

The performance graph of the original algorithm is extremely misleading since the algorithm basically stops taking on positions around May 2011. Basically it just becomes a buy and hold strategy after that. So the performance is basically just coming from a speculative buy in oil (especially since the ratios are not 1:1 between USO and BNO).

@Taylor - please do post, would like to take a look at your edited algo!

@Gunnar - yup, I should have called this out more clearly in the original post, but I did point out that it devolves into a buy and hold in the thread further down. I had hoped to (just haven't gotten to it yet) extend this to a more meaningful pairs trade that tracks the spread vs just trades on the dumb threshold. Initially I just wanted to throw this out as an example of how to use the new Fetcher feature.

And since we're updating, the spread is still narrowing, and of course still getting press: http://seekingalpha.com/article/1382511-wti-brent-spread-dips-below-9-50-for-first-time-in-24-months-headed-even-lower

Errors....
ValueError: 'Price' is not in list
There was a runtime error on line 26.

How are you determining an entry/exit point?