Skip to content

Instantly share code, notes, and snippets.

@FrozenQuant
Last active January 1, 2016 13:39
Show Gist options
  • Save FrozenQuant/8152946 to your computer and use it in GitHub Desktop.
Save FrozenQuant/8152946 to your computer and use it in GitHub Desktop.
R Markdown file for watching a Faber strategy
Faber Strategy Monitor
========================================================
This post was created in R using Markdown and posted directly to WordPress. It creates a table of data and a set of price charts for tracking funds used in Mebane Faber's trend following strategy. Data is gathered from Yahoo Finance using the API in the **quantmod** package, then rendered into a web page using RStudio and [***knitr***](http://yihui.name/knitr/), with the help of **googleVis** and **ggplot2**.
This particular implementation of the Faber strategy comes from his book *The Ivy Portfolio*. The program is to invest in a broad array of markets and buy individual ETFs when the price of the ETF exceeds its 10-month moving average and sell when it goes below. This particular example uses ten ETFs, two in each major category (as shown in Table 9.2 of *The Ivy Portfolio*).
The table shows some basic information about each ETF, the current price versus the 10-month SMA, and the same price/SMA data as of the prior month end. The chart is from the great package **googleVis**. The default HTML viewer may not display the table correctly, so you may need to look at it using Chrome.
```{r setup, echo=FALSE, message=FALSE, warning=FALSE}
options("getSymbols.warning4.0"=FALSE)
library(quantmod, quietly=TRUE)
library(googleVis)
library(ggplot2, quietly=TRUE)
library(reshape2,quietly=TRUE)
```
```{r table, echo=FALSE, warning=FALSE, message=FALSE}
# Reads in CSV file with the names and symbols used in this strategy.
file.location <- "http://www.frozenquant.com/get/FaberSampleHoldings.csv"
CSVClasses<-c(rep("factor",3),"character")
FaberHoldings <- read.table(file.location, header=TRUE, sep=",", colClasses=CSVClasses)
FaberTable <- FaberHoldings[,c(1,4,2)]
FaberTable$Price <- NA
FaberTable$MovAvg <- NA
FaberTable$Trend <- "Eq"
FaberTable$LastMonthPrice <- NA
FaberTable$LastMonthSMA <- NA
FaberTable$LastMonthTrend <- "Eq"
# Get the symbols in the table
symbols <- levels(FaberHoldings$Symbols)
# Load data with quantmod
msg<-getSymbols(symbols, index.class=c("POSIXt","POSIXct"), from='2010-01-01', auto.assign=TRUE)
# Get a current quote frem Yahoo
quote <- getQuote(symbols, index.class=c("POSIXt","POSIXct"), from='2010-01-01')
# Put together the table - this checks to see if the quote is as of
# a date later than the end of the time series and appends it if so.
# Also reduces variables to the closing value only rather than OHLC
# Note this loop takes the last 2 values
for (symbol in symbols){
date.hist <- as.Date(last(index(get(symbol))))
date.quote <- as.Date(quote[symbol,"Trade Time"])
if (date.quote > date.hist){
assign(symbol, rbind(Cl(get(symbol)),
xts(quote[symbol,"Last"],
order.by=as.POSIXct(quote[symbol,"Trade Time"]))))
last_price <- round(last(Cl(to.monthly(get(symbol))),2),2)
last_sma <- round(last(SMA(Cl(to.monthly(get(symbol))),10),2),2)
}
else{
assign(symbol,Cl(get(symbol)))
last_price <- round(last(Cl(to.monthly(get(symbol))),2),2)
last_sma <- round(last(SMA(Cl(to.monthly(get(symbol))),10),2),2)
}
# Update Table - insert current and penultimate values
FaberTable[FaberTable$Symbols==symbol,]$Price <- last_price[2]
FaberTable[FaberTable$Symbols==symbol,]$MovAvg <- last_sma[2]
FaberTable[FaberTable$Symbols==symbol,]$Trend <- (if (last_price[2] > last_sma[2]) "Above" else if (last_price[2] < last_sma[2]) "Below" )
FaberTable[FaberTable$Symbols==symbol,]$LastMonthPrice <- last_price[1]
FaberTable[FaberTable$Symbols==symbol,]$LastMonthSMA <- last_sma[1]
FaberTable[FaberTable$Symbols==symbol,]$LastMonthTrend <- (if (last_price[1] > last_sma[1]) "Above" else if (last_price[1] < last_sma[1]) "Below" )
}
```
Here is a chart using the Google Visualization API. This was updated as of `r format(quote[1,"Trade Time"],"%m/%d/%Y %H:%M:%S")`. You can click on the headings to resort the table, a nice feature of this package. The code below shows how easy it is to create a nice table from a data frame.
```{r displaytable,results='asis'}
InvestmentTable <- gvisTable(FaberTable, options = list(width = 800, height = 300,
page = "enable"))
print(InvestmentTable, "chart")
```
```{r define_ggSMA, echo=FALSE}
sma_for_ggplot<- function(obj, sma_periods=200){
x<- Cl(obj)
colnames(x) <- unlist(strsplit(colnames(x),"\\."))[1]
y<-as.data.frame(x)
y$dates<- as.Date(index(x))
sma<- SMA(x, sma_periods)
colnames(sma)<-"SMA"
sma<- as.data.frame(sma)
sma$dates<- as.Date(index(x))
z<- melt(y,id="dates")
return(merge(z,sma,by="dates"))
}
```
```{r CalcCharts, echo=FALSE}
# Set the size of the plots to be larger than default
opts_chunk$set(fig.width=10)
levels <- levels(FaberHoldings$Type)[c(3,4,1,5,2)]
for (level in levels){
gg_symbols<- FaberHoldings[level==FaberHoldings$Type,]$Symbols
gg_symbols<- as.character(gg_symbols)
gg_df<- data.frame()
for(gg_symbol in gg_symbols){
gg_df<- rbind(gg_df,sma_for_ggplot(get(gg_symbol),200))
}
# Note how the syntax works - you define the data frame in qplot, then add the second line in
# geom_path, then finally the facet command.
p <- qplot(dates, value, data = gg_df, geom = "line", group = variable) + geom_path(aes(y=SMA),color="red",na.rm=T) + scale_x_date(lim = c(as.Date("2012-1-1"), as.Date(last(gg_df$dates))))+ facet_grid(variable ~ ., scales = "free_y")
assign(paste("gg.",make.names(level),sep=""),p)
}
```
The charts below show the data from January 1, 2012 to present with the 200-day moving average in red. The charts are made with **ggplot2**.
This is the chart for the domestic stock ETFs:
```{r ds, echo=FALSE}
gg.Domestic.Stock
```
This is the chart for the foreign stock ETFs:
```{r fs, echo=FALSE}
gg.Foreign.Stock
```
This is the chart for the bond ETFs:
```{r bond, echo=FALSE}
gg.Bond
```
This is the chart for the commodity ETFs:
```{r commodity, echo=FALSE}
gg.Commodity
```
This is the chart for the real estate ETFs:
```{r re, echo=FALSE}
gg.Real.Estate
```
These charts show how nicely facet charts work in ggplot2. Also, by adding additional ETFs to the csv file it will seamlessly add more symbols to the charts. The table will also be expanded automatically.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment