S&P 500 Stock Analysis

Column

S&P 500 Stock Risk vs Growth

Straw Broom Charts of 4 Selected Stocks

Column

Zoom In: S&P 500 Stock Risk vs Growth

S&P 500 Distribution of Securities by Sector

AVGO: Broadcom

Column

AVGO: Broadcom Candlestick Chart

AVGO: Daily log(Returns) Distribution

Confidence Intervals for the Stock Price

0.5% 2.5% 25% 50% 75% 97.5% 99.5%
164.01 176.21 260.28 320.5 400.83 546.66 751.54

Column

Candlestick with Bollinger Bands for the past 25 weeks

250 Monte-Carlo Simulations for Prices Over 252 Trading Days

Compound Annual Growth Rate (CAGR) Simulation

34.48%

ABMD: ABIOMED Inc

Column

ABMD: ABIOMED Inc Candlestick Chart

ABMD: Daily log(Returns) Distribution

Confidence Intervals for the Stock Price

0.5% 2.5% 25% 50% 75% 97.5% 99.5%
194.85 216.18 380.22 513.88 710.33 1113.09 1764.72

Column

Candlestick with Bollinger Bands for the past 25 weeks

250 Monte-Carlo Simulations for Prices Over 252 Trading Days

Compound Annual Growth Rate (CAGR) Simulation

32.83%

ROST: Ross Stores

Column

ROST: Ross Stores Candlestick Chart

ROST: Daily log(Returns) Distribution

Confidence Intervals for the Stock Price

0.5% 2.5% 25% 50% 75% 97.5% 99.5%
74.46 78.98 108.83 129.13 155.19 200.27 260.14

Column

Candlestick with Bollinger Bands for the past 25 weeks

250 Monte-Carlo Simulations for Prices Over 252 Trading Days

Compound Annual Growth Rate (CAGR) Simulation

31.34%

ALGN: Align Technology

Column

ALGN: Ross Stores Candlestick Chart

ALGN: Daily log(Returns) Distribution

Confidence Intervals for the Stock Price

0.5% 2.5% 25% 50% 75% 97.5% 99.5%
179.59 197.5 331.23 436.44 587.04 885.71 1350.68

Column

Candlestick with Bollinger Bands for the past 25 weeks

250 Monte-Carlo Simulations for Prices Over 252 Trading Days

Compound Annual Growth Rate (CAGR) Simulation

30.30%
---
title: "Dashboard Lab"
author: "Qian Yao, Fuyan Li"
output: 
  flexdashboard::flex_dashboard:
    orientation: columns
    vertical_layout: scroll
    source_code: embed
---

```{r setup, include=FALSE}
library(flexdashboard)
library(quantmod)
library(tidyverse)
library(rvest)
library(lubridate)
library(tidyquant)
library(dygraphs)
library(formattable)
startDate = "2008-01-01"
endDate = "2018-10-17"

## web scraping: get the list of S&P500 stocks
# Web-scrape SP500 stock list
sp_500 <- read_html("https://en.wikipedia.org/wiki/List_of_S%26P_500_companies") %>%
  html_node("table.wikitable") %>%
  html_table() %>%
  select(`Ticker symbol`, Security, `GICS Sector`, `GICS Sub Industry`) %>% 
  as_tibble()
# Format names
names(sp_500) <- sp_500 %>% 
  names() %>% 
  str_to_lower() %>% 
  make.names()

sp_500$ticker.symbol <- gsub('[.]', '-', sp_500$ticker.symbol)

############ creating functions to map
get_stock_prices <- function(ticker, return_format = "tibble", ...) {
  # Get stock prices
  stock_prices_xts <- getSymbols(Symbols = ticker, auto.assign = FALSE, ...)
  # Rename
  names(stock_prices_xts) <- c("Open", "High", "Low", "Close", "Volume", "Adjusted")
  # Return in xts format if tibble is not specified
  if (return_format == "tibble") {
    stock_prices <- stock_prices_xts %>%
      as_tibble() %>%
      rownames_to_column(var = "Date") %>%
      mutate(Date = ymd(Date))
  } else {
    stock_prices <- stock_prices_xts
  }
  stock_prices
}


get_log_returns <- function(x, return_format = "tibble", period = 'daily', ...) {
  # Convert tibble to xts
  if (!is.xts(x)) {
    x <- xts(x[,-1], order.by = x$Date)
  }
  # Get log returns
  log_returns_xts <- periodReturn(x = x$Adjusted, type = 'log', period = period, ...)
  # Rename
  names(log_returns_xts) <- "Log.Returns"
  # Return in xts format if tibble is not specified
  if (return_format == "tibble") {
    log_returns <- log_returns_xts %>%
      as_tibble() %>%
      rownames_to_column(var = "Date") %>%
      mutate(Date = ymd(Date))
  } else {
    log_returns <- log_returns_xts
  }
  log_returns
}


sp_500_detail <- sp_500 %>% filter(!ticker.symbol %in% c('BHF', 'DXC', 'JEF', 'UA')) %>%
  mutate(
    stock.prices = map(ticker.symbol, 
                       function(.x) get_stock_prices(.x, 
                                                     return_format = "tibble",
                                                     from = startDate,
                                                     to = endDate)
    ),
    log.returns  = map(stock.prices, 
                       function(.x) get_log_returns(.x, return_format = "tibble")),
    mean.log.returns = map_dbl(log.returns, ~ mean(.$Log.Returns)),
    sd.log.returns   = map_dbl(log.returns, ~ sd(.$Log.Returns)),
    n.trade.days = map_dbl(stock.prices, ~ sum(complete.cases(.)))
  ) 

sp_500_short <- sp_500_detail %>% 
  select(ticker.symbol, mean.log.returns:n.trade.days)
```

