Пример распределения активов

В этом примере показано, как настроить базовую задачу распределения активов, которая использует оптимизацию портфеля со средним отклонением с Portfolio объект для оценки эффективных портфелей.

Шаг 1. Определение задачи портфеля.

Предположим, что вы хотите управлять фондом распределения активов с четырьмя классами активов: облигации, акции с большой капитализацией, акции с малой капитализацией и новые акции. Фонд длинный только без заимствований или кредитного плеча, должен иметь не более 85% портфеля в акциях и не более 35% портфеля в формирующихся акциях. Стоимость торговли первыми тремя активами составляет 10 базисные точки в годовом исчислении, а стоимость торговли новыми акциями в четыре раза выше. Наконец, вы хотите убедиться, что средний оборот не более 15%. Чтобы решить эту задачу, вы настройте задачу оптимизации портфеля основных средних дисперсий, а затем медленно вводите различные ограничения на задачу, чтобы получить решение.

Чтобы настроить задачу оптимизации портфеля, начните с основных определений известных величин, связанных со структурой этой задачи. Каждый класс основных средств считается имеющим торгуемое основное средство с ценой в реальном времени. Такие активы могут быть, пример, биржевыми фондами (ETF). Первоначальный портфель с владениями в каждом активе, который в общей сложности составляет 7,5 млн. долл. США, а также дополнительная денежная позиция в размере 60 000 долл. США. Эти основные количества и затраты на торговлю настраиваются в следующих переменных с именами активов в массиве ячеек Asset, текущие цены в вектор Price, текущие портфельные активы в вектор Holding, и транзакционные издержки в вектор UnitCost.

Чтобы проанализировать это портфолио, можно настроить блоттер в table объект, чтобы помочь отслеживать цены, холдинги, веса и так далее. В частности, можно вычислить начальные веса портфеля и сохранить их в новом поле blotter под названием InitPort.

Asset = { 'Bonds', 'Large-Cap Equities', 'Small-Cap Equities', 'Emerging Equities' };
Price = [ 52.4; 122.7; 35.2; 46.9 ];
Holding = [ 42938; 24449; 42612; 15991 ];
UnitCost = [ 0.001; 0.001; 0.001; 0.004 ];

Blotter = table('RowNames', Asset);
Blotter.Price = Price;
Blotter.InitHolding = Holding;
Wealth = sum(Blotter.Price .* Blotter.InitHolding);
Blotter.InitPort = (1/Wealth)*(Blotter.Price .* Blotter.InitHolding);
Blotter.UnitCost = UnitCost;
Blotter
Blotter=4×4 table
                          Price    InitHolding    InitPort    UnitCost
                          _____    ___________    ________    ________

    Bonds                  52.4       42938         0.3        0.001  
    Large-Cap Equities    122.7       24449         0.4        0.001  
    Small-Cap Equities     35.2       42612         0.2        0.001  
    Emerging Equities      46.9       15991         0.1        0.004  

Шаг 2. Симуляция цен на активы.

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

Среднее значение и ковариация годовых общих возвратов активов поддерживаются в переменных AssetMean и AssetCovar. Моделируемые общие цены возврата основных средств (которые являются объединенными совокупными возвратами) ведутся в переменной Y. Все начальные цены возврата активов нормированы к 1 в этом примере.

AssetMean = [ 0.05; 0.1; 0.12; 0.18 ];
AssetCovar = [ 0.0064 0.00408 0.00192 0;
    0.00408 0.0289 0.0204 0.0119;
    0.00192 0.0204 0.0576 0.0336;
    0 0.0119 0.0336 0.1225 ];

