Disclaimer: The content of this RMarkdown note came from a course called Analyzing Financial Data and Implementing Financial Models Using R.

Chapter 2: Individual Security Returns

how to calculate total return

Key Issues

2.1 Price Returns

Calculate the daily price returns for IBM stock form 2011 to 2013. Use IBM stock as the example b/c IBM pays dividends so we can compare the results for price returns and total returns.

# To clean up the memory of your current R session run the following line
rm(list=ls(all=TRUE))

# Step 1: Import IBM Data from Yahoo Finance
library(quantmod)
library(xts)
data.IBM <- read.csv("data/IBM Yahoo.csv")
head(data.IBM)
##         Date   Open   High    Low  Close  Volume Adj.Close
## 1 2013-12-31 186.49 187.79 186.30 187.57 3619700  169.4835
## 2 2013-12-30 185.32 186.70 184.67 186.41 3018600  168.4353
## 3 2013-12-27 185.84 186.50 184.56 185.08 3381600  167.2336
## 4 2013-12-26 183.56 185.56 183.51 185.35 3325700  167.4775
## 5 2013-12-24 181.96 183.50 181.91 183.22 1613600  165.5529
## 6 2013-12-23 181.05 182.93 180.61 182.23 4079900  164.6584
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$date)
names(data.IBM) <- 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
# Adj price doesn't match the textbook
# This is due to div payments and stock splits after this book was published
# Refer to the discussion regarding this topic in total returns (p. 58)

# Step 2: Subset the Data to Only Include the 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: Clearn up Data Object
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)

A Note on Stock Splits and the Use of Closing Prices from Yahoo Finance (p. 57)

  • Closing prices do not reflect stock splits
  • so when we see large returns when using close prices, investigation is warranted

2.2 Total Returns

Calculate IBM’s total returns from January 2011 to December 2013.

Total return is the sum of

  • price return
  • reinvestment of intermediate cash flows (such as dividends for stocks and coupons for bonds)

Adj closing price (Yahoo Finance) incorporates:

  • not only adjustments for dividend payments
  • but also adjustments for stock splits

The adjustments are made retroactively

  • such that closing price and adj. closing price are the same after the div pay or stock split
  • for example, both prices are the same on Nov 6th (ex-date) after (p. 59)

Three dividend dates in understanding total returns

  1. dividend declare date
  2. dividend payable date
  3. ex-dividend date or ex-date (i.e., Nov 6th) means that those who purchased IBM stock on Nov 6th or after would not be entitled to the div
# Step 1: Import Adjusted Closing Price Data
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
IBM.ret$tot.ret <- Delt(IBM.ret$IBM.Adjusted)
IBM.ret[c(1:3, nrow(IBM.ret)), ]
##            IBM.Adjusted     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
options(digits = 3)
IBM.ret <- IBM.ret[, 2]         #typo on page 61: it reads IBM.log.ret when it's IBM.ret
IBM.ret[c(1:3, nrow(IBM.ret)), ]
##            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 LogarithmicTotal Returns

simple return versus logarithmic returns Logarithmic returns makes it easier to calculate cumulative returns.

Calculate the logarithmic total returns for IBM stock from January 2011 to December 2013.

