Пример #1
0
        public void SABRParamToIVFacts()
        {
            //for  beta==1 and zero nu and rho we get a flat surface with vol==alpha
            var vol = SABR.CalcImpVol_Beta1(100, 100, 1, 0.32, 0, 0);

            Assert.Equal(0.32, vol, 10);
            vol = SABR.CalcImpVol_Beta1(100, 150, 1, 0.32, 0, 0);
            Assert.Equal(0.32, vol, 10);
            vol = SABR.CalcImpVol_Beta1(100, 50, 1, 0.32, 0, 0);
            Assert.Equal(0.32, vol, 10);

            //for positive rho should see upside vols > downside
            var volU = SABR.CalcImpVol_Beta1(100, 150, 1, 0.32, 0.5, 0.16);
            var volD = SABR.CalcImpVol_Beta1(100, 75, 1, 0.32, 0.5, 0.16);

            Assert.True(volU > volD);

            //for negative rho should see upside vols < downside
            volU = SABR.CalcImpVol_Beta1(100, 150, 1, 0.32, -0.5, 0.16);
            volD = SABR.CalcImpVol_Beta1(100, 75, 1, 0.32, -0.5, 0.16);
            Assert.True(volU < volD);

            //for larger nu should see upside wing vols higher
            volU = SABR.CalcImpVol_Beta1(100, 150, 1, 0.32, 0, 0.16);
            volD = SABR.CalcImpVol_Beta1(100, 75, 1, 0.32, 0, 0.16);
            var wingLow = volU + volD;

            volU = SABR.CalcImpVol_Beta1(100, 150, 1, 0.32, 0, 0.32);
            volD = SABR.CalcImpVol_Beta1(100, 75, 1, 0.32, 0, 0.32);
            var wingHigh = volU + volD;

            Assert.True(wingHigh > wingLow);

            //for GB parameterization, should see no sensitivity to rho and nu at ATM
            var volA = SABR.CalcImpVol_GB(100, 100, 1, 0.32, 0, 0.16);
            var volB = SABR.CalcImpVol_GB(100, 100, 1, 0.32, -0.5, 0.26);

            Assert.Equal(volA, volB, 10);

            //for hagan and berestycki, should see agreement in most cases
            var volHa = SABR.CalcImpVol_Hagan(100, 100, 1, 0.32, 0.9, 0.5, 0.16);
            var volBe = SABR.CalcImpVol_Berestycki(100, 100, 1, 0.32, 0.9, 0.5, 0.16);

            Assert.Equal(volHa, volBe, 5);
            volHa = SABR.CalcImpVol_Hagan(100, 150, 1, 0.32, 0.5, 0.5, 0.16);
            volBe = SABR.CalcImpVol_Berestycki(100, 150, 1, 0.32, 0.5, 0.5, 0.16);
            Assert.Equal(volHa, volBe, 3);
        }
Пример #2
0
        public double GetVolForAbsoluteStrike(double strike, double maturity, double forward)
        {
            var alpha = _alphaInterp.Interpolate(maturity);
            var beta  = _betaInterp.Interpolate(maturity);
            var nu    = _nuInterp.Interpolate(maturity);
            var rho   = _rhoInterp.Interpolate(maturity);
            var fwd   = forward;

            if (beta >= 1.0)
            {
                return(SABR.CalcImpVol_Beta1(fwd, strike, maturity, alpha, rho, nu));
            }
            else
            {
                return(SABR.CalcImpVol_Hagan(fwd, strike, maturity, alpha, beta, rho, nu));
            }
        }
Пример #3
0
 public static double GetVolForAbsoluteStrike(double strike, double maturity, double forward, SABRParameters sabrParams) => sabrParams.Beta >= 1.0
         ? SABR.CalcImpVol_Beta1(forward, strike, maturity, sabrParams.Alpha, sabrParams.Rho, sabrParams.Nu)
         : SABR.CalcImpVol_Hagan(forward, strike, maturity, sabrParams.Alpha, sabrParams.Beta, sabrParams.Rho, sabrParams.Nu);