Я пытаюсь решить проблему, которую я отправил в QSE, https://quant.stackexchange.com/questions/65680/find-k-of-n-assets-that-minimize-the-correlation-matrix/, но я сталкиваюсь с проблема с использованием cvxpy lib. А именно, то, что я считаю проблемой выпуклого двоичного программирования, как утверждает cvxpy, не соответствует правилам DCP.
Проблема, которую я пытаюсь решить, заключается в следующем: из заданных 10 рискованных активов найти 5 наименее коррелированных. Моя текущая методология решения этой проблемы
- Получите доход от каждого актива
- Найдите корреляционную матрицу
C
для этих доходов. - Formulate the convex optimization problem as
x
is a binary vector- сумма записей
x
равна 5 C' = transpose(C * x) * x
- это матрица, в которойi
-я строка иi
-й столбецC
обнуляются, когдаi
-я записьx
равна 0 (и не обнуляется в противном случае). Примечание: мне интересно, возникает ли здесь моя проблема. Это был лучший способ, который я мог придумать, чтобы удалить записи из корреляционной матрицыC
, которые соответствуют отклоненным активам.- Наконец, я хочу минимизировать сумму квадратов
C'
. Это даст мне что-то вроде портфеля из 5 наименее коррелированных активов.
Ниже приводится нерабочий код, который у меня пока есть.
import pandas as pd
import pandas_datareader as web
import datetime as dt
import cvxpy as cvx
stocks = ['SHW', 'GOOG', 'AMZN', 'WMT', 'XOM', 'JNJ', 'UPS', 'AMT', 'AAPL', 'NEE']
start = dt.datetime(2015, 1, 1)
end = dt.datetime(2020, 1, 1)
d = web.DataReader(stocks, 'yahoo', start, end)['Adj Close']
corr = d.corr().to_numpy()
x = cvx.Variable(len(stocks), boolean=True)
cost = cvx.sum_squares((corr @ x).T @ x)
prob = cvx.Problem(cvx.Minimize(cost), [cvx.sum(x) == 5])
prob.solve(solver='ECOS_BB')
И ошибка, которую он производит
DCPError: Problem does not follow DCP rules. Specifically:
The objective is not DCP. Its following subexpressions are not:
# The corr array
Я также пытался переформулировать это несколькими способами, которые не помогли, включая
- Использование матрицы переменных cvxp
X
с логическими и симметричными атрибутами cvxpy. Если он симметричен и каждая строка в сумме равна 5, то у меня есть матрица, для которой я могу выполнить поэлементное умножение, чтобы найтиC'
. Это не работает, потому что переменной разрешен только один атрибут (странное ограничение cvxpy). - Использование двоичной матрицы переменной cvxp
X
и симметричной матрицы переменной cvxpY
, включая ограничениеX == Y
(чтобы обойти ограничение с двумя атрибутами). Я не могу вспомнить, почему это не сработало. - Используя двоичную матрицу переменной cvxp
X
и ограничения, что сумма каждойi
-й строки равна 5 и чтоi
-я строка равнаj
-ому столбцу. У меня были проблемы с этим, потому что тестированиеX[i] == X[:i]
создает логический массив, который я не знал, как уменьшить с помощью cvxpy. - Я также пробовал использовать не -двоичный вектор переменной cvxpy
x
и пытался ограничитьi
-е значениеx
равным 0 или 1, но ограничениеx[i] == 0 || x[i] == 1
недействительно из-за _28 _ - Я также не удалось найти условие логического или cvxpy.
Итак, я попытался переформулировать это несколькими разными способами, но постоянно сталкиваюсь с проблемами с каждой стратегией. Мне интересно, может ли кто-нибудь мне помочь
- Определите, действительно ли это проблема, которую может решить cvxpy. Если это не так, как я могу изменить его, чтобы решить, по сути, то, что я хочу? Если это что-то, что cvxpy может решить
- Что я могу сделать с моим текущим кодом, чтобы исправить его проблемы?
Спасибо за ваше время.