S&P 500 Stock Analysis
=======================================================================

Column {.sidebar data-width=200 data-padding=10}
-----------------------------------------------------------------------

- We took S&P 500 stocks and compared every one of them by looking at the mean and the standard deviation of the log returns: The mean characterizes the average growth or return while the standard deviation characterizes the volatility or risk.
- From the zoom-in plot, we can see that a small number of stocks have a combination of high mean and low standard deviation log returns. So we picked top 4 stocks for further analysis. Also these 4 stocks follow a diversification strategy, which minimize the risks.
- Comparing the top 4 stocks, ABMD had the highest historical price while ROST had the lowest historical price. AVGO had a small decline since 2018.

Column {data-width=450}
-----------------------------------------------------------------------

### S&P 500 Stock Risk vs Growth

```{r}
sp_500_short %>% 
  select(ticker.symbol, mean.log.returns:n.trade.days) %>%
  ggplot(aes(sd.log.returns, mean.log.returns, color = n.trade.days)) + 
    geom_point(shape=16, aes(size = n.trade.days), alpha = .4) + 
    theme_minimal() + 
    scale_color_gradient(low = "#0091ff", high = "#f0650e") + 
    scale_alpha(range=c(.25, .6)) + 
  labs(x = "Risk (StDev Log Returns)", y = "Growth (Mean Log Returns)", title = "") 
```

### Straw Broom Charts of 4 Selected Stocks

```{r}
AVGO <- tq_get("AVGO", get = "stock.prices", from = startDate, to = endDate)
AVGO_xts <- xts(AVGO[,-1], order.by = as.Date(AVGO$date))
ABMD <- tq_get("ABMD", get = "stock.prices", from = startDate, to = endDate)
ABMD_xts <- xts(ABMD[,-1], order.by = as.Date(ABMD$date))
ROST <- tq_get("ROST", get = "stock.prices", from = startDate, to = endDate)
ROST_xts <- xts(ROST[,-1], order.by = as.Date(ROST$date))
ALGN <- tq_get("ALGN", get = "stock.prices", from = startDate, to = endDate)
ALGN_xts <- xts(ALGN[,-1], order.by = as.Date(ALGN$date))
tickers <- c('AVGO_xts', 'ABMD_xts', 'ROST_xts', 'ALGN_xts')
closePrices <- do.call(merge, lapply(tickers, function(x) Cl(get(x))))
names(closePrices) <- c('AVGO.Close', 'ABMD.Close', 'ROST.Close', 'ALGN.Close')
dygraph(closePrices, group = "stock") %>%
  dyRangeSelector()
```


Column {data-width=350}
-----------------------------------------------------------------------

### Zoom In: S&P 500 Stock Risk vs Growth

