T-Bond Seasonality

To install Systematic Investor Toolbox (SIT) please visit About page.

The Jay On The Markets wrote two posts about Treasury Bond Seasonality at:

Below I will try to adapt a code from the posts:

#*****************************************************************
# Load historical data
#*****************************************************************
library(SIT)
load.packages('quantmod')

tickers = 'TLT'

data = new.env()
getSymbols.extra(tickers, src = 'yahoo', from = '1980-01-01', env = data, auto.assign = T)

for(i in ls(data))
	data[[i]] = adjustOHLC(data[[i]], use.Adjusted=T)

bt.prep(data, align='remove.na')

#*****************************************************************
# Setup
#*****************************************************************
prices = data$prices

models = list()

commission = list(cps = 0.01, fixed = 10.0, percentage = 0.0)

universe = prices > 0

key.date.index = date.month.ends(data$dates, F)
key.date = NA * prices
	key.date[key.date.index,] = T	
	
#*****************************************************************
# Benchmark
#*****************************************************************
data$weight[] = NA
	data$weight$TLT = 1
models$TLT = bt.run.share(data, clean.signal=T, commission = commission, trade.summary=T, silent=T)

#*****************************************************************
# Last 5 trading days of the month
#*****************************************************************
signals = list(L5=-4:0)
	signals = calendar.signal(key.date, signals)
	signals$exL5 = ifna(!signals$L5,T)
models = c(models, calendar.strategy(data, signals, universe = universe, commission = commission))

#*****************************************************************
# Create Report
#*****************************************************************
#strategy.performance.snapshoot(models, T)
plotbt(models, plotX = T, log = 'y', LeftMargin = 3, main = NULL)
	mtext('Cumulative Performance', side = 2, line = 1)

plot of chunk plot-2

print(plotbt.strategy.sidebyside(models, make.plot=F, return.table=T, perfromance.fn=engineering.returns.kpi))
  TLT L5 exL5
Period Jul2002 - Mar2015 Jul2002 - Mar2015 Jul2002 - Mar2015
Cagr 8.08 5.15 1.64
Sharpe 0.63 0.82 0.19
DVR 0.56 0.7 0.07
R2 0.89 0.86 0.37
Volatility 13.83 6.42 12.25
MaxDD -26.58 -17.22 -30.85
Exposure 99.97 23.74 76.22
Win.Percent 100 63.82 53.29
Avg.Trade 167.27 0.48 0.25
Profit.Factor NaN 2.09 1.19
Num.Trades 1 152 152
print(last.trades(models$L5, make.plot=F, return.table=T))
models$L5 weight entry.date exit.date nhold entry.price exit.price return
TLT 100 2013-07-24 2013-07-31 7 102.49 102.66 0.17
TLT 100 2013-08-23 2013-08-30 7 99.66 101.29 1.63
TLT 100 2013-09-23 2013-09-30 7 101.27 101.95 0.67
TLT 100 2013-10-24 2013-10-31 7 103.65 103.41 -0.23
TLT 100 2013-11-21 2013-11-29 8 99.17 100.61 1.46
TLT 100 2013-12-23 2013-12-31 8 100.15 98.73 -1.42
TLT 100 2014-01-24 2014-01-31 7 104.18 104.95 0.75
TLT 100 2014-02-21 2014-02-28 7 103.66 105.50 1.78
TLT 100 2014-03-24 2014-03-31 7 106.18 106.28 0.09
TLT 100 2014-04-23 2014-04-30 7 108.37 108.50 0.12
TLT 100 2014-05-22 2014-05-30 8 109.74 111.71 1.79
TLT 100 2014-06-23 2014-06-30 7 109.40 111.43 1.86
TLT 100 2014-07-24 2014-07-31 7 112.49 112.17 -0.29
TLT 100 2014-08-22 2014-08-29 7 115.72 117.46 1.51
TLT 100 2014-09-23 2014-09-30 7 114.17 114.98 0.72
TLT 100 2014-10-24 2014-10-31 7 118.69 118.22 -0.39
TLT 100 2014-11-20 2014-11-28 8 118.64 121.73 2.60
TLT 100 2014-12-23 2014-12-31 8 123.05 125.42 1.93
TLT 100 2015-01-23 2015-01-30 7 134.24 137.73 2.60
TLT 100 2015-02-20 2015-02-27 7 126.30 129.28 2.36
print(plotbt.monthly.table(models$L5$equity, make.plot = F))
  Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec Year MaxDD
