0

I am learning investment portfolios, but I need to know how I can generate many random weights for portfolios.

To achieve multiply them with the returns of several shares and also obtain volatility and return for each different weights. The weights must add 1 in total, to achieve the results shown in the images.

Here, for example, I generate a weight for the actions of my portfolio, but I need to generate more weights randomly, to simulate more portfolios and achieve the results of the images.

import random
n=9
weights = [random.random() for _ in range(n)]
sum_weights = sum(weights)
weights = [w/sum_weights for w in weights]

image 1 image 2

muru
  • 4,723
  • 1
  • 34
  • 78
mitch
  • 13
  • 6
  • have you checked this? https://stackoverflow.com/questions/18659858/generating-a-list-of-random-numbers-summing-to-1 – zero May 31 '19 at 06:25
  • Thank you. But I'm looking for something different, for example, I have defined a number and type of shares = Shares. Also I have different random weights (random weights_{i}= R_W_{i}, i=1,2,3...) Often – mitch May 31 '19 at 07:00
  • (R_W1)*Shares,(R_W2)*Shares , (R_W3)*Shares,...., (R_Wn)*Shares – mitch May 31 '19 at 07:02
  • I don't understand what your target is. In your image, the columns don't add up to 100%, neither does the row (see row 0). So I'm not sure what you're saying. Would help if you expounded a bit more and/or gave more data. or is this purely random number generation? – zero May 31 '19 at 08:33
  • The rows of the shares must be added, in the image, the rows add up to 100%. in row zero: (AAPL weight) + (MSFT weight) + (XOM weight) +(JNJ weight) + (JPM weight) + (AMZN weight) + (GE weight) + (FB weight) + (T weight)=1 – mitch May 31 '19 at 08:51
  • hmm anyway, you just want to randomize 9 values that add up to 100% for each row, is that it? :) – zero May 31 '19 at 08:53
  • In row one, the X Company weight add up 1 – mitch May 31 '19 at 08:56
  • yeah how about in the other rows, should they add up to 1 as well? – zero May 31 '19 at 08:58
  • Yes, I want to randomize 9 values that add up to 100% for each row, and have N randomized rows – mitch May 31 '19 at 09:00
  • From the image, I assume you're running `pandas`? – zero May 31 '19 at 09:02
  • Yeah, in row 1: (AAPL weight) + (MSFT weight) + (XOM weight) +(JNJ weight) + (JPM weight) + (AMZN weight) + (GE weight) + (FB weight) + (T weight)=1 as well – mitch May 31 '19 at 09:02
  • Yes, I am running pandas – mitch May 31 '19 at 09:03

1 Answers1

1

You can use numpy broadcasting for easier computation

import numpy as np
import pandas as pd

# Set Seed for reproducibility
np.random.seed(0)

# Set your n

n = 9
# Randomize a Numpy Array with 100 x n array
rand_nos = np.random.rand(100, n)

Now, to get the sum per row,

rand_nos.sum(axis=1)

Now you have a 100 x n array. To broadcast array operations, you have to match the the column count in the left array to the row count of the right array. So to match, we use the .transpose() method of a numpy.ndarray. That will result into a n x 100 array. In order to bring it back to a 100 x n array, we just apply the .transpose() method on the resulting array. Code will look like so:

onehundred_by_n = rand_nos.transpose() / rand_nos.sum(axis=1) # This is a 100 x 1 array
n_by_onehundred = onehundred_by_n.transpose() # This is now a n x 100 array

Once you have n_by_onehundred, it's easy to read it into a dataframe (since pandas.DataFrames are essentially numpy.ndarrays). Add a columns keyword argument and you're set with your randomized dataframe.

df = pd.DataFrame(
    n_by_onehundred,
    columns=[
    'AAPL weight', 'MSFT weight', 'XOM weight',
    'JNJ weight', 'JPM weight', 'AMZN weight',
    'GE weight', 'FB weight', 'T weight', 
]
)

Just for completeness, if you want to check that each row in df sums up to 1, just run:

df.sum(axis=1) # This sums each row

You should get 100 1s representing each row

zero
  • 1,605
  • 3
  • 15
  • 24
  • Thank you very much, it is exactly what I was looking for. Where could I learn more about this? – mitch May 31 '19 at 09:50
  • I've attached a link to array broadcasting in the answer. Array broadcasting works for `numpy.ndarray`, `pandas.Series` and `pandas.DataFrame` (since both `pandas` objects inherits from `numpy.ndarray`s) – zero May 31 '19 at 09:51
  • Thanks you, greetings from Mexico – mitch May 31 '19 at 09:55