В этом примере показано, как решить задачу оптимизации портфеля Смешано-целочисленного квадратичного программирования (MIQP) с помощью intlinprog
Решатель Смешано-целочисленного линейного программирования (MILP). Идея состоит в том, чтобы итеративно решить последовательность проблем MILP, которые локально аппроксимируют проблему MIQP. Для подхода, основанного на проблеме смотрите Смешано-целочисленную Оптимизацию Портфеля Квадратичного программирования: основанный на проблеме.
Когда Markowitz показал ("Выбор Портфеля", J. Финансируйте Объем 7, Выпуск 1, стр 77-91, март 1952), можно выразить много задач оптимизации портфеля как проблемы квадратичного программирования. Предположим, что у вас есть набор N
активы и хотят выбрать портфель, с будучи частью ваших инвестиций, которые находятся в активе . Если вы знаете вектор из среднего значения возвращается из каждого актива и ковариационной матрицы из возвратов, затем для данного уровня нерасположенности к риску вы максимизируете настроенный риском ожидаемый доход:
quadprog
решатель решает эту проблему квадратичного программирования. Однако в дополнение к простой проблеме квадратичного программирования, вы можете хотеть ограничить портфель во множестве путей, таких как:
Наличие не больше, чем M
активы в портфеле, где M <= N
.
Наличие, по крайней мере, m
активы в портфеле, где 0 < m <= M
.
Наличие полунепрерывных ограничений, значение также , или для некоторых фиксированных частей и .
Вы не можете включать эти ограничения в quadprog
. Трудность является дискретной природой ограничений. Кроме того, в то время как смешано-целочисленный линейный решатель программирования intlinprog
действительно обрабатывает дискретные ограничения, это не обращается к квадратичным целевым функциям.
Этот пример создает последовательность проблем MILP, которые удовлетворяют ограничениям, и что все больше аппроксимированный квадратичная целевая функция. В то время как этот метод работает на этот пример, он не может примениться к различной проблеме или типам ограничения.
Начните путем моделирования ограничений.
вектор частей распределения активов, с для каждого . Чтобы смоделировать количество активов в портфеле, вам нужны переменные индикатора таким образом, что когда , и когда . Чтобы получить переменные, которые удовлетворяют этому ограничению, установите вектор, чтобы быть бинарной переменной и наложить линейные ограничения
Эти неравенства оба осуществляют это и нуль в точно то же время, и они также осуществляют это каждый раз, когда .
Кроме того, чтобы осуществить ограничения на количество активов в портфеле, наложите линейные ограничения
Как сначала сформулировано, вы пытаетесь максимизировать целевую функцию. Однако все решатели Optimization Toolbox™ минимизируют. Поэтому сформулируйте проблему как минимизацию отрицания цели:
Эта целевая функция нелинейна. intlinprog
Решатель MILP требует линейной целевой функции. Существует стандартный метод, чтобы переформулировать эту проблему в одну с линейными объективными и нелинейными ограничениями. Введите слабую переменную представлять квадратичный термин.
Когда вы итеративно решаете приближения 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).