```{r}
sp_500_short %>% 
  select(ticker.symbol, mean.log.returns:n.trade.days) %>%
  ggplot(aes(sd.log.returns, mean.log.returns, color = n.trade.days)) + 
  geom_point(shape=16, aes(size = n.trade.days), alpha = .4) + 
  theme_minimal() + 
  scale_color_gradient(low = "#0091ff", high = "#f0650e") + 
  scale_alpha(range=c(.25, .6)) + 
  coord_cartesian(xlim = c(0.01, 0.033), ylim = c(0.001, 0.00132)) + 
  geom_text(aes(label=ticker.symbol), hjust = 0, vjust = 0) + 
  geom_rect(mapping = aes(xmin = 0.016, xmax = 0.0328, ymin = 0.00109, ymax = 0.00125, fill = factor(1)), alpha = 0) + 
  guides(fill=FALSE) +   # remove legend for a particular aesthetic (fill)
  labs(x = "Risk (StDev Log Returns)", y = "Growth (Mean Log Returns)") 
```

### S&P 500 Distribution of Securities by Sector

```{r}
sp_500 %>%
  # Summarise data by frequency
  group_by(gics.sector) %>%
  summarise(count = n()) %>%
  # Visualize 
  ggplot(aes(x = gics.sector %>% fct_reorder(count),
             y = count
            )) + 
  geom_bar(stat = "identity") +
  geom_text(aes(label = count), size = 3, nudge_y = 4, nudge_x = .1) + 
  scale_y_continuous(limits = c(0,80)) +
  xlab(label = "GICS Sector") +
  theme(plot.title = element_text(size = 16)) + 
  coord_flip() 
```

AVGO: Broadcom
=======================================================================

Column {.sidebar data-width=200 data-padding=10}
-----------------------------------------------------------------------

- Candlestick chart shows that AVGO had a increasing trend but a slightly decline since Jan 2018. Using a 20-day simple moving average with 2 standard deviations, we can see that there were two periods, one in July and one in September, that had higher volatility.
- Applying the log-transformation, we can visually see that the daily returns are approximately normally distributed. After conducting 250 Monte Carlo simulations for one year of trading days simulations (N = 252), the resulting 95% confidence intervals for the stock price at the end of the simulation is between $176.21 and $546.66, with a median estimated price of $320.5.
- CAGR is 34.48% given the simulation.

Column {data-width=400}
-----------------------------------------------------------------------

### AVGO: Broadcom Candlestick Chart

```{r}
AVGO <- tq_get("AVGO", get = "stock.prices", from = startDate, to = endDate)
AVGO_xts <- xts(AVGO[,-1], order.by = as.Date(AVGO$date))

AVGO_log_returns <- AVGO_xts %>%
  Ad() %>%
  dailyReturn(type = "log")
names(AVGO_log_returns) <- "AVGO.Log.Returns"

N <- 252 # Number of Stock Price Simulations
M <- 250  # Number of Monte Carlo Simulations   
mu <- mean(AVGO_log_returns, na.rm = TRUE)
sigma <- sd(AVGO_log_returns, na.rm = TRUE)
day <- 1:N
price_init <- AVGO_xts$adjusted[[nrow(AVGO_xts$adjusted)]]
# Simulate prices
set.seed(123)
monte_carlo_mat <- matrix(nrow = N, ncol = M)
for (j in 1:M) {
  monte_carlo_mat[[1, j]] <- price_init
  for(i in 2:N) {
    monte_carlo_mat[[i, j]] <- monte_carlo_mat[[i - 1, j]] * exp(rnorm(1, mu, sigma))
  }
}
# Format and organize data frame
price_sim <- cbind(day, monte_carlo_mat) %>% as_tibble() 
nm <- str_c("Sim.", seq(1, M))
nm <- c("Day", nm)
names(price_sim) <- nm
price_sim <- price_sim %>%
  gather(key = "Simulation", value = "Stock.Price", -(Day))

dygraph(AVGO_xts[,1:4]) %>% dyCandlestick()
```

### AVGO: Daily log(Returns) Distribution

```{r}

AVGO_log_returns %>%    
  ggplot(aes(x = AVGO.Log.Returns)) + 
  geom_histogram(bins = 100) + 
  geom_density() +
  geom_rug(alpha = 0.5) + 
  labs(title = "", y = "Count")
```

### Confidence Intervals for the Stock Price

