Оптимизация портфеля с полунепрерывным и ограничения кардинальности

Этот пример показывает, как использовать объект Portfolio непосредственно обработать полунепрерывный и ограничения кардинальности при выполнении оптимизации портфеля. Оптимизация портфеля находит распределение активов, которое максимизирует возврат или минимизирует риск согласно набору инвестиционных ограничений. Класс Portfolio в Financial Toolbox™ разработан и реализован на основе среды Оптимизации Markowitz Mean-Variance. Среда Оптимизации Среднего Отклонения решает проблемы, где возврат является ожидаемым портфелем, возвращаются, и риск является отклонением портфеля, возвращается. Используя класс Portfolio, можно минимизировать риск на границе эффективности (EF), максимизировать возврат на EF, максимизировать возврат для данного риска и минимизировать риск для данного возврата. Можно также использовать PortfolioCVaR или классы PortfolioMAD в Financial Toolbox™, чтобы задать полунепрерывный и ограничения кардинальности. Такие задачи оптимизации объединяются с ограничениями, такими как группа, линейное неравенство, оборот и ошибочные ограничения отслеживания. Эти ограничения формулируются как нелинейное программирование (NLP) проблемы с непрерывными переменными, представленными как веса актива xi.

Полунепрерывный и ограничения кардинальности две других общих категории ограничений портфеля, которые формулируются математически путем добавления бинарных переменных vi.

  • Полунепрерывное ограничение ограничивает выделение актива. Например, можно использовать это ограничение, чтобы ограничить выделенный вес выделенного актива к между 5% и 50%. При помощи этого ограничения можно избежать очень маленьких или больших положений, чтобы минимизировать маслобойки и операционные затраты. Математически сформулировать этот тип ограничения, бинарной переменной vi необходим, где vi 0 или 1. Значение 0 указывает, что актив i не выделяюсь и значение 1, указывает, что актив i выделяюсь. Математическая формаlb*vixiub*vi, где vi 0 или 1. Задайте этот тип ограничения как BoundType 'Conditional' в классе Portfolio с помощью функции setBounds.

  • Ограничение кардинальности ограничивает количество активов в оптимальном выделении, Например, для портфеля со вселенной 100 активов, можно задать выделение оптимального портфеля между 20 и 40 активами. Эта возможность помогает ограничить количество положений, и таким образом уменьшать операционные затраты. Математически сформулировать этот тип ограничения, бинарные переменные, представленные как vi необходимы, где vi 0 или 1. Значение 0 указывает, что актив i не выделяюсь и значение 1, указывает, что актив i выделяюсь. Математическая форма MinNumAssets1NumAssetsviMaxNumAssets, где vi 0 или 1. Задайте этот тип ограничения путем установки 'MinNumAssets' и ограничений 'MaxNumAssets' в классе Portfolio с помощью функции setMinMaxNumAssets.

Для получения дополнительной информации о полунепрерывном и ограничениях кардинальности, см. Алгоритмы.

Когда полунепрерывный и ограничения кардинальности используются для оптимизации портфеля, это приводит к смешанным целочисленным проблемам нелинейного программирования (MINLP). Класс Portfolio позволяет вам конфигурировать эти два ограничения, а именно, полунепрерывные ограничения с помощью setBounds с 'Conditional' BoundType и ограничения кардинальности с помощью setMinMaxNumAssets. Класс Portfolio автоматически формулирует математические проблемы и подтверждает заданные ограничения. Класс Portfolio также обеспечивает встроенные решатели MINLP и гибкие опции решателя для вас, чтобы настроить производительность решателя с помощью функции setSolverMINLP.

Этот пример демонстрирует объект Portfolio с полунепрерывным и ограничениями кардинальности и использует набор данных BlueChipStockMoments, который имеет вселенную 30 активов.

load BlueChipStockMoments
numAssets = numel(AssetList)
numAssets = 30

Ограничьте минимальный вес для каждого выделенного актива

Создайте полностью инвестированный портфель только с длинными позициями: xi0  исумма(xi)=1. Они сконфигурированы с setDefaultConstraints.

p = Portfolio('AssetList', AssetList,'AssetCovar', AssetCovar, 'AssetMean', AssetMean);
p = setDefaultConstraints(p);

Предположим, что вы хотите избежать очень маленьких положений, чтобы минимизировать маслобойку и операционные затраты. Добавьте другое ограничение, чтобы ограничить выделенные положения, чтобы быть не менее чем 5% путем установки ограничений xi=0 илиxi0.05 использование setBounds с BoundType 'Conditional'.

pWithMinWeight = setBounds(p, 0.05, 'BoundType', 'Conditional');

Постройте границы эффективности для обоих объектов Portfolio.

