В этом примере показано, как использовать два различных метода для калибровки модели стохастической волатильности SABR из рыночных подразумеваемых волатильностей Normal (Bachelier) с отрицательными ударами. Оба подхода используют SABR
аналитический прайс. Когда Beta
параметр SABR
модель установлена в нуль, модель является моделью Normal SABR, которая позволяет вычислять подразумеваемые волатильности Normal для отрицательных ударов.
Создание гипотетического рынка подразумевало Нормальную волатильность для европейских свопсов в ряде забастовок перед калибровкой. Срок действия свопционов истекает через год после Settle
дата и двухлетние свопы в качестве базового инструмента. Скорости выражены десятичными числами. Рынок подразумевал Нормальные волатильности преобразуются из базисных точек в десятичные числа. (Изменение модулей влияет на числовое значение и интерпретацию Alpha
параметр в SABR
модель.)
% Load the market implied Normal volatility data for swaptions expiring in one year. Settle = datetime(2020, 4, 24); ExerciseDate = datetime(2021, 4, 24); Basis = 1; ZeroDates = Settle + [calmonths([3 6 9]) calyears([1 2 3 4 5 ... 6 7 10 15 20])]'; ZeroRates = [-.54 -.57 -.60 -.62 -.67 -.67 -.65 -.61 ... -.56 -.51 -.36 -.19 -.10]'/100; Compounding = 1; ZeroCurve = ratecurve("zero",Settle,ZeroDates,ZeroRates,'Compounding',Compounding); ATMStrike = -0.70/100; MarketStrikes = ATMStrike + ((-0.5:0.25:1.5)')./100; MarketVolatilities = [29.89 25.47 23.21 26.17 29.59 33.12 37.81 41.88 46.24]'/10000; % At the time of Settle, define the underlying forward rate and the at-the-money volatility. CurrentForwardValue = MarketStrikes(3)
CurrentForwardValue = -0.0070
ATMVolatility = MarketVolatilities(3)
ATMVolatility = 0.0023
Alpha
, Rho
, и Nu
НепосредственноМожно калибровать Alpha
, Rho
, и Nu
параметры непосредственно. Установите значение Beta
параметр, чтобы нуль в порядок, чтобы разрешить отрицательные скорости в SABR
модель (Normal SABR). После того, как вы исправите значение (Beta
), вы подбираете параметры (Alpha
), (Rho
), и (Nu
) непосредственно. Функция Optimization Toolbox™ lsqnonlin
генерирует значения параметров, которые минимизируют квадратичную невязку между волатильностями рынка и волатильностями, вычисленными SABR
аналитический прайс.
% Define the predetermined Beta Beta1 = 0; % Setting Beta to zero allows negative rates for Normal volatilities % Calibrate Alpha, Rho, and Nu objFun = @(X) MarketVolatilities - ... volatilities(finpricer("Analytic", 'Model', ... finmodel("SABR", 'Alpha', X(1), 'Beta', Beta1, 'Rho', X(2), ... 'Nu', X(3), 'VolatilityType', 'Normal'), 'DiscountCurve', ZeroCurve), ... ExerciseDate, CurrentForwardValue, MarketStrikes); % If necessary, adjust the tolerances and stopping criteria for lsqnonlin X = lsqnonlin(objFun, [ATMVolatility 0 0.5], [0 -1 0], [Inf 1 Inf]);
Local minimum found. Optimization completed because the size of the gradient is less than the value of the optimality tolerance.
Alpha1 = X(1); Rho1 = X(2); Nu1 = X(3);
Другим методом является использование альтернативного метода калибровки. Как и в первом методе, вы задаете значение (Beta
) в нуль, чтобы разрешить отрицательные ставки. Однако после фиксации значения (Beta
), вы подбираете параметры (Rho
) и (Nu
) непосредственно в то время как (Alpha
) подразумевается от рыночной волатильности денег. Модели, калиброванные с использованием этого метода, приводят к волатильности в деньгах, которая равна рыночным котировкам. Этот подход может быть полезным, когда волатильность в деньгах цитируется чаще всего и важна для соответствия. Подразумевать (Alpha
) от рынка на деньги Нормальная волатильность (), решить следующий кубический полином для (Alpha
), и выберите наименьший положительный действительный корень. Это аналогично подходу, используемому для подразумевания (Alpha
) с рынка на деньги Черная волатильность [2]. Однако обратите внимание, что следующее выражение, которое используется для Normal volatilities, отличается от выражения, которое используется для Black volatilities.
% Define the predetermined Beta Beta2 = 0; % Setting Beta to zero allows negative rates for Normal volatilities % Year fraction from Settle date to option maturity T = yearfrac(Settle, ExerciseDate, Basis); % This function solves the SABR at-the-money volatility equation as a % polynomial of Alpha alpharootsNormal = @(Rho,Nu) roots([... Beta2.*(Beta2 - 2)*T/24/CurrentForwardValue^(2 - 2*Beta2) ... Rho*Beta2*Nu*T/4/CurrentForwardValue^(1 - Beta2) ... (1 + (2 - 3*Rho^2)*Nu^2*T/24) ... -ATMVolatility*CurrentForwardValue^(-Beta2)]); % This function converts at-the-money volatility into Alpha by picking the % smallest positive real root atmNormalVol2SabrAlpha = @(Rho,Nu) min(real(arrayfun(@(x) ... x*(x>0) + realmax*(x<0 || abs(imag(x))>1e-6), alpharootsNormal(Rho,Nu)))); % Calibrate Rho and Nu (while converting at-the-money volatility into Alpha % using atmNormalVol2SabrAlpha) objFun = @(X) MarketVolatilities - ... volatilities(finpricer("Analytic", 'Model', ... finmodel("SABR", 'Alpha', atmNormalVol2SabrAlpha(X(1), X(2)), ... 'Beta', Beta2, 'Rho', X(1), 'Nu', X(2), 'VolatilityType', 'Normal'), ... 'DiscountCurve', ZeroCurve), ... ExerciseDate, CurrentForwardValue, MarketStrikes); % If necessary, adjust the tolerances and stopping criteria for lsqnonlin X = lsqnonlin(objFun, [0 0.5], [-1 0], [1 Inf]);
Local minimum found. Optimization completed because the size of the gradient is less than the value of the optimality tolerance.
Rho2 = X(1); Nu2 = X(2); % Obtain final Alpha from at-the-money volatility using calibrated parameters Alpha2 = atmNormalVol2SabrAlpha(Rho2, Nu2); % Display calibrated parameters C = {Alpha1 Beta1 Rho1 Nu1;Alpha2 Beta2 Rho2 Nu2}; format; CalibratedPrameters = cell2table(C,... 'VariableNames',{'Alpha' 'Beta' 'Rho' 'Nu'},... 'RowNames',{'Method 1';'Method 2'})
CalibratedPrameters=2×4 table
Alpha Beta Rho Nu
_________ ____ _________ _______
Method 1 0.0023279 0 -0.010078 0.63538
Method 2 0.0022389 0 -0.019029 0.66368
Используйте калиброванные модели для вычисления новых волатильностей при любом значении удара, включая отрицательные удары.
Вычислите летучесть для моделей, калиброванных с помощью Метода 1 и Метода 2, затем постройте график результатов. Модель, калиброванная с использованием Метода 2, точно воспроизводит волатильность рынка на деньгах (отмеченная кругом).
PlottingStrikes = (min(MarketStrikes)-0.0025:0.0001:max(MarketStrikes)+0.0025)'; % Compute volatilities for model calibrated by Method 1 SABR_Model_Method_1 = finmodel("SABR", ... 'Alpha', Alpha1, 'Beta', Beta1, 'Rho', Rho1, 'Nu', Nu1, ... 'VolatilityType', 'Normal'); ComputedVols1 = volatilities(finpricer("Analytic", ... 'Model', SABR_Model_Method_1, 'DiscountCurve', ZeroCurve), ... ExerciseDate, CurrentForwardValue, PlottingStrikes); % Compute volatilities for model calibrated by Method 2 SABR_Model_Method_2 = finmodel("SABR", ... 'Alpha', Alpha2, 'Beta', Beta2, 'Rho', Rho2, 'Nu', Nu2, ... 'VolatilityType', 'Normal'); ComputedVols2 = volatilities(finpricer("Analytic", ... 'Model', SABR_Model_Method_2, 'DiscountCurve', ZeroCurve), ... ExerciseDate, CurrentForwardValue, PlottingStrikes); figure; plot(MarketStrikes,MarketVolatilities*10000,'xk',... PlottingStrikes,ComputedVols1*10000,'b', ... PlottingStrikes,ComputedVols2*10000,'r', ... CurrentForwardValue,ATMVolatility*10000,'ok',... 'MarkerSize',10); h = gca; line([0,0],[min(h.YLim),max(h.YLim)],'LineStyle','--'); xlabel('Strike', 'FontWeight', 'bold'); ylabel('Implied Normal Volatility (bps)', 'FontWeight', 'bold'); legend('Market Volatilities', 'Normal SABR Model (Method 1)', ... 'Normal SABR Model (Method 2)', 'At-the-money volatility', ... 'Location', 'northwest');
[1] Hagan, Patrick S., Deep Kumar, Andrew S. Lesniewski, and Diana E. Woodward. «Управление риском улыбки». Wilmott Magazine, (январь 2002): 84-108 .
[2] Уэст, Грэм. Калибровка модели SABR на неликвидных рынках. Прикладные математические финансы. 12, № 4 (декабрь 2005 года): 371-385.