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

В этом примере показано, как использовать 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. Задайте этот тип ограничения как 'Conditional' BoundType в 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  andsum(xi)=1. Они сконфигурированы с setDefaultConstraints.

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

Предположим, что вы хотите избежать очень маленьких положений, чтобы минимизировать маслобойку и операционные затраты. Добавьте другое ограничение, чтобы ограничить выделенные положения, чтобы быть не менее чем 5% путем установки ограничений xi=0orxi0.05 использование 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' средние значения lbxiubи 'Conditional' средние значения xi=0orlbxiub.

Позвольте активы в 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