public InverseNonCentralChiSquareDistribution(double df, double ncp, int maxEvaluations, double accuracy) { nonCentralDist_ = new NonCentralChiSquareDistribution(df, ncp); guess_ = df + ncp; maxEvaluations_ = maxEvaluations; accuracy_ = accuracy; }
public override double discountBondOption(Option.Type type, double strike, double maturity, double bondMaturity) { Utils.QL_REQUIRE(strike > 0.0, () => "strike must be positive"); double discountT = discountBond(0.0, maturity, x0()); double discountS = discountBond(0.0, bondMaturity, x0()); if (maturity < Const.QL_EPSILON) { switch (type) { case Option.Type.Call: return(Math.Max(discountS - strike, 0.0)); case Option.Type.Put: return(Math.Max(strike - discountS, 0.0)); default: Utils.QL_FAIL("unsupported option type"); break; } } double sigma2 = sigma() * sigma(); double h = Math.Sqrt(k() * k() + 2.0 * sigma2); double b = B(maturity, bondMaturity); double rho = 2.0 * h / (sigma2 * (Math.Exp(h * maturity) - 1.0)); double psi = (k() + h) / sigma2; double df = 4.0 * k() * theta() / sigma2; double ncps = 2.0 * rho * rho * x0() * Math.Exp(h * maturity) / (rho + psi + b); double ncpt = 2.0 * rho * rho * x0() * Math.Exp(h * maturity) / (rho + psi); NonCentralChiSquareDistribution chis = new NonCentralChiSquareDistribution(df, ncps); NonCentralChiSquareDistribution chit = new NonCentralChiSquareDistribution(df, ncpt); double z = Math.Log(A(maturity, bondMaturity) / strike) / b; double call = discountS * chis.value(2.0 * z * (rho + psi + b)) - strike * discountT * chit.value(2.0 * z * (rho + psi)); if (type == Option.Type.Call) { return(call); } else { return(call - discountS + strike * discountT); } }