Quantopian's community platform is shutting down. Please read this post for more information and download your code.
Back to Community
Request for a starting point on Sector Rotation Strategies

Hi,
I had been a fairly active participant in the Wealthlab community till about 3 years ago, when life decided to pull me in a different direction. Then last week I try to login there and the website and the looks are completely different. So, I was looking for a similar site, when I saw this site mentioned in Barron's this week and decided to give it a try. My programming skills are rusty at best, so I need some help.

Here is the strategy. I don't remember where i saw it, but I wrote it down and am writing it from my notes. I wish I had the source written so I could give credit to where credit is due.

I am using two sectors to be held. I will list the ETFs to be used below. There are a few overlaps in the ETFs (eg. healthcare and biotech - IYH and IBB), but if a sector is doing very well, then it maybe worth just piling on to it.

Please note, ROC = rate of change = [(Close - Close n periods ago) / (Close n periods ago)] * 100
X= Delay Period, which hopefully means will avoid sectors that are peaking.
For this case, I am looking at 120 day ROC, but for buying purposes, I will look at the 120 day ROC of ETFs 20 days ago.

The strategy is long only and is simply stated as-
1. At the end of each month, RANK the group of ETFs based on their ROC(n=120 Day), X(20 days back).
2. At the open of the 1st trading day of each month, BUY the Top 2 ETFs, except if they closed below their 120 day moving average. In such case, buy TLT (long-term Treasury bonds) instead.
3. Repeat every month.

ETF universe consists of the following:
TLT
IYC
ITB
IYK
IYE
IYF
IBB
IYH
IYJ
IYW
IYM
IYZ
IDU
ICLN
IGF
IYR
IFGL

Thank you for your help.
Maji

2 responses

Hi Maji,

I'd start with something like this:

import pandas

def lastbday(dtime):  
    '''Check if date is the last business day of the month'''  
    return pandas.bdate_range(dtime.strftime('%m/%d/%Y'),  
                              periods=1, freq='BM')[0].date() == dtime.date()

def roc(data, n, x):  
    '''Calculate rate of change'''  
    # FIXME: to be implemented  
    pass

def rank(data, etfs):  
    '''Calculate rank for the set of etfs.'''  
    # FIXME: this is a fake implementation  
    import random  
    return [(random.randrange(-100, 100), etf) for etf in etfs]

def initialize(context):  
    context.etfs = [sid(23921), sid(21644), sid(32011), sid(21650),  
                    sid(21646), sid(21522), sid(22445), sid(21648),  
                    sid(21649), sid(21524), sid(21651), sid(21638),  
                    sid(36480), sid(44539), sid(21652), sid(35095)]  
    context.tlt = sid(23921)

def handle_data(context, data):  
    if lastbday(get_datetime()):  
        (rank1, topetf1), (rank2, topetf2) = sorted(rank(data,  
                                                         context.etfs))[-2:]  
        cash = context.portfolio.cash  
        if data[topetf1].price > data[topetf1].mavg(120) and \  
           data[topetf2].price > data[topetf2].mavg(120):  
            for etf in topetf1, topetf2:  
                order(etf, amount=cash/2/data[etf].price)  
                log.debug('bought %s' % etf.symbol)  
        else  
            order(context.tlt, cash/data[context.tlt].price)  
            log.debug('bought TLT')

Please, consider this code as an example. I just wanted to give you an overall idea of how implementation would look like.

Regards,
Ed

Thank you Ed.