Numpy - generate random array with restrictions on individual values in array - Portfolio Optimisation

429 Views Asked by At

I'm developing a portfolio optimisation code with constraints using monte-carlo simulation. However, I have run into a problem. My problem is as follows:

I have a list of instruments ["Multi", "Equity 1", "Equity 2", "Equity 3", "FI", "Cash"]

And I would like to generate a list of random numbers for these instruments e.g.

weights (random numbers) = [xx, xx, xx, xx, xx, xx]

However, with multiple constraints such as :

  1. All weights between 0.05 and 0.20.
  2. Weight of say "Cash" must be between 0 and 0.10 (i.e. the 0<= weights[-1] <= 0.10)
  3. Weight of "Equity 1" has to be 0.15 (i.e. weights[1] = 0.15)

Is there anyway that I can generate random numbers that satisfy all these criteria? and of course the sum of all weights must be equal to one.

Thank you all for your help!

1

There are 1 best solutions below

0
On BEST ANSWER

You can generate the numbers one by one, computing at each step the total sum of the weights you already got. I will use random.randint function for my demonstration.

import random

weights_name = ["Multi", "Equity 1", "Equity 2", "Equity 3", "FI", "Cash"]
weights = [0] * 6

weights[1] = 0.15  # Equity 1 weight
remaining = 0.85 # the sum of the remaining weights

x = random.randint(0, 100)
weights[-1] = x/1000 # Cash weigth
remaining -= weights[-1]

So for the remaining weigths, you have to generate random values such that the last one wouldn't be larger than 0.2.

last_weight = remaining
while last_weight > 0.2:
    last_weight = remaining
    for i in [0, 2, 3]:
        weights[i] = 0.05 + random.randint(0, 150)/1000 # generating a random no between 0.05 and 0.20
        last_weight -= weights[i]
weights[4] = last_weight
for w in weights:
    print(w)

My output:

0.2
0.15
0.176
0.196
0.18200000000000005
0.096