```{r}
end_stock_prices <- price_sim %>% filter(Day == max(Day))
probs <- c(.005, .025, .25, .5, .75, .975, .995)
dist_end_stock_prices <- quantile(end_stock_prices$Stock.Price, probs = probs)
dist_table <- dist_end_stock_prices %>% round(2) %>% t() %>% as.data.frame()
knitr::kable(dist_table)   # put it in a table
```


Column {data-width=400}
-----------------------------------------------------------------------

### Candlestick with Bollinger Bands for the past 25 weeks

```{r}
week_num = 25      # input
end <- ymd(Sys.Date())
start <- end - weeks(week_num)
AVGO %>%
  ggplot(aes(x = date, y = close)) +
  geom_candlestick(aes(open = open, close = close, high = high, low = low)) + 
  geom_bbands(aes(high = high, low = low, close = close),
              ma_fun = SMA, n = 20, sd = 2, size = 1) + 
  labs(title = "",
       x = "", y = "Closing Price") +
  coord_x_date(xlim = c(start, end),
               ylim = c(180, 300))
```

### 250 Monte-Carlo Simulations for Prices Over 252 Trading Days

```{r}
# Visualize simulation
price_sim %>%
  ggplot(aes(x = Day, y = Stock.Price, Group = Simulation)) + 
  geom_line(alpha = 0.1)
```

### Compound Annual Growth Rate (CAGR) Simulation

```{r}
# Inputs
N_hist          <- nrow(AVGO_xts) / 252
p_start_hist    <- AVGO_xts$adjusted[[1]]
p_end_hist      <- AVGO_xts$adjusted[[nrow(AVGO_xts)]]
N_sim           <- N / 252
p_start_sim     <- p_end_hist
p_end_sim       <- dist_end_stock_prices[[4]]
# Compound annual growth rate (CAGR) calculations
CAGR_historical <- (p_end_hist / p_start_hist) ^ (1 / N_hist) - 1   # 35.72%
CAGR_sim        <- (p_end_sim / p_start_sim) ^ (1 / N_sim) - 1    # 34.19%

# valueBox(formattable::percent(CAGR_historical,2), icon = "fa-pencil")
valueBox(formattable::percent(CAGR_sim, 2), icon = "fa-pencil")
```


ABMD: ABIOMED Inc
=======================================================================

Column {.sidebar data-width=200 data-padding=10}
-----------------------------------------------------------------------

- Candlestick chart shows that ABMD had a slightly volatility since June 2018. Using a 20-day simple moving average with 2 standard deviations, we can see that there were one period in May that had higher volatility.
- Applying the log-transformation, we can visually see that the daily returns are approximately normally distributed. After conducting 250 Monte Carlo simulations for one year of trading days simulations (N = 252), the resulting 95% confidence intervals for the stock price at the end of the simulation is between $216.18 and $1113.09, with a median estimated price of $513.88.
- CAGR is 32.83% given the simulation.

Column {data-width=400}
-----------------------------------------------------------------------

### ABMD: ABIOMED Inc Candlestick Chart

```{r}
ABMD <- tq_get("ABMD", get = "stock.prices", from = startDate, to = endDate)
ABMD_xts <- xts(ABMD[,-1], order.by = as.Date(ABMD$date))

ABMD_log_returns <- ABMD_xts %>%
  Ad() %>%
  dailyReturn(type = "log")
names(ABMD_log_returns) <- "ABMD.Log.Returns"

N <- 252 # Number of Stock Price Simulations
M <- 250  # Number of Monte Carlo Simulations   
mu <- mean(ABMD_log_returns, na.rm = TRUE)
sigma <- sd(ABMD_log_returns, na.rm = TRUE)
day <- 1:N
price_init <- ABMD_xts$adjusted[[nrow(ABMD_xts$adjusted)]]
# Simulate prices
set.seed(123)
monte_carlo_mat <- matrix(nrow = N, ncol = M)
for (j in 1:M) {
  monte_carlo_mat[[1, j]] <- price_init
  for(i in 2:N) {
    monte_carlo_mat[[i, j]] <- monte_carlo_mat[[i - 1, j]] * exp(rnorm(1, mu, sigma))
  }
}
# Format and organize data frame
price_sim <- cbind(day, monte_carlo_mat) %>% as_tibble() 
nm <- str_c("Sim.", seq(1, M))
nm <- c("Day", nm)
names(price_sim) <- nm
price_sim <- price_sim %>%
  gather(key = "Simulation", value = "Stock.Price", -(Day))

dygraph(ABMD_xts[,1:4]) %>% dyCandlestick()
```

