Re: SABR Calibration
Posted by Mario Marra on May 10, 2017; 3:41pm
URL: http://quantlib.414.s1.nabble.com/SABR-Calibration-tp18226p18265.html
Ok guys, there are some progress and I want 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");
}