Introduction to TidyQuant

install.packages("tidyverse")
install.packages("tidyquant")
library(tidyverse)
library(tidyquant)
install.packages('knitr', dependencies = TRUE)
knitr::opts_chunk$set(message = FALSE,
                      warning = FALSE,
                      echo = TRUE)
tq_get("NFLX",get = "stock.prices")
## # A tibble: 2,713 × 8
##    symbol date        open  high   low close    volume adjusted
##    <chr>  <date>     <dbl> <dbl> <dbl> <dbl>     <dbl>    <dbl>
##  1 NFLX   2012-01-03  10.0  10.4  10.0  10.3  29213800     10.3
##  2 NFLX   2012-01-04  10.3  11.6  10.3  11.5 100489900     11.5
##  3 NFLX   2012-01-05  11.3  11.7  11.0  11.3  86552900     11.3
##  4 NFLX   2012-01-06  11.3  12.5  11.2  12.3 125610800     12.3
##  5 NFLX   2012-01-09  12.8  14.2  12.4  14.0 214073300     14.0
##  6 NFLX   2012-01-10  14.3  14.3  13.2  13.7 146335000     13.7
##  7 NFLX   2012-01-11  13.6  13.7  13.1  13.2  87148600     13.2
##  8 NFLX   2012-01-12  13.2  13.3  12.7  13.2  61243000     13.2
##  9 NFLX   2012-01-13  13.1  13.8  12.9  13.5  88839100     13.5
## 10 NFLX   2012-01-17  13.7  14.0  13.5  13.5  58832200     13.5
## # … with 2,703 more rows
sp_500 <- tq_index("SP500") %>%
  tq_get(get = "stock.prices")
sp_500
## # A tibble: 1,325,175 × 15
##    symbol company   ident…¹ sedol weight sector share…² local…³ date        open
##    <chr>  <chr>     <chr>   <chr>  <dbl> <chr>    <dbl> <chr>   <date>     <dbl>
##  1 AAPL   Apple In… 037833… 2046… 0.0696 Infor…  1.64e8 USD     2012-01-03  14.6
##  2 AAPL   Apple In… 037833… 2046… 0.0696 Infor…  1.64e8 USD     2012-01-04  14.6
##  3 AAPL   Apple In… 037833… 2046… 0.0696 Infor…  1.64e8 USD     2012-01-05  14.8
##  4 AAPL   Apple In… 037833… 2046… 0.0696 Infor…  1.64e8 USD     2012-01-06  15.0
##  5 AAPL   Apple In… 037833… 2046… 0.0696 Infor…  1.64e8 USD     2012-01-09  15.2
##  6 AAPL   Apple In… 037833… 2046… 0.0696 Infor…  1.64e8 USD     2012-01-10  15.2
##  7 AAPL   Apple In… 037833… 2046… 0.0696 Infor…  1.64e8 USD     2012-01-11  15.1
##  8 AAPL   Apple In… 037833… 2046… 0.0696 Infor…  1.64e8 USD     2012-01-12  15.1
##  9 AAPL   Apple In… 037833… 2046… 0.0696 Infor…  1.64e8 USD     2012-01-13  15.0
## 10 AAPL   Apple In… 037833… 2046… 0.0696 Infor…  1.64e8 USD     2012-01-17  15.2
## # … with 1,325,165 more rows, 5 more variables: high <dbl>, low <dbl>,
## #   close <dbl>, volume <dbl>, adjusted <dbl>, and abbreviated variable names
## #   ¹​identifier, ²​shares_held, ³​local_currency
tq_transmute_fun_options()
## $zoo
##  [1] "rollapply"          "rollapplyr"         "rollmax"           
##  [4] "rollmax.default"    "rollmaxr"           "rollmean"          
##  [7] "rollmean.default"   "rollmeanr"          "rollmedian"        
## [10] "rollmedian.default" "rollmedianr"        "rollsum"           
## [13] "rollsum.default"    "rollsumr"          
## 
## $xts
##  [1] "apply.daily"     "apply.monthly"   "apply.quarterly" "apply.weekly"   
##  [5] "apply.yearly"    "diff.xts"        "lag.xts"         "period.apply"   
##  [9] "period.max"      "period.min"      "period.prod"     "period.sum"     
## [13] "periodicity"     "to_period"       "to.daily"        "to.hourly"      
## [17] "to.minutes"      "to.minutes10"    "to.minutes15"    "to.minutes3"    
## [21] "to.minutes30"    "to.minutes5"     "to.monthly"      "to.period"      
## [25] "to.quarterly"    "to.weekly"       "to.yearly"      
## 
## $quantmod
##  [1] "allReturns"      "annualReturn"    "ClCl"            "dailyReturn"    
##  [5] "Delt"            "HiCl"            "Lag"             "LoCl"           
##  [9] "LoHi"            "monthlyReturn"   "Next"            "OpCl"           
## [13] "OpHi"            "OpLo"            "OpOp"            "periodReturn"   
## [17] "quarterlyReturn" "seriesAccel"     "seriesDecel"     "seriesDecr"     
## [21] "seriesHi"        "seriesIncr"      "seriesLo"        "weeklyReturn"   
## [25] "yearlyReturn"   
## 
## $TTR
##  [1] "adjRatios"          "ADX"                "ALMA"              
##  [4] "aroon"              "ATR"                "BBands"            
##  [7] "CCI"                "chaikinAD"          "chaikinVolatility" 
## [10] "CLV"                "CMF"                "CMO"               
## [13] "CTI"                "DEMA"               "DonchianChannel"   
## [16] "DPO"                "DVI"                "EMA"               
## [19] "EMV"                "EVWMA"              "GMMA"              
## [22] "growth"             "HMA"                "keltnerChannels"   
## [25] "KST"                "lags"               "MACD"              
## [28] "MFI"                "momentum"           "OBV"               
## [31] "PBands"             "ROC"                "rollSFM"           
## [34] "RSI"                "runCor"             "runCov"            
## [37] "runMAD"             "runMax"             "runMean"           
## [40] "runMedian"          "runMin"             "runPercentRank"    
## [43] "runSD"              "runSum"             "runVar"            
## [46] "SAR"                "SMA"                "SMI"               
## [49] "SNR"                "stoch"              "TDI"               
## [52] "TRIX"               "ultimateOscillator" "VHF"               
## [55] "VMA"                "volatility"         "VWAP"              
## [58] "VWMA"               "wilderSum"          "williamsAD"        
## [61] "WMA"                "WPR"                "ZigZag"            
## [64] "ZLEMA"             
## 
## $PerformanceAnalytics
## [1] "Return.annualized"        "Return.annualized.excess"
## [3] "Return.clean"             "Return.cumulative"       
## [5] "Return.excess"            "Return.Geltner"          
## [7] "zerofill"
sp_500 %>%
  group_by(symbol) %>%
  tq_transmute(adjusted,mutate_fun = monthlyReturn)
## # A tibble: 63,526 × 3
## # Groups:   symbol [504]
##    symbol date       monthly.returns
##    <chr>  <date>               <dbl>
##  1 AAPL   2012-01-31         0.110  
##  2 AAPL   2012-02-29         0.188  
##  3 AAPL   2012-03-30         0.105  
##  4 AAPL   2012-04-30        -0.0260 
##  5 AAPL   2012-05-31        -0.0107 
##  6 AAPL   2012-06-29         0.0109 
##  7 AAPL   2012-07-31         0.0458 
##  8 AAPL   2012-08-31         0.0939 
##  9 AAPL   2012-09-28         0.00280
## 10 AAPL   2012-10-31        -0.108  
## # … with 63,516 more rows
sp_500
## # A tibble: 1,325,175 × 15
##    symbol company   ident…¹ sedol weight sector share…² local…³ date        open
##    <chr>  <chr>     <chr>   <chr>  <dbl> <chr>    <dbl> <chr>   <date>     <dbl>
##  1 AAPL   Apple In… 037833… 2046… 0.0696 Infor…  1.64e8 USD     2012-01-03  14.6
##  2 AAPL   Apple In… 037833… 2046… 0.0696 Infor…  1.64e8 USD     2012-01-04  14.6
##  3 AAPL   Apple In… 037833… 2046… 0.0696 Infor…  1.64e8 USD     2012-01-05  14.8
##  4 AAPL   Apple In… 037833… 2046… 0.0696 Infor…  1.64e8 USD     2012-01-06  15.0
##  5 AAPL   Apple In… 037833… 2046… 0.0696 Infor…  1.64e8 USD     2012-01-09  15.2
##  6 AAPL   Apple In… 037833… 2046… 0.0696 Infor…  1.64e8 USD     2012-01-10  15.2
##  7 AAPL   Apple In… 037833… 2046… 0.0696 Infor…  1.64e8 USD     2012-01-11  15.1
##  8 AAPL   Apple In… 037833… 2046… 0.0696 Infor…  1.64e8 USD     2012-01-12  15.1
##  9 AAPL   Apple In… 037833… 2046… 0.0696 Infor…  1.64e8 USD     2012-01-13  15.0
## 10 AAPL   Apple In… 037833… 2046… 0.0696 Infor…  1.64e8 USD     2012-01-17  15.2
## # … with 1,325,165 more rows, 5 more variables: high <dbl>, low <dbl>,
## #   close <dbl>, volume <dbl>, adjusted <dbl>, and abbreviated variable names
## #   ¹​identifier, ²​shares_held, ³​local_currency

Core Functions

Prerequisites

library(tidyverse)
library(tidyquant)

Retrieving Consolidated Symbol Data

Stock Indexes

tq_index_options
## function () 
## {
##     c("DOW", "DOWGLOBAL", "SP400", "SP500", "SP600")
## }
## <bytecode: 0x55adf79cd380>
## <environment: namespace:tidyquant>
tq_index("SP500")
## # A tibble: 504 × 8
##    symbol company                    ident…¹ sedol weight sector share…² local…³
##    <chr>  <chr>                      <chr>   <chr>  <dbl> <chr>    <dbl> <chr>  
##  1 AAPL   Apple Inc.                 037833… 2046… 0.0696 Infor…  1.64e8 USD    
##  2 MSFT   Microsoft Corporation      594918… 2588… 0.0557 Infor…  8.12e7 USD    
##  3 AMZN   Amazon.com Inc.            023135… 2000… 0.0330 Consu…  9.65e7 USD    
##  4 GOOGL  Alphabet Inc. Class A      02079K… BYVY… 0.0193 Commu…  6.53e7 USD    
##  5 TSLA   Tesla Inc                  88160R… B616… 0.0191 Consu…  2.90e7 USD    
##  6 GOOG   Alphabet Inc. Class C      02079K… BYY8… 0.0174 Commu…  5.84e7 USD    
##  7 BRK-B  Berkshire Hathaway Inc. C… 084670… 2073… 0.0160 Finan…  1.96e7 USD    
##  8 UNH    UnitedHealth Group Incorp… 91324P… 2917… 0.0155 Healt…  1.02e7 USD    
##  9 JNJ    Johnson & Johnson          478160… 2475… 0.0142 Healt…  2.86e7 USD    
## 10 XOM    Exxon Mobil Corporation    30231G… 2326… 0.0135 Energy  4.54e7 USD    
## # … with 494 more rows, and abbreviated variable names ¹​identifier,
## #   ²​shares_held, ³​local_currency

Stock Exchanges

Not sure what’s happening here: tq_exchange(“NASDAQ”) returns:

Error in open.connection(con, “rb”) : cannot open the connection to ‘https://api.nasdaq.com/api/screener/stocks?tableonly=true&exchange=nasdaq&download=true

Get Quantitative Data

tq_get_options()
##  [1] "stock.prices"       "stock.prices.japan" "dividends"         
##  [4] "splits"             "economic.data"      "quandl"            
##  [7] "quandl.datatable"   "tiingo"             "tiingo.iex"        
## [10] "tiingo.crypto"      "alphavantager"      "alphavantage"      
## [13] "rblpapi"

Yahoo! Finance

aapl_prices  <- tq_get("AAPL", get = "stock.prices", from = " 1990-01-01")
aapl_prices 
## # A tibble: 8,260 × 8
##    symbol date        open  high   low close    volume adjusted
##    <chr>  <date>     <dbl> <dbl> <dbl> <dbl>     <dbl>    <dbl>
##  1 AAPL   1990-01-02 0.315 0.335 0.312 0.333 183198400    0.265
##  2 AAPL   1990-01-03 0.339 0.339 0.335 0.335 207995200    0.267
##  3 AAPL   1990-01-04 0.342 0.346 0.333 0.336 221513600    0.268
##  4 AAPL   1990-01-05 0.337 0.342 0.330 0.337 123312000    0.269
##  5 AAPL   1990-01-08 0.335 0.339 0.330 0.339 101572800    0.271
##  6 AAPL   1990-01-09 0.339 0.339 0.330 0.336  86139200    0.268
##  7 AAPL   1990-01-10 0.336 0.336 0.319 0.321 199718400    0.256
##  8 AAPL   1990-01-11 0.324 0.324 0.308 0.308 211052800    0.246
##  9 AAPL   1990-01-12 0.306 0.310 0.301 0.308 171897600    0.246
## 10 AAPL   1990-01-15 0.308 0.319 0.306 0.306 161739200    0.244
## # … with 8,250 more rows
x8411T <- tq_get("8411.T", get = "stock.prices.japan", from = "2016-01-01", to  = "2016-12-31")

FRED Economic Data

wti_price_usd <- tq_get("DCOILWTICO", get = "economic.data")
wti_price_usd 
## # A tibble: 2,806 × 3
##    symbol     date       price
##    <chr>      <date>     <dbl>
##  1 DCOILWTICO 2012-01-02  NA  
##  2 DCOILWTICO 2012-01-03 103. 
##  3 DCOILWTICO 2012-01-04 103. 
##  4 DCOILWTICO 2012-01-05 102. 
##  5 DCOILWTICO 2012-01-06 102. 
##  6 DCOILWTICO 2012-01-09 101. 
##  7 DCOILWTICO 2012-01-10 102. 
##  8 DCOILWTICO 2012-01-11 101. 
##  9 DCOILWTICO 2012-01-12  99.0
## 10 DCOILWTICO 2012-01-13  98.7
## # … with 2,796 more rows

