public SABR(double t, double forward, double alpha, double beta, double nu, double rho,
             bool alphaIsFixed, bool betaIsFixed, bool nuIsFixed, bool rhoIsFixed,
             bool vegaWeighted                         = false,
             EndCriteria endCriteria                   = null,
             OptimizationMethod optMethod              = null,
             double errorAccept                        = 0.0020, bool useMaxError = false, int maxGuesses = 50, double shift = 0.0,
             VolatilityType volatilityType             = VolatilityType.ShiftedLognormal,
             SabrApproximationModel approximationModel = SabrApproximationModel.Hagan2002)
 {
     t_                  = t;
     forward_            = forward;
     alpha_              = alpha;
     beta_               = beta;
     nu_                 = nu;
     rho_                = rho;
     alphaIsFixed_       = alphaIsFixed;
     betaIsFixed_        = betaIsFixed;
     nuIsFixed_          = nuIsFixed;
     rhoIsFixed_         = rhoIsFixed;
     vegaWeighted_       = vegaWeighted;
     endCriteria_        = endCriteria;
     optMethod_          = optMethod;
     errorAccept_        = errorAccept;
     useMaxError_        = useMaxError;
     maxGuesses_         = maxGuesses;
     shift_              = shift;
     volatilityType_     = volatilityType;
     approximationModel_ = approximationModel;
 }
Esempio n. 2
0
File: Sabr.cs Progetto: igitur/qlnet
 public static double sabrVolatility(double strike, double forward, double expiryTime, double alpha, double beta,
                                     double nu, double rho, SabrApproximationModel approximationModel = SabrApproximationModel.Hagan2002)
 {
     QL_REQUIRE(strike > 0.0, () => "strike must be positive: " + strike + " not allowed");
     QL_REQUIRE(forward > 0.0, () => "at the money forward rate must be: " + forward + " not allowed");
     QL_REQUIRE(expiryTime >= 0.0, () => "expiry time must be non-negative: " + expiryTime + " not allowed");
     validateSabrParameters(alpha, beta, nu, rho);
     return(unsafeSabrVolatility(strike, forward, expiryTime, alpha, beta, nu, rho, approximationModel));
 }
Esempio n. 3
0
File: Sabr.cs Progetto: igitur/qlnet
 public static double unsafeShiftedSabrVolatility(double strike,
                                                  double forward,
                                                  double expiryTime,
                                                  double alpha,
                                                  double beta,
                                                  double nu,
                                                  double rho,
                                                  double shift,
                                                  SabrApproximationModel approximationModel = SabrApproximationModel.Hagan2002)
 {
     return(unsafeSabrVolatility(strike + shift, forward + shift, expiryTime,
                                 alpha, beta, nu, rho, approximationModel));
 }
        public SABRInterpolation(List <double> xBegin, // x = strikes
                                 int xEnd,
                                 List <double> yBegin, // y = volatilities
                                 double t,             // option expiry
                                 double forward,
                                 double?alpha,
                                 double?beta,
                                 double?nu,
                                 double?rho,
                                 bool alphaIsFixed,
                                 bool betaIsFixed,
                                 bool nuIsFixed,
                                 bool rhoIsFixed,
                                 bool vegaWeighted            = true,
                                 EndCriteria endCriteria      = null,
                                 OptimizationMethod optMethod = null,
                                 double errorAccept           = 0.0020,
                                 bool useMaxError             = false,
                                 int maxGuesses = 50,
                                 double shift   = 0.0,
                                 VolatilityType volatilityType             = VolatilityType.ShiftedLognormal,
                                 SabrApproximationModel approximationModel = SabrApproximationModel.Hagan2002)
        {
            List <double?> addParams = new List <double?>();

            addParams.Add(shift);
            addParams.Add(volatilityType == VolatilityType.ShiftedLognormal ? 0.0 : 1.0);
            addParams.Add((double?)approximationModel);

            impl_ = new XABRInterpolationImpl <SABRSpecs>(
                xBegin, xEnd, yBegin, t, forward,
                new List <double?>()
            {
                alpha, beta, nu, rho
            },
                //boost::assign::list_of(alpha)(beta)(nu)(rho),
                new List <bool>()
            {
                alphaIsFixed, betaIsFixed, nuIsFixed, rhoIsFixed
            },
                //boost::assign::list_of(alphaIsFixed)(betaIsFixed)(nuIsFixed)(rhoIsFixed),
                vegaWeighted, endCriteria, optMethod, errorAccept, useMaxError,
                maxGuesses, addParams);
            coeffs_ = (impl_ as XABRInterpolationImpl <SABRSpecs>).coeff_;
        }