2002               1.3 0.3 1.9 -0.7 1.8 5.9 -2.3
2003 0.1 2.4 1.6 1.7 -1.1 -2.0 -3.4 0.3 3.1 -0.1 -1.6 -0.1 0.7 -7.3
2004 -0.4 1.4 -1.7 -0.5 1.6 1.3 -0.5 1.9 -1.3 -0.5 -2.1 0.3 -0.6 -5.2
2005 0.3 -1.0 1.4 1.0 0.8 0.8 -0.5 1.9 -0.5 -1.1 -0.6 1.1 3.5 -2.6
2006 -1.4 0.5 -2.5 -0.8 -1.1 1.0 0.6 0.8 -0.4 2.9 1.1 -1.6 -0.9 -5.5
2007 -0.1 1.6 -0.6 0.3 -0.2 1.6 1.7 1.1 0.9 -1.2 0.6 1.8 7.8 -2.6
2008 0.6 2.4 0.6 -0.1 -1.2 2.5 0.6 0.8 1.3 -4.1 1.2 -1.2 3.3 -9.2
2009 -3.7 -2.0 1.6 -3.5 -0.5 0.9 3.6 1.1 2.2 0.8 1.5 -0.5 1.4 -12.8
2010 0.3 2.4 0.2 2.2 -2.0 2.5 0.6 0.7 0.5 -1.0 1.4 1.6 9.8 -2.8
2011 -0.4 3.2 -0.3 1.3 0.9 -3.4 1.9 0.7 -0.1 2.2 -2.9 1.7 4.6 -5.1
2012 3.7 0.5 -0.9 -0.5 3.4 0.1 -1.7 2.3 2.2 1.9 0.4 -0.7 11.1 -3.8
2013 -2.0 1.3 0.4 0.4 -1.9 1.8 0.1 1.6 0.6 -0.3 1.4 -1.5 1.9 -2.7
2014 0.7 1.7 0.1 0.1 1.7 1.8 -0.3 1.5 0.7 -0.4 2.6 1.9 12.6 -1.7
2015 2.6 2.3 0.0                   5.0 -1.4
Avg 0.0 1.3 0.0 0.1 0.0 0.8 0.2 1.2 0.7 0.1 0.2 0.4 4.7 -4.6

Next, let’s test with Direxion Daily 20+ Yr Trsy Bull 3X ETF (TMF)

Below I will extend it with iShares 20+ Year Treasury Bond (TLT) which is not a perfect proxy, but will do for our testing purposes.

#*****************************************************************
# Load historical data
#*****************************************************************
tickers = 'TLT,TMF'

data = new.env()
getSymbols.extra(tickers, src = 'yahoo', from = '1980-01-01', env = data, auto.assign = T)

data$TMF = extend.data(data$TMF, create.leveraged(data$TLT, leverage=3), scale=T)    

for(i in ls(data))
	data[[i]] = adjustOHLC(data[[i]], use.Adjusted=T)

bt.prep(data, align='remove.na')

#*****************************************************************
# Setup
#*****************************************************************
prices = data$prices
  # do not invest in TLT
	prices$TLT = NA	

models = list()

commission = list(cps = 0.01, fixed = 10.0, percentage = 0.0)

universe = prices > 0

key.date.index = date.month.ends(data$dates, F)
key.date = NA * prices
	key.date[key.date.index,] = T	

#*****************************************************************
# Benchmark
#*****************************************************************
data$weight[] = NA
	data$weight$TMF = 1
models$TMF = bt.run.share(data, clean.signal=T, commission = commission, trade.summary=T, silent=T)

#*****************************************************************
# Last 5 trading days of the month
#*****************************************************************
signals = list(L5=-4:0)
	signals = calendar.signal(key.date, signals)
	signals$exL5 = ifna(!signals$L5,T)
models = c(models, calendar.strategy(data, signals, universe = universe, commission = commission))

#*****************************************************************
# Create Report
#*****************************************************************
#strategy.performance.snapshoot(models, T)
plotbt(models, plotX = T, log = 'y', LeftMargin = 3, main = NULL)
	mtext('Cumulative Performance', side = 2, line = 1)

plot of chunk plot-3

print(plotbt.strategy.sidebyside(models, make.plot=F, return.table=T, perfromance.fn=engineering.returns.kpi))
  TMF L5 exL5
