В этом примере показано, как использовать Portfolio
объект для непосредственного указателя полунепрерывных и кардинальных ограничений при выполнении оптимизации портфеля. Оптимизация портфеля находит распределение активов, которое максимизирует возврат или минимизирует риск, удовлетворяющий набору инвестиционных ограничений. The Portfolio
класс в Financial Toolbox™ разработан и реализован на основе среды оптимизации средних дисперсий Markowitz. Среда оптимизации средних дисперсий решает проблемы, где возврат является ожидаемой доходностью портфеля, а риск - отклонением возвратов портфеля. Использование Portfolio
класс, вы можете минимизировать риск на эффективной границе (EF), максимизировать возврат на EF, максимизировать возврат для данного риска и минимизировать риск для заданного возврата. Можно также использовать PortfolioCVaR
или PortfolioMAD
классы в Financial Toolbox™ для задания полунепрерывных и кардинальных ограничений. Такие задачи оптимизации интегрируются с ограничениями, такими как группа, линейное неравенство, оборот и отслеживание ограничений ошибок. Эти ограничения сформулированы как задачи нелинейного программирования (NLP) с непрерывными переменными, представленными в виде весов активов .
Полунепрерывные и кардинальные ограничения являются двумя другими общими категориями портфельных ограничений, которые формулируются математически путем добавления двоичных переменных .
Полунепрерывное ограничение ограничивает распределение актива. Для примера можно использовать это ограничение, чтобы ограничить распределенный вес присвоенного актива от 5% до 50%. Используя это ограничение, можно избежать очень маленьких или больших позиций, чтобы минимизировать оттоки и эксплуатационные затраты. Чтобы математически сформулировать этот тип ограничения, двоичная переменная нужно, где является 0
или 1
. Значение 0
указывает, что актив i не распределен, и значение 1
указывает, что основное средство i распределено. Математическая форма, где является 0
или 1
. Задайте этот тип ограничения как 'Conditional'
BoundType
в Portfolio
класс с использованием setBounds
функция.
Ограничение кардинальности ограничивает количество активов в оптимальном распределении, Например, для портфеля с вселенной из 100 активов, можно задать оптимальное распределение портфеля между 20 и 40 активами. Эта возможность помогает ограничить количество позиций и, таким образом, сократить эксплуатационные затраты. Чтобы математически сформулировать этот тип ограничения, двоичные переменные представлены как нужны, где является 0
или 1
. Значение 0
указывает, что актив i не распределен, и значение 1
указывает, что основное средство i распределено. Математическая форма , где является 0
или 1
. Задайте этот тип ограничения путем установки 'MinNumAssets'
и 'MaxNumAssets'
ограничения в Portfolio
класс с использованием setMinMaxNumAssets
функция.
Для получения дополнительной информации об ограничениях полунепрерывности и кардинальности, см. Алгоритмы.
Когда полунепрерывные и кардинальные ограничения используются для оптимизации портфеля, это приводит к смешанным целочисленным нелинейным задачам программирования (MINLP). The Portfolio
класс позволяет вам сконфигурировать эти два ограничения, в частности, полунепрерывные ограничения с помощью setBounds
с 'Conditional'
BoundType
, и ограничения кардинальности с помощью setMinMaxNumAssets
. The Portfolio
класс автоматически формулирует математические задачи и проверяет указанные ограничения. The Portfolio
класс также предоставляет встроенные решатели MINLP и гибкие опции решателя для вас, чтобы настроить эффективность решателя с помощью setSolverMINLP
функция.
Этот пример демонстрирует Portfolio
объект с полунепрерывными и кардинальными ограничениями и использует BlueChipStockMoments
набор данных, который имеет вселенную из 30 активов.
load BlueChipStockMoments
numAssets = numel(AssetList)
numAssets = 30
Создайте полностью инвестированный портфель с только длинными позициями: . Они сконфигурированы с setDefaultConstraints
.
p = Portfolio('AssetList', AssetList,'AssetCovar', AssetCovar, 'AssetMean', AssetMean); p = setDefaultConstraints(p);
Предположим, что вы хотите избегать очень маленьких позиций, чтобы минимизировать отток и эксплуатационные затраты. Добавьте другое ограничение, чтобы ограничить выделенные положения не менее 5% путем установки ограничений использование setBounds
с 'Conditional'
BoundType
.
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
с 'Conditional'
BoundType
. В противном случае оптимизатор не может оценить, какие активы распределяются, и не может сформулировать MinNumAssets
ограничение. Для получения дополнительной информации смотрите Условные границы с нижними границами, определенными как Пустые или Нулевые.
Постройте график эффективной границы, чтобы сравнить этот портфель с базовым портфелем, который имеет только ограничения по умолчанию.
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). The 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
объект, такой как группа, линейное неравенство, оборот и ошибка отслеживания, может использоваться вместе со 'Conditional'
BoundType
, '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'
средства и 'Conditional'
средства .
Разрешить использование ресурсов в 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
Portfolio
| setBounds
| setMinMaxNumAssets
| setSolverMINLP