Chapter 2: Individual Security Returns

Total Return and Price Return

2.1: Price Returns

  • In this section, we will use IBM stock as the example because they pay dividends. We can compare the results for price returns and total returns

Step 1: Import IBM Data from Yahoo Finance

  • At the start of each chapter, load the quantmod and xts packages
  • Using techniques from Chapter 1, read-in the IBM Yahoo.csv file
library(quantmod)
## Loading required package: xts
## Loading required package: zoo
## 
## Attaching package: 'zoo'
## The following objects are masked from 'package:base':
## 
##     as.Date, as.Date.numeric
## Loading required package: TTR
## Version 0.4-0 included new data defaults. See ?getSymbols.
library(xts)
data.IBM <- read.csv("IBM Yahoo.csv", header=TRUE)
date <- as.Date(data.IBM$Date,format="%Y-%m-%d")
data.IBM <- cbind(date,data.IBM[,-1])
data.IBM <- data.IBM[order(data.IBM$date),]
data.IBM <- xts(data.IBM[,2:7],order.by=data.IBM[,1])
names(data.IBM) <-
  paste(c("IBM.Open","IBM.High","IBM.Low",
  "IBM.Close","IBM.Volume","IBM.Adjusted"))
data.IBM[c(1:3,nrow(data.IBM)),]
##            IBM.Open IBM.High IBM.Low IBM.Close IBM.Volume IBM.Adjusted
## 2010-12-31   146.73   147.07  145.96    146.76    2969800     125.8031
## 2011-01-03   147.21   148.20  147.14    147.48    4603800     126.4203
## 2011-01-04   147.56   148.22  146.64    147.64    5060100     126.5574
## 2013-12-31   186.49   187.79  186.30    187.57    3619700     169.4835

Step 2: Subset the data to only include closing price

  • The price return is calculated off the closing price. In data.IBM, this is IBM.Close or column 4. Subset the data to only include IBM closing price
IBM.prc.ret <- data.IBM[,4]
IBM.prc.ret[c(1:3,nrow(IBM.prc.ret))]
##            IBM.Close
## 2010-12-31    146.76
## 2011-01-03    147.48
## 2011-01-04    147.64
## 2013-12-31    187.57

Step 3: Calculate IBM’s Price Return

IBM.prc.ret$IBM.prc.ret <- Delt(IBM.prc.ret$IBM.Close)
IBM.prc.ret[c(1:3,nrow(IBM.prc.ret)),]
##            IBM.Close IBM.prc.ret
## 2010-12-31    146.76          NA
## 2011-01-03    147.48 0.004905976
## 2011-01-04    147.64 0.001084913
## 2013-12-31    187.57 0.006222858

Step 4: Clean up data object

  • Since the first observation is NA, we can delete this observation in IBM.prc.ret

  • Since we are dealing with returns, we do not need IBM.Clsoe and the first column can also be deleted

options(digits=3)
IBM.prc.ret <- IBM.prc.ret[-1,2]
IBM.prc.ret[c(1:3,nrow(IBM.prc.ret)),]
##            IBM.prc.ret
## 2011-01-03     0.00491
## 2011-01-04     0.00108
## 2011-01-05    -0.00400
## 2013-12-31     0.00622
options(digits=7)

2.2: Total Returns

  • The return to investors from holding shares of stock are not liited to changes in the price of the security (there are also dividends)

  • Total return equals the sum of both the change in price of the shares and any income generated from the dividends and the reinvestment of those dividends

  • For a daily total return calculation, the dividend yield is zero or non-ex dividend dates

  • Yahoo Finance gives us an adjusted closing prie varialbe, which in data.IBM, is the 6th column (labeled IBM.Adjusted)

  • We will now calculate IBM’s total returns from January 2011 to December 2013

data.IBM[715:720,]
##            IBM.Open IBM.High IBM.Low IBM.Close IBM.Volume IBM.Adjusted
## 2013-11-01   179.81   180.34  178.88    179.23    3644500     161.0826
## 2013-11-04   179.90   180.80  179.34    180.27    3483300     162.0173
## 2013-11-05   179.54   179.80  177.71    177.85    6096800     159.8423
## 2013-11-06   177.91   179.75  177.78    179.19    4560700     161.9115
## 2013-11-07   179.60   181.39  179.60    180.00    5219500     162.6434
## 2013-11-08   178.83   180.08  177.35    179.99    6275000     162.6344
  • We now turn to calculating IBM’s daily total return