# Step 1: Import Adjusted Closing Price Data
IBM.log.ret <- data.IBM[, 6]
IBM.log.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 Log Returns
IBM.log.ret$IBM.log.ret <- diff(log(IBM.log.ret$IBM.Adjusted))
IBM.log.ret[c(1:3, nrow(IBM.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
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 Arithmetic Returns
options(digits =3, scipen = 100) #scipen to change threshold before R converts to scientific no
tot.rets <- cbind(IBM.ret, IBM.log.ret)
tot.rets[c(1:3, nrow(tot.rets)), ]
##            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(IBM.ret$tot.ret - IBM.log.ret$IBM.log.ret), na.rm = TRUE)
## [1] 0.00363
min(abs(IBM.ret$tot.ret - IBM.log.ret$IBM.log.ret), na.rm = TRUE)
## [1] 0.00000000118
options(digits =7, scipen = 0)

Differences on each are fairly small

2.4 Cumulating Multi-Day Returns

How much would an investment in Amazon have made through the end of 2013 if we puchased AMZN shares at the closing price on December 31, 2010? Assume that we reinvested dividends.

2.4.1 Cumulating Arithmetic Returns

# Step 1: Import Data and Calculate Arithmetic Returns
IBM.acum <- IBM.ret                #from Section 2.2
IBM.acum[c(1:3, nrow(IBM.acum)), ]
##                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
IBM.acum[1,1] <- 0
IBM.acum[c(1:3, nrow(IBM.acum)), ]
##                tot.ret
## 2010-12-31 0.000000000
## 2011-01-03 0.004905977
## 2011-01-04 0.001084913
## 2013-12-31 0.006222858

# Step 3: Calcualte Gross Daily Returns
IBM.acum$GrossRet <- IBM.acum$tot.ret + 1
IBM.acum[c(1:3, nrow(IBM.acum)), ]
##                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 Cummulative Gross Returns
IBM.acum$GrossCum <- cumprod(IBM.acum$GrossRet)
IBM.acum[c(1:3, nrow(IBM.acum)), ]
##                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 Cummulative Gross Returns to Cumulative Net Returns
IBM.acum$NetCum <- IBM.acum$GrossCum - 1
IBM.acum[c(1:3, nrow(IBM.acum)), ]
##                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

Interpretation

  • The net cummulative return value of 0.35 means that an investment made in IBM stock at the end of 2010 would have returned 35% by the end of 2013.

2.4.2 Cumulating Logarithmic Returns

An alternative way is to take the sum of the daily logarithmic returns.

# Step 1: Import Data and Calculate Logarithmic Returns
IBM.logcum <- IBM.log.ret             #from Section 2.3
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$IBM.log.ret[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
logcumret <- sum(IBM.logcum$IBM.log.ret)
logcumret
## [1] 0.2980377

# Step 4: Convert  Log Return Back to Arithmetic Return
cumret <- exp(logcumret) - 1
cumret
## [1] 0.3472126

Interpretation

  • The net cummulative return value of 0.35 means that an investment made in IBM stock at the end of 2010 would have returned 35% by the end of 2013.

Cumulating arithmetic returns versus logarithmic returns

  • Cumulating arithmetic returns to show daily cumulative values
  • Cumulating logarithmic returns to calculate multi-period returns b/c it is easier to calculate

2.4.3 Comparing Price Return and Total Return

Show that total return yields higher returns than price returns for a stock that pays div.

# Step 1: Import Data and Calculate Price and Total Returns
IBM.Ret <- cbind(IBM.prc.ret, IBM.ret)     #from Section 2.1 & 2.2
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
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
IBM.Ret$gross.prc <- IBM.Ret$prc.ret + 1
IBM.Ret$gross.tot <- IBM.Ret$tot.ret + 1
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
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
y.range <- range(IBM.Ret[, 5:6])
y.range
## [1] 1.000000 1.526869
title1 <- "IBM Stock Performance Based on.exit"
title2 <- "Total Return and Price Returns"
title3 <- "December 31, 2010 - December 31, 2013"
plot(IBM.Ret$cum.tot,
     type = "l",
     auto.grid = FALSE,
     xlab = "Date",
     ylab = "Value of Investment ($)",
     ylim = y.range,
     minor.ticks = FALSE,
     main = paste(title1, "\n", title2, "\n", title3))
lines(IBM.Ret$cum.prc, type = "l", lty = 3)
legend("topleft",
       col = c("black", "black"),
       c("Value Based on Total Return", "Value Based on Price Return"),
       lty = c(1, 3))

Interpretation

  • The gap b/t the black line and gray line increases over time as IBM pays quarterly dividends

2.5 Weely Returns

# To clean up the memory of your current R session run the following line
rm(list=ls(all=TRUE))

# Step 1: Import IBM Data from Yahoo Finance
library(quantmod)
library(xts)

data.AMZN <- read.csv("data/AMZN Yahoo.csv", header = TRUE)
date <- as.Date(data.AMZN$Date, format = "%Y-%m-%d")
data.AMZN <- cbind(date, data.AMZN[, -1])
data.AMZN <- data.AMZN[order(data.AMZN$date), ]
data.AMZN <- xts(data.AMZN[, 2:7], order.by = data.AMZN[, 1])
names(data.AMZN) <- paste(c("AMZN.Open", "AMZN.High", "AMZN.Low", 
                            "AMZN.Close", "AMZN.Volume", "AMZN.Adjusted"))

data.AMZN[c(1:3, nrow(data.AMZN)), ]
##            AMZN.Open AMZN.High AMZN.Low AMZN.Close AMZN.Volume
## 2010-12-31    181.96    182.30   179.51     180.00     3451900
## 2011-01-03    181.37    186.00   181.21     184.22     5331400
## 2011-01-04    186.15    187.70   183.78     185.01     5031800
## 2013-12-31    394.58    398.83   393.80     398.79     1996500
##            AMZN.Adjusted
## 2010-12-31        180.00
## 2011-01-03        184.22
## 2011-01-04        185.01
## 2013-12-31        398.79

# Step 1: Import Data into R
wk <- data.AMZN
wk[c(1:3, nrow(wk)), ]
##            AMZN.Open AMZN.High AMZN.Low AMZN.Close AMZN.Volume
## 2010-12-31    181.96    182.30   179.51     180.00     3451900
## 2011-01-03    181.37    186.00   181.21     184.22     5331400
## 2011-01-04    186.15    187.70   183.78     185.01     5031800
## 2013-12-31    394.58    398.83   393.80     398.79     1996500
##            AMZN.Adjusted
## 2010-12-31        180.00
## 2011-01-03        184.22
## 2011-01-04        185.01
## 2013-12-31        398.79

# Step 2: Convert to Daily Data to Weekly Data
AMZN.weekly <- to.weekly(wk)
AMZN.weekly[c(1:3, nrow(AMZN.weekly)), ]
##            wk.Open wk.High wk.Low wk.Close wk.Volume wk.Adjusted
## 2010-12-31  181.96  182.30 179.51   180.00   3451900      180.00
## 2011-01-07  181.37  188.45 181.21   185.49  22183400      185.49
## 2011-01-14  185.04  188.94 182.51   188.75  15899000      188.75
## 2013-12-31  399.41  399.92 392.45   398.79   4483600      398.79

# Step 3: Clean up Weekly Data to Keep Only the Adj Closing Prices at the End of Each Week
AMZN.weekly <- AMZN.weekly[, 6]
AMZN.weekly[c(1:3, nrow(AMZN.weekly)), ]
##            wk.Adjusted
## 2010-12-31      180.00
## 2011-01-07      185.49
## 2011-01-14      188.75
## 2013-12-31      398.79

# Step 4: Calculate Weekly Returns
# Delt: calculates the % change from Friday of a week to Friday of the following week 
AMZN.weekly$Ret <- Delt(AMZN.weekly$wk.Adjusted)
AMZN.weekly[c(1:3, nrow(AMZN.weekly)), ]
##            wk.Adjusted         Ret
## 2010-12-31      180.00          NA
## 2011-01-07      185.49 0.030500028
## 2011-01-14      188.75 0.017575044
## 2013-12-31      398.79 0.001783616

# Step 5: Clean up Weekly Returns Data by Deleting the First Observation
AMZN.weekly <- AMZN.weekly[-1, 2]
AMZN.weekly[c(1:3, nrow(AMZN.weekly)), ]
##                     Ret
## 2011-01-07  0.030500028
## 2011-01-14  0.017575044
## 2011-01-21 -0.060026501
## 2013-12-31  0.001783616

Verify Weekly Return Calculations (p. 71)

  • Cross check with GrossCum of daily returns
  • Ret(1/14/2011) = GrossCum(1/14/2011) / GrossCum(1/7/2011) - 1

2.6 Monthly Returns

# Step 1: Import Data into R
mo <- data.AMZN
mo[c(1:3, nrow(mo)), ]
##            AMZN.Open AMZN.High AMZN.Low AMZN.Close AMZN.Volume
## 2010-12-31    181.96    182.30   179.51     180.00     3451900
## 2011-01-03    181.37    186.00   181.21     184.22     5331400
## 2011-01-04    186.15    187.70   183.78     185.01     5031800
## 2013-12-31    394.58    398.83   393.80     398.79     1996500
##            AMZN.Adjusted
## 2010-12-31        180.00
## 2011-01-03        184.22
## 2011-01-04        185.01
## 2013-12-31        398.79

# Step 2: Convert to Daily Data to monthly Data
AMZN.monthly <- to.monthly(mo)
AMZN.monthly[c(1:3, nrow(AMZN.monthly)), ]
##          mo.Open mo.High mo.Low mo.Close mo.Volume mo.Adjusted
## Dec 2010  181.96  182.30 179.51   180.00   3451900      180.00
## Jan 2011  181.37  191.60 166.90   169.64 113611300      169.64
## Feb 2011  170.52  191.40 169.51   173.29  95776400      173.29
## Dec 2013  399.00  405.63 379.50   398.79  55686700      398.79

# Step 3: Clean up monthly Data to Keep Only the Adj Closing Prices at the End of Each Week
AMZN.monthly <- AMZN.monthly[, 6]
AMZN.monthly[c(1:3, nrow(AMZN.monthly)), ]
##          mo.Adjusted
## Dec 2010      180.00
## Jan 2011      169.64
## Feb 2011      173.29
## Dec 2013      398.79

# Step 4: Calculate monthly Returns
# Delt: calculates the % change from Friday of a week to Friday of the following week 
AMZN.monthly$Ret <- Delt(AMZN.monthly$mo.Adjusted)
AMZN.monthly[c(1:3, nrow(AMZN.monthly)), ]
##          mo.Adjusted         Ret
## Dec 2010      180.00          NA
## Jan 2011      169.64 -0.05755556
## Feb 2011      173.29  0.02151612
## Dec 2013      398.79  0.01313453

# Step 5: Clean up monthly Returns Data by Deleting the First Observation
AMZN.monthly <- AMZN.monthly[-1, 2]
AMZN.monthly[c(1:3, nrow(AMZN.monthly)), ]
##                  Ret
## Jan 2011 -0.05755556
## Feb 2011  0.02151612
## Mar 2011  0.03947148
## Dec 2013  0.01313453

2.7 Comparing Performance of Multiple Securities: Total Returns

AABA replaced YHOO in the textbook. The shares of what used to be known as Yahoo under the ticker symbol YHOO started trading Monday as Altaba (think alternative Alibaba) and trade under the symbol AABA.Jun 19, 2017.

# See what objects are in the R memory
ls()
## [1] "AMZN.monthly" "AMZN.weekly"  "data.AMZN"    "date"        
## [5] "mo"           "wk"

# Delete all these objects
rm(list = ls())
ls()
## character(0)

# Compare total returns of multiple securities - AMZN, IBM, AABA, ^GSPC
# Which of these investments performed better from 12/31/2010 to 12/31/2013
# Pay dividends: IBM
# Don't pay: AMZN, AABA, ^GSPC

#Step 1: Importing Price Data
library(quantmod)
data.AMZN <- getSymbols("AMZN", from = "2010-12-31", to = "2014-01-01", auto.assign = FALSE)
data.AABA<- getSymbols("AABA", from = "2010-12-31", to = "2014-01-01", auto.assign = FALSE)
data.IBM <- getSymbols("IBM", from = "2010-12-31", to = "2014-01-01", auto.assign = FALSE)
data.GSPC <- getSymbols("^GSPC", from = "2010-12-31", to = "2014-01-01", auto.assign = FALSE)
#to = "2013-12-31" in the book was replaced by to = "2014-01-01"
#B/c that code doesn't produce the output that includes stock price of 2013-12-31the date. 

# Step 2: Combine Data
multi <- data.AMZN[, 6] # Need to create a new data object before cbinding
multi <- merge(multi, data.GSPC[, 6])
multi <- merge(multi, data.AABA[, 6])
multi <- merge(multi, data.IBM[, 6])
#multi <- cbind(multi, data.GSPC[, 6], data.AABA[, 6], data.IBM[, 6])
multi[c(1:3, nrow(multi)), ]
##            AMZN.Adjusted GSPC.Adjusted AABA.Adjusted IBM.Adjusted
## 2010-12-31        180.00       1257.64         16.63     123.2834
## 2011-01-03        184.22       1271.87         16.75     123.8883
## 2011-01-04        185.01       1270.20         16.59     124.0227
## 2013-12-31        398.79       1848.36         40.44     166.0890

# Step 3: Convert Data into a data.frame
multi.df <- cbind(index(multi), 
                  data.frame(multi))
names(multi.df) <- c("date", "AMZN", "GSPC", "AABA", "IBM")
multi.df[c(1:3, nrow(multi.df)), ]
##                  date   AMZN    GSPC  AABA      IBM
## 2010-12-31 2010-12-31 180.00 1257.64 16.63 123.2834
## 2011-01-03 2011-01-03 184.22 1271.87 16.75 123.8883
## 2011-01-04 2011-01-04 185.01 1270.20 16.59 124.0227
## 2013-12-31 2013-12-31 398.79 1848.36 40.44 166.0890

# Step 4: Calculate Normalized Values for Each Security
multi.df$AMZN.idx <- multi.df$AMZN / multi.df$AMZN[1]
multi.df$GSPC.idx <- multi.df$GSPC / multi.df$GSPC[1]
multi.df$AABA.idx <- multi.df$AABA/ multi.df$AABA[1]
multi.df$IBM.idx <- multi.df$IBM / multi.df$IBM[1]
multi.df[c(1:3, nrow(multi.df)), 6:9]
##            AMZN.idx GSPC.idx  AABA.idx  IBM.idx
## 2010-12-31 1.000000 1.000000 1.0000000 1.000000
## 2011-01-03 1.023444 1.011315 1.0072159 1.004906
## 2011-01-04 1.027833 1.009987 0.9975948 1.005996
## 2013-12-31 2.215500 1.469705 2.4317499 1.347213

# Step 5: Plot the Capital Appreciation of Each Security

# GSPC first
y.range = range(multi.df[, 6:9])
y.range
## [1] 0.6668671 2.4564041

plot(x = multi.df$date,
     y = multi.df$GSPC.idx,
     type = "l",
     xlab = "Date",
     ylab = "Value of Investment ($)",
     ylim = y.range,
     col = "black",
     lty = 1,
     lwd = 2,
     main = "Value of $1 Investment in AMZN, IBM, AABA, 
        And the S&P 500 Index Based on Total Returns
        December 31, 2010 - December 31, 2013")


# Add a line for AMZN, AABA, IBM

lines(x = multi.df$date,
      y = multi.df$AMZN.idx,
      col = "black",
      lty = 2,
      lwd = 1)
lines(x = multi.df$date,
      y = multi.df$IBM.idx,
      col = "gray40",
      lty = 1,
      lwd = 2)
lines(x = multi.df$date,
      y = multi.df$AABA.idx,
      col = "gray60",
      lty = 1,
      lwd = 1)
abline(h = 1, lty = 1, col = "black")
legend("topleft",
       c("S&P 500 Index", "AMZN", "IBM", "AABA"),
       col = c("black", "black", "gray40", "gray60"),
       lty = c(1, 2, 1, 1),
       lwd = c(2, 1, 2, 1))