Chapter 3: Portfolio Returns

Key Issues

portfolio returns = returns of basket of securities benchmark portfolio = hypothetical portfolio that we can compare the performance of our portf

3.1 Constructing Portfolio Returns (Long Way)

Portfolio return is the weighted average of the returns of the individual securities in the portfolio. Suppose we invested $50K in AMZN, $10 in GSPC, $30 in YHOO, and $10 in IBM How much would this portfolio return b/t December 31, 2010 and December 31, 2013?

Step 0: Import Price Data

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

library(quantmod)
library(xts)

#Importing Price Data
data.AMZN <- getSymbols("AMZN", from = "2010-12-31", to = "2013-12-31", auto.assign = FALSE)
data.YHOO <- getSymbols("YHOO", from = "2010-12-31", to = "2013-12-31", auto.assign = FALSE)
data.IBM <- getSymbols("IBM", from = "2010-12-31", to = "2013-12-31", auto.assign = FALSE)
data.GSPC <- getSymbols("^GSPC", from = "2010-12-31", to = "2013-12-31", auto.assign = FALSE)


multi <- data.AMZN[, 6] # Need to create a new data object before cbinding
multi <- cbind(multi, data.GSPC[, 6], data.YHOO[, 6], data.IBM[, 6])

Step 1: Find First and Last Adjusted Closing Price for Each Security Over the Investmet Period

period.ret <- multi[c(1, nrow(multi)), ]
period.ret
##            AMZN.Adjusted GSPC.Adjusted YHOO.Adjusted IBM.Adjusted
## 2010-12-31        180.00       1257.64         16.63     124.5860
## 2013-12-31        398.79       1848.36         40.44     167.8438

Step 2: Calculate Returns for Each Security Over the Investment Period

rets <- lapply(period.ret, Delt) # lapply returns output in a list
rets
## $AMZN.Adjusted
##            Delt.1.arithmetic
## 2010-12-31                NA
## 2013-12-31            1.2155
## 
## $GSPC.Adjusted
##            Delt.1.arithmetic
## 2010-12-31                NA
## 2013-12-31         0.4697051
## 
## $YHOO.Adjusted
##            Delt.1.arithmetic
## 2010-12-31                NA
## 2013-12-31           1.43175
## 
## $IBM.Adjusted
##            Delt.1.arithmetic
## 2010-12-31                NA
## 2013-12-31         0.3472125
#rets <- mapply(Delt, data.frame(period.ret)) #mapply does the same but returns output in DF

Step 3: Convert to a data.frame and Clean up Data

rets <- data.frame(rets)
rets
##            Delt.1.arithmetic Delt.1.arithmetic.1 Delt.1.arithmetic.2
## 2010-12-31                NA                  NA                  NA
## 2013-12-31            1.2155           0.4697051             1.43175
##            Delt.1.arithmetic.3
## 2010-12-31                  NA
## 2013-12-31           0.3472125
rets <- rets[2, ] * 100
names(rets) <- paste(c("AMZN", "GSPC", "YHOO", "IBM"))
rets
##              AMZN     GSPC    YHOO      IBM
## 2013-12-31 121.55 46.97051 143.175 34.72125

Step 4: Calculate Weight of Each Security in the Portfolio

i.AMZN <- 50000
i.GSPC <- 10000
i.YHOO <- 30000
i.IBM <- 10000

w.AMZN <- i.AMZN / (i.AMZN + i.GSPC + i.YHOO + i.IBM)
w.GSPC <- i.GSPC / (i.AMZN + i.GSPC + i.YHOO + i.IBM)
w.YHOO <- i.YHOO / (i.AMZN + i.GSPC + i.YHOO + i.IBM)
w.IBM <- i.IBM / (i.AMZN + i.GSPC + i.YHOO + i.IBM)
w.AMZN
## [1] 0.5
w.GSPC
## [1] 0.1
w.YHOO
## [1] 0.3
w.IBM
## [1] 0.1

Step 5: Calculate Portfolio Return

port.ret.4asset <- w.AMZN * rets$AMZN + w.GSPC * rets$GSPC + w.YHOO * rets$YHOO + w.IBM * rets$IBM
port.ret.4asset 
## [1] 111.8967

Interpretation

  • 112 means the portfolio return over the period is 112%.

3.2 Constructing Portfolio Returns (Matrix Algebra)

The long way described above becomes too cumbersome as the number of securities in P grows.

# Creat a matrix (1 by 4) of weights
wgt <- c(0.5, 0.1, 0.3, 0.1)
mat.wgt <- matrix(wgt, 1) #1 in the 2nd arg means # of rows

# Create a matrix of (4, by 1) of returns of individual stocks
ret <- c(rets$AMZN, rets$GSPC, rets$YHOO, rets$IBM)
mat.ret <- matrix(ret, 4)
mat.ret
##           [,1]
## [1,] 121.55001
## [2,]  46.97051
## [3,] 143.17499
## [4,]  34.72125

# Calculate the portfolio return using matrix multiplication
port.ret <- mat.wgt %*% mat.ret
port.ret
##          [,1]
## [1,] 111.8967

3.3 Constructing Benchmark Portfolio Returns

Construct an equal-weighted (EW) and value-weighted (VW) portfolio, consisting of AMZN, YHOO, and IBM.

In this section, prepare an object, port, which will be used later to build EW and VW portfolio.

Step 1: Importing the Price Data

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
data.YHOO[c(1:3, nrow(data.YHOO)), ]
##            YHOO.Open YHOO.High YHOO.Low YHOO.Close YHOO.Volume
## 2010-12-31     16.74     16.76    16.47      16.63     7754500
## 2011-01-03     16.81     16.94    16.67      16.75    17684000
## 2011-01-04     16.71     16.83    16.57      16.59    11092800
## 2013-12-31     40.17     40.50    40.00      40.44     8291400
##            YHOO.Adjusted
## 2010-12-31         16.63
## 2011-01-03         16.75
## 2011-01-04         16.59
## 2013-12-31         40.44
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     124.5860
## 2011-01-03   147.21   148.20  147.14    147.48    4603800     125.1972
## 2011-01-04   147.56   148.22  146.64    147.64    5060100     125.3331
## 2013-12-31   186.49   187.79  186.30    187.57    3619700     167.8438

Step 2: Create Object with Only the Relevant Data

port <- data.AMZN[, c(4, 6)]
port <- merge(port, data.YHOO[, c(4, 6)])
port <- merge(port, data.IBM[, c(4, 6)])
#port <- cbind(port, data.YHOO[, c(4, 6)], data.IBM[, c(4, 6)])
port[c(1:3, nrow(port)), ]
##            AMZN.Close AMZN.Adjusted YHOO.Close YHOO.Adjusted IBM.Close
## 2010-12-31     180.00        180.00      16.63         16.63    146.76
## 2011-01-03     184.22        184.22      16.75         16.75    147.48
## 2011-01-04     185.01        185.01      16.59         16.59    147.64
## 2013-12-31     398.79        398.79      40.44         40.44    187.57
##            IBM.Adjusted
## 2010-12-31     124.5860
## 2011-01-03     125.1972
## 2011-01-04     125.3331
## 2013-12-31     167.8438

Step 3: Calculate Returns of Each Security

port$AMZN.ret <- Delt(port$AMZN.Adjusted)
port$YHOO.ret <- Delt(port$YHOO.Adjusted)
port$IBM.ret <- Delt(port$IBM.Adjusted)
port[c(1:3, nrow(port)), ]
##            AMZN.Close AMZN.Adjusted YHOO.Close YHOO.Adjusted IBM.Close
## 2010-12-31     180.00        180.00      16.63         16.63    146.76
## 2011-01-03     184.22        184.22      16.75         16.75    147.48
## 2011-01-04     185.01        185.01      16.59         16.59    147.64
## 2013-12-31     398.79        398.79      40.44         40.44    187.57
##            IBM.Adjusted    AMZN.ret     YHOO.ret     IBM.ret
## 2010-12-31     124.5860          NA           NA          NA
## 2011-01-03     125.1972 0.023444450  0.007215935 0.004905984
## 2011-01-04     125.3331 0.004288318 -0.009552239 0.001084912
## 2013-12-31     167.8438 0.013778412  0.005970099 0.006222864

