我正在使用Gekko进行投资组合优化。我正在使用每个资产的回报及其协方差矩阵作为输入。我正在尝试的代码是
# Initialize Model
m = GEKKO(remote=True)
#initialize variables
w=m.Array(m.Var,23)
for i in range(23):
w[i].value = 0.04347826
w[i].lower = 0.0
w[i].upper = 1.0
#Equations
m.Equation(0.18 >= (np.dot(w.T,np.dot(covariance_ar, w)))**0.5)
m.Equation(np.sum(w[0:23]) == 1.0)
m.Equation(w[7]+w[9]+w[11] >= (np.sum(w[7:13])*0.3))
m.Equation(w[7]+w[9]+w[11] <= (np.sum(w[7:13])*0.7))
m.Equation(w[11]+w[12] >= 0.0)
m.Equation(w[11]+w[12] <= (np.sum(w[7:13])*0.15))
#Objective
m.Obj(-(np.sum(return_ar.T @ w)))
#Solve simulation
m.solve() # solve on public server
#Results
for i in range(23):
print('w['+str(i)+']='+str(w[i].value))
return_ar是形状为(23,1)的单个资产的收益数组,而covariance_ar是形状为(23,23)的收益的协方差数组
尽管代码成功运行,但权重数量较少,但具有23个权重参数,却引发错误 例外:@error:最大方程式长度....... APM模型错误:字符串> 15000个字符 考虑将线分成多个方程式
您能帮我制定代码约束以使其起作用吗?
答案 0 :(得分:2)
我无法运行您的代码,因为它缺少值,所以我不得不用示例值对其进行修改。
rtools40
这会重现您观察到的相同错误。您可以通过列表理解来重新定义# Initialize Model
from gekko import GEKKO
import numpy as np
m = GEKKO(remote=True)
#initialize variables
w=m.Array(m.Var,23)
for i in range(23):
w[i].value = 0.04347826
w[i].lower = 0.0
w[i].upper = 1.0
#Equations
covariance_ar = np.random.rand(23,23)
m.Equation(0.18 >= (np.dot(w.T,np.dot(covariance_ar, w)))**0.5)
m.Equation(m.sum(w[0:23]) == 1.0)
m.Equation(w[7]+w[9]+w[11] >= (m.sum(w[7:13])*0.3))
m.Equation(w[7]+w[9]+w[11] <= (m.sum(w[7:13])*0.7))
m.Equation(w[11]+w[12] >= 0.0)
m.Equation(w[11]+w[12] <= (m.sum(w[7:13])*0.15))
#Objective
m.Obj(-(m.sum(w)))
#Solve simulation
m.solve() # solve on public server
#Results
for i in range(23):
print('w['+str(i)+']='+str(w[i].value))
函数,从而克服方程长度的限制。另外,您需要使用np.dot
gekko函数而不是numpy函数进行求和。
m.sum()
您现在可以将# Initialize Model
from gekko import GEKKO
import numpy as np
m = GEKKO(remote=True)
#initialize variables
w=m.Array(m.Var,23)
for i in range(23):
w[i].value = 0.04347826
w[i].lower = 0.0
w[i].upper = 1.0
#Equations
C = np.random.rand(23,23)
Cw = [m.sum([m.Intermediate(C[i,j]*w[j]) \
for j in range(23)]) \
for i in range(23)]
wCw = m.sum([Cw[i]*w[i] for i in range(23)])
m.Equation(0.18 >= (wCw)**0.5)
m.Equation(m.sum(w[0:23]) == 1.0)
m.Equation(w[7]+w[9]+w[11] >= (m.sum(w[7:13])*0.3))
m.Equation(w[7]+w[9]+w[11] <= (m.sum(w[7:13])*0.7))
m.Equation(w[11]+w[12] >= 0.0)
m.Equation(w[11]+w[12] <= (m.sum(w[7:13])*0.15))
#Objective
return_ar = np.ones(23)
for i in range(23):
m.Maximize(w[i]*return_ar[i])
#Solve optimization
m.solve() # solve on public server
#Results
for i in range(23):
print('w['+str(i)+']='+str(w[i].value))
和covariance_ar
的值使用。此方法起作用的原因是,Gekko可以将方程分解为较小的部分,然后单独求解。每个等式的15,000个字符的长度限制不仅是处理上的限制,而且还鼓励使用与稀疏非线性规划求解器更好的模型表示策略。