在一条语句中计算多个移动计算

时间:2019-03-12 10:25:50

标签: r tidyverse quantmod tidyquant

我想在一个陈述中计算所有移动均线,而不是重复自己。使用quantmod是否可行,还是需要巧妙地使用tidyeval和/或purrr?

library(tidyquant)
library(quantmod)
library(zoo)

tibble(date = as.Date('2018-01-01') + days(1:100), 
       value = 100 + cumsum(rnorm(100))) %>% 
  tq_mutate(mutate_fun = rollapply, select = "value", width = 10, FUN = mean, col_rename = "rm10") %>% 
  tq_mutate(mutate_fun = rollapply, select = "value", width = 5, FUN = mean, col_rename = "rm5") %>% 
  gather(series, value, -date) %>% 
  ggplot(aes(date, value, color = series)) + 
     geom_line()

3 个答案:

答案 0 :(得分:1)

这是使用data.table的新frollmean()函数的解决方案
需要data.table v1.12.0或更高版本。

样本数据

library( data.table )
set.seed(123)
dt <- data.table( date = as.Date('2018-01-01') + days(1:100), 
            value = 100 + cumsum(rnorm(100)))

代码

#set windwos you want to roll on
windows <- c(5,10)
#create a rm+window column for each roll
dt[, ( paste0( "rm", windows ) ) := lapply( windows, function(x) frollmean( value, x)) ]

输出

head( dt, 15 )
#           date     value      rm5     rm10
#  1: 2018-01-02  99.43952       NA       NA
#  2: 2018-01-03  99.20935       NA       NA
#  3: 2018-01-04 100.76806       NA       NA
#  4: 2018-01-05 100.83856       NA       NA
#  5: 2018-01-06 100.96785 100.2447       NA
#  6: 2018-01-07 102.68292 100.8933       NA
#  7: 2018-01-08 103.14383 101.6802       NA
#  8: 2018-01-09 101.87877 101.9024       NA
#  9: 2018-01-10 101.19192 101.9731       NA
# 10: 2018-01-11 100.74626 101.9287 101.0867
# 11: 2018-01-12 101.97034 101.7862 101.3398
# 12: 2018-01-13 102.33015 101.6235 101.6519
# 13: 2018-01-14 102.73092 101.7939 101.8482
# 14: 2018-01-15 102.84161 102.1239 102.0485
# 15: 2018-01-16 102.28577 102.4318 102.1802

情节

#plot molten data
library(ggplot2)
ggplot( data = melt(dt, id.vars = c("date") ), 
        aes(x = date, y = value, colour = variable)) + 
  geom_line()

enter image description here

更新-分组数据

library(data.table)
library(ggplot2)
set.seed(123)
#changed the sample data a bit, to get different values for grp=1 and grp=2
dt <- data.table(grp = rep(1:2, each = 100), date = rep(as.Date('2018-01-01') + days(1:100), 2), value = 100 + cumsum(rnorm(200)))
dt[, ( paste0( "rm", windows ) ) := lapply( windows, function(x) frollmean( value, x)), by = "grp" ]
ggplot( data = melt(dt, id.vars = c("date", "grp") ), 
        aes(x = date, y = value, colour = variable)) + 
  geom_line() +
  facet_wrap(~grp, nrow = 1)

enter image description here

答案 1 :(得分:0)

在此示例中,我使用通过getSymbols的{​​{1}}函数下载的AAPL调整后收盘价

让我们说您想要具有以下长度的SMA:

quantmod

现在像这样创建SMA:

smaLength = c(30,35,40,46,53,61,70,81,93)

结果:

lapply(smaLength,function(x) SMA(AAPL$AAPL.Adjusted,x)) %>% do.call(cbind,.) %>% tail()

答案 2 :(得分:0)

定义输入,然后套用在宽度上,为每个将它们合并在一起的对象创建一个rollmean。最后画出来。

library(ggplot2)
library(magrittr)
library(zoo)

set.seed(123)
w <- c(1, 5, 10)
zoo(100 * cumsum(rnorm(100)), as.Date("2018-01-01") + 1:100) %>%
  lapply(w, rollmeanr, x = .) %>%
  do.call("merge", .) %>%
  setNames(w) %>%
  autoplot(facet = NULL)

screenshot