我想计算
“紧接公告日前5,10,30个连续交易日的平均收市价,但不包括交易停止日(交易量为0或NA的日期)
例如,现在我们将2014/5/7设置为公告日。
然后是连续5天的平均价格:
平均价格(2014/5 / 7,2014 / 5 / 5,2014 / 5 / 2,2014 / 4 / 30,2014 / 4/29), 2014/5/6和2014/5/1的价格被排除在外,因为那些日子的交易量为0。2014年11月9日编辑
需要注意的一点是:每个股票的公告日不同,而且数据中的最后一个有效日期也不同,因此在计算平均值时使用tail
是不合适的。 < / p>
Date Price Volume 2014/5/9 1.42 668000 2014/5/8 1.4 2972000 2014/5/7 1.5 1180000 2014/5/6 1.59 0 2014/5/5 1.59 752000 2014/5/2 1.6 138000 2014/5/1 1.6 NA 2014/4/30 1.6 656000 2014/4/29 1.61 364000 2014/4/28 1.61 1786000 2014/4/25 1.64 1734000 2014/4/24 1.68 1130000 2014/4/23 1.68 506000 2014/4/22 1.67 354000 2014/4/21 1.7 0 2014/4/18 1.7 0 2014/4/17 1.7 1954000 2014/4/16 1.65 1788000 2014/4/15 1.71 1294000 2014/4/14 1.68 1462000
可重复代码:
require(quantmod)
require(data.table)
tickers <- c("0007.hk","1036.hk")
date_begin <- as.Date("2010-01-01")
date_end <- as.Date("2014-09-09")
# retrive data of all stocks
prices <- getSymbols(tickers, from = date_begin, to = date_end, auto.assign = TRUE)
dataset <- merge(Cl(get(prices[1])),Vo(get(prices[1])))
for (i in 2:length(prices)){
dataset <- merge(dataset, Cl(get(prices[i])),Vo(get(prices[i])))
}
# Write First
write.zoo(dataset, file = "prices.csv", sep = ",", qmethod = "double")
# Read zoo
test <- fread("prices.csv")
setnames(test, "Index", "Date")
然后我得到了一个data.table。第一列是日期,然后是每种库存的价格和数量。
实际上,原始数据包含大约40种股票的信息。列名具有相同的模式:“X”+ ticker.close,“X”+ ticker.volumn
不同股票的最后交易日不同。
所需的输出:
days 0007.HK 1036.HK 5 1.1 1.1 10 1.1 1.1 30 1.1 1.1
主要问题:
.SD和lapply和.SDCol可用于循环不同的股票。计算最后连续N天时可以使用.N。
由于宣布日不同,它变得有点复杂。
对使用quantmod或使用data.table的多个股票的单一股票的任何建议都非常欢迎!
感谢GSee和pbible提供了很好的解决方案,它非常有用。我将在稍后更新我的代码,为每个股票添加不同的公告日,并在稍后咨询。
实际上,它更像是一个xts问题而不是data.table问题。任何有关data.table的内容都会非常有用。非常感谢!
由于不同的股票有不同的公告日,我试图首先按照@pbible的逻辑制定解决方案,任何建议都将受到极大的欢迎。
library(quantmod)
tickers <- c("0007.hk","1036.hk")
date_begin <- as.Date("2010-01-01")
# Instead of making one specific date_end, different date_end is used for convenience of the following work.
date_end <- c(as.Date("2014-07-08"),as.Date("2014-05-15"))
for ( i in 1: length(date_end)) {
stocks <- getSymbols(tickers[i], from = date_begin, to = date_end[i], auto.assign = TRUE)
dataset <- cbind(Cl(get(stocks)),Vo(get(stocks)))
usable <- subset(dataset,dataset[,2] > 0 & !is.na(dataset[,2]))
sma.5 <- SMA(usable[,1],5)
sma.10 <- SMA(usable[,1],10)
sma.30 <- SMA(usable[,1],30)
col <- as.matrix(rbind(tail(sma.5,1), tail(sma.10,1), tail(sma.30,1)))
colnames(col) <- colnames(usable[,1])
rownames(col) <- c("5","10","30")
if (i == 1) {
matrix <- as.matrix(col)
}
else {matrix <- cbind(matrix,col)}
}
我得到了我想要的东西,但代码很难看。任何使它优雅的建议都非常受欢迎!
答案 0 :(得分:2)
嗯,这是一种方法。我不知道你为什么要摆脱循环,这并没有摆脱它(实际上它有一个嵌套在另一个循环中)。你正在做的一件事是在你的循环的每次迭代中在内存中增长对象(即matrix <- cbind(matrix,col)
部分是低效的)。这个答案避免了这一点。
library(quantmod)
tickers <- c("0007.hk","1036.hk")
date_begin <- as.Date("2010-01-01")
myEnv <- new.env()
date_end <- c(as.Date("2014-07-08"),as.Date("2014-05-15"))
lookback <- c(5, 10, 30) # different number of days to look back for calculating mean.
symbols <- getSymbols(tickers, from=date_begin,
to=tail(sort(date_end), 1), env=myEnv) # to=last date
end.dates <- setNames(date_end, symbols)
out <- do.call(cbind, lapply(end.dates, function(x) {
dat <- na.omit(get(names(x), pos=myEnv))[paste0("/", x)]
prc <- Cl(dat)[Vo(dat) > 0]
setNames(vapply(lookback, function(n) mean(tail(prc, n)), numeric(1)),
lookback)
}))
colnames(out) <- names(end.dates)
out
# 0007.HK 1036.HK
#5 1.080 8.344
#10 1.125 8.459
#30 1.186 8.805
一些评论......
myEnv
,用于保存您的数据,使其不会混乱您的工作区。 getSymbols
的输出(正如您在尝试中所做的那样),因为输入代码不是大写的。 lapply
循环(包含在do.call(cbind, ...)
中)。我正在遍历已命名的end.dates
向量
myEnv
获取数据,删除NAs,并将其子集设置为仅包含截至相关结束日期的数据。vapply
在不同回溯的矢量上循环并计算mean
。它包含在setNames
中,以便根据使用哪个回溯来计算每个结果。lapply
调用返回一个命名向量列表。 do.call(cbind, LIST)
与调用cbind(LIST[[1]], LIST[[2]], LIST[[3]])
相同,但LIST
可以是任意长度的列表。希望这有帮助。
答案 1 :(得分:1)
使用subset
和移动平均线(SMA)这样的事情怎么样?这是我放在一起的解决方案。
library(quantmod)
tickers <- c("0007.hk","1036.hk","cvx")
date_begin <- as.Date("2010-01-01")
date_end <- as.Date("2014-09-09")
stocks <- getSymbols(tickers, from = date_begin, to = date_end, auto.assign = TRUE)
stock3Summary <- function(stock){
dataset <- cbind(Cl(get(stock)),Vo(get(stock)))
usable <- subset(dataset,dataset[,2] > 0 & !is.na(dataset[,2]))
sma.5 <- SMA(usable[,1],5)
sma.10 <- SMA(usable[,1],10)
sma.30 <- SMA(usable[,1],30)
col <- as.matrix(rbind(tail(sma.5,1), tail(sma.10,1), tail(sma.30,1)))
colnames(col) <- colnames(usable[,1])
rownames(col) <- c("5","10","30")
col
}
matrix <- as.matrix(stock3Summary(stocks[1]))
for( i in 2:length(stocks)){
matrix <- cbind(matrix,stock3Summary(stocks[i]))
}
输出:
> matrix
X0007.HK.Close X1036.HK.Close CVX.Close
5 1.082000 8.476000 126.6900
10 1.100000 8.412000 127.6080
30 1.094333 8.426333 127.6767
这适用于多种股票。它将仅使用最近的有效日期。