### ABMD: Daily log(Returns) Distribution

```{r}
ABMD_log_returns %>%    
  ggplot(aes(x = ABMD.Log.Returns)) + 
  geom_histogram(bins = 100) + 
  geom_density() +
  geom_rug(alpha = 0.5) + 
  labs(title = "", y = "Count")
```

### Confidence Intervals for the Stock Price

```{r}
end_stock_prices <- price_sim %>% filter(Day == max(Day))
probs <- c(.005, .025, .25, .5, .75, .975, .995)
dist_end_stock_prices <- quantile(end_stock_prices$Stock.Price, probs = probs)
dist_table <- dist_end_stock_prices %>% round(2) %>% t() %>% as.data.frame()
knitr::kable(dist_table)   # put it in a table
```


Column {data-width=400}
-----------------------------------------------------------------------

### Candlestick with Bollinger Bands for the past 25 weeks

```{r}
week_num = 25      # input
end <- ymd(Sys.Date())
start <- end - weeks(week_num)
ABMD %>%
  ggplot(aes(x = date, y = close)) +
  geom_candlestick(aes(open = open, close = close, high = high, low = low)) + 
  geom_bbands(aes(high = high, low = low, close = close),
              ma_fun = SMA, n = 20, sd = 2, size = 1) + 
  labs(title = "",
       x = "", y = "Closing Price") +
  coord_x_date(xlim = c(start, end),
               ylim = c(270, 500))
```

### 250 Monte-Carlo Simulations for Prices Over 252 Trading Days

```{r}
# Visualize simulation
price_sim %>%
  ggplot(aes(x = Day, y = Stock.Price, Group = Simulation)) + 
  geom_line(alpha = 0.1)
```

### Compound Annual Growth Rate (CAGR) Simulation

```{r}
# Inputs
N_hist          <- nrow(ABMD_xts) / 252
p_start_hist    <- ABMD_xts$adjusted[[1]]
p_end_hist      <- ABMD_xts$adjusted[[nrow(ABMD_xts)]]
N_sim           <- N / 252
p_start_sim     <- p_end_hist
p_end_sim       <- dist_end_stock_prices[[4]]
# Compound annual growth rate (CAGR) calculations
CAGR_historical <- (p_end_hist / p_start_hist) ^ (1 / N_hist) - 1   # 34.92%
CAGR_sim        <- (p_end_sim / p_start_sim) ^ (1 / N_sim) - 1    # 32.79%

# valueBox(formattable::percent(CAGR_historical,2), icon = "fa-pencil")
valueBox(formattable::percent(CAGR_sim, 2), icon = "fa-pencil")
```


ROST: Ross Stores
=======================================================================

Column {.sidebar data-width=200 data-padding=10}
-----------------------------------------------------------------------

- Candlestick chart shows that ROST had a slightly volatility in H2 of 2017. Using a 20-day simple moving average with 2 standard deviations, we can see that there was no outstanding volatility.
- Applying the log-transformation, we can visually see that the daily returns are approximately normally distributed. After conducting 250 Monte Carlo simulations for one year of trading days simulations (N = 252), the resulting 95% confidence intervals for the stock price at the end of the simulation is between $78.98 and $200.27, with a median estimated price of $129.13.
- CAGR is 31.34% given the simulation.

Column {data-width=400}
-----------------------------------------------------------------------

### ROST: Ross Stores Candlestick Chart