QUANDL API

quandl_api_key("kDJmytC1yySwj-yEfK6y")
quandl_search(query = "Oil", database_code = "NSE", per_page = 3)
## Oil India Limited
## Code: NSE/OIL
## Desc: Historical prices for Oil India Limited<br><br>National Stock Exchange of India<br><br>Ticker: OIL<br><br>ISIN: INE274J01014
## Freq: daily
## Cols: Date | Open | High | Low | Last | Close | Total Trade Quantity | Turnover (Lacs)
## 
## Oil Country Tubular Limited
## Code: NSE/OILCOUNTUB
## Desc: Historical prices for Oil Country Tubular Limited<br><br>National Stock Exchange of India<br><br>Ticker: OILCOUNTUB<br><br>ISIN: INE591A01010
## Freq: daily
## Cols: Date | Open | High | Low | Last | Close | Total Trade Quantity | Turnover (Lacs)
## 
## Essar Oil Limited
## Code: NSE/ESSAROIL
## Desc: Historical prices for Essar Oil Limited<br><br>National Stock Exchange of India<br><br>Ticker: ESSAROIL<br><br>ISIN: INE011A01019
## Freq: daily
## Cols: Date | Open | High | Low | Last | Close | Total Trade Quantity | Turnover (Lacs)
## # A tibble: 3 × 13
##      id dataset_…¹ datab…² name  descr…³ refre…⁴ newes…⁵ oldes…⁶ colum…⁷ frequ…⁸
##   <int> <chr>      <chr>   <chr> <chr>   <chr>   <chr>   <chr>   <list>  <chr>  
## 1  6668 OIL        NSE     Oil … Histor… 2019-0… 2019-0… 2009-0… <chr>   daily  
## 2  6669 OILCOUNTUB NSE     Oil … Histor… 2019-0… 2019-0… 1998-0… <chr>   daily  
## 3  6041 ESSAROIL   NSE     Essa… Histor… 2016-0… 2016-0… 1998-0… <chr>   daily  
## # … with 3 more variables: type <chr>, premium <lgl>, database_id <int>, and
## #   abbreviated variable names ¹​dataset_code, ²​database_code, ³​description,
## #   ⁴​refreshed_at, ⁵​newest_available_date, ⁶​oldest_available_date,
## #   ⁷​column_names, ⁸​frequency
get = "quandl"
get = "quandl.datatable"

c("WIKI/FB", "WIKI/AAPL") %>%
  tq_get(get  = "quandl",
         from = "2016-01-01",
         to   = "2016-12-31")
## # A tibble: 504 × 14
##    symbol  date        open  high   low close   volume ex.divi…¹ split…² adj.o…³
##    <chr>   <date>     <dbl> <dbl> <dbl> <dbl>    <dbl>     <dbl>   <dbl>   <dbl>
##  1 WIKI/FB 2016-01-04 102.  102.   99.8 102.  37912403         0       1   102. 
##  2 WIKI/FB 2016-01-05 103.  104.  102.  103.  23258238         0       1   103. 
##  3 WIKI/FB 2016-01-06 101.  104.  101.  103.  25096183         0       1   101. 
##  4 WIKI/FB 2016-01-07 100.  101.   97.3  97.9 45172906         0       1   100. 
##  5 WIKI/FB 2016-01-08  99.9 100.   97.0  97.3 35402298         0       1    99.9
##  6 WIKI/FB 2016-01-11  97.9  98.6  95.4  97.5 29932385         0       1    97.9
##  7 WIKI/FB 2016-01-12  99   100.   97.6  99.4 28395390         0       1    99  
##  8 WIKI/FB 2016-01-13 101.  101.   95.2  95.4 33410553         0       1   101. 
##  9 WIKI/FB 2016-01-14  95.8  98.9  92.4  98.4 48658623         0       1    95.8
## 10 WIKI/FB 2016-01-15  94.0  96.4  93.5  95.0 46132781         0       1    94.0
## # … with 494 more rows, 4 more variables: adj.high <dbl>, adj.low <dbl>,
## #   adj.close <dbl>, adj.volume <dbl>, and abbreviated variable names
## #   ¹​ex.dividend, ²​split.ratio, ³​adj.open
c("WIKI/FB", "WIKI/AAPL") %>%
  tq_get(get          = "quandl",
         from         = "2007-01-01",
         to           = "2016-12-31",
         column_index = 11, 
         collapse     = "annual",      
         transform    = "rdiff")  
## # A tibble: 13 × 3
##    symbol    date       adj.close
##    <chr>     <date>         <dbl>
##  1 WIKI/FB   2013-12-31    1.05  
##  2 WIKI/FB   2014-12-31    0.428 
##  3 WIKI/FB   2015-12-31    0.341 
##  4 WIKI/FB   2016-12-31    0.0993
##  5 WIKI/AAPL 2008-12-31   -0.569 
##  6 WIKI/AAPL 2009-12-31    1.47  
##  7 WIKI/AAPL 2010-12-31    0.531 
##  8 WIKI/AAPL 2011-12-31    0.256 
##  9 WIKI/AAPL 2012-12-31    0.326 
## 10 WIKI/AAPL 2013-12-31    0.0806
## 11 WIKI/AAPL 2014-12-31    0.406 
## 12 WIKI/AAPL 2015-12-31   -0.0302
## 13 WIKI/AAPL 2016-12-31    0.125
tq_get("ZACKS/FC", get = "quandl.datatable")   # Zacks Fundamentals Condensed
## [1] NA
tq_get("ZACKS/FR", get = "quandl.datatable")   # Zacks Fundamental Ratios
## [1] NA
tq_get("ZACKS/MT", get = "quandl.datatable")   # Zacks Master Table
## [1] NA
tq_get("ZACKS/MKTV", get = "quandl.datatable") # Zacks Market Value Supplement
## [1] NA
tq_get("ZACKS/SHRS", get = "quandl.datatable") # Zacks Shares Out Supplement
## [1] NA

Mutate Quantitative Data

data("FANG")

FANG
## # A tibble: 4,032 × 8
##    symbol date        open  high   low close    volume adjusted
##    <chr>  <date>     <dbl> <dbl> <dbl> <dbl>     <dbl>    <dbl>
##  1 FB     2013-01-02  27.4  28.2  27.4  28    69846400     28  
##  2 FB     2013-01-03  27.9  28.5  27.6  27.8  63140600     27.8
##  3 FB     2013-01-04  28.0  28.9  27.8  28.8  72715400     28.8
##  4 FB     2013-01-07  28.7  29.8  28.6  29.4  83781800     29.4
##  5 FB     2013-01-08  29.5  29.6  28.9  29.1  45871300     29.1
##  6 FB     2013-01-09  29.7  30.6  29.5  30.6 104787700     30.6
##  7 FB     2013-01-10  30.6  31.5  30.3  31.3  95316400     31.3
##  8 FB     2013-01-11  31.3  32.0  31.1  31.7  89598000     31.7
##  9 FB     2013-01-14  32.1  32.2  30.6  31.0  98892800     31.0
## 10 FB     2013-01-15  30.6  31.7  29.9  30.1 173242600     30.1
## # … with 4,022 more rows

Transmute Quantitative Data

FANG %>%
  group_by(symbol) %>%
  tq_transmute(select = adjusted, mutate_fun = to.monthly, indexAt = "lastof")
## # A tibble: 192 × 3
## # Groups:   symbol [4]
##    symbol date       adjusted
##    <chr>  <date>        <dbl>
##  1 FB     2013-01-31     31.0
##  2 FB     2013-02-28     27.2
##  3 FB     2013-03-31     25.6
##  4 FB     2013-04-30     27.8
##  5 FB     2013-05-31     24.4
##  6 FB     2013-06-30     24.9
##  7 FB     2013-07-31     36.8
##  8 FB     2013-08-31     41.3
##  9 FB     2013-09-30     50.2
## 10 FB     2013-10-31     50.2
## # … with 182 more rows
wti_prices <- tq_get("DCOILWTICO", get = "economic.data") 

wti_prices %>%    
  tq_transmute(mutate_fun = to.period,
               period     = "months", 
               col_rename = "WTI Price")
## # A tibble: 130 × 2
##    date       `WTI Price`
##    <date>           <dbl>
##  1 2012-01-31        98.5
##  2 2012-02-29       107. 
##  3 2012-03-30       103. 
##  4 2012-04-30       105. 
##  5 2012-05-31        86.5
##  6 2012-06-29        85.0
##  7 2012-07-31        88.1
##  8 2012-08-31        96.5
##  9 2012-09-28        92.2
## 10 2012-10-31        86.2
## # … with 120 more rows

Mutate Quantitative Data

FANG %>%
  group_by(symbol) %>%
  tq_mutate(select     = close, 
            mutate_fun = MACD, 
            col_rename = c("MACD", "Signal"))
## # A tibble: 4,032 × 10
## # Groups:   symbol [4]
##    symbol date        open  high   low close    volume adjusted  MACD Signal
##    <chr>  <date>     <dbl> <dbl> <dbl> <dbl>     <dbl>    <dbl> <dbl>  <dbl>
##  1 FB     2013-01-02  27.4  28.2  27.4  28    69846400     28      NA     NA
##  2 FB     2013-01-03  27.9  28.5  27.6  27.8  63140600     27.8    NA     NA
##  3 FB     2013-01-04  28.0  28.9  27.8  28.8  72715400     28.8    NA     NA
##  4 FB     2013-01-07  28.7  29.8  28.6  29.4  83781800     29.4    NA     NA
##  5 FB     2013-01-08  29.5  29.6  28.9  29.1  45871300     29.1    NA     NA
##  6 FB     2013-01-09  29.7  30.6  29.5  30.6 104787700     30.6    NA     NA
##  7 FB     2013-01-10  30.6  31.5  30.3  31.3  95316400     31.3    NA     NA
##  8 FB     2013-01-11  31.3  32.0  31.1  31.7  89598000     31.7    NA     NA
##  9 FB     2013-01-14  32.1  32.2  30.6  31.0  98892800     31.0    NA     NA
## 10 FB     2013-01-15  30.6  31.7  29.9  30.1 173242600     30.1    NA     NA
## # … with 4,022 more rows
fb_returns <- tq_get("META", get  = "stock.prices", from = "2016-01-01", to   = "2016-12-31") %>%
  tq_transmute(adjusted, periodReturn, period = "weekly", col_rename = "fb.returns")

xlk_returns <- tq_get("XLK", from = "2016-01-01", to = "2016-12-31") %>%
  tq_transmute(adjusted, periodReturn, period = "weekly", col_rename = "xlk.returns")

returns_combined <- left_join(fb_returns, xlk_returns, by = "date")
returns_combined
## # A tibble: 52 × 3
##    date       fb.returns xlk.returns
##    <date>          <dbl>       <dbl>
##  1 2016-01-08   -0.0478     -0.0516 
##  2 2016-01-15   -0.0242     -0.0187 
##  3 2016-01-22    0.0313      0.0264 
##  4 2016-01-29    0.146       0.0213 
##  5 2016-02-05   -0.0725     -0.0422 
##  6 2016-02-12   -0.0198     -0.00582
##  7 2016-02-19    0.0251      0.0354 
##  8 2016-02-26    0.0320      0.0148 
##  9 2016-03-04    0.00436     0.0281 
## 10 2016-03-11    0.00941     0.0106 
## # … with 42 more rows
regr_fun <- function(data) {
  coef(lm(fb.returns ~ xlk.returns, data = timetk::tk_tbl(data, silent = TRUE)))
}

returns_combined %>%
  tq_mutate(mutate_fun = rollapply,
            width      = 12,
            FUN        = regr_fun,
            by.column  = FALSE,
            col_rename = c("coef.0", "coef.1"))
## # A tibble: 52 × 5
##    date       fb.returns xlk.returns coef.0 coef.1
##    <date>          <dbl>       <dbl>  <dbl>  <dbl>
##  1 2016-01-08   -0.0478     -0.0516      NA     NA
##  2 2016-01-15   -0.0242     -0.0187      NA     NA
##  3 2016-01-22    0.0313      0.0264      NA     NA
##  4 2016-01-29    0.146       0.0213      NA     NA
##  5 2016-02-05   -0.0725     -0.0422      NA     NA
##  6 2016-02-12   -0.0198     -0.00582     NA     NA
##  7 2016-02-19    0.0251      0.0354      NA     NA
##  8 2016-02-26    0.0320      0.0148      NA     NA
##  9 2016-03-04    0.00436     0.0281      NA     NA
## 10 2016-03-11    0.00941     0.0106      NA     NA
## # … with 42 more rows
returns_combined
## # A tibble: 52 × 3
##    date       fb.returns xlk.returns
##    <date>          <dbl>       <dbl>
##  1 2016-01-08   -0.0478     -0.0516 
##  2 2016-01-15   -0.0242     -0.0187 
##  3 2016-01-22    0.0313      0.0264 
##  4 2016-01-29    0.146       0.0213 
##  5 2016-02-05   -0.0725     -0.0422 
##  6 2016-02-12   -0.0198     -0.00582
##  7 2016-02-19    0.0251      0.0354 
##  8 2016-02-26    0.0320      0.0148 
##  9 2016-03-04    0.00436     0.0281 
## 10 2016-03-11    0.00941     0.0106 
## # … with 42 more rows

_xy Variants

FANG %>%
  group_by(symbol) %>%
  tq_mutate_xy(x = close, y = volume, 
               mutate_fun = EVWMA, col_rename = "EVWMA")