Step 4: Convert to data.frame Object and Subset Data

port <- cbind(index(port), data.frame(port))
names(port)[1] <- "date"
port[c(1:3, nrow(port)), ]
##                  date AMZN.Close AMZN.Adjusted YHOO.Close YHOO.Adjusted
## 2010-12-31 2010-12-31     180.00        180.00      16.63         16.63
## 2011-01-03 2011-01-03     184.22        184.22      16.75         16.75
## 2011-01-04 2011-01-04     185.01        185.01      16.59         16.59
## 2013-12-31 2013-12-31     398.79        398.79      40.44         40.44
##            IBM.Close IBM.Adjusted    AMZN.ret     YHOO.ret     IBM.ret
## 2010-12-31    146.76     124.5860          NA           NA          NA
## 2011-01-03    147.48     125.1972 0.023444450  0.007215935 0.004905984
## 2011-01-04    147.64     125.3331 0.004288318 -0.009552239 0.001084912
## 2013-12-31    187.57     167.8438 0.013778412  0.005970099 0.006222864

port <- subset(port,
               port$date >= "2012-12-31" &
               port$date <= "2013-12-31")
port[c(1:3, nrow(port)), ]
##                  date AMZN.Close AMZN.Adjusted YHOO.Close YHOO.Adjusted
## 2012-12-31 2012-12-31     250.87        250.87      19.90         19.90
## 2013-01-02 2013-01-02     257.31        257.31      20.08         20.08
## 2013-01-03 2013-01-03     258.48        258.48      19.78         19.78
## 2013-12-31 2013-12-31     398.79        398.79      40.44         40.44
##            IBM.Close IBM.Adjusted    AMZN.ret     YHOO.ret      IBM.ret
## 2012-12-31    191.55     168.1425 0.023207448  0.020512821  0.009060750
## 2013-01-02    196.35     172.3559 0.025670679  0.009045226  0.025058747
## 2013-01-03    195.27     171.4079 0.004547095 -0.014940189 -0.005500391
## 2013-12-31    187.57     167.8438 0.013778412  0.005970099  0.006222864

3.3.1 Equal-Weighted Portfolio

considerd as an approach to capture the small capitalization stock premeum (the belief that small cap stock yield higher returns over larger cap stocks) An example is the S&P 500 Equal Weight Index

Step 1: Keep Only Variables We Need to Construct EW Portfolio

ewport <- port[, c(1, 8:10)]
ewport[c(1:3, nrow(ewport)), ]
##                  date    AMZN.ret     YHOO.ret      IBM.ret
## 2012-12-31 2012-12-31 0.023207448  0.020512821  0.009060750
## 2013-01-02 2013-01-02 0.025670679  0.009045226  0.025058747
## 2013-01-03 2013-01-03 0.004547095 -0.014940189 -0.005500391
## 2013-12-31 2013-12-31 0.013778412  0.005970099  0.006222864

names(ewport)[2:4] <- c("AMZN", "YHOO", "IBM")
rownames(ewport) <- seq(1, nrow(ewport), 1)
ewport[c(1:3, nrow(ewport)), ]
##           date        AMZN         YHOO          IBM
## 1   2012-12-31 0.023207448  0.020512821  0.009060750
## 2   2013-01-02 0.025670679  0.009045226  0.025058747
## 3   2013-01-03 0.004547095 -0.014940189 -0.005500391
## 253 2013-12-31 0.013778412  0.005970099  0.006222864

Step 2: Convert Net Returns to Gross Returns

ewport[2:4] <- ewport[2:4] + 1
ewport[c(1:3, nrow(ewport)), ]
##           date     AMZN      YHOO       IBM
## 1   2012-12-31 1.023207 1.0205128 1.0090608
## 2   2013-01-02 1.025671 1.0090452 1.0250587
## 3   2013-01-03 1.004547 0.9850598 0.9944996
## 253 2013-12-31 1.013778 1.0059701 1.0062229

Step 3: Calculate EW Portfolio Values for 1Q 2013

# Subset ewport by data from December 31, 2012 to March 31, 2013
ewq1 <- subset(ewport,
               ewport$date >= "2012-12-31" &
               ewport$date <= "2013-03-31")
ewq1[c(1:3, nrow(ewq1)), ]
##          date     AMZN      YHOO       IBM
## 1  2012-12-31 1.023207 1.0205128 1.0090608
## 2  2013-01-02 1.025671 1.0090452 1.0250587
## 3  2013-01-03 1.004547 0.9850598 0.9944996
## 61 2013-03-28 1.004485 0.9974566 1.0114278

# Calculate the cumulative gross returns fro each security for Q1
ewq1[1, 2:4] <- 1
ewq1[2:4] <- cumprod(ewq1[2:4])
ewq1[c(1:3, nrow(ewq1)), ]
##          date     AMZN      YHOO      IBM
## 1  2012-12-31 1.000000 1.0000000 1.000000
## 2  2013-01-02 1.025671 1.0090452 1.025059
## 3  2013-01-03 1.030335 0.9939699 1.019421
## 61 2013-03-28 1.062263 1.1824121 1.118234

# Calculate the index value for each security for Q1
num.sec <- 3
ewq1$AMZN.ind <- ewq1$AMZN / num.sec
ewq1$YHOO.ind <- ewq1$YHOO / num.sec
ewq1$IBM.ind <- ewq1$IBM / num.sec
ewq1[c(1:3, nrow(ewq1)), ]
##          date     AMZN      YHOO      IBM  AMZN.ind  YHOO.ind   IBM.ind
## 1  2012-12-31 1.000000 1.0000000 1.000000 0.3333333 0.3333333 0.3333333
## 2  2013-01-02 1.025671 1.0090452 1.025059 0.3418902 0.3363484 0.3416862
## 3  2013-01-03 1.030335 0.9939699 1.019421 0.3434448 0.3313233 0.3398068
## 61 2013-03-28 1.062263 1.1824121 1.118234 0.3540878 0.3941374 0.3727448

# Calculate the agrregate portfolio value on each day
q1.val <- data.frame(rowSums(ewq1[, 5:7]))
q1.val[c(1:3, nrow(q1.val)), ]
## [1] 1.000000 1.019925 1.014575 1.120970
names(q1.val) <- paste("port.val")
q1.val$date <- ewq1$date
q1.val[c(1:3, nrow(q1.val)), ]
##    port.val       date
## 1  1.000000 2012-12-31
## 2  1.019925 2013-01-02
## 3  1.014575 2013-01-03
## 61 1.120970 2013-03-28

# Pass the aggregate portfolio value at the end of Q1 to Q2
q2.inv <- q1.val[nrow(q1.val), 1]
q2.inv
## [1] 1.12097

Step 4: Calculate EW Portfolio Values for 2Q 2013

# Subset ewport by data from April 1, 2013 to June 30, 2013
ewq2 <- subset(ewport,
               ewport$date >= "2013-04-01" &
               ewport$date <= "2013-06-30")
ewq2[c(1:3, nrow(ewq2)), ]
##           date      AMZN      YHOO       IBM
## 62  2013-04-01 0.9816878 0.9987250 0.9956868
## 63  2013-04-02 1.0065365 1.0119149 1.0093229
## 64  2013-04-03 0.9837080 0.9831791 0.9920694
## 125 2013-06-28 1.0005045 0.9866510 0.9767953

# Calculate the cumulative gross returns fro each security for Q2
#ewq2[1, 2:4] <- 1 This is the difference from Q1
ewq2[2:4] <- cumprod(ewq2[2:4])
ewq2[c(1:3, nrow(ewq2)), ]
##           date      AMZN      YHOO       IBM
## 62  2013-04-01 0.9816878 0.9987250 0.9956868
## 63  2013-04-02 0.9881047 1.0106247 1.0049695
## 64  2013-04-03 0.9720065 0.9936251 0.9969995
## 125 2013-06-28 1.0420279 1.0679982 0.9001677

# Calculate the index value for each security for Q2
ewq2$AMZN.ind <- (q2.inv / num.sec) * ewq2$AMZN #a difference from Q1
ewq2$YHOO.ind <- (q2.inv / num.sec) * ewq2$YHOO 
ewq2$IBM.ind <- (q2.inv / num.sec) * ewq2$IBM 
ewq2[c(1:3, nrow(ewq2)), ]
##           date      AMZN      YHOO       IBM  AMZN.ind  YHOO.ind   IBM.ind
## 62  2013-04-01 0.9816878 0.9987250 0.9956868 0.3668142 0.3731802 0.3720450
## 63  2013-04-02 0.9881047 1.0106247 1.0049695 0.3692119 0.3776267 0.3755135
## 64  2013-04-03 0.9720065 0.9936251 0.9969995 0.3631967 0.3712746 0.3725355
## 125 2013-06-28 1.0420279 1.0679982 0.9001677 0.3893607 0.3990646 0.3363536

# Calculate the agrregate portfolio value on each day
q2.val <- data.frame(rowSums(ewq2[, 5:7]))
q2.val[c(1:3, nrow(q2.val)), ]
## [1] 1.112039 1.122352 1.107007 1.124779
names(q2.val) <- paste("port.val")
q2.val$date <- ewq2$date
q2.val[c(1:3, nrow(q2.val)), ]
##     port.val       date
## 62  1.112039 2013-04-01
## 63  1.122352 2013-04-02
## 64  1.107007 2013-04-03
## 125 1.124779 2013-06-28

# Pass the aggregate portfolio value at the end of Q2 to Q3
q3.inv <- q2.val[nrow(q2.val), 1]
q3.inv 
## [1] 1.124779
#$1.121 at the end of Q1 and 1.125
#Means the portfolio grown from $1.121 at the end of Q1 to $1.125 at the end of Q2
#Note that it doesn't mean that the portfolio grew 12.5% during Q2 but 12.5% during Q1-Q2
#b/c this is a cumulative measure 

Step 5: Calculate EW Portfolio Values for 3Q 2013

# Subset ewport by data from July 1, 2013 to September 30, 2013
ewq3 <- subset(ewport,
               ewport$date >= "2013-07-01" &
                 ewport$date <= "2013-09-30")
ewq3[c(1:3, nrow(ewq3)), ]
##           date      AMZN      YHOO       IBM
## 126 2013-07-01 1.0158810 1.0043773 1.0008895
## 127 2013-07-02 1.0057781 0.9900951 1.0011502
## 128 2013-07-03 1.0010573 1.0240096 1.0091384
## 189 2013-09-30 0.9893358 0.9886736 0.9906912

# Calculate the cumulative gross returns fro each security for Q3
#ewq3[1, 2:4] <- 1 This is the difference from Q1
ewq3[2:4] <- cumprod(ewq3[2:4])
ewq3[c(1:3, nrow(ewq3)), ]
##           date     AMZN     YHOO       IBM
## 126 2013-07-01 1.015881 1.004377 1.0008895
## 127 2013-07-02 1.021751 0.994429 1.0020407
## 128 2013-07-03 1.022831 1.018305 1.0111977
## 189 2013-09-30 1.125860 1.319936 0.9738146

# Calculate the index value for each security for Q3
ewq3$AMZN.ind <- (q3.inv / num.sec) * ewq3$AMZN #a difference from Q1
ewq3$YHOO.ind <- (q3.inv / num.sec) * ewq3$YHOO 
ewq3$IBM.ind <- (q3.inv / num.sec) * ewq3$IBM 
ewq3[c(1:3, nrow(ewq3)), ]
##           date     AMZN     YHOO       IBM  AMZN.ind  YHOO.ind   IBM.ind
## 126 2013-07-01 1.015881 1.004377 1.0008895 0.3808805 0.3765675 0.3752598
## 127 2013-07-02 1.021751 0.994429 1.0020407 0.3830813 0.3728376 0.3756914
## 128 2013-07-03 1.022831 1.018305 1.0111977 0.3834863 0.3817893 0.3791246
## 189 2013-09-30 1.125860 1.319936 0.9738146 0.4221145 0.4948788 0.3651087

# Calculate the agrregate portfolio value on each day
q3.val <- data.frame(rowSums(ewq3[, 5:7]))
q3.val[c(1:3, nrow(q3.val)), ]
## [1] 1.132708 1.131610 1.144400 1.282102
names(q3.val) <- paste("port.val")
q3.val$date <- ewq3$date
q3.val[c(1:3, nrow(q3.val)), ]
##     port.val       date
## 126 1.132708 2013-07-01
## 127 1.131610 2013-07-02
## 128 1.144400 2013-07-03
## 189 1.282102 2013-09-30

# Pass the aggregate portfolio value at the end of Q3 to Q4
q4.inv <- q3.val[nrow(q3.val), 1]
q4.inv
## [1] 1.282102

Step 6: Calculate EW Portfolio Values for 4Q 2013

# Subset ewport by data from October 1, 2013 to December 31, 2013
ewq4 <- subset(ewport,
               ewport$date >= "2013-10-01" &
                 ewport$date <= "2013-12-31")
ewq4[c(1:3, nrow(ewq4)), ]
##           date      AMZN      YHOO       IBM
## 190 2013-10-01 1.0265801 1.0343685 1.0064802
## 191 2013-10-02 0.9986291 0.9950451 0.9923812
## 192 2013-10-03 0.9820598 0.9923844 0.9940527
## 253 2013-12-31 1.0137784 1.0059701 1.0062229

# Calculate the cumulative gross returns fro each security for q4
#ewq4[1, 2:4] <- 1 This is the difference from Q1
ewq4[2:4] <- cumprod(ewq4[2:4])
ewq4[c(1:3, nrow(ewq4)), ]
##           date     AMZN     YHOO       IBM
## 190 2013-10-01 1.026580 1.034368 1.0064802
## 191 2013-10-02 1.025173 1.029243 0.9988120
## 192 2013-10-03 1.006781 1.021405 0.9928718
## 253 2013-12-31 1.275557 1.219174 1.0183460

# Calculate the index value for each security for q4
ewq4$AMZN.ind <- (q4.inv / num.sec) * ewq4$AMZN #a difference from Q1
ewq4$YHOO.ind <- (q4.inv / num.sec) * ewq4$YHOO 
ewq4$IBM.ind <- (q4.inv / num.sec) * ewq4$IBM 
ewq4[c(1:3, nrow(ewq4)), ]
##           date     AMZN     YHOO       IBM  AMZN.ind  YHOO.ind   IBM.ind
## 190 2013-10-01 1.026580 1.034368 1.0064802 0.4387268 0.4420553 0.4301368
## 191 2013-10-02 1.025173 1.029243 0.9988120 0.4381253 0.4398650 0.4268596
## 192 2013-10-03 1.006781 1.021405 0.9928718 0.4302653 0.4365151 0.4243210
## 253 2013-12-31 1.275557 1.219174 1.0183460 0.5451312 0.5210352 0.4352078

# Calculate the agrregate portfolio value on each day
q4.val <- data.frame(rowSums(ewq4[, 5:7]))
q4.val[c(1:3, nrow(q4.val)), ]
## [1] 1.310919 1.304850 1.291101 1.501374
names(q4.val) <- paste("port.val")
q4.val$date <- ewq4$date
q4.val[c(1:3, nrow(q4.val)), ]
##     port.val       date
## 190 1.310919 2013-10-01
## 191 1.304850 2013-10-02
## 192 1.291101 2013-10-03
## 253 1.501374 2013-12-31

Step 7: Combine Quarterly EW Portfolio Values into One Data Object

ew.portval <- rbind(q1.val, q2.val, q3.val, q4.val)
ew.portval[c(1:3, nrow(ew.portval)), ]
##     port.val       date
## 1   1.000000 2012-12-31
## 2   1.019925 2013-01-02
## 3   1.014575 2013-01-03
## 253 1.501374 2013-12-31

3.3.2 Value-Weighted Portfolio

It’s considerd as an approach to track the changes in the size of the sector. Larger firms are given more weight in VW, whereas equal weights are given in EW portfolio. An example is the S&P 500 Index. It rebalances only at the beginning of each quarter.

Step 1: Keep Only Variables We Need to Construct EW Portfolio

vwport <- port[, c(1, 2, 4, 6, 8:10)] #port is from 3.3 Constructing Benchmark Portfolio Returns
vwport[c(1:3, nrow(vwport)), ]
##                  date AMZN.Close YHOO.Close IBM.Close    AMZN.ret
## 2012-12-31 2012-12-31     250.87      19.90    191.55 0.023207448
## 2013-01-02 2013-01-02     257.31      20.08    196.35 0.025670679
## 2013-01-03 2013-01-03     258.48      19.78    195.27 0.004547095
## 2013-12-31 2013-12-31     398.79      40.44    187.57 0.013778412
##                YHOO.ret      IBM.ret
## 2012-12-31  0.020512821  0.009060750
## 2013-01-02  0.009045226  0.025058747
## 2013-01-03 -0.014940189 -0.005500391
## 2013-12-31  0.005970099  0.006222864
rownames(vwport) <- seq(1:nrow(vwport))
vwport[c(1:3, nrow(vwport)), ]
##           date AMZN.Close YHOO.Close IBM.Close    AMZN.ret     YHOO.ret
## 1   2012-12-31     250.87      19.90    191.55 0.023207448  0.020512821
## 2   2013-01-02     257.31      20.08    196.35 0.025670679  0.009045226
## 3   2013-01-03     258.48      19.78    195.27 0.004547095 -0.014940189
## 253 2013-12-31     398.79      40.44    187.57 0.013778412  0.005970099
##          IBM.ret
## 1    0.009060750
## 2    0.025058747
## 3   -0.005500391
## 253  0.006222864

Step 2: Convert Net Returns to Gross Returns

vwport$AMZN.ret <- vwport$AMZN.ret + 1
vwport$YHOO.ret <- vwport$YHOO.ret + 1
vwport$IBM.ret <- vwport$IBM.ret + 1
vwport[c(1:3, nrow(vwport)), ]
##           date AMZN.Close YHOO.Close IBM.Close AMZN.ret  YHOO.ret
## 1   2012-12-31     250.87      19.90    191.55 1.023207 1.0205128
## 2   2013-01-02     257.31      20.08    196.35 1.025671 1.0090452
## 3   2013-01-03     258.48      19.78    195.27 1.004547 0.9850598
## 253 2013-12-31     398.79      40.44    187.57 1.013778 1.0059701
##       IBM.ret
## 1   1.0090608
## 2   1.0250587
## 3   0.9944996
## 253 1.0062229

Step 3: Calculate the Market Capitalization of Each Security in the Portfolio

# Construct Series of Calendar Days
date <- seq(as.Date("2012-12-31"), as.Date("2013-12-31"), by = 1)
date <- data.frame(date)
date[c(1:3, nrow(date)), ]
## [1] "2012-12-31" "2013-01-01" "2013-01-02" "2013-12-31"

# Create Data Object with Daily Prices
PRICE.qtr <- vwport[, 1:4]
PRICE.qtr[c(1:3, nrow(PRICE.qtr)), ]
##           date AMZN.Close YHOO.Close IBM.Close
## 1   2012-12-31     250.87      19.90    191.55
## 2   2013-01-02     257.31      20.08    196.35
## 3   2013-01-03     258.48      19.78    195.27
## 253 2013-12-31     398.79      40.44    187.57

# Filling in Last Available Price on Non-trading Days
PRICE.qtr <- na.locf(merge(x = date, y = PRICE.qtr, by = "date", all.x = TRUE))
#all.x=T tells R to keep all the data in the "by" varialble that is available in x=date
#na.locf tells R to copy over the last available data in y 
#when there is a date in x that is not available in y
PRICE.qtr[c(1:3, nrow(PRICE.qtr)), ]
##           date AMZN.Close YHOO.Close IBM.Close
## 1   2012-12-31     250.87      19.90    191.55
## 2   2013-01-01     250.87      19.90    191.55
## 3   2013-01-02     257.31      20.08    196.35
## 366 2013-12-31     398.79      40.44    187.57

# Keep Only Prices at the End of Each Calendar Quarter
PRICE.qtr <- subset(PRICE.qtr,
                    PRICE.qtr$date == as.Date("2012-12-31") |
                    PRICE.qtr$date == as.Date("2013-03-31") |
                    PRICE.qtr$date == as.Date("2013-06-30") |
                    PRICE.qtr$date == as.Date("2013-09-30"))
PRICE.qtr
##           date AMZN.Close YHOO.Close IBM.Close
## 1   2012-12-31     250.87      19.90    191.55
## 91  2013-03-31     266.49      23.53    213.30
## 182 2013-06-30     277.69      25.13    191.11
## 274 2013-09-30     312.64      33.17    185.18

# Obtain Share Outstanding Data from SEC Filings
#http://www.sec.gov/edgar/searchedgar/companysearch.html
#Interactive Data / Financial Statements / Condensed Consolidated Balance Sheets
PRICE.qtr$AMZN.shout <- c(454000000, 455000000, 457000000, 458000000)
PRICE.qtr$YHOO.shout <- c(1115233000, 1084766000, 1065046000, 1013059000)
PRICE.qtr$IBM.shout <- c(1117367676, 1108794396, 1095425823, 1085854383)
PRICE.qtr
##           date AMZN.Close YHOO.Close IBM.Close AMZN.shout YHOO.shout
## 1   2012-12-31     250.87      19.90    191.55   4.54e+08 1115233000
## 91  2013-03-31     266.49      23.53    213.30   4.55e+08 1084766000
## 182 2013-06-30     277.69      25.13    191.11   4.57e+08 1065046000
## 274 2013-09-30     312.64      33.17    185.18   4.58e+08 1013059000
##      IBM.shout
## 1   1117367676
## 91  1108794396
## 182 1095425823
## 274 1085854383

# Calculate Market Capitalization of Each Security
str(PRICE.qtr)
## 'data.frame':    4 obs. of  7 variables:
##  $ date      : chr  "2012-12-31" "2013-03-31" "2013-06-30" "2013-09-30"
##  $ AMZN.Close: chr  "250.87" "266.49" "277.69" "312.64"
##  $ YHOO.Close: chr  "19.90" "23.53" "25.13" "33.17"
##  $ IBM.Close : chr  "191.55" "213.30" "191.11" "185.18"
##  $ AMZN.shout: num  4.54e+08 4.55e+08 4.57e+08 4.58e+08
##  $ YHOO.shout: num  1.12e+09 1.08e+09 1.07e+09 1.01e+09
##  $ IBM.shout : num  1.12e+09 1.11e+09 1.10e+09 1.09e+09
PRICE.qtr$date <- as.Date(PRICE.qtr$date)
PRICE.qtr$AMZN.Close <- as.numeric(PRICE.qtr$AMZN.Close)
PRICE.qtr$YHOO.Close <- as.numeric(PRICE.qtr$YHOO.Close)
PRICE.qtr$IBM.Close <- as.numeric(PRICE.qtr$IBM.Close)
str(PRICE.qtr)
## 'data.frame':    4 obs. of  7 variables:
##  $ date      : Date, format: "2012-12-31" "2013-03-31" ...
##  $ AMZN.Close: num  251 266 278 313
##  $ YHOO.Close: num  19.9 23.5 25.1 33.2
##  $ IBM.Close : num  192 213 191 185
##  $ AMZN.shout: num  4.54e+08 4.55e+08 4.57e+08 4.58e+08
##  $ YHOO.shout: num  1.12e+09 1.08e+09 1.07e+09 1.01e+09
##  $ IBM.shout : num  1.12e+09 1.11e+09 1.10e+09 1.09e+09

