时间序列分析工具箱——tidyquant

时间序列分析工具箱——tidyquant

本文翻译自《Demo Week: class(Monday) <- tidyquant》

原文链接:http://www.business-science.io/code-tools/2017/10/23/demo_week_tidyquant.html

tidyquant 的用途

使用 tidyquant 的六大理由:

  1. 直接从 Yahoo! Finance、FRED Database、Quandl 等数据源获得网络数据
  2. 简化 xts、zoo、quantmod、TTR 和 PerformanceAnalytics 中金融及时间序列函数的调用
  3. 可视化: 漂亮的主题以及针对金融的 geom(例如 geom_ma
  4. 构建投资组合
  5. 财务分析以及投资组合归因方法
  6. 为金融与时间序列分析提供坚实的基础tidyquant 会自动加载 tidyverse 和各种金融、时间序列分析包,这使得它成为任何金融或时间序列分析的理想起点。

该教程将会介绍前两个主题。其他主题请查看 tidyquant 的文档

加载包

请先安装 tidyquant

# Install libraries
install.packages("tidyquant")

加载 tidyquant

# Load libraries
library(tidyquant) # Loads tidyverse, financial pkgs, used to get and manipulate data

tq_get:获得数据

使用 tq_get() 获得网络数据。tidyquant 提供了大量 API 用于连接包括 Yahoo! Finance、FRED Economic Database、Quandl 等等在内的数据源。

从 Yahoo! Finance 获得股票数据

将一列股票代码传入 tq_get(),同时设置 get = "stock.prices"。可以添加 fromto 参数设置数据的起始和结束日期。

# Get Stock Prices from Yahoo! Finance

# Create a vector of stock symbols
FANG_symbols <- c("FB", "AMZN", "NFLX", "GOOG")

# Pass symbols to tq_get to get daily prices
FANG_data_d <- FANG_symbols %>%
    tq_get(
        get = "stock.prices",
        from = "2014-01-01", to = "2016-12-31")

# Show the result
FANG_data_d
## # A tibble: 3,024 x 8
##    symbol       date  open  high   low close   volume adjusted
##     <chr>     <date> <dbl> <dbl> <dbl> <dbl>    <dbl>    <dbl>
##  1     FB 2014-01-02 54.83 55.22 54.19 54.71 43195500    54.71
##  2     FB 2014-01-03 55.02 55.65 54.53 54.56 38246200    54.56
##  3     FB 2014-01-06 54.42 57.26 54.05 57.20 68852600    57.20
##  4     FB 2014-01-07 57.70 58.55 57.22 57.92 77207400    57.92
##  5     FB 2014-01-08 57.60 58.41 57.23 58.23 56682400    58.23
##  6     FB 2014-01-09 58.65 58.96 56.65 57.22 92253300    57.22
##  7     FB 2014-01-10 57.13 58.30 57.06 57.94 42449500    57.94
##  8     FB 2014-01-13 57.91 58.25 55.38 55.91 63010900    55.91
##  9     FB 2014-01-14 56.46 57.78 56.10 57.74 37503600    57.74
## 10     FB 2014-01-15 57.98 58.57 57.27 57.60 33663400    57.60
## # ... with 3,014 more rows

可以使用 ggplot2 画出上述结果。使用 tidyquant 提供的主题(调用 theme_tq()scale_color_tq())实现金融、商务风格的可视化效果。

# Plot data
FANG_data_d %>%
    ggplot(aes(x = date, y = adjusted, color = symbol)) + 
    geom_line() +
    facet_wrap(~ symbol, ncol = 2, scales = "free_y") +
    theme_tq() +
    scale_color_tq() +
    labs(title = "Visualize Financial Data")

从 FRED 获得经济数据

下面的例子来自房地美副首席经济学家 Leonard Kieffer 近期的文章——《A (TIDYQUANT)UM OF SOLACE》。我们将使用 tq_get() 并设置参数 get = "economic.data" 来从 FRED 经济数据库获取数据。

将一列 FRED 代码传递到 tq_get()

# Economic Data from the FRED

# Create a vector of FRED symbols
FRED_symbols <- c('ETOTALUSQ176N',    # All housing units
                  'EVACANTUSQ176N',   # Vacant
                  'EYRVACUSQ176N',    # Year-round vacant
                  'ERENTUSQ176N')     # Vacant for rent

# Pass symbols to tq_get to get economic data
FRED_data_m <- FRED_symbols %>%
    tq_get(get="economic.data", from = "2001-04-01")

# Show results
FRED_data_m
## # A tibble: 260 x 3
##           symbol       date  price
##            <chr>     <date>  <int>
##  1 ETOTALUSQ176N 2001-04-01 117786
##  2 ETOTALUSQ176N 2001-07-01 118216
##  3 ETOTALUSQ176N 2001-10-01 118635
##  4 ETOTALUSQ176N 2002-01-01 119061
##  5 ETOTALUSQ176N 2002-04-01 119483
##  6 ETOTALUSQ176N 2002-07-01 119909
##  7 ETOTALUSQ176N 2002-10-01 120350
##  8 ETOTALUSQ176N 2003-01-01 120792
##  9 ETOTALUSQ176N 2003-04-01 121233
## 10 ETOTALUSQ176N 2003-07-01 121682
## # ... with 250 more rows

和金融数据一样,使用 ggplot2 画图,使用 tidyquant 提供的主题(调用 theme_tq()scale_color_tq())实现金融、商务风格的可视化效果。

# Plot data
FRED_data_m %>%
    ggplot(aes(x = date, y = price, color = symbol)) + 
    geom_line() +
    facet_wrap(~ symbol, ncol = 2, scales = "free_y") +
    theme_tq() +
    scale_color_tq() +
    labs(title = "Visualize Economic Data")

使用 tq_transmutetq_mutate 转换数据

函数 tq_transmute()tq_mutate() 可以使 xtszooquantmod 中的函数调用更“tidy”。这里直接介绍使用,“可用函数”一节罗列了已经整合进 tidyquant 的若干其他函数。

tq_transmute

tq_transmute()tq_mutate() 之间的区别在于 tq_transmute() 将返回一个新的数据框对象,而 tq_mutate() 则在原有数据框的基础上横向添加数据(例如,增加一列)。当数据因为改变周期而改变行数时,tq_transmute() 特别有用。

改变周期与 tq_transmute

下面的例子将改变数据的周期,从每日数据变为月度数据。这时,你需要使用 tq_transmute() 来完成这一操作,因为数据的行数改变了。

# Change periodicity from daily to monthly using to.period from xts
FANG_data_m <- FANG_data_d %>%
    group_by(symbol) %>%
    tq_transmute(
        select      = adjusted,
        mutate_fun  = to.period,
        period      = "months")

FANG_data_m
## # A tibble: 144 x 3
## # Groups:   symbol [4]
##    symbol       date adjusted
##     <chr>     <date>    <dbl>
##  1     FB 2014-01-31    62.57
##  2     FB 2014-02-28    68.46
##  3     FB 2014-03-31    60.24
##  4     FB 2014-04-30    59.78
##  5     FB 2014-05-30    63.30
##  6     FB 2014-06-30    67.29
##  7     FB 2014-07-31    72.65
##  8     FB 2014-08-29    74.82
##  9     FB 2014-09-30    79.04
## 10     FB 2014-10-31    74.99
## # ... with 134 more rows

改变数据周期可以缩减数据量。一些注意事项项:

  • theme_tq()scale_color_tq() 用来绘制商务风格的图。
  • 如果要改变数据的周期或者进行其他基于时间的操作,请留意后续关于 tibbletime 包的教程,tibbletime 以另外一种标准处理基于时间的操作。

周期改变前,数据太多

# Daily data
FANG_data_d %>%
    ggplot(aes(date, adjusted, color = symbol)) +
    geom_point() +
    geom_line() +
    facet_wrap(~ symbol, ncol = 2, scales = "free_y") +
    scale_color_tq() +
    theme_tq() +
    labs(title = "Before transformation: Too Much Data")

周期改变后,容易理解

tq_transmute() 转变成月度数据后容易理解多了。

# Monthly data
FANG_data_m %>%
    ggplot(aes(date, adjusted, color = symbol)) +
    geom_point() +
    geom_line() +
    facet_wrap(~ symbol, ncol = 2, scales = "free_y") +
    scale_color_tq() +
    theme_tq() +
    labs(title = "After transformation: Easier to Understand")

tq_mutate

tq_mutate() 函数基于 xts 包为数据添加新的列。正因为这样,当返回数据不止一列时,tq_mutate() 显得特别有用(dplyr::mutate() 就没有这样的功能)。

tq_mutate 与滞后数据

一个关于 lag.xts 的例子。通常我们需要不只一列滞后数据,这正是 tq_mutate() 擅长的。下面,为原数据添加五列滞后数据。

# Lags - Get first 5 lags

# Pro Tip: Make the new column names first, then add to the `col_rename` arg
column_names <- paste0("lag", 1:5)

# First five lags are output for each group of symbols
FANG_data_d %>%
    select(symbol, date, adjusted) %>%
    group_by(symbol) %>%
    tq_mutate(
        select     = adjusted,
        mutate_fun = lag.xts,
        k          = 1:5,
        col_rename = column_names)
## # A tibble: 3,024 x 8
## # Groups:   symbol [4]
##    symbol       date adjusted  lag1  lag2  lag3  lag4  lag5
##     <chr>     <date>    <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
##  1     FB 2014-01-02    54.71    NA    NA    NA    NA    NA
##  2     FB 2014-01-03    54.56 54.71    NA    NA    NA    NA
##  3     FB 2014-01-06    57.20 54.56 54.71    NA    NA    NA
##  4     FB 2014-01-07    57.92 57.20 54.56 54.71    NA    NA
##  5     FB 2014-01-08    58.23 57.92 57.20 54.56 54.71    NA
##  6     FB 2014-01-09    57.22 58.23 57.92 57.20 54.56 54.71
##  7     FB 2014-01-10    57.94 57.22 58.23 57.92 57.20 54.56
##  8     FB 2014-01-13    55.91 57.94 57.22 58.23 57.92 57.20
##  9     FB 2014-01-14    57.74 55.91 57.94 57.22 58.23 57.92
## 10     FB 2014-01-15    57.60 57.74 55.91 57.94 57.22 58.23
## # ... with 3,014 more rows

tq_mutate 与滚动函数

另一个例子,应用 xts 中的滚动函数 roll.apply()。让我们借助函数 quantile() 得到滚动分位数。下面是每个函数的参数:

tq_mutate 的参数:

  • select = adjusted,只选择复权修正过的数据列。该参数也可以不填,或选择其他不同的列。
  • mutate_fun = rollapply,这是一个 xts 函数,将会以 “tidy” 的方式(分组)调用。

rollapply 的参数:

  • width = 5,告诉 rollapply 计算窗口的周期(长度)是多少。
  • by.column = FALSErollapply() 函数默认对每一列分别操作,然而我们要把所有列放在一起操作。
  • FUN = quantilequantile() 正是要被滚动调用的函数。

quantile 的参数:

  • probs = c(0, 0.025, ...),计算这些概率的分位数。
  • na.rm = TRUEquantile 会去掉遇到的 NA 值。
# Rolling quantile
FANG_data_d %>%
    select(symbol, date, adjusted) %>%
    group_by(symbol) %>%
    tq_mutate(
        select     = adjusted,
        mutate_fun = rollapply,
        width      = 5,
        by.column  = FALSE,
        FUN        = quantile,
        probs      = c(0, 0.025, 0.25, 0.5, 0.75, 0.975, 1),
        na.rm      = TRUE)
## # A tibble: 3,024 x 10
## # Groups:   symbol [4]
##    symbol       date adjusted   X0.  X2.5.  X25.  X50.  X75. X97.5.
##     <chr>     <date>    <dbl> <dbl>  <dbl> <dbl> <dbl> <dbl>  <dbl>
##  1     FB 2014-01-02    54.71    NA     NA    NA    NA    NA     NA
##  2     FB 2014-01-03    54.56    NA     NA    NA    NA    NA     NA
##  3     FB 2014-01-06    57.20    NA     NA    NA    NA    NA     NA
##  4     FB 2014-01-07    57.92    NA     NA    NA    NA    NA     NA
##  5     FB 2014-01-08    58.23 54.56 54.575 54.71 57.20 57.92 58.199
##  6     FB 2014-01-09    57.22 54.56 54.824 57.20 57.22 57.92 58.199
##  7     FB 2014-01-10    57.94 57.20 57.202 57.22 57.92 57.94 58.201
##  8     FB 2014-01-13    55.91 55.91 56.041 57.22 57.92 57.94 58.201
##  9     FB 2014-01-14    57.74 55.91 56.041 57.22 57.74 57.94 58.201
## 10     FB 2014-01-15    57.60 55.91 56.041 57.22 57.60 57.74 57.920
## # ... with 3,014 more rows, and 1 more variables: X100. <dbl>

可用函数

已经介绍了如何将 xts 函数和 tq_transmutetq_mutate 联合使用。还有许多 xts 函数可以以 “tidy” 的方式使用!用 tq_transmute_fun_options() 查看其他可用函数。

# Available functions
# mutate_fun =
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"
##  [4] "apply.weekly"    "apply.yearly"    "diff.xts"       
##  [7] "lag.xts"         "period.apply"    "period.max"     
## [10] "period.min"      "period.prod"     "period.sum"     
## [13] "periodicity"     "to.daily"        "to.hourly"      
## [16] "to.minutes"      "to.minutes10"    "to.minutes15"   
## [19] "to.minutes3"     "to.minutes30"    "to.minutes5"    
## [22] "to.monthly"      "to.period"       "to.quarterly"   
## [25] "to.weekly"       "to.yearly"       "to_period"      
## 
## $quantmod
##  [1] "allReturns"      "annualReturn"    "ClCl"           
##  [4] "dailyReturn"     "Delt"            "HiCl"           
##  [7] "Lag"             "LoCl"            "LoHi"           
## [10] "monthlyReturn"   "Next"            "OpCl"           
## [13] "OpHi"            "OpLo"            "OpOp"           
## [16] "periodReturn"    "quarterlyReturn" "seriesAccel"    
## [19] "seriesDecel"     "seriesDecr"      "seriesHi"       
## [22] "seriesIncr"      "seriesLo"        "weeklyReturn"   
## [25] "yearlyReturn"   
## 
## $TTR
##  [1] "adjRatios"          "ADX"                "ALMA"              
##  [4] "aroon"              "ATR"                "BBands"            
##  [7] "CCI"                "chaikinAD"          "chaikinVolatility" 
## [10] "CLV"                "CMF"                "CMO"               
## [13] "DEMA"               "DonchianChannel"    "DPO"               
## [16] "DVI"                "EMA"                "EMV"               
## [19] "EVWMA"              "GMMA"               "growth"            
## [22] "HMA"                "KST"                "lags"              
## [25] "MACD"               "MFI"                "momentum"          
## [28] "OBV"                "PBands"             "ROC"               
## [31] "rollSFM"            "RSI"                "runCor"            
## [34] "runCov"             "runMAD"             "runMax"            
## [37] "runMean"            "runMedian"          "runMin"            
## [40] "runPercentRank"     "runSD"              "runSum"            
## [43] "runVar"             "SAR"                "SMA"               
## [46] "SMI"                "SNR"                "stoch"             
## [49] "TDI"                "TRIX"               "ultimateOscillator"
## [52] "VHF"                "VMA"                "volatility"        
## [55] "VWAP"               "VWMA"               "wilderSum"         
## [58] "williamsAD"         "WMA"                "WPR"               
## [61] "ZigZag"             "ZLEMA"             
## 
## $PerformanceAnalytics
## [1] "Return.annualized"        "Return.annualized.excess"
## [3] "Return.clean"             "Return.cumulative"       
## [5] "Return.excess"            "Return.Geltner"          
## [7] "zerofill"
posted @ 2018-06-23 16:17  xuruilong100  阅读(2398)  评论(0编辑  收藏  举报