Today I want to highlight a whitepaper about Adaptive Asset Allocation by Butler, Philbrick and Gordillo and the discussion by David Varadi on the robustness of parameters of the Adaptive Asset Allocation algorithm.
In this post I will follow the steps of the Adaptive Asset Allocation paper, and in the next post I will show how to test the sensitivity of parameters of the of the Adaptive Asset Allocation algorithm.
I will use the 10 ETFs that invest into the same asset classes as presented in the paper:
- U.S. Stocks (SPY)
- European Stocks (EFA)
- Japanese Stocks (EWJ)
- Emerging Market Stocks (EEM)
- U.S. REITs (IYR)
- International REITs (RWX)
- U.S. Mid-term Treasuries (IEF)
- U.S. Long-term Treasuries (TLT)
- Commodities (DBC)
- Gold (GLD)
Unfortunately, most of these 10 ETFs only began trading in the end of 2004, so I will only be able to replicate the recent Adaptive Asset Allocation strategy performance.
Let’s start by loading historical prices of 10 ETFs using the Systematic Investor Toolbox:
###############################################################################
# Load Systematic Investor Toolbox (SIT)
# http://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,EFA,EWJ,EEM,IYR,RWX,IEF,TLT,DBC,GLD')
data <- new.env()
getSymbols(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='keep.all', dates='2004:12::')
#*****************************************************************
# Code Strategies
#******************************************************************
prices = data$prices
n = ncol(prices)
models = list()
# find period ends
period.ends = endpoints(prices, 'months')
period.ends = period.ends[period.ends > 0]
# Adaptive Asset Allocation parameters
n.top = 5 # number of momentum positions
n.mom = 6*22 # length of momentum look back
n.vol = 1*22 # length of volatility look back
Next, let’s create portfolios as outlined in the whitepaper:
#*****************************************************************
# Equal Weight
#******************************************************************
data$weight[] = NA
data$weight[period.ends,] = ntop(prices[period.ends,], n)
models$equal.weight = bt.run.share(data, clean.signal=F)
#*****************************************************************
# Volatliliy Position Sizing
#******************************************************************
ret.log = bt.apply.matrix(prices, ROC, type='continuous')
hist.vol = bt.apply.matrix(ret.log, runSD, n = n.vol)
adj.vol = 1/hist.vol[period.ends,]
data$weight[] = NA
data$weight[period.ends,] = adj.vol / rowSums(adj.vol, na.rm=T)
models$volatility.weighted = bt.run.share(data, clean.signal=F)
#*****************************************************************
# Momentum Portfolio
#*****************************************************************
momentum = prices / mlag(prices, n.mom)
data$weight[] = NA
data$weight[period.ends,] = ntop(momentum[period.ends,], n.top)
models$momentum = bt.run.share(data, clean.signal=F)
#*****************************************************************
# Combo: weight positions in the Momentum Portfolio according to Volatliliy
#*****************************************************************
weight = ntop(momentum[period.ends,], n.top) * adj.vol
data$weight[] = NA
data$weight[period.ends,] = weight / rowSums(weight, na.rm=T)
models$combo = bt.run.share(data, clean.signal=F,trade.summary = TRUE)
Finally let’s create the Adaptive Asset Allocation portfolio:
#*****************************************************************
# Adaptive Asset Allocation (AAA)
# weight positions in the Momentum Portfolio according to
# the minimum variance algorithm
#*****************************************************************
weight = NA * prices
weight[period.ends,] = ntop(momentum[period.ends,], n.top)
for( i in period.ends[period.ends >= n.mom] ) {
hist = ret.log[ (i - n.vol + 1):i, ]
# require all assets to have full price history
include.index = count(hist)== n.vol
# also only consider assets in the Momentum Portfolio
index = ( weight[i,] > 0 ) & include.index
n = sum(index)
if(n > 0) {
hist = hist[ , index]
# create historical input assumptions
ia = create.historical.ia(hist, 252)
s0 = apply(coredata(hist),2,sd)
ia$cov = cor(coredata(hist), use='complete.obs',method='pearson') * (s0 %*% t(s0))
# create constraints: 0<=x<=1, sum(x) = 1
constraints = new.constraints(n, lb = 0, ub = 1)
constraints = add.constraints(rep(1, n), 1, type = '=', constraints)
# compute minimum variance weights
weight[i,] = 0
weight[i,index] = min.risk.portfolio(ia, constraints)
}
}
# Adaptive Asset Allocation (AAA)
data$weight[] = NA
data$weight[period.ends,] = weight[period.ends,]
models$aaa = bt.run.share(data, clean.signal=F,trade.summary = TRUE)
The last step is create reports for all models:
#*****************************************************************
# Create Report
#******************************************************************
models = rev(models)
plotbt.custom.report.part1(models)
plotbt.custom.report.part2(models)
plotbt.custom.report.part3(models$combo, trade.summary = TRUE)
plotbt.custom.report.part3(models$aaa, trade.summary = TRUE)
The AAA portfolio performs very well, producing the highest Sharpe ratio and smallest draw-down across all strategies. In the next post I will look at the sensitivity of AAA parameters.
To view the complete source code for this example, please have a look at the bt.aaa.test() function in bt.test.r at github.
R-bloggers.com offers daily e-mail updates about R news and tutorials on topics such as: visualization (ggplot2, Boxplots, maps, animation), programming (RStudio, Sweave, LaTeX, SQL, Eclipse, git, hadoop, Web Scraping) statistics (regression, PCA, time series, trading) and more...





Zero Inflated Models and Generalized Linear Mixed Models with R.
Zuur, Saveliev, Ieno (2012).