Step 1: Import Adjusted Closing Price Data

  • Because we already called in the IBM.data, we only need to check that t is still in the R memory. If it is, keep the adjusted close price or column 6 in data.IBM
IBM.ret <- data.IBM[,6]
IBM.ret[c(1:3,nrow(IBM.ret)),]
##            IBM.Adjusted
## 2010-12-31     125.8031
## 2011-01-03     126.4203
## 2011-01-04     126.5574
## 2013-12-31     169.4835

Step 2: Calculate Total Return

  • When we apply the Delt command on the adjusted close price we calcualte the total return

  • Total return equals price return on non ex-dividend days and the total return is higher than the price return on ex-dividend days

IBM.ret$IBM.tot.ret=Delt(IBM.ret$IBM.Adjusted)
IBM.ret[c(1:3,nrow(IBM.ret)),]
##            IBM.Adjusted IBM.tot.ret
## 2010-12-31     125.8031          NA
## 2011-01-03     126.4203 0.004905977
## 2011-01-04     126.5574 0.001084913
## 2013-12-31     169.4835 0.006222858

Step 3: Clean up the data

  • To output the data, show the total return coumn and limit the number of decimals on display using the digits=3 option
options(digits=3)
IBM.ret <- IBM.ret[,2]
IBM.ret[c(1:3,nrow(IBM.ret)),]
##            IBM.tot.ret
## 2010-12-31          NA
## 2011-01-03     0.00491
## 2011-01-04     0.00108
## 2013-12-31     0.00622
options(digits=7)

2.3: Logarithmic Total Returns

  • The returns using the Delt command are called arithmetic returns, or simple returns

  • Logartithmic returns are used a lot in various areas of finance

  • Calculate the logarithmic total return for IBM stock from January 2011 to December 2013

Step 1: Import Adjusted Closing Price Data

  • Because we are calculating logarithmic total returns, we need the adjusted closing price data as our base data source
IBM.log.ret <- data.IBM[,6]
IBM.log.ret[c(1:3,nrow(IBM.log.ret)),]
##            IBM.Adjusted
## 2010-12-31     125.8031
## 2011-01-03     126.4203
## 2011-01-04     126.5574
## 2013-12-31     169.4835

Step 2: Calculate Log Returns

  • Use a combination of the diff and log commands to calculate logarithmic returns
IBM.log.ret$IBM.log.ret <- diff(log(IBM.log.ret$IBM.Adjusted))
IBM.log.ret[c(1:3,nrow(IBM.log.ret)),]
##            IBM.Adjusted IBM.log.ret
## 2010-12-31     125.8031          NA
## 2011-01-03     126.4203 0.004893982
## 2011-01-04     126.5574 0.001084325
## 2013-12-31     169.4835 0.006203576

Step 3: Clean up the data

  • Clean up IBM.log.ret to delete the first coumn and keep only the logarithmic return series
options(digits=3)
IBM.log.ret <- IBM.log.ret[,2]
IBM.log.ret[c(1:3,nrow(IBM.log.ret)),]
##            IBM.log.ret
## 2010-12-31          NA
## 2011-01-03     0.00489
## 2011-01-04     0.00108
## 2013-12-31     0.00620
options(digits=7)

Compare Log Returns with Artihmetic Returns

  • Combine the two total return calculations using the cbind command

  • Use the na.rm=TRUE option so that R still calculates a max and a min even though there is an NA in the data

options(digits=3,scipen=100)
tot.rets <- cbind(IBM.ret,IBM.log.ret)
tot.rets[c(1:3,nrow(tot.rets)),]
##            IBM.tot.ret IBM.log.ret
## 2010-12-31          NA          NA
## 2011-01-03     0.00491     0.00489
## 2011-01-04     0.00108     0.00108
## 2013-12-31     0.00622     0.00620
max(abs(tot.rets$IBM.tot.ret-tot.rets$IBM.log.ret),na.rm=TRUE)
## [1] 0.00363
min(abs(tot.rets$IBM.tot.ret-tot.rets$IBM.log.ret),na.rm=TRUE)
## [1] 0.00000000118
options(digits=7,scipen=0)
  • We used scipen=100 to increase the threshold before R converts the output into scientific notation

  • Once done, revert the scipen option back to zero so that the output of subsequent analyses will revert back to the default display options

