|
require(quantmod) |
|
require(PerformanceAnalytics) |
|
getSymbols("VFINX",from="1990-01-01",adjust=TRUE) |
|
getSymbols("VBMFX",from="1990-01-01",adjust=TRUE) |
|
perf <- na.omit(merge(monthlyReturn(VBMFX[,4]),monthlyReturn(VFINX[,4]))) |
|
colnames(perf) <- c("VBMFX","VFINX") |
|
|
|
#get 8 month RSI; randomly picked 8; no optimization |
|
rsi<- lag(merge(RSI(perf[,1],n=8),RSI(perf[,2],n=8)),k=1) |
|
#allocate between vbmfx and vfinx based on highest RSI |
|
rsi.perf <- ifelse(rsi[,1]>rsi[,2],perf[,1],perf[,2]) |
|
rsi.each <- as.xts(as.matrix(rsi>50) * as.matrix(perf), |
|
order.by=index(perf)) |
|
|
|
#get cumulative returns for moving average |
|
cumul <- as.xts(apply(perf+1,MARGIN=2,cumprod),order.by=index(perf)) |
|
#do 10 month Mebane Faber style system |
|
ma <- lag(merge(runMean(cumul[,1],n=10),runMean(cumul[,2],n=10)),k=1) |
|
#apply 50% allocation to each fund if they are > 10 month moving average |
|
ma.perf <- as.xts(apply(as.matrix(cumul>ma) * as.matrix(perf)/2, |
|
MARGIN=1,sum), |
|
order.by=index(perf)) |
|
ma.each <- as.xts(as.matrix(cumul>ma) * as.matrix(perf), |
|
order.by=index(perf)) |
|
|
|
#add omega as another allocation method |
|
omega <- lag(merge(apply.rolling(perf[,1],width=6,by=1,FUN=Omega), |
|
apply.rolling(perf[,2],width=6,by=1,FUN=Omega)), |
|
k=1) |
|
#if omega >= 1 then apply 50% allocation |
|
omega.perf <- as.xts(apply(as.matrix(omega>=1) * as.matrix(perf)/2, |
|
MARGIN=1,sum), |
|
order.by=index(perf)) |
|
omega.each <- as.xts(as.matrix(omega>=1) * as.matrix(perf), |
|
order.by=index(perf)) |
|
|
|
perf.all <- merge(perf,rsi.perf,rsi.each,ma.perf,ma.each,omega.perf,omega.each) |
|
perf.all[is.na(perf.all)]<-0 |
|
colnames(perf.all) <- c(colnames(perf),paste(c(rep("rsi",3),rep("ma",3),rep("omega",3)), |
|
c("",".VBMFX",".VFINX"),sep="")) |
|
|
|
#now let's add two very basic systems |
|
#and explore on Systematic Investor's efficient frontier |
|
######################################################## |
|
#continue to highlight the very fine work of |
|
#http://systematicinvestor.wordpress.com/ |
|
#adapted some of his code to provide |
|
#a not-so-novel additional example for |
|
#those that might be interested |
|
####################################################### |
|
# Load Systematic Investor Toolbox (SIT) |
|
con = gzcon(url('https://github.com/systematicinvestor/SIT/raw/master/sit.gz', 'rb')) |
|
source(con) |
|
close(con) |
|
|
|
#-------------------------------------------------------------------------- |
|
# Create Efficient Frontier |
|
#-------------------------------------------------------------------------- |
|
ia = list() |
|
#amend to use the funds and basic systems |
|
ia$symbols = colnames(perf.all) |
|
ia$n = len(ia$symbols) |
|
#use PerformanceAnalytics tables to get return (geometric) and risk |
|
#for the entire period |
|
ia$expected.return = as.matrix(t(table.Stats(perf.all)[7,])) |
|
ia$risk = as.matrix(t(table.Stats(perf.all)[14,])) |
|
ia$correlation = cor(perf.all) |
|
ia$cov = cov(perf.all) |
|
n = ia$n |
|
|
|
# 0 <= x.i <= 1 |
|
constraints = new.constraints(n, lb = 0, ub = 1) |
|
|
|
# SUM x.i = 1 |
|
constraints = add.constraints(rep(1, n), 1, type = '=', constraints) |
|
|
|
# create efficient frontier |
|
ef.risk = portopt(ia, constraints, 50) |
|
|
|
#I am getting an error here |
|
#plot.ef(ia, ef.risk), transition.map=TRUE) |
|
#know what is happening but not motivated to fix |
|
#"Error in x$weight : $ operator is invalid for atomic vectors" |
|
#will do manually plot |
|
colors <- c("purple","indianred3","steelblue2","steelblue3","steelblue4", |
|
"darkolivegreen2","darkolivegreen3","darkolivegreen4", |
|
"chocolate2","chocolate3","chocolate4") |
|
plot(ef.risk$return~ef.risk$risk,col="grey60",lwd=3,type="l", |
|
xlim=c(min(ia$risk),max(ia$risk)+.01), |
|
ylim=c(min(ia$expected.return),max(ia$expected.return))) |
|
points(x=as.numeric(ia$risk),y=as.numeric(ia$expected.return),pch=19, |
|
col=colors,cex=1.5) |
|
text(x=as.numeric(ia$risk),y=as.numeric(ia$expected.return), |
|
labels=ia$symbols,pos=4,col=colors) |
|
title(main="Efficient Frontier of VBMFX and VFINX and Systematic Allocation", |
|
adj=0,outer=TRUE,line=-1) |
|
plot.transition.map(ef.risk,col=colors) |
|
|
|
chart.CumReturns(perf.all,colorset=colors, |
|
main="Growth of VBMFX and VFINX and Systematic Allocations", |
|
legend.loc="topleft") |
Great post, I really liked the last chart to show the relative performance of each strategy. I just ran a quick test of the SMA10 strategy on VFINX in quantstrat. My equity curve looks similar to yours, but doesn't go quite so parabolic... could just be the scale that gives that appearance.
ReplyDeleteAgain, great posts recently. I especially like how you are demonstrating the use of knitr to generate reports.
Ross
Nice post, one question about the combined portfolios (ma): what is the rule there regarding rebalancing and allocation?
ReplyDeleteCheers
Andreas
thanks so much to rbresearch and Andreas for the comments. Rule for this simple example is monthly rebalancing. Hope to use PortfolioAnalytics or the SIT (Systematic Investor Toolkit) to try other methods of rebalancing soon. Great question with very big implications.
ReplyDelete