尝试使用GEKKO解决这个非线性优化问题时出现了错误。

4

@错误: 使用序列设置数组元素

我试图最小化下行风险。

我有一个二维数组的收益率形状为(1000, 10),并且组合以$100开始。将每一行中的每个收益率连续复合10次。对所有行都这样做。将每一行的最后一个单元格的值与最后一列值的平均值进行比较。如果该值小于平均值,则保留该值,否则设为零。那么我们将得到一个 (1000, 1) 的数组。最后,我计算这个数组的标准差。

目标是最小化标准差。约束条件:权重需要小于1。

预期回报即权重*收益率应等于一个值(例如7%)。我必须对几个值(如7%、8%或10%)进行这样的操作。

wt = np.array([0.4, 0.3, 0.3])

cov = array([[0.00026566, 0.00016167, 0.00011949],
   [0.00016167, 0.00065866, 0.00021662],
   [0.00011949, 0.00021662, 0.00043748]])

ret =[.098, 0.0620,.0720]
iterations = 10000

return_sim = np.random.multivariate_normal(ret, cov, iterations)

def simulations(wt):

    downside =[]
    fund_ret =np.zeros((1000,10))
    prt_ret = np.dot(return_sim , wt)

    re_ret = np.array(prt_ret).reshape(1000, 10) #10 years

    for m in range(len(re_ret)):
        fund_ret[m][0] = 100 * (1 + re_ret[m][0])  #start with $100
        for n in range(9):

            fund_ret[m][n+1] = fund_ret[m][n]* (1 + re_ret[m][n+1])

    mean = np.mean(fund_ret[:,-1])  #just need the last column and all rows

    for i in range(1000): 
        downside.append(np.maximum((mean - fund_ret[i,-1]), 0))

    return np.std(downside)

b = GEKKO()
w = b.Array(b.Var,3,value=0.33,lb=1e-5, ub=1)
b.Equation(b.sum(w)<=1)
b.Equation(np.dot(w,ret) == .07) 
b.Minimize(simulations(w))
b.solve(disp=False)

#simulations(wt)

如果您将“gekko”部分注释掉并在底部调用模拟函数,它就可以正常工作。

我编辑了问题并使其更加清晰。希望现在更好了。 - Mohit Tuteja
也许与此问题有关:https://github.com/BYU-PRISM/GEKKO/issues/54 - Arraval
1个回答

1
在这种情况下,您需要考虑使用不同的优化器,例如scipy.minimize.optimize。函数np.std()目前不受Gekko支持。Gekko将模型编译为字节码以进行自动微分,因此您需要将问题适应为受支持的形式。对于大规模或非线性问题,Gekko的方法具有几个优点。对于少于100个变量且约线性约束的小问题,像scipy.minimize.optimize这样的优化器通常是可行的选择。以下是您的问题及其解决方案:
import numpy as np
from scipy.optimize import minimize

wt = np.array([0.4, 0.3, 0.3])

cov = np.array([[0.00026566, 0.00016167, 0.00011949],
   [0.00016167, 0.00065866, 0.00021662],
   [0.00011949, 0.00021662, 0.00043748]])

ret =[.098, 0.0620,.0720]
iterations = 10000
return_sim = np.random.multivariate_normal(ret, cov, iterations)

def simulations(wt):
    downside =[]
    fund_ret =np.zeros((1000,10))
    prt_ret = np.dot(return_sim , wt)
    re_ret = np.array(prt_ret).reshape(1000, 10) #10 years

    for m in range(len(re_ret)):
        fund_ret[m][0] = 100 * (1 + re_ret[m][0]) #start with $100
        for n in range(9):
            fund_ret[m][n+1] = fund_ret[m][n]* (1+re_ret[m][n+1])

    #just need the last column and all rows
    mean = np.mean(fund_ret[:,-1])  

    for i in range(1000): 
        downside.append(np.maximum((mean - fund_ret[i,-1]), 0))

    return np.std(downside)

b = (1e-5,1); bnds=(b,b,b)
cons = ({'type': 'ineq', 'fun': lambda x:  sum(x)-1},\
        {'type': 'eq',   'fun': lambda x:  np.dot(x,ret)-.07})
sol = minimize(simulations,wt,bounds=bnds,constraints=cons)
w = sol.x
print(w)

这会生成解决方案sol,并带有最优值w=sol.x:
     fun: 6.139162309118155
     jac: array([ 8.02691203, 10.04863131,  9.49171901])
 message: 'Optimization terminated successfully.'
    nfev: 33
     nit: 6
    njev: 6
  status: 0
 success: True
       x: array([0.09741111, 0.45326888, 0.44932001])

1
明白了。我真的很感激你也为此提供了一些见解。谢谢! - Mohit Tuteja

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接