Число, которое вы хотите вычислить, похоже на то, что (к сожалению) называется взвешенной по времени доходностью;хотя для таких возвратов доход от одной сделки объединяется с помощью умножения, а не суммирования. На самом деле, если это приемлемо, это довольно легко вычислить. Начните с данных:
library("PMwR")
library("zoo")
data <- structure(
c(100, 105, 110, NA, 10, 7.5, 5, NA, NA, NA,
NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,
NA, NA, 200, 750, 1000, NA, 750, 500, NA, 500,
250, NA, 6, 7, 8, 8, 8, 8, 9),
.Dim = c(8L, 5L),
.Dimnames = list(NULL, c("Stock1", "Stock2", "Stock3",
"Stock4", "Stock5")),
index = structure(c(18187, 18190, 18191, 18192, 18193,
18194, 18197, 18198), class = "Date"),
class = "zoo")
data
## Stock1 Stock2 Stock3 Stock4 Stock5
## 2019-10-18 100.0 NA NA 750 NA
## 2019-10-21 105.0 NA NA 1000 6
## 2019-10-22 110.0 NA NA NA 7
## 2019-10-23 NA NA NA 750 8
## 2019-10-24 10.0 NA NA 500 8
## 2019-10-25 7.5 NA NA NA 8
## 2019-10-28 5.0 NA NA 500 8
## 2019-10-29 NA NA 200 250 9
Обратите внимание, что я использую здесь zoo
, но вы всегда можете позвонить as.xts
(так как xts
наследуется от zoo
). С PMwR
я использую функцию returns
. Для взвешенных по времени возвратов (т. Е. Произведение возвратов за одну сделку) просто преобразуйте все NA-возвраты в нули.
R <- returns(data, pad = 0)
R <- na.fill(R, 0)
apply(R, 2, function(x) prod(1+x)-1)
## Stock1 Stock2 Stock3 Stock4 Stock5
## -0.4500000 0.0000000 0.0000000 -0.5555556 0.5000000
Если вы действительно хотите суммировать возвраты, есть немного больше работы длясделайте:
sum_returns <- function(x) {
x <- c(NA, as.vector(x), NA)
start <- which(is.finite(x[-1]) & is.na (x[-length(x)]))
end <- which(is.na (x[-1]) & is.finite(x[-length(x)]))
sum(x[end]/x[start+1]-1)
}
apply(data, 2, sum_returns)
## Stock1 Stock2 Stock3 Stock4 Stock5
## -0.4 0.0 0.0 -0.5 0.5
Если вам нужно провести различие между нулевым доходом и никогда не инвестировать, добавьте что-то вроде
never.invested <- apply(data, 2, function(x) all(is.na(x)))
## Stock1 Stock2 Stock3 Stock4 Stock5
## FALSE TRUE FALSE FALSE FALSE