weights <- PRICE.qtr
weights$AMZN.mcap <- weights$AMZN.Close * weights$AMZN.shout
weights$YHOO.mcap <- weights$YHOO.Close * weights$YHOO.shout
weights$IBM.mcap <- weights$IBM.Close * weights$IBM.shout
weights
##           date AMZN.Close YHOO.Close IBM.Close AMZN.shout YHOO.shout
## 1   2012-12-31     250.87      19.90    191.55   4.54e+08 1115233000
## 91  2013-03-31     266.49      23.53    213.30   4.55e+08 1084766000
## 182 2013-06-30     277.69      25.13    191.11   4.57e+08 1065046000
## 274 2013-09-30     312.64      33.17    185.18   4.58e+08 1013059000
##      IBM.shout    AMZN.mcap   YHOO.mcap     IBM.mcap
## 1   1117367676 113894980000 22193136700 214031778338
## 91  1108794396 121252950000 25524543980 236505844667
## 182 1095425823 126904330000 26764605980 209346829034
## 274 1085854383 143189120000 33603167030 201078514644

# Calculate Quarter-end Aggregate Market Capitalization
weights$tot.mcap <- rowSums(weights[, 8:10])
weights
##           date AMZN.Close YHOO.Close IBM.Close AMZN.shout YHOO.shout
## 1   2012-12-31     250.87      19.90    191.55   4.54e+08 1115233000
## 91  2013-03-31     266.49      23.53    213.30   4.55e+08 1084766000
## 182 2013-06-30     277.69      25.13    191.11   4.57e+08 1065046000
## 274 2013-09-30     312.64      33.17    185.18   4.58e+08 1013059000
##      IBM.shout    AMZN.mcap   YHOO.mcap     IBM.mcap     tot.mcap
## 1   1117367676 113894980000 22193136700 214031778338 350119895038
## 91  1108794396 121252950000 25524543980 236505844667 383283338647
## 182 1095425823 126904330000 26764605980 209346829034 363015765014
## 274 1085854383 143189120000 33603167030 201078514644 377870801674

Step 4: Calculate Quarter-end Weights of Each Security in the Portfolio

weights$AMZN.wgt <- weights$AMZN.mcap / weights$tot.mcap
weights$YHOO.wgt <- weights$YHOO.mcap / weights$tot.mcap
weights$IBM.wgt <- weights$IBM.mcap / weights$tot.mcap
weights
##           date AMZN.Close YHOO.Close IBM.Close AMZN.shout YHOO.shout
## 1   2012-12-31     250.87      19.90    191.55   4.54e+08 1115233000
## 91  2013-03-31     266.49      23.53    213.30   4.55e+08 1084766000
## 182 2013-06-30     277.69      25.13    191.11   4.57e+08 1065046000
## 274 2013-09-30     312.64      33.17    185.18   4.58e+08 1013059000
##      IBM.shout    AMZN.mcap   YHOO.mcap     IBM.mcap     tot.mcap
## 1   1117367676 113894980000 22193136700 214031778338 350119895038
## 91  1108794396 121252950000 25524543980 236505844667 383283338647
## 182 1095425823 126904330000 26764605980 209346829034 363015765014
## 274 1085854383 143189120000 33603167030 201078514644 377870801674
##      AMZN.wgt   YHOO.wgt   IBM.wgt
## 1   0.3253028 0.06338725 0.6113100
## 91  0.3163533 0.06659445 0.6170522
## 182 0.3495835 0.07372849 0.5766880
## 274 0.3789367 0.08892766 0.5321356

weights <- weights[, c(1, 12:14)]
weights
##           date  AMZN.wgt   YHOO.wgt   IBM.wgt
## 1   2012-12-31 0.3253028 0.06338725 0.6113100
## 91  2013-03-31 0.3163533 0.06659445 0.6170522
## 182 2013-06-30 0.3495835 0.07372849 0.5766880
## 274 2013-09-30 0.3789367 0.08892766 0.5321356

weights$date <- weights$date + 1 #since the weights are applicable at the start of the next Q
weights
##           date  AMZN.wgt   YHOO.wgt   IBM.wgt
## 1   2013-01-01 0.3253028 0.06338725 0.6113100
## 91  2013-04-01 0.3163533 0.06659445 0.6170522
## 182 2013-07-01 0.3495835 0.07372849 0.5766880
## 274 2013-10-01 0.3789367 0.08892766 0.5321356

Step 5: Calculate the Quarterly VW Portfolio Values

q1.vw.wgt <- subset(weights, date == "2013-01-01") #I'm not sure why author took the long way
q2.vw.wgt <- subset(weights, date == "2013-04-01")
q3.vw.wgt <- subset(weights, date == "2013-07-01")
q4.vw.wgt <- subset(weights, date == "2013-10-01")
q1.vw.wgt
##         date  AMZN.wgt   YHOO.wgt IBM.wgt
## 1 2013-01-01 0.3253028 0.06338725 0.61131
q2.vw.wgt
##          date  AMZN.wgt   YHOO.wgt   IBM.wgt
## 91 2013-04-01 0.3163533 0.06659445 0.6170522
q3.vw.wgt
##           date  AMZN.wgt   YHOO.wgt  IBM.wgt
## 182 2013-07-01 0.3495835 0.07372849 0.576688
q4.vw.wgt
##           date  AMZN.wgt   YHOO.wgt   IBM.wgt
## 274 2013-10-01 0.3789367 0.08892766 0.5321356

Step 6: Create Pie Charts of the Weights

par(mfrow = c(2, 2))

Q1.pie.values <- as.numeric(q1.vw.wgt[, -1])
Q1.pie.labels <- names(q1.vw.wgt[, -1])
pie(Q1.pie.values,
    labels = Q1.pie.labels,
    col = c("black", "gray", "gray40"),
    main = "Q1 Value Weighting")

Q2.pie.values <- as.numeric(q2.vw.wgt[, -1])
Q2.pie.labels <- names(q1.vw.wgt[, -1])
pie(Q2.pie.values,
    labels = Q2.pie.labels,
    col = c("black", "gray", "gray40"),
    main = "Q2 Value Weighting")

Q3.pie.values <- as.numeric(q3.vw.wgt[, -1])
Q3.pie.labels <- c("Amazon", "Yahoo", "IBM")
pct <- round(Q3.pie.values * 100)
Q3.pie.labels <- paste(Q3.pie.labels, pct) #Add Pct to Labels
Q3.pie.labels <- paste(Q3.pie.labels, "%", sep = "") #Add % Sign
pie(Q3.pie.values,
    labels = Q3.pie.labels,
    col = c("black", "gray", "gray40"),
    main = "Q3 Value Weighting")

Q4.pie.values <- as.numeric(q4.vw.wgt[, -1])
Q4.pie.labels <- c("Amazon", "Yahoo", "IBM")
pct <- round(Q4.pie.values * 100)
Q4.pie.labels <- paste(Q4.pie.labels, pct) #Add Pct to Labels
Q4.pie.labels <- paste(Q4.pie.labels, "%", sep = "") #Add % Sign
pie(Q4.pie.values,
    labels = Q4.pie.labels,
    col = rainbow(length(Q4.pie.labels)), #to plot colored pie charts
    main = "Q4 Value Weighting")

Step 7: Calculate VW Portfolio Values for 1Q 2013

vw.q1 <- subset(vwport,
                vwport$date >= as.Date("2012-12-31") &
                vwport$date <= as.Date("2013-03-31"))
