# Load packages
library(tidyverse)
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## âś” dplyr     1.2.1     âś” readr     2.2.0
## âś” forcats   1.0.1     âś” stringr   1.6.0
## âś” ggplot2   4.0.3     âś” tibble    3.3.1
## âś” lubridate 1.9.5     âś” tidyr     1.3.2
## âś” purrr     1.2.2     
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## âś– dplyr::filter() masks stats::filter()
## âś– dplyr::lag()    masks stats::lag()
## ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
library(tidyquant)
## Registered S3 method overwritten by 'quantmod':
##   method            from
##   as.zoo.data.frame zoo 
## ── Attaching core tidyquant packages ─────────────────────── tidyquant 1.0.12 ──
## âś” PerformanceAnalytics 2.1.0      âś” TTR                  0.24.4
## ✔ quantmod             0.4.29     ✔ xts                  0.14.3── Conflicts ────────────────────────────────────────── tidyquant_conflicts() ──
## âś– zoo::as.Date()                 masks base::as.Date()
## âś– zoo::as.Date.numeric()         masks base::as.Date.numeric()
## âś– dplyr::filter()                masks stats::filter()
## âś– xts::first()                   masks dplyr::first()
## âś– dplyr::lag()                   masks stats::lag()
## âś– xts::last()                    masks dplyr::last()
## âś– PerformanceAnalytics::legend() masks graphics::legend()
## âś– quantmod::summary()            masks base::summary()
## ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors

Goal

  1. Import stock prices
  2. Convert prices to returns
  3. Make plot

1 Import stock prices

# Choose stocks
symbols <- c("SPY", "EFA", "IJS", "EEM", "AGG")

prices <- tq_get(
  x = symbols,
  get = "stock.prices",
  from = "2012-01-01",
  to = "2017-01-01"
)

prices
## # A tibble: 6,290 Ă— 8
##    symbol date        open  high   low close    volume adjusted
##    <chr>  <date>     <dbl> <dbl> <dbl> <dbl>     <dbl>    <dbl>
##  1 SPY    2012-01-03  128.  128.  127.  128. 193697900     98.8
##  2 SPY    2012-01-04  127.  128.  127.  128. 127186500     99.0
##  3 SPY    2012-01-05  127.  128.  126.  128. 173895000     99.2
##  4 SPY    2012-01-06  128.  128.  127.  128. 148050000     99.0
##  5 SPY    2012-01-09  128   128.  127.  128.  99530200     99.2
##  6 SPY    2012-01-10  129.  130.  129.  129. 115282000    100. 
##  7 SPY    2012-01-11  129.  129.  129.  129. 111540700    100. 
##  8 SPY    2012-01-12  130.  130.  129.  130. 118983700    100. 
##  9 SPY    2012-01-13  129.  129.  128.  129. 179836200     99.9
## 10 SPY    2012-01-17  130.  130.  129.  129. 132209200    100. 
## # ℹ 6,280 more rows

2 Convert prices to returns

asset_returns_tbl <- prices %>%
  group_by(symbol) %>%
  tq_transmute(
    select = adjusted,
    mutate_fun = periodReturn,
    period = "monthly",
    type = "log"
  ) %>%
  ungroup() %>%
  set_names(c("asset", "date", "returns"))

asset_returns_tbl
## # A tibble: 300 Ă— 3
##    asset date        returns
##    <chr> <date>        <dbl>
##  1 SPY   2012-01-31  0.0295 
##  2 SPY   2012-02-29  0.0425 
##  3 SPY   2012-03-30  0.0317 
##  4 SPY   2012-04-30 -0.00670
##  5 SPY   2012-05-31 -0.0619 
##  6 SPY   2012-06-29  0.0398 
##  7 SPY   2012-07-31  0.0118 
##  8 SPY   2012-08-31  0.0247 
##  9 SPY   2012-09-28  0.0250 
## 10 SPY   2012-10-31 -0.0184 
## # ℹ 290 more rows

3 Make plot

asset_returns_tbl %>%
  ggplot(aes(x = returns)) +
  geom_density(aes(color = asset), alpha = 1) +
  geom_histogram(
    aes(fill = asset),
    show.legend = FALSE,
    alpha = 0.3,
    binwidth = 0.01
  ) +
  facet_wrap(~asset, ncol = 1) +
  labs(
    title = "Distribution of Monthly Returns, 2012-2016",
    y = "Frequency",
    x = "Rate of Returns",
    caption = "A typical monthly return is higher for SPY and IJS than for AGG, EEM, and EFA."
  )