Esempio n. 5
0
File: Sabr.cs Progetto: igitur/qlnet
        public static double unsafeSabrVolatility(double strike, double forward, double expiryTime, double alpha, double beta,
                                                  double nu, double rho, SabrApproximationModel approximationModel = SabrApproximationModel.Hagan2002)
        {
            if (approximationModel == SabrApproximationModel.Hagan2002)
            {
                double oneMinusBeta = 1.0 - beta;
                double A            = Math.Pow(forward * strike, oneMinusBeta);
                double sqrtA        = Math.Sqrt(A);
                double logM;

                if (!close(forward, strike))
                {
                    logM = Math.Log(forward / strike);
                }
                else
                {
                    double epsilon = (forward - strike) / strike;
                    logM = epsilon - .5 * epsilon * epsilon;
                }
                double z   = (nu / alpha) * sqrtA * logM;
                double B   = 1.0 - 2.0 * rho * z + z * z;
                double C   = oneMinusBeta * oneMinusBeta * logM * logM;
                double tmp = (Math.Sqrt(B) + z - rho) / (1.0 - rho);
                double xx  = Math.Log(tmp);
                double D   = sqrtA * (1.0 + C / 24.0 + C * C / 1920.0);
                double d   = 1.0 + expiryTime *
                             (oneMinusBeta * oneMinusBeta * alpha * alpha / (24.0 * A)
                              + 0.25 * rho * beta * nu * alpha / sqrtA
                              + (2.0 - 3.0 * rho * rho) * (nu * nu / 24.0));

                double multiplier;
                // computations become precise enough if the square of z worth slightly more than the precision machine (hence the m)
                const double m = 10;

                if (Math.Abs(z * z) > Const.QL_EPSILON * m)
                {
                    multiplier = z / xx;
                }
                else
                {
                    multiplier = 1.0 - 0.5 * rho * z - (3.0 * rho * rho - 2.0) * z * z / 12.0;
                }
                return((alpha / D) * multiplier * d);
            }
            else if (approximationModel == SabrApproximationModel.Obloj2008)
            {
                double oneMinusBeta = 1.0 - beta;
                double Fmid         = Math.Sqrt(forward * strike);
                double gamma1       = beta / Fmid;
                double gamma2       = -beta * oneMinusBeta / (Fmid * Fmid);
                double zeta         = alpha / (nu * oneMinusBeta) * (Math.Pow(forward, oneMinusBeta) - Math.Pow(strike, oneMinusBeta));
                double D            = Math.Log((Math.Sqrt(1.0 - 2.0 * rho * zeta + zeta * zeta) + zeta - rho) / (1.0 - rho));
                double epsilon      = alpha * alpha * expiryTime;

                double logM;

                if (!close(forward, strike))
                {
                    logM = Math.Log(forward / strike);
                }
                else
                {
                    double eps = (forward - strike) / strike;
                    logM = eps - .5 * eps * eps;
                }

                double a = nu * Math.Pow(Fmid, beta) / alpha;
                double b = Math.Pow(a, 2.0);
                double d = 1.0 + ((2.0 * gamma2 - gamma1 * gamma1 + 1 / (Fmid * Fmid)) / 24.0 * b
                                  + rho * gamma1 / 4.0 * a
                                  + (2.0 - 3.0 * rho * rho) / 24.0) * epsilon;

                return(alpha * logM / D * d);
            }
            else
            {
                QL_FAIL("Unknown approximation model.");
                return(0.0);
            }
        }