vw.q1[c(1:3, nrow(vw.q1)), ]
##          date AMZN.Close YHOO.Close IBM.Close AMZN.ret  YHOO.ret   IBM.ret
## 1  2012-12-31     250.87      19.90    191.55 1.023207 1.0205128 1.0090608
## 2  2013-01-02     257.31      20.08    196.35 1.025671 1.0090452 1.0250587
## 3  2013-01-03     258.48      19.78    195.27 1.004547 0.9850598 0.9944996
## 61 2013-03-28     266.49      23.53    213.30 1.004485 0.9974566 1.0114278

vw.q1 <- vw.q1[, c(1, 5:7)]
vw.q1[c(1:3, nrow(vw.q1)), ]
##          date AMZN.ret  YHOO.ret   IBM.ret
## 1  2012-12-31 1.023207 1.0205128 1.0090608
## 2  2013-01-02 1.025671 1.0090452 1.0250587
## 3  2013-01-03 1.004547 0.9850598 0.9944996
## 61 2013-03-28 1.004485 0.9974566 1.0114278

names(vw.q1)[2:4] <- paste(c("AMZN", "YHOO", "IBM"))
vw.q1[c(1:3, nrow(vw.q1)), ]
##          date     AMZN      YHOO       IBM
## 1  2012-12-31 1.023207 1.0205128 1.0090608
## 2  2013-01-02 1.025671 1.0090452 1.0250587
## 3  2013-01-03 1.004547 0.9850598 0.9944996
## 61 2013-03-28 1.004485 0.9974566 1.0114278

vw.q1[1, 2:4] <- 1
vw.q1$AMZN <- cumprod(vw.q1$AMZN) 
vw.q1$YHOO <- cumprod(vw.q1$YHOO)
vw.q1$IBM <- cumprod(vw.q1$IBM)
vw.q1[c(1:3, nrow(vw.q1)), ]
##          date     AMZN      YHOO      IBM
## 1  2012-12-31 1.000000 1.0000000 1.000000
## 2  2013-01-02 1.025671 1.0090452 1.025059
## 3  2013-01-03 1.030335 0.9939699 1.019421
## 61 2013-03-28 1.062263 1.1824121 1.118234

vw.q1$AMZN.idx <- vw.q1$AMZN * q1.vw.wgt$AMZN.wgt #Apply the Q-end weights; note 
# that q1.vw.wgt$AMZN.wgt is a scalar
vw.q1$YHOO.idx <- vw.q1$YHOO * q1.vw.wgt$YHOO.wgt
vw.q1$IBM.idx <- vw.q1$IBM * q1.vw.wgt$IBM.wgt
vw.q1[c(1:3, nrow(vw.q1)), ]
##          date     AMZN      YHOO      IBM  AMZN.idx   YHOO.idx   IBM.idx
## 1  2012-12-31 1.000000 1.0000000 1.000000 0.3253028 0.06338725 0.6113100
## 2  2013-01-02 1.025671 1.0090452 1.025059 0.3336535 0.06396060 0.6266286
## 3  2013-01-03 1.030335 0.9939699 1.019421 0.3351707 0.06300502 0.6231819
## 61 2013-03-28 1.062263 1.1824121 1.118234 0.3455572 0.07494985 0.6835878
#idx = daily gross returns * quarterly weight
#weight is based on market capitalization
#So larger firms would have a greater influence on portfolio returns

q1.vw.val <- data.frame(rowSums(vw.q1[, 5:7])) #Calculate the daily portfolio values
q1.vw.val[c(1:3, nrow(q1.vw.val)), ]
## [1] 1.000000 1.024243 1.021358 1.104095
names(q1.vw.val) <- paste("port.val")
q1.vw.val$date <- vw.q1$date
q1.vw.val[c(1:3, nrow(q1.vw.val)), ]
##    port.val       date
## 1  1.000000 2012-12-31
## 2  1.024243 2013-01-02
## 3  1.021358 2013-01-03
## 61 1.104095 2013-03-28

q2.vw.inv <- q1.vw.val[nrow(q1.vw.val), 1]
q2.vw.inv
## [1] 1.104095

Step 8: Calculate VW Portfolio Values for 2Q 2013

vw.q2 <- subset(vwport,
                vwport$date >= "2013-04-01" &
                vwport$date <= "2013-06-30")
vw.q2[c(1:3, nrow(vw.q2)), ]
##           date AMZN.Close YHOO.Close IBM.Close  AMZN.ret  YHOO.ret
## 62  2013-04-01     261.61      23.50    212.38 0.9816878 0.9987250
## 63  2013-04-02     263.32      23.78    214.36 1.0065365 1.0119149
## 64  2013-04-03     259.03      23.38    212.66 0.9837080 0.9831791
## 125 2013-06-28     277.69      25.13    191.11 1.0005045 0.9866510
##       IBM.ret
## 62  0.9956868
## 63  1.0093229
## 64  0.9920694
## 125 0.9767953

vw.q2 <- vw.q2[, c(1, 5:7)]
vw.q2[c(1:3, nrow(vw.q2)), ]
##           date  AMZN.ret  YHOO.ret   IBM.ret
## 62  2013-04-01 0.9816878 0.9987250 0.9956868
## 63  2013-04-02 1.0065365 1.0119149 1.0093229
## 64  2013-04-03 0.9837080 0.9831791 0.9920694
## 125 2013-06-28 1.0005045 0.9866510 0.9767953

names(vw.q2)[2:4] <- paste(c("AMZN", "YHOO", "IBM"))
vw.q2[c(1:3, nrow(vw.q2)), ]
##           date      AMZN      YHOO       IBM
## 62  2013-04-01 0.9816878 0.9987250 0.9956868
## 63  2013-04-02 1.0065365 1.0119149 1.0093229
## 64  2013-04-03 0.9837080 0.9831791 0.9920694
## 125 2013-06-28 1.0005045 0.9866510 0.9767953

#vw.q2[1, 2:4] <- 1 #difference from Q1
vw.q2$AMZN <- cumprod(vw.q2$AMZN)
vw.q2$YHOO <- cumprod(vw.q2$YHOO)
vw.q2$IBM <- cumprod(vw.q2$IBM)
vw.q2[c(1:3, nrow(vw.q2)), ]
##           date      AMZN      YHOO       IBM
## 62  2013-04-01 0.9816878 0.9987250 0.9956868
## 63  2013-04-02 0.9881047 1.0106247 1.0049695
## 64  2013-04-03 0.9720065 0.9936251 0.9969995
## 125 2013-06-28 1.0420279 1.0679982 0.9001677

vw.q2$AMZN.ind <- (q2.vw.inv * q2.vw.wgt$AMZN.wgt) * vw.q2$AMZN #Apply weight
vw.q2$YHOO.ind <- (q2.vw.inv * q2.vw.wgt$YHOO.wgt) * vw.q2$YHOO
vw.q2$IBM.ind <- (q2.vw.inv * q2.vw.wgt$IBM.wgt) * vw.q2$IBM
vw.q2[c(1:3, nrow(vw.q2)), ]
##           date      AMZN      YHOO       IBM  AMZN.ind   YHOO.ind
## 62  2013-04-01 0.9816878 0.9987250 0.9956868 0.3428879 0.07343285
## 63  2013-04-02 0.9881047 1.0106247 1.0049695 0.3451292 0.07430780
## 64  2013-04-03 0.9720065 0.9936251 0.9969995 0.3395064 0.07305787
## 125 2013-06-28 1.0420279 1.0679982 0.9001677 0.3639637 0.07852627
##       IBM.ind
## 62  0.6783458
## 63  0.6846699
## 64  0.6792401
## 125 0.6132701

q2.vw.val <- data.frame(rowSums(vw.q2[, 5:7]))
q2.vw.val[c(1:3, nrow(q2.vw.val)), ]
## [1] 1.094667 1.104107 1.091804 1.055760