X = portsim(AssetMean'/12, AssetCovar/12, 60); % Monthly total returns for 5 years (60 months)
[Y, T] = ret2tick(X, [], 1/12);                % form total return prices.
plot(T, log(Y));
title('\bfSimulated Asset Class Total Return Prices');
xlabel('Year');
ylabel('Log Total Return Price');
legend(Asset,'Location','best');

Figure contains an axes. The axes with title \bfSimulated Asset Class Total Return Prices contains 4 objects of type line. These objects represent Bonds, Large-Cap Equities, Small-Cap Equities, Emerging Equities.

Шаг 3. Настройка объекта Портфолио.

Чтобы исследовать портфели на эффективной границе, создайте Portfolio объект, использующий следующие спецификации:

  • Веса портфеля неотрицательны и равны 1.

  • Распределение капитала составляет не более 85% от портфеля.

  • Формирующийся капитал составляет не более 35% портфеля.

Эти спецификации включены в Portfolio p объекта в следующей последовательности использования функций, которая начинается с использования Portfolio объект.

  1. Спецификация начального портфеля от Blotter задает количество активов в вашей вселенной, поэтому вам не нужно указывать NumAssets свойство непосредственно. Затем настройте ограничения по умолчанию (только для long с ограничением бюджета). В сложение установите групповое ограничение, которое накладывает верхнюю границу на акции в портфеле (акции идентифицируются в матрице групп с 1s) и верхнее ограничение на появляющиеся акции. Хотя вы могли установить верхнюю границу для новых акций, используя setBounds function, заметьте, как addGroups функция используется для настройки этого ограничения.

  2. Чтобы иметь полностью заданную задачу оптимизации портфеля со средним отклонением, необходимо задать среднее и ковариационное значения возвратов активов. Начиная с этих моментов в переменных AssetMean и AssetCovar, можно использовать setAssetMoments функция, чтобы ввести эти переменные в вашу Portfolio объект (помните, что вы предполагаете, что ваши необработанные данные являются ежемесячными возвратами, из-за чего вы делите ваши ежегодные входные моменты на 12, чтобы получить ежемесячные возвраты).

  3. Используйте общие цены возврата с estimateAssetMoments функция со спецификацией, что ваши данные в Y цены, а не возвраты, для оценки моментов возврата активов для вашего Portfolio объект.

  4. Хотя возвращается в вашем Portfolio объект находится в модулях ежемесячных возвратов, и поскольку последующие затраты указаны в годовом исчислении, удобно указывать их как годовые общие возвраты с этим прямым преобразованием AssetMean и AssetCovar свойства вашего Portfolio p объекта.

  5. Отобразите Portfolio p объекта.

p = Portfolio('Name', 'Asset Allocation Portfolio', ...
'AssetList', Asset, 'InitPort', Blotter.InitPort);

p = setDefaultConstraints(p);
p = setGroups(p, [ 0, 1, 1, 1 ], [], 0.85);
p = addGroups(p, [ 0, 0, 0, 1 ], [], 0.35);

p = setAssetMoments(p, AssetMean/12, AssetCovar/12);
p = estimateAssetMoments(p, Y, 'DataFormat', 'Prices');

p.AssetMean = 12*p.AssetMean;
p.AssetCovar = 12*p.AssetCovar;

display(p)
p = 
  Portfolio with properties:

          BuyCost: []
         SellCost: []
     RiskFreeRate: []
        AssetMean: [4x1 double]
       AssetCovar: [4x4 double]
    TrackingError: []
     TrackingPort: []
         Turnover: []
      BuyTurnover: []
     SellTurnover: []
             Name: 'Asset Allocation Portfolio'
        NumAssets: 4
        AssetList: {1x4 cell}
         InitPort: [4x1 double]
      AInequality: []
      bInequality: []
        AEquality: []
        bEquality: []
       LowerBound: [4x1 double]
       UpperBound: []
      LowerBudget: 1
      UpperBudget: 1
      GroupMatrix: [2x4 double]
       LowerGroup: []
       UpperGroup: [2x1 double]
           GroupA: []
           GroupB: []
       LowerRatio: []
       UpperRatio: []
     MinNumAssets: []
     MaxNumAssets: []
        BoundType: [4x1 categorical]

Шаг 4. Проверьте проблему портфеля.

Важным шагом в оптимизации портфеля является подтверждение того, что задача портфеля является допустимой, и основным тестом является обеспечение того, чтобы набор портфелей был непустым и ограниченным. Используйте estimateBounds функция для определения границ для набора портфелей. В этом случае, так как оба lb и ub являются конечными, множество ограничено.

[lb, ub] = estimateBounds(p);
display([lb, ub])
    0.1500    1.0000
         0    0.8500
         0    0.8500
         0    0.3500

Шаг 5. Построение графика эффективной границы.

Учитывая построенные Portfolio объект, используйте plotFrontier функция для просмотра эффективной границы. Вместо использования по умолчанию 10 портфелей вдоль границы можно отобразить границу с 40 портфелями. Заметьте, что валовые эффективные возвраты портфеля составляют от примерно 6% до 16% в год.

plotFrontier(p, 40)

Figure contains an axes. The axes with title \bfAsset Allocation Portfolio contains 2 objects of type scatter, line. These objects represent Initial Portfolio, Efficient Frontier.

Шаг 6. Оценка валовых и чистых возвратов портфеля.

The Portfolio p объекта не включает транзакционные издержки, так что задача оптимизации портфеля, указанная в p использует валовые возвраты портфеля в качестве возврата прокси. Чтобы обработать чистые возвраты, создайте вторую Portfolio q объекта включая транзакционные издержки.

q = setCosts(p, UnitCost, UnitCost);
display(q)
q = 
  Portfolio with properties:

          BuyCost: [4x1 double]
         SellCost: [4x1 double]
     RiskFreeRate: []
        AssetMean: [4x1 double]
       AssetCovar: [4x4 double]
    TrackingError: []
     TrackingPort: []
         Turnover: []
      BuyTurnover: []
     SellTurnover: []
             Name: 'Asset Allocation Portfolio'
        NumAssets: 4
        AssetList: {1x4 cell}
         InitPort: [4x1 double]
      AInequality: []
      bInequality: []
        AEquality: []
        bEquality: []
       LowerBound: [4x1 double]
       UpperBound: []
      LowerBudget: 1
      UpperBudget: 1
      GroupMatrix: [2x4 double]
       LowerGroup: []
       UpperGroup: [2x1 double]
           GroupA: []
           GroupB: []
       LowerRatio: []
       UpperRatio: []
     MinNumAssets: []
     MaxNumAssets: []
        BoundType: [4x1 categorical]

Шаг 7. Анализ описательных свойств структур портфеля.

Для более конкретного определения областей значений эффективных возвратов портфеля и рисков используйте estimateFrontierLimits функция для получения портфелей в конечных точках эффективной границы. Учитывая эти портфели, вычислите их моменты с помощью estimatePortMoments функция. Следующий код генерирует таблицу, в которой перечислены риск и возврат начального портфеля, а также валовые и чистые моменты возвратов портфеля для портфелей в конечных точках эффективной границы:

[prsk0, pret0] = estimatePortMoments(p, p.InitPort);

pret = estimatePortReturn(p, p.estimateFrontierLimits);
qret = estimatePortReturn(q, q.estimateFrontierLimits);

displayReturns(pret0, pret, qret)
Annualized Portfolio Returns ...
                                    Gross       Net
Initial Portfolio Return             9.70 %    9.70 %
Minimum Efficient Portfolio Return   5.90 %    5.77 %
Maximum Efficient Portfolio Return  13.05 %   12.86 %

Результаты показывают, что стоимость торговли колеблется от 14 до 19 базисных пунктов, чтобы получить от текущего портфеля к эффективным портфелям на конечных точках эффективной границы (эти затраты являются различием между валовыми и чистыми возвратами портфеля). В сложение заметьте, что максимальный эффективный возврат портфеля (13%) меньше максимального возврата актива (18%) из-за ограничений на распределение капитала.

Шаг 8. Получение Портфеля на заданном уровне возврата на эффективной границе.

Общим подходом к выбору эффективных портфелей является выбор портфеля, который имеет желаемую долю области значений ожидаемых возвратов портфеля. Чтобы получить портфель, который составляет 30% от области значений от минимальной до максимального возврата на эффективной границе, получите область значений чистых возвратов в qret использование Portfolio q объекта и интерполяция, чтобы получить 30% -ный уровень с interp1 функция для получения портфеля qwgt.

Level = 0.3;

qret = estimatePortReturn(q, q.estimateFrontierLimits);
qwgt = estimateFrontierByReturn(q, interp1([0, 1], qret, Level));
[qrsk, qret] = estimatePortMoments(q, qwgt);

displayReturnLevel(Level, qret, qrsk);
Portfolio at 30% return level on efficient frontier ...
    Return       Risk
      7.90       9.09
display(qwgt)
qwgt = 4×1

    0.6252
    0.1856
    0.0695
    0.1198

Целевой портфель, который составляет 30% от области значений от минимальной до максимальных чистых возвратов, имеет возврат 7,9% и риск 9,1%.

Шаг 9. Получение Портфеля на заданных уровнях риска на эффективной границе.

Хотя можно принять этот результат, предположим, что необходимо определить значения для риска портфеля. В частности, предположим, что у вас есть консервативный целевой риск 10%, умеренный целевой риск 15% и агрессивный целевой риск 20%, и вы хотите получить портфели, которые удовлетворяют каждому целевому риску. Используйте estimateFrontierByRisk функция для получения целевых рисков, заданных в переменной TargetRisk. Получившиеся три эффективных портфеля получаются в qwgt.

TargetRisk = [ 0.10; 0.15; 0.20 ];
qwgt = estimateFrontierByRisk(q, TargetRisk);
display(qwgt)
qwgt = 4×3

    0.5407    0.2020    0.1500
    0.2332    0.4000    0.0318
    0.0788    0.1280    0.4682
    0.1474    0.2700    0.3500

Используйте estimatePortRisk функция для вычисления портфельных рисков по трем портфелям для подтверждения достижения целевых рисков:

display(estimatePortRisk(q, qwgt))
    0.1000
    0.1500
    0.2000

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

[qwgt, qbuy, qsell] = estimateFrontierByRisk(q, 0.15);

Если вы усредните покупки и продажи по этому портфелю, то увидите, что средний оборот составляет 17%, что больше целевого показателя в 15%:

disp(sum(qbuy + qsell)/2) 
    0.1700

Поскольку вы также хотите убедиться, что средний оборот не более 15%, можно добавить среднее ограничение оборота к Portfolio объект, использующий setTurnover:

q = setTurnover(q, 0.15);
[qwgt, qbuy, qsell] = estimateFrontierByRisk(q, 0.15);

Вы можете ввести предполагаемый эффективный портфель с покупками и продажами в Blotter:

qbuy(abs(qbuy) < 1.0e-5) = 0;
qsell(abs(qsell) < 1.0e-5) = 0;  % Zero out near 0 trade weights.

Blotter.Port = qwgt;
Blotter.Buy = qbuy;
Blotter.Sell = qsell;

display(Blotter)
Blotter=4×7 table
                          Price    InitHolding    InitPort    UnitCost     Port      Buy       Sell  
                          _____    ___________    ________    ________    _______    ____    ________

    Bonds                  52.4       42938         0.3        0.001      0.18787       0     0.11213
    Large-Cap Equities    122.7       24449         0.4        0.001          0.4       0           0
    Small-Cap Equities     35.2       42612         0.2        0.001      0.16213       0    0.037871
    Emerging Equities      46.9       15991         0.1        0.004         0.25    0.15           0

The Buy и Sell элементы Blotter - изменения в весах портфеля, которые должны быть преобразованы в изменения в портфельных холдингах для определения сделок. Поскольку вы работаете с чистыми возвратами портфеля, сначала необходимо вычислить стоимость торговли от вашего начального портфеля до нового портфеля. Это достигается следующим образом:

TotalCost = Wealth * sum(Blotter.UnitCost .* (Blotter.Buy + Blotter.Sell))
TotalCost = 5.6248e+03

Стоимость торговли составляет $5,625, так что, в целом, вам придется скорректировать свое начальное богатство соответственно, прежде чем настраивать новые веса портфеля. Однако, чтобы сохранить анализ простым, обратите внимание, что у вас есть достаточные денежные средства ($60 0000), выделенные для оплаты торговых расходов и что вы не будете касаться денежной позиции, чтобы создать какие-либо позиции в вашем портфеле. Таким образом, вы можете заполнить свой блоттер новыми портфельными холдингами и сделками, чтобы добраться до нового портфеля, не производя никаких изменений в вашем общем инвестированном богатстве. Во-первых, вычислите портфельный холдинг:

Blotter.Holding = Wealth * (Blotter.Port ./ Blotter.Price);

Вычисление количества общих ресурсов в Buy и Sell в вашем Blotter:

Blotter.BuyShare = Wealth * (Blotter.Buy ./ Blotter.Price);
Blotter.SellShare = Wealth * (Blotter.Sell ./ Blotter.Price);

Заметьте, как вы использовали специальное правило усечения для получения модуля количества акций для покупки и продажи. Очистите Blotter путем удаления удельных затрат и веса портфеля покупок и продаж:

Blotter.Buy = [];
Blotter.Sell = [];
Blotter.UnitCost = [];

Этап 10. Отображение конечных результатов.

Конечным результатом является блоттер, который содержит предложенные сделки для перехода от вашего текущего портфеля к портфелю с умеренным риском. Чтобы совершить сделку, вам нужно будет продать 16 049 акций вашего облигационного актива и 8 069 акций вашего акционерного актива с малой капитализацией, и вам нужно будет приобрести 23 986 акций вашего нового акционерного актива.

display(Blotter)
Blotter=4×7 table
                          Price    InitHolding    InitPort     Port      Holding    BuyShare    SellShare
                          _____    ___________    ________    _______    _______    ________    _________

    Bonds                  52.4       42938         0.3       0.18787     26889          0        16049  
    Large-Cap Equities    122.7       24449         0.4           0.4     24449          0            0  
    Small-Cap Equities     35.2       42612         0.2       0.16213     34543          0       8068.8  
    Emerging Equities      46.9       15991         0.1          0.25     39977      23986            0  

Конечный график использует plotFrontier функция для отображения эффективной границы и начального портфеля для полностью заданной задачи оптимизации портфеля. Он также добавляет расположение портфеля умеренного риска или конечного портфеля на эффективной границе.

plotFrontier(q, 40);
hold on
scatter(estimatePortRisk(q, qwgt), estimatePortReturn(q, qwgt), 'filled', 'r');
h = legend('Initial Portfolio', 'Efficient Frontier', 'Final Portfolio', 'location', 'best');
set(h, 'Fontsize', 8);
hold off

Figure contains an axes. The axes with title \bfAsset Allocation Portfolio contains 3 objects of type scatter, line. These objects represent Initial Portfolio, Efficient Frontier, Final Portfolio.

Локальные функции

function displayReturns(pret0, pret, qret)
fprintf('Annualized Portfolio Returns ...\n');
fprintf('                                   %6s    %6s\n','Gross','Net');
fprintf('Initial Portfolio Return           %6.2f %%  %6.2f %%\n',100*pret0,100*pret0);
fprintf('Minimum Efficient Portfolio Return %6.2f %%  %6.2f %%\n',100*pret(1),100*qret(1));
fprintf('Maximum Efficient Portfolio Return %6.2f %%  %6.2f %%\n',100*pret(2),100*qret(2));
end

function displayReturnLevel(Level, qret, qrsk)
fprintf('Portfolio at %g%% return level on efficient frontier ...\n',100*Level);
fprintf('%10s %10s\n','Return','Risk');
fprintf('%10.2f %10.2f\n',100*qret,100*qrsk);
end

См. также

| | | | | | | | |

Похожие примеры

Подробнее о

Внешние веб-сайты