## # A tibble: 4,032 × 9
## # Groups:   symbol [4]
##    symbol date        open  high   low close    volume adjusted EVWMA
##    <chr>  <date>     <dbl> <dbl> <dbl> <dbl>     <dbl>    <dbl> <dbl>
##  1 FB     2013-01-02  27.4  28.2  27.4  28    69846400     28    NA  
##  2 FB     2013-01-03  27.9  28.5  27.6  27.8  63140600     27.8  NA  
##  3 FB     2013-01-04  28.0  28.9  27.8  28.8  72715400     28.8  NA  
##  4 FB     2013-01-07  28.7  29.8  28.6  29.4  83781800     29.4  NA  
##  5 FB     2013-01-08  29.5  29.6  28.9  29.1  45871300     29.1  NA  
##  6 FB     2013-01-09  29.7  30.6  29.5  30.6 104787700     30.6  NA  
##  7 FB     2013-01-10  30.6  31.5  30.3  31.3  95316400     31.3  NA  
##  8 FB     2013-01-11  31.3  32.0  31.1  31.7  89598000     31.7  NA  
##  9 FB     2013-01-14  32.1  32.2  30.6  31.0  98892800     31.0  NA  
## 10 FB     2013-01-15  30.6  31.7  29.9  30.1 173242600     30.1  30.1
## # … with 4,022 more rows

Quantitative Analysis Package

Prerequisites

library(tidyverse)
library(tidyquant)

Function Compatibility

tq_transmute_fun_options() %>% str()
## List of 5
##  $ zoo                 : chr [1:14] "rollapply" "rollapplyr" "rollmax" "rollmax.default" ...
##  $ xts                 : chr [1:27] "apply.daily" "apply.monthly" "apply.quarterly" "apply.weekly" ...
##  $ quantmod            : chr [1:25] "allReturns" "annualReturn" "ClCl" "dailyReturn" ...
##  $ TTR                 : chr [1:64] "adjRatios" "ADX" "ALMA" "aroon" ...
##  $ PerformanceAnalytics: chr [1:7] "Return.annualized" "Return.annualized.excess" "Return.clean" "Return.cumulative" ...

zoo Functionality

tq_transmute_fun_options()$zoo
##  [1] "rollapply"          "rollapplyr"         "rollmax"           
##  [4] "rollmax.default"    "rollmaxr"           "rollmean"          
##  [7] "rollmean.default"   "rollmeanr"          "rollmedian"        
## [10] "rollmedian.default" "rollmedianr"        "rollsum"           
## [13] "rollsum.default"    "rollsumr"

xts Functionality

tq_transmute_fun_options()$xts
##  [1] "apply.daily"     "apply.monthly"   "apply.quarterly" "apply.weekly"   
##  [5] "apply.yearly"    "diff.xts"        "lag.xts"         "period.apply"   
##  [9] "period.max"      "period.min"      "period.prod"     "period.sum"     
## [13] "periodicity"     "to_period"       "to.daily"        "to.hourly"      
## [17] "to.minutes"      "to.minutes10"    "to.minutes15"    "to.minutes3"    
## [21] "to.minutes30"    "to.minutes5"     "to.monthly"      "to.period"      
## [25] "to.quarterly"    "to.weekly"       "to.yearly"

quantmod Functionality

tq_transmute_fun_options()$quantmod
##  [1] "allReturns"      "annualReturn"    "ClCl"            "dailyReturn"    
##  [5] "Delt"            "HiCl"            "Lag"             "LoCl"           
##  [9] "LoHi"            "monthlyReturn"   "Next"            "OpCl"           
## [13] "OpHi"            "OpLo"            "OpOp"            "periodReturn"   
## [17] "quarterlyReturn" "seriesAccel"     "seriesDecel"     "seriesDecr"     
## [21] "seriesHi"        "seriesIncr"      "seriesLo"        "weeklyReturn"   
## [25] "yearlyReturn"

TTR Functionality

tq_transmute_fun_options()$TTR
##  [1] "adjRatios"          "ADX"                "ALMA"              
##  [4] "aroon"              "ATR"                "BBands"            
##  [7] "CCI"                "chaikinAD"          "chaikinVolatility" 
## [10] "CLV"                "CMF"                "CMO"               
## [13] "CTI"                "DEMA"               "DonchianChannel"   
## [16] "DPO"                "DVI"                "EMA"               
## [19] "EMV"                "EVWMA"              "GMMA"              
## [22] "growth"             "HMA"                "keltnerChannels"   
## [25] "KST"                "lags"               "MACD"              
## [28] "MFI"                "momentum"           "OBV"               
## [31] "PBands"             "ROC"                "rollSFM"           
## [34] "RSI"                "runCor"             "runCov"            
## [37] "runMAD"             "runMax"             "runMean"           
## [40] "runMedian"          "runMin"             "runPercentRank"    
## [43] "runSD"              "runSum"             "runVar"            
## [46] "SAR"                "SMA"                "SMI"               
## [49] "SNR"                "stoch"              "TDI"               
## [52] "TRIX"               "ultimateOscillator" "VHF"               
## [55] "VMA"                "volatility"         "VWAP"              
## [58] "VWMA"               "wilderSum"          "williamsAD"        
## [61] "WMA"                "WPR"                "ZigZag"            
## [64] "ZLEMA"

PerformanceAnalytics Functionality

tq_transmute_fun_options()$PerformanceAnalytics
## [1] "Return.annualized"        "Return.annualized.excess"
## [3] "Return.clean"             "Return.cumulative"       
## [5] "Return.excess"            "Return.Geltner"          
## [7] "zerofill"

Quantitative Power In Action

data("FANG")

FANG
## # A tibble: 4,032 × 8
##    symbol date        open  high   low close    volume adjusted
##    <chr>  <date>     <dbl> <dbl> <dbl> <dbl>     <dbl>    <dbl>
##  1 FB     2013-01-02  27.4  28.2  27.4  28    69846400     28  
##  2 FB     2013-01-03  27.9  28.5  27.6  27.8  63140600     27.8
##  3 FB     2013-01-04  28.0  28.9  27.8  28.8  72715400     28.8
##  4 FB     2013-01-07  28.7  29.8  28.6  29.4  83781800     29.4
##  5 FB     2013-01-08  29.5  29.6  28.9  29.1  45871300     29.1
##  6 FB     2013-01-09  29.7  30.6  29.5  30.6 104787700     30.6
##  7 FB     2013-01-10  30.6  31.5  30.3  31.3  95316400     31.3
##  8 FB     2013-01-11  31.3  32.0  31.1  31.7  89598000     31.7
##  9 FB     2013-01-14  32.1  32.2  30.6  31.0  98892800     31.0
## 10 FB     2013-01-15  30.6  31.7  29.9  30.1 173242600     30.1
## # … with 4,022 more rows

Example 1: Use quantmod periodReturn to Convert Prices to Returns

Example 1A: Getting and Charting Annual Returns

FANG_annual_returns <- FANG %>%
    group_by(symbol) %>%
    tq_transmute(select     = adjusted, 
                 mutate_fun = periodReturn, 
                 period     = "yearly", 
                 type       = "arithmetic")
FANG_annual_returns
## # A tibble: 16 × 3
## # Groups:   symbol [4]
##    symbol date       yearly.returns
##    <chr>  <date>              <dbl>
##  1 FB     2013-12-31         0.952 
##  2 FB     2014-12-31         0.428 
##  3 FB     2015-12-31         0.341 
##  4 FB     2016-12-30         0.0993
##  5 AMZN   2013-12-31         0.550 
##  6 AMZN   2014-12-31        -0.222 
##  7 AMZN   2015-12-31         1.18  
##  8 AMZN   2016-12-30         0.109 
##  9 NFLX   2013-12-31         3.00  
## 10 NFLX   2014-12-31        -0.0721
## 11 NFLX   2015-12-31         1.34  
## 12 NFLX   2016-12-30         0.0824
## 13 GOOG   2013-12-31         0.550 
## 14 GOOG   2014-12-31        -0.0597
## 15 GOOG   2015-12-31         0.442 
## 16 GOOG   2016-12-30         0.0171
FANG_annual_returns %>%
    ggplot(aes(x = date, y = yearly.returns, fill = symbol)) +
    geom_col() +
    geom_hline(yintercept = 0, color = palette_light()[[1]]) +
    scale_y_continuous(labels = scales::percent) +
    labs(title = "FANG: Annual Returns",
         subtitle = "Get annual returns quickly with tq_transmute!",
         y = "Annual Returns", x = "") + 
    facet_wrap(~ symbol, ncol = 2, scales = "free_y") +
    theme_tq() + 
    scale_fill_tq()

Example 1B: Getting Daily Log Returns

FANG_daily_log_returns <- FANG %>%
    group_by(symbol) %>%
    tq_transmute(select     = adjusted, 
                 mutate_fun = periodReturn, 
                 period     = "daily", 
                 type       = "log",
                 col_rename = "monthly.returns")
FANG_daily_log_returns %>%
    ggplot(aes(x = monthly.returns, fill = symbol)) +
    geom_density(alpha = 0.5) +
    labs(title = "FANG: Charting the Daily Log Returns",
         x = "Monthly Returns", y = "Density") +
    theme_tq() +
    scale_fill_tq() + 
    facet_wrap(~ symbol, ncol = 2)

Example 2: Use xts to.period to Change the Periodicity from Daily to Monthly

FANG %>%
    group_by(symbol) %>%
    tq_transmute(select     = open:volume, 
                 mutate_fun = to.period, 
                 period     = "months")
## # A tibble: 192 × 7
## # Groups:   symbol [4]
##    symbol date        open  high   low close    volume
##    <chr>  <date>     <dbl> <dbl> <dbl> <dbl>     <dbl>
##  1 FB     2013-01-31  29.2  31.5  28.7  31.0 190744900
##  2 FB     2013-02-28  26.8  27.3  26.3  27.2  83027800
##  3 FB     2013-03-28  26.1  26.2  25.5  25.6  28585700
##  4 FB     2013-04-30  27.1  27.8  27.0  27.8  36245700
##  5 FB     2013-05-31  24.6  25.0  24.3  24.4  35925000
##  6 FB     2013-06-28  24.7  25.0  24.4  24.9  96778900
##  7 FB     2013-07-31  38.0  38.3  36.3  36.8 154828700
##  8 FB     2013-08-30  42.0  42.3  41.1  41.3  67735100
##  9 FB     2013-09-30  50.1  51.6  49.8  50.2 100095000
## 10 FB     2013-10-31  47.2  52    46.5  50.2 248809000
## # … with 182 more rows

Without Periodicity Aggregation

FANG_daily <- FANG %>%
    group_by(symbol)

FANG_daily %>%
    ggplot(aes(x = date, y = adjusted, color = symbol)) +
    geom_line(size = 1) +
    labs(title = "Daily Stock Prices",
         x = "", y = "Adjusted Prices", color = "") +
    facet_wrap(~ symbol, ncol = 2, scales = "free_y") +
    scale_y_continuous(labels = scales::dollar) +
    theme_tq() + 
    scale_color_tq()

With Monthly Periodicity Aggregation

FANG_monthly <- FANG %>%
    group_by(symbol) %>%
    tq_transmute(select     = adjusted, 
                 mutate_fun = to.period, 
                 period     = "months")

FANG_monthly %>%
    ggplot(aes(x = date, y = adjusted, color = symbol)) +
    geom_line(size = 1) +
    labs(title = "Monthly Stock Prices",
         x = "", y = "Adjusted Prices", color = "") +
    facet_wrap(~ symbol, ncol = 2, scales = "free_y") +
    scale_y_continuous(labels = scales::dollar) +
    theme_tq() + 
    scale_color_tq()

Example 3: Use TTR runCor to Visualize Rolling Correlations of Returns

Asset Returns

FANG_returns_monthly <- FANG %>%
    group_by(symbol) %>%
    tq_transmute(select     = adjusted, 
                 mutate_fun = periodReturn,
                 period     = "monthly")

Baseline Returns

baseline_returns_monthly <- "XLK" %>%
    tq_get(get  = "stock.prices",
           from = "2013-01-01", 
           to   = "2016-12-31") %>%
    tq_transmute(select     = adjusted, 
                 mutate_fun = periodReturn,
                 period     = "monthly")
                 
returns_joined <- left_join(FANG_returns_monthly, 
                            baseline_returns_monthly,
                            by = "date")
returns_joined
## # A tibble: 192 × 4
## # Groups:   symbol [4]
##    symbol date       monthly.returns.x monthly.returns.y
##    <chr>  <date>                 <dbl>             <dbl>
##  1 FB     2013-01-31          0.106             -0.0138 
##  2 FB     2013-02-28         -0.120              0.00782
##  3 FB     2013-03-28         -0.0613             0.0258 
##  4 FB     2013-04-30          0.0856             0.0175 
##  5 FB     2013-05-31         -0.123              0.0279 
##  6 FB     2013-06-28          0.0218            -0.0289 
##  7 FB     2013-07-31          0.479              0.0373 
##  8 FB     2013-08-30          0.122             -0.0104 
##  9 FB     2013-09-30          0.217              0.0253 
## 10 FB     2013-10-31         -0.000398           0.0502 
## # … with 182 more rows
FANG_rolling_corr <- returns_joined %>%
    tq_transmute_xy(x          = monthly.returns.x, 
                    y          = monthly.returns.y,
                    mutate_fun = runCor,
                    n          = 6,
                    col_rename = "rolling.corr.6")
                    
FANG_rolling_corr %>%
    ggplot(aes(x = date, y = rolling.corr.6, color = symbol)) +
    geom_hline(yintercept = 0, color = palette_light()[[1]]) +
    geom_line(size = 1) +
    labs(title = "FANG: Six Month Rolling Correlation to XLK",
         x = "", y = "Correlation", color = "") +
    facet_wrap(~ symbol, ncol = 2) +
    theme_tq() + 
    scale_color_tq()

Example 4: Use TTR MACD to Visualize Moving Average Convergence Divergence

FANG_macd <- FANG %>%
    group_by(symbol) %>%
    tq_mutate(select     = close, 
              mutate_fun = MACD, 
              nFast      = 12, 
              nSlow      = 26, 
              nSig       = 9, 
              maType     = SMA) %>%
    mutate(diff = macd - signal) %>%
    select(-(open:volume))
    
