В этом примере показано, как создать оптимальный портфель 10,20 и 30-летние казначейства, которые будут сохранены сроком на один месяц. Акцент сделан полному процессу распределения активов.
Шаг 1: Загрузите Данные о Рынке - загружается Историческая ежедневная доходность казначейских облигаций США, загруженная с FRED.
Шаг 2: Вычислите Инварианты Рынка - Ежедневно изменяется в доходе до срока погашения, выбраны в качестве инвариантов и приняты, чтобы быть многомерен нормальный. Из-за недостающих данных для 30-летних связей, алгоритм максимизации ожидания используется, чтобы оценить среднее значение и ковариацию инвариантов. Статистические данные инварианта спроектированы к инвестиционному горизонту.
Шаг 3: Симулируйте Инварианты на Горизонте - из-за высокой корреляции и свойственной структуры в кривых доходности, анализ главных компонентов применяется к инвариантной статистике. Многомерные нормальные случайные ничьи сделаны на пробеле PCA. Симуляции преобразовываются назад в инвариантный пробел с помощью загрузок PCA.
Шаг 4: Вычислите Распределение Возвратов на Горизонте - симулированные ежемесячные изменения в кривой доходности используются, чтобы вычислить выражение для ценных бумаг портфеля на горизонте. Это требует значений интерполяции прочь симулированных кривых доходности, поскольку ценные бумаги портфеля будут иметь сроки платежа, которые являются одним месяцем меньше чем 10, 20 и 30 лет. Прибыль/Потеря для каждого сценария/безопасности вычисляется путем оценки казначейств с помощью симулированных и интерполированных выражений. Симулированные линейные возвраты и их статистика вычисляются от цен.
Шаг 5: Оптимизируйте Распределение активов - Квадратичное среднее / оптимизация отклонения выполняется на казначействе, возвращает статистику, чтобы вычислить веса оптимального портфеля для 10 точек вдоль Границы эффективности. Настройка инвестора должна выбрать портфель, который является самым близким к среднему значению возможных отношений Шарпа.
Исторические Данные о Доходе до срока погашения для Ряда: DGS6MO, DGS1, DGS2, DGS3, DGS5, DGS7, DGS10, DGS20, DGS30 Для Дат: 1 сентября 2000 - 1 сентября 2010 Полученный из: http://research.stlouisfed.org/fred2/categories/115 Примечание: Данные загружается с помощью Datafeed Toolbox™ с помощью команд как:>> conn
= fred;
>> data
= fetch(conn,'DGS10','9/1/2000','9/1/2010');
Результаты были агрегированы и сохранены в бинарном файле MAT для удобства
disp('Step 1: Load and Visualize Market Data...');
Step 1: Load and Visualize Market Data...
histData = load('HistoricalYTMData.mat'); % Time to maturity for each series tsYTMMats = histData.tsYTMMats; % Dates rates were observed tsYTMObsDates = histData.tsYTMObsDates; % Observed Rates tsYTMRates = histData.tsYTMRates; % Visualize Yield Curves miny = min(tsYTMRates(:)); maxy = max(tsYTMRates(:)); figure; h = plot(tsYTMMats,tsYTMRates,'k-o'); axis([0,32,miny,maxy]); xlabel('Time to Maturity'); ylabel('Yield'); legend('Historic Yield Curve','location','se'); grid on; for i = 1:50:length(tsYTMObsDates) set(h,'ydata',tsYTMRates(i,:)); title(datestr(tsYTMObsDates(i))); pause(0.1); end
Для инвариантов рынка используйте стандарт: ежедневные изменения в доходе до срока погашения для каждого ряда. Можно оценить, что их статистическое распределение многомерно нормальный. Анализ IID каждого инвариантного ряда приводит к достойным результатам - больше в "независимом" факторе, чем "идентичный". Более полное моделирование с помощью более комплексных распределений и/или моделей временных рядов выходит за рамки этого проекта. То, что должно будет составляться, является оценкой параметров распределения в присутствие недостающих данных. 30-летние связи были прекращены в течение периода между февралем 2002 и февралем 2006, таким образом, нет никаких выражений для этого периода времени.
disp('Step 2: Calculate Market Invariants...');
Step 2: Calculate Market Invariants...
% Invariants are assumed to be daily changes in YTM rates tsYTMRateDeltas = diff(tsYTMRates); % About 1/3 of the 30 year rates (column 9) are missing from the original % data set. Rather than throw out all these observations, an expectation % Maximization routine is used to estimate the mean and covariance of the % invariants. Default options (NaN skip for initial estimates, etc.) are used. [tsInvMu,tsInvCov] = ecmnmle(tsYTMRateDeltas); % Calculate standard deviations and correlations [tsInvStd,tsInvCorr] = cov2corr(tsInvCov); % The investment horizon is 1 month. (21 business days between 9/1/2010 % and 10/1/2010). Since the invariants are summable and the means and % variances of normal distributions are normal, we can project the % invariants to the investment horizon as follows hrznInvMu = 21*tsInvMu'; hrznInvCov = 21*tsInvCov; [hrznInvStd,hrznInvCor] = cov2corr(hrznInvCov); % Display results disp('The market invariants projected to the horizon have the following stats');
The market invariants projected to the horizon have the following stats
disp('Mean:');
Mean:
disp(hrznInvMu);
1.0e-03 * -0.5149 -0.4981 -0.4696 -0.4418 -0.3788 -0.3268 -0.2604 -0.2184 -0.1603
disp('Standard Deviation:');
Standard Deviation:
disp(hrznInvStd);
0.0023 0.0024 0.0030 0.0032 0.0033 0.0032 0.0030 0.0027 0.0026
disp('Correlation:');
Correlation:
disp(hrznInvCor);
1.0000 0.8553 0.5952 0.5629 0.4980 0.4467 0.4028 0.3338 0.3088 0.8553 1.0000 0.8282 0.7901 0.7246 0.6685 0.6175 0.5349 0.4973 0.5952 0.8282 1.0000 0.9653 0.9114 0.8589 0.8055 0.7102 0.6642 0.5629 0.7901 0.9653 1.0000 0.9519 0.9106 0.8664 0.7789 0.7361 0.4980 0.7246 0.9114 0.9519 1.0000 0.9725 0.9438 0.8728 0.8322 0.4467 0.6685 0.8589 0.9106 0.9725 1.0000 0.9730 0.9218 0.8863 0.4028 0.6175 0.8055 0.8664 0.9438 0.9730 1.0000 0.9562 0.9267 0.3338 0.5349 0.7102 0.7789 0.8728 0.9218 0.9562 1.0000 0.9758 0.3088 0.4973 0.6642 0.7361 0.8322 0.8863 0.9267 0.9758 1.0000
Высокая корреляция не идеальна для симуляции распределения инвариантов на горизонте (и в конечном счете цены безопасности). Разложение основного компонента используется, чтобы извлечь ортогональные инварианты. Это могло также использоваться для сокращения размерности, однако поскольку количество инвариантов все еще относительно мало, сохраните все 9 компонентов для более точной реконструкции. Однако отсутствующие значения в данных о рынке препятствуют тому, чтобы вы оценили непосредственно прочь данных временных рядов. Вместо этого это может быть сделано непосредственно прочь ковариационной матрицы
disp('Step 3: Simulate Market Invariants at Horizon...');
Step 3: Simulate Market Invariants at Horizon...
% Perform PCA decomposition using invariants' covariance [pcaFactorCoeff,pcaFactorVar,pcaFactorExp] = pcacov(hrznInvCov); % Keeping all components of pca decompositon numFactors = 9; % Create PCA factor covariance matrix pcaFactorCov = corr2cov(sqrt(pcaFactorVar),eye(numFactors)); % The number of simulations (random draws) numSim = 10000; % Fix random seed for reproducible results stream = RandStream('mrg32k3a'); RandStream.setGlobalStream(stream); % Take random draws from multi-variate normal distribution with zero mean % and diagonal covariance pcaFactorSims = mvnrnd(zeros(numFactors,1),pcaFactorCov,numSim); % Transform to horizon invariants and calculate statistics hrznInvSims = pcaFactorSims*pcaFactorCoeff' + repmat(hrznInvMu,numSim,1); hrznInvSimsMu = mean(hrznInvSims); hrznInvSimsCov = cov(hrznInvSims); [hrznInvSimsStd,hrznInvSimsCor] = cov2corr(hrznInvSimsCov); % Display results disp('The simulated invariants have very similar statistics to the original invariants');
The simulated invariants have very similar statistics to the original invariants
disp('Mean:');
Mean:
disp(hrznInvSimsMu);
1.0e-03 * -0.4983 -0.5002 -0.4832 -0.4542 -0.4031 -0.3597 -0.2867 -0.2515 -0.1875
disp('Standard Deviation:');
Standard Deviation:
disp(hrznInvSimsStd);
0.0023 0.0023 0.0030 0.0031 0.0032 0.0031 0.0029 0.0027 0.0026
disp('Correlation:');
Correlation:
disp(hrznInvSimsCor);
1.0000 0.8527 0.5827 0.5502 0.4846 0.4327 0.3896 0.3197 0.2961 0.8527 1.0000 0.8227 0.7840 0.7181 0.6603 0.6097 0.5246 0.4896 0.5827 0.8227 1.0000 0.9646 0.9100 0.8569 0.8048 0.7074 0.6633 0.5502 0.7840 0.9646 1.0000 0.9507 0.9085 0.8656 0.7757 0.7344 0.4846 0.7181 0.9100 0.9507 1.0000 0.9721 0.9428 0.8710 0.8319 0.4327 0.6603 0.8569 0.9085 0.9721 1.0000 0.9726 0.9211 0.8870 0.3896 0.6097 0.8048 0.8656 0.9428 0.9726 1.0000 0.9552 0.9264 0.3197 0.5246 0.7074 0.7757 0.8710 0.9211 0.9552 1.0000 0.9753 0.2961 0.4896 0.6633 0.7344 0.8319 0.8870 0.9264 0.9753 1.0000
Портфель будет состоять из 10, 20, и 30-летние казначейства зрелости. Для простоты примите, что они - новые проблемы о расчетном дне и оценены по рыночной стоимости, выведенной из кривой текущей доходности. Прибыль и распределения Потерь вычисляются путем оценки каждой безопасности вдоль каждого симулированного выражения на горизонте и вычитания покупной цены. Цены горизонта требуют нестандартного времени к выражениям зрелости. Они вычисляются с помощью интерполяции кубическим сплайном. Симулированные линейные возвраты являются своими статистическими данными, которые вычисляются из сценариев Прибыли и Потери.
disp('Step 4: Calculate Distribution of Security Returns at Horizon...');
Step 4: Calculate Distribution of Security Returns at Horizon...
% Purchase and investment horizon dates settleDate = '9/1/2010'; hrznDate = '10/1/2010'; % The maturity dates for new issue treasuries purchased on the settle date treasuryMaturities = {'9/1/2020','9/1/2030','9/1/2040'}; % The observed yields for the securities of interes on the settle date treasuryYTMAtSettle = tsYTMRates(end,7:9); % Initialize arrays for later use treasuryYTMAtHorizonSim = zeros(numSim,3); treasuryPricesAtSettle = zeros(1,3); treasuryPricesAtHorizonSim = zeros(numSim,3); % Use actual/actual day count basis with annualized yields basis = 8; % Price treasuries at settle date using known yield to maturity % Note: For simplicity, we are assuming that none of these securities % include coupon payments. The hope is that although the prices may not be % accurate the overall structure/relationships between value will be % preserved for the asset allocation process. for j=1:3 treasuryPricesAtSettle(j) = bndprice(treasuryYTMAtSettle(j),0,settleDate,... treasuryMaturities(j),'basis',basis); end % To price the treasuries at the horizon, we need to know yield to maturity % at 9 years 11 months, 19 years 11 months and 29 years 11 months for each % simulation. We approximate these using cubic spline interpolation % Transform simulated invariants to YTM at horizon hrznYTMRatesSims = repmat(tsYTMRates(end,:),numSim,1) + hrznInvSims; hrznYTMMaturities = {'4/1/2011','10/1/2011','10/1/2012','10/1/2013',... '10/1/2015','10/1/2017','10/1/2020','10/1/2030',... '10/1/2040'}; % Convert dates to numeric serial dates x = datenum(hrznYTMMaturities); xi = datenum(treasuryMaturities); % For numerical accuracy, shift x values to start at zero minDate = min(x); x = x - minDate; xi = xi - minDate; % For each simulation and maturity approximate yield near 10,20,30 year % nodes. Note that the effects of a spline fit vs. linear fit have a % significant effect on the resulting ideal allocation. This is due % to significant under-estimation of yield when using a linear fit % for points just short of the known nodes for i=1:numSim treasuryYTMAtHorizonSim(i,:) = interp1(x,hrznYTMRatesSims(i,:),xi,'spline'); end % Visualize 1 simulated yield curve with interpolation figure; plot(x,hrznYTMRatesSims(1,:),'k-o',xi,treasuryYTMAtHorizonSim(1,:),'ro'); xlabel('Time (days)'); ylabel('Yield'); legend({'Simulated Yield Curve','Interpolated Yields'},'location','se'); grid on; title('Zoom to See Spline vs. Linear Interpolants');
% Price treasuries at horizon for each simulated yield to maturity % Same assumptions are being made here as in above call to bndprice basis = 8*ones(numSim,1); for j=1:3 treasuryPricesAtHorizonSim(:,j) = bndprice(treasuryYTMAtHorizonSim(:,j),0,... hrznDate,treasuryMaturities(j),'basis',basis); end % Calculate distribution of linear returns treasuryReturns = ( treasuryPricesAtHorizonSim - repmat(treasuryPricesAtSettle,numSim,1) )./repmat(treasuryPricesAtSettle,numSim,1); % Calculate returns statistics retsMean = mean(treasuryReturns); retsCov = cov(treasuryReturns); [retsStd,retsCor] = cov2corr(retsCov); % Visualize results for 30 year treasury figure; hist(treasuryReturns,100); title('Distribution of Returns for 10, 20, 30 Year Treasuries'); grid on; legend({'10 year','20 year','30 year'});
Распределение активов оптимизировано с помощью квадратичного программирования. Десять оптимальных портфелей вычисляются, и вычисляются их sharpe отношения. Оптимальный портфель на основе настройки инвестора выбран, чтобы быть тем, который является самым близким к среднему значению отношения Шарпа
disp('Step 5: Optimize Asset Allocation...');
Step 5: Optimize Asset Allocation...
% Calculate 10 points along the projection of the efficient frontier into % std/return space. [portStd,portRet,portWts] = portopt(retsMean,retsCov,10); % Visualize figure; subplot(2,1,1) plot(portStd,portRet,'k-o'); xlabel('Portfolio Std'); ylabel('Portfolio Return'); title('Efficient Frontier Projection'); legend('Optimal Portfolios','location','se'); grid on; subplot(2,1,2) bar(portWts,'stacked'); xlabel('Portfolio Number'); ylabel('Portfolio Weights'); title('Percentage invested in each treasury'); legend({'10 year','20 year','30 year'});
% Sharpe ratio is calculated using 0 risk-free rate since we are investing % in treasuries sharpe = portRet./portStd; % Investor chooses portfolio based on a near mean Sharpe ratio sharpeTarget = mean(sharpe); investorChoice = find( min(abs(sharpe-sharpeTarget)) == abs(sharpe-sharpeTarget)); investorPortfolioWts = portWts(investorChoice,:); disp('Investor percentage allocation in 10,20,30 year treasuries');
Investor percentage allocation in 10,20,30 year treasuries
disp(investorPortfolioWts);
0.3989 0.3196 0.2815
tbilldisc2yield
| tbillprice
| tbillrepo
| tbillval01
| tbillyield
| tbillyield2disc