В этом примере показано, как использовать Portfolio
возразите, чтобы непосредственно обработать полунепрерывный и ограничения кардинальности при выполнении оптимизации портфеля. Оптимизация портфеля находит распределение активов, которое максимизирует возврат или минимизирует риск согласно набору инвестиционных ограничений. Portfolio
класс в Financial Toolbox™ спроектирован и реализован на основе среды Оптимизации Markowitz Mean-Variance. Среда Оптимизации Среднего Отклонения решает проблемы, где возврат является ожидаемым портфелем, возвращаются, и риск является отклонением портфеля, возвращается. Используя 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). Portfolio
класс позволяет вам конфигурировать эти два ограничения, а именно, полунепрерывные ограничения с помощью setBounds
с 'Conditional'
BoundType
, и ограничения кардинальности с помощью setMinMaxNumAssets
. Portfolio
класс автоматически формулирует математические проблемы и подтверждает заданные ограничения. 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
ограничение. Для получения дополнительной информации смотрите Условные Границы с 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
объект, такой как группа, линейное неравенство, оборот и ошибка отслеживания может использоваться вместе с '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