I am trying to build an efficient frontier as in the Markowitz problem. I have written the code below, but I get the error "ValueError: Objective function must return a scalar". I have tested 'fun' with some values, for example, I input to the console:
W = np.ones([n])/n # start optimization with equal weights cov_matrix = returns.cov() fun = 0.5*np.dot(np.dot(W, cov_matrix), W) # variance of the portfolio fun The output is 0.00015337622774133828, which is a scalar. I don't know what might be wrong. Any help is appreciated.
Code:
from scipy.optimize import minimize import pandas as pd import numpy as np from openpyxl import load_workbook wb = load_workbook('path/Assets_3.xlsx') # in this workbook there is data for returns. # The next lines clean unnecessary first column and first row. ws = wb.active df = pd.DataFrame(ws.values) df1 = df.drop(0,axis=1) df1 = df1.drop(0) df1 = df1.astype(float) rf = 0.05 r_bar = 0.05 returns = df1.copy() def efficient_frontier(rf, r_bar, returns): n = len(returns.transpose()) W = np.ones([n])/n # start optimization with equal weights exp_ret = returns.mean() cov_matrix = returns.cov() fun = 0.5*np.dot(np.dot(W, cov_matrix), W) # variance of the portfolio cons = ({'type': 'eq', 'fun': lambda W: sum(W) - 1. }, {'type': 'ineq', 'fun': lambda W: np.dot(exp_ret,W) - r_bar }) bnds = [(0.,1.) for i in range(n)] # weights between 0..1. res = minimize(fun, W, (returns, cov_matrix, rf), method='SLSQP', bounds = bnds, constraints = cons) return res x= efficient_frontier(rf,r_bar,returns) x Some Data
1 2 3 1 0.060206 0.005781 0.001117 2 0.006463 -0.007390 0.001133 3 -0.003211 -0.015730 0.001167 4 0.044227 -0.006250 0.001225 5 -0.040571 -0.006910 0.001292 6 -0.007900 -0.006160 0.001208 7 0.068702 0.013836 0.001300 8 0.039286 0.009854 0.001350 9 0.012457 -0.007950 0.001358 10 -0.013758 0.001021 0.001283 11 -0.002616 -0.013600 0.001300 12 0.059004 -0.006090 0.001442 13 0.015566 0.002818 0.001308 14 -0.036454 0.001395 0.001283 15 0.058899 0.011072 0.001325 16 -0.043086 0.017070 0.001308 17 0.023156 -0.003350 0.001392 18 0.063705 0.000301 0.001417 19 0.017628 -0.001960 0.001508 20 -0.014567 -0.006990 0.001525 21 -0.007191 -0.013000 0.001425 22 -0.000815 0.014773 0.001450 23 0.046493 -0.001540 0.001542 24 0.051832 -0.008580 0.001742 25 -0.007151 0.001177 0.001633 26 -0.018196 -0.008680 0.001642 27 -0.013513 -0.008810 0.001675 28 -0.026493 -0.010510 0.001825 29 -0.003249 -0.014750 0.001800 30 0.001222 0.022258 0.001758
fundoesn't seem to be a function.np.arraywith shape (1), intead of afloat?funis not a callable object! Probably that is the issue....