В этом примере показано, как использовать два различных метода для калибровки модели стохастической волатильности SABR из рыночных подразумеваемых волатильностей Normal (Bachelier) с негативными ударами. Оба подхода используют SABR аналитический прайсер. Когда Beta параметра SABR модель установлена в нуль, модель является моделью Normal SABR, которая позволяет вычислить подразумеваемые нормальные волатильности для отрицательных ударов.
Настройка гипотетического рынка подразумевала нормальные волатильности для европейских свопционов в диапазоне ударов перед калибровкой. Свопции истекают через один год с 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 модель (нормальный SABR). После фиксации значения (Beta), вы подгоняете параметры (Alpha), ρ (Rho), и (Nu) непосредственно. Функция 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) из рыночной Нормальная волатильность в денежном выражении (ATM), решить следующий кубический многочлен для α (Alpha) и выберите наименьший положительный реальный корень. Это похоже на подход, используемый для подразумевания (Alpha) от рыночной волатильности черного [2]. Однако следует отметить, что следующее выражение, которое используется для нормальных летучих веществ, отличается от выражения, которое используется для летучих веществ черного цвета.
α-startНормальный, ATMF-β = 0
% 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] Хаган, Патрик С., Дип Кумар, Эндрю С. Лесневски и Диана Э. Вудворд. «Управление риском улыбки». Wilmott Magazine, (январь 2002): 84-108 .
[2] Уэст, Грэм. «Калибровка модели SABR на неликвидных рынках». Прикладное математическое финансирование. 12, № 4 (декабрь 2005 года): 371-385.