示例#1
0
        //! Implied internal rate of return.
        // The function verifies
        // the theoretical existance of an IRR and numerically
        // establishes the IRR to the desired precision.
        public static double yield(Leg leg, double npv, DayCounter dayCounter, Compounding compounding, Frequency frequency,
                                   bool includeSettlementDateFlows, Date settlementDate = null, Date npvDate = null,
                                   double accuracy = 1.0e-10, int maxIterations = 100, double guess = 0.05)
        {
            NewtonSafe solver = new NewtonSafe();

            solver.setMaxEvaluations(maxIterations);
            IrrFinder objFunction = new IrrFinder(leg, npv,
                                                  dayCounter, compounding, frequency,
                                                  includeSettlementDateFlows,
                                                  settlementDate, npvDate);

            return(solver.solve(objFunction, accuracy, guess, guess / 10.0));
        }
示例#2
0
        //! implied volatility
        public double impliedVolatility(double targetValue,
                                        Handle <YieldTermStructure> discountCurve,
                                        double guess,
                                        double accuracy     = 1.0e-4,
                                        int maxEvaluations  = 100,
                                        double minVol       = 1.0e-7,
                                        double maxVol       = 4.0,
                                        VolatilityType type = VolatilityType.ShiftedLognormal,
                                        double?displacement = 0.0)
        {
            calculate();
            if (isExpired())
            {
                throw new ArgumentException("instrument expired");
            }
            ImpliedVolHelper_ f      = new ImpliedVolHelper_(this, discountCurve, targetValue, displacement, type);
            NewtonSafe        solver = new NewtonSafe();

            solver.setMaxEvaluations(maxEvaluations);
            return(solver.solve(f, accuracy, guess, minVol, maxVol));
        }
示例#3
0
        protected override double solveImpl(ISolver1d f, double xAccuracy)
        {
            /* The implementation of the algorithm was inspired by Press, Teukolsky, Vetterling, and Flannery,
             * "Numerical Recipes in C", 2nd edition, Cambridge University Press */

            double froot, dfroot, dx;

            froot  = f.value(root_);
            dfroot = f.derivative(root_);

            if (dfroot.IsEqual(default(double)))
            {
                throw new ArgumentException("Newton requires function's derivative");
            }
            ++evaluationNumber_;

            while (evaluationNumber_ <= maxEvaluations_)
            {
                dx     = froot / dfroot;
                root_ -= dx;
                // jumped out of brackets, switch to NewtonSafe
                if ((xMin_ - root_) * (root_ - xMax_) < 0.0)
                {
                    NewtonSafe s = new NewtonSafe();
                    s.setMaxEvaluations(maxEvaluations_ - evaluationNumber_);
                    return(s.solve(f, xAccuracy, root_ + dx, xMin_, xMax_));
                }
                if (Math.Abs(dx) < xAccuracy)
                {
                    return(root_);
                }
                froot  = f.value(root_);
                dfroot = f.derivative(root_);
                evaluationNumber_++;
            }

            Utils.QL_FAIL("maximum number of function evaluations (" + maxEvaluations_ + ") exceeded",
                          QLNetExceptionEnum.MaxNumberFuncEvalExceeded);
            return(0);
        }
示例#4
0
        public double impliedVolatility(
            double targetValue,
            Handle <YieldTermStructure> discountCurve,
            double guess,
            double accuracy,
            int maxEvaluations,
            double minVol,
            double maxVol,
            VolatilityType type,
            double displacement)
        {
            calculate();
            if (isExpired())
            {
                throw new ArgumentException("instrument expired");
            }

            ImpliedVolHelper f      = new ImpliedVolHelper(this, discountCurve, targetValue, displacement, type);
            NewtonSafe       solver = new NewtonSafe();

            solver.setMaxEvaluations(maxEvaluations);
            return(solver.solve(f, accuracy, guess, minVol, maxVol));
        }
示例#5
0
        /*! Black 1976 implied standard deviation,
         *    i.e. volatility*sqrt(timeToMaturity)
         */
        public static double blackFormulaImpliedStdDev(Option.Type optionType,
                                                       double strike,
                                                       double forward,
                                                       double blackPrice,
                                                       double discount     = 1.0,
                                                       double displacement = 0.0,
                                                       double?guess        = null,
                                                       double accuracy     = 1.0e-6,
                                                       int maxIterations   = 100)
        {
            checkParameters(strike, forward, displacement);

            QL_REQUIRE(discount > 0.0, () =>
                       "discount (" + discount + ") must be positive");

            QL_REQUIRE(blackPrice >= 0.0, () =>
                       "option price (" + blackPrice + ") must be non-negative");
            // check the price of the "other" option implied by put-call paity
            double otherOptionPrice = blackPrice - (int)optionType * (forward - strike) * discount;

            QL_REQUIRE(otherOptionPrice >= 0.0, () =>
                       "negative " + (-1 * (int)optionType) +
                       " price (" + otherOptionPrice +
                       ") implied by put-call parity. No solution exists for " +
                       optionType + " strike " + strike +
                       ", forward " + forward +
                       ", price " + blackPrice +
                       ", deflator " + discount);

            // solve for the out-of-the-money option which has
            // greater vega/price ratio, i.e.
            // it is numerically more robust for implied vol calculations
            if (optionType == Option.Type.Put && strike > forward)
            {
                optionType = Option.Type.Call;
                blackPrice = otherOptionPrice;
            }
            if (optionType == Option.Type.Call && strike < forward)
            {
                optionType = Option.Type.Put;
                blackPrice = otherOptionPrice;
            }

            strike  = strike + displacement;
            forward = forward + displacement;

            if (guess == null)
            {
                guess = blackFormulaImpliedStdDevApproximation(optionType, strike, forward, blackPrice, discount, displacement);
            }
            else
            {
                QL_REQUIRE(guess >= 0.0, () => "stdDev guess (" + guess + ") must be non-negative");
            }

            BlackImpliedStdDevHelper f = new BlackImpliedStdDevHelper(optionType, strike, forward, blackPrice / discount);
            NewtonSafe solver          = new NewtonSafe();

            solver.setMaxEvaluations(maxIterations);
            double minSdtDev = 0.0, maxStdDev = 24.0; // 24 = 300% * sqrt(60)
            double stdDev = solver.solve(f, accuracy, guess.Value, minSdtDev, maxStdDev);

            QL_REQUIRE(stdDev >= 0.0, () => "stdDev (" + stdDev + ") must be non-negative");
            return(stdDev);
        }