```{r}
ROST <- tq_get("ROST", get = "stock.prices", from = startDate, to = endDate)
ROST_xts <- xts(ROST[,-1], order.by = as.Date(ROST$date))

ROST_log_returns <- ROST_xts %>%
  Ad() %>%
  dailyReturn(type = "log")
names(ROST_log_returns) <- "ROST.Log.Returns"

N <- 252 # Number of Stock Price Simulations
M <- 250  # Number of Monte Carlo Simulations   
mu <- mean(ROST_log_returns, na.rm = TRUE)
sigma <- sd(ROST_log_returns, na.rm = TRUE)
day <- 1:N
price_init <- ROST_xts$adjusted[[nrow(ROST_xts$adjusted)]]
# Simulate prices
set.seed(123)
monte_carlo_mat <- matrix(nrow = N, ncol = M)
for (j in 1:M) {
  monte_carlo_mat[[1, j]] <- price_init
  for(i in 2:N) {
    monte_carlo_mat[[i, j]] <- monte_carlo_mat[[i - 1, j]] * exp(rnorm(1, mu, sigma))
  }
}
# Format and organize data frame
price_sim <- cbind(day, monte_carlo_mat) %>% as_tibble() 
nm <- str_c("Sim.", seq(1, M))
nm <- c("Day", nm)
names(price_sim) <- nm
price_sim <- price_sim %>%
  gather(key = "Simulation", value = "Stock.Price", -(Day))

dygraph(ROST_xts[,1:4]) %>% dyCandlestick()
```

### ROST: Daily log(Returns) Distribution

```{r}
ROST_log_returns %>%    
  ggplot(aes(x = ROST.Log.Returns)) + 
  geom_histogram(bins = 100) + 
  geom_density() +
  geom_rug(alpha = 0.5) + 
  labs(title = "", y = "Count")
```

### Confidence Intervals for the Stock Price

```{r}
end_stock_prices <- price_sim %>% filter(Day == max(Day))
probs <- c(.005, .025, .25, .5, .75, .975, .995)
dist_end_stock_prices <- quantile(end_stock_prices$Stock.Price, probs = probs)
dist_table <- dist_end_stock_prices %>% round(2) %>% t() %>% as.data.frame()
knitr::kable(dist_table)   # put it in a table
```


Column {data-width=400}
-----------------------------------------------------------------------

### Candlestick with Bollinger Bands for the past 25 weeks

```{r}
week_num = 25      # input
end <- ymd(Sys.Date())
start <- end - weeks(week_num)
ROST %>%
  ggplot(aes(x = date, y = close)) +
  geom_candlestick(aes(open = open, close = close, high = high, low = low)) + 
  geom_bbands(aes(high = high, low = low, close = close),
              ma_fun = SMA, n = 20, sd = 2, size = 1) + 
  labs(title = "",
       x = "", y = "Closing Price") +
  coord_x_date(xlim = c(start, end),
               ylim = c(70, 105))
```

### 250 Monte-Carlo Simulations for Prices Over 252 Trading Days

```{r}
# Visualize simulation
price_sim %>%
  ggplot(aes(x = Day, y = Stock.Price, Group = Simulation)) + 
  geom_line(alpha = 0.1)
```

### Compound Annual Growth Rate (CAGR) Simulation

```{r}
# Inputs
N_hist          <- nrow(ROST_xts) / 252
p_start_hist    <- ROST_xts$adjusted[[1]]
p_end_hist      <- ROST_xts$adjusted[[nrow(ROST_xts)]]
N_sim           <- N / 252
p_start_sim     <- p_end_hist
p_end_sim       <- dist_end_stock_prices[[4]]
# Compound annual growth rate (CAGR) calculations
CAGR_historical <- (p_end_hist / p_start_hist) ^ (1 / N_hist) - 1   # 32.31%
CAGR_sim        <- (p_end_sim / p_start_sim) ^ (1 / N_sim) - 1    # 31.06%

# valueBox(formattable::percent(CAGR_historical,2), icon = "fa-pencil")
valueBox(formattable::percent(CAGR_sim, 2), icon = "fa-pencil")
```


ALGN: Align Technology
=======================================================================

Column {.sidebar data-width=200 data-padding=10}
-----------------------------------------------------------------------

- Candlestick chart shows that ALGN had a decline in Oct 2018. Using a 20-day simple moving average with 2 standard deviations, we can see that Oct has a large volatility.
- Applying the log-transformation, we can visually see that the daily returns are approximately normally distributed. After conducting 250 Monte Carlo simulations for one year of trading days simulations (N = 252), the resulting 95% confidence intervals for the stock price at the end of the simulation is between $197.5 and $885.71, with a median estimated price of $436.44.
- CAGR is 30.30% given the simulation.
- In conclusion, ROST and ABMD have less volatility than AVGO and ALGN. Comparing ROST and ABMD, ABMD has a higher CAGR than ROST, so we expect ABMD will produce the most short term gains.

