Пример #1
0
        protected override double optionletPrice(Option.Type optionType, double strike)
        {
            ConundrumIntegrand integrand = new ConundrumIntegrand(vanillaOptionPricer_, rateCurve_, gFunction_, fixingDate_, paymentDate_, annuity_, swapRateValue_, strike, optionType);

            stdDeviationsForUpperLimit_ = requiredStdDeviations_;
            double a;
            double b;
            double integralValue;

            if (optionType == Option.Type.Call)
            {
                upperLimit_ = resetUpperLimit(stdDeviationsForUpperLimit_);
                //    while(upperLimit_ <= strike){
                //        stdDeviationsForUpperLimit_ += 1.;
                //        upperLimit_ = resetUpperLimit(stdDeviationsForUpperLimit_);
                //    }
                integralValue = integrate(strike, upperLimit_, integrand);
                //refineIntegration(integralValue, *integrand);
            }
            else
            {
                a             = Math.Min(strike, lowerLimit_);
                b             = strike;
                integralValue = integrate(a, b, integrand);
            }

            double dFdK          = integrand.firstDerivativeOfF(strike);
            double swaptionPrice = vanillaOptionPricer_.value(strike, optionType, annuity_);

            // v. HAGAN, Conundrums..., formule 2.17a, 2.18a
            return(coupon_.accrualPeriod() * (discount_ / annuity_) * ((1 + dFdK) * swaptionPrice + ((int)optionType) * integralValue));
        }
Пример #2
0
        public double integrate(double a, double b, ConundrumIntegrand integrand)
        {
            double result = .0;

            //double abserr =.0;
            //double alpha = 1.0;

            //double epsabs = precision_;
            //double epsrel = 1.0; // we are interested only in absolute precision
            //size_t neval =0;

            // we use the non adaptive algorithm only for semi infinite interval
            if (a > 0)
            {
                // we estimate the actual boudary by testing integrand values
                double upperBoundary = 2 * a;
                while (integrand.value(upperBoundary) > precision_)
                {
                    upperBoundary *= 2.0;
                }
                // sometimes b < a because of a wrong estimation of b based on stdev
                if (b > a)
                {
                    upperBoundary = Math.Min(upperBoundary, b);
                }

                GaussKronrodNonAdaptive gaussKronrodNonAdaptive = new GaussKronrodNonAdaptive(precision_, 1000000, 1.0);
                // if the integration intervall is wide enough we use the
                // following change variable x -> a + (b-a)*(t/(a-b))^3
                upperBoundary = Math.Max(a, Math.Min(upperBoundary, hardUpperLimit_));
                if (upperBoundary > 2 * a)
                {
                    VariableChange variableChange = new VariableChange(integrand.value, a, upperBoundary, 3);
                    result = gaussKronrodNonAdaptive.value(variableChange.value, .0, 1.0);
                }
                else
                {
                    result = gaussKronrodNonAdaptive.value(integrand.value, a, upperBoundary);
                }

                // if the expected precision has not been reached we use the old algorithm
                if (!gaussKronrodNonAdaptive.integrationSuccess())
                {
                    GaussKronrodAdaptive integrator = new GaussKronrodAdaptive(precision_, 100000);
                    b      = Math.Max(a, Math.Min(b, hardUpperLimit_));
                    result = integrator.value(integrand.value, a, b);
                }
            } // if a < b we use the old algorithm
            else
            {
                b = Math.Max(a, Math.Min(b, hardUpperLimit_));
                GaussKronrodAdaptive integrator = new GaussKronrodAdaptive(precision_, 100000);
                result = integrator.value(integrand.value, a, b);
            }
            return(result);
        }
Пример #3
0
        public double refineIntegration(double integralValue, ConundrumIntegrand integrand)
        {
            double percDiff = 1000.0;

            while (Math.Abs(percDiff) < refiningIntegrationTolerance_)
            {
                stdDeviationsForUpperLimit_ += 1.0;
                double lowerLimit = upperLimit_;
                upperLimit_ = resetUpperLimit(stdDeviationsForUpperLimit_);
                double diff = integrate(lowerLimit, upperLimit_, integrand);
                percDiff       = diff / integralValue;
                integralValue += diff;
            }
            return(integralValue);
        }
