Issue
I have a portfolio of 40 stocks and I'm trying to calculate the standard deviation for the total portfolio while changing the weight per stock every time I calculate this standard deviation. I know how to create a list of random numbers summing to 1, but how can I add max and min weights per stock..
The maximum I'm using is 4.5% and the minimum 0.5%.
The code I use for creating a list of random numbers summing to 1 is:
import numpy as np, numpy.random
random = np.random.dirichlet(np.ones(10), size=1)
But how can I make this list with only values between 0.005 and 0.045?
Solution
Perhaps using np.random.normal would give better results. You could scale down the distribution to the 0.005-0.045 range using the proportion of 80% that is variable (above 0.005). Because normal distributions can still have outliers, it will be necessary to "retry" the calculation if the values go out of bounds (but that shouldn't happen too frequently unless you give a large standard deviation):
import numpy as np
def randStock(count=40,minR=0.005,maxR=0.045,sd=3):
iterations = 0
while True:
iterations += 1
r = np.random.normal(1,sd,count) #normal distribution
r -= min(r) # offset to zero
r /= max(r) # scale to 0..1
r = minR + r/sum(r)*(maxR-minR)/(maxR+minR) # scale to range
if min(r)>=minR and max(r)<=maxR: return r, iterations
Output:
for _ in range(10):
s,i = randStock()
print(*map("{:6.4f}".format,(sum(s),min(s),max(s))),i,"iterations")
[sum] [min] [max] [mean]
1.0000 0.0050 0.0404 0.0250 1 iterations
1.0000 0.0050 0.0409 0.0250 2 iterations
1.0000 0.0050 0.0395 0.0250 1 iterations
1.0000 0.0050 0.0411 0.0250 4 iterations
1.0000 0.0050 0.0410 0.0250 2 iterations
1.0000 0.0050 0.0428 0.0250 1 iterations
1.0000 0.0050 0.0433 0.0250 1 iterations
1.0000 0.0050 0.0424 0.0250 1 iterations
1.0000 0.0050 0.0371 0.0250 1 iterations
1.0000 0.0050 0.0446 0.0250 1 iterations
Note that this could be improved to randomize the lower bound a bit more and you can chose a different standard deviations
Answered By - Alain T.
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.