names(q2.vw.val) <- paste("port.val")
q2.vw.val[c(1:3, nrow(q2.vw.val)), ]
## [1] 1.094667 1.104107 1.091804 1.055760

q2.vw.val$date <- vw.q2$date
q2.vw.val[c(1:3, nrow(q2.vw.val)), ]
##     port.val       date
## 62  1.094667 2013-04-01
## 63  1.104107 2013-04-02
## 64  1.091804 2013-04-03
## 125 1.055760 2013-06-28

q3.vw.inv <- q2.vw.val[nrow(q2.vw.val), 1]
q3.vw.inv
## [1] 1.05576
#$1.104 at the end of Q1 and $1.056 by the end of Q2
#it doesn't mean that the portfolio grew 5.6% during Q2 but 5.6% during Q1-Q2
#b/c it's a cumulative measure

Step 9: Calculate VW Portfolio Values for 3Q 2013

vw.q3 <- subset(vwport,
                vwport$date >= "2013-07-01" &
                vwport$date <= "2013-09-30")
vw.q3[c(1:3, nrow(vw.q3)), ]
##           date AMZN.Close YHOO.Close IBM.Close  AMZN.ret  YHOO.ret
## 126 2013-07-01     282.10      25.24    191.28 1.0158810 1.0043773
## 127 2013-07-02     283.73      24.99    191.50 1.0057781 0.9900951
## 128 2013-07-03     284.03      25.59    193.25 1.0010573 1.0240096
## 189 2013-09-30     312.64      33.17    185.18 0.9893358 0.9886736
##       IBM.ret
## 126 1.0008895
## 127 1.0011502
## 128 1.0091384
## 189 0.9906912

vw.q3 <- vw.q3[, c(1, 5:7)]
vw.q3[c(1:3, nrow(vw.q3)), ]
##           date  AMZN.ret  YHOO.ret   IBM.ret
## 126 2013-07-01 1.0158810 1.0043773 1.0008895
## 127 2013-07-02 1.0057781 0.9900951 1.0011502
## 128 2013-07-03 1.0010573 1.0240096 1.0091384
## 189 2013-09-30 0.9893358 0.9886736 0.9906912

names(vw.q3)[2:4] <- paste(c("AMZN", "YHOO", "IBM"))
vw.q3[c(1:3, nrow(vw.q3)), ]
##           date      AMZN      YHOO       IBM
## 126 2013-07-01 1.0158810 1.0043773 1.0008895
## 127 2013-07-02 1.0057781 0.9900951 1.0011502
## 128 2013-07-03 1.0010573 1.0240096 1.0091384
## 189 2013-09-30 0.9893358 0.9886736 0.9906912

#vw.q3[1, 2:4] <- 1 #difference from Q1
vw.q3$AMZN <- cumprod(vw.q3$AMZN)
vw.q3$YHOO <- cumprod(vw.q3$YHOO)
vw.q3$IBM <- cumprod(vw.q3$IBM)
vw.q3[c(1:3, nrow(vw.q3)), ]
##           date     AMZN     YHOO       IBM
## 126 2013-07-01 1.015881 1.004377 1.0008895
## 127 2013-07-02 1.021751 0.994429 1.0020407
## 128 2013-07-03 1.022831 1.018305 1.0111977
## 189 2013-09-30 1.125860 1.319936 0.9738146

vw.q3$AMZN.ind <- (q3.vw.inv * q3.vw.wgt$AMZN.wgt) * vw.q3$AMZN #Apply weight
vw.q3$YHOO.ind <- (q3.vw.inv * q3.vw.wgt$YHOO.wgt) * vw.q3$YHOO
vw.q3$IBM.ind <- (q3.vw.inv * q3.vw.wgt$IBM.wgt) * vw.q3$IBM
vw.q3[c(1:3, nrow(vw.q3)), ]
##           date     AMZN     YHOO       IBM  AMZN.ind   YHOO.ind   IBM.ind
## 126 2013-07-01 1.015881 1.004377 1.0008895 0.3749376 0.07818033 0.6093857
## 127 2013-07-02 1.021751 0.994429 1.0020407 0.3771041 0.07740596 0.6100866
## 128 2013-07-03 1.022831 1.018305 1.0111977 0.3775028 0.07926444 0.6156618
## 189 2013-09-30 1.125860 1.319936 0.9738146 0.4155282 0.10274332 0.5929013

q3.vw.val <- data.frame(rowSums(vw.q3[, 5:7]))
q3.vw.val[c(1:3, nrow(q3.vw.val)), ]
## [1] 1.062504 1.064597 1.072429 1.111173

names(q3.vw.val) <- paste("port.val")
q3.vw.val[c(1:3, nrow(q3.vw.val)), ]
## [1] 1.062504 1.064597 1.072429 1.111173

q3.vw.val$date <- vw.q3$date
q3.vw.val[c(1:3, nrow(q3.vw.val)), ]
##     port.val       date
## 126 1.062504 2013-07-01
## 127 1.064597 2013-07-02
## 128 1.072429 2013-07-03
## 189 1.111173 2013-09-30

q4.vw.inv <- q3.vw.val[nrow(q3.vw.val), 1]
q4.vw.inv
## [1] 1.111173
#$1.104 at the end of Q1 and $1.111 by the end of Q3
#it doesn't mean that the portfolio grew 11.1% during q3 but 11.1% during Q1-Q3
#b/c it's a cumulative measure

Step 10: Calculate VW Portfolio Values for 4Q 2013

vw.q4 <- subset(vwport,
                vwport$date >= "2013-10-01" &
                  vwport$date <= "2013-12-31")
vw.q4[c(1:3, nrow(vw.q4)), ]
##           date AMZN.Close YHOO.Close IBM.Close  AMZN.ret  YHOO.ret
## 190 2013-10-01     320.95      34.31    186.38 1.0265801 1.0343685
## 191 2013-10-02     320.51      34.14    184.96 0.9986291 0.9950451
## 192 2013-10-03     314.76      33.88    183.86 0.9820598 0.9923844
## 253 2013-12-31     398.79      40.44    187.57 1.0137784 1.0059701
##       IBM.ret
## 190 1.0064802
## 191 0.9923812
## 192 0.9940527
## 253 1.0062229

vw.q4 <- vw.q4[, c(1, 5:7)]
vw.q4[c(1:3, nrow(vw.q4)), ]
##           date  AMZN.ret  YHOO.ret   IBM.ret
## 190 2013-10-01 1.0265801 1.0343685 1.0064802
## 191 2013-10-02 0.9986291 0.9950451 0.9923812
## 192 2013-10-03 0.9820598 0.9923844 0.9940527
## 253 2013-12-31 1.0137784 1.0059701 1.0062229

names(vw.q4)[2:4] <- paste(c("AMZN", "YHOO", "IBM"))
vw.q4[c(1:3, nrow(vw.q4)), ]
##           date      AMZN      YHOO       IBM
## 190 2013-10-01 1.0265801 1.0343685 1.0064802
## 191 2013-10-02 0.9986291 0.9950451 0.9923812
## 192 2013-10-03 0.9820598 0.9923844 0.9940527
## 253 2013-12-31 1.0137784 1.0059701 1.0062229

#vw.q4[1, 2:4] <- 1 #difference from Q1
vw.q4$AMZN <- cumprod(vw.q4$AMZN)
vw.q4$YHOO <- cumprod(vw.q4$YHOO)
vw.q4$IBM <- cumprod(vw.q4$IBM)
vw.q4[c(1:3, nrow(vw.q4)), ]
##           date     AMZN     YHOO       IBM
## 190 2013-10-01 1.026580 1.034368 1.0064802
## 191 2013-10-02 1.025173 1.029243 0.9988120
## 192 2013-10-03 1.006781 1.021405 0.9928718
## 253 2013-12-31 1.275557 1.219174 1.0183460