Period Jul2002 - Mar2015 Jul2002 - Mar2015 Jul2002 - Mar2015
Cagr 17.4 16.02 -0.85
Sharpe 0.59 0.86 0.16
DVR 0.43 0.67 0.01
R2 0.73 0.79 0.05
Volatility 41.89 19.55 37.05
MaxDD -66.97 -46.13 -78.15
Exposure 99.97 23.74 76.22
Win.Percent 100 63.82 51.32
Avg.Trade 661.5 1.44 0.61
Profit.Factor NaN 2.12 1.16
Num.Trades 1 152 152
print(last.trades(models$L5, make.plot=F, return.table=T))
models$L5 weight entry.date exit.date nhold entry.price exit.price return
TMF 100 2013-07-24 2013-07-31 7 49.88 50.03 0.30
TMF 100 2013-08-23 2013-08-30 7 45.57 47.80 4.89
TMF 100 2013-09-23 2013-09-30 7 47.60 48.53 1.95
TMF 100 2013-10-24 2013-10-31 7 50.93 50.53 -0.79
TMF 100 2013-11-21 2013-11-29 8 44.30 46.39 4.72
TMF 100 2013-12-23 2013-12-31 8 45.58 43.60 -4.34
TMF 100 2014-01-24 2014-01-31 7 50.99 52.09 2.16
TMF 100 2014-02-21 2014-02-28 7 50.10 52.94 5.67
TMF 100 2014-03-24 2014-03-31 7 53.72 53.87 0.28
TMF 100 2014-04-23 2014-04-30 7 56.92 57.08 0.28
TMF 100 2014-05-22 2014-05-30 8 58.99 62.10 5.27
TMF 100 2014-06-23 2014-06-30 7 58.11 61.48 5.80
TMF 100 2014-07-24 2014-07-31 7 63.09 62.47 -0.98
TMF 100 2014-08-22 2014-08-29 7 68.38 71.48 4.53
TMF 100 2014-09-23 2014-09-30 7 65.29 66.73 2.21
TMF 100 2014-10-24 2014-10-31 7 72.97 72.11 -1.18
TMF 100 2014-11-20 2014-11-28 8 72.73 78.66 8.15
TMF 100 2014-12-23 2014-12-31 8 80.70 86.04 6.62
TMF 100 2015-01-23 2015-01-30 7 104.60 112.72 7.76
TMF 100 2015-02-20 2015-02-27 7 86.62 92.58 6.88
for(n in names(models)) {
	print('##', n)
	print(plotbt.monthly.table(models[[n]]$equity, make.plot = F))
}

TMF

  Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec Year MaxDD
2002               17.0 13.0 -11.1 -3.4 14.0 34.3 -19.1
2003 -2.1 9.4 -4.4 3.0 19.7 -5.8 -27.6 3.4 18.3 -9.2 0.7 3.8 0.0 -40.9
2004 5.4 6.8 4.0 -17.9 -1.0 2.9 4.4 12.8 2.7 5.2 -7.2 7.9 24.8 -29.5
2005 10.9 -4.6 -1.7 11.8 9.6 6.3 -10.0 10.6 -10.6 -6.8 1.8 9.1 24.8 -20.5
2006 -4.1 3.2 -13.2 -8.2 -0.7 3.4 6.5 9.4 5.7 2.4 7.0 -8.0 0.5 -25.7
2007 -3.1 10.3 -5.1 2.6 -6.8 -3.4 10.0 5.3 0.4 5.3 16.5 -2.5 30.4 -22.2
2008 5.8 -2.0 5.9 -7.6 -8.1 7.9 -1.5 8.2 3.2 -6.2 46.8 44.7 120.4 -21.6
2009 -35.4 -5.7 11.3 -22.6 -14.6 0.1 0.3 5.8 7.4 -9.4 3.0 -20.1 -61.9 -64.1
2010 7.3 -1.8 -6.7 9.9 16.5 16.8 -3.9 25.9 -9.0 -13.6 -6.0 -11.7 16.1 -41.5
2011 -9.4 4.5 -0.5 6.6 10.4 -7.4 13.3 27.4 41.3 -12.9 4.9 9.5 109.2 -30.2
2012 -1.5 -7.9 -13.0 14.4 28.9 -5.8 11.4 -4.6 -7.9 -2.1 3.9 -7.8 0.6 -28.2
2013 -9.6 3.4 -1.8 14.3 -19.7 -10.3 -7.4 -4.5 1.5 4.1 -8.2 -6.0 -39.0 -44.5
2014 19.5 1.6 1.8 6.0 8.8 -1.0 1.6 14.4 -6.6 8.1 9.1 9.4 97.3 -14.7
2015 31.0 -17.9 4.5                   12.4 -28.5
Avg 1.1 0.0 -1.5 1.0 3.6 0.3 -0.2 10.1 4.6 -3.5 5.3 3.2 26.4 -30.8

L5

  Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec Year MaxDD
