Оптимизация портфеля против сравнительного теста

В этом примере показано, как выполнить оптимизацию портфеля с помощью Portfolio объект в Financial Toolbox™.

Этот пример, в частности, демонстрирует оптимизацию портфеля, чтобы максимизировать информационное отношение относительно сравнительного теста рынка. А именно, финансовые данные содержатся в table читается в MATLAB®, и визуализация (и на ежедневных и на ежегодных уровнях) выполняется. Объект Portfolio создается с данными о рынке с помощью активного ежедневного возврата в каждом активе. Используя функции, поддерживающие объект Portfolio, граница эффективности вычисляется непосредственно. Затем индивидуально настраиваемая задача оптимизации решена, чтобы найти распределение активов с максимизируемым информационным отношением.

Импортируйте исторические данные Используя MATLAB®

Импортируйте исторические цены на вселенную актива и промышленный индекс Доу-Джонса (DJI) сравнительный тест рынка. Данные импортированы в table из электронной таблицы Microsoft® Excel® с помощью MATLAB® readtable функция.

data = readtable('dowPortfolio.xlsx');
head(data, 10)
ans=10×32 table
       Dates        DJI      AA       AIG      AXP      BA        C       CAT      DD       DIS      GE       GM       HD       HON      HPQ      IBM     INTC      JNJ      JPM      KO       MCD      MMM      MO       MRK     MSFT      PFE      PG        T       UTX      VZ       WMT      XOM 
    ___________    _____    _____    _____    _____    _____    _____    _____    _____    _____    _____    _____    _____    _____    _____    _____    _____    _____    _____    _____    _____    _____    _____    _____    _____    _____    _____    _____    _____    _____    _____    _____

    03-Jan-2006    10847    28.72    68.41    51.53    68.63    45.26    55.86    40.68    24.18     33.6    17.82    39.79    36.14    28.35    80.13    24.57    59.08    37.78    38.98    32.72    75.93    52.27    30.73    26.19    22.16    56.38     22.7    54.94    26.79     44.9    56.64
    04-Jan-2006    10880    28.89    68.51    51.03    69.34    44.42    57.29    40.46    23.77    33.56     18.3    39.05    35.99    29.18    80.03     24.9    59.99    37.56    38.91    33.01    75.54    52.65    31.08    26.32    22.88    56.48    22.87    54.61    27.58    44.99    56.74
    05-Jan-2006    10882    29.12     68.6    51.57    68.53    44.65    57.29    40.38    24.19    33.47    19.34    38.67    35.97    28.97    80.56    25.25    59.74    37.67     39.1    33.05    74.85    52.52    31.13    26.34     22.9     56.3    22.92    54.41     27.9    44.38    56.45
    06-Jan-2006    10959    29.02    68.89    51.75    67.57    44.65    58.43    40.55    24.52     33.7    19.61    38.96    36.53     29.8    82.96    25.28    60.01    37.94    39.47    33.25    75.47    52.95    31.08    26.26    23.16    56.24    23.21    54.58    28.01    44.56    57.57
    09-Jan-2006    11012    29.37    68.57    53.04    67.01    44.43    59.49    40.32    24.78    33.61    21.12    39.38    36.23    30.17    81.76    25.44    60.38    38.55    39.66    33.88    75.84    53.11    31.58    26.21    23.16    56.67     23.3     55.2    28.12     44.4    57.54
    10-Jan-2006    11012    28.44    69.18    52.88    67.33    44.57    59.25     40.2    25.09    33.43    20.79    40.33    36.17    30.33     82.1     25.1    60.49    38.61     39.7    33.91    75.37    53.04    31.27    26.35    22.77    56.45    23.16    55.24    28.24    44.54    57.99
    11-Jan-2006    11043    28.05     69.6    52.59     68.3    44.98    59.28    38.87    25.33    33.66    20.61    41.44    36.19    30.88    82.19    25.12    59.91    38.58    39.72     34.5    75.22    53.31    31.39    26.63    23.06    56.65    23.34    54.41    28.58    45.23    58.38
    12-Jan-2006    10962    27.68    69.04     52.6     67.9    45.02    60.13    38.02    25.41    33.25    19.76    41.05    35.77    30.57    81.61    24.96    59.63    37.87     39.5    33.96    74.57    53.23    31.41    26.48     22.9    56.02    23.24     53.9    28.69    44.43    57.77
    13-Jan-2006    10960    27.81    68.84     52.5     67.7    44.92    60.24    37.86    25.47    33.35     19.2    40.43    35.85    31.43    81.22    24.78    59.26    37.84    39.37    33.65    74.38    53.29     31.4    26.53    22.99    56.49    23.27     54.1    28.75     44.1    59.06
    17-Jan-2006    10896    27.97    67.84    52.03    66.93    44.47    60.85    37.75    25.15     33.2    18.68    40.11    35.56     31.2    81.05    24.52    58.74    37.64    39.11    33.77    73.99    52.85    31.16    26.34    22.63    56.25    23.13    54.41    28.12    43.66    59.61

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

