В этом примере показано, как выполнить оптимизацию портфеля с помощью Portfolio
объект в Financial Toolbox™.
Этот пример, в частности, демонстрирует оптимизацию портфеля для максимизации информационного коэффициента относительно рыночного бенчмарка. В частности, финансовые данные, содержащиеся в table
считывается в MATLAB ® и выполняется визуализация (как на дневном, так и на годовом уровнях). A Portfolio
создается с использованием рыночных данных с помощью активного ежедневного возврата для каждого основного средства. Использование функций, поддерживающих Portfolio
объект, эффективная граница вычисляется непосредственно. Затем настраиваемая задача оптимизации решается, чтобы найти распределение активов с максимальным информационным коэффициентом.
Импортируйте исторические цены для вселенной активов и рыночного бенчмарка Dow Jones Среднее Значение (DJI). Данные импортируются в table
из электронной таблицы Microsoft ® Excel ® с использованием readtable
MATLAB ®
функция.
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 из таблицы. Визуализация показывает эволюцию всех цен активов, нормализованных, чтобы начать с единицы, то есть накопительных возвратов.
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(data.Dates,assetP); hold on; plot(data.Dates,benchmarkP,'LineWidth',3,'Color','k'); hold off; xlabel('Date'); ylabel('Normalized Price'); title('Normalized Asset Prices and Benchmark'); 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 the weights. [portRiskAct, portRetnAct] = estimatePortMoments(pAct, pwgtAct); % Get the risk and return. % Extract the asset moments and 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;
Запустите гибридную оптимизацию, чтобы найти портфель вдоль границы с максимальным информационным коэффициентом. Отношение информации является отношением относительной отдачи к относительному риску (известному как «отслеживающая ошибка»). В то время как коэффициент Шарпа смотрит на возвраты относительно рискованного актива, коэффициент информации основан на возвратах относительно рискованного бенчмарка, в этом случае бенчмарка DJI. Это делается путем выполнения оптимизации, которая находит оптимальное ограничение возврата, для которого задача оптимизации портфеля возвращает портфель максимального информационного коэффициента. Портфельные оптимизационные функции вызываются из целевой функции infoRatioTargetReturn
который оптимизируется функцией Optimization Toolbox™ fminbnd
. Локальная функция infoRatioTargetReturn
вычисляет минимальный (активный) портфель рисков, учитывая целевой активный возврат.
The infoRatioTargetReturn
локальная функция вызывается как целевая функция в стандартной программе оптимизации (fminbnd
), который стремится найти целевой возврат, который максимизирует отношение информации и минимизирует отрицательное отношение информации.
objFun = @(targetReturn) -infoRatioTargetReturn(targetReturn,pAct);
options = optimset('TolX',1.0e-8);
[optPortRetn, ~, exitflag] = fminbnd(objFun,min(portRetnAct),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.35551 {'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('Active return for Max. Info Ratio portfolio is %0.2f%%\n', optPortRetn*25200);
Active return for Max. Info Ratio portfolio is 12.14%
fprintf('Tracking error for Max. Info Ratio portfolio is %0.2f%%\n', optPortRisk*sqrt(252)*100);
Tracking error for Max. Info Ratio portfolio is 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
fminbnd
| inforatio
| Portfolio