Как рассчитать множественную доходность активов - PullRequest
1 голос
/ 31 октября 2019

Я попытался настроить R-код для расчета доходности каждого столбца. Моя проблема заключается в том, что в коде должны учитываться несколько вложений разных периодов времени в каждом активе (столбце).

Мне удалось извлечь соответствующие цены каждого дня, в котором каждая инвестиция принадлежала (строки), как xts-объект. НС указывают на то, что на данную дату не было данной акции. Поэтому у меня есть таблица , как показано ниже (как объект xts). Кроме того, обратите внимание, что выходные дни не включены в столбец индекса:

 Stock 1 Stock 2 Stock 3 Stock 4 Stock 4
2019-10-18 100 NA NA 750 NA
2019-10-21 105 NA NA 1000 6
2019-10-22 110 NA NA NA 7
2019-10-23 NA NA NA 750 8
2019-10-24 10 NA NA 500 8
2019-10-25 7.5 NA NA NA 8
2019-10-28 5 NA NA 500 8 
2019-10-29 NA NA 200 250 9

Для интерпретации таблицы приведен следующий пример: Акция 1 принадлежала в период с 2019 по 18-18 2019-10-22 где было продано. В 2019-10-23 акции 1 не были в собственности, тогда как они были снова куплены в 2019-10-24 и снова проданы в 2019-10-28, и, следовательно, NA на 2019-10-29. Числа в столбце Акции 1 отражают цены акций за указанные дни.

Выход Я ищу, чтобы получить - это вектор, суммирующий каждую независимую инвестицию - который не основанпри размере вложения:

 Stock 1 Stock 2 Stock 3 Stock 4 Stock 5
Cumulative Return -40% NA 0% -50% 50%

Обратите внимание, что для каждой кумулятивной прибыли каждая инвестиция использует первую и последнюю строки каждого инвестиционного периода. В качестве примера -40% рассчитывается следующим образом: 110/100-1 + 5/10-1.

Если в актив (столбец) делаются несколько инвестиций, он всегда будет иметь непересекающиеся периоды, как впример выше.

Заранее спасибо!

1 Ответ

1 голос
/ 01 ноября 2019

Число, которое вы хотите вычислить, похоже на то, что (к сожалению) называется взвешенной по времени доходностью;хотя для таких возвратов доход от одной сделки объединяется с помощью умножения, а не суммирования. На самом деле, если это приемлемо, это довольно легко вычислить. Начните с данных:

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 
...