Skip to content

Instantly share code, notes, and snippets.

@timelyportfolio
Created June 15, 2012 20:18
  • Star 2 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save timelyportfolio/2938507 to your computer and use it in GitHub Desktop.
R Horizon Chart
require(lattice)
require(latticeExtra)
require(reshape2)
require(quantmod)
#set up horizon plots as a function
horizonplot <- function(prices,horizon.type="offset",scale=0.05,title=NA,alpha=0.4){
#get change in prices since beginning or 1st row
prices.change <- prices[,4]/as.numeric(prices[1,4])-1
#get as a data.frame so it will work well with melt and lattice
prices.change.df <- as.data.frame(cbind(as.Date(index(prices.change)),coredata(prices.change)))
#get date back to recognizable date form
prices.change.df[,1] <- as.Date(prices.change.df[,1])
#names columns for easier access
colnames(prices.change.df) <- c("date","change")
#smooth line for better appearance
prices.smooth <- spline(as.numeric(prices.change.df$change)~as.numeric(prices.change.df$date))
#do mirror graph
pmirror <-
xyplot(y~as.Date(x),data=prices.smooth,ylim=c(0,scale),origin=0,
par.settings=theEconomist.theme(box="transparent"),
lattice.options=theEconomist.opts(),
xlab=NULL,ylab=NULL,
#do function for an area chart
panel = function(x,y,...){
#divide by the scale specified and go through each time until no more left
#each pass will darken the graph with alpha
#first for loop will do the positive in green
for (i in 0:round(max(y)/scale,0))
panel.xyarea(x,y=ifelse(y>0,y,NA)-(scale * i),col="green",border="green",alpha=alpha,lwd=2,...)
#second for loop handles the negatives in red
#will take absolute value of y to mirror
for (i in 0:round(max(ifelse(y < 0,abs(y),0))/scale,0))
panel.xyarea(x,y=ifelse(y<0,abs(y),NA)-(scale * i),col="red",border="red",lwd=2,alpha=alpha,...)
},
main=title)
#get the positive and negative plots for the offset chart
#very similar to the mirror chart above
#except the negative values will be moved to the top of y range
#and inverted
ppos<-
xyplot(y~as.Date(x),data=prices.smooth,ylim=c(0,scale),origin=0,
par.settings=theEconomist.theme(box="transparent"),
lattice.options=theEconomist.opts(),
xlab=NULL,ylab=NULL,
panel = function(x,y,...){
#
for (i in 0:round(max(y)/scale,0))
panel.xyarea(x,y=ifelse(y>0,y,NA)-(scale * i),col="green",border="green",alpha=alpha,lwd=2,...)
},
main=title)
pneg <-
xyplot(y~as.Date(x),data=prices.smooth,ylim=c(0,scale),origin=scale,
panel=function(x,y,...){
for (i in 0:round(min(y)/-scale,0)) {
panel.xyarea(x,y=scale+ifelse(y<0,y,NA)+(scale*i),col="red",border="red",lwd=2,alpha=alpha,...)
}
})
ifelse(horizon.type=="mirror", return(pmirror), return(ppos+pneg))
}
getSymbols("^W0DOW",from="2011-12-31")
getSymbols("^GSPC",from="2011-12-31")
getSymbols("^DJUBS",from="2011-12-31")
#do the default offset
p1<-horizonplot(prices=W0DOW,horizon.type="offset",title="Dow Jones World Ex Americas")
p2<-horizonplot(prices=GSPC,horizon.type="offset",title="S&P 500")
p3<-horizonplot(prices=DJUBS,horizon.type="offset",title="Dow Jones UBS Commodity Index")
print(p1,position=c(0,0.66,1,1),more=TRUE)
print(p2,position=c(0,0.33,1,0.66),more=TRUE)
print(p3,position=c(0,0,1,0.33))
#do again but this time as mirror
p1<-horizonplot(prices=W0DOW,horizon.type="mirror",title="Dow Jones World Ex Americas")
p2<-horizonplot(prices=GSPC,horizon.type="mirror",title="S&P 500")
p3<-horizonplot(prices=DJUBS,horizon.type="mirror",title="Dow Jones UBS Commodity Index")
print(p1,position=c(0,0.66,1,1),more=TRUE)
print(p2,position=c(0,0.33,1,0.66),more=TRUE)
print(p3,position=c(0,0,1,0.33))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment