Моделирование предварительной оплаты с двумя факторными оболочками белая модель и модель рынка LIBOR

Этот пример показывает, как смоделировать предварительную оплату в MATLAB® с помощью функциональности от Financial Instruments Toolbox™. А именно, изменение модели предварительной оплаты Ричарда и Списка реализовано с помощью двух факторных Белых как оболочка моделей процентной ставки и Модели Рынка LIBOR, чтобы моделировать будущие пути процентной ставки. Ценная бумага, обеспеченная закладной, оценена и с пользовательскими и с моделями предварительной оплаты по умолчанию.

Введение

Моделирование предварительной оплаты крайне важно для анализа ценных бумаг, обеспеченных закладной, (MBS). Предварительные оплаты отдельными ипотечными держателями влияют и на сумму и на синхронизацию потоков наличности - и для облигаций, обеспеченных ипотеками (например, ценные бумаги с выплатой только процентов), предварительная оплата может значительно влиять на значение ценных бумаг.

Модель PSA

Самая основная модель предварительной оплаты является моделью Public Securities Association (PSA), которая принимает фазу наращивания и затем постоянный условный уровень предварительной оплаты (CPR). Модель PSA может быть сгенерирована в MATLAB с помощью функции Financial Instruments Toolbox psaspeed2rate.

G2PP_CPR = psaspeed2rate([100 200]);
figure
plot(G2PP_CPR)
title('100 and 200 PSA Prepayment Speeds')
xlabel('Months')
ylabel('CPR')
ylim([0 .14])
legend({'100 PSA','200 PSA'}, 'Location', 'Best')

Ценная бумага, обеспеченная закладной,

MBS, анализируемый в этом примере, назревает в 2 020 и обрисовал в общих чертах свойства в этом разделе. Потоки наличности сгенерированы для скоростей предварительной оплаты PSA просто путем ввода скорости PSA как входного параметра.

% Parameters for MBS passthrough to be priced
Settle = datenum('15-Dec-2007');
Maturity = datenum('15-Dec-2020');
IssueDate = datenum('15-Dec-2000');
GrossRate = .0475;
CouponRate = .045;
Delay = 14;
Period = 12;
Basis = 4;

% Generate cash flows and dates for baseline case using 100 PSA
[CFlowAmounts, CFlowDates] = mbscfamounts(Settle,Maturity, IssueDate,...
    GrossRate, CouponRate, Delay,100);
CFlowTimes = yearfrac(Settle,CFlowDates);
NumCouponsRemaining = cpncount(Settle, Maturity, Period,Basis, 1, IssueDate);

Ричард и модель списка

В то время как предварительная оплата, моделирующая часто, включает комплексное и сложное моделирование, часто на уровне ссуды, этот пример использует немного измененный подход на основе модели, предложенной Ричардом, и Сыпьтесь [6].

Модель предварительной оплаты Ричарда и Списка включает следующие факторы:

  • Рефинансирование стимула

  • Сезонность (месяц года)

  • Приправа или возраст ипотеки

  • Перегорание

Ричард и Список предлагают мультипликативную модель следующего:

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

Стимул рефинансирования является функцией отношения купонной ставки ипотеки к доступной ипотечной ставке в тот момент. Например, Управление надзора за сберегательными учреждениями (OTS) предлагает следующую модель:

Стимул рефинансирования требует симуляции уровней будущего права. Это будет обсуждено позже в этом примере.

C_M = .1:.1:2;
G2PP_Refi = .2406 - .1389 * atan(5.952*(1.089 - C_M));
figure
plot(C_M,G2PP_Refi)
xlabel('Coupon/Mortgage Rate')
ylabel('CPR')
title('Refinancing Incentive')

Приправа получает тенденцию предварительной оплаты к подъему в начале ипотеки перед выравниванием. Модели OTS множитель приправы можно следующим образом:

Seasoning = ones(360,1);
Seasoning(1:29) = (1:29)/30;
figure
plot(Seasoning)
xlim([1 360])
title('Seasoning Multiplier')
xlabel('Months')