Column {data-width=400}
-----------------------------------------------------------------------

### ALGN: Ross Stores Candlestick Chart

```{r}
ALGN <- tq_get("ALGN", get = "stock.prices", from = startDate, to = endDate)
ALGN_xts <- xts(ALGN[,-1], order.by = as.Date(ALGN$date))

ALGN_log_returns <- ALGN_xts %>%
  Ad() %>%
  dailyReturn(type = "log")
names(ALGN_log_returns) <- "ALGN.Log.Returns"

N <- 252 # Number of Stock Price Simulations
M <- 250  # Number of Monte Carlo Simulations   
mu <- mean(ALGN_log_returns, na.rm = TRUE)
sigma <- sd(ALGN_log_returns, na.rm = TRUE)
day <- 1:N
price_init <- ALGN_xts$adjusted[[nrow(ALGN_xts$adjusted)]]
# Simulate prices
set.seed(123)
monte_carlo_mat <- matrix(nrow = N, ncol = M)
for (j in 1:M) {
  monte_carlo_mat[[1, j]] <- price_init
  for(i in 2:N) {
    monte_carlo_mat[[i, j]] <- monte_carlo_mat[[i - 1, j]] * exp(rnorm(1, mu, sigma))
  }
}
# Format and organize data frame
price_sim <- cbind(day, monte_carlo_mat) %>% as_tibble() 
nm <- str_c("Sim.", seq(1, M))
nm <- c("Day", nm)
names(price_sim) <- nm
price_sim <- price_sim %>%
  gather(key = "Simulation", value = "Stock.Price", -(Day))

dygraph(ALGN_xts[,1:4]) %>% dyCandlestick()
```

### ALGN: Daily log(Returns) Distribution

```{r}
ALGN_log_returns %>%    
  ggplot(aes(x = ALGN.Log.Returns)) + 
  geom_histogram(bins = 100) + 
  geom_density() +
  geom_rug(alpha = 0.5) + 
  labs(title = "", y = "Count")
```

### Confidence Intervals for the Stock Price

```{r}
end_stock_prices <- price_sim %>% filter(Day == max(Day))
probs <- c(.005, .025, .25, .5, .75, .975, .995)
dist_end_stock_prices <- quantile(end_stock_prices$Stock.Price, probs = probs)
dist_table <- dist_end_stock_prices %>% round(2) %>% t() %>% as.data.frame()
knitr::kable(dist_table)   # put it in a table
```


Column {data-width=400}
-----------------------------------------------------------------------

### Candlestick with Bollinger Bands for the past 25 weeks

```{r}
week_num = 25      # input
end <- ymd(Sys.Date())
start <- end - weeks(week_num)
ALGN %>%
  ggplot(aes(x = date, y = close)) +
  geom_candlestick(aes(open = open, close = close, high = high, low = low)) + 
  geom_bbands(aes(high = high, low = low, close = close),
              ma_fun = SMA, n = 20, sd = 2, size = 1) + 
  labs(title = "",
       x = "", y = "Closing Price") +
  coord_x_date(xlim = c(start, end),
               ylim = c(200, 450))
```

### 250 Monte-Carlo Simulations for Prices Over 252 Trading Days

```{r}
# Visualize simulation
price_sim %>%
  ggplot(aes(x = Day, y = Stock.Price, Group = Simulation)) + 
  geom_line(alpha = 0.1)
```

### Compound Annual Growth Rate (CAGR) Simulation

```{r}
# Inputs
N_hist          <- nrow(ALGN_xts) / 252
p_start_hist    <- ALGN_xts$adjusted[[1]]
p_end_hist      <- ALGN_xts$adjusted[[nrow(ALGN_xts)]]
N_sim           <- N / 252
p_start_sim     <- p_end_hist
p_end_sim       <- dist_end_stock_prices[[4]]
# Compound annual growth rate (CAGR) calculations
CAGR_historical <- (p_end_hist / p_start_hist) ^ (1 / N_hist) - 1   # 31.97%
CAGR_sim        <- (p_end_sim / p_start_sim) ^ (1 / N_sim) - 1    # 30.06%

# valueBox(formattable::percent(CAGR_historical,2), icon = "fa-pencil")
valueBox(formattable::percent(CAGR_sim, 2), icon = "fa-pencil")
```