pythonnumpyoptimizationportfolionumpy-random

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


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!


Solution

  • 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