3

I am trying to find all possible portfolio-allocations for n number of equities with weighting steps of s. The function expand.grid() is used for calculating all variations, and a subset is done using rowSums(), reducing the output to all variations where the weightings are 100.

The problem:

This way doesn't work for "larger" numbers. Using the subset after expand.grid() doesn't seem to be the best way. Any ideas?

Here is the code:

n <- 5 #number equities
s <- 20 #weighting steps

Ptf <- function(n, s){
  m <- expand.grid(rep(list(seq(0, 100, s)), n))
  subset(m, rowSums(m)==100)
}

Ptfs <- Ptf(n, s)

Result:

head(Ptfs)
   Var1 Var2 Var3 Var4 Var5
6   100    0    0    0    0
11   80   20    0    0    0
16   60   40    0    0    0
21   40   60    0    0    0
26   20   80    0    0    0
31    0  100    0    0    0
> tail(Ptfs)
     Var1 Var2 Var3 Var4 Var5
4321    0    0    0   40   60
5186   20    0    0    0   80
5191    0   20    0    0   80
5221    0    0   20    0   80
5401    0    0    0   20   80
6481    0    0    0    0  100

Increasing the number of equities n <- 10 delivers an error message:

> n <- 10 #number equities
> s <- 20 #weighting steps
> 
...
> 
> Ptfs <- Ptf(n, s)
Error: cannot allocate vector of size 461.3 Mb

Any help would be really appreciated!

Michael Harper
  • 14,721
  • 2
  • 60
  • 84

1 Answers1

2

As per the links above, you can do this easily with the partitions package...

library(partitions)
Ptfs <- as.data.frame(s*t(as.matrix(compositions(100/s,n))))

Ptfs
     V1  V2  V3  V4  V5
1   100   0   0   0   0
2    80  20   0   0   0
3    60  40   0   0   0
4    40  60   0   0   0
5    20  80   0   0   0
6     0 100   0   0   0
7    80   0  20   0   0
8    60  20  20   0   0
9    40  40  20   0   0
10   20  60  20   0   0
11    0  80  20   0   0
12   60   0  40   0   0
13   40  20  40   0   0
14   20  40  40   0   0
15    0  60  40   0   0
16   40   0  60   0   0
17   20  20  60   0   0
18    0  40  60   0   0
19   20   0  80   0   0
20    0  20  80   0   0
21    0   0 100   0   0
22   80   0   0  20   0
...
Andrew Gustar
  • 17,295
  • 1
  • 22
  • 32