Множитель сезонности просто моделирует сезонное поведение предварительных оплат - эти данные основаны на рисунке 3 [6], который применяется к поведению Джинни Мэй 30-летний, односемейный MBSs.

Seasonality = [.94 .76 .73 .96 .98 .92 .99 1.1 1.18 1.21 1.23 .97];
figure
plot(Seasonality)
xlim([1 12])
ax = gca;
ax.XTick = 1:12;
ax.XTickLabel = {'Jan','Feb','Mar','Apr','May','Jun','Jul','Aug', ...
    'Sep','Oct','Nov','Dec'};
title('Seasonality Multiplier')

G2 ++ модель процентной ставки

Поскольку стимул рефинансирования требует симуляции уровней будущего права, модель процентной ставки должна использоваться. Одним выбором является 2D факторная аддитивная модель Gaussian, называемая G2 ++ Бриго и Меркурио [2].

G2 ++ Модель Процентной ставки:

где двумерное Броуновское движение с корреляцией

и короткий уровень, и константы возвращения к среднему уровню и и константы энергозависимости, и форвардный курс рынка или форвардный курс, наблюдаемый относительно Уладить даты.

Модель рынка LIBOR

Модель рынка LIBOR (LMM) отличается от моделей короткого уровня, в которых она развивает набор дискретных форвардных курсов. А именно, логарифмически нормальный LMM задает следующее уравнение диффузии для каждого форвардного курса:

где

собственный вес является размерным геометрическим броуновским движением N с:

LMM связывает дрейфы форвардных курсов на основе аргументов без арбитражей. А именно, под Пятном мера LIBOR дрейфы выражаются как следующее:

где

часть времени, сопоставленная с ith форвардным курсом

и Пятно счетные деньги LIBOR задано как следующее:

Учитывая вышеупомянутое, выбор с LMM состоит в том, как смоделировать энергозависимость и корреляцию.

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

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

Точно так же корреляция между форвардными курсами должна быть задана. Это может быть оценено от исторических данных или адаптировано к ценам опции. В данном примере следующая функциональная форма будет использоваться:

Если энергозависимость и корреляция заданы, параметры должны быть калиброваны - это может быть сделано с историческим или данными о рынке, обычно swaptions или прописными буквами/этажами. В данном примере мы просто используем обоснованные оценки для параметров энергозависимости и корреляции.

% The volatility function to be used -- and one choice for the parameters
LMMVolFunc = @(a,t) (a(1)*t + a(2)).*exp(-a(3)*t) + a(4);
LMMVolParams = [.13 .04 .7 .08];

% Volatility specification
fplot(@(t) LMMVolFunc(LMMVolParams,t),[0 10])
title(['Volatility Function with parameters ' mat2str(LMMVolParams)])
ylabel('Volatility (%)')
xlabel('Tenor (years)')

Калибровка, чтобы продать данные

Параметры в модели G2 ++ могут быть калиброваны, чтобы продать данные. Как правило, параметры калибруются к наблюдаемой прописной букве процентной ставки, полу и/или swaption данным. На данный момент данные о рыночной капитализации используются для калибровки.

Эти данные являются hardcoded, но могли быть импортированы в MATLAB с Database Toolbox™ или Datafeed Toolbox™.

% Zero Curve -- this data is hardcoded for now, but could be bootstrapped
% using the |bootstrap| method of |IRDataCurve|.
ZeroTimes = [3/12 6/12 1 5 7 10 20 30]';
ZeroRates = [0.033 0.034 0.035 0.040 0.042 0.044 0.048 0.0475]';
ZeroDates = daysadd(Settle,360*ZeroTimes,1);
DiscountRates = zero2disc(ZeroRates,ZeroDates,Settle);
irdc = IRDataCurve('Zero',Settle,ZeroDates,ZeroRates);

figure
plot(ZeroDates,ZeroRates)
datetick
title(['US Zero Curve for ' datestr(Settle)])

