Mean-Variance optimization using scipy.optimize

395 views Asked by At

i'm working on portefolio optimization so i want to minimize a function which computes the variance of its net result subject to its mean is equal or larger than a certain expected result exp :

minimize Var (Net Result) subject to E(Net result) >=exp

i defined my objective function as :

R=[]
length_to_split=[26,56,46,38,48,38,45,55,59,47]
from itertools import accumulate 
def objective(z):
    for i in range(0, len(dataframe)):
        
        R.append((1- max(0, (dataframe.iloc[i,1]- z) /dataframe.iloc[i,1]) )*(dataframe.iloc[i,2]-dataframe.iloc[i,1]))
    R_ann=[R[x - y: x] for x, y in zip(accumulate(length_to_split), length_to_split)] #each sublist 
    #contains results of one year 
    R_avg=sum([sum(r) for r in R_ann ] )/len([sum(r) for r in R_ann ])  #[sum(r) for r in R_ann ] will 
    #return 10 results corresponding to net results for each year from 2010 to 2019.
    var = sum((Rj-R_avg)**2 for Rj in [sum(r) for r in R_ann ]) / len([sum(r) for r in R_ann ])
    return var

dataframe is a data which contains 4 columns where the first one represents costs and the second one premiums and then i defined my constraint function as :

K=[]
from statistics import mean 
def constraint(z):
    exp=1000000
    for i in range(0, len(dataframe)):
        if dataframe.iloc[i,1]>z:
            K.append((1- ((dataframe.iloc[i,1]-z) /dataframe.iloc[i,1])) * (dataframe.iloc[i,2]-dataframe.iloc[1,1]))
        else: 
            K.append((dataframe.iloc[i,2]-dataframe.iloc[i,1])) 
    K_ann=[K[v - w: v] for v, w in zip(accumulate(length_to_split), length_to_split)] 
    return mean([sum(j)  for j in K_ann]) -exp

When i tried to minimize the objective function as,

from scipy.optimize import minimize
con = {'type': 'ineq', 'fun': constraint}
guess=500000
minimize(objective,guess,constraints=con)

it gave me the error below :

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-404-ff80aabebc42> in <module>
      2 con = {'type': 'ineq', 'fun': constraint}
      3 guess=500000
----> 4 minimize(objective,guess,constraints=con)
      5 # initial guesses

~\Anaconda3\lib\site-packages\scipy\optimize\_minimize.py in minimize(fun, x0, args, method, jac, hess, hessp, bounds, constraints, tol, callback, options)
    607     elif meth == 'slsqp':
    608         return _minimize_slsqp(fun, x0, args, jac, bounds,
--> 609                                constraints, callback=callback, **options)
    610     elif meth == 'trust-constr':
    611         return _minimize_trustregion_constr(fun, x0, args, jac, hess, hessp,

~\Anaconda3\lib\site-packages\scipy\optimize\slsqp.py in _minimize_slsqp(func, x0, args, jac, bounds, constraints, maxiter, ftol, iprint, disp, eps, callback, **unknown_options)
    313               for c in cons['eq']]))
    314     mieq = sum(map(len, [atleast_1d(c['fun'](x, *c['args']))
--> 315                for c in cons['ineq']]))
    316     # m = The total number of constraints
    317     m = meq + mieq

~\Anaconda3\lib\site-packages\scipy\optimize\slsqp.py in <listcomp>(.0)
    313               for c in cons['eq']]))
    314     mieq = sum(map(len, [atleast_1d(c['fun'](x, *c['args']))
--> 315                for c in cons['ineq']]))
    316     # m = The total number of constraints
    317     m = meq + mieq

<ipython-input-401-fe7f26be36f9> in constraint(z)
     10             K.append((dataframe.iloc[i,2]-dataframe.iloc[i,1]))
     11     K_ann=[K[v - w: v] for v, w in zip(accumulate(length_to_split), length_to_split)]
---> 12     return mean([sum(j)  for j in K_ann]) -exp
     13 #contrainte(900000)
     14 

~\Anaconda3\lib\statistics.py in mean(data)
    309     if n < 1:
    310         raise StatisticsError('mean requires at least one data point')
--> 311     T, total, count = _sum(data)
    312     assert count == n
    313     return _convert(total/n, T)

~\Anaconda3\lib\statistics.py in _sum(data, start)
    145     for typ, values in groupby(data, type):
    146         T = _coerce(T, typ)  # or raise TypeError
--> 147         for n,d in map(_exact_ratio, values):
    148             count += 1
    149             partials[d] = partials_get(d, 0) + n

~\Anaconda3\lib\statistics.py in _exact_ratio(x)
    227         return (x, None)
    228     msg = "can't convert type '{}' to numerator/denominator"
--> 229     raise TypeError(msg.format(type(x).__name__))
    230 
    231 

TypeError: can't convert type 'ndarray' to numerator/denominator

Could someone help me solve this problem please? i could not get the correct result i think the problem is with my constraint function even when i fix this type of error.

0

There are 0 answers