2.4: Cumulating Multi-day Returns

  • To fully capture the effects of being able to reinvest dividends, we should calculate daily returns and string them together for longer periods

  • The returns of that stock going forward determines whether the reinvested dividend earned a positive or negative return

  • To string together multiple days of arithmetic returns, we have to take the product of the daily gross returns

Step 1: Import Data and Calculate Arithmetic Returns

  • Call IBM.ret to see that we have the correct data still available in R memory
IBM.acum <- IBM.ret
IBM.acum[c(1:3,nrow(IBM.acum)),]
##            IBM.tot.ret
## 2010-12-31          NA
## 2011-01-03 0.004905977
## 2011-01-04 0.001084913
## 2013-12-31 0.006222858

Step 2: Set first day total return value to zero

  • Set the return equal to zero on the day we are aking the investment (December 31, 2010)
IBM.acum[1,1]<-0
IBM.acum[c(1:3,nrow(IBM.acum)),]
##            IBM.tot.ret
## 2010-12-31 0.000000000
## 2011-01-03 0.004905977
## 2011-01-04 0.001084913
## 2013-12-31 0.006222858

Step 3: Calculate gross daily returns

  • Create a new variable for the gross return, which is one plus the net total return
IBM.acum$GrossRet <- 1+IBM.acum$IBM.tot.ret
IBM.acum[c(1:3,nrow(IBM.acum)),]
##            IBM.tot.ret GrossRet
## 2010-12-31 0.000000000 1.000000
## 2011-01-03 0.004905977 1.004906
## 2011-01-04 0.001084913 1.001085
## 2013-12-31 0.006222858 1.006223

Step 4: Calculate Cumulative Gross Returns

  • Use the cumprod command to take the cumulative product of the gross return

  • cumprod takes the product of all the gross returns

IBM.acum$GrossCum <- cumprod(IBM.acum$GrossRet)
IBM.acum[c(1:3,nrow(IBM.acum)),]
##            IBM.tot.ret GrossRet GrossCum
## 2010-12-31 0.000000000 1.000000 1.000000
## 2011-01-03 0.004905977 1.004906 1.004906
## 2011-01-04 0.001084913 1.001085 1.005996
## 2013-12-31 0.006222858 1.006223 1.347213

Step 5: Convert Cumulative Gross Returns to Cumulative Net Returns

  • Subtract one from the GrossCum to calculate the net cumulative return or NetCum

  • NetCum is interpreted as the percentage return from the investment date

IBM.acum$NetCum <- IBM.acum$GrossCum-1
IBM.acum[c(1:3,nrow(IBM.acum)),]
##            IBM.tot.ret GrossRet GrossCum      NetCum
## 2010-12-31 0.000000000 1.000000 1.000000 0.000000000
## 2011-01-03 0.004905977 1.004906 1.004906 0.004905977
## 2011-01-04 0.001084913 1.001085 1.005996 0.005996213
## 2013-12-31 0.006222858 1.006223 1.347213 0.347212558

2.4.2: Cumulating Logarithmic Returns

  • An alternative way to calculate multi-period returns is to take the sum of the daily logarithmic returns

Step 1: Import data and calculate logarithmic returns

  • Call IBM.logret to see that we have the correct data still available in the R memory
IBM.logcum <- IBM.log.ret
IBM.logcum[c(1:3,nrow(IBM.logcum)),]
##            IBM.log.ret
## 2010-12-31          NA
## 2011-01-03 0.004893982
## 2011-01-04 0.001084325
## 2013-12-31 0.006203576

Step 2: Set the first log return to zero

IBM.logcum[1,1]<-0
IBM.logcum[c(1:3,nrow(IBM.logcum)),]
##            IBM.log.ret
## 2010-12-31 0.000000000
## 2011-01-03 0.004893982
## 2011-01-04 0.001084325
## 2013-12-31 0.006203576

Step 3: Take the sum of all logarithmic returns during the investment period

  • Using the Sum command, add up the values in IBM.log.ret
