Попытка решить эту нелинейную оптимизацию с помощью GEKKO, получаю эту ошибку

@Error: установка элемента массива с последовательностью

Я пытаюсь свести к минимуму риск ухудшения ситуации.

У меня есть двумерный массив формы доходности (1000, 10), а портфель начинается со 100 долларов. Соедините это 10 раз с каждым возвратом подряд. Сделайте это для всех строк. Сравните значение последней ячейки для каждой строки со средним из значений последнего столбца. Сохраните значение, если оно меньше среднего или равно нулю. Итак, у нас будет массив (1000, 1). В конце концов, я нахожу это стандартное отклонение.

Цель - минимизировать стандартное отклонение. Ограничения: вес должен быть меньше 1

ожидаемый доход т.е. wt * ret должно быть равно 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 и вызовете функцию моделирования внизу, все будет нормально


person Mohit Tuteja    schedule 03.06.2020    source источник
comment
Я отредактировал вопрос и уточнил. Надеюсь, так лучше.   -  person Mohit Tuteja    schedule 03.06.2020
comment
возможно, это связано с этой проблемой: github.com/BYU-PRISM/GEKKO/issues/54   -  person Arraval    schedule 04.06.2020


Ответы (1)


В этом случае вам следует рассмотреть другой оптимизатор, например scipy.minimize.optimize. Функция np.std() в настоящее время не поддерживается в 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])
person John Hedengren    schedule 04.06.2020
comment
Попался. Я очень ценю, что вы пролили свет и на это. Спасибо !! - person Mohit Tuteja; 05.06.2020