Return Calculations in R

ECON 424

Eric Zivot

Set Options and Load Packages

# set options and load packages
options(digits = 3)
options(width = 75)
Sys.setenv(TZ="UTC")
library(dygraphs)
library(IntroCompFinR)
## Loading required package: xts
## Loading required package: zoo
## 
## Attaching package: 'zoo'
## 
## The following objects are masked from 'package:base':
## 
##     as.Date, as.Date.numeric
library(PerformanceAnalytics)
## 
## Attaching package: 'PerformanceAnalytics'
## 
## The following object is masked from 'package:graphics':
## 
##     legend
library(xts)

Future Value Calculations

Calculate future value of $1000 after 1, 5 and 10 years assuming 3% return per year.

V = 1000
R = 0.03
FV1 = V*(1 + R)
FV5 = V*(1 + R)^5
FV10 = V*(1 + R)^10
FV1
## [1] 1030
FV5
## [1] 1159
FV10
## [1] 1344

Rule of 70

Calculate how long it takes to double your money at different interest rates.

# create sequence of interest rates
R = seq(0.01, 0.10, by=0.01)
R
##  [1] 0.01 0.02 0.03 0.04 0.05 0.06 0.07 0.08 0.09 0.10
# Commpute time it takes for investment to double in value: Exact calculation
n = log(2)/log(1 + R)
names(n) = R
n
##  0.01  0.02  0.03  0.04  0.05  0.06  0.07  0.08  0.09   0.1 
## 69.66 35.00 23.45 17.67 14.21 11.90 10.24  9.01  8.04  7.27
# Commpute time it takes for investment to double in value: rule of 70
n = 0.7/R
names(n) = R
n
##  0.01  0.02  0.03  0.04  0.05  0.06  0.07  0.08  0.09   0.1 
## 70.00 35.00 23.33 17.50 14.00 11.67 10.00  8.75  7.78  7.00

Multiple Compounding Periods

Calculate future value of $1000 after 1 year with different compounding periods.

V = 1000
R = 0.1
m = c(1, 2, 4, 356, 10000)
FV = V*(1 + R/m)^(m)
RA = FV/V - 1
names(FV) = names(RA) = m
print(FV, digits=4)
##     1     2     4   356 10000 
##  1100  1102  1104  1105  1105
print(RA, digits=4)
##      1      2      4    356  10000 
## 0.1000 0.1025 0.1038 0.1052 0.1052

Simple 1-Month Return on Microsoft Stock

Invest in Microsoft stock for 1 month and calculate simple return.

# prices
P0 = 90
Pm1 = 85
# 1-month net and gross return
R = (P0 - Pm1)/Pm1
R
## [1] 0.0588
1 + R
## [1] 1.06

Simple 2-Month Returns on Microsoft Stock

Invest in Microsoft stock for 2 months and calculate simple return.

# price 2 periods back
Pm2 = 80
# 2-month net and gross return
R.2 = (P0 - Pm2)/Pm2
R.2
## [1] 0.125
1 + R.2
## [1] 1.12

Vectorized Calculations

Calculate 1 period returns from a vector of prices.

# vector of prices
P = c(Pm2, Pm1, P0)
# calculate vector of 1-month returns from vector of prices
R = (P[2:3] - P[1:2])/P[1:2]
R 
## [1] 0.0625 0.0588
# calculate 2-month return from 2 1-month returns
(1 + R[1])*(1 + R[2]) - 1
## [1] 0.125
# same calculation vectorized using R function cumprod()
cumprod(1+R) - 1
## [1] 0.0625 0.1250

Portfolio Returns

Calculate 1 month return on portfolio with 10 shares of stock in Microsoft and 10 shares of stock in Starbucks.

# prices
P.msft = c(85, 90)
P.sbux = c(30, 28)
# initial wealth
V = P.msft[1]*10 + P.sbux[1]*10
V
## [1] 1150
# portfolio weights
x.msft = P.msft[1]/V
x.msft
## [1] 0.0739
x.sbux = P.sbux[1]/V
x.sbux
## [1] 0.0261
# asset returns
R.msft = (P.msft[2] - P.msft[1])/P.msft[1]
R.msft
## [1] 0.0588
R.sbux = (P.sbux[2] - P.sbux[1])/P.sbux[1]
R.sbux
## [1] -0.0667
# portfolio return
R.p = x.msft*R.msft + x.sbux*R.sbux
R.p
## [1] 0.00261

Example Data - SBUX Monthly Prices