logcumret=sum(IBM.logcum$IBM.log.ret)
logcumret
## [1] 0.2980377

Step 4: Convert log return back to Arithmetic Return

  • We need to convert the cumulative logarithmic return to a cumulative arithmetic return. We do this by using the exp command (exponential logarithmic)
cumret=exp(logcumret)-1
cumret
## [1] 0.3472126
  • As we can see, it takes fewer steps to calculate multi-period returns using logarithmic returns than it is using arithmetic returns

2.4.3: Comparing price return and total return

Step 1: Import Data and Calculate Price and Total Returns

  • We have already combined the price and total returns data from tot.rets, so we only need to call in data

  • Rename the data to better identify the variables as prc.ret and tot.ret

IBM.Ret <- cbind(IBM.prc.ret,IBM.ret)
names(IBM.Ret) <- c("prc.ret","tot.ret")
IBM.Ret[c(1:3,nrow(IBM.Ret)),]
##                prc.ret     tot.ret
## 2010-12-31          NA          NA
## 2011-01-03 0.004905976 0.004905977
## 2011-01-04 0.001084913 0.001084913
## 2013-12-31 0.006222858 0.006222858

Step 2: Set First Returns to Zero

  • Set the Dec 31, 2011 price and total return to zero
IBM.Ret$prc.ret[1] <- 0
IBM.Ret$tot.ret[1] <- 0
IBM.Ret[c(1:3,nrow(IBM.Ret)),]
##                prc.ret     tot.ret
## 2010-12-31 0.000000000 0.000000000
## 2011-01-03 0.004905976 0.004905977
## 2011-01-04 0.001084913 0.001084913
## 2013-12-31 0.006222858 0.006222858

Step 3: Calculate Gross Returns

  • Calculate the gross price return gross.prc and gross total return gross.tot
IBM.Ret$gross.prc<-1+IBM.Ret$prc.ret
IBM.Ret$gross.tot<-1+IBM.Ret$tot.ret
IBM.Ret[c(1:3,nrow(IBM.Ret)),]
##                prc.ret     tot.ret gross.prc gross.tot
## 2010-12-31 0.000000000 0.000000000  1.000000  1.000000
## 2011-01-03 0.004905976 0.004905977  1.004906  1.004906
## 2011-01-04 0.001084913 0.001084913  1.001085  1.001085
## 2013-12-31 0.006222858 0.006222858  1.006223  1.006223

Step 4: Cumulate the Gross Returns

  • Calculate the cumulative price return cum.prc and cumulative total return cum.tot by using the cumprod command
IBM.Ret$cum.prc <- cumprod(IBM.Ret$gross.prc)
IBM.Ret$cum.tot <- cumprod(IBM.Ret$gross.tot)
IBM.Ret[c(1:3,nrow(IBM.Ret)),]
##                prc.ret     tot.ret gross.prc gross.tot  cum.prc  cum.tot
## 2010-12-31 0.000000000 0.000000000  1.000000  1.000000 1.000000 1.000000
## 2011-01-03 0.004905976 0.004905977  1.004906  1.004906 1.004906 1.004906
## 2011-01-04 0.001084913 0.001084913  1.001085  1.001085 1.005996 1.005996
## 2013-12-31 0.006222858 0.006222858  1.006223  1.006223 1.278073 1.347213

Step 5: Plot the Two Return Series

  • First plot the cum.tot variable, and then plot the cum.prc variable

  • Using the abline command, add a horizontal line at $1 so we can interpret whether the investment is making money or losing money

y.range <- range(IBM.Ret[,5:6])
y.range
## [1] 1.000000 1.526869
plot(IBM.Ret$cum.tot,
     type="l",
     auto.grid=FALSE,
     xlab="Date",
     ylab="Value of Investment ($)",
     ylim=y.range,
     minor.ticks=FALSE,
     main="IBM Stock Performance Based on
Total Returns and Price Returns
     December 31, 2010 - December 31, 2013")
lines(IBM.Ret$cum.prc,
      type="l",
      lty=3)
abline(h=1,col="black")
legend("topleft",
       col=c("black","black"),
       lty=c(1,3),
       c("Value Based on Total Return",
         "Value Based on Price Return"))

  • As the graph shows, the value of an investment based on IBM’s total return is equal to or greater than the value on an investment based on IBM’s price return