FANG_macd %>%
    filter(date >= as_date("2016-10-01")) %>%
    ggplot(aes(x = date)) + 
    geom_hline(yintercept = 0, color = palette_light()[[1]]) +
    geom_line(aes(y = macd, col = symbol)) +
    geom_line(aes(y = signal), color = "blue", linetype = 2) +
    geom_bar(aes(y = diff), stat = "identity", color = palette_light()[[1]]) +
    facet_wrap(~ symbol, ncol = 2, scale = "free_y") +
    labs(title = "FANG: Moving Average Convergence Divergence",
         y = "MACD", x = "", color = "") +
    theme_tq() +
    scale_color_tq()

FANG_macd
## # A tibble: 4,032 × 6
## # Groups:   symbol [4]
##    symbol date       adjusted  macd signal  diff
##    <chr>  <date>        <dbl> <dbl>  <dbl> <dbl>
##  1 FB     2013-01-02     28      NA     NA    NA
##  2 FB     2013-01-03     27.8    NA     NA    NA
##  3 FB     2013-01-04     28.8    NA     NA    NA
##  4 FB     2013-01-07     29.4    NA     NA    NA
##  5 FB     2013-01-08     29.1    NA     NA    NA
##  6 FB     2013-01-09     30.6    NA     NA    NA
##  7 FB     2013-01-10     31.3    NA     NA    NA
##  8 FB     2013-01-11     31.7    NA     NA    NA
##  9 FB     2013-01-14     31.0    NA     NA    NA
## 10 FB     2013-01-15     30.1    NA     NA    NA
## # … with 4,022 more rows

Example 5: Use xts apply.quarterly to Get the Max and Min Price for Each Quarter

FANG_max_by_qtr <- FANG %>%
    group_by(symbol) %>%
    tq_transmute(select     = adjusted, 
                 mutate_fun = apply.quarterly, 
                 FUN        = max, 
                 col_rename = "max.close") %>%
    mutate(year.qtr = paste0(year(date), "-Q", quarter(date))) %>%
    select(-date)
FANG_max_by_qtr
## # A tibble: 64 × 3
## # Groups:   symbol [4]
##    symbol max.close year.qtr
##    <chr>      <dbl> <chr>   
##  1 FB          32.5 2013-Q1 
##  2 FB          29.0 2013-Q2 
##  3 FB          51.2 2013-Q3 
##  4 FB          58.0 2013-Q4 
##  5 FB          72.0 2014-Q1 
##  6 FB          67.6 2014-Q2 
##  7 FB          79.0 2014-Q3 
##  8 FB          81.4 2014-Q4 
##  9 FB          85.3 2015-Q1 
## 10 FB          88.9 2015-Q2 
## # … with 54 more rows
FANG_min_by_qtr <- FANG %>%
    group_by(symbol) %>%
    tq_transmute(select     = adjusted, 
                 mutate_fun = apply.quarterly, 
                 FUN        = min, 
                 col_rename = "min.close") %>%
    mutate(year.qtr = paste0(year(date), "-Q", quarter(date))) %>%
    select(-date)

FANG_by_qtr <- left_join(FANG_max_by_qtr, FANG_min_by_qtr,
                         by = c("symbol"   = "symbol",
                                "year.qtr" = "year.qtr"))
FANG_by_qtr
## # A tibble: 64 × 4
## # Groups:   symbol [4]
##    symbol max.close year.qtr min.close
##    <chr>      <dbl> <chr>        <dbl>
##  1 FB          32.5 2013-Q1       25.1
##  2 FB          29.0 2013-Q2       22.9
##  3 FB          51.2 2013-Q3       24.4
##  4 FB          58.0 2013-Q4       44.8
##  5 FB          72.0 2014-Q1       53.5
##  6 FB          67.6 2014-Q2       56.1
##  7 FB          79.0 2014-Q3       62.8
##  8 FB          81.4 2014-Q4       72.6
##  9 FB          85.3 2015-Q1       74.1
## 10 FB          88.9 2015-Q2       77.5
## # … with 54 more rows
FANG_by_qtr %>%
    ggplot(aes(x = year.qtr, color = symbol)) +
    geom_segment(aes(xend = year.qtr, y = min.close, yend = max.close),
                 size = 1) +
    geom_point(aes(y = max.close), size = 2) +
    geom_point(aes(y = min.close), size = 2) +
    facet_wrap(~ symbol, ncol = 2, scale = "free_y") +
    labs(title = "FANG: Min/Max Price By Quarter",
         y = "Stock Price", color = "") +
    theme_tq() +
    scale_color_tq() +
    scale_y_continuous(labels = scales::dollar) +
    theme(axis.text.x = element_text(angle = 90, hjust = 1),
          axis.title.x = element_blank())

Example 6: Use zoo rollapply to visualize a rolling regression

stock_prices <- c("MA", "V") %>%
    tq_get(get  = "stock.prices",
           from = "2015-01-01",
           to   = "2016-12-31") %>%
    group_by(symbol) 

Get stock pairs

stock_pairs <- stock_prices %>%
    tq_transmute(select     = adjusted,
                 mutate_fun = periodReturn,
                 period     = "daily",
                 type       = "log",
                 col_rename = "returns") %>%
    spread(key = symbol, value = returns)
    
stock_pairs %>%
    ggplot(aes(x = V, y = MA)) +
    geom_point(color = palette_light()[[1]], alpha = 0.5) +
    geom_smooth(method = "lm") +
    labs(title = "Visualizing Returns Relationship of Stock Pairs") +
    theme_tq()

lm(MA ~ V, data = stock_pairs) %>%
    summary()
## 
## Call:
## lm(formula = MA ~ V, data = stock_pairs)
## 
## Residuals:
##        Min         1Q     Median         3Q        Max 
## -0.0269574 -0.0039657  0.0002155  0.0039651  0.0289460 
## 
## Coefficients:
##              Estimate Std. Error t value Pr(>|t|)    
## (Intercept) 0.0001130  0.0003097   0.365    0.715    
## V           0.8133665  0.0226393  35.927   <2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 0.00695 on 502 degrees of freedom
## Multiple R-squared:   0.72,  Adjusted R-squared:  0.7194 
## F-statistic:  1291 on 1 and 502 DF,  p-value: < 2.2e-16
regr_fun <- function(data) {
    coef(lm(MA ~ V, data = timetk::tk_tbl(data, silent = TRUE)))
}

stock_pairs <- stock_pairs %>%
         tq_mutate(mutate_fun = rollapply,
                   width      = 90,
                   FUN        = regr_fun,
                   by.column  = FALSE,
                   col_rename = c("coef.0", "coef.1"))
stock_pairs
## # A tibble: 504 × 5
##    date             MA        V coef.0 coef.1
##    <date>        <dbl>    <dbl>  <dbl>  <dbl>
##  1 2015-01-02  0        0           NA     NA
##  2 2015-01-05 -0.0285  -0.0223      NA     NA
##  3 2015-01-06 -0.00216 -0.00646     NA     NA
##  4 2015-01-07  0.0154   0.0133      NA     NA
##  5 2015-01-08  0.0154   0.0133      NA     NA
##  6 2015-01-09 -0.0128  -0.0149      NA     NA
##  7 2015-01-12 -0.0129  -0.00196     NA     NA
##  8 2015-01-13  0.00228  0.00292     NA     NA
##  9 2015-01-14 -0.00108 -0.0202      NA     NA
## 10 2015-01-15 -0.0146  -0.00955     NA     NA
## # … with 494 more rows
stock_pairs %>%
    ggplot(aes(x = date, y = coef.1)) +
    geom_line(size = 1, color = palette_light()[[1]]) +
    geom_hline(yintercept = 0.8134, size = 1, color = palette_light()[[2]]) +
    labs(title = "MA ~ V: Visualizing Rolling Regression Coefficient", x = "") +
    theme_tq()

stock_prices %>%
    tq_transmute(adjusted, 
                 periodReturn, 
                 period = "daily", 
                 type = "log", 
                 col_rename = "returns") %>%
    mutate(wealth.index = 100 * cumprod(1 + returns)) %>%
    ggplot(aes(x = date, y = wealth.index, color = symbol)) +
    geom_line(size = 1) +
    labs(title = "MA and V: Stock Prices") +
    theme_tq() + 
    scale_color_tq()

Example 7: Use Return.clean and Return.excess to clean and calculate excess returns

FANG %>%
    group_by(symbol) %>%
    tq_transmute(adjusted, periodReturn, period = "daily") %>%
    tq_transmute(daily.returns, Return.clean, alpha = 0.05) %>%
    tq_transmute(daily.returns, Return.excess, Rf = 0.03 / 252)
## # A tibble: 4,032 × 3
## # Groups:   symbol [4]
##    symbol date       `daily.returns > Rf`
##    <chr>  <date>                    <dbl>
##  1 FB     2013-01-02            -0.000119
##  2 FB     2013-01-03            -0.00833 
##  3 FB     2013-01-04             0.0355  
##  4 FB     2013-01-07             0.0228  
##  5 FB     2013-01-08            -0.0124  
##  6 FB     2013-01-09             0.0525  
##  7 FB     2013-01-10             0.0231  
##  8 FB     2013-01-11             0.0133  
##  9 FB     2013-01-14            -0.0244  
## 10 FB     2013-01-15            -0.0276  
## # … with 4,022 more rows

Scaling and Modeling with TidyQuant

Prerequisites

library(tidyverse)
library(tidyquant)  

Scaling the Getting of Financial Data

Method 1: Map a character vector with multiple stock symbols

c("AAPL", "GOOG", "FB") %>%
    tq_get(get = "stock.prices", from = "2016-01-01", to = "2017-01-01")
## # A tibble: 504 × 8
##    symbol date        open  high   low close    volume adjusted
##    <chr>  <date>     <dbl> <dbl> <dbl> <dbl>     <dbl>    <dbl>
##  1 AAPL   2016-01-04  25.7  26.3  25.5  26.3 270597600     24.2
##  2 AAPL   2016-01-05  26.4  26.5  25.6  25.7 223164000     23.5
##  3 AAPL   2016-01-06  25.1  25.6  25.0  25.2 273829600     23.1
##  4 AAPL   2016-01-07  24.7  25.0  24.1  24.1 324377600     22.1
##  5 AAPL   2016-01-08  24.6  24.8  24.2  24.2 283192000     22.2
##  6 AAPL   2016-01-11  24.7  24.8  24.3  24.6 198957600     22.6
##  7 AAPL   2016-01-12  25.1  25.2  24.7  25.0 196616800     22.9
##  8 AAPL   2016-01-13  25.1  25.3  24.3  24.3 249758400     22.3
##  9 AAPL   2016-01-14  24.5  25.1  23.9  24.9 252680400     22.8
## 10 AAPL   2016-01-15  24.0  24.4  23.8  24.3 319335600     22.3
## # … with 494 more rows
### Method 2: Map a tibble with stocks in first column
#### Method 2A: Make a tibble

stock_list <- tibble(stocks = c("AAPL", "JPM", "CVX"),
                     industry = c("Technology", "Financial", "Energy"))
stock_list
## # A tibble: 3 × 2
##   stocks industry  
##   <chr>  <chr>     
## 1 AAPL   Technology
## 2 JPM    Financial 
## 3 CVX    Energy
stock_list %>%
    tq_get(get = "stock.prices", from = "2016-01-01", to = "2017-01-01")
## # A tibble: 756 × 9
##    stocks industry   date        open  high   low close    volume adjusted
##    <chr>  <chr>      <date>     <dbl> <dbl> <dbl> <dbl>     <dbl>    <dbl>
##  1 AAPL   Technology 2016-01-04  25.7  26.3  25.5  26.3 270597600     24.2
##  2 AAPL   Technology 2016-01-05  26.4  26.5  25.6  25.7 223164000     23.5
##  3 AAPL   Technology 2016-01-06  25.1  25.6  25.0  25.2 273829600     23.1
##  4 AAPL   Technology 2016-01-07  24.7  25.0  24.1  24.1 324377600     22.1
##  5 AAPL   Technology 2016-01-08  24.6  24.8  24.2  24.2 283192000     22.2
##  6 AAPL   Technology 2016-01-11  24.7  24.8  24.3  24.6 198957600     22.6
##  7 AAPL   Technology 2016-01-12  25.1  25.2  24.7  25.0 196616800     22.9
##  8 AAPL   Technology 2016-01-13  25.1  25.3  24.3  24.3 249758400     22.3
##  9 AAPL   Technology 2016-01-14  24.5  25.1  23.9  24.9 252680400     22.8
## 10 AAPL   Technology 2016-01-15  24.0  24.4  23.8  24.3 319335600     22.3
## # … with 746 more rows

Method 2B: Use index or exchange

tq_index("DOW")
## # A tibble: 30 × 8
##    symbol company                    ident…¹ sedol weight sector share…² local…³
##    <chr>  <chr>                      <chr>   <chr>  <dbl> <chr>    <dbl> <chr>  
##  1 UNH    UnitedHealth Group Incorp… 91324P… 2917… 0.113  Healt… 5781069 USD    
##  2 GS     Goldman Sachs Group Inc.   38141G… 2407… 0.0663 Finan… 5781069 USD    
##  3 HD     Home Depot Inc.            437076… 2434… 0.0638 Consu… 5781069 USD    
##  4 AMGN   Amgen Inc.                 031162… 2023… 0.0553 Healt… 5781069 USD    
##  5 MCD    McDonald's Corporation     580135… 2550… 0.0534 Consu… 5781069 USD    
##  6 MSFT   Microsoft Corporation      594918… 2588… 0.0508 Infor… 5781069 USD    
##  7 CAT    Caterpillar Inc.           149123… 2180… 0.0405 Indus… 5781069 USD    
##  8 V      Visa Inc. Class A          92826C… B2PZ… 0.0404 Infor… 5781069 USD    
##  9 HON    Honeywell International I… 438516… 2020… 0.0391 Indus… 5781069 USD    
## 10 JNJ    Johnson & Johnson          478160… 2475… 0.0367 Healt… 5781069 USD    
## # … with 20 more rows, and abbreviated variable names ¹​identifier,
## #   ²​shares_held, ³​local_currency