dates = datenum(data.Dates);
benchPrice = data.DJI;
assetNames = data.Properties.VariableNames(3:2:end); % using half of the assets for display
assetPrice = data(:,assetNames).Variables;

assetP = assetPrice./assetPrice(1, :);  
benchmarkP = benchPrice / benchPrice(1);

figure;
plot(dates,assetP);
hold on;
plot(dates,benchmarkP,'LineWidth',3,'Color','k');
hold off;
xlabel('Date');
ylabel('Normalized Price');
title('Normalized Asset Prices and Benchmark');
datetick('x');
grid on;

Полужирная линия указывает на сравнительный тест рынка DJIA.

Вычислите возвращается и доходность с учетом риска

Вычислите ряд возврата от ценового ряда и вычислите моменты актива (исторические возвраты и стандартные отклонения). Визуализация показывает график рассеивания характеристик возврата риск всех активов и сравнительного теста рынка DJI.

benchReturn = tick2ret(benchPrice);
assetReturn = tick2ret(assetPrice);

benchRetn = mean(benchReturn);
benchRisk =  std(benchReturn);
assetRetn = mean(assetReturn);
assetRisk =  std(assetReturn);

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

scale = 252;

assetRiskR = sqrt(scale) * assetRisk;
benchRiskR = sqrt(scale) * benchRisk;
assetReturnR = scale * assetRetn;
benchReturnR = scale * benchRetn;

figure;
scatter(assetRiskR, assetReturnR, 6, 'm', 'Filled');
hold on
scatter(benchRiskR, benchReturnR, 6, 'g', 'Filled');
for k = 1:length(assetNames)
    text(assetRiskR(k) + 0.005, assetReturnR(k), assetNames{k}, 'FontSize', 8);
end
text(benchRiskR + 0.005, benchReturnR, 'Benchmark', 'Fontsize', 8);
hold off;

xlabel('Risk (Std Dev of Return)');
ylabel('Expected Annual Return');
grid on;

Настройте оптимизацию портфеля

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

p = Portfolio('AssetList',assetNames);

Настройте ограничения портфеля по умолчанию (вся сумма весов к 1, нет закорачивая, и 100%-е инвестиции в опасные активы).

p = setDefaultConstraints(p);

Добавьте, что актив возвращается и ковариация к Portfolio объект.

activReturn = assetReturn - benchReturn;
pAct = estimateAssetMoments(p,activReturn,'missingdata',false)
pAct = 
  Portfolio with properties:

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

Вычислите границу эффективности Используя Portfolio Объект

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

pwgtAct = estimateFrontier(pAct, 20); % Estimate weights
[portRiskAct, portRetnAct] = estimatePortMoments(pAct, pwgtAct); % Get risk and return

% Extract asset moments & names
[assetActRetnDaily, assetActCovarDaily] = getAssetMoments(pAct);
assetActRiskDaily = sqrt(diag(assetActCovarDaily));
assetNames = pAct.AssetList;

% Rescale
assetActRiskAnnual = sqrt(scale) * assetActRiskDaily;
portRiskAnnual  = sqrt(scale) *  portRiskAct;
assetActRetnAnnual = scale * assetActRetnDaily;
portRetnAnnual = scale *  portRetnAct;

figure;
subplot(2,1,1);
plot(portRiskAnnual, portRetnAnnual, 'bo-', 'MarkerFaceColor', 'b');
hold on;

scatter(assetActRiskAnnual, assetActRetnAnnual, 12, 'm', 'Filled');
hold on;
for k = 1:length(assetNames)
    text(assetActRiskAnnual(k) + 0.005, assetActRetnAnnual(k), assetNames{k}, 'FontSize', 8);
end

hold off;

xlabel('Risk (Std Dev of Active Return)');
ylabel('Expected Active Return');
grid on;

subplot(2,1,2);
plot(portRiskAnnual, portRetnAnnual./portRiskAnnual, 'bo-', 'MarkerFaceColor', 'b');
xlabel('Risk (Std Dev of Active Return)');
ylabel('Information Ratio');
grid on;

