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.
Ok guys, there are some progress and I to share them with you. Thanks to
- As it is available elsewhere, in order to get the calibration, you need a
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::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
https://lists.sourceforge.net/lists/listinfo/quantlib-users