# Date Range: April 1, 2014 to April 1, 2019
# Portfolio:
# Technology: NVDA, MSFT
# Financials: JPM, BAC
# Real Estate: AMT, PLD
# Load Required Libraries
library(xts)
## Loading required package: zoo
##
## Attaching package: 'zoo'
## The following objects are masked from 'package:base':
##
## as.Date, as.Date.numeric
library(quantmod)
## Loading required package: TTR
## Registered S3 method overwritten by 'quantmod':
## method from
## as.zoo.data.frame zoo
library(zoo)
# Create the Data Files
# Date range
start.date <- "2014-04-01"
end.date <- "2019-04-01"
# Download NVDA (Technology)
getSymbols("NVDA", from = start.date, to = end.date, src = "yahoo", auto.assign = TRUE)
## [1] "NVDA"
data.NVDA <- NVDA
names(data.NVDA) <- paste(c("NVDA.Open","NVDA.High","NVDA.Low",
"NVDA.Close","NVDA.Volume","NVDA.Adjusted"))
# Download MSFT (Technology)
getSymbols("MSFT", from = start.date, to = end.date, src = "yahoo", auto.assign = TRUE)
## [1] "MSFT"
data.MSFT <- MSFT
names(data.MSFT) <- paste(c("MSFT.Open","MSFT.High","MSFT.Low",
"MSFT.Close","MSFT.Volume","MSFT.Adjusted"))
# Download JPM (Financials)
getSymbols("JPM", from = start.date, to = end.date, src = "yahoo", auto.assign = TRUE)
## [1] "JPM"
data.JPM <- JPM
names(data.JPM) <- paste(c("JPM.Open","JPM.High","JPM.Low",
"JPM.Close","JPM.Volume","JPM.Adjusted"))
# Download BAC (Financials)
getSymbols("BAC", from = start.date, to = end.date, src = "yahoo", auto.assign = TRUE)
## [1] "BAC"
data.BAC <- BAC
names(data.BAC) <- paste(c("BAC.Open","BAC.High","BAC.Low",
"BAC.Close","BAC.Volume","BAC.Adjusted"))
# Download AMT (Real Estate)
getSymbols("AMT", from = start.date, to = end.date, src = "yahoo", auto.assign = TRUE)
## [1] "AMT"
data.AMT <- AMT
names(data.AMT) <- paste(c("AMT.Open","AMT.High","AMT.Low",
"AMT.Close","AMT.Volume","AMT.Adjusted"))
#Download PLD (Real Estate)
getSymbols("PLD", from = start.date, to = end.date, src = "yahoo", auto.assign = TRUE)
## [1] "PLD"
data.PLD <- PLD
names(data.PLD) <- paste(c("PLD.Open","PLD.High","PLD.Low",
"PLD.Close","PLD.Volume","PLD.Adjusted"))
# Plot the Data for Each Security to Check for Missing Data
par(mfrow = c(3, 2))
plot(data.NVDA$NVDA.Close, main = "NVDA Close Price", xlab = "Date", ylab = "Price ($)")
plot(data.MSFT$MSFT.Close, main = "MSFT Close Price", xlab = "Date", ylab = "Price ($)")
plot(data.JPM$JPM.Close, main = "JPM Close Price", xlab = "Date", ylab = "Price ($)")
plot(data.BAC$BAC.Close, main = "BAC Close Price", xlab = "Date", ylab = "Price ($)")
plot(data.AMT$AMT.Close, main = "AMT Close Price", xlab = "Date", ylab = "Price ($)")
plot(data.PLD$PLD.Close, main = "PLD Close Price", xlab = "Date", ylab = "Price ($)")

par(mfrow = c(1, 1))
# Confirm no missing data
cat("Missing values per stock:\n")
## Missing values per stock:
cat("NVDA:", sum(is.na(data.NVDA)), "\n")
## NVDA: 0
cat("MSFT:", sum(is.na(data.MSFT)), "\n")
## MSFT: 0
cat("JPM:", sum(is.na(data.JPM)), "\n")
## JPM: 0
cat("BAC:", sum(is.na(data.BAC)), "\n")
## BAC: 0
cat("AMT:", sum(is.na(data.AMT)), "\n")
## AMT: 0
cat("PLD:", sum(is.na(data.PLD)), "\n")
## PLD: 0
# Check dimensions
cat("\nDimensions (rows x cols):\n")
##
## Dimensions (rows x cols):
cat("NVDA:", dim(data.NVDA), "\n")
## NVDA: 1258 6
cat("MSFT:", dim(data.MSFT), "\n")
## MSFT: 1258 6
cat("JPM:", dim(data.JPM), "\n")
## JPM: 1258 6
cat("BAC:", dim(data.BAC), "\n")
## BAC: 1258 6
cat("AMT:", dim(data.AMT), "\n")
## AMT: 1258 6
cat("PLD:", dim(data.PLD), "\n")
## PLD: 1258 6
# Plot Candlestick Charts (Weekly) - One Stock Per Sector
# Technology: NVDA weekly
wk.NVDA <- to.weekly(data.NVDA)
NVDA.ohlc <- as.quantmod.OHLC(wk.NVDA[, -5],
col.names = c("Open","High","Low","Close","Volume"))
chartSeries(NVDA.ohlc, theme = "white.mono",
name = "NVDA Weekly OHLC (Apr 2014 - Apr 2019)")