Выполните информационную максимизацию отношения Используя Optimization Toolbox™

Запустите гибридную оптимизацию, чтобы найти портфель вдоль границы с максимальным информационным отношением. Информационное отношение является отношением относительного возврата к относительному риску (известный как "отслеживание ошибки"). Принимая во внимание, что взгляды отношения Шарпа на возвраты относительно безрискового актива, информационное отношение на основе возвратов относительно опасного сравнительного теста, в этом случае сравнительный тест DJI. Это сделано путем выполнения оптимизации, которая находит оптимальное ограничение возврата, для которого задача оптимизации портфеля возвращает максимальный информационный портфель отношения. Функции оптимизации портфеля вызваны от целевой функции infoRatioTargetReturn это оптимизировано функцией Optimization Toolbox™ fminbnd. Локальная функция infoRatioTargetReturn вычисляет минимальный (активный) портфель риска, учитывая целевой активный возврат.

infoRatioTargetReturn локальная функция вызвана как целевая функция в стандартной программе оптимизации (fminbnd) это стремится найти целевой возврат, который максимизирует информационное отношение и минимизирует отрицательное информационное отношение.

objFun = @(targetReturn) -infoRatioTargetReturn(targetReturn,pAct);
options = optimset('TolX',1.0e-8);
[optPortRetn, ~, exitflag] = fminbnd(objFun,0,max(portRetnAct),options);

Получите веса, информационное отношение, и риск возвращается для оптимального портфеля.

[optInfoRatio,optWts] = infoRatioTargetReturn(optPortRetn,pAct);
optPortRisk = estimatePortRisk(pAct,optWts) 
optPortRisk = 0.0040

Постройте оптимальный портфель

Проверьте, что найденный портфель является действительно максимальным портфелем информационного отношения.

% Rescale
optPortRiskAnnual = sqrt(scale) * optPortRisk;
optPortReturnAnnual = scale * optPortRetn;

figure;
subplot(2,1,1);

scatter(assetActRiskAnnual, assetActRetnAnnual, 6, 'm', 'Filled');
hold on
for k = 1:length(assetNames)
    text(assetActRiskAnnual(k) + 0.005,assetActRetnAnnual(k),assetNames{k},'FontSize',8);
end
plot(portRiskAnnual,portRetnAnnual,'bo-','MarkerSize',4,'MarkerFaceColor','b');
plot(optPortRiskAnnual,optPortReturnAnnual,'ro-','MarkerFaceColor','r');
hold off;

xlabel('Risk (Std Dev of Active Return)');
ylabel('Expected Active Return');
grid on;

subplot(2,1,2);
plot(portRiskAnnual,portRetnAnnual./portRiskAnnual,'bo-','MarkerSize',4,'MarkerFaceColor','b');
hold on
plot(optPortRiskAnnual,optPortReturnAnnual./optPortRiskAnnual,'ro-','MarkerFaceColor','r');
hold off;

xlabel('Risk (Std Dev of Active Return)');
ylabel('Information Ratio');
title('Information Ratio with Optimal Portfolio');
grid on;

Отобразите решение для оптимизации портфеля

Отобразите решение для оптимизации портфеля.

assetIndx = optWts > .001;
results = table(assetNames(assetIndx)', optWts(assetIndx)*100, 'VariableNames',{'Asset', 'Weight'});
disp('Maximum Information Ratio Portfolio:');
Maximum Information Ratio Portfolio:
disp(results);
     Asset      Weight
    ________    ______

    {'AA'  }     1.539
    {'AXP' }    0.3555
    {'C'   }    9.6533
    {'DD'  }    4.0684
    {'HPQ' }    17.698
    {'JPM' }    21.565
    {'MCD' }    26.736
    {'MO'  }    13.648
    {'MSFT'}    2.6858
    {'UTX' }    2.0509
fprintf('Max. Info Ratio portfolio has expected active return %0.2f%%\n', optPortRetn*25200);
Max. Info Ratio portfolio has expected active return 12.14%
fprintf('Max. Info Ratio portfolio has expected tracking error of %0.2f%%\n', optPortRisk*sqrt(252)*100);
Max. Info Ratio portfolio has expected tracking error of 6.32%

Локальная функция

function [infoRatio,wts] = infoRatioTargetReturn(targetReturn,portObj)
% Calculate information ratio for a target-return portfolio along the
% efficient frontier
wts = estimateFrontierByReturn(portObj,targetReturn);
portRiskAct = estimatePortRisk(portObj,wts);
infoRatio = targetReturn/portRiskAct;
end