Doesn’t work again… tq_exchange(“NYSE”)

tq_index("DOW") %>%
  slice(1:3) %>%
  tq_get(get = "stock.prices")
## # A tibble: 8,139 × 15
##    symbol company   ident…¹ sedol weight sector share…² local…³ date        open
##    <chr>  <chr>     <chr>   <chr>  <dbl> <chr>    <dbl> <chr>   <date>     <dbl>
##  1 UNH    UnitedHe… 91324P… 2917…  0.113 Healt… 5781069 USD     2012-01-03  51.2
##  2 UNH    UnitedHe… 91324P… 2917…  0.113 Healt… 5781069 USD     2012-01-04  51.3
##  3 UNH    UnitedHe… 91324P… 2917…  0.113 Healt… 5781069 USD     2012-01-05  51.9
##  4 UNH    UnitedHe… 91324P… 2917…  0.113 Healt… 5781069 USD     2012-01-06  52.8
##  5 UNH    UnitedHe… 91324P… 2917…  0.113 Healt… 5781069 USD     2012-01-09  52.6
##  6 UNH    UnitedHe… 91324P… 2917…  0.113 Healt… 5781069 USD     2012-01-10  53.0
##  7 UNH    UnitedHe… 91324P… 2917…  0.113 Healt… 5781069 USD     2012-01-11  52.5
##  8 UNH    UnitedHe… 91324P… 2917…  0.113 Healt… 5781069 USD     2012-01-12  53.2
##  9 UNH    UnitedHe… 91324P… 2917…  0.113 Healt… 5781069 USD     2012-01-13  52.7
## 10 UNH    UnitedHe… 91324P… 2917…  0.113 Healt… 5781069 USD     2012-01-17  53.0
## # … with 8,129 more rows, 5 more variables: high <dbl>, low <dbl>, close <dbl>,
## #   volume <dbl>, adjusted <dbl>, and abbreviated variable names ¹​identifier,
## #   ²​shares_held, ³​local_currency

Scaling the Mutation of Financial Data

data("FANG")

FANG
## # A tibble: 4,032 × 8
##    symbol date        open  high   low close    volume adjusted
##    <chr>  <date>     <dbl> <dbl> <dbl> <dbl>     <dbl>    <dbl>
##  1 FB     2013-01-02  27.4  28.2  27.4  28    69846400     28  
##  2 FB     2013-01-03  27.9  28.5  27.6  27.8  63140600     27.8
##  3 FB     2013-01-04  28.0  28.9  27.8  28.8  72715400     28.8
##  4 FB     2013-01-07  28.7  29.8  28.6  29.4  83781800     29.4
##  5 FB     2013-01-08  29.5  29.6  28.9  29.1  45871300     29.1
##  6 FB     2013-01-09  29.7  30.6  29.5  30.6 104787700     30.6
##  7 FB     2013-01-10  30.6  31.5  30.3  31.3  95316400     31.3
##  8 FB     2013-01-11  31.3  32.0  31.1  31.7  89598000     31.7
##  9 FB     2013-01-14  32.1  32.2  30.6  31.0  98892800     31.0
## 10 FB     2013-01-15  30.6  31.7  29.9  30.1 173242600     30.1
## # … with 4,022 more rows
FANG_returns_yearly <- FANG %>%
  group_by(symbol) %>%
  tq_transmute(select     = adjusted, 
               mutate_fun = periodReturn, 
               period     = "yearly", 
               col_rename = "yearly.returns") 

FANG_returns_yearly %>%
  ggplot(aes(x = year(date), y = yearly.returns, fill = symbol)) +
  geom_bar(position = "dodge", stat = "identity") +
  labs(title = "FANG: Annual Returns", 
       subtitle = "Mutating at scale is quick and easy!",
       y = "Returns", x = "", color = "") +
  scale_y_continuous(labels = scales::percent) +
  coord_flip() +
  theme_tq() +
  scale_fill_tq()

Modeling Financial Data using purrr

Example: Applying a Regression Model to Detect a Positive Trend

Analyze a Single Stock

AAPL <- tq_get("AAPL", from = "2007-01-01", to = "2016-12-31")
AAPL
## # A tibble: 2,518 × 8
##    symbol date        open  high   low close     volume adjusted
##    <chr>  <date>     <dbl> <dbl> <dbl> <dbl>      <dbl>    <dbl>
##  1 AAPL   2007-01-03  3.08  3.09  2.92  2.99 1238319600     2.56
##  2 AAPL   2007-01-04  3.00  3.07  2.99  3.06  847260400     2.61
##  3 AAPL   2007-01-05  3.06  3.08  3.01  3.04  834741600     2.59
##  4 AAPL   2007-01-08  3.07  3.09  3.05  3.05  797106800     2.61
##  5 AAPL   2007-01-09  3.09  3.32  3.04  3.31 3349298400     2.82
##  6 AAPL   2007-01-10  3.38  3.49  3.34  3.46 2952880000     2.96
##  7 AAPL   2007-01-11  3.43  3.46  3.40  3.42 1440252800     2.92
##  8 AAPL   2007-01-12  3.38  3.40  3.33  3.38 1312690400     2.89
##  9 AAPL   2007-01-16  3.42  3.47  3.41  3.47 1244076400     2.96
## 10 AAPL   2007-01-17  3.48  3.49  3.39  3.39 1646260000     2.90
## # … with 2,508 more rows
get_annual_returns <- function(stock.returns) {
  stock.returns %>%
    tq_transmute(select     = adjusted, 
                 mutate_fun = periodReturn, 
                 type       = "log", 
                 period     = "yearly")
}

AAPL_annual_log_returns <- get_annual_returns(AAPL)
AAPL_annual_log_returns
## # A tibble: 10 × 2
##    date       yearly.returns
##    <date>              <dbl>
##  1 2007-12-31         0.860 
##  2 2008-12-31        -0.842 
##  3 2009-12-31         0.904 
##  4 2010-12-31         0.426 
##  5 2011-12-30         0.228 
##  6 2012-12-31         0.282 
##  7 2013-12-31         0.0776
##  8 2014-12-31         0.341 
##  9 2015-12-31        -0.0306
## 10 2016-12-30         0.118
AAPL_annual_log_returns %>%
  ggplot(aes(x = year(date), y = yearly.returns)) + 
  geom_hline(yintercept = 0, color = palette_light()[[1]]) +
  geom_point(size = 2, color = palette_light()[[3]]) +
  geom_line(size = 1, color = palette_light()[[3]]) + 
  geom_smooth(method = "lm", se = FALSE) +
  labs(title = "AAPL: Visualizing Trends in Annual Returns",
       x = "", y = "Annual Returns", color = "") +
  theme_tq()

mod <- lm(yearly.returns ~ year(date), data = AAPL_annual_log_returns)
mod
## 
## Call:
## lm(formula = yearly.returns ~ year(date), data = AAPL_annual_log_returns)
## 
## Coefficients:
## (Intercept)   year(date)  
##    58.86279     -0.02915
library(broom)
tidy(mod)
## # A tibble: 2 × 5
##   term        estimate std.error statistic p.value
##   <chr>          <dbl>     <dbl>     <dbl>   <dbl>
## 1 (Intercept)  58.9     113.         0.520   0.617
## 2 year(date)   -0.0291    0.0562    -0.518   0.618
get_model <- function(stock_data) {
  annual_returns <- get_annual_returns(stock_data)
  mod <- lm(yearly.returns ~ year(date), data = annual_returns)
  tidy(mod)
}

get_model(AAPL)
## # A tibble: 2 × 5
##   term        estimate std.error statistic p.value
##   <chr>          <dbl>     <dbl>     <dbl>   <dbl>
## 1 (Intercept)  58.9     113.         0.520   0.617
## 2 year(date)   -0.0291    0.0562    -0.518   0.618

Scale to Many Stocks

set.seed(10)
stocks_tbl <- tq_index("SP500") %>%
  sample_n(5) 
stocks_tbl
## # A tibble: 5 × 8
##   symbol company                    ident…¹ sedol  weight sector share…² local…³
##   <chr>  <chr>                      <chr>   <chr>   <dbl> <chr>    <dbl> <chr>  
## 1 XRAY   DENTSPLY SIRONA Inc.       24906P… BYNP… 2.02e-4 Healt… 2356969 USD    
## 2 OXY    Occidental Petroleum Corp… 674599… 2655… 1.58e-3 Energy 8115123 USD    
## 3 ANSS   ANSYS Inc.                 03662Q… 2045… 5.73e-4 Infor…  939783 USD    
## 4 J      Jacobs Solutions Inc.      46982L… BNGC… 4.79e-4 Indus… 1404679 USD    
## 5 HAS    Hasbro Inc.                418056… 2414… 2.86e-4 Consu… 1387904 USD    
## # … with abbreviated variable names ¹​identifier, ²​shares_held, ³​local_currency
stocks_model_stats <- stocks_tbl %>%
  select(symbol, company) %>%
  tq_get(from = "2007-01-01", to = "2016-12-31") %>%
  
  # Nest 
  group_by(symbol, company) %>%
  nest() %>%
  
  # Apply the get_model() function to the new "nested" data column
  mutate(model = map(data, get_model)) %>%
  
  # Unnest and collect slope
  unnest(model) %>%
  filter(term == "year(date)") %>%
  arrange(desc(estimate)) %>%
  select(-term)

stocks_model_stats
## # A tibble: 5 × 7
## # Groups:   symbol, company [5]
##   symbol company                       data     estimate std.e…¹ stati…² p.value
##   <chr>  <chr>                         <list>      <dbl>   <dbl>   <dbl>   <dbl>
## 1 HAS    Hasbro Inc.                   <tibble>  0.0162   0.0264  0.615    0.556
## 2 XRAY   DENTSPLY SIRONA Inc.          <tibble>  0.00142  0.0268  0.0531   0.959
## 3 J      Jacobs Solutions Inc.         <tibble> -0.00240  0.0507 -0.0474   0.963
## 4 ANSS   ANSYS Inc.                    <tibble> -0.0259   0.0312 -0.830    0.431
## 5 OXY    Occidental Petroleum Corpora… <tibble> -0.0317   0.0264 -1.20     0.264
## # … with abbreviated variable names ¹​std.error, ²​statistic

Error Handling when Scaling

tq_get("XYZ", "stock.prices")
## [1] NA

Bad Apples Fail Gracefully, tq_get

c("AAPL", "GOOG", "BAD APPLE") %>%
  tq_get(get = "stock.prices", complete_cases = TRUE)
## # A tibble: 5,426 × 8
##    symbol date        open  high   low close    volume adjusted
##    <chr>  <date>     <dbl> <dbl> <dbl> <dbl>     <dbl>    <dbl>
##  1 AAPL   2012-01-03  14.6  14.7  14.6  14.7 302220800     12.5
##  2 AAPL   2012-01-04  14.6  14.8  14.6  14.8 260022000     12.6
##  3 AAPL   2012-01-05  14.8  14.9  14.7  14.9 271269600     12.7
##  4 AAPL   2012-01-06  15.0  15.1  15.0  15.1 318292800     12.9
##  5 AAPL   2012-01-09  15.2  15.3  15.0  15.1 394024400     12.9
##  6 AAPL   2012-01-10  15.2  15.2  15.1  15.1 258196400     12.9
##  7 AAPL   2012-01-11  15.1  15.1  15.0  15.1 215084800     12.9
##  8 AAPL   2012-01-12  15.1  15.1  15.0  15.0 212587200     12.8
##  9 AAPL   2012-01-13  15.0  15.0  15.0  15.0 226021600     12.8
## 10 AAPL   2012-01-17  15.2  15.2  15.1  15.2 242897200     13.0
## # … with 5,416 more rows
c("AAPL", "GOOG", "BAD APPLE") %>%
  tq_get(get = "stock.prices", complete_cases = FALSE)
## # A tibble: 5,427 × 8
##    symbol date        open  high   low close    volume adjusted
##    <chr>  <date>     <dbl> <dbl> <dbl> <dbl>     <dbl>    <dbl>
##  1 AAPL   2012-01-03  14.6  14.7  14.6  14.7 302220800     12.5
##  2 AAPL   2012-01-04  14.6  14.8  14.6  14.8 260022000     12.6
##  3 AAPL   2012-01-05  14.8  14.9  14.7  14.9 271269600     12.7
##  4 AAPL   2012-01-06  15.0  15.1  15.0  15.1 318292800     12.9
##  5 AAPL   2012-01-09  15.2  15.3  15.0  15.1 394024400     12.9
##  6 AAPL   2012-01-10  15.2  15.2  15.1  15.1 258196400     12.9
##  7 AAPL   2012-01-11  15.1  15.1  15.0  15.1 215084800     12.9
##  8 AAPL   2012-01-12  15.1  15.1  15.0  15.0 212587200     12.8
##  9 AAPL   2012-01-13  15.0  15.0  15.0  15.0 226021600     12.8
## 10 AAPL   2012-01-17  15.2  15.2  15.1  15.2 242897200     13.0
## # … with 5,417 more rows

Charting with TidyQuant

Prerequisites

library(tidyverse)
library(tidyquant)  

# Use FANG data set
data("FANG") 

# Get AAPL and AMZN Stock Prices
AAPL <- tq_get("AAPL", get = "stock.prices", from = "2015-09-01", to = "2016-12-31")
AMZN <- tq_get("AMZN", get = "stock.prices", from = "2000-01-01", to = "2016-12-31")

end <- as_date("2016-12-31")

Chart Types

Line Chart

AAPL %>%
  ggplot(aes(x = date, y = close)) +
  geom_line() +
  labs(title = "AAPL Line Chart", y = "Closing Price", x = "") + 
  theme_tq()

Bar Chart

AAPL %>%
  ggplot(aes(x = date, y = close)) +
  geom_barchart(aes(open = open, high = high, low = low, close = close)) +
  labs(title = "AAPL Bar Chart", y = "Closing Price", x = "") + 
  theme_tq()

