#Import Library
library(PerformanceAnalytics)
## Loading required package: xts
## Loading required package: zoo
##
## Attaching package: 'zoo'
## The following objects are masked from 'package:base':
##
## as.Date, as.Date.numeric
##
## Attaching package: 'PerformanceAnalytics'
## The following object is masked from 'package:graphics':
##
## legend
library(quantmod)
## Loading required package: TTR
## Registered S3 method overwritten by 'quantmod':
## method from
## as.zoo.data.frame zoo
library(ggplot2)
library(xts)
library(zoo)
library(dplyr)
##
## Attaching package: 'dplyr'
## The following objects are masked from 'package:xts':
##
## first, last
## The following objects are masked from 'package:stats':
##
## filter, lag
## The following objects are masked from 'package:base':
##
## intersect, setdiff, setequal, union
library(PortfolioAnalytics)
## Loading required package: foreach
library(tidyquant)
## Loading required package: lubridate
##
## Attaching package: 'lubridate'
## The following objects are masked from 'package:base':
##
## date, intersect, setdiff, union
## ══ Need to Learn tidyquant? ════════════════════════════════════════════════════
## Business Science offers a 1-hour course - Learning Lab #9: Performance Analysis & Portfolio Optimization with tidyquant!
## </> Learn more at: https://university.business-science.io/p/learning-labs-pro </>
library(tidyverse)
## ── Attaching packages ─────────────────────────────────────── tidyverse 1.3.1 ──
## ✓ tibble 3.1.6 ✓ purrr 0.3.4
## ✓ tidyr 1.1.4 ✓ stringr 1.4.0
## ✓ readr 2.1.1 ✓ forcats 0.5.1
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## x purrr::accumulate() masks foreach::accumulate()
## x lubridate::as.difftime() masks base::as.difftime()
## x lubridate::date() masks base::date()
## x dplyr::filter() masks stats::filter()
## x dplyr::first() masks xts::first()
## x lubridate::intersect() masks base::intersect()
## x dplyr::lag() masks stats::lag()
## x dplyr::last() masks xts::last()
## x lubridate::setdiff() masks base::setdiff()
## x lubridate::union() masks base::union()
## x purrr::when() masks foreach::when()
library(timetk)
library(tibbletime)
##
## Attaching package: 'tibbletime'
## The following object is masked from 'package:stats':
##
## filter
library(broom)
library(dygraphs)
symbols <- c("SPY","EFA", "IJS", "EEM","AGG")
prices <-
getSymbols(symbols, src = 'yahoo',
from = "2013-01-01",
to = "2017-12-31",
auto.assign = TRUE, warnings = FALSE) %>%
map(~Ad(get(.))) %>%
reduce(merge) %>%
`colnames<-`(symbols)
## 'getSymbols' currently uses auto.assign=TRUE by default, but will
## use auto.assign=FALSE in 0.5-0. You will still be able to use
## 'loadSymbols' to automatically load data. getOption("getSymbols.env")
## and getOption("getSymbols.auto.assign") will still be checked for
## alternate defaults.
##
## This message is shown once per session and may be disabled by setting
## options("getSymbols.warning4.0"=FALSE). See ?getSymbols for details.
prices_monthly <- to.monthly(prices, indexAt = "last", OHLC = FALSE)
asset_returns_xts <- na.omit(Return.calculate(prices_monthly, method = "log"))
w <- rep(1/length(symbols), length(symbols))
portfolio_returns_xts_rebalanced_monthly <-
Return.portfolio(asset_returns_xts, weights = w, rebalance_on = "months") %>%
`colnames<-`("returns")
asset_returns_long <-
prices %>%
to.monthly(indexAt = "last", OHLC = FALSE) %>%
tk_tbl(preserve_index = TRUE, rename_index = "date") %>%
gather(asset, returns, -date) %>%
group_by(asset) %>%
mutate(returns = (log(returns) - log(lag(returns)))) %>%
na.omit()
portfolio_returns_tq_rebalanced_monthly <-
asset_returns_long %>%
tq_portfolio(assets_col = asset,
returns_col = returns,
weights = w,
col_rename = "returns",
rebalance_on = "months")
spy_monthly_xts <-
getSymbols("SPY",
src = 'yahoo',
from = "2013-01-01",
to = "2017-12-31",
auto.assign = TRUE,
warnings = FALSE) %>%
map(~Ad(get(.))) %>%
reduce(merge) %>%
`colnames<-`("SPY") %>%
to.monthly(indexAt = "last", OHLC = FALSE)
market_returns_xts <-
Return.calculate(spy_monthly_xts, method = "log") %>%
na.omit()
market_returns_tidy <-
market_returns_xts %>%
tk_tbl(preserve_index = TRUE, rename_index = "date") %>%
na.omit() %>%
select(date, returns = SPY)
head(market_returns_tidy)
portfolio_returns_tq_rebalanced_monthly %>%
mutate(market_returns = market_returns_tidy$returns) %>%
head()
cov(portfolio_returns_xts_rebalanced_monthly,market_returns_tidy$returns)/var(market_returns_tidy$returns)
## [,1]
## returns 0.8027526
returns <- merge.xts(asset_returns_xts$EFA, asset_returns_xts$IJS, asset_returns_xts$EEM, asset_returns_xts$AGG, asset_returns_xts$SPY)
colnames(returns) <- c("EFA", "IJS", "EEM", "AGG", "SP500")
dygraph(returns, main = "Developed-market securities in Europe vs. Small-Cap 600 vs. Emerging Markets vs. Aggregate Bond vs. S&P 500") %>%
dyAxis("y", label = "Return", valueRange = c(-1,0.5)) %>%
dyRangeSelector(dateWindow = c("2013-01-01", "2017-12-31")) %>%
dyOptions(colors = RColorBrewer::brewer.pal(5, "Set2"))
round(tail(returns, n = 5), 4)
## EFA IJS EEM AGG SP500
## 2017-08-31 -0.0004 -0.0276 0.0232 0.0073 0.0029
## 2017-09-29 0.0233 0.0790 -0.0004 -0.0078 0.0150
## 2017-10-31 0.0167 0.0059 0.0323 -0.0011 0.0233
## 2017-11-30 0.0069 0.0369 -0.0039 -0.0036 0.0301
## 2017-12-29 0.0028 -0.0080 0.0219 0.0023 0.0070
corrplot::corrplot(cor(returns), method = 'number')
wts <- c(1/3, 1/3, 1/3)
portfolio_returns <- Return.portfolio(R = returns[,1:3], weights = wts, wealth.index = TRUE)
benchmark_returns <- Return.portfolio(R = returns[,4], wealth.index = TRUE)
comp <- merge.xts(portfolio_returns, benchmark_returns)
colnames(comp) <- c("Portfolio", "Benchmark")
dygraph(comp, main = "Portfolio Performance vs. Benchmark") %>%
dyAxis("y", label = "Amount ($)")