# Financials: JPM weekly
wk.JPM <- to.weekly(data.JPM)
JPM.ohlc <- as.quantmod.OHLC(wk.JPM[, -5],
col.names = c("Open","High","Low","Close","Volume"))
chartSeries(JPM.ohlc, theme = "white.mono",
name = "JPM Weekly OHLC (Apr 2014 - Apr 2019)")

# Real Estate: AMT weekly
wk.AMT <- to.weekly(data.AMT)
AMT.ohlc <- as.quantmod.OHLC(wk.AMT[, -5],
col.names = c("Open","High","Low","Close","Volume"))
chartSeries(AMT.ohlc, theme = "white.mono",
name = "AMT Weekly OHLC (Apr 2014 - Apr 2019)")

# Capital Gains by Sector - Third Year Only (Apr 2016 - Mar 2017)
yr3.start <- "2016-04-01"
yr3.end <- "2017-03-31"
# Extract and merge sector close prices
Close.NVDA <- subset(data.NVDA$NVDA.Close, index(data.NVDA) >= yr3.start & index(data.NVDA) <= yr3.end)
Close.MSFT <- subset(data.MSFT$MSFT.Close, index(data.MSFT) >= yr3.start & index(data.MSFT) <= yr3.end)
Close.JPM <- subset(data.JPM$JPM.Close, index(data.JPM) >= yr3.start & index(data.JPM) <= yr3.end)
Close.BAC <- subset(data.BAC$BAC.Close, index(data.BAC) >= yr3.start & index(data.BAC) <= yr3.end)
Close.AMT <- subset(data.AMT$AMT.Close, index(data.AMT) >= yr3.start & index(data.AMT) <= yr3.end)
Close.PLD <- subset(data.PLD$PLD.Close, index(data.PLD) >= yr3.start & index(data.PLD) <= yr3.end)
# Average two stocks per sector
tech.merged <- merge(Close.NVDA, Close.MSFT, join = "inner")
fin.merged <- merge(Close.JPM, Close.BAC, join = "inner")
re.merged <- merge(Close.AMT, Close.PLD, join = "inner")
tech.avg <- xts(rowMeans(tech.merged), order.by = index(tech.merged))
fin.avg <- xts(rowMeans(fin.merged), order.by = index(fin.merged))
re.avg <- xts(rowMeans(re.merged), order.by = index(re.merged))
# Normalize to capital gain index (starting value = 1)
tech.idx <- tech.avg / as.numeric(tech.avg[1])
fin.idx <- fin.avg / as.numeric(fin.avg[1])
re.idx <- re.avg / as.numeric(re.avg[1])
# Align on common dates
all.idx <- merge(tech.idx, fin.idx, re.idx, join = "inner")
## Warning in merge.xts(tech.idx, fin.idx, re.idx, join = "inner"): 'join' only
## applicable to two object merges
names(all.idx) <- c("Technology","Financials","RealEstate")
multi.df <- data.frame(
date = as.Date(index(all.idx)),
Technology = as.numeric(all.idx$Technology),
Financials = as.numeric(all.idx$Financials),
RealEstate = as.numeric(all.idx$RealEstate)
)
# Plot capital gains by sector
y.range <- range(multi.df[, 2:4], na.rm = TRUE)
plot(x = multi.df$date,
y = multi.df$Technology,
type = "l",
col = "steelblue",
lwd = 2,
ylim = y.range,
xlab = "Date",
ylab = "Capital Gain (Indexed to 1.0)",
main = "Capital Gains by Sector - Third Year\n(April 2016 - March 2017)")
lines(x = multi.df$date,
y = multi.df$Financials,
col = "firebrick",
lwd = 2)
lines(x = multi.df$date,
y = multi.df$RealEstate,
col = "darkgreen",
lwd = 2)
abline(h = 1,
lty = 2,
col = "gray50")
legend("topleft",
legend = c("Technology (NVDA, MSFT)",
"Financials (JPM, BAC)",
"Real Estate (AMT, PLD)"),
col = c("steelblue","firebrick","darkgreen"),
lwd = 2,
lty = 1)