AAPL %>%
  ggplot(aes(x = date, y = close)) +
  geom_barchart(aes(open = open, high = high, low = low, close = close)) +
  labs(title = "AAPL Bar Chart", 
       subtitle = "Zoomed in using coord_x_date",
       y = "Closing Price", x = "") + 
  coord_x_date(xlim = c(end - weeks(6), end),
               ylim = c(100, 120)) + 
  theme_tq()

AAPL %>%
  ggplot(aes(x = date, y = close)) +
  geom_barchart(aes(open = open, high = high, low = low, close = close),
                colour_up = "darkgreen", colour_down = "darkred", size = 1) +
  labs(title = "AAPL Bar Chart", 
       subtitle = "Zoomed in, Experimenting with Formatting",
       y = "Closing Price", x = "") + 
  coord_x_date(xlim = c(end - weeks(6), end),
               ylim = c(100, 120)) + 
  theme_tq()

Candlestick Chart

AAPL %>%
  ggplot(aes(x = date, y = close)) +
  geom_candlestick(aes(open = open, high = high, low = low, close = close)) +
  labs(title = "AAPL Candlestick Chart", y = "Closing Price", x = "") +
  theme_tq()

AAPL %>%
  ggplot(aes(x = date, y = close)) +
  geom_candlestick(aes(open = open, high = high, low = low, close = close)) +
  labs(title = "AAPL Candlestick Chart", 
       subtitle = "Zoomed in using coord_x_date",
       y = "Closing Price", x = "") + 
  coord_x_date(xlim = c(end - weeks(6), end),
               ylim = c(100, 120)) + 
  theme_tq()

AAPL %>%
  ggplot(aes(x = date, y = close)) +
  geom_candlestick(aes(open = open, high = high, low = low, close = close),
                   colour_up = "darkgreen", colour_down = "darkred", 
                   fill_up  = "darkgreen", fill_down  = "darkred") +
  labs(title = "AAPL Candlestick Chart", 
       subtitle = "Zoomed in, Experimenting with Formatting",
       y = "Closing Price", x = "") + 
  coord_x_date(xlim = c(end - weeks(6), end),
               ylim = c(100, 120)) + 
  theme_tq()

Charting Multiple Securities

start <- end - weeks(6)
FANG %>%
  filter(date >= start - days(2 * 15)) %>%
  ggplot(aes(x = date, y = close, group = symbol)) +
  geom_candlestick(aes(open = open, high = high, low = low, close = close)) +
  labs(title = "FANG Candlestick Chart", 
       subtitle = "Experimenting with Mulitple Stocks",
       y = "Closing Price", x = "") + 
  coord_x_date(xlim = c(start, end)) +
  facet_wrap(~ symbol, ncol = 2, scale = "free_y") + 
  theme_tq()

start <- end - weeks(6)
FANG %>%
  filter(date >= start - days(2 * 15)) %>%
  ggplot(aes(x = date, y = close, group = symbol)) +
  geom_candlestick(aes(open = open, high = high, low = low, close = close)) +
  geom_ma(ma_fun = SMA, n = 15, color = "darkblue", size = 1) +
  labs(title = "FANG Candlestick Chart", 
       subtitle = "Experimenting with Mulitple Stocks",
       y = "Closing Price", x = "") + 
  coord_x_date(xlim = c(start, end)) +
  facet_wrap(~ symbol, ncol = 2, scale = "free_y") +
  theme_tq()

Performance Analysis with TidyQuant

Quick Example

library(tidyverse)
library(tidyquant)

Ra <- c("AAPL", "GOOG", "NFLX") %>%
  tq_get(get  = "stock.prices",
         from = "2010-01-01",
         to   = "2015-12-31") %>%
  group_by(symbol) %>%
  tq_transmute(select     = adjusted, 
               mutate_fun = periodReturn, 
               period     = "monthly", 
               col_rename = "Ra")
Ra
## # A tibble: 216 × 3
## # Groups:   symbol [3]
##    symbol date            Ra
##    <chr>  <date>       <dbl>
##  1 AAPL   2010-01-29 -0.103 
##  2 AAPL   2010-02-26  0.0654
##  3 AAPL   2010-03-31  0.148 
##  4 AAPL   2010-04-30  0.111 
##  5 AAPL   2010-05-28 -0.0161
##  6 AAPL   2010-06-30 -0.0208
##  7 AAPL   2010-07-30  0.0227
##  8 AAPL   2010-08-31 -0.0550
##  9 AAPL   2010-09-30  0.167 
## 10 AAPL   2010-10-29  0.0607
## # … with 206 more rows
Rb <- "XLK" %>%
  tq_get(get  = "stock.prices",
         from = "2010-01-01",
         to   = "2015-12-31") %>%
  tq_transmute(select     = adjusted, 
               mutate_fun = periodReturn, 
               period     = "monthly", 
               col_rename = "Rb")
Rb
## # A tibble: 72 × 2
##    date            Rb
##    <date>       <dbl>
##  1 2010-01-29 -0.0993
##  2 2010-02-26  0.0348
##  3 2010-03-31  0.0684
##  4 2010-04-30  0.0126
##  5 2010-05-28 -0.0748
##  6 2010-06-30 -0.0540
##  7 2010-07-30  0.0745
##  8 2010-08-31 -0.0561
##  9 2010-09-30  0.117 
## 10 2010-10-29  0.0578
## # … with 62 more rows
RaRb <- left_join(Ra, Rb, by = c("date" = "date"))
RaRb
## # A tibble: 216 × 4
## # Groups:   symbol [3]
##    symbol date            Ra      Rb
##    <chr>  <date>       <dbl>   <dbl>
##  1 AAPL   2010-01-29 -0.103  -0.0993
##  2 AAPL   2010-02-26  0.0654  0.0348
##  3 AAPL   2010-03-31  0.148   0.0684
##  4 AAPL   2010-04-30  0.111   0.0126
##  5 AAPL   2010-05-28 -0.0161 -0.0748
##  6 AAPL   2010-06-30 -0.0208 -0.0540
##  7 AAPL   2010-07-30  0.0227  0.0745
##  8 AAPL   2010-08-31 -0.0550 -0.0561
##  9 AAPL   2010-09-30  0.167   0.117 
## 10 AAPL   2010-10-29  0.0607  0.0578
## # … with 206 more rows
RaRb_capm <- RaRb %>%
  tq_performance(Ra = Ra, 
                 Rb = Rb, 
                 performance_fun = table.CAPM)
RaRb_capm
## # A tibble: 3 × 13
## # Groups:   symbol [3]
##   symbol ActivePr…¹  Alpha Annua…²  Beta `Beta-` `Beta+` Corre…³ Corre…⁴ Infor…⁵
##   <chr>       <dbl>  <dbl>   <dbl> <dbl>   <dbl>   <dbl>   <dbl>   <dbl>   <dbl>
## 1 AAPL        0.119 0.0089   0.112 1.11    0.578  1.04    0.659    0       0.628
## 2 GOOG        0.034 0.0028   0.034 1.14    1.39   1.16    0.644    0       0.168
## 3 NFLX        0.447 0.053    0.859 0.384  -1.52   0.0045  0.0817   0.495   0.637
## # … with 3 more variables: `R-squared` <dbl>, TrackingError <dbl>,
## #   TreynorRatio <dbl>, and abbreviated variable names ¹​ActivePremium,
## #   ²​AnnualizedAlpha, ³​Correlation, ⁴​`Correlationp-value`, ⁵​InformationRatio
RaRb_capm %>% select(symbol, Alpha, Beta)
## # A tibble: 3 × 3
## # Groups:   symbol [3]
##   symbol  Alpha  Beta
##   <chr>   <dbl> <dbl>
## 1 AAPL   0.0089 1.11 
## 2 GOOG   0.0028 1.14 
## 3 NFLX   0.053  0.384

Workflow

Individual Assets

args(SharpeRatio)
## function (R, Rf = 0, p = 0.95, FUN = c("StdDev", "VaR", "ES"), 
##     weights = NULL, annualize = FALSE, SE = FALSE, SE.control = NULL, 
##     ...) 
## NULL

Step 1A: Get stock prices

stock_prices <- c("AAPL", "GOOG", "NFLX") %>%
  tq_get(get  = "stock.prices",
         from = "2010-01-01",
         to   = "2015-12-31")
stock_prices
## # A tibble: 4,527 × 8
##    symbol date        open  high   low close    volume adjusted
##    <chr>  <date>     <dbl> <dbl> <dbl> <dbl>     <dbl>    <dbl>
##  1 AAPL   2010-01-04  7.62  7.66  7.58  7.64 493729600     6.53
##  2 AAPL   2010-01-05  7.66  7.70  7.62  7.66 601904800     6.54
##  3 AAPL   2010-01-06  7.66  7.69  7.53  7.53 552160000     6.43
##  4 AAPL   2010-01-07  7.56  7.57  7.47  7.52 477131200     6.42
##  5 AAPL   2010-01-08  7.51  7.57  7.47  7.57 447610800     6.46
##  6 AAPL   2010-01-11  7.6   7.61  7.44  7.50 462229600     6.41
##  7 AAPL   2010-01-12  7.47  7.49  7.37  7.42 594459600     6.33
##  8 AAPL   2010-01-13  7.42  7.53  7.29  7.52 605892000     6.42
##  9 AAPL   2010-01-14  7.50  7.52  7.46  7.48 432894000     6.39
## 10 AAPL   2010-01-15  7.53  7.56  7.35  7.35 594067600     6.28
## # … with 4,517 more rows

Step 2A: Mutate to returns

stock_returns_monthly <- stock_prices %>%
  group_by(symbol) %>%
  tq_transmute(select     = adjusted, 
               mutate_fun = periodReturn, 
               period     = "monthly", 
               col_rename = "Ra")
stock_returns_monthly
## # A tibble: 216 × 3
## # Groups:   symbol [3]
##    symbol date            Ra
##    <chr>  <date>       <dbl>
##  1 AAPL   2010-01-29 -0.103 
##  2 AAPL   2010-02-26  0.0654
##  3 AAPL   2010-03-31  0.148 
##  4 AAPL   2010-04-30  0.111 
##  5 AAPL   2010-05-28 -0.0161
##  6 AAPL   2010-06-30 -0.0208
##  7 AAPL   2010-07-30  0.0227
##  8 AAPL   2010-08-31 -0.0550
##  9 AAPL   2010-09-30  0.167 
## 10 AAPL   2010-10-29  0.0607
## # … with 206 more rows

Step 4: Analyze Performance

stock_returns_monthly %>%
  tq_performance(
    Ra = Ra, 
    Rb = NULL, 
    performance_fun = SharpeRatio
  )
## # A tibble: 3 × 4
## # Groups:   symbol [3]
##   symbol `ESSharpe(Rf=0%,p=95%)` `StdDevSharpe(Rf=0%,p=95%)` VaRSharpe(Rf=0%,p…¹
##   <chr>                    <dbl>                       <dbl>               <dbl>
## 1 AAPL                     0.173                       0.292               0.218
## 2 GOOG                     0.129                       0.203               0.157
## 3 NFLX                     0.237                       0.284               0.272
## # … with abbreviated variable name ¹​`VaRSharpe(Rf=0%,p=95%)`
stock_returns_monthly %>%
  tq_performance(
    Ra = Ra, 
    Rb = NULL, 
    performance_fun = SharpeRatio, 
    Rf = 0.03 / 12, 
    p  = 0.99
  )
## # A tibble: 3 × 4
## # Groups:   symbol [3]
##   symbol `ESSharpe(Rf=0.2%,p=99%)` `StdDevSharpe(Rf=0.2%,p=99%)` VaRSharpe(Rf=…¹
##   <chr>                      <dbl>                         <dbl>           <dbl>
## 1 AAPL                      0.116                          0.258          0.134 
## 2 GOOG                      0.0826                         0.170          0.0998
## 3 NFLX                      0.115                          0.272          0.142 
## # … with abbreviated variable name ¹​`VaRSharpe(Rf=0.2%,p=99%)`

Portfolios (Asset Groups)

Single Portfolio

Steps 1A and 2A: Asset Period Returns

stock_returns_monthly <- c("AAPL", "GOOG", "NFLX") %>%
  tq_get(get  = "stock.prices",
         from = "2010-01-01",
         to   = "2015-12-31") %>%
  group_by(symbol) %>%
  tq_transmute(select     = adjusted, 
               mutate_fun = periodReturn, 
               period     = "monthly", 
               col_rename = "Ra")
stock_returns_monthly
## # A tibble: 216 × 3
## # Groups:   symbol [3]
##    symbol date            Ra
##    <chr>  <date>       <dbl>
##  1 AAPL   2010-01-29 -0.103 
##  2 AAPL   2010-02-26  0.0654
##  3 AAPL   2010-03-31  0.148 
##  4 AAPL   2010-04-30  0.111 
##  5 AAPL   2010-05-28 -0.0161
##  6 AAPL   2010-06-30 -0.0208
##  7 AAPL   2010-07-30  0.0227
##  8 AAPL   2010-08-31 -0.0550
##  9 AAPL   2010-09-30  0.167 
## 10 AAPL   2010-10-29  0.0607
## # … with 206 more rows

Steps 1B and 2B: Baseline Period Returns

baseline_returns_monthly <- "XLK" %>%
  tq_get(get  = "stock.prices",
         from = "2010-01-01",
         to   = "2015-12-31") %>%
  tq_transmute(select     = adjusted, 
               mutate_fun = periodReturn, 
               period     = "monthly", 
               col_rename = "Rb")
baseline_returns_monthly
## # A tibble: 72 × 2
##    date            Rb
##    <date>       <dbl>
##  1 2010-01-29 -0.0993
##  2 2010-02-26  0.0348
##  3 2010-03-31  0.0684
##  4 2010-04-30  0.0126
##  5 2010-05-28 -0.0748
##  6 2010-06-30 -0.0540
##  7 2010-07-30  0.0745
##  8 2010-08-31 -0.0561
##  9 2010-09-30  0.117 
## 10 2010-10-29  0.0578
## # … with 62 more rows

Step 3A: Aggregate to Portfolio Period Returns

wts <- c(0.5, 0.0, 0.5)
portfolio_returns_monthly <- stock_returns_monthly %>%
  tq_portfolio(assets_col  = symbol, 
               returns_col = Ra, 
               weights     = wts, 
               col_rename  = "Ra")
portfolio_returns_monthly
## # A tibble: 72 × 2
##    date            Ra
##    <date>       <dbl>
##  1 2010-01-29  0.0307
##  2 2010-02-26  0.0629
##  3 2010-03-31  0.130 
##  4 2010-04-30  0.239 
##  5 2010-05-28  0.0682
##  6 2010-06-30 -0.0219
##  7 2010-07-30 -0.0272
##  8 2010-08-31  0.116 
##  9 2010-09-30  0.251 
## 10 2010-10-29  0.0674
## # … with 62 more rows
wts_map <- tibble(
  symbols = c("AAPL", "NFLX"),
  weights = c(0.5, 0.5)
)
wts_map
## # A tibble: 2 × 2
##   symbols weights
##   <chr>     <dbl>
## 1 AAPL        0.5
## 2 NFLX        0.5
stock_returns_monthly %>%
  tq_portfolio(assets_col  = symbol, 
               returns_col = Ra, 
               weights     = wts_map, 
               col_rename  = "Ra_using_wts_map")
## # A tibble: 72 × 2
##    date       Ra_using_wts_map
##    <date>                <dbl>
##  1 2010-01-29           0.0307
##  2 2010-02-26           0.0629
##  3 2010-03-31           0.130 
##  4 2010-04-30           0.239 
##  5 2010-05-28           0.0682
##  6 2010-06-30          -0.0219
##  7 2010-07-30          -0.0272
##  8 2010-08-31           0.116 
##  9 2010-09-30           0.251 
## 10 2010-10-29           0.0674
## # … with 62 more rows

Step 3B: Merging Ra and Rb

RaRb_single_portfolio <- left_join(portfolio_returns_monthly, 
                                   baseline_returns_monthly,
                                   by = "date")
RaRb_single_portfolio
## # A tibble: 72 × 3
##    date            Ra      Rb
##    <date>       <dbl>   <dbl>
##  1 2010-01-29  0.0307 -0.0993
##  2 2010-02-26  0.0629  0.0348
##  3 2010-03-31  0.130   0.0684
##  4 2010-04-30  0.239   0.0126
##  5 2010-05-28  0.0682 -0.0748
##  6 2010-06-30 -0.0219 -0.0540
##  7 2010-07-30 -0.0272  0.0745
##  8 2010-08-31  0.116  -0.0561
##  9 2010-09-30  0.251   0.117 
## 10 2010-10-29  0.0674  0.0578
## # … with 62 more rows

Step 4: Computing the CAPM Table

RaRb_single_portfolio %>%
  tq_performance(Ra = Ra, Rb = Rb, performance_fun = table.CAPM)
## # A tibble: 1 × 12
##   ActiveP…¹  Alpha Annua…²  Beta `Beta-` `Beta+` Corre…³ Corre…⁴ Infor…⁵ R-squ…⁶
##       <dbl>  <dbl>   <dbl> <dbl>   <dbl>   <dbl>   <dbl>   <dbl>   <dbl>   <dbl>
## 1     0.327 0.0299   0.425 0.754  -0.243   0.503   0.283  0.0162   0.858  0.0799
## # … with 2 more variables: TrackingError <dbl>, TreynorRatio <dbl>, and
## #   abbreviated variable names ¹​ActivePremium, ²​AnnualizedAlpha, ³​Correlation,
## #   ⁴​`Correlationp-value`, ⁵​InformationRatio, ⁶​`R-squared`

Multiple Portfolios

stock_returns_monthly <- c("AAPL", "GOOG", "NFLX") %>%
  tq_get(get  = "stock.prices",
         from = "2010-01-01",
         to   = "2015-12-31") %>%
  group_by(symbol) %>%
  tq_transmute(select     = adjusted, 
               mutate_fun = periodReturn, 
               period     = "monthly", 
               col_rename = "Ra")

baseline_returns_monthly <- "XLK" %>%
  tq_get(get  = "stock.prices",
         from = "2010-01-01",
         to   = "2015-12-31") %>%
  tq_transmute(select     = adjusted, 
               mutate_fun = periodReturn, 
               period     = "monthly", 
               col_rename = "Rb")

Step 3A: Aggregate Portfolio Returns for Multiple Portfolios

stock_returns_monthly_multi <- stock_returns_monthly %>%
  tq_repeat_df(n = 3)
stock_returns_monthly_multi
## # A tibble: 648 × 4
## # Groups:   portfolio [3]
##    portfolio symbol date            Ra
##        <int> <chr>  <date>       <dbl>
##  1         1 AAPL   2010-01-29 -0.103 
##  2         1 AAPL   2010-02-26  0.0654
##  3         1 AAPL   2010-03-31  0.148 
##  4         1 AAPL   2010-04-30  0.111 
##  5         1 AAPL   2010-05-28 -0.0161
##  6         1 AAPL   2010-06-30 -0.0208
##  7         1 AAPL   2010-07-30  0.0227
##  8         1 AAPL   2010-08-31 -0.0550
##  9         1 AAPL   2010-09-30  0.167 
## 10         1 AAPL   2010-10-29  0.0607
## # … with 638 more rows
weights <- c(
  0.50, 0.25, 0.25,
  0.25, 0.50, 0.25,
  0.25, 0.25, 0.50
)
stocks <- c("AAPL", "GOOG", "NFLX")
weights_table <-  tibble(stocks) %>%
  tq_repeat_df(n = 3) %>%
  bind_cols(tibble(weights)) %>%
  group_by(portfolio)
weights_table
## # A tibble: 9 × 3
## # Groups:   portfolio [3]
##   portfolio stocks weights
##       <int> <chr>    <dbl>
## 1         1 AAPL      0.5 
## 2         1 GOOG      0.25
## 3         1 NFLX      0.25
## 4         2 AAPL      0.25
## 5         2 GOOG      0.5 
## 6         2 NFLX      0.25
## 7         3 AAPL      0.25
## 8         3 GOOG      0.25
## 9         3 NFLX      0.5
portfolio_returns_monthly_multi <- stock_returns_monthly_multi %>%
  tq_portfolio(assets_col  = symbol, 
               returns_col = Ra, 
               weights     = weights_table, 
               col_rename  = "Ra")
portfolio_returns_monthly_multi
## # A tibble: 216 × 3
## # Groups:   portfolio [3]
##    portfolio date              Ra
##        <int> <date>         <dbl>
##  1         1 2010-01-29 -0.0489  
##  2         1 2010-02-26  0.0482  
##  3         1 2010-03-31  0.123   
##  4         1 2010-04-30  0.145   
##  5         1 2010-05-28  0.0245  
##  6         1 2010-06-30 -0.0308  
##  7         1 2010-07-30  0.000600
##  8         1 2010-08-31  0.0474  
##  9         1 2010-09-30  0.222   
## 10         1 2010-10-29  0.0789  
## # … with 206 more rows

Steps 3B and 4: Merging and Assessing Performance

RaRb_multiple_portfolio <- left_join(portfolio_returns_monthly_multi, 
                                     baseline_returns_monthly,
                                     by = "date")
RaRb_multiple_portfolio
## # A tibble: 216 × 4
## # Groups:   portfolio [3]
##    portfolio date              Ra      Rb
##        <int> <date>         <dbl>   <dbl>
##  1         1 2010-01-29 -0.0489   -0.0993
##  2         1 2010-02-26  0.0482    0.0348
##  3         1 2010-03-31  0.123     0.0684
##  4         1 2010-04-30  0.145     0.0126
##  5         1 2010-05-28  0.0245   -0.0748
##  6         1 2010-06-30 -0.0308   -0.0540
##  7         1 2010-07-30  0.000600  0.0745
##  8         1 2010-08-31  0.0474   -0.0561
##  9         1 2010-09-30  0.222     0.117 
## 10         1 2010-10-29  0.0789    0.0578
## # … with 206 more rows
RaRb_multiple_portfolio %>%
  tq_performance(Ra = Ra, Rb = Rb, performance_fun = table.CAPM)
## # A tibble: 3 × 13
## # Groups:   portfolio [3]
##   portfolio Activ…¹  Alpha Annua…²  Beta `Beta-` `Beta+` Corre…³ Corre…⁴ Infor…⁵
##       <int>   <dbl>  <dbl>   <dbl> <dbl>   <dbl>   <dbl>   <dbl>   <dbl>   <dbl>
## 1         1   0.231 0.0193   0.258 0.908   0.312   0.741   0.472  0        0.917
## 2         2   0.219 0.0192   0.256 0.886   0.436   0.660   0.438  0.0001   0.809
## 3         3   0.319 0.0308   0.439 0.721  -0.179   0.394   0.252  0.0325   0.774
## # … with 3 more variables: `R-squared` <dbl>, TrackingError <dbl>,
## #   TreynorRatio <dbl>, and abbreviated variable names ¹​ActivePremium,
## #   ²​AnnualizedAlpha, ³​Correlation, ⁴​`Correlationp-value`, ⁵​InformationRatio
RaRb_multiple_portfolio %>%
  tq_performance(Ra = Ra, Rb = NULL, performance_fun = SharpeRatio)
## # A tibble: 3 × 4
## # Groups:   portfolio [3]
##   portfolio `ESSharpe(Rf=0%,p=95%)` `StdDevSharpe(Rf=0%,p=95%)` VaRSharpe(Rf=0…¹
##       <int>                   <dbl>                       <dbl>            <dbl>
## 1         1                   0.172                       0.355            0.263
## 2         2                   0.146                       0.334            0.236
## 3         3                   0.150                       0.317            0.238
## # … with abbreviated variable name ¹​`VaRSharpe(Rf=0%,p=95%)`

Available Functions

tq_performance_fun_options()
## $table.funs
##  [1] "table.AnnualizedReturns" "table.Arbitrary"        
##  [3] "table.Autocorrelation"   "table.CAPM"             
##  [5] "table.CaptureRatios"     "table.Correlation"      
##  [7] "table.Distributions"     "table.DownsideRisk"     
##  [9] "table.DownsideRiskRatio" "table.DrawdownsRatio"   
## [11] "table.HigherMoments"     "table.InformationRatio" 
## [13] "table.RollingPeriods"    "table.SFM"              
## [15] "table.SpecificRisk"      "table.Stats"            
## [17] "table.TrailingPeriods"   "table.UpDownRatios"     
## [19] "table.Variability"      
## 
## $CAPM.funs
##  [1] "CAPM.alpha"       "CAPM.beta"        "CAPM.beta.bear"   "CAPM.beta.bull"  
##  [5] "CAPM.CML"         "CAPM.CML.slope"   "CAPM.dynamic"     "CAPM.epsilon"    
##  [9] "CAPM.jensenAlpha" "CAPM.RiskPremium" "CAPM.SML.slope"   "TimingRatio"     
## [13] "MarketTiming"    
## 
## $SFM.funs
## [1] "SFM.alpha"       "SFM.beta"        "SFM.CML"         "SFM.CML.slope"  
## [5] "SFM.dynamic"     "SFM.epsilon"     "SFM.jensenAlpha"
## 
## $descriptive.funs
## [1] "mean"           "sd"             "min"            "max"           
## [5] "cor"            "mean.geometric" "mean.stderr"    "mean.LCL"      
## [9] "mean.UCL"      
## 
## $annualized.funs
## [1] "Return.annualized"        "Return.annualized.excess"
## [3] "sd.annualized"            "SharpeRatio.annualized"  
## 
## $VaR.funs
## [1] "VaR"  "ES"   "ETL"  "CDD"  "CVaR"
## 
## $moment.funs
##  [1] "var"              "cov"              "skewness"         "kurtosis"        
##  [5] "CoVariance"       "CoSkewness"       "CoSkewnessMatrix" "CoKurtosis"      
##  [9] "CoKurtosisMatrix" "M3.MM"            "M4.MM"            "BetaCoVariance"  
## [13] "BetaCoSkewness"   "BetaCoKurtosis"  
## 
## $drawdown.funs
## [1] "AverageDrawdown"   "AverageLength"     "AverageRecovery"  
## [4] "DrawdownDeviation" "DrawdownPeak"      "maxDrawdown"      
## 
## $Bacon.risk.funs
## [1] "MeanAbsoluteDeviation" "Frequency"             "SharpeRatio"          
## [4] "MSquared"              "MSquaredExcess"        "HurstIndex"           
## 
## $Bacon.regression.funs
##  [1] "CAPM.alpha"       "CAPM.beta"        "CAPM.epsilon"     "CAPM.jensenAlpha"
##  [5] "SystematicRisk"   "SpecificRisk"     "TotalRisk"        "TreynorRatio"    
##  [9] "AppraisalRatio"   "FamaBeta"         "Selectivity"      "NetSelectivity"  
## 
## $Bacon.relative.risk.funs
## [1] "ActivePremium"    "ActiveReturn"     "TrackingError"    "InformationRatio"
## 
## $Bacon.drawdown.funs
## [1] "PainIndex"     "PainRatio"     "CalmarRatio"   "SterlingRatio"
## [5] "BurkeRatio"    "MartinRatio"   "UlcerIndex"   
## 
## $Bacon.downside.risk.funs
##  [1] "DownsideDeviation"     "DownsidePotential"     "DownsideFrequency"    
##  [4] "SemiDeviation"         "SemiVariance"          "UpsideRisk"           
##  [7] "UpsidePotentialRatio"  "UpsideFrequency"       "BernardoLedoitRatio"  
## [10] "DRatio"                "Omega"                 "OmegaSharpeRatio"     
## [13] "OmegaExcessReturn"     "SortinoRatio"          "M2Sortino"            
## [16] "Kappa"                 "VolatilitySkewness"    "AdjustedSharpeRatio"  
## [19] "SkewnessKurtosisRatio" "ProspectRatio"        
## 
## $misc.funs
## [1] "KellyRatio"   "Modigliani"   "UpDownRatios"