Пример #4
0
 public double refineIntegration(double integralValue, ConundrumIntegrand integrand) {
     double percDiff = 1000.0;
     while (Math.Abs(percDiff) < refiningIntegrationTolerance_) {
         stdDeviationsForUpperLimit_ += 1.0;
         double lowerLimit = upperLimit_;
         upperLimit_ = resetUpperLimit(stdDeviationsForUpperLimit_);
         double diff = integrate(lowerLimit, upperLimit_, integrand);
         percDiff = diff / integralValue;
         integralValue += diff;
     }
     return integralValue;
 }
Пример #5
0
        public double integrate(double a, double b, ConundrumIntegrand integrand) {
            double result = .0;
            //double abserr =.0;
            //double alpha = 1.0;

            //double epsabs = precision_;
            //double epsrel = 1.0; // we are interested only in absolute precision
            //size_t neval =0;

            // we use the non adaptive algorithm only for semi infinite interval
            if (a > 0) {
                // we estimate the actual boudary by testing integrand values
                double upperBoundary = 2 * a;
                while (integrand.value(upperBoundary) > precision_)
                    upperBoundary *= 2.0;
                // sometimes b < a because of a wrong estimation of b based on stdev
                if (b > a)
                    upperBoundary = Math.Min(upperBoundary, b);

                GaussKronrodNonAdaptive gaussKronrodNonAdaptive = new GaussKronrodNonAdaptive(precision_, 1000000, 1.0);
                // if the integration intervall is wide enough we use the
                // following change variable x -> a + (b-a)*(t/(a-b))^3
                if (upperBoundary > 2 * a) {
                    VariableChange variableChange = new VariableChange(integrand.value, a, upperBoundary, 3);
                    result = gaussKronrodNonAdaptive.value(variableChange.value, .0, 1.0);
                } else {
                    result = gaussKronrodNonAdaptive.value(integrand.value, a, upperBoundary);
                }

                // if the expected precision has not been reached we use the old algorithm
                if (!gaussKronrodNonAdaptive.integrationSuccess()) {
                    GaussKronrodAdaptive integrator = new GaussKronrodAdaptive(precision_, 1000000);
                    result = integrator.value(integrand.value, a, b);
                }
            } // if a < b we use the old algorithm
            else {
                GaussKronrodAdaptive integrator = new GaussKronrodAdaptive(precision_, 1000000);
                result = integrator.value(integrand.value, a, b);
            }
            return result;
        }
Пример #6
0
        protected override double optionletPrice(Option.Type optionType, double strike) {
            ConundrumIntegrand integrand = new ConundrumIntegrand(vanillaOptionPricer_, rateCurve_, gFunction_, fixingDate_, paymentDate_, annuity_, swapRateValue_, strike, optionType);
            stdDeviationsForUpperLimit_ = requiredStdDeviations_;
            double a;
            double b;
            double integralValue;
            if (optionType == Option.Type.Call) {
                upperLimit_ = resetUpperLimit(stdDeviationsForUpperLimit_);
                //    while(upperLimit_ <= strike){
                //        stdDeviationsForUpperLimit_ += 1.;
                //        upperLimit_ = resetUpperLimit(stdDeviationsForUpperLimit_);
                //    }
                integralValue = integrate(strike, upperLimit_, integrand);
                //refineIntegration(integralValue, *integrand);
            } else {
                a = Math.Min(strike, lowerLimit_);
                b = strike;
                integralValue = integrate(a, b, integrand);
            }

            double dFdK = integrand.firstDerivativeOfF(strike);
            double swaptionPrice = vanillaOptionPricer_.value(strike, optionType, annuity_);

            // v. HAGAN, Conundrums..., formule 2.17a, 2.18a
            return coupon_.accrualPeriod() * (discount_ / annuity_) * ((1 + dFdK) * swaptionPrice + ((int)optionType) * integralValue);
        }