簡體   English   中英

根據其他列計算平均值

[英]Calculate the average based on other columns

我想算一算

“緊接公告日前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而被排除在外。

編輯於11/9/2014

需要注意的一點是:每個股票的公告日不同,並且它不是數據中的最后有效日期,因此在計算平均值時使用tail是不合適的。

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

主要問題:

  1. .SD和lapply和.SDCol可用於循環不同的股票。 計算最后連續N天時可以使用.N。

  2. 由於宣布日不同,它變得有點復雜。

使用quantmod或使用data.table的多個股票對單一股票的任何建議都非常受歡迎!

感謝GSee和pbible提供了很好的解決方案,它非常有用。 我將在稍后更新我的代碼,為每個股票添加不同的公告日,並在稍后咨詢。

實際上,它更像是一個xts問題,而不是一個數據問題。 任何有關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)}
}

我得到了我想要的東西,但代碼很難看。任何使它優雅的建議都非常受歡迎!

嗯,這是一種方法。 我不知道你為什么要擺脫循環,這並沒有擺脫它(實際上它有一個嵌套在另一個循環中)。 你正在做的一件事是在你的循環的每次迭代中在內存中生長對象(即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向量。
    1. 第一行從myEnv獲取數據,刪除NA,並將其子集設置為僅包含截至相關結束日期的數據。
    2. 下一行提取關閉列,並將其子集設置為僅包含volume大於零的行。
    3. vapply在不同回溯的向量上循環並計算mean 它包含在setNames以便根據使用哪個回溯來計算每個結果。
  • lapply調用返回一個命名向量列表。 do.call(cbind, LIST)與調用cbind(LIST[[1]], LIST[[2]], LIST[[3]])相同,除了LIST可以是任何長度的列表。
  • 此時我們有一個帶行名的矩陣,但沒有列名。 因此,我根據它們所代表的庫存來命名列。

希望這可以幫助。

使用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

這適用於多種股票。 它將僅使用最近的有效日期。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM