Home > Asset Allocation, Backtesting, R > Update for Backtesting Asset Allocation Portfolios post

Update for Backtesting Asset Allocation Portfolios post

It was over a year since my original post, Backtesting Asset Allocation portfolios. I have expanded the functionality of the Systematic Investor Toolbox both in terms of optimization functions and helper back-test functions during this period.

Today, I want to update the Backtesting Asset Allocation portfolios post and showcase new functionality. I will use the following global asset universe as: SPY,QQQ,EEM,IWM,EFA,TLT,IYR,GLD to form portfolios every month using different asset allocation methods.

###############################################################################
# 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,quadprog,corpcor,lpSolve')
	tickers = spl('SPY,QQQ,EEM,IWM,EFA,TLT,IYR,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='remove.na', dates='1990::') 
	
	#*****************************************************************
	# Code Strategies
	#****************************************************************** 					
	cluster.group = cluster.group.kmeans.90
		
	obj = portfolio.allocation.helper(data$prices, 
		periodicity = 'months', lookback.len = 60, 
		min.risk.fns = list(
			EW=equal.weight.portfolio,
			RP=risk.parity.portfolio(),
			MD=max.div.portfolio,						
			
			MV=min.var.portfolio,
			MVE=min.var.excel.portfolio,
			MV2=min.var2.portfolio,
			
			MC=min.corr.portfolio,
			MCE=min.corr.excel.portfolio,
			MC2=min.corr2.portfolio,
			
			MS=max.sharpe.portfolio(),
			ERC = equal.risk.contribution.portfolio,

			# target retunr / risk
			TRET.12 = target.return.portfolio(12/100),								
			TRISK.10 = target.risk.portfolio(10/100),
		
			# cluster
			C.EW = distribute.weights(equal.weight.portfolio, cluster.group),
			C.RP = distribute.weights(risk.parity.portfolio, cluster.group),
			
			# rso
			RSO.RP.5 = rso.portfolio(risk.parity.portfolio, 5, 500), 
			
			# others
			MMaxLoss = min.maxloss.portfolio,
			MMad = min.mad.portfolio,
			MCVaR = min.cvar.portfolio,
			MCDaR = min.cdar.portfolio,
			MMadDown = min.mad.downside.portfolio,
			MRiskDown = min.risk.downside.portfolio,
			MCorCov = min.cor.insteadof.cov.portfolio
		)
	)
	
	models = create.strategies(obj, data)$models
						
	#*****************************************************************
	# Create Report
	#******************************************************************    
	strategy.performance.snapshoot(models, T, 'Backtesting Asset Allocation portfolios')

plot1

I hope you will enjoy creating your own portfolio allocation methods or playing with a large variety of portfolio allocation techniques that are readily available for your experimentation.

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

  1. David Bingham Skalak
    October 24, 2013 at 4:35 pm

    Hi, I find your work exemplary. And I’m extremely grateful that you are so generous as to post it publicly.

    I considering starting a MCDar portfolio in an IRA. So I wanted to make sure that I’m interpreting the weights correctly in the bt.aa.test.new() output: “MCDaR , percent = 87% Latest weights : EEM EFA GLD IWM IYR QQQ SPY TLT 2013-10-23 0 3.29245 182.059 0 0 529.98 0 303.952 ”

    The sum of the weights is 1019.28 So GLD should be weighted 182.059/1019.28 =~ 8.05% of the portfolio, and similarly for the other instruments?

    Regards, David Skalak

    • October 26, 2013 at 4:15 pm

      Please use following statement to get portfolio weights at the last 5 re-balances:

      round(100 * last(models$MCDaR$weight[obj$period.ends[-len(obj$period.ends)]+1], 5))
      

      The numbers printed by the default represent the number of shares at the last re-balance given that you want to invest $100,000

  2. Pierre
    October 26, 2013 at 5:54 am

    Hi Michael,

    Very impressive update. Thank you so much for your continued efforts and for sharing the fruits of these.
    With kind regards,

    Pierre

  3. October 26, 2013 at 6:45 pm

    Thank you Michael for your wonderful work. It was a long time since you wrote ,
    I missed your post .
    I believe that your SIT is one of the most beautiful things written for R.
    I admire your work so much so that if you decide to ask some money for SIT, i would be among those that would contribute willingly .
    The talent should be rewarded .
    I had already told you in the past. If I had to find one limit to your SIT , for me , is its inability to indicate percentage costs in the various models under study.
    This limit reaches its climax exactly when we perform backtest of different optimization algorithms in order to compare the efficacy of one over another.
    The turnover of the various different models leads to conclusions often illusory. It would be really important to introduce a mechanism that penalize effectively and realistically the algorithms that perform a higher number of trades . Otherwise , I repeat, any comparison is meaningless .
    The best way that I can think of to get more accurate comparisons is the introduction , as I said , of costs \ commissions (expressed as a percentage of trade) . The current mechanism of commission in SIT , in my opinion, is not right.
    I tried several times to introduce myself this mechanism (both trying to modify the SIT’s code , that working in excel environment ) . But I’ve never managed to get a well-structured result. It ‘s too complex for my current programming skills .

  1. November 11, 2013 at 10:14 pm

Leave a comment