# 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))