# load daily data from IntroCompFinR - xts object
data(sbuxDailyPrices)
# pick off end-of-month prices using xts function to.monthly()
sbuxMonthlyPrices = to.monthly(sbuxDailyPrices, OHLC=FALSE)
class(sbuxMonthlyPrices)
## [1] "xts" "zoo"
str(sbuxMonthlyPrices)
## An 'xts' object on Jan 1993/Dec 2014 containing:
##   Data: num [1:264, 1] 1.12 1.05 1.1 1.12 1.39 1.42 1.38 1.41 1.59 1.55 ...
##  - attr(*, "dimnames")=List of 2
##   ..$ : NULL
##   ..$ : chr "SBUX"
##   Indexed by objects of class: [yearmon] TZ: UTC
##   xts Attributes:  
##  NULL

Example Data

head(sbuxMonthlyPrices, n=3)
##          SBUX
## Jan 1993 1.12
## Feb 1993 1.05
## Mar 1993 1.10
tail(sbuxMonthlyPrices, n=3)
##          SBUX
## Oct 2014 75.0
## Nov 2014 80.9
## Dec 2014 81.8
colnames(sbuxMonthlyPrices)
## [1] "SBUX"

Extract Data and Time Index

# coredata() extracts data
head(coredata(sbuxMonthlyPrices), n=3)
##      SBUX
## [1,] 1.12
## [2,] 1.05
## [3,] 1.10
# index() extracts time index
head(index(sbuxMonthlyPrices), n=3)
## [1] "Jan 1993" "Feb 1993" "Mar 1993"

Plot Monthly Closing Prices

plot.zoo(sbuxMonthlyPrices, main="Monthly Prices on SBUX",
         lwd = 2, col="blue", ylab="Price")

Compute Monthly Simple Returns

sbuxRet = diff(sbuxMonthlyPrices)/lag(sbuxMonthlyPrices)
head(sbuxRet, n=3)
##             SBUX
## Jan 1993      NA
## Feb 1993 -0.0625
## Mar 1993  0.0476
# remove first NA observation
sbuxRet = sbuxRet[-1]
head(sbuxRet, n=3)
##             SBUX
## Feb 1993 -0.0625
## Mar 1993  0.0476
## Apr 1993  0.0182

Calculate Monthly CC Returns

# compute from simple returns
sbuxRetC = log(1 + sbuxRet)
head(sbuxRetC, n=3)
##             SBUX
## Feb 1993 -0.0645
## Mar 1993  0.0465
## Apr 1993  0.0180
# compute directly from prices
sbuxRetC = diff(log(sbuxMonthlyPrices))
sbuxRetC = sbuxRetC[-1]
head(sbuxRetC, n=3)
##             SBUX
## Feb 1993 -0.0645
## Mar 1993  0.0465
## Apr 1993  0.0180

PerformanceAnalytics Package

# Simple returns using Return.calculate()
sbuxRet = Return.calculate(sbuxMonthlyPrices)
head(sbuxRet, n=3)
##             SBUX
## Jan 1993      NA
## Feb 1993 -0.0625
## Mar 1993  0.0476
# CC returns using Return.calculate()
sbuxRetC = Return.calculate(sbuxMonthlyPrices, method="log")
head(sbuxRetC, n=3)
##             SBUX
## Jan 1993      NA
## Feb 1993 -0.0645
## Mar 1993  0.0465

Plot Simple Returns

# use default line style
plot.zoo(sbuxRet, main="SBUX Simple Monthly Return", 
         lwd=2, col="blue", ylab="Return")
abline(h=0)

Plot Simple Returns

# use type="h" instead of default type="l"
plot.zoo(sbuxRet, main="SBUX Simple Monthly Return", 
         type="h", lwd=2, col="blue", ylab="Return")
abline(h=0)

Compare Simple and CC Returns

# plot simple and cc returns on same graph
dataToPlot = merge(sbuxRet, sbuxRetC)
colnames(dataToPlot) = c("Simple", "CC")
plot.zoo(dataToPlot, main="Simple vs CC Returns", plot.type="single", 
         ylab="Returns", lwd=2, col=c("black", "red"))
abline(h=0)
legend("bottomleft", legend=colnames(dataToPlot),
       lty="solid", lwd=2, col=c("black", "red"))

Compare Simple and CC Returns

# plot simple and cc returns in different panels
my.panel <- function(...) {
  lines(...)
  abline(h=0)
}
plot.zoo(dataToPlot, main="Simple vs CC Returns", plot.type="multiple", 
         panel=my.panel, lwd=2, col=c("black", "red"))

Dynamic (Interactive) Plots using dygraphs

Use the R package dygraphs to create dynamic time series graphs that can be viewed in a web browser. See https://rstudio.github.io/dygraphs/.

# basic time series plot - use the mouse to move about the plot
dygraph(sbuxMonthlyPrices) 

Dynamic (Interactive) Plots using dygraphs

# basic time series plot with range slider underneath
dygraph(sbuxMonthlyPrices) %>% dyRangeSelector()