Closed apsteinmetz closed 7 years ago
Internally, the tq_performance
function looks for a date column that is in either Date
or POSIXct
class, which is insufficient. We have a much better function in timekit, tk_get_timeseries_variables()
that will find yearmon
and yearqtr
class rows and enable use in tq_performance()
and all the other core tq_
functions.
Also, we will be deprecating the tidyquant
as_xts()
and as_tibble()
functions for the more robust functions from the timekit
package: tk_xts()
and tk_tbl()
, respectively. You will not need to specify a "date" column as the timekit
functions will detect any of the main time-based classes.
I've got good news and bad news. The good news is that zoo
yearmon
and yearqtr
are integrated now with via the merge to implement the timekit
coercion functions, https://github.com/business-science/tidyquant/commit/352e30b870737b7389597b66d69cb93bbab857ad. However, there's a new issue #53 that's root is within dplyr (https://github.com/tidyverse/dplyr/issues/2921). The dplyr
issue causes yearmon
and yearqtr
classes to convert to numeric during binding and grouping operations (which are essential to the tidyverse). Unfortunately, this will need to be handled within dplyr
.
You can now do this:
library(tidyquant)
library(timekit)
set.seed(12345)
Ra <- rnorm(3*12,.06/12,.01)
Ra_tibble <- tibble(date = as.yearmon("2009-01-01")+seq(1/12,3,1/12),
Ra = Ra)
Ra_xts <- tk_xts(Ra_tibble, silent = TRUE)
Ra_tibble %>%
tq_performance(Ra = Ra, Rf = 0.02/12, performance_fun = SharpeRatio)
#> # A tibble: 1 x 3
#> `ESSharpe(Rf=0.2%,p=95%)` `StdDevSharpe(Rf=0.2%,p=95%)`
#> * <dbl> <dbl>
#> 1 0.4851708 0.5995772
#> # ... with 1 more variables: `VaRSharpe(Rf=0.2%,p=95%)` <dbl>
Ra_xts$Ra %>%
SharpeRatio(Rf = 0.02/12)
#> Ra
#> StdDev Sharpe (Rf=0.2%, p=95%): 0.5995772
#> VaR Sharpe (Rf=0.2%, p=95%): 0.6748474
#> ES Sharpe (Rf=0.2%, p=95%): 0.4851708
You just can't do this:
library(tidyquant)
FANG %>%
group_by(symbol) %>%
tq_transmute(adjusted, periodReturn, period = "monthly") %>%
mutate(date = as.yearmon(date))
#> Warning in mutate_impl(.data, dots): Vectorizing 'yearmon' elements may not
#> preserve their attributes
#> Warning in mutate_impl(.data, dots): Vectorizing 'yearmon' elements may not
#> preserve their attributes
#> Warning in mutate_impl(.data, dots): Vectorizing 'yearmon' elements may not
#> preserve their attributes
#> Warning in mutate_impl(.data, dots): Vectorizing 'yearmon' elements may not
#> preserve their attributes
#> # A tibble: 192 x 3
#> # Groups: symbol [4]
#> symbol date monthly.returns
#> <chr> <dbl> <dbl>
#> 1 FB 2013.000 0.1064285714
#> 2 FB 2013.083 -0.1204002582
#> 3 FB 2013.167 -0.0612844037
#> 4 FB 2013.250 0.0856137608
#> 5 FB 2013.333 -0.1231544833
#> 6 FB 2013.417 0.0217658727
#> 7 FB 2013.500 0.4790996977
#> 8 FB 2013.583 0.1220109272
#> 9 FB 2013.667 0.2165172871
#> 10 FB 2013.750 -0.0003981883
#> # ... with 182 more rows
When converting time series to monthly it makes sense to use the yearmon class. If you are comparing two assets from different data sources, the dates may not line up precisely. I found that happening using FRED with Yahoo. Similarly, trading days may not be equivalent across assets in different marketplaces, bonds and stocks, for example. Converting everything to yearmon when looking at monthly data forces alignment. In some cases it may introduce imprecision but for most uses it is fine. PerformanceAnalytics is fine with yearmon. tq_performance does not accept dates in yearmon form, which forces the user to convert to yearmon to ensure alignment, then convert back to date. It's not to tough to do, but it is an inconsistency.