Этот пример показывает, как решить задачу оптимизации портфеля Смешано-целочисленного квадратичного программирования (MIQP) с помощью решателя Смешано-целочисленного линейного программирования (MILP) intlinprog
. Идея состоит в том, чтобы итеративно решить последовательность проблем MILP, которые локально аппроксимируют проблему MIQP. Для основанного на проблеме подхода смотрите Смешано-целочисленную Оптимизацию Портфеля Квадратичного программирования: основанный на проблеме.
Когда Markowitz показал ("Выбор Портфеля", J. Финансируйте Объем 7, Выпуск 1, стр 77-91, март 1952), можно выразить много задач оптимизации портфеля как проблемы квадратичного программирования. Предположим, что вы имеете набор активов N
и хотите выбрать портфель, с будучи частью ваших инвестиций, которые находятся в активе . Если вы знаете вектор из среднего значения возвращается из каждого актива и ковариационной матрицы из возвратов, затем для данного уровня нерасположенности к риску вы максимизируете настроенный риском ожидаемый доход:
Решатель quadprog
решает эту проблему квадратичного программирования. Однако в дополнение к простой проблеме квадратичного программирования, вы можете хотеть ограничить портфель во множестве путей, таких как:
Наличие не больше, чем активов M
в портфеле, где M <= N
.
Наличие, по крайней мере, активов m
в портфеле, где 0 < m <= M
.
Наличие полунепрерывных ограничений, значение также , или для некоторых фиксированных частей и .
Вы не можете включать эти ограничения в quadprog
. Трудность является дискретной природой ограничений. Кроме того, в то время как смешано-целочисленный линейный решатель программирования, intlinprog
действительно обрабатывает дискретные ограничения, он не обращается к квадратичным целевым функциям.
Этот пример создает последовательность проблем MILP, которые удовлетворяют ограничения, и что все больше аппроксимированный квадратичная целевая функция. В то время как этот метод работает на этот пример, он не может примениться к различной проблеме или типам ограничения.
Начните путем моделирования ограничений.
вектор частей распределения активов, с для каждого . Чтобы смоделировать количество активов в портфеле, вам нужны переменные индикатора таким образом, что когда , и когда . Чтобы получить переменные, которые удовлетворяют это ограничение, установите вектор, чтобы быть бинарной переменной и наложить линейные ограничения
Эти неравенства оба осуществляют это и нуль в точно то же время, и они также осуществляют это каждый раз, когда .
Кроме того, чтобы осуществить ограничения на количество активов в портфеле, наложите линейные ограничения
Как сначала сформулировано, вы пытаетесь максимизировать целевую функцию. Однако все решатели Optimization Toolbox™ минимизируют. Поэтому сформулируйте проблему как минимизацию отрицания цели:
Эта целевая функция нелинейна. Решатель MILP intlinprog
требует линейной целевой функции. Существует стандартный метод, чтобы повторно сформулировать эту проблему в одну с линейными объективными и нелинейными ограничениями. Введите слабую переменную представлять квадратичный термин.
Когда вы итеративно решаете приближения MILP, вы включаете новые линейные ограничения, каждое из которых аппроксимирует нелинейное ограничение локально около текущей точки. В частности, для где постоянный вектор и переменный вектор, первый порядок, который приближение Тейлора к ограничению
Заменяя дает
Для каждого промежуточного решения вы вводите новое линейное ограничение в и как линейная часть выражения выше:
Это имеет форму , где , существует a множитель для назовите, и .
Этот метод добавления новых линейных ограничений к проблеме называется сокращающим плоским методом. Для получения дополнительной информации смотрите Дж. Э. Келли младшего "Плоский Сокращением Метод для Решения Выпуклых Программ". Дж. Сок. Indust. Прикладная Математика. Издание 8, № 4, стр 703-712, декабрь 1960.
Чтобы выразить проблемы для решателя intlinprog
, необходимо сделать следующее:
Решите то, что представляют ваши переменные
Выразите нижние и верхние границы с точки зрения этих переменных
Дайте линейные матрицы равенства и неравенства
Имейте первое переменные представляют вектор, следующее переменные представляют двоичный файл вектор и последняя переменная представляют слабая переменная. Существуют переменные в проблеме.
Загрузите данные для проблемы. Эти данные имеют 225 ожидаемых доходов в векторном r
и ковариации возвратов в 225 225 матричном Q
. Данные эквивалентны в Использовании Квадратичного программирования на примере Задач оптимизации Портфеля.
load port5
r = mean_return;
Q = Correlation .* (stdDev_return * stdDev_return');
Определите номер активов как N
.
N = length(r);
Установите индексы для переменных
xvars = 1:N; vvars = N+1:2*N; zvar = 2*N+1;
Нижние границы всех переменных 2N+1
в проблеме являются нулем. Верхние границы первых переменных 2N
один, и последняя переменная не имеет никакой верхней границы.
lb = zeros(2*N+1,1); ub = ones(2*N+1,1); ub(zvar) = Inf;
Определите номер активов в решении быть между 100 и 150. Включите это ограничение в проблему в форме, а именно,
путем записи двух линейных ограничений формы :
M = 150; m = 100; A = zeros(1,2*N+1); % Allocate A matrix A(vvars) = 1; % A*x represents the sum of the v(i) A = [A;-A]; b = zeros(2,1); % Allocate b vector b(1) = M; b(2) = -m;
Включайте полунепрерывные ограничения. Возьмите минимальную ненулевую часть активов, чтобы быть 0.001
для каждого типа актива и максимальной частью, чтобы быть 0.05
.
fmin = 0.001; fmax = 0.05;
Включайте неравенства и как линейные неравенства.
Atemp = eye(N); Amax = horzcat(Atemp,-Atemp*fmax,zeros(N,1)); A = [A;Amax]; b = [b;zeros(N,1)]; Amin = horzcat(-Atemp,Atemp*fmin,zeros(N,1)); A = [A;Amin]; b = [b;zeros(N,1)];
Включайте ограничение, которое портфель составляет 100%, которые инвестируют, означая .
Aeq = zeros(1,2*N+1); % Allocate Aeq matrix
Aeq(xvars) = 1;
beq = 1;
Установите коэффициент нерасположенности к риску к 100
.
lambda = 100;
Задайте целевую функцию как вектор. Включайте нули для множителей переменные.
f = [-r;zeros(N,1);lambda];
Чтобы решить проблему итеративно, начните путем решения проблемы с текущими ограничениями, которые еще не отражают линеаризации. Целочисленные ограничения находятся в векторе vvars
.
options = optimoptions(@intlinprog,'Display','off'); % Suppress iterative display [xLinInt,fval,exitFlagInt,output] = intlinprog(f,vvars,A,b,Aeq,beq,lb,ub,options);
Подготовьте останавливающееся условие к итерациям: остановитесь когда слабая переменная в 0,01% истинного квадратичного значения. Установите более трудные допуски, чем значение по умолчанию помогать гарантировать, что проблема остается строго выполнимой, когда ограничения накапливаются.
thediff = 1e-4; iter = 1; % iteration counter assets = xLinInt(xvars); % the x variables truequadratic = assets'*Q*assets; zslack = xLinInt(zvar); % slack variable value options = optimoptions(options,'LPOptimalityTolerance',1e-10,'RelativeGapTolerance',1e-8,... 'ConstraintTolerance',1e-9,'IntegerTolerance',1e-6);
Сохраните историю вычисленных истинных квадратичных и слабых переменных для графического вывода.
history = [truequadratic,zslack];
Вычислите квадратичные и слабые значения. Если они отличаются, то добавьте другое линейное ограничение и решите снова.
В синтаксисе тулбокса, каждом новом линейном ограничении прибывает из линейной аппроксимации
Вы видите что новая строка и новый элемент в , с термин, представленный-1 коэффициентом в .
После того, как вы найдете новое решение, используйте линейное ограничение на полпути между старыми и новыми решениями. Этот эвристический способ включать линейные ограничения может быть быстрее, чем простое взятие нового решения. Чтобы использовать решение вместо промежуточной эвристики, прокомментируйте "На полпути" строка ниже и не прокомментируйте следующую.
while abs((zslack - truequadratic)/truequadratic) > thediff % relative error newArow = horzcat(2*assets'*Q,zeros(1,N),-1); % Linearized constraint rhs = assets'*Q*assets; % right hand side of the linearized constraint A = [A;newArow]; b = [b;rhs]; % Solve the problem with the new constraints [xLinInt,fval,exitFlagInt,output] = intlinprog(f,vvars,A,b,Aeq,beq,lb,ub,options); assets = (assets+xLinInt(xvars))/2; % Midway from the previous to the current % assets = xLinInt(xvars); % Use the previous line or this one truequadratic = xLinInt(xvars)'*Q* xLinInt(xvars); zslack = xLinInt(zvar); history = [history;truequadratic,zslack]; iter = iter + 1; end
Постройте историю слабой переменной и квадратичную часть целевой функции, чтобы видеть, как они сходились.
plot(history) legend('Quadratic','Slack') xlabel('Iteration number') title('Quadratic and linear approximation (slack)')
Каково качество решения MILP? Структура output
содержит ту информацию. Исследуйте абсолютный разрыв между внутренне вычисленными границами на цели в решении.
disp(output.absolutegap)
0
Абсолютный разрыв является нулем, указывая, что решение MILP точно.
Постройте оптимальное выделение. Используйте xLinInt(xvars)
, не assets
, потому что assets
не может удовлетворить ограничения при использовании на полпути обновление.
bar(xLinInt(xvars)) grid on xlabel('Asset index') ylabel('Proportion of investment') title('Optimal Asset Allocation')
Можно легко видеть, что все ненулевое распределение активов между полунепрерывными границами и .
Сколько ненулевые активы там? Ограничение состоит в том, что существует между 100 и 150 ненулевыми активами.
sum(xLinInt(vvars))
ans = 100
Каковы ожидаемый доход для этого выделения и значение доходности с учетом риска?
fprintf('The expected return is %g, and the risk-adjusted return is %g.\n',... r'*xLinInt(xvars),-fval)
The expected return is 0.000595107, and the risk-adjusted return is -0.0360382.
Более тщательно продуманные исследования возможны при помощи функций, специально предназначенных для оптимизации портфеля в Financial Toolbox™. Для примера, который показывает, как использовать класс Портфеля, чтобы непосредственно обработать полунепрерывный и ограничения кардинальности, смотрите Оптимизацию Портфеля с Полунепрерывным и Ограничения Кардинальности (Financial Toolbox).