Home > Backtesting, R > Calendar Strategy: Fed Days

Calendar Strategy: Fed Days

UPDATE: I was pointed out a problem with original post due to look ahead bias introduced by prices > SMA(prices,100) statement. In the calendar strategy logic I did not use a usual lag of one day because important days are known before hand. However, the prices > SMA(prices,100) statement should be lagged by one day. I updated plots and source code.

Today, I want to follow up with the Calendar Strategy: Option Expiry post. Let’s examine the importance of the FED meeting days as presented in the Fed Days And Intermediate-Term Highs post.

Let’s dive in and examine historical perfromance of SPY during FED meeting days:

###############################################################################
# Load Systematic Investor Toolbox (SIT)
# https://systematicinvestor.wordpress.com/systematic-investor-toolbox/
###############################################################################
setInternet2(TRUE)
con = gzcon(url('http://www.systematicportfolio.com/sit.gz', 'rb'))
    source(con)
close(con)
	#*****************************************************************
	# Load historical data
	#****************************************************************** 
	load.packages('quantmod')
		
	tickers = spl('SPY')
		
	data <- new.env()
	getSymbols.extra(tickers, src = 'yahoo', from = '1980-01-01', env = data, set.symbolnames = T, auto.assign = T)
		for(i in data$symbolnames) data[[i]] = adjustOHLC(data[[i]], use.Adjusted=T)
	bt.prep(data, align='keep.all', fill.gaps = T)

	#*****************************************************************
	# Setup
	#*****************************************************************
	prices = data$prices
		n = ncol(prices)
		
	dates = data$dates	
	
	models = list()
	
	universe = prices > 0
		# 100 day SMA filter
		universe = universe & prices > SMA(prices,100)
		
	# Find Fed Days
	info = get.FOMC.dates(F)
		key.date.index = na.omit(match(info$day, dates))
	
	key.date = NA * prices
		key.date[key.date.index,] = T
		
	#*****************************************************************
	# Strategy
	#*****************************************************************
	signals = list(T0=0)
		for(i in 1:15) signals[[paste0('N',i)]] = 0:i	
	signals = calendar.signal(key.date, signals)
	models = calendar.strategy(data, signals, universe = universe)

	strategy.performance.snapshoot(models, T, sort.performance=F)

plot1

Please note 100 day moving average filter above. If we take it out, the performance deteriorates significantly.

	# custom stats	
	out = sapply(models, function(x) list(
		CAGR = 100*compute.cagr(x$equity),
		MD = 100*compute.max.drawdown(x$equity),
		Win = x$trade.summary$stats['win.prob', 'All'],
		Profit = x$trade.summary$stats['profitfactor', 'All']
		))	
	performance.barchart.helper(out, sort.performance = F)
	
	strategy.performance.snapshoot(models$N15, control=list(main=T))
	
	last.trades(models$N15)
	
	trades = models$N15$trade.summary$trades
		trades = make.xts(parse.number(trades[,'return']), as.Date(trades[,'entry.date']))
	layout(1:2)
		par(mar = c(4,3,3,1), cex = 0.8) 
	barplot(trades, main='N15 Trades', las=1)
	plot(cumprod(1+trades/100), type='b', main='N15 Trades', las=1)

N15 Strategy:

plot2

plot3

plot4

plot5

With this post I wanted to show how easily we can study calendar strategy performance using the Systematic Investor Toolbox.

Next, I will look at the importance of the Dividend days.

To view the complete source code for this example, please have a look at the bt.calendar.strategy.fed.days.test() function in bt.test.r at github.

Advertisements
Categories: Backtesting, R
  1. Mondo
    May 7, 2014 at 12:25 pm

    Thanks, very interesting. Could you explain why some trade in the N15 example are held for only a couple of days e.g. the trade entered on 2012-06-18? Doesn’t the N 15 mean hold for 15 days from the Fed day?

    • May 7, 2014 at 11:56 pm

      Please note the 100 day moving average filter. If during 15 days, SPY drops below its 100 day moving average, we exit position until SPY is above its 100 day moving average and 15 days has not yet passed since Fed meeting day.

  2. Zack
    May 7, 2014 at 3:15 pm

    Could you clarify what N15 means? Are you buying on the evening before a Fed day and holding for 15 days? Your entry/exit dates suggest that, except the entry on 6/18/12 exited 2 days later, so it is not clear what this strategy is doing. These are interesting studies.

    • May 7, 2014 at 11:58 pm

      N15 – enter at the close a day before Fed meeting and exit 15 days later. If during that period SPY drops below its 100 day moving average, we exit and only re-enter if SPY is above its 100 day moving average and 15 days has not yet passed since Fed meeting day.

  3. Philip Van Eygen
    May 20, 2014 at 1:25 pm

    Dear,

    As always, very interesting.
    Could you please show a way to test whether the return during any N day period after a FED meeting is statistically different from any N day period where there is not a FED meeting?

    On the same subject of calendar strategies could you show how to recreate using R the Day of the month graph from marketsci: http://marketsci.wordpress.com/2014/01/30/day-of-month-seasonality-for-february-2/ ?

    Thanks in advance and keep up the great blogging!

  1. May 7, 2014 at 6:15 am

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: