There are 100 different stocks in total to choose from. Each stock has a price, p_i, I want to create random portfolios for simulation purposes. The total value of the portfolio needs to be $1,000,000 (give or take $100) and the number of different shares in the portfolio can be random too (for example the portfolio could be long in 20 stocks). I'm struggling to create "a good" algorithm to do this.
It's not really a knapsack problem because nothing needs to be optimized. It is kind of like a random sample but not quite. So I'm wondering what algorithm I could use to solve this problem. Any ideas?
N
number of stocks from the total universe of stocksN
random floats, X_1
, ..., X_N
, between 0 and 1X_1 + ... + X_N
. If T
equals 0, repeat step 1.X_1 = X_1 / T
, ... X_N = X_N / T
. Notice the sum X_1 + ... + X_N
now equals 1.W
= the value of the total portfolio (e.g. W = 1000000
)X_i * W
dollars in the i
th stocki
th stock is therefore S_i = X_i * W / p_i
In Python,
import numpy as np
import pandas as pd
pd.options.display.float_format = '{:.2f}'.format
N = 100
W = 10**6
portfolio_size = np.random.randint(1, N+1)
df = pd.DataFrame({'price': np.random.uniform(1, 100, size=(N,))})
df = df.iloc[np.random.choice(N, portfolio_size, replace=False)]
while True:
df['value'] = np.random.random(portfolio_size)
T = df['value'].sum()
if T != 0: break
df['value'] *= W/T
df['shares'] = df['value']/df['price']
df.index.name='stock num'
print(df)
print('Total value of portfolio: {}'.format(df['value'].sum()))
yields something like
price value shares
stock num
0 34.52 65296.14 1891.72
24 6.82 13008.12 1906.35
83 15.56 100550.05 6463.14
12 60.35 30366.58 503.17
77 76.75 100814.58 1313.49
36 96.50 85649.01 887.53
51 26.28 96860.06 3685.21
9 43.22 31757.96 734.87
56 67.33 19889.57 295.40
66 79.99 30343.49 379.34
21 1.45 1718.19 1187.56
30 34.48 33604.31 974.65
52 80.15 64579.28 805.71
55 41.02 10226.60 249.29
40 8.49 25755.19 3032.82
20 89.46 102164.38 1142.06
5 45.94 42620.16 927.71
73 96.17 6021.88 62.62
58 60.00 24133.96 402.21
45 40.59 114640.49 2824.31
Total value of portfolio: 1000000.0