% Cap Data
Reset = 2;
Notional = 100;
CapMaturity = daysadd(Settle,360*[1:5 7 10 15 20 25 30],1);
CapVolatility = [.28 .30 .32 .31 .30 .27 .23 .2 .18 .17 .165]';

% ATM strikes could be computed with swapbyzero
Strike = [0.0353 0.0366 0.0378 0.0390 0.0402 0.0421 0.0439 ...
    0.0456 0.0471 0.0471 0.0471]';

% This could be computed with capbyblk
BlackCapPrices = [0.1532 0.6416 1.3366 2.0290 2.7366 4.2960 6.5992 ...
    9.6787 12.2580 14.0969 15.7873]';

figure
scatter(CapMaturity,CapVolatility)
datetick
title(['ATM Volatility for Caps on ' datestr(Settle)])

%
% To calibrate the model parameters, a parameter set will be found that
% minimizes the sum of the squared differences between the G2++ predicted
% Cap values and the observed Black Cap values. The Optimization Toolbox(TM)
% function <docid:optim_ug#buuhch7 lsqnonlin> is used in this example, although other approaches
% (for example, Global Optimization) may also be applicable. The function
% <docid:fininst_ug#btxewvg-313 capbylg2f>
% computes the analytic values for the caps given parameter values.
%
% Upper and lower bounds for the model parameters are set to be
% relatively constrained. As Brigo and Mercurio discuss, the correlation
% parameter, $$ rho $$, can often be close to |-1| when fitting a G2++ model
% to interest-rate cap prices. Therefore, $$ rho $$ is constrained
% to be between |-.7| and |.7| to ensure that the parameters represent a truly
% two-factor model. The remaining mean reversion and volatility
% parameters are constrained to be between |0| and |.5|. Calibration remains a
% complex task, and while the plot below indicates that the best fit
% parameters seem to do a reasonably good job of reproducing the Cap
% prices, it should be noted that the procedure outlined here simply
% represents one approach.

% Call to lsqnonlin to calibrate parameters
objfun = @(x) BlackCapPrices - capbylg2f(irdc,x(1),x(2),x(3),x(4),x(5),Strike,CapMaturity);
x0 = [.5 .05 .1 .01 -.1];
lb = [0 0 0 0 -.7];
ub = [.5 .5 .5 .5 .7];

G2PP_Params = lsqnonlin(objfun,x0,lb,ub);

a = G2PP_Params(1);
b = G2PP_Params(2);
sigma = G2PP_Params(3);
eta = G2PP_Params(4);
rho = G2PP_Params(5);

% Compare the results
figure
scatter(CapMaturity,BlackCapPrices)
hold on
scatter(CapMaturity,capbylg2f(irdc,a,b,sigma,eta,rho,Strike,CapMaturity),'rx')
datetick
title('Market and Model Implied Prices')
ylabel('Price ($)')
Local minimum possible.

lsqnonlin stopped because the final change in the sum of squares relative to 
its initial value is less than the value of the function tolerance.

G2 ++ образцовая реализация

Модель LinearGaussian2F может использоваться, чтобы задать модель G2 ++ и моделировать будущие процентные ставки путей.

% G2++ model from Brigo and Mercurio with time homogeneous volatility
% parameters
G2PP = LinearGaussian2F(irdc,a,b,sigma,eta,rho);

Реализация модели рынка LIBOR

После того, как энергозависимость и корреляция были калиброваны, симуляция Монте-Карло используется, чтобы развить уровни вперед вовремя. Объект LiborMarketModel используется, чтобы моделировать форвардные курсы.

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

6M уровни LIBOR выбраны, чтобы быть развитыми в этой симуляции. Поскольку ежемесячный вектор предварительной оплаты должен быть вычислен, интерполяция используется, чтобы сгенерировать промежуточные уровни. Простая линейная интерполяция используется.

numForwardRates = 46;

% Instead of being fit, VolPhi is simply hard-coded  --
% representative of a declining volatility over time.
VolPhi = linspace(1.2,.8,numForwardRates-1)';

