Table of Contents

A SABR smile

The 1Y into 10Y swaption smile of QuantLib's swaption cube tests' market data: an at-the-money vol and the market's spreads to it at four strikes about the forward, fitted by SABR with β fixed. The fit's values match QuantLib's on the same data. The sample, SabrSmile.cs, carries QuantLib's notice.

The smile

A flat 5% curve on 15 October 2026, the ten-year Euribor swap rate a year forward, and its quotes: 14.70% at the money, and the spreads to it at −200, −50, +50 and +200 bp:

// A flat 5% curve, and the ten-year swap the option is on.
YieldTermStructure curve = new FlatForward(today, 0.05, new Actual365Fixed());
var swapIndex = new EuriborSwapIsdaFixA(new Period(10, TimeUnit.Years), curve);
Date optionDate = new TARGET().Advance(today, new Period(1, TimeUnit.Years), BusinessDayConvention.ModifiedFollowing);
double expiry = new Actual365Fixed().YearFraction(today, optionDate);
double forward = swapIndex.Fixing(optionDate, context);

// The market's quotes: 14.70% at the money, and the spreads to it at four strikes about the forward.
double[] strikeSpreads = [-0.020, -0.005, 0.0, 0.005, 0.020];
double[] volSpreads = [0.0729, 0.0086, 0.0, -0.0024, 0.0098];
double[] strikes = [.. strikeSpreads.Select(s => forward + s)];
double[] quotes = [.. volSpreads.Select(s => 0.1470 + s)];

The fit

SABRInterpolation fits α, ν and ρ with β fixed at 0.5, minimizing the vols' errors weighted by the strikes' Black vegas, from SABR's default guesses:

// β fixed at 0.5; α, ν and ρ fitted from SABR's default guesses, the errors weighted by the strikes' vegas.
var sabr = new SABRInterpolation(strikes, quotes, expiry, forward, alpha: null, beta: 0.5, nu: null, rho: null,
    alphaIsFixed: false, betaIsFixed: true, nuIsFixed: false, rhoIsFixed: false);
SABR Value
Forward 5.1316%
α 0.032567
β (fixed) 0.5
ν 0.522132
ρ -0.084029
Root-mean-square error 0.0491%
Maximum error 0.1597%

The smile section

The fitted parameters as a SabrSmileSection, the smile an engine reads at any strike:

// The fitted parameters as a smile section, the smile an engine or a cube reads at any strike.
var section = new SabrSmileSection(expiry, forward, [sabr.Alpha, sabr.Beta, sabr.Nu, sabr.Rho]);

The smile on a 50 bp grid, beside the quotes:

Strike against the forward Strike Quote SABR
-200 bp 3.1316% 21.99% 21.8303%
-150 bp 3.6316% 19.2484%
-100 bp 4.1316% 17.1568%
-50 bp 4.6316% 15.56% 15.6055%
0 bp 5.1316% 14.70% 14.6913%
+50 bp 5.6316% 14.46% 14.4276%
+100 bp 6.1316% 14.6552%
+150 bp 6.6316% 15.1568%
+200 bp 7.1316% 15.68% 15.7784%

Five quotes and three free parameters leave a residual: the fit misses the wing quotes by up to 0.16 vol points, and gives the smile between them.