Archive

Archive for February, 2013

Sector Rotation Back Test Shiny web application

Today, I want to share the Sector Rotation Back Test application (code at GitHub).

This is the last application in the series of examples (I have shared 5 examples) that will demonstrate the amazing Shiny framework and Systematic Investor Toolbox to analyze stocks, make back-tests, and create summary reports.

The motivation for this series of posts is to show how to translate, with minimal effort, your back-test scripts into live web applications that can either be run from the Shiny server or your personal computer.

Please note that Back Test applications take longer time to update the plots/tables and hence maybe more appropriate to run from your local computer.

For example to run Sector Rotation application from your computer, you first need to install Shiny. And next execute following commands:

library(shiny)
runGitHub('SIT','systematicinvestor', subdir = 'Shiny/sector.rotation')
Advertisements
Categories: R, Shiny

Market Filter Back Test Shiny web application

February 16, 2013 5 comments

Today, I want to share the Market Filter Back Test application (code at GitHub).

This is the forth application in the series of examples (I plan to share 5 examples) that will demonstrate the amazing Shiny framework and Systematic Investor Toolbox to analyze stocks, make back-tests, and create summary reports.

The motivation for this series of posts is to show how to translate, with minimal effort, your back-test scripts into live web applications that can either be run from the Shiny server or your personal computer.

Please note that Back Test applications take longer time to update the plots/tables and hence maybe more appropriate to run from your local computer.

I will post the next example application on Monday.

Have a good long weekend

Categories: R, Shiny

January Seasonality Shiny web application

Today, I want to share the January Seasonality application (code at GitHub).

This example is based on the An Example of Seasonality Analysis post.

This is the third application in the series of examples (I plan to share 5 examples) that will demonstrate the amazing Shiny framework and Systematic Investor Toolbox to analyze stocks, make back-tests, and create summary reports.

The motivation for this series of posts is to show how to translate, with minimal effort, your back-test scripts into live web applications that can either be run from the Shiny server or your personal computer.

I will post the fourth example application tomorrow.

Categories: R, Shiny

Multiple Stocks Plot Shiny web application

Today, I want to share the Multiple Stocks Plot application (code at GitHub).

This is the second application in the series of examples (I plan to share 5 examples) that will demonstrate the amazing Shiny framework and Systematic Investor Toolbox to analyze stocks, make back-tests, and create summary reports.

The motivation for this series of posts is to show how to translate, with minimal effort, your back-test scripts into live web applications that can either be run from the Shiny server or your personal computer.

I will post the third example application tomorrow.

Categories: R, Shiny

Single Stock Plot Shiny web application

February 13, 2013 1 comment

Today, I want to share the Single Stock Plot application (code at GitHub).

This is the first application in the series of examples (I plan to share 5 examples) that will demonstrate the amazing Shiny framework and Systematic Investor Toolbox to analyze stocks, make back-tests, and create summary reports.

The motivation for this series of posts is to show how to translate, with minimal effort, your back-test scripts into live web applications that can either be run from the Shiny server or your personal computer.

I will post the second example application tomorrow.

Categories: R, Shiny

Cluster Portfolio Allocation

February 12, 2013 5 comments

Today, I want to continue with clustering theme and show how the portfolio weights are determined in the Cluster Portfolio Allocation method. One example of the Cluster Portfolio Allocation method is Cluster Risk Parity (Varadi, Kapler, 2012).

The Cluster Portfolio Allocation method has 3 steps:

  • Create Clusters
  • Allocate funds within each Cluster
  • Allocate funds across all Clusters

I will illustrate below all 3 steps using “Equal Weight” and “Risk Parity” portfolio allocation methiods. Let’s start by loading historical prices for the 10 major asset classes.