wgt = estimateFrontier(p);
wgtWithMinWeight = estimateFrontier(pWithMinWeight);
figure(1);
plotFrontier(p, wgt); hold on;
plotFrontier(pWithMinWeight, wgtWithMinWeight); hold off;
legend('Baseline portfolio', 'With minWeight constraint', 'location', 'best');

Данные показывают, что два объекта Portfolio имеют почти идентичные границы эффективности. Однако тот с минимальным требованием веса более практичен, поскольку это предотвращает положения близко к нулю.

Проверяйте оптимальные веса на портфель с ограничениями по умолчанию, чтобы видеть, как много активов ниже 5%-го предела для каждого оптимального выделения.

toler = eps;
sum(wgt>toler & wgt<0.05)
ans = 1×10

     5     7     5     4     2     3     4     2     0     0

Используйте estimateFrontierByReturn, чтобы исследовать структуры портфеля для целевого возврата на границе для обоих случаев.

targetRetn = 0.011;
pwgt = estimateFrontierByReturn(p, targetRetn);
pwgtWithMinWeight = estimateFrontierByReturn(pWithMinWeight, targetRetn);

Постройте состав двух объектов Portfolio для вселенной 30 активов.

figure(2);
barh([pwgt, pwgtWithMinWeight]);
grid on
xlabel('Proportion of Investment')
yticks(1:p.NumAssets);
yticklabels(p.AssetList);
title('Asset Allocation');
legend('Without min weight limit', 'With min weight limit', 'location', 'best');

Покажите только выделенные активы.

idx = (pwgt>toler) | (pwgtWithMinWeight>toler);

barh([pwgt(idx), pwgtWithMinWeight(idx)]);
grid on
xlabel('Proportion of Investment')
yticks(1:sum(idx));
yticklabels(p.AssetList(idx));
title('Asset Allocation');
legend('Without min weight limit', 'With min weight limit', 'location', 'best');

Ограничьте максимальное количество активов, чтобы выделить

Используйте setMinMaxNumAssets, чтобы определить максимальный номер выделенных активов для объекта Portfolio. Предположим, что вы хотите не больше, чем восемь активов, которые инвестируют в оптимальный портфель. Для этого с объектом Portfolio, используйте setMinMaxNumAssets.

pWithMaxNumAssets = setMinMaxNumAssets(p, [], 8);

wgt = estimateFrontier(p);
wgtWithMaxNumAssets = estimateFrontier(pWithMaxNumAssets);
plotFrontier(p, wgt); hold on;
plotFrontier(pWithMaxNumAssets, wgtWithMaxNumAssets); hold off;
legend('Baseline portfolio', 'With MaxNumAssets constraint', 'location', 'best');

Используйте estimateFrontierByReturn, чтобы найти выделение, которое минимизирует риск на границе для данного целевого возврата.

pwgtWithMaxNum = estimateFrontierByReturn(pWithMaxNumAssets, targetRetn);

Постройте состав двух объектов Portfolio для вселенной 30 активов.

idx = (pwgt>toler) | (pwgtWithMaxNum>toler);

barh([pwgt(idx), pwgtWithMaxNum(idx)]);
grid on
xlabel('Proportion of Investment')
yticks(1:sum(idx));
yticklabels(p.AssetList(idx));
title('Asset Allocation');
legend('Baseline portfolio', 'With MaxNumAssets constraint', 'location', 'best');

sum(abs(pwgt)>toler)
ans = 11

Считайте общее количество выделенных активов, чтобы проверить, что самое большее выделяются только восемь активов.

sum(abs(pwgtWithMaxNum)>toler)
ans = 8

Ограничьте минимальное и максимальное количество активов, чтобы выделить

Предположим, что вы хотите установить и нижние и верхние границы для количества активов выделять в портфеле, учитывая вселенную активов. Используйте setBounds, чтобы задать позволенное количество активов, чтобы выделить как от 5 до 10, и выделенный вес как не менее чем 5%.

p1 = setMinMaxNumAssets(p, 5, 10);
p1 = setBounds(p1, 0.05, 'BoundType', 'conditional'); 

Если актив выделяется, необходимо ясно задать минимальное требование веса для того актива. Это сделано с помощью setBounds с BoundType 'Conditional'. В противном случае оптимизатор не может оценить, какие активы выделяются и не могут сформулировать ограничение MinNumAssets. Для получения дополнительной информации смотрите Условные Границы с LowerBound, Заданным как Пустые или Нуль.

Постройте границу эффективности, чтобы сравнить этот портфель с базовым портфелем, который имеет только ограничения по умолчанию.

wgt = estimateFrontier(p);
wgt1 = estimateFrontier(p1);
plotFrontier(p, wgt); hold on;
plotFrontier(p1, wgt1); hold off;
legend('Baseline portfolio', 'With MaxNumAssets constraint', 'location', 'best');

Распределение активов для равно взвешенного портфеля

