Моделирование предварительной оплаты с двумя факторными оболочками белая модель и модель рынка 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)])

Чтобы калибровать параметры модели, набор параметра будет найден, что это минимизирует сумму различий в квадрате между G2 ++, предсказал значения Кэпа и наблюдаемые значения Черной шапочки. Функция Optimization Toolbox™ lsqnonlin используется в этом примере, несмотря на то, что другие подходы (например, Глобальная Оптимизация) могут также быть применимыми. Функциональный capbylg2f вычисляет аналитические значения для дна, данного значения параметров.

Верхние и нижние границы для параметров модели собираются быть относительно ограниченными. Как Бриго и Меркурио обсуждают, параметр корреляции, может часто быть близко к -1 подбирая модель G2 ++ к ценам дна процентной ставки. Поэтому ограничивается быть между -.7 и .7 гарантировать, что параметры представляют действительно 2D факторную модель. Остающееся возвращение к среднему уровню и параметры энергозависимости ограничиваются быть между 0 и .5. Калибровка остается комплексная задача, и в то время как график ниже показывает, что лучшие подходящие параметры, кажется, делают довольно хорошее задание репродуцирования цен Кэпа, нужно отметить, что процедура, обрисованная в общих чертах здесь просто, представляет один подход.

% 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.9872

 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