Beta = .08;
CorrFunc = @(i,j,Beta) exp(-Beta*abs(i-j));
CorrMat = CorrFunc(meshgrid(1:numForwardRates-1)',meshgrid(1:numForwardRates-1),Beta);

VolFunc = cell(length(VolPhi),1);
for jdx = 1:length(VolPhi)
    VolFunc(jdx) = {@(t) VolPhi(jdx)*ones(size(t)).*(LMMVolParams(1)*t + ...
        LMMVolParams(2)).*exp(-LMMVolParams(3)*t) + LMMVolParams(4)};
end

LMM = LiborMarketModel(irdc,VolFunc,CorrMat);

G2 ++ симуляция Монте-Карло

Различные пути процентной ставки могут быть моделированы путем вызова метода simTermStructs.

Одно ограничение к 2D факторным моделям Gaussian как этот - то, что это действительно разрешает отрицательные процентные ставки. Это - беспокойство, особенно в средах низкой процентной ставки. Чтобы обработать эту возможность, любые пути процентной ставки с отрицательными уровнями просто отклоняются.

nPeriods = NumCouponsRemaining;
nTrials = 100;
DeltaTime = 1/12;

% Generate factors and short rates
Tenor = [1/12 1 2 3 4 5 7 10 15 20 30];
G2PP_SimZeroRates = G2PP.simTermStructs(nPeriods,'NTRIALS',nTrials,...
    'Tenor',Tenor,'DeltaTime',DeltaTime);

SimDates = daysadd(Settle,360*DeltaTime*(0:nPeriods),1);

% Tenors that will be recovered for each simulation date. The stepsize is
% included here to facilitate computing a discount factor for each
% simulation path.

% Remove any paths that go negative
NegIdx = squeeze(any(any(G2PP_SimZeroRates < 0,1),2));
G2PP_SimZeroRates(:,:,NegIdx) = [];
nTrials = size(G2PP_SimZeroRates,3);

% Plot evolution of one sample path
trialIdx = 1;
figure
surf(Tenor,SimDates,G2PP_SimZeroRates(:,:,trialIdx))
datetick y keepticks keeplimits
title(['Evolution of the Zero Curve for Trial:' num2str(trialIdx) ' of G2++ Model'])
xlabel('Tenor (Years)')

Симуляция модели рынка LIBOR

Различные пути процентной ставки могут быть моделированы путем вызова метода simTermStructs объекта LiborMarketModel.

LMMPeriod = 2; % Semi-annual rates
LMMNumPeriods = NumCouponsRemaining/12*LMMPeriod; % Number of semi-annual periods
LMMDeltaTime = 1/LMMPeriod;
LMMNTRIALS = 100;

% Simulate
[LMMZeroRates, LMMForwardRates] = LMM.simTermStructs(LMMNumPeriods,'nTrials',LMMNTRIALS,'DeltaTime',LMMDeltaTime);
ForwardTimes = 1/2:1/2:numForwardRates/2;
LMMSimTimes = 0:1/LMMPeriod:LMMNumPeriods/LMMPeriod;

% Plot evolution of one sample path
trialIdx = 1;
figure
tmpPlotData = LMMZeroRates(:,:,trialIdx);
tmpPlotData(tmpPlotData == 0) = NaN;
surf(ForwardTimes,LMMSimTimes,tmpPlotData)
title(['Evolution of the Zero Curve for Trial:' num2str(trialIdx) ' of LIBOR Market Model'])
xlabel('Tenor (Years)')

Вычислите ипотечные ставки из симуляции

Если пути процентной ставки были моделированы, ипотечная ставка должна быть вычислена - один подход, обсужденный [7], должен вычислить ипотечную ставку из комбинации 2-летних и 10-летних уровней.

В данном примере следующее используется:

% Compute mortgage rates from interest rate paths
TwoYearRates = squeeze(G2PP_SimZeroRates(:,Tenor == 2,:));
TenYearRates = squeeze(G2PP_SimZeroRates(:,Tenor == 7,:));
G2PP_MortgageRates = .024 + .2*TwoYearRates + .6*TenYearRates;

LMMMortgageRates = squeeze(.024 + .2*LMMZeroRates(:,4,:) + .6*LMMZeroRates(:,20,:));
LMMDiscountFactors = squeeze(cumprod(1./(1 + LMMZeroRates(:,1,:)*.5)));

% Interpolate to get monthly mortgage rates
MonthlySimTimes = 0:1/12:LMMNumPeriods/LMMPeriod;
LMMMonthlyMortgageRates = zeros(nPeriods+1,LMMNTRIALS);
LMMMonthlyDF = zeros(nPeriods+1,LMMNTRIALS);
for trialidx = 1:LMMNTRIALS
   LMMMonthlyMortgageRates(:,trialidx) = interp1(LMMSimTimes,LMMMortgageRates(:,trialidx),MonthlySimTimes,'linear','extrap');
   LMMMonthlyDF(:,trialidx) = interp1(LMMSimTimes,LMMDiscountFactors(:,trialidx),MonthlySimTimes,'linear','extrap');
end

Вычислительный CPR и генерация и оценка потоков наличности

Если Ипотечные ставки были моделированы, CPR может быть вычислен из мультипликативной модели для каждого пути процентной ставки.

% Compute Seasoning and Refinancing Multipliers
Seasoning = ones(nPeriods+1,1);
Seasoning(1:30) = 1/30*(1:30);
G2PP_Refi = .2406 - .1389 * atan(5.952*(1.089 - CouponRate./G2PP_MortgageRates));
LMM_Refi = .2406 - .1389 * atan(5.952*(1.089 - CouponRate./LMMMonthlyMortgageRates));

% CPR is simply computed by evaluating the multiplicative model
G2PP_CPR = bsxfun(@times,G2PP_Refi,Seasoning.*(Seasonality(month(CFlowDates))'));
LMM_CPR = bsxfun(@times,LMM_Refi,Seasoning.*(Seasonality(month(CFlowDates))'));

% Compute single monthly mortality (SMM) from CPR
G2PP_SMM = 1 - (1 - G2PP_CPR).^(1/12);
LMM_SMM = 1 - (1 - LMM_CPR).^(1/12);

% Plot CPR's against 100 PSA
CPR_PSA100 = psaspeed2rate(100);
figure
PSA_handle = plot(CPR_PSA100(1:nPeriods),'rx');
hold on
G2PP_handle = plot(G2PP_CPR,'b');
LMM_handle = plot(LMM_CPR,'g');
title('Prepayment Speeds')
legend([PSA_handle(1) G2PP_handle(1) LMM_handle(1)],{'100 PSA','G2PP CPR','LMM CPR'},'Location', 'Best');

Сгенерируйте потоки наличности и вычислите приведенную стоимость

С вектором одного ежемесячного журнала mortalities (SMM), вычисленного для каждого пути процентной ставки, потоки наличности для MBS могут быть вычислены и обесценены.

% Compute the baseline zero rate at each cash flow time
CFlowZero = interp1(ZeroTimes,ZeroRates,CFlowTimes,'linear','extrap');

% Compute DF for each cash flow time
CFlowDF_Zero = zero2disc(CFlowZero,CFlowDates,Settle);

% Compute the price of the MBS using the zero curve
Price_Zero = CFlowAmounts*CFlowDF_Zero';

% Generate the cash flows for each IR Path
G2PP_CFlowAmounts = mbscfamounts(Settle, ...
    repmat(Maturity,1,nTrials), IssueDate, GrossRate, CouponRate, Delay, [], G2PP_SMM(2:end,:));

% Compute the DF for each IR path
G2PP_CFlowDFSim = cumprod(exp(squeeze(-G2PP_SimZeroRates(:,1,:).*DeltaTime)));

% Present value the cash flows for each MBS
G2PP_Price_Ind = sum(G2PP_CFlowAmounts.*G2PP_CFlowDFSim',2);
G2PP_Price = mean(G2PP_Price_Ind);

% Repeat for LMM
LMM_CFlowAmounts = mbscfamounts(Settle, ...
    repmat(Maturity,1,LMMNTRIALS), IssueDate, GrossRate, CouponRate, Delay, [], LMM_SMM(2:end,:));

% Present value the cash flows for each MBS
LMM_Price_Ind = sum(LMM_CFlowAmounts.*LMMMonthlyDF',2);
LMM_Price = mean(LMM_Price_Ind);

Результаты разных подходов могут быть сравнены. Количество испытаний за модель G2 ++ обычно будет меньше чем 100 из-за фильтрации из любых путей, которые производят отрицательные процентные ставки.

Кроме того, в то время как номер испытаний за модель G2 ++ в этом примере определяется, чтобы быть 100, часто имеет место, что большее число симуляций должно быть запущено, чтобы произвести точную оценку.

fprintf('                     # of Monte Carlo Trials: %8d\n'    , nTrials)
fprintf('                     # of Time Periods/Trial: %8d\n\n'  , nPeriods)
fprintf('                      MBS Price with PSA 100: %8.4f\n'  , Price_Zero)
fprintf(' MBS Price with Custom G2PP Prepayment Model: %8.4f\n\n', G2PP_Price)
fprintf(' MBS Price with Custom LMM Prepayment Model: %8.4f\n\n', LMM_Price)
                     # of Monte Carlo Trials:       73
                     # of Time Periods/Trial:      156

                      MBS Price with PSA 100:   1.0187
 MBS Price with Custom G2PP Prepayment Model:   0.9871

 MBS Price with Custom LMM Prepayment Model:   0.9993

Заключение

Этот пример показывает, как калибровать и моделировать G2 ++ модель процентной ставки и как использовать сгенерированные пути процентной ставки в модели предварительной оплаты свободно на основе модели Ричарда и Roll. Этот пример также обеспечивает полезную отправную точку использования G2 ++ и модели процентной ставки LMM в других финансовых приложениях.

Библиография

Этот пример основан на следующих книгах, бумагах и статьях в журнале:

  1. Андерсен, L. и В. Питербарг (2010). Моделирование процентной ставки, атлантическое финансовое нажатие.

  2. Brigo, D. и Ф. Меркурио (2001). Модели Процентной ставки - Теория и Практика с Улыбкой, Инфляцией и Кредитом (2-й редактор 2 006 редакторов). Springer Verlag. ISBN 978-3-540-22149-4.

  3. Hayre, L, редактор, Сэломон Смит Барни Гуид к Mortgage-Backed and Asset-Backed Securities. Нью-Йорк: John Wiley & Sons, 2001b

  4. Karpishpan, Y., О. Турель и А. Хэша, вводя модель структуры термина LMM Citi для ипотек, журнал фиксированного дохода, объем 20 (2010) 44-58.

  5. Rebonato, R., К. Маккей и R. Белый (2010). Модель Рынка Sabr/Libor: Оценка, Калибровка и Хеджирование для Комплексных Производных Процентной ставки. John Wiley & Sons.

  6. Ричард, S. F. и R. Прокрутитесь, 1989, "Предварительные оплаты на ценных бумагах, обеспеченных закладной, фиксированной процентной ставки", журнал управления портфелем.

  7. Управление надзора за сберегательными учреждениями, "сетевое руководство модели стоимости портфеля", март 2000.

  8. Глиняная кружка, H. J., Беликофф, A. L., Левин, K. и Тянь, X., Анализ Mortgage Backed Securities: До и после Кредитного кризиса (5 января 2007). Границы Кредитного риска: Субстандартный Кризис, Оценивая и Страхуясь, CVA, MBS, Оценки и Ликвидность; Bielecki, Томаш; Дамиано Бриго и Фредерик Пэтрас, редакторы, февраль 2011. Доступный в SSRN: https://papers.ssrn.com/sol3/papers.cfm?abstract_id=955358