Thursday, April 27, 2017

R script for the Seeking Alpha article

library(quantmod)
library(PerformanceAnalytics)
library(tseries)
# initial value
stockRatio <- .5
interRatio <- .15
# rebalancing period
# prd <- 'yearly'
prd <- 'monthly'
# prd <- 'daily'

# symbols used
# VUSTX govvies
# VWESX IG bonds
# VTSMX stocks
# VWEHX junk
# VGTSX international stocks ex US
# VTRIX international value

# get the data
getSymbols(c('VTSMX','VWESX', 'VUSTX', 'VWEHX', 'VGTSX'), from='1900-07-28')

# ---------this section is the base portfolio analysis------------
m=merge(Ad(VTSMX),Ad(VUSTX), all=F)
s=periodReturn(m[,1], period = prd)
b=periodReturn(m[,2], period = prd)
# create the portfolios
p1 <- stockRatio * s + (1-stockRatio) * b
# first plot
plot(cumprod(1+p1), main= 'Total Returns, Base Port, Yearly Rebal', log='y')
grid(lwd=3, equilogs = F)
# ---------this section is the IG corporate portfolio analysis------------
m=merge(Ad(VTSMX),Ad(VWESX), all=F)
s=periodReturn(m[,1], period = prd)
b=periodReturn(m[,2], period = prd)
# create the portfolios
p1 <- stockRatio * s + (1-stockRatio) * b
# first plot
plot(cumprod(1+p1), main= 'Total Returns, IG Corp Port, Yearly Rebal', log='y')
# plot last year
plot(tail(cumprod(1+p1),255), main= 'Total Returns, Base Port, Yearly Rebal', log='y')
# ---------this section is the high yield analysis------------
m=merge(Ad(VTSMX),Ad(VWEHX),Ad(VUSTX), all=F)
s=periodReturn(m[,1], period = prd)
j=periodReturn(m[,2], period = prd)
b=periodReturn(m[,3], period = prd)
# create the portfolios
p1 <- stockRatio * s + (1-stockRatio) * b
p2 <- stockRatio * s + (1-stockRatio) * j
# first plot
plot(cumprod(1+s), main= 'Total Returns')
lines(cumprod(1+j), col='red')
lines(cumprod(1+b), col='green')
grid(lwd = 3)
legend('topleft', c('Stocks','High Yield','Gov Bonds'), fill = c('black','red','green'))
# second plot
plot(cumprod(1+p1), ylim=c(1,10), log='y', main='Portfolio Growth of $1')
lines(cumprod(1+p2), col='red')
grid(lwd = 3, equilogs = F)
legend('topleft', c('Govern Bonds','High Yield'), fill = c('black','red'))
# get the drawdowns, use daily data
prd <- 'daily'
s=periodReturn(m[,1], period = prd)
j=periodReturn(m[,2], period = prd)
b=periodReturn(m[,3], period = prd)
# create the portfolios
p1 <- stockRatio * s + (1-stockRatio) * b
p2 <- stockRatio * s + (1-stockRatio) * j
table.Drawdowns(p1)
table.Drawdowns(p2)
# not used here
# pDum <- portfolio.optim(mm, pm=.07)
# pdum$pw
# ---------this section is the international stock analysis------------
m <- merge(Ad(VTSMX), Ad(VGTSX), Ad(VUSTX), all=F)
# p3 is US stocks/bonds since 1996
# p4 is US + internat / bonds
s <- periodReturn(m[,1])
i <- periodReturn(m[,2])
b <- periodReturn(m[,3])
p3 <- (s + b) /2
p4 <- (.35 *s + .15 * i + .5 * b)
plot(cumprod(1+p3), log='y', main = 'With/Without International Stocks')
lines(cumprod(1+p4), col='red')
grid(lwd = 3)
legend('topleft', c('US Stocks only','Incl Intern Stocks'), fill = c('black','red'), bty = 'n',cex = 2)

Wednesday, March 15, 2017

An R Script to Calculate and Plot Alpha

Alpha is the essence of trading. Getting risk-adjusted returns above the market is a zero sum game and what leads to value. Here's an R script to calculate and plot the alpha of an asset. Any asset that is available for download in Yahoo is OK. It also outputs some related statistics.

