为数据组创建权重向量

creating a weight vector for groups of data

我使用的数据是关于财务数据的。我遇到的问题是我想为给定投资组合中的许多公司分配权重。也就是说,如果我有 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)

然而,当公司数量增加时会出现问题and/or 投资组合数量增加。

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

下一步是创建以下 table 使用;

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

以上结果为等权重数据。同样,当公司数量增加和投资组合规模增加时,问题就会出现。

这是dputlinkdput data

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

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。您可以评估每个投资组合的权重 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

这是实现它的一种快速/简单的方法,但在统计准确性方面存在问题,请参考这个非常有趣的post: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