###############################################################################
# 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 for ETFs
	#****************************************************************** 
	load.packages('quantmod')

	tickers = spl('GLD,UUP,SPY,QQQ,IWM,EEM,EFA,IYR,USO,TLT')

	data <- new.env()
	getSymbols(tickers, src = 'yahoo', from = '1900-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
	#****************************************************************** 
	# compute returns
	ret = data$prices / mlag(data$prices) - 1

	# setup period
	dates = '2012::2012'
	ret = ret[dates]

Next, let’s compute “Plain” portfolio allocation (i.e. no Clustering)

	fn.name = 'equal.weight.portfolio'				
	fn = match.fun(fn.name)

	# create input assumptions
	ia = create.historical.ia(ret, 252) 
	
	# compute allocation without cluster, for comparison
	weight = fn(ia)

Next, let’s create clusters and compute portfolio allocation within each Cluster

	# create clusters
	group = cluster.group.kmeans.90(ia)
	ngroups = max(group)

	weight0 = rep(NA, ia$n)
			
	# store returns for each cluster
	hist.g = NA * ia$hist.returns[,1:ngroups]
			
	# compute weights within each group	
	for(g in 1:ngroups) {
		if( sum(group == g) == 1 ) {
			weight0[group == g] = 1
			hist.g[,g] = ia$hist.returns[, group == g, drop=F]
		} else {
			# create input assumptions for the assets in this cluster
			ia.temp = create.historical.ia(ia$hist.returns[, group == g, drop=F], 252) 

			# compute allocation within cluster
			w0 = fn(ia.temp)
			
			# set appropriate weights
			weight0[group == g] = w0
			
			# compute historical returns for this cluster
			hist.g[,g] = ia.temp$hist.returns %*% w0
		}
	}

Next, let’s compute portfolio allocation across all Clusters and compute final portfolio weights

	# create GROUP input assumptions
	ia.g = create.historical.ia(hist.g, 252) 
			
	# compute allocation across clusters
	group.weights = fn(ia.g)
				
	# mutliply out group.weights by within group weights
	for(g in 1:ngroups)
		weight0[group == g] = weight0[group == g] * group.weights[g]

Finally, let’s create reports and compare portfolio allocations

	#*****************************************************************
	# Create Report
	#****************************************************************** 			
	load.packages('RColorBrewer')
	col = colorRampPalette(brewer.pal(9,'Set1'))(ia$n)

	layout(matrix(1:2,nr=2,nc=1))
	par(mar = c(0,0,2,0))
	index = order(group)

	pie(weight[index], labels = paste(colnames(ret), round(100*weight,1),'%')[index], col=col, main=fn.name)

	pie(weight0[index], labels = paste(colnames(ret), round(100*weight0,1),'%')[index], col=col, main=paste('Cluster',fn.name))	

equal.weight.portfolio.plot.png.small

The difference is most striking in the “Equal Weight” portfolio allocation method. The Cluster version allocates 25% to each cluster first, and then allocates equally within each cluster. The Plain version allocates equally among all assets. The “Risk Parity” version below works in similar way, but instead of having equal weights, the focus is on the equal risk allocations. I.e. UUP gets a much bigger allocation because it is far less risky than any other asset.

risk.parity.portfolio.plot.png.small

Next week, I will show how to back-test Cluster Portfolio Allocation methods.

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

Categories: Cluster, R

Tracking Number of Historical Clusters in DOW 30 and S&P 500

February 5, 2013 1 comment

In the Tracking Number of Historical Clusters post, I looked at how 3 different methods were able to identify clusters across the 10 major asset universe. Today, I want to share the impact of clustering on the larger universe. Below I examined the historical time series of number of clusters in the DOW 30 and S&P 500 indices.

I went back to the 1970 for the companies in DOW 30 index.

plot1_dow.png.small

plot2_dow.png.small

plot3_dow.png.small

I went back to the 1994 for the companies in S&P 500 index.

plot1_sp500.png.small

plot2_sp500.png.small

plot3_sp500.png.small

Takeaways: The markets are changing, and correspondingly the diversification (i.e. number of clusters) goes thought cycles as can be seen in the charts. The results will vary across different methods and must be validated by the user. For example, some readers will consider an average of 10 clusters for S&P 500 as too small, while others might think that 10 clusters as sufficient.

Categories: Cluster, R