# Simple Moving Average - Fifth Year (Apr 2018 - Apr 2019)
# Sector: Technology | Stock: NVDA
# Calculate Rolling 50-Day and 200-Day Average Price
NVDA.sma <- data.NVDA$NVDA.Close
NVDA.sma$sma50 <- rollmeanr(NVDA.sma$NVDA.Close, k = 50)
NVDA.sma$sma200 <- rollmeanr(NVDA.sma$NVDA.Close, k = 200)
# Subset to the Fifth Year of the Data
yr5.start <- "2018-04-01"
yr5.end <- "2019-04-01"
NVDA.sma5 <- subset(NVDA.sma,
index(NVDA.sma) >= yr5.start & index(NVDA.sma) <= yr5.end)
# Plot the Simple Moving Average
y.range <- range(NVDA.sma5, na.rm = TRUE)
plot(x = index(NVDA.sma5),
y = NVDA.sma5$NVDA.Close,
type = "l",
ylim = y.range,
xlab = "Date",
ylab = "Price ($)",
col = "black",
lwd = 2,
main = "NVDA - Simple Moving Average\nApril 2018 - April 2019")
lines(x = index(NVDA.sma5),
y = NVDA.sma5$sma50,
col = "steelblue",
lwd = 1.5)
lines(x = index(NVDA.sma5),
y = NVDA.sma5$sma200,
col = "firebrick",
lty = 2,
lwd = 1.5)
legend("topright",
legend = c("NVDA Price","50-Day SMA","200-Day SMA"),
col = c("black","steelblue","firebrick"),
lty = c(1,1,2),
lwd = c(2,1.5,1.5))

# Bollinger Bands Plot - Fifth Year (Apr 2018 - Apr 2019)
# Sector: Technology | Stock: NVDA
# Obtain Closing Price and Calculate Rolling 20-Day Mean and Std. Dev.
NVDA.bb <- data.NVDA$NVDA.Close
NVDA.bb$avg <- rollmeanr(NVDA.bb$NVDA.Close, k = 20)
NVDA.bb$sd <- rollapply(NVDA.bb$NVDA.Close, width = 20, FUN = sd, fill = NA)
# Subset to the Fifth Year
NVDA.bb5 <- subset(NVDA.bb,
index(NVDA.bb) >= yr5.start & index(NVDA.bb) <= yr5.end)
# Calculate Bollinger Bands
NVDA.bb5$sd2up <- NVDA.bb5$avg + 2 * NVDA.bb5$sd
NVDA.bb5$sd2down <- NVDA.bb5$avg - 2 * NVDA.bb5$sd
# Plot the Bollinger Bands
y.range <- range(NVDA.bb5[, -3], na.rm = TRUE)
plot(x = index(NVDA.bb5),
y = NVDA.bb5$NVDA.Close,
type = "l",
ylim = y.range,
xlab = "Date",
ylab = "Price ($)",
lwd = 3,
main = "NVDA - Bollinger Bands (20 Days, 2 Std. Dev.)\nApril 2018 - April 2019")
lines(x = index(NVDA.bb5),
y = NVDA.bb5$avg,
lty = 2)
lines(x = index(NVDA.bb5),
y = NVDA.bb5$sd2up,
col = "gray40")
lines(x = index(NVDA.bb5),
y = NVDA.bb5$sd2down,
col = "gray40")
legend("topright",
legend = c("NVDA Price","20-Day Moving Average","Upper Band (+2 SD)","Lower Band (-2 SD)"),
lty = c(1,2,1,1),
lwd = c(3,1,1,1),
col = c("black","black","gray40","gray40"))

# Portfolio Value Chart - Entire 5-Year Dataset (Apr 2014 - Apr 2019)
# Use Adjusted Closing Prices for All Six Stocks
port.merged <- merge(data.NVDA$NVDA.Adjusted,
data.MSFT$MSFT.Adjusted,
data.JPM$JPM.Adjusted,
data.BAC$BAC.Adjusted,
data.AMT$AMT.Adjusted,
data.PLD$PLD.Adjusted,
join = "inner")
## Warning in merge.xts(data.NVDA$NVDA.Adjusted, data.MSFT$MSFT.Adjusted,
## data.JPM$JPM.Adjusted, : 'join' only applicable to two object merges
port.merged <- na.omit(port.merged)
# Normalize each stock to its first value (equal-weighted $1 initial investment)
for (i in 1:6) {
port.merged[, i] <- port.merged[, i] / as.numeric(port.merged[1, i])
}
# Portfolio value = average of 6 normalized stock values
port.value <- xts(rowMeans(port.merged), order.by = index(port.merged))
port.df <- data.frame(
date = as.Date(index(port.value)),
portfolio = as.numeric(port.value)
)
# Plot the Portfolio Value
plot(x = port.df$date,
y = port.df$portfolio,
type = "l",
col = "darkblue",
lwd = 2,
xlab = "Date",
ylab = "Portfolio Value (Indexed to $1.00)",
main = "Equal-Weighted Portfolio Value\n6 Stocks Across 3 Sectors (April 2014 - April 2019)")
abline(h = 1,
lty = 2,
col = "gray50")
legend("topleft",
legend = c("Portfolio Value","Initial Investment ($1)"),
col = c("darkblue","gray50"),
lty = c(1,2),
lwd = c(2,1))