For example, supposing we wanted to analyze the materials etf XLB. We would call the function with

> AlphaPlot('XLB')

and the function would output:

[1] "Number of Trading Days is  4585"
[1] "Beta is  0.96"
[1] "Beta of Last 100 Days is 1.04"
[1] "Annualized Total Return 0.07657"
[1] "Annualized Alpha 0.01973"
[1] "Ending Cumulative Alpha is 0.4208"

In the plot window, this graph of cumulative alpha over time will appear:

If you want to try this, here's the code. The usual disclaimers apply:
This is not investment advice. Don't blame me if you lose money.
The code may have bugs I didn't catch. Kindly make a comment if you find one.
You may not agree with my interpretation of modern finance.
Alpha here is purely historical. We all know about past performance and such.

# Typical call
# AlphaPlot('PUTW','SPY')
library(quantmod)
#
AlphaPlot <- function( asset, baseAsset = 'SPY', period = 'd', judgemtl = 'n', plotLength = 'all', yLog=TRUE){
#   Creates and plots a alpha series of 'asset' against 'baseAsset'
  # asset       = the asset to get the alpha of
  # baseAsset   = the base (independent) asset or index
  # period      = 'd', 'm', or 'y'
  # judgemtl    = used to assign a non-statistical beta
  # plotLength  = if a number, plots the last plotLength days
  
  if ( !plotLength == 'all') {
    if ( !is.numeric(plotLength ) ) {
      print('plotLength must be set to all or a number')
      return()
    }
  }

  myEnv <- new.env()
  getSymbols(c( asset, baseAsset ), from = '1990-01-01', env = myEnv)
  MainXTS <- do.call(merge, c(eapply(myEnv, Ad),all=FALSE))
  
  period   <- tolower(period)
  prd <- c( 'daily', 'monthly', 'yearly')
  dum <- substring(prd,1,1)
  inx <- which( period==dum)
  dum <- prd[inx]
  a <- periodReturn( MainXTS[,1], period = dum )
  b <- periodReturn( MainXTS[,2], period = dum)
  
  
print( paste("Number of Trading Days is ",length(MainXTS[,1])) )
  if (judgemtl == 'n'){
    reg <- lm( a ~ b )
    beta <- reg$coeff[2]
  }
  if ( judgemtl != 'n' ) beta <- judgemtl
  title = paste('Cumulative Alpha', asset, dum, 'versus', baseAsset, collapse='   ')
  alpha <- cumprod(1 + (a - beta * b))
  print( paste( 'Beta is ', format(beta, digits = 2 ) ) )
  dumm <- lm( tail(a,100) ~ tail(b,100) )
  print( paste("Beta of Last 100 Days is", format(dumm$coeff[2], digits = 3)) )
  annAlpha <- as.numeric( tail( alpha,1 ) )
  annAlpha <- annAlpha ^ (255/length(MainXTS[,1]))
  gg=as.numeric(tail(MainXTS[,1],1)) / as.numeric(head(MainXTS[,1],1))
  print( paste( 'Annualized Total Return',  format( gg ^ (255/length(MainXTS[,1]))-1,digits = 4 ) ) )
  print(paste( 'Annualized Alpha', format(annAlpha-1, digits = 4) ) )
  print( paste( 'Ending Cumulative Alpha is', format(alpha[length(alpha)]-1,digits = 4) ) )
  
  if (plotLength == 'all') plot( alpha, main = title )
  else plot( tail( alpha, plotLength ), main = title )
  #legend( 'topleft', c( paste( 'Beta = ', sprintf("%5.2f", beta) ) ) )

}

As you can see there are a number of options. If you just call it with the symbol (in quotes), it will default to using SPY as the base with which to calculate the alpha. If you give it a second symbol, it will use that as the base. It defaults to daily prices, but you can specify 'm' for monthly or 'y' for yearly. Beta comes out of the calculation, but if you want to use your judgement for it, specify "judgement=" and a number. It also defaults to using all the downloaded data, but you can use the "plotlength=" and put in a number for the last number of days.

Good luck everyone! I'll be putting more of this kind of stuff up soon.