2002               3.9 0.8 5.8 -2.3 5.4 18.3 -6.8
2003 0.2 7.4 5.0 5.1 -3.3 -5.9 -9.9 0.8 9.4 -0.5 -4.7 -0.2 1.4 -20.7
2004 -1.3 4.4 -5.1 -1.6 4.9 3.8 -1.5 5.8 -3.7 -1.4 -6.1 0.8 -2.0 -14.9
2005 0.8 -2.9 4.1 3.1 2.5 2.4 -1.5 5.7 -1.5 -3.2 -1.9 3.4 11.0 -7.4
2006 -4.1 1.7 -7.4 -2.4 -3.2 3.1 1.7 2.5 -1.0 9.1 3.5 -4.6 -2.3 -15.4
2007 -0.4 4.8 -1.8 0.8 -0.5 5.0 5.2 3.4 2.7 -3.5 1.8 5.6 25.1 -7.7
2008 1.8 7.1 1.7 -0.3 -3.7 7.8 1.9 2.3 3.6 -11.8 3.2 -3.7 8.9 -25.5
2009 -11.1 -5.9 4.8 -12.4 -1.7 2.8 12.5 5.0 8.7 2.6 5.3 -1.7 5.7 -36.4
2010 0.3 7.7 0.5 7.0 -5.7 8.2 1.8 1.8 1.5 -3.1 4.3 4.9 32.2 -9.0
2011 -1.2 9.6 -1.0 3.8 2.8 -9.9 6.0 2.1 -0.8 5.6 -8.7 4.8 11.8 -14.9
2012 11.7 1.9 -2.7 -1.6 10.3 0.1 -4.9 6.8 6.5 5.8 1.4 -2.1 36.6 -11.0
2013 -5.9 4.0 1.4 1.2 -5.8 5.4 0.2 4.8 1.9 -0.8 4.7 -4.4 6.0 -8.1
2014 2.1 5.6 0.2 0.2 5.2 5.7 -1.0 4.5 2.2 -1.2 8.1 6.6 44.8 -4.9
2015 7.7 6.8 0.0                   15.1 -4.1
Avg 0.0 4.0 0.0 0.2 0.1 2.4 0.9 3.8 2.3 0.3 0.7 1.1 15.2 -13.3

exL5

  Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec Year MaxDD
2002               12.2 11.8 -16.2 -1.4 7.8 11.6 -19.5
2003 -2.5 1.6 -9.3 -2.2 23.6 0.0 -19.8 2.3 7.8 -9.0 5.4 3.7 -4.5 -32.4
2004 6.5 2.1 9.4 -16.8 -5.9 -1.2 5.7 6.4 6.4 6.5 -1.4 6.7 23.5 -27.4
2005 9.8 -2.0 -5.8 8.2 6.7 3.7 -8.8 4.4 -9.5 -3.8 3.6 5.3 9.7 -22.2
2006 -0.2 1.3 -6.5 -6.1 2.4 0.1 4.5 6.5 6.6 -6.3 3.2 -3.8 0.4 -16.6
2007 -2.9 5.1 -3.5 1.6 -6.6 -8.1 4.3 1.6 -2.5 8.9 14.3 -7.8 2.0 -21.5
2008 3.8 -8.6 4.0 -7.5 -4.8 -0.1 -3.4 5.5 -0.6 6.2 42.0 50.0 98.9 -27.3
2009 -27.4 0.1 6.1 -11.8 -13.2 -2.7 -11.0 0.7 -1.3 -11.9 -2.4 -18.9 -64.6 -64.6
2010 6.8 -9.0 -7.3 2.6 23.5 7.8 -5.7 23.5 -10.5 -11.0 -10.0 -16.0 -13.8 -43.1
2011 -8.5 -4.9 0.4 2.5 7.2 2.7 6.7 24.6 42.3 -17.6 14.7 4.4 84.1 -24.3
2012 -11.9 -9.7 -10.7 16.2 16.7 -6.0 17.0 -10.8 -13.6 -7.6 2.4 -5.9 -27.2 -34.7
2013 -4.0 -0.7 -3.2 12.8 -14.8 -15.1 -7.7 -9.0 -0.5 4.9 -12.4 -1.8 -43.2 -48.8
2014 16.9 -3.9 1.4 5.6 3.3 -6.5 2.6 9.4 -8.7 9.3 0.8 2.5 34.6 -16.7
2015 21.5 -23.2 4.5                   -2.5 -33.6
Avg 0.6 -4.0 -1.6 0.4 3.2 -2.1 -1.3 6.0 2.1 -3.7 4.5 2.0 7.8 -30.9

(this report was produced on: 2015-03-24)