为数据组创建权重向量

时间:2018-07-08 20:13:55

标签: r portfolio

我使用的数据是关于财务数据的。我的问题是我想为给定投资组合中的许多公司分配权重。也就是说,如果我有3家公司(如下面的示例所示),我想为投资组合中的3家公司中的每家公司分配相同的权重,则为每家公司0.33%。我认为,当投资组合的规模增加并且必须手动键入特定的权重可能很麻烦时,也有兴趣对投资组合中的公司随机分配权重。

数据如下:

可以使用tidyquant包通过以下代码创建哪些内容:

stock_returns_monthly <- c("AAPL", "GOOG", "NFLX") %>%
  tq_get(get = "stock.prices",
         from = "2010-01-01",
         to = "2015-12-31") %>%
  group_by(symbol) %>%
  tq_transmute(select = adjusted,
               mutate_fun = periodReturn,
               period = "monthly",
               col_rename = "Ra")

stock_returns_monthly_multi <- stock_returns_monthly %>%
  tq_repeat_df(n = 3)

n = 3设置要创建的投资组合的数量。

输出:

# A tibble: 6 x 4
# Groups:   portfolio [1]
  portfolio symbol date            Ra
      <int> <chr>  <date>       <dbl>
1         1 AAPL   2010-01-29 -0.103 
2         1 AAPL   2010-02-26  0.0654
3         1 AAPL   2010-03-31  0.148 
4         1 AAPL   2010-04-30  0.111 
5         1 AAPL   2010-05-28 -0.0161
6         1 AAPL   2010-06-30 -0.0208

我要解决两个问题:

1)为每个投资组合在所有公司中设置相等的权重,以下代码有效。

weights <- c(0.33, 0.33, 0.33,
             0.33, 0.33, 0.33,
             0.33, 0.33, 0.33)

但是,当公司数量增加和/或投资组合数量增加时,就会出现问题。

2)为每个投资组合中的每个公司随机分配权重。

下一步是使用以下方法创建下表

stocks <- c("AAPL", "GOOG", "NFLX")
weights_table <-  tibble(stocks) %>%
  tq_repeat_df(n = 3) %>%
  bind_cols(tibble(weights)) %>%
  group_by(portfolio)

输出:

# A tibble: 9 x 3
# Groups:   portfolio [3]
  portfolio stocks weights
      <int> <chr>    <dbl>
1         1 AAPL     0.330
2         1 GOOG     0.330
3         1 NFLX     0.330
4         2 AAPL     0.330
5         2 GOOG     0.330
6         2 NFLX     0.330
7         3 AAPL     0.330
8         3 GOOG     0.330
9         3 NFLX     0.330

以上结果适用于均等加权数据。同样,当公司数量增加且投资组合规模增加时,也会出现问题。

在这里dput链接dput data

1 个答案:

答案 0 :(得分:1)

stock_returns_monthly_multi数据集作为df。请注意,df似乎已经在portfolio上分组了。使用dplyrweights将在每个symbol中的portfolio数中平均分配。

library(dplyr)

df <- stock_returns_monthly_multi

df %>% 
   distinct(portfolio, symbol) %>% 
mutate(weights = 1/n())

# A tibble: 9 x 3
# Groups:   portfolio [3]
#  portfolio symbol weights
#      <int> <chr>    <dbl>
#1         1 AAPL     0.333
#2         1 GOOG     0.333
#3         1 NFLX     0.333
#4         2 AAPL     0.333
#5         2 GOOG     0.333
#6         2 NFLX     0.333
#7         3 AAPL     0.333
#8         3 GOOG     0.333
#9         3 NFLX     0.333

编辑: :如果您需要为每个投资组合分别随机分配加1的权重。您可以评估每个投资组合的权重(em)w = x / sum(x),其中x的元素为i.i.d。 runif [0,1] 。 prop.table可用于实现这一目标:

df %>% 
   distinct(portfolio, symbol) %>% 
mutate(weights = prop.table(runif(n())))

#+ + # A tibble: 9 x 3
## Groups:   portfolio [3]
#  portfolio symbol weights
#      <int> <chr>    <dbl>
#1         1 AAPL     0.548
#2         1 GOOG     0.292
#3         1 NFLX     0.160
#4         2 AAPL     0.107
#5         2 GOOG     0.140
#6         2 NFLX     0.754
#7         3 AAPL     0.195
#8         3 GOOG     0.417
#9         3 NFLX     0.387

这是一种快速/简便的方法,但是存在统计准确性 的问题,请参阅此有趣的文章:Randomly generated weights sum to one。我们可以将接受的答案编码为一个函数(gen_weight_vec)并与mutate一起使用。像这样:

gen_weight_vec <- function(n){x <- runif(n) 
                              y <- -log(x) 
                              return(y/sum(y))}

df_weight <- df %>% 
                distinct(portfolio, symbol) %>% 
             mutate(weights = gen_weight_vec(n()))

您可以检查每个porfolio的权重总和:

 summarise(df_weight, sum_weights = sum(weights))

## A tibble: 3 x 2
#  portfolio sum_weights
#      <int>       <dbl>
#1         1          1 
#2         2          1
#3         3          1