tidyquant icon indicating copy to clipboard operation
tidyquant copied to clipboard

feature:helper function to turn tidy data into RaRb format shown in vignette

Open apsteinmetz opened this issue 7 years ago • 2 comments

You may think this is overly complicating matters. If so, please disregard. I do like to retrieve a full set of asset returns including mutual funds, their benchmarks and the risk free rate as a set when using the PerformanceAnalytics package. Long format makes it easy to compare arbitrary sets of series in ggplot. Yet many performance functions require wide data to compare the asset, its benchmark and the risk-free rate.

I took a stab at making a helper function to convert long tidy to wide RaRb format by matching a list of assets and their benchmarks. You can optionally specify the symbol for the time-varying risk free rate.

I am using the blp_bdh_tq data set I created in this issue note

# make RaRb helper function

#set what we want to pull from the long-style data frame
#match asset symbols to their benchmark symbols
RaRb_names<-tibble(Ra_name=c('AGTHX','FDEGX'),
                   Rb_name=c('SPX','SPX'))

#Rf could be a list matching number of rows in the RaRb_names table if 
# we are looking at assets in more than one currency,
# otherwise a single name value.
Rf_names<-'LD12TRUU' 

#names of the relevant columns in the data frame                   
name_col<-'symbol'
return_col<- 'return'

#the actual helper function
make_RaRbRf<-function(x,name_col,return_col,RaRb_names,Rf_names=NULL) {
  #function to take a list of portfolios/funds/stocks and 
  # merge with a list of benchmarks and, optionally, risk-free rate.
  # no error checking.
  #I am looping rather than applying. Shrug.
  #I really hate the squirrelly way we have to pass variable column names to filter and select 
  RaRbRf<-tibble()
  for (n in 1:nrow(RaRb_names)) {
    Ra<-x %>% 
      ungroup() %>% 
      filter_(paste(name_col," == '",RaRb_names$Ra_name[n],"'",sep='')) %>% 
      select(date,asset=get(name_col),Ra=get(return_col))
    Rb<-x %>% 
      ungroup() %>% 
      filter_(paste(name_col," == '",RaRb_names$Rb_name[n],"'",sep='')) %>% 
      select(date=date,benchmark=get(name_col),Rb=get(return_col))
    if (!(is.null(Rf_names))){
      if (length(Rf_names)<nrow(RaRb_names)){  #unmatched vectors. use only first Rf rate
        Rf<-x %>% 
          ungroup() %>% 
          filter_(paste(name_col," == '",Rf_names[1],"'",sep='')) %>% 
          select(date=date,Rf_rate=get(name_col),Rf=get(return_col))
      } else{ #multiple Rf rates
        Rf<-x %>% 
          ungroup() %>% 
          filter_(paste(name_col," == '",Rf_names[n],"'",sep='')) %>% 
          select(date=date,Rf_rate=get(name_col),Rf=get(return_col))
        
      }
      RaRbRf<-Ra %>% 
        left_join(Rb,by='date') %>% 
        left_join(Rf,by='date') %>% 
        bind_rows(RaRbRf)
    } else{
      RaRbRf<-Ra %>% 
        left_join(Rb,by='date') %>% 
        bind_rows(RaRbRf)
    }
  }
  return (group_by(RaRbRf,asset))
} #END FUNCTION

# test it out
make_RaRbRf(blp_bdh_tq,name_col,return_col,RaRb_names,Rf_names)
#Source: local data frame [252 x 7]
#Groups: asset [2]
#         date asset            Ra benchmark          Rb  Rf_rate          Rf
#       <date> <chr>         <dbl>     <chr>       <dbl>    <chr>       <dbl>
#1  2007-01-31 FDEGX  2.956467e-02       SPX  0.01614987 LD12TRUU 0.004266667
#2  2007-02-28 FDEGX -2.517091e-06       SPX -0.01956115 LD12TRUU 0.004300000
#3  2007-03-31 FDEGX  1.007866e-03       SPX  0.01118683 LD12TRUU 0.004200000
#4  2007-04-30 FDEGX  5.135944e-02       SPX  0.04429756 LD12TRUU 0.004091667
#5  2007-05-31 FDEGX  3.831427e-02       SPX  0.03489320 LD12TRUU 0.003941667
#6  2007-06-30 FDEGX  1.752771e-02       SPX -0.01661234 LD12TRUU 0.004016667
#7  2007-07-31 FDEGX  1.541267e-02       SPX -0.03100609 LD12TRUU 0.004133333
#8  2007-08-31 FDEGX -4.464409e-03       SPX  0.01498840 LD12TRUU 0.003341667
#9  2007-09-30 FDEGX  6.143493e-02       SPX  0.03740037 LD12TRUU 0.003183333
#10 2007-10-31 FDEGX  6.041405e-02       SPX  0.01590713 LD12TRUU 0.003283333
## ... with 242 more rows

#without Rf
make_RaRbRf(blp_bdh_tq,name_col,return_col,RaRb_names)

apsteinmetz avatar Jun 23 '17 03:06 apsteinmetz

It may actually be very easy to just leverage the PerformanceAnalytics functions by getting tq_performance() to accept a column name as an argument for Rf. This should be fairly simple since the PerfAnalytics functions are already setup to accept the risk free rate.

mdancho84 avatar Jun 23 '17 03:06 mdancho84

Yes. I was surprised it didn't work to being with since tq_performance just wraps the PerformanceAnalytics function and passes through whatever you send it.

apsteinmetz avatar Jun 23 '17 20:06 apsteinmetz