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

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

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

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

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

Чтобы анализировать этот портфель, можно настроить промокательную бумагу в table возразите, чтобы помочь отследить цены, активы, веса, и т.д. В частности, можно вычислить начальные веса портфеля и обеспечить их в новом поле промокательной бумаги под названием 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
Warning: This syntax will be removed in a future release. See the documentation for recommended usage.
plot(T, log(Y));
title('\bfSimulated Asset Class Total Return Prices');
xlabel('Year');
ylabel('Log Total Return Price');
legend(Asset,'Location','best');

Шаг 3. Подготовка объекта Portfolio.

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

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

  • Выделение акции - не больше, чем 85% портфеля.

  • Появляющаяся акция - не больше, чем 35% портфеля.

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

  1. Спецификация начального портфеля от Blotter дает количество активов в вашей вселенной, таким образом, вы не должны задавать NumAssets свойство непосредственно. Затем настройте ограничения по умолчанию (длинно-единственный с ограничением бюджета). Кроме того, настройте ограничение группы, которое налагает верхнюю границу на акции в портфеле (акции идентифицированы в матрице группы с 1) и ограничение верхней границы на появляющиеся акции. Несмотря на то, что вы, возможно, установили верхнюю границу на появляющихся акциях с помощью setBounds функция, заметьте как 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);

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

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);

Можно ввести предполагаемый эффективный портфель с покупками и продажами в Промокательную бумагу:

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

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

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.BuyShare = Wealth * (Blotter.Buy ./ Blotter.Price);
Blotter.SellShare = Wealth * (Blotter.Sell ./ Blotter.Price);

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

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

Служебные функции

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
Для просмотра документации необходимо авторизоваться на сайте