the SABR interpolation set up is quite generic, so I think it’s easy to add your new calibration strategy: Add a

similar to SABRSpecs in sabrinterpolation.hpp and modify the inverse() and direct() methods that are the transformations between the (unconstrained) optimisation space and the SABR parameter space. You can probably inherit from SABRSpecs and just overwrite the two methods.

You can check if alpha is fixed in these methods (they have the isFixed bool-vector as an input) and if yes set it to the value from the paper. Then add the spec struct as a template parameter to SABRInterpolation (it’s hardcoded to SABRSpecs at the moment) and typedef SABRInterpolation_t<SABRSpec> to SABRInterpolation to maintain backwards compatibility. You can add a second typedef SABRInterpolation_t<SABRSmartAlphaSpecs> to SABRSmartAlphaInterpolation, which is then your new interpolation class.

There is a small problem though, since neither the option maturity nor the atm vol is provided to the inverse / direct methods. This would require an extension of the signature of these methods in SABRSpecs, ZabrSpecs, SviSpecs, and their common backbone XABRInterpolationImpl. Which is straightforward though.

If the new interpolation is actually working more stable and / or is faster to compute, then the whole thing might be worth a pull request.

About the number of parameters: When you use Levenberg Marquardt I’d expect that you need 3 points (not 4) to calibrate 3 parameters? Do you get an exception if you provide 3 points?

If on the other hand you use e.g. the Simplex Optimiser there is no such restriction, the optimisation should run with any number of points.

> On 10 May 2017, at 17:41, Mario Marra <

[hidden email]> wrote:

>

> Ok guys, there are some progress and I to share them with you. Thanks to

> Luigi's help, I managed to solve the following issues:

>

> - As it is available elsewhere, in order to get the calibration, you need a

> call to update. In my code I did:

> SABRLinInterpolation.update();

>

> - To calibrate 3 parameters it is needed at least 4 (should be)

> observations, however, I found a way around it by incrementing the the

> strikes and the vol by an amount close to zero and the calibration seems to

> work well (I compared to the one in RStudio and the results seem to be

> correct);

>

> What we are still trying to solve is the issue related to the constraint.

>> From the equation (6) of the file I attached you can see that the constraint

> of alpha is a specific figure which is a function of ATM_Vol, Forward,

> Time_to_Maturity, Beta, Rho and Nu.

> I suggested to use a Composite constraint but it seems that it might not be

> that easy as suggested by Luigi through emails.

>

> So from now the real question is, do you know how can I force the

> calibration to have AlphaIsFixed = False while at the same time returning a

> parameter which returns the correct value if the equation (6) from the paper

> is used?

>

> Thank you in advance,

>

> Mario

>

>

> Following there is what I have down so far

>

> ######

>

> int main(int argc, const char * argv[])

> {

> //~~~~~~~~~~~~~~~~~~~~~~~~~SABR Interpolation Curve

> std::cout << "SABR Interpolation" << std::endl;

> std::vector <Real> xVec(4), yVec(xVec.size());

>

> xVec[0] = 100; yVec[0] = 0.120232487; //Create vectors

> xVec[1] = 120; yVec[1] = 0.088666203;

> xVec[2] = 120.00000000001; yVec[2] = 0.0886662030001; //Trick to have the

> calibration working as you need n+1 observations to calibrate n parameters

> xVec[3] = 120.00000000002; yVec[3] = 0.0886662030002;//Trick to have the

> calibration working as you need n+1 observations to calibrate n parameters

>

> //SABR::SABR(4.649315068, 110.5, 0.5, 1, 0.5, 0.5, false,

> false, false, false); //It just assigns value within the private components

> of the class

> SABRInterpolation SABRLinInterpolation(xVec.begin(), xVec.end(),

> yVec.begin(), 3.649315068, 114.3, 0.087443, 1, 0.657465, -0.41797, false,

> true, false, false);

> SABRLinInterpolation.enableExtrapolation(); //This step is necessary to get

> the possibility of interpolate the curve outside the strikes provided

> {//Without Calibration

> for (double x = 90; x <= 150; x++)

> std::cout << "Sabr Vol at Strike " << x << ":" << SABRLinInterpolation(x)

> << std::endl;

> }

> std::cout << "The error is :" << SABRLinInterpolation.rmsError() <<

> std::endl << std::endl << std::endl;

>

> //~~~~~~~~~~~~~~~~~~~~~~~~~SABR Calibration

> {

> SABRLinInterpolation.update(); //Return Parameters

> Real Return_Parms[4] = { SABRLinInterpolation.alpha(),

> SABRLinInterpolation.beta(),SABRLinInterpolation.rho(),SABRLinInterpolation.nu()

> };

> std::cout << "The parameters calibrated are are (alpha, beta, rho and nu):

> " << std::endl;

> {

> for (int y = 0; y <= 3; y++)

> std::cout << Return_Parms[y] << std::endl;

> }

> std::cout << "\n\n";

> {

> for (double x = 90; x <= 150; x++)

> std::cout << "Sabr Vol at Strike (Calibrated) " << x << ":" <<

> SABRLinInterpolation(x) << std::endl;

> }

> std::cout << "\nThe error is :" << SABRLinInterpolation.rmsError() <<

> std::endl;

>

> system("pause");

> }

>

>

>

> --

> View this message in context:

http://quantlib.10058.n7.nabble.com/SABR-Calibration-tp18226p18265.html> Sent from the quantlib-users mailing list archive at Nabble.com.

>

> ------------------------------------------------------------------------------

> Check out the vibrant tech community on one of the world's most

> engaging tech sites, Slashdot.org!

http://sdm.link/slashdot> _______________________________________________

> QuantLib-users mailing list

>

[hidden email]
>

https://lists.sourceforge.net/lists/listinfo/quantlib-users