# How to use all cores in solve() method?

I'm trying to find optimal wights of stocks that maximises return per volatility. I'm able to solve it for two and three stocks within one second. But when I go for 4 stocks, the computer just never gives any result even in more than an our hour. Any idea on how to make it fast enough? I want to make a program for n stocks and I'm unable to go even for more than three stocks. I also tried Sympy but that is able to do for two stocks within a minute but hangs in three stocks for too long I don't have any hope with it.

I do have access to cloud computers and can make instances of 100s cores and 1000s GB RAM. I tried it on Windows server but it just gives runtime error soon enough. My own system runs indefinitely. Anyways, I suppose my code uses only one core for solving by default. All steps are pretty easy, it just hangs on the last solve() method. Is there a way I can utilise all other cores to solve it soon enough?

Here's the algorithm I'm using. r and v are the mean return and variance of the portfolio. r_i, sigma_i, sigma_ij, w_i are mean, standard deviation, covariance, and weights respectively. Equations eq1, eq2, eq3 have been derived by hand by minimising mean/standard_deviation.

r1, r2, r3, r4, s1, s2, s3, s4, s12, s13, s14, s23, s24, s34, w1, w2, w3, w4 = var('r_1, r_2, r_3, r_4, sigma_1, sigma_2, sigma_3, sigma_4, sigma_12, sigma_13, sigma_14, sigma_23, sigma_24, sigma_34, w_1, w_2, w_3, w_4')

r = r1*w1 + r2*w2 + r3*w3 + r4*(1-w1-w2-w3)

v = ((w1**2*s1**2 + w2**2*s2**2 + w3**2*s3**2 + (1-w1-w2-w3)**2*s4**2+2*s12*w1*w2 + 2*s13*w1*w3+
2*s14*(1-w2-w1-w3)*w1+s23*w2*w3 + 2*s24*w2*(1-w2-w1-w3) + 2*s34*w3*(1-w2-w1-w3)))

dr1 = derivative(r, w1)
dr2 = derivative(r, w2)
dr3 = derivative(r, w3)

dv1 = derivative(v, w1)
dv2 = derivative(v, w2)
dv3 = derivative(v, w3)

eq1 = (dv1/dr1 == 2*v/r)
eq2 = (dv2/dr2 == 2*v/r)
eq3 = (dv3/dr3 == 2*v/r)
eq4 = (w1+w2+w3+w4 == 1)

sol = solve((eq1, eq2, eq3, eq4), (w1, w2,w3, w4))
show(sol)

edit retag close merge delete

Sort by ยป oldest newest most voted

Your equations can be turned into polynomial ones, and thus you'll will have better control over their solution if you empoy polynomial ideal machinery - over the rationals it will look like:

P.<r1, r2, r3, r4, s1, s2, s3, s4, s12, s13, s14, s23, s24, s34, w1, w2, w3, w4> = QQ[]

r = r1*w1 + r2*w2 + r3*w3 + r4*(1-w1-w2-w3)

v = ((w1**2*s1**2 + w2**2*s2**2 + w3**2*s3**2 + (1-w1-w2-w3)**2*s4**2+2*s12*w1*w2 + 2*s13*w1*w3+ 2*s14*(1-w2-w1-w3)*w1+s23*w2*w3 + 2*s24*w2*(1-w2-w1-w3) + 2*s34*w3*(1-w2-w1-w3)))

dr1 = derivative(r, w1)
dr2 = derivative(r, w2)
dr3 = derivative(r, w3)

dv1 = derivative(v, w1)
dv2 = derivative(v, w2)
dv3 = derivative(v, w3)

eq1 = numerator(dv1/dr1 - 2*v/r)
eq2 = numerator(dv2/dr2 - 2*v/r)
eq3 = numerator(dv3/dr3 - 2*v/r)
eq4 = w1+w2+w3+w4 - 1

J = P.ideal( [eq1, eq2, eq3, eq4] )


I've used a variant of a custom myvariety() routine to obtain a list of 65 solutions (including parametric ones) over the rationals, although it may be incomplete. Among them there are 37 solutions with nonzero dr1, dr2, dr3, and r(appearing in denominators of original equations), which you may find at https://gist.github.com/maxale/76773b...

more