table.Stats

RaRb_multiple_portfolio %>%
  tq_performance(Ra = Ra, Rb = NULL, performance_fun = table.Stats)
## # A tibble: 3 × 17
## # Groups:   portfolio [3]
##   portfolio Arith…¹ Geome…² Kurto…³ LCLMe…⁴ Maximum Median Minimum   NAs Obser…⁵
##       <int>   <dbl>   <dbl>   <dbl>   <dbl>   <dbl>  <dbl>   <dbl> <dbl>   <dbl>
## 1         1  0.0293  0.0259    1.14  0.0099   0.222 0.0307  -0.266     0      72
## 2         2  0.029   0.0252    1.65  0.0086   0.227 0.037   -0.3       0      72
## 3         3  0.0388  0.0313    1.81  0.01     0.370 0.046   -0.403     0      72
## # … with 7 more variables: Quartile1 <dbl>, Quartile3 <dbl>, SEMean <dbl>,
## #   Skewness <dbl>, Stdev <dbl>, `UCLMean(0.95)` <dbl>, Variance <dbl>, and
## #   abbreviated variable names ¹​ArithmeticMean, ²​GeometricMean, ³​Kurtosis,
## #   ⁴​`LCLMean(0.95)`, ⁵​Observations

table.CAPM

RaRb_multiple_portfolio %>%
  tq_performance(Ra = Ra, Rb = Rb, performance_fun = table.CAPM)
## # A tibble: 3 × 13
## # Groups:   portfolio [3]
##   portfolio Activ…¹  Alpha Annua…²  Beta `Beta-` `Beta+` Corre…³ Corre…⁴ Infor…⁵
##       <int>   <dbl>  <dbl>   <dbl> <dbl>   <dbl>   <dbl>   <dbl>   <dbl>   <dbl>
## 1         1   0.231 0.0193   0.258 0.908   0.312   0.741   0.472  0        0.917
## 2         2   0.219 0.0192   0.256 0.886   0.436   0.660   0.438  0.0001   0.809
## 3         3   0.319 0.0308   0.439 0.721  -0.179   0.394   0.252  0.0325   0.774
## # … with 3 more variables: `R-squared` <dbl>, TrackingError <dbl>,
## #   TreynorRatio <dbl>, and abbreviated variable names ¹​ActivePremium,
## #   ²​AnnualizedAlpha, ³​Correlation, ⁴​`Correlationp-value`, ⁵​InformationRatio

table.AnnualizedReturns

RaRb_multiple_portfolio %>%
  tq_performance(Ra = Ra, Rb = NULL, performance_fun = table.AnnualizedReturns)
## # A tibble: 3 × 4
## # Groups:   portfolio [3]
##   portfolio AnnualizedReturn `AnnualizedSharpe(Rf=0%)` AnnualizedStdDev
##       <int>            <dbl>                     <dbl>            <dbl>
## 1         1            0.360                      1.26            0.286
## 2         2            0.348                      1.16            0.301
## 3         3            0.448                      1.06            0.424

table.Correlation

RaRb_multiple_portfolio %>%
  tq_performance(Ra = Ra, Rb = Rb, performance_fun = table.Correlation)
## # A tibble: 3 × 5
## # Groups:   portfolio [3]
##   portfolio `p-value` `Lower CI` `Upper CI` to.Rb
##       <int>     <dbl>      <dbl>      <dbl> <dbl>
## 1         1 0.0000284     0.270       0.634 0.472
## 2         2 0.000122      0.229       0.608 0.438
## 3         3 0.0325        0.0220      0.457 0.252

table.DownsideRisk

RaRb_multiple_portfolio %>%
  tq_performance(Ra = Ra, Rb = NULL, performance_fun = table.DownsideRisk)
## # A tibble: 3 × 12
## # Groups:   portfolio [3]
##   portfolio DownsideDe…¹ Downs…² Downs…³ GainD…⁴ Histo…⁵ Histo…⁶ LossD…⁷ Maxim…⁸
##       <int>        <dbl>   <dbl>   <dbl>   <dbl>   <dbl>   <dbl>   <dbl>   <dbl>
## 1         1       0.045   0.0488  0.045   0.0538  -0.141 -0.0811  0.0517   0.402
## 2         2       0.0501  0.0538  0.0501  0.0528  -0.162 -0.0842  0.0588   0.438
## 3         3       0.0684  0.0721  0.0684  0.0831  -0.222 -0.131   0.0813   0.595
## # … with 3 more variables: `ModifiedES(95%)` <dbl>, `ModifiedVaR(95%)` <dbl>,
## #   SemiDeviation <dbl>, and abbreviated variable names
## #   ¹​`DownsideDeviation(0%)`, ²​`DownsideDeviation(MAR=10%)`,
## #   ³​`DownsideDeviation(Rf=0%)`, ⁴​GainDeviation, ⁵​`HistoricalES(95%)`,
## #   ⁶​`HistoricalVaR(95%)`, ⁷​LossDeviation, ⁸​MaximumDrawdown

table.DownsideRiskRatio

RaRb_multiple_portfolio %>%
  tq_performance(Ra = Ra, Rb = NULL, performance_fun = table.DownsideRiskRatio)
## # A tibble: 3 × 9
## # Groups:   portfolio [3]
##   portfolio Annualiseddo…¹ Downs…² month…³ Omega Omega…⁴ Sorti…⁵ Upsid…⁶ Upsid…⁷
##       <int>          <dbl>   <dbl>   <dbl> <dbl>   <dbl>   <dbl>   <dbl>   <dbl>
## 1         1          0.156  0.0198  0.045   2.48    1.48   0.652  0.0491   0.986
## 2         2          0.173  0.0217  0.0501  2.34    1.34   0.579  0.0507   0.952
## 3         3          0.237  0.0294  0.0684  2.32    1.32   0.567  0.0681   0.937
## # … with abbreviated variable names ¹​Annualiseddownsiderisk,
## #   ²​Downsidepotential, ³​monthlydownsiderisk, ⁴​`Omega-sharperatio`,
## #   ⁵​Sortinoratio, ⁶​Upsidepotential, ⁷​Upsidepotentialratio

table.HigherMoments

RaRb_multiple_portfolio %>%
  tq_performance(Ra = Ra, Rb = Rb, performance_fun = table.HigherMoments)
## # A tibble: 3 × 6
## # Groups:   portfolio [3]
##   portfolio BetaCoKurtosis BetaCoSkewness BetaCoVariance CoKurtosis CoSkewness
##       <int>          <dbl>          <dbl>          <dbl>      <dbl>      <dbl>
## 1         1          0.756          0.196          0.908          0          0
## 2         2          0.772          1.71           0.886          0          0
## 3         3          0.455          0.369          0.721          0          0

table.InformationRatio

RaRb_multiple_portfolio %>%
  tq_performance(Ra = Ra, Rb = Rb, performance_fun = table.InformationRatio)
## # A tibble: 3 × 4
## # Groups:   portfolio [3]
##   portfolio AnnualisedTrackingError InformationRatio TrackingError
##       <int>                   <dbl>            <dbl>         <dbl>
## 1         1                   0.252            0.917        0.0728
## 2         2                   0.271            0.809        0.0782
## 3         3                   0.412            0.774        0.119

table.Variability

RaRb_multiple_portfolio %>%
  tq_performance(Ra = Ra, Rb = NULL, performance_fun = table.Variability)
## # A tibble: 3 × 4
## # Groups:   portfolio [3]
##   portfolio AnnualizedStdDev MeanAbsolutedeviation monthlyStdDev
##       <int>            <dbl>                 <dbl>         <dbl>
## 1         1            0.286                0.0658        0.0825
## 2         2            0.301                0.0679        0.0868
## 3         3            0.424                0.091         0.122

VaR

RaRb_multiple_portfolio %>%
  tq_performance(Ra = Ra, Rb = NULL, performance_fun = VaR)
## # A tibble: 3 × 2
## # Groups:   portfolio [3]
##   portfolio    VaR
##       <int>  <dbl>
## 1         1 -0.111
## 2         2 -0.123
## 3         3 -0.163

SharpeRatio

RaRb_multiple_portfolio %>%
  tq_performance(Ra = Ra, Rb = NULL, performance_fun = SharpeRatio)
## # A tibble: 3 × 4
## # Groups:   portfolio [3]
##   portfolio `ESSharpe(Rf=0%,p=95%)` `StdDevSharpe(Rf=0%,p=95%)` VaRSharpe(Rf=0…¹
##       <int>                   <dbl>                       <dbl>            <dbl>
## 1         1                   0.172                       0.355            0.263
## 2         2                   0.146                       0.334            0.236
## 3         3                   0.150                       0.317            0.238
## # … with abbreviated variable name ¹​`VaRSharpe(Rf=0%,p=95%)`

Customizing using the …

Customizing tq_portfolio

args(Return.portfolio)
## function (R, weights = NULL, wealth.index = FALSE, contribution = FALSE, 
##     geometric = TRUE, rebalance_on = c(NA, "years", "quarters", 
##         "months", "weeks", "days"), value = 1, verbose = FALSE, 
##     ...) 
## NULL
wts <- c(0.5, 0.0, 0.5)
portfolio_returns_monthly <- stock_returns_monthly %>%
  tq_portfolio(assets_col  = symbol, 
               returns_col = Ra, 
               weights     = wts, 
               col_rename  = "Ra")

portfolio_returns_monthly %>%
  ggplot(aes(x = date, y = Ra)) +
  geom_bar(stat = "identity", fill = palette_light()[[1]]) +
  labs(title = "Portfolio Returns",
       subtitle = "50% AAPL, 0% GOOG, and 50% NFLX",
       caption = "Shows an above-zero trend meaning positive returns",
       x = "", y = "Monthly Returns") +
  geom_smooth(method = "lm") +
  theme_tq() +
  scale_color_tq() +
  scale_y_continuous(labels = scales::percent)

wts <- c(0.5, 0, 0.5)
portfolio_growth_monthly <- stock_returns_monthly %>%
  tq_portfolio(assets_col   = symbol, 
               returns_col  = Ra, 
               weights      = wts, 
               col_rename   = "investment.growth",
               wealth.index = TRUE) %>%
  mutate(investment.growth = investment.growth * 10000)

portfolio_growth_monthly %>%
  ggplot(aes(x = date, y = investment.growth)) +
  geom_line(size = 2, color = palette_light()[[1]]) +
  labs(title = "Portfolio Growth",
       subtitle = "50% AAPL, 0% GOOG, and 50% NFLX",
       caption = "Now we can really visualize performance!",
       x = "", y = "Portfolio Value") +
  geom_smooth(method = "loess") +
  theme_tq() +
  scale_color_tq() +
  scale_y_continuous(labels = scales::dollar)

portfolio_growth_monthly_multi <- stock_returns_monthly_multi %>%
  tq_portfolio(assets_col   = symbol, 
               returns_col  = Ra, 
               weights      = weights_table, 
               col_rename   = "investment.growth",
               wealth.index = TRUE) %>%
  mutate(investment.growth = investment.growth * 10000)

portfolio_growth_monthly_multi %>%
  ggplot(aes(x = date, y = investment.growth, color = factor(portfolio))) +
  geom_line(size = 2) +
  labs(title = "Portfolio Growth",
       subtitle = "Comparing Multiple Portfolios",
       caption = "Portfolio 3 is a Standout!",
       x = "", y = "Portfolio Value",
       color = "Portfolio") +
  geom_smooth(method = "loess") +
  theme_tq() +
  scale_color_tq() +
  scale_y_continuous(labels = scales::dollar)

Customizing tq_performance

args(SharpeRatio)
## function (R, Rf = 0, p = 0.95, FUN = c("StdDev", "VaR", "ES"), 
##     weights = NULL, annualize = FALSE, SE = FALSE, SE.control = NULL, 
##     ...) 
## NULL
RaRb_multiple_portfolio %>%
  tq_performance(Ra              = Ra, 
                 performance_fun = SharpeRatio)
## # A tibble: 3 × 4
## # Groups:   portfolio [3]
##   portfolio `ESSharpe(Rf=0%,p=95%)` `StdDevSharpe(Rf=0%,p=95%)` VaRSharpe(Rf=0…¹
##       <int>                   <dbl>                       <dbl>            <dbl>
## 1         1                   0.172                       0.355            0.263
## 2         2                   0.146                       0.334            0.236
## 3         3                   0.150                       0.317            0.238
## # … with abbreviated variable name ¹​`VaRSharpe(Rf=0%,p=95%)`
RaRb_multiple_portfolio %>%
  tq_performance(Ra              = Ra, 
                 performance_fun = SharpeRatio,
                 Rf              = 0.03 / 12)
## # A tibble: 3 × 4
## # Groups:   portfolio [3]
##   portfolio `ESSharpe(Rf=0.2%,p=95%)` `StdDevSharpe(Rf=0.2%,p=95%)` VaRSharpe(…¹
##       <int>                     <dbl>                         <dbl>        <dbl>
## 1         1                     0.157                         0.325        0.241
## 2         2                     0.134                         0.305        0.216
## 3         3                     0.141                         0.296        0.222
## # … with abbreviated variable name ¹​`VaRSharpe(Rf=0.2%,p=95%)`
RaRb_multiple_portfolio %>%
  tq_performance(Ra              = Ra, 
                 performance_fun = SharpeRatio,
                 Rf              = 0.03 / 12, 
                 p               = 0.99)
## # A tibble: 3 × 4
## # Groups:   portfolio [3]
##   portfolio `ESSharpe(Rf=0.2%,p=99%)` `StdDevSharpe(Rf=0.2%,p=99%)` VaRSharpe(…¹
##       <int>                     <dbl>                         <dbl>        <dbl>
## 1         1                    0.105                          0.325        0.134
## 2         2                    0.0952                         0.305        0.115
## 3         3                    0.0915                         0.296        0.117
## # … with abbreviated variable name ¹​`VaRSharpe(Rf=0.2%,p=99%)`