Construct an equal-weighted (EW) and value-weighted (VW) portfolio, consisting of AMZN, TSLA, AAPL, and MSFT.
In this section, prepare an object, port, which will be used later to build EW and VW portfolio.
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 = "2016-12-31", to = "2017-07-01", auto.assign = FALSE)
data.TSLA <- getSymbols("TSLA", from = "2016-12-31", to = "2017-07-01", auto.assign = FALSE)
data.MSFT <- getSymbols("MSFT", from = "2016-12-31", to = "2017-07-01", auto.assign = FALSE)
data.AAPL <- getSymbols("AAPL", from = "2016-12-31", to = "2017-07-01", auto.assign = FALSE)
#to = "2013-12-31" in the book was replaced by to = "2017-07-01"
#B/c that code doesn't produce the output that includes stock price of 2013-12-31the date.
Step 1: Importing the Price Data
data.AMZN[c(1:3, nrow(data.AMZN)), ]
## AMZN.Open AMZN.High AMZN.Low AMZN.Close AMZN.Volume
## 2017-01-03 757.92 758.76 747.70 753.67 3521100
## 2017-01-04 758.39 759.68 754.20 757.18 2510500
## 2017-01-05 761.55 782.40 760.26 780.45 5830100
## 2017-06-30 980.12 983.47 967.61 968.00 3390300
## AMZN.Adjusted
## 2017-01-03 753.67
## 2017-01-04 757.18
## 2017-01-05 780.45
## 2017-06-30 968.00
data.TSLA[c(1:3, nrow(data.TSLA)), ]
## TSLA.Open TSLA.High TSLA.Low TSLA.Close TSLA.Volume
## 2017-01-03 214.86 220.33 210.96 216.99 5923300
## 2017-01-04 214.75 228.00 214.31 226.99 11213500
## 2017-01-05 226.42 227.48 221.95 226.75 5911700
## 2017-06-30 363.71 366.77 359.62 361.61 5848500
## TSLA.Adjusted
## 2017-01-03 216.99
## 2017-01-04 226.99
## 2017-01-05 226.75
## 2017-06-30 361.61
data.MSFT[c(1:3, nrow(data.MSFT)), ]
## MSFT.Open MSFT.High MSFT.Low MSFT.Close MSFT.Volume
## 2017-01-03 64.192 64.243 63.517 62.58 20694100
## 2017-01-04 63.875 64.151 63.507 62.30 21340000
## 2017-01-05 63.579 64.059 63.415 62.30 24876000
## 2017-06-30 69.494 70.100 69.453 68.93 24161100
## MSFT.Adjusted
## 2017-01-03 61.21319
## 2017-01-04 60.93930
## 2017-01-05 60.93930
## 2017-06-30 68.22208
data.AAPL[c(1:3, nrow(data.AAPL)), ]
## AAPL.Open AAPL.High AAPL.Low AAPL.Close AAPL.Volume
## 2017-01-03 117.662 118.201 116.605 116.15 28781900
## 2017-01-04 117.713 118.384 117.611 116.02 21118100
## 2017-01-05 117.784 118.739 117.672 116.61 22193600
## 2017-06-30 145.539 146.052 144.864 144.02 23024100
## AAPL.Adjusted
## 2017-01-03 114.3118
## 2017-01-04 114.1838
## 2017-01-05 114.7645
## 2017-06-30 142.9428
Step 2: Create Object with Only the Relevant Data
port <- data.AMZN[, c(4, 6)]
port <- merge(port, data.TSLA[, c(4, 6)])
port <- merge(port, data.MSFT[, c(4, 6)])
port <- merge(port, data.AAPL[, c(4, 6)])
#port <- cbind(port, data.TSLA[, c(4, 6)], data.MSFT[, c(4, 6)], data.AAPL[, c(4, 6)])
port[c(1:3, nrow(port)), ]
## AMZN.Close AMZN.Adjusted TSLA.Close TSLA.Adjusted MSFT.Close
## 2017-01-03 753.67 753.67 216.99 216.99 62.58
## 2017-01-04 757.18 757.18 226.99 226.99 62.30
## 2017-01-05 780.45 780.45 226.75 226.75 62.30
## 2017-06-30 968.00 968.00 361.61 361.61 68.93
## MSFT.Adjusted AAPL.Close AAPL.Adjusted
## 2017-01-03 61.21319 116.15 114.3118
## 2017-01-04 60.93930 116.02 114.1838
## 2017-01-05 60.93930 116.61 114.7645
## 2017-06-30 68.22208 144.02 142.9428
Step 3: Calculate Returns of Each Security
port$AMZN.ret <- Delt(port$AMZN.Adjusted)
port$TSLA.ret <- Delt(port$TSLA.Adjusted)
port$MSFT.ret <- Delt(port$MSFT.Adjusted)
port$AAPL.ret <- Delt(port$AAPL.Adjusted)
port[c(1:3, nrow(port)), ]
## AMZN.Close AMZN.Adjusted TSLA.Close TSLA.Adjusted MSFT.Close
## 2017-01-03 753.67 753.67 216.99 216.99 62.58
## 2017-01-04 757.18 757.18 226.99 226.99 62.30
## 2017-01-05 780.45 780.45 226.75 226.75 62.30
## 2017-06-30 968.00 968.00 361.61 361.61 68.93
## MSFT.Adjusted AAPL.Close AAPL.Adjusted AMZN.ret
## 2017-01-03 61.21319 116.15 114.3118 NA
## 2017-01-04 60.93930 116.02 114.1838 0.004657224
## 2017-01-05 60.93930 116.61 114.7645 0.030732480
## 2017-06-30 68.22208 144.02 142.9428 -0.008125576
## TSLA.ret MSFT.ret AAPL.ret
## 2017-01-03 NA NA NA
## 2017-01-04 0.046085072 -0.004474330 -0.001119264
## 2017-01-05 -0.001057337 0.000000000 0.005085292
## 2017-06-30 0.002383881 0.006424249 0.002366525
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 TSLA.Close TSLA.Adjusted
## 2017-01-03 2017-01-03 753.67 753.67 216.99 216.99
## 2017-01-04 2017-01-04 757.18 757.18 226.99 226.99
## 2017-01-05 2017-01-05 780.45 780.45 226.75 226.75
## 2017-06-30 2017-06-30 968.00 968.00 361.61 361.61
## MSFT.Close MSFT.Adjusted AAPL.Close AAPL.Adjusted AMZN.ret
## 2017-01-03 62.58 61.21319 116.15 114.3118 NA
## 2017-01-04 62.30 60.93930 116.02 114.1838 0.004657224
## 2017-01-05 62.30 60.93930 116.61 114.7645 0.030732480
## 2017-06-30 68.93 68.22208 144.02 142.9428 -0.008125576
## TSLA.ret MSFT.ret AAPL.ret
## 2017-01-03 NA NA NA
## 2017-01-04 0.046085072 -0.004474330 -0.001119264
## 2017-01-05 -0.001057337 0.000000000 0.005085292
## 2017-06-30 0.002383881 0.006424249 0.002366525
port <- subset(port,
port$date >= "2016-12-31" &
port$date <= "2017-12-31")
port[c(1:3, nrow(port)), ]
## date AMZN.Close AMZN.Adjusted TSLA.Close TSLA.Adjusted
## 2017-01-03 2017-01-03 753.67 753.67 216.99 216.99
## 2017-01-04 2017-01-04 757.18 757.18 226.99 226.99
## 2017-01-05 2017-01-05 780.45 780.45 226.75 226.75
## 2017-06-30 2017-06-30 968.00 968.00 361.61 361.61
## MSFT.Close MSFT.Adjusted AAPL.Close AAPL.Adjusted AMZN.ret
## 2017-01-03 62.58 61.21319 116.15 114.3118 NA
## 2017-01-04 62.30 60.93930 116.02 114.1838 0.004657224
## 2017-01-05 62.30 60.93930 116.61 114.7645 0.030732480
## 2017-06-30 68.93 68.22208 144.02 142.9428 -0.008125576
## TSLA.ret MSFT.ret AAPL.ret
## 2017-01-03 NA NA NA
## 2017-01-04 0.046085072 -0.004474330 -0.001119264
## 2017-01-05 -0.001057337 0.000000000 0.005085292
## 2017-06-30 0.002383881 0.006424249 0.002366525
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, 10:13)]
ewport[c(1:3, nrow(ewport)), ]
## date AMZN.ret TSLA.ret MSFT.ret AAPL.ret
## 2017-01-03 2017-01-03 NA NA NA NA
## 2017-01-04 2017-01-04 0.004657224 0.046085072 -0.004474330 -0.001119264
## 2017-01-05 2017-01-05 0.030732480 -0.001057337 0.000000000 0.005085292
## 2017-06-30 2017-06-30 -0.008125576 0.002383881 0.006424249 0.002366525
names(ewport)[2:5] <- c("AMZN", "TSLA", "MSFT", "AAPL")
rownames(ewport) <- seq(1, nrow(ewport), 1)
ewport[c(1:3, nrow(ewport)), ]
## date AMZN TSLA MSFT AAPL
## 1 2017-01-03 NA NA NA NA
## 2 2017-01-04 0.004657224 0.046085072 -0.004474330 -0.001119264
## 3 2017-01-05 0.030732480 -0.001057337 0.000000000 0.005085292
## 125 2017-06-30 -0.008125576 0.002383881 0.006424249 0.002366525
Step 2: Convert Net Returns to Gross Returns
ewport[2:5] <- ewport[2:5] + 1
ewport[c(1:3, nrow(ewport)), ]
## date AMZN TSLA MSFT AAPL
## 1 2017-01-03 NA NA NA NA
## 2 2017-01-04 1.0046572 1.0460851 0.9955257 0.9988807
## 3 2017-01-05 1.0307325 0.9989427 1.0000000 1.0050853
## 125 2017-06-30 0.9918744 1.0023839 1.0064242 1.0023665
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 >= "2016-12-31" &
ewport$date <= "2017-03-31")
ewq1[c(1:3, nrow(ewq1)), ]
## date AMZN TSLA MSFT AAPL
## 1 2017-01-03 NA NA NA NA
## 2 2017-01-04 1.004657 1.0460851 0.9955257 0.9988807
## 3 2017-01-05 1.030732 0.9989427 1.0000000 1.0050853
## 62 2017-03-31 1.011639 1.0013672 1.0022828 0.9981242
# Calculate the cumulative gross returns fro each security for Q1
ewq1[1, 2:5] <- 1
ewq1[2:5] <- cumprod(ewq1[2:5])
ewq1[c(1:3, nrow(ewq1)), ]
## date AMZN TSLA MSFT AAPL
## 1 2017-01-03 1.000000 1.000000 1.0000000 1.0000000
## 2 2017-01-04 1.004657 1.046085 0.9955257 0.9988807
## 3 2017-01-05 1.035533 1.044979 0.9955257 1.0039603
## 62 2017-03-31 1.176297 1.282547 1.0587932 1.2422114
# Calculate the index value for each security for Q1
num.sec <- 4
ewq1$AMZN.ind <- ewq1$AMZN / num.sec
ewq1$TSLA.ind <- ewq1$TSLA / num.sec
ewq1$MSFT.ind <- ewq1$MSFT / num.sec
ewq1$AAPL.ind <- ewq1$AAPL / num.sec
ewq1[c(1:3, nrow(ewq1)), ]
## date AMZN TSLA MSFT AAPL AMZN.ind TSLA.ind
## 1 2017-01-03 1.000000 1.000000 1.0000000 1.0000000 0.2500000 0.2500000
## 2 2017-01-04 1.004657 1.046085 0.9955257 0.9988807 0.2511643 0.2615213
## 3 2017-01-05 1.035533 1.044979 0.9955257 1.0039603 0.2588832 0.2612448
## 62 2017-03-31 1.176297 1.282547 1.0587932 1.2422114 0.2940743 0.3206369
## MSFT.ind AAPL.ind
## 1 0.2500000 0.2500000
## 2 0.2488814 0.2497202
## 3 0.2488814 0.2509901
## 62 0.2646983 0.3105529
# Calculate the agrregate portfolio value on each day
q1.val <- data.frame(rowSums(ewq1[, 6:9]))
q1.val[c(1:3, nrow(q1.val)), ]
## [1] 1.000000 1.011287 1.019999 1.189962
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 2017-01-03
## 2 1.011287 2017-01-04
## 3 1.019999 2017-01-05
## 62 1.189962 2017-03-31
# Pass the aggregate portfolio value at the end of Q1 to Q2
q2.inv <- q1.val[nrow(q1.val), 1]
q2.inv
## [1] 1.189962
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 >= "2017-04-01" &
ewport$date <= "2017-06-30")
ewq2[c(1:3, nrow(ewq2)), ]
## date AMZN TSLA MSFT AAPL
## 63 2017-04-03 1.0056061 1.0726554 0.9952930 1.0002784
## 64 2017-04-04 1.0171843 1.0173523 1.0027460 1.0074461
## 65 2017-04-05 1.0027017 0.9713533 0.9974135 0.9948194
## 125 2017-06-30 0.9918744 1.0023839 1.0064242 1.0023665
# Calculate the cumulative gross returns fro each security for Q2
#ewq2[1, 2:5] <- 1 This is the difference from Q1
ewq2[2:5] <- cumprod(ewq2[2:5])
ewq2[c(1:3, nrow(ewq2)), ]
## date AMZN TSLA MSFT AAPL
## 63 2017-04-03 1.005606 1.072655 0.9952930 1.000278
## 64 2017-04-04 1.022887 1.091269 0.9980261 1.007727
## 65 2017-04-05 1.025650 1.060007 0.9954448 1.002506
## 125 2017-06-30 1.091885 1.299353 1.0526131 1.006644
# Calculate the index value for each security for Q2
ewq2$AMZN.ind <- (q2.inv / num.sec) * ewq2$AMZN #a difference from Q1
ewq2$TSLA.ind <- (q2.inv / num.sec) * ewq2$TSLA
ewq2$MSFT.ind <- (q2.inv / num.sec) * ewq2$MSFT
ewq2$AAPL.ind <- (q2.inv / num.sec) * ewq2$AAPL
ewq2[c(1:3, nrow(ewq2)), ]
## date AMZN TSLA MSFT AAPL AMZN.ind TSLA.ind
## 63 2017-04-03 1.005606 1.072655 0.9952930 1.000278 0.2991584 0.3191049
## 64 2017-04-04 1.022887 1.091269 0.9980261 1.007727 0.3042992 0.3246421
## 65 2017-04-05 1.025650 1.060007 0.9954448 1.002506 0.3051213 0.3153422
## 125 2017-06-30 1.091885 1.299353 1.0526131 1.006644 0.3248256 0.3865454
## MSFT.ind AAPL.ind
## 63 0.2960903 0.2975734
## 64 0.2969034 0.2997892
## 65 0.2961354 0.2982361
## 125 0.3131425 0.2994671
# Calculate the agrregate portfolio value on each day
q2.val <- data.frame(rowSums(ewq2[, 6:9]))
q2.val[c(1:3, nrow(q2.val)), ]
## [1] 1.211927 1.225634 1.214835 1.323981
names(q2.val) <- paste("port.val")
q2.val$date <- ewq2$date
q2.val[c(1:3, nrow(q2.val)), ]
## port.val date
## 63 1.211927 2017-04-03
## 64 1.225634 2017-04-04
## 65 1.214835 2017-04-05
## 125 1.323981 2017-06-30
#$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 7: Combine Quarterly EW Portfolio Values into One Data Object
ew.portval <- rbind(q1.val, q2.val)
ew.portval[c(1:3, nrow(ew.portval)), ]
## port.val date
## 1 1.000000 2017-01-03
## 2 1.011287 2017-01-04
## 3 1.019999 2017-01-05
## 125 1.323981 2017-06-30
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:13)] #port is from 3.3 Constructing Benchmark Portfolio Returns
vwport[c(1:3, nrow(vwport)), ]
## date AMZN.Close TSLA.Close MSFT.Close AAPL.Close
## 2017-01-03 2017-01-03 753.67 216.99 62.58 116.15
## 2017-01-04 2017-01-04 757.18 226.99 62.30 116.02
## 2017-01-05 2017-01-05 780.45 226.75 62.30 116.61
## 2017-06-30 2017-06-30 968.00 361.61 68.93 144.02
## AMZN.ret TSLA.ret MSFT.ret AAPL.ret
## 2017-01-03 NA NA NA NA
## 2017-01-04 0.004657224 0.046085072 -0.004474330 -0.001119264
## 2017-01-05 0.030732480 -0.001057337 0.000000000 0.005085292
## 2017-06-30 -0.008125576 0.002383881 0.006424249 0.002366525
rownames(vwport) <- seq(1:nrow(vwport))
vwport[c(1:3, nrow(vwport)), ]
## date AMZN.Close TSLA.Close MSFT.Close AAPL.Close AMZN.ret
## 1 2017-01-03 753.67 216.99 62.58 116.15 NA
## 2 2017-01-04 757.18 226.99 62.30 116.02 0.004657224
## 3 2017-01-05 780.45 226.75 62.30 116.61 0.030732480
## 125 2017-06-30 968.00 361.61 68.93 144.02 -0.008125576
## TSLA.ret MSFT.ret AAPL.ret
## 1 NA NA NA
## 2 0.046085072 -0.004474330 -0.001119264
## 3 -0.001057337 0.000000000 0.005085292
## 125 0.002383881 0.006424249 0.002366525
Step 2: Convert Net Returns to Gross Returns
vwport$AMZN.ret <- vwport$AMZN.ret + 1
vwport$TSLA.ret <- vwport$TSLA.ret + 1
vwport$MSFT.ret <- vwport$MSFT.ret + 1
vwport$AAPL.ret <- vwport$AAPL.ret + 1
vwport[c(1:3, nrow(vwport)), ]
## date AMZN.Close TSLA.Close MSFT.Close AAPL.Close AMZN.ret
## 1 2017-01-03 753.67 216.99 62.58 116.15 NA
## 2 2017-01-04 757.18 226.99 62.30 116.02 1.0046572
## 3 2017-01-05 780.45 226.75 62.30 116.61 1.0307325
## 125 2017-06-30 968.00 361.61 68.93 144.02 0.9918744
## TSLA.ret MSFT.ret AAPL.ret
## 1 NA NA NA
## 2 1.0460851 0.9955257 0.9988807
## 3 0.9989427 1.0000000 1.0050853
## 125 1.0023839 1.0064242 1.0023665
Step 3: Calculate the Market Capitalization of Each Security in the Portfolio
# Construct Series of Calendar Days
date <- seq(as.Date("2016-12-31"), as.Date("2017-12-31"), by = 1)
date <- data.frame(date)
date[c(1:3, nrow(date)), ]
## [1] "2016-12-31" "2017-01-01" "2017-01-02" "2017-12-31"
# Create Data Object with Daily Prices
PRICE.qtr <- vwport[, 1:6]
PRICE.qtr[c(1:3, nrow(PRICE.qtr)), ]
## date AMZN.Close TSLA.Close MSFT.Close AAPL.Close AMZN.ret
## 1 2017-01-03 753.67 216.99 62.58 116.15 NA
## 2 2017-01-04 757.18 226.99 62.30 116.02 1.0046572
## 3 2017-01-05 780.45 226.75 62.30 116.61 1.0307325
## 125 2017-06-30 968.00 361.61 68.93 144.02 0.9918744
# 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 TSLA.Close MSFT.Close AAPL.Close AMZN.ret
## 1 2016-12-31 <NA> <NA> <NA> <NA> <NA>
## 2 2017-01-01 <NA> <NA> <NA> <NA> <NA>
## 3 2017-01-02 <NA> <NA> <NA> <NA> <NA>
## 366 2017-12-31 968.00 361.61 68.93 144.02 0.9918744
# Keep Only Prices at the End of Each Calendar Quarter
PRICE.qtr <- subset(PRICE.qtr,
PRICE.qtr$date == as.Date("2017-01-02") |
PRICE.qtr$date == as.Date("2017-04-02"))
PRICE.qtr
## date AMZN.Close TSLA.Close MSFT.Close AAPL.Close AMZN.ret
## 3 2017-01-02 <NA> <NA> <NA> <NA> <NA>
## 93 2017-04-02 886.54 278.30 65.86 143.66 1.0116393
# 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(478000000, 477000000)
PRICE.qtr$TSLA.shout <- c(149825000, 131425000)
PRICE.qtr$MSFT.shout <- c(7723000000, 7808000000)
PRICE.qtr$AAPL.shout <- c(5255423000, 5336166000)
PRICE.qtr
## date AMZN.Close TSLA.Close MSFT.Close AAPL.Close AMZN.ret
## 3 2017-01-02 <NA> <NA> <NA> <NA> <NA>
## 93 2017-04-02 886.54 278.30 65.86 143.66 1.0116393
## AMZN.shout TSLA.shout MSFT.shout AAPL.shout
## 3 4.78e+08 149825000 7.723e+09 5255423000
## 93 4.77e+08 131425000 7.808e+09 5336166000
# Calculate Market Capitalization of Each Security
str(PRICE.qtr)
## 'data.frame': 2 obs. of 10 variables:
## $ date : chr "2017-01-02" "2017-04-02"
## $ AMZN.Close: chr NA " 886.54"
## $ TSLA.Close: chr NA "278.30"
## $ MSFT.Close: chr NA "65.86"
## $ AAPL.Close: chr NA "143.66"
## $ AMZN.ret : chr NA "1.0116393"
## $ AMZN.shout: num 4.78e+08 4.77e+08
## $ TSLA.shout: num 1.50e+08 1.31e+08
## $ MSFT.shout: num 7.72e+09 7.81e+09
## $ AAPL.shout: num 5.26e+09 5.34e+09
PRICE.qtr$date <- as.Date(PRICE.qtr$date)
PRICE.qtr$AMZN.Close <- as.numeric(PRICE.qtr$AMZN.Close)
PRICE.qtr$TSLA.Close <- as.numeric(PRICE.qtr$TSLA.Close)
PRICE.qtr$MSFT.Close <- as.numeric(PRICE.qtr$MSFT.Close)
PRICE.qtr$AAPL.Close <- as.numeric(PRICE.qtr$AAPL.Close)
str(PRICE.qtr)
## 'data.frame': 2 obs. of 10 variables:
## $ date : Date, format: "2017-01-02" "2017-04-02"
## $ AMZN.Close: num NA 887
## $ TSLA.Close: num NA 278
## $ MSFT.Close: num NA 65.9
## $ AAPL.Close: num NA 144
## $ AMZN.ret : chr NA "1.0116393"
## $ AMZN.shout: num 4.78e+08 4.77e+08
## $ TSLA.shout: num 1.50e+08 1.31e+08
## $ MSFT.shout: num 7.72e+09 7.81e+09
## $ AAPL.shout: num 5.26e+09 5.34e+09
weights <- PRICE.qtr
weights$AMZN.mcap <- weights$AMZN.Close * weights$AMZN.shout
weights$TSLA.mcap <- weights$TSLA.Close * weights$TSLA.shout
weights$MSFT.mcap <- weights$MSFT.Close * weights$MSFT.shout
weights$AAPL.mcap <- weights$AAPL.Close * weights$AAPL.shout
weights
## date AMZN.Close TSLA.Close MSFT.Close AAPL.Close AMZN.ret
## 3 2017-01-02 NA NA NA NA <NA>
## 93 2017-04-02 886.54 278.3 65.86 143.66 1.0116393
## AMZN.shout TSLA.shout MSFT.shout AAPL.shout AMZN.mcap TSLA.mcap
## 3 4.78e+08 149825000 7.723e+09 5255423000 NA NA
## 93 4.77e+08 131425000 7.808e+09 5336166000 422879580000 36575577500
## MSFT.mcap AAPL.mcap
## 3 NA NA
## 93 514234880000 766593607560
# Calculate Quarter-end Aggregate Market Capitalization
weights$tot.mcap <- rowSums(weights[, 10:13])
weights
## date AMZN.Close TSLA.Close MSFT.Close AAPL.Close AMZN.ret
## 3 2017-01-02 NA NA NA NA <NA>
## 93 2017-04-02 886.54 278.3 65.86 143.66 1.0116393
## AMZN.shout TSLA.shout MSFT.shout AAPL.shout AMZN.mcap TSLA.mcap
## 3 4.78e+08 149825000 7.723e+09 5255423000 NA NA
## 93 4.77e+08 131425000 7.808e+09 5336166000 422879580000 36575577500
## MSFT.mcap AAPL.mcap tot.mcap
## 3 NA NA NA
## 93 514234880000 766593607560 979026203500
Step 4: Calculate Quarter-end Weights of Each Security in the Portfolio
weights$AMZN.wgt <- weights$AMZN.mcap / weights$tot.mcap
weights$TSLA.wgt <- weights$TSLA.mcap / weights$tot.mcap
weights$MSFT.wgt <- weights$MSFT.mcap / weights$tot.mcap
weights$AAPL.wgt <- weights$AAPL.mcap / weights$tot.mcap
weights
## date AMZN.Close TSLA.Close MSFT.Close AAPL.Close AMZN.ret
## 3 2017-01-02 NA NA NA NA <NA>
## 93 2017-04-02 886.54 278.3 65.86 143.66 1.0116393
## AMZN.shout TSLA.shout MSFT.shout AAPL.shout AMZN.mcap TSLA.mcap
## 3 4.78e+08 149825000 7.723e+09 5255423000 NA NA
## 93 4.77e+08 131425000 7.808e+09 5336166000 422879580000 36575577500
## MSFT.mcap AAPL.mcap tot.mcap AMZN.wgt TSLA.wgt MSFT.wgt
## 3 NA NA NA NA NA NA
## 93 514234880000 766593607560 979026203500 0.431939 0.03735914 0.5252514
## AAPL.wgt
## 3 NA
## 93 0.7830164
weights <- weights[, c(1, 14:17)]
weights
## date AAPL.mcap tot.mcap AMZN.wgt TSLA.wgt
## 3 2017-01-02 NA NA NA NA
## 93 2017-04-02 766593607560 979026203500 0.431939 0.03735914
weights[1, "date"] <- weights[1, "date"]+2
weights[2, "date"] <- weights[2, "date"]+1 #since the weights are applicable at the start of the next Q
weights
## date AAPL.mcap tot.mcap AMZN.wgt TSLA.wgt
## 3 2017-01-04 NA NA NA NA
## 93 2017-04-03 766593607560 979026203500 0.431939 0.03735914
Step 5: Calculate the Quarterly VW Portfolio Values
q1.vw.wgt <- subset(weights, date == "2017-01-01") #I'm not sure why author took the long way
q2.vw.wgt <- subset(weights, date == "2017-04-01")
q1.vw.wgt
## [1] date AAPL.mcap tot.mcap AMZN.wgt TSLA.wgt
## <0 rows> (or 0-length row.names)
q2.vw.wgt
## [1] date AAPL.mcap tot.mcap AMZN.wgt TSLA.wgt
## <0 rows> (or 0-length row.names)
Step 7: Calculate VW Portfolio Values for 1Q 2013
vw.q1 <- subset(vwport,
vwport$date >= as.Date("2017-01-01") &
vwport$date <= as.Date("2017-04-02"))
vw.q1[c(1:3, nrow(vw.q1)), ]
## date AMZN.Close TSLA.Close MSFT.Close AAPL.Close AMZN.ret
## 1 2017-01-03 753.67 216.99 62.58 116.15 NA
## 2 2017-01-04 757.18 226.99 62.30 116.02 1.004657
## 3 2017-01-05 780.45 226.75 62.30 116.61 1.030732
## 62 2017-03-31 886.54 278.30 65.86 143.66 1.011639
## TSLA.ret MSFT.ret AAPL.ret
## 1 NA NA NA
## 2 1.0460851 0.9955257 0.9988807
## 3 0.9989427 1.0000000 1.0050853
## 62 1.0013672 1.0022828 0.9981242
vw.q1 <- vw.q1[, c(1, 6:9)]
vw.q1[c(1:3, nrow(vw.q1)), ]
## date AMZN.ret TSLA.ret MSFT.ret AAPL.ret
## 1 2017-01-03 NA NA NA NA
## 2 2017-01-04 1.004657 1.0460851 0.9955257 0.9988807
## 3 2017-01-05 1.030732 0.9989427 1.0000000 1.0050853
## 62 2017-03-31 1.011639 1.0013672 1.0022828 0.9981242
names(vw.q1)[2:5] <- paste(c("AMZN", "TSLA", "MSFT", "AAPL"))
vw.q1[c(1:3, nrow(vw.q1)), ]
## date AMZN TSLA MSFT AAPL
## 1 2017-01-03 NA NA NA NA
## 2 2017-01-04 1.004657 1.0460851 0.9955257 0.9988807
## 3 2017-01-05 1.030732 0.9989427 1.0000000 1.0050853
## 62 2017-03-31 1.011639 1.0013672 1.0022828 0.9981242
vw.q1[1, 2:5] <- 1
vw.q1$AMZN <- cumprod(vw.q1$AMZN)
vw.q1$TSLA <- cumprod(vw.q1$TSLA)
vw.q1$MSFT <- cumprod(vw.q1$MSFT)
vw.q1$AAPL <- cumprod(vw.q1$AAPL)
vw.q1[c(1:3, nrow(vw.q1)), ]
## date AMZN TSLA MSFT AAPL
## 1 2017-01-03 1.000000 1.000000 1.0000000 1.0000000
## 2 2017-01-04 1.004657 1.046085 0.9955257 0.9988807
## 3 2017-01-05 1.035533 1.044979 0.9955257 1.0039603
## 62 2017-03-31 1.176297 1.282547 1.0587932 1.2422114
If you invest $100 in the equal weighted portfolio at the beginning of the period the gross return would have been 132.