Создайте равно взвешенный портфель с помощью и setBounds и функций setMinMaxNumAssets.

numAssetsAllocated = 8;
weight= 1/numAssetsAllocated;
p2 = setBounds(p, weight, weight, 'BoundType', 'conditional');   
p2 = setMinMaxNumAssets(p2, numAssetsAllocated, numAssetsAllocated); 

Когда любой или любая комбинация 'Conditional', BoundType, MinNumAssets или MaxNumAssets активны, задача оптимизации, формулируется как смешанное целочисленное нелинейное программирование (MINLP) проблема. Класс Portfolio автоматически создает проблему MINLP на основе заданных ограничений.

При работе с объектом Portfolio можно выбрать один из трех решателей с помощью функции setSolverMINLP. В этом примере, вместо того, чтобы использовать опции решателя MINLP по умолчанию, настраивают опции решателя, чтобы помочь с проблемой сходимости. Используйте большое количество (50) для 'MaxIterationsInactiveCut' с setSolverMINLP вместо значения по умолчанию 30 для 'MaxIterationsInactiveCut'. Значение 50 работает хорошо в нахождении границы эффективности оптимального распределения активов.

p2 = setSolverMINLP(p2, 'OuterApproximation', 'MaxIterationsInactiveCut', 50);

Постройте границы эффективности для базовых и равно взвешенных портфелей.

wgt = estimateFrontier(p);
wgt2 = estimateFrontier(p2);
plotFrontier(p, wgt); hold on;
plotFrontier(p2, wgt2); hold off;
legend('Baseline portfolio', 'Equal Weighted portfolio', 'location', 'best');

Используйте estimateFrontierByRisk, чтобы оптимизировать для определенного уровня риска в этом случае .05, определить, какое выделение максимизирует портфель, возвращаются.

targetRisk = 0.05;
pwgt = estimateFrontierByRisk(p, targetRisk);
pwgt2 = estimateFrontierByRisk(p2, targetRisk);

idx = (pwgt>toler) | (pwgt2>toler);
barh([pwgt(idx), pwgt2(idx)]);
grid on
xlabel('Proportion of investment')
yticks(1:sum(idx));
yticklabels(p.AssetList(idx));
title('Asset Allocation');
legend('Baseline portfolio', 'Equal weighted portfolio', 'location', 'best');

Используйте 'Conditional' BoundType, MinNumAssets и ограничения MaxNumAssets с другими ограничениями

Можно задать другие ограничения для объекта Portfolio с помощью функций set. Эти другие ограничения для объекта Portfolio, такие как группа, линейное неравенство, оборот и ошибка отслеживания могут использоваться вместе с BoundType 'Conditional', 'MinNumAssets' и ограничениями 'MaxNumAssets'. Например, задайте ошибочное ограничение отслеживания с помощью setTrackingError.

ii = [15, 16, 20, 21, 23, 25, 27, 29, 30];	% indexes of assets to include in tracking portfolio
trackingPort(ii) = 1/numel(ii);
q = setTrackingError(p, 0.5, trackingPort);

Затем используйте setMinMaxNumAssets, чтобы добавить ограничение, чтобы ограничить максимальное количество активов, чтобы вложить капитал.

q = setMinMaxNumAssets(q, [], 8);

Вдобавок к этим ранее заданным ограничениям используйте setBounds, чтобы добавить ограничение, чтобы ограничить вес для выделенных активов. Можно использовать ограничения со смешанными значениями BoundType, где 'Simple' означает lbxiubи средние значения 'Conditional' xi=0 илиlbxiub.

Позвольте активам в trackingPort иметь значение BoundType 'Conditional' в оптимальном распределении.

lb = zeros(q.NumAssets, 1);
ub = zeros(q.NumAssets, 1)*0.5;
lb(ii) = 0.1;
ub(ii) = 0.3;
boundType = repmat("simple",q.NumAssets,1);
boundType(ii) = "conditional";
q = setBounds(q, lb, ub, 'BoundType',boundType);

Постройте границу эффективности:

plotFrontier(q);

Используйте estimateFrontierByReturn, чтобы найти выделение, которое минимизирует риск для данного возврата в 0.125.

targetRetn = 0.0125;
pwgt = estimateFrontierByReturn(q, targetRetn);

Покажите выделение активов в развес.

idx = abs(pwgt)>eps;
assetnames = q.AssetList';
Asset = assetnames(idx);
Weight = pwgt(idx);
resultAlloc = table(Asset, Weight)
resultAlloc=7×2 table
    Asset     Weight 
    ______    _______

    'JNJ'         0.1
    'MMM'     0.19503
    'MO'       0.1485
    'MSFT'        0.1
    'PG'          0.1
    'WMT'      0.2212
    'XOM'     0.13527

Для просмотра документации необходимо авторизоваться на сайте