backtest

Optimal Stock Bond Allocation

It’s been more than a month since I last posted. Time flies when you are busy working on the things you enjoy.

After reading a piece on the lacklustre performance of hedge funds versus a standard 60/40 portfolio mix, it got me thinking deeper about stock bond allocation. In this post I am going to dissect and check the internal workings of the equity bond allocation and see if there are any tactical overlay that can improve a static allocation mix.

Data: I will be using monthly data from Data Stream and Bloomberg; SP500 and 10 Year treasuries, all total return from January 1988 to May 2012.

Here a backtest helper function wrapped around SIT:

require(TTR)
require(quantmod)

setInternet2(TRUE)
con = gzcon(url('https://github.com/systematicinvestor/SIT/raw/master/sit.gz', 'rb'))
source(con)
close(con)

btest<-function(data1,allocation,rebalancing){
  data <- list(prices=data1[,1:2])
  data$weight<-data1[,1:2]
  data$weight[!is.na(data$weight)]<- NA
  data$execution.price<-data1[,1:2]
  data$execution.price[!is.na(data$execution.price)]<-NA
  data$dates<-index(data1[,1:2])
  prices = data$prices   
  nperiods = nrow(prices)
  data$weight[] = NA  
  data$weight[1,] = allocation
  period.ends = seq(1,nrow(data$prices),rebalancing)-1 
  period.ends<-period.ends[period.ends>0]
  data$weight[period.ends,]<-repmat(allocation, len(period.ends), 1)
  capital = 100000
  data$weight[] = (capital / prices) * data$weight
  model = bt.run(data, type='share', capital=capital)
  return(model)
}

This simply runs the backtest for provided allocation and rebalancing period for 2 assets. To check the performance of all equity allocation from 0 to 1 in increments of n%, I will be using the following wrapper function:

sensitivity<-function(data1,rebalancing,allocation.increments){
  equity.allocation<-seq(0,1,allocation.increments) #Y-axis
  eq = matrix(NA, nrow=nrow(data1), ncol=1)

  for(i in equity.allocation) {
    allocation <- matrix(c((1-i),i), nrow=1)
    temp<-btest(data1,allocation,rebalancing)
    eq<-cbind(eq,temp$equity)
  }
  eq<-eq[,-1]
  colnames(eq) = 1-equity.allocation

  cagr<-matrix(NA,nrow=ncol(eq),ncol=1)
  for(i in 1:ncol(eq)){
    cagr[i]<-compute.cagr(eq[,i])
  }
  cagr<-as.data.frame(cbind(1-equity.allocation,cagr))
  colnames(cagr)<-c('Equity Allocation','CAGR')

  sharpe<-matrix(NA,nrow=ncol(eq),ncol=1)
  eq.ret<-ROC(eq)
  eq.ret[is.na(eq.ret)]<-0
  for(i in 1:ncol(eq)){
    sharpe[i]<-compute.sharpe(eq.ret[,i])
  }
  sharpe<-as.data.frame(cbind(1-equity.allocation,sharpe))
  colnames(sharpe)<-c('Equity Allocation','Sharpe')
  return(list(eq=eq,cagr=cagr,sharpe=sharpe))
} 

Running the sensitivity function in increments of 5% provides:

 

As you increase the equity allocation, you become more aggressive, which is obviously displayed from the chart above. What is the optimal allocation based on highest CAGR or Sharpe? The sensitivity function also returns a list of the performance of each equity allocation and the chart:

In the above chart, I’ve graphed two lines each with its own respective axis. From the chart, it seems that the equity allocation that provided the highest Sharpe Ratio is ~0.25. This seems to be similar to a risk parity allocation as historical data shows that such allocation is very close to optimal risk parity.

Diving deeper, I went in to check each successive 12 month period’s highest Sharpe equity allocation from 1988 to 2012. In another word, this takes us back in time!

 

 

From this chart, the max sharpe allocation varied significantly over each year. Whenever crisis hit, the allocation to bonds seems to dominate that on equity and vice versa in bull markets. This intuitively make sense as you would want to be in risk off mode during bear markets.

The last chart shows the rolling 12 month performance of each equity allocation from 0 to 1 in increments on 5%.

 

In another post, I will follow up on whether there are any tactical overlays that can improve performance.

 

 

Advertisements

Diversification through Equity Blending

In a sound asset allocation framework, it is never a good idea to over weight the risky portion of the portfolio. One example would be the traditional 60/40 portfolio whereby an investor allocates 60% to equities and 40% to bonds. Such allocation may intuitively makes sense as you “feel” diversified but when extraordinary events happen, you will be less protected. Below is the performance of the 60/40 allocation rebalanced monthly since 2003. Note I used SPY and IEF for the mix.

In this post, I would like to show some ideas that will reduce risk and increase return by bringing in a different type of return stream. Traditional asset allocation focuses mainly on optimal diversification of assets, here I will focus on allocation to strategies. From my own research, there are only so many asset classes the individual can choose to mix to form portfolios, not to mention the less than reliable cross correlation between assets classes in market turmoil (2008). To bring stability for the core portfolio, I will incorporate Harry Browne’s Permanent Portfolio. This return stream is composed of equal weight allocation to equities, gold, bonds. and liquid cash. For the more aggressive part, I will use daily equity mean reversion (RSI2). Note that a basic strategy overlay on an asset can produce a return stream that can have diversification benefits. Below are three different equity curves. Black, green and red represents, mean reversion, 60/40 equal weight allocation of both strategies, and permanent portfolio respectively.  

To summarize, I have taken two return streams derived from strategies traded over assets and combined them to form a portfolio. The allocation percentage is 40% to the risk asset (mean reversion/MR) and 60% to the conservative asset (Permanent Portfolio/PP). And here are the performance metrics.

Traditional represents the traditional 60/40 allocation to equity and bonds while B-H represents buy and hold for the SP500. This superficial analysis is only meant to prove the powerful idea of equity blending of assets and trading strategies. When traditional search for diversification becomes fruitless, this idea of incorporating different strategies can have a huge impact on your underlying performance.

I will come back later for the R code as its pretty late and I have class tomorrow!

Systematic Edge Backtest Engine: plotting features

Here are some new additions to the plotting functions of the backtester. They are a great way of visualizing the performance of a trading strategy. As I wanted ease and simplicity, all of the following plots can be done in one line of code. Each image is followed by the code that  generated it.

plot.equity(equity,bench,testParameters)

 

plot.drawdown(perf,bench)

plot.horizon(equity,bench,testParameters,250)

plot.calendarHeatMap(equity)

The first two plots are very self-explanatory. The third plot is called horizon plot. It is a compact way of visualizing time series data. The intuition behind the way I use it is to chart rolling n (250 in my case) period performance of a strategy relative to its benchmark. The darker the red, the more underperformance, while the darker the blue, the more outperformance. If you refer to the plot and look at the 2008 crisis, you can see that in general, the colour of the strategy is lighter in red compared to the benchmark, showing hedging at its best.

The last chart is a calendar heat-map. It plots the n-period log return for the entire test period and shows you how it has performed in different periods of time. This plot is great for detailed consistency checking as it is a great way peeling in to the strategies performance as it cycles through time; a true time machine in my opinion.

A creative performance measure derived from the calendar heat map is the percent of daily return above a user defined return threshold. The threshold by definition should be the risk free rate. When doing strategy comparison, the higher the percent of days of out performance, the better.

Much more to come. Enjoy!