vw.q4$AMZN.ind <- (q4.vw.inv * q4.vw.wgt$AMZN.wgt) * vw.q4$AMZN #Apply weight
vw.q4$YHOO.ind <- (q4.vw.inv * q4.vw.wgt$YHOO.wgt) * vw.q4$YHOO
vw.q4$IBM.ind <- (q4.vw.inv * q4.vw.wgt$IBM.wgt) * vw.q4$IBM
vw.q4[c(1:3, nrow(vw.q4)), ]
##           date     AMZN     YHOO       IBM  AMZN.ind  YHOO.ind   IBM.ind
## 190 2013-10-01 1.026580 1.034368 1.0064802 0.4322561 0.1022101 0.5951264
## 191 2013-10-02 1.025173 1.029243 0.9988120 0.4316635 0.1017037 0.5905922
## 192 2013-10-03 1.006781 1.021405 0.9928718 0.4239194 0.1009291 0.5870798
## 253 2013-12-31 1.275557 1.219174 1.0183460 0.5370912 0.1204715 0.6021426

q4.vw.val <- data.frame(rowSums(vw.q4[, 5:7]))
q4.vw.val[c(1:3, nrow(q4.vw.val)), ]
## [1] 1.129593 1.123959 1.111928 1.259705

names(q4.vw.val) <- paste("port.val")
q4.vw.val[c(1:3, nrow(q4.vw.val)), ]
## [1] 1.129593 1.123959 1.111928 1.259705

q4.vw.val$date <- vw.q4$date
q4.vw.val[c(1:3, nrow(q4.vw.val)), ]
##     port.val       date
## 190 1.129593 2013-10-01
## 191 1.123959 2013-10-02
## 192 1.111928 2013-10-03
## 253 1.259705 2013-12-31
#$1.104 at the end of Q1 and $1.259 by the end of Q4
#it doesn't mean that the portfolio grew 25.9% during Q4 but 25.9% during Q1-Q4
#b/c it's a cumulative measure

Step 11: Combine Quarterly VW Portfolio Values into One Data Object

vw.portval <- rbind(q1.vw.val, q2.vw.val, q3.vw.val, q4.vw.val)
vw.portval[c(1:3, nrow(vw.portval)), ]
##     port.val       date
## 1   1.000000 2012-12-31
## 2   1.024243 2013-01-02
## 3   1.021358 2013-01-03
## 253 1.259705 2013-12-31

3.3.3 Normalized EW and VW Portfolio Price Chart

Compare the performance of EW and VW portfolio from 12/31/2012 to 12/31/2013

Step 1: Combine the Data

port.val <- merge(vw.portval, ew.portval, by = "date")
port.val[c(1:3, nrow(port.val)), ]
##           date port.val.x port.val.y
## 1   2012-12-31   1.000000   1.000000
## 2   2013-01-02   1.024243   1.019925
## 3   2013-01-03   1.021358   1.014575
## 253 2013-12-31   1.259705   1.501374

Step 2: Rename the Variables

names(port.val)[2:3] <- paste(c("VW.cum", "EW.cum"))
port.val[c(1:3, nrow(port.val)), ]
##           date   VW.cum   EW.cum
## 1   2012-12-31 1.000000 1.000000
## 2   2013-01-02 1.024243 1.019925
## 3   2013-01-03 1.021358 1.014575
## 253 2013-12-31 1.259705 1.501374

Step 3: Plot the Data

par(mfrow = c(1, 1))
y.range <- range(port.val[, 2:3])
y.range
## [1] 1.000000 1.506584
plot(port.val$EW.cum,
     xlab = "Date",
     ylab = "Value of Investment",
     ylim = y.range,
     type = "l",
     lty = 1,
     main = "Value of R1 Investment in Equal-Weighted and
          Value-Weighted Portfolio of AMZN, YHOO, and IBM
          December 31, 2012 - December 31, 2013")
lines(port.val$VW.cum, lty = 2)
abline(h = 1, lty = 1)
legend("topleft",
       c("Equal-Weighted Portfolio", "Value-Weighted Portfolio"), #typo in the textbook
       lty = c(1, 2))

3.3.4 Saving Benchmark Portfolio Returns into a CSV File

Net returns as well as cumulative returns

Step 1: Convert the Data into an xts Object

# This is to appropriately take the lag of the portfolio value
port.xts <- xts(port.val[, 2:3], order.by = port.val[, 1])
port.xts[c(1:3, nrow(port.xts)), ]
##              VW.cum   EW.cum
## 2012-12-31 1.000000 1.000000
## 2013-01-02 1.024243 1.019925
## 2013-01-03 1.021358 1.014575
## 2013-12-31 1.259705 1.501374

port.xts$Lag.VW <- Lag(port.xts$VW.cum, k = 1)
port.xts$Lag.EW <- Lag(port.xts$EW.cum, k = 1)
port.xts[c(1:3, nrow(port.xts)), ]
##              VW.cum   EW.cum   Lag.VW   Lag.EW
## 2012-12-31 1.000000 1.000000       NA       NA
## 2013-01-02 1.024243 1.019925 1.000000 1.000000
## 2013-01-03 1.021358 1.014575 1.024243 1.019925
## 2013-12-31 1.259705 1.501374 1.247967 1.488182

Step 2: Create EW and VW Returns

port.xts$VW.ret <- port.xts$VW.cum / port.xts$Lag.VW - 1
port.xts$EW.ret <- port.xts$EW.cum / port.xts$Lag.EW - 1
port.xts[c(1:3, nrow(port.xts)), ]
##              VW.cum   EW.cum   Lag.VW   Lag.EW       VW.ret       EW.ret
## 2012-12-31 1.000000 1.000000       NA       NA           NA           NA
## 2013-01-02 1.024243 1.019925 1.000000 1.000000  0.024242757  0.019924884
## 2013-01-03 1.021358 1.014575 1.024243 1.019925 -0.002816844 -0.005245396
## 2013-12-31 1.259705 1.501374 1.247967 1.488182  0.009406118  0.008864927

Step 3: Clean up the Data

Port.Ret <- port.xts[, c(1, 2, 5, 6)]
Port.Ret[c(1:3, nrow(port.xts)), ]
##              VW.cum   EW.cum       VW.ret       EW.ret
## 2012-12-31 1.000000 1.000000           NA           NA
## 2013-01-02 1.024243 1.019925  0.024242757  0.019924884
## 2013-01-03 1.021358 1.014575 -0.002816844 -0.005245396
## 2013-12-31 1.259705 1.501374  0.009406118  0.008864927

Step 4: Create a Date Variable in the Data Object

csv.port <- cbind(data.frame(index(Port.Ret)), data.frame(Port.Ret))
names(csv.port)[1] <- paste("date")
csv.port[c(1:3, nrow(port.xts)), ]
##                  date   VW.cum   EW.cum       VW.ret       EW.ret
## 2012-12-31 2012-12-31 1.000000 1.000000           NA           NA
## 2013-01-02 2013-01-02 1.024243 1.019925  0.024242757  0.019924884
## 2013-01-03 2013-01-03 1.021358 1.014575 -0.002816844 -0.005245396
## 2013-12-31 2013-12-31 1.259705 1.501374  0.009406118  0.008864927

Step 5: Replace Index with Observation Numbers

rownames(csv.port) <- seq(1:nrow(csv.port))
csv.port[c(1:3, nrow(port.xts)), ]
##           date   VW.cum   EW.cum       VW.ret       EW.ret
## 1   2012-12-31 1.000000 1.000000           NA           NA
## 2   2013-01-02 1.024243 1.019925  0.024242757  0.019924884
## 3   2013-01-03 1.021358 1.014575 -0.002816844 -0.005245396
## 253 2013-12-31 1.259705 1.501374  0.009406118  0.008864927

Step 6: Save the Data to a CSV File

#write.csv(csv.port, "Hypothetical Portfolio (Daily).csv")