protected ZeroYieldStructure(int settlementDays, Calendar calendar, DayCounter dc = null,
                              List <Handle <Quote> > jumps = null, List <Date> jumpDates = null)
     : base(settlementDays, calendar, dc, jumps, jumpDates)
 {
 }
        public override void calculate()
        {
            Utils.QL_REQUIRE(arguments_.accruedCoupon == null &&
                             arguments_.lastFixing == null, () =>
                             "this engine cannot price options already started");
            Utils.QL_REQUIRE(arguments_.localCap == null &&
                             arguments_.localFloor == null &&
                             arguments_.globalCap == null &&
                             arguments_.globalFloor == null, () =>
                             "this engine cannot price capped/floored options");

            Utils.QL_REQUIRE(arguments_.exercise.type() == Exercise.Type.European, () => "not an European option");

            PercentageStrikePayoff moneyness = arguments_.payoff as PercentageStrikePayoff;

            Utils.QL_REQUIRE(moneyness != null, () => "wrong payoff given");

            List <Date> resetDates = arguments_.resetDates;

            resetDates.Add(arguments_.exercise.lastDate());

            double underlying = process_.stateVariable().link.value();

            Utils.QL_REQUIRE(underlying > 0.0, () => "negative or null underlying");
            double            strike = underlying * moneyness.strike();
            StrikedTypePayoff payoff = new PlainVanillaPayoff(moneyness.optionType(), strike);

            results_.value = 0.0;
            results_.delta = results_.gamma = 0.0;
            results_.theta = 0.0;
            results_.rho   = results_.dividendRho = 0.0;
            results_.vega  = 0.0;

            for (int i = 1; i < resetDates.Count; i++)
            {
                double weight   = process_.dividendYield().link.discount(resetDates[i - 1]);
                double discount = process_.riskFreeRate().link.discount(resetDates[i]) /
                                  process_.riskFreeRate().link.discount(resetDates[i - 1]);
                double qDiscount = process_.dividendYield().link.discount(resetDates[i]) /
                                   process_.dividendYield().link.discount(resetDates[i - 1]);
                double forward  = underlying * qDiscount / discount;
                double variance = process_.blackVolatility().link.blackForwardVariance(resetDates[i - 1], resetDates[i], strike);

                BlackCalculator black = new BlackCalculator(payoff, forward, Math.Sqrt(variance), discount);

                DayCounter rfdc  = process_.riskFreeRate().link.dayCounter();
                DayCounter divdc = process_.dividendYield().link.dayCounter();
                DayCounter voldc = process_.blackVolatility().link.dayCounter();

                results_.value += weight * black.value();
                results_.delta += weight * (black.delta(underlying) +
                                            moneyness.strike() * discount *
                                            black.beta());
                results_.gamma += 0.0;
                results_.theta += process_.dividendYield().link.forwardRate(
                    resetDates[i - 1], resetDates[i], rfdc, Compounding.Continuous, Frequency.NoFrequency).value() *
                                  weight * black.value();

                double dt = rfdc.yearFraction(resetDates[i - 1], resetDates[i]);
                results_.rho += weight * black.rho(dt);

                double t = divdc.yearFraction(process_.dividendYield().link.referenceDate(), resetDates[i - 1]);
                dt = divdc.yearFraction(resetDates[i - 1], resetDates[i]);
                results_.dividendRho += weight * (black.dividendRho(dt) -
                                                  t * black.value());

                dt             = voldc.yearFraction(resetDates[i - 1], resetDates[i]);
                results_.vega += weight * black.vega(dt);
            }
        }
 protected ZeroYieldStructure(DayCounter dc = null, List <Handle <Quote> > jumps = null, List <Date> jumpDates = null)
     : base(dc, jumps, jumpDates)
 {
 }
 protected ZeroYieldStructure(Date referenceDate, Calendar calendar = null, DayCounter dc         = null,
                              List <Handle <Quote> > jumps          = null, List <Date> jumpDates = null)
     : base(referenceDate, calendar, dc, jumps, jumpDates)
 {
 }
        public InterpolatedHazardRateCurve(List <Date> dates, List <double> hazardRates, DayCounter dayCounter, Calendar cal = null,
                                           List <Handle <Quote> > jumps = null, List <Date> jumpDates = null, Interpolator interpolator = default(Interpolator))
            : base(dates[0], cal, dayCounter, jumps, jumpDates)
        {
            dates_ = dates;
            times_ = new List <double>();
            data_  = hazardRates;

            if (interpolator == null)
            {
                interpolator_ = FastActivator <Interpolator> .Create();
            }
            else
            {
                interpolator_ = interpolator;
            }

            initialize();
        }
 public InterpolatedHazardRateCurve(List <Date> dates, List <double> hazardRates, DayCounter dayCounter, Interpolator interpolator)
     : base(dates[0], null, dayCounter)
 {
     dates_ = dates;
     if (interpolator == null)
     {
         interpolator_ = FastActivator <Interpolator> .Create();
     }
     else
     {
         interpolator_ = interpolator;
     }
     initialize();
 }
Beispiel #7
0
        public override void calculate()
        {
            Utils.QL_REQUIRE(arguments_.exercise.type() == Exercise.Type.American, () => "not an American Option");

            AmericanExercise ex = arguments_.exercise as AmericanExercise;

            Utils.QL_REQUIRE(ex != null, () => "non-American exercise given");

            Utils.QL_REQUIRE(!ex.payoffAtExpiry(), () => "payoff at expiry not handled");

            PlainVanillaPayoff payoff = arguments_.payoff as PlainVanillaPayoff;

            Utils.QL_REQUIRE(payoff != null, () => "non-plain payoff given");

            double variance         = process_.blackVolatility().link.blackVariance(ex.lastDate(), payoff.strike());
            double dividendDiscount = process_.dividendYield().link.discount(ex.lastDate());
            double riskFreeDiscount = process_.riskFreeRate().link.discount(ex.lastDate());

            double spot = process_.stateVariable().link.value();

            Utils.QL_REQUIRE(spot > 0.0, () => "negative or null underlying given");

            double strike = payoff.strike();

            if (payoff.optionType() == Option.Type.Put)
            {
                // use put-call simmetry
                Utils.swap <double>(ref spot, ref strike);
                Utils.swap <double>(ref riskFreeDiscount, ref dividendDiscount);
                payoff = new PlainVanillaPayoff(Option.Type.Call, strike);
            }

            if (dividendDiscount >= 1.0)
            {
                // early exercise is never optimal - use Black formula
                double          forwardPrice = spot * dividendDiscount / riskFreeDiscount;
                BlackCalculator black        = new BlackCalculator(payoff, forwardPrice, Math.Sqrt(variance), riskFreeDiscount);

                results_.value        = black.value();
                results_.delta        = black.delta(spot);
                results_.deltaForward = black.deltaForward();
                results_.elasticity   = black.elasticity(spot);
                results_.gamma        = black.gamma(spot);

                DayCounter rfdc  = process_.riskFreeRate().link.dayCounter();
                DayCounter divdc = process_.dividendYield().link.dayCounter();
                DayCounter voldc = process_.blackVolatility().link.dayCounter();
                double     t     = rfdc.yearFraction(process_.riskFreeRate().link.referenceDate(), arguments_.exercise.lastDate());
                results_.rho = black.rho(t);

                t = divdc.yearFraction(process_.dividendYield().link.referenceDate(), arguments_.exercise.lastDate());
                results_.dividendRho = black.dividendRho(t);

                t                    = voldc.yearFraction(process_.blackVolatility().link.referenceDate(), arguments_.exercise.lastDate());
                results_.vega        = black.vega(t);
                results_.theta       = black.theta(spot, t);
                results_.thetaPerDay = black.thetaPerDay(spot, t);

                results_.strikeSensitivity  = black.strikeSensitivity();
                results_.itmCashProbability = black.itmCashProbability();
            }
            else
            {
                // early exercise can be optimal - use approximation
                results_.value = americanCallApproximation(spot, strike, riskFreeDiscount, dividendDiscount, variance);
            }
        }
 protected internal InterpolatedHazardRateCurve(int settlementDays, Calendar cal, DayCounter dc,
                                                List <Handle <Quote> > jumps = null,
                                                List <Date> jumpDates        = null,
                                                Interpolator interpolator    = default(Interpolator))
     : base(settlementDays, cal, dc, jumps, jumpDates)
 {
 }
 //! calculate the reference date based on the global evaluation date
 protected BlackVolTermStructure(int settlementDays, Calendar cal, BusinessDayConvention bdc = BusinessDayConvention.Following,
                                 DayCounter dc = null)
     : base(settlementDays, cal, bdc, dc)
 {
 }
 //! initialize with a fixed reference date
 protected BlackVolTermStructure(Date referenceDate, Calendar cal = null,
                                 BusinessDayConvention bdc        = BusinessDayConvention.Following, DayCounter dc = null)
     : base(referenceDate, cal, bdc, dc)
 {
 }
        //! default constructor

        /*! \warning term structures initialized by means of this
         *           constructor must manage their own reference date
         *           by overriding the referenceDate() method.
         */

        protected BlackVolTermStructure(BusinessDayConvention bdc = BusinessDayConvention.Following, DayCounter dc = null)
            : base(bdc, dc)
        {
        }
        public DiscretizedSwaption(Swaption.Arguments args,
                                   Date referenceDate,
                                   DayCounter dayCounter)
            : base(new DiscretizedSwap(args, referenceDate, dayCounter), args.exercise.type(), new List <double>())
        {
            arguments_     = args;
            exerciseTimes_ = new InitializedList <double>(arguments_.exercise.dates().Count);
            for (int i = 0; i < exerciseTimes_.Count; ++i)
            {
                exerciseTimes_[i] =
                    dayCounter.yearFraction(referenceDate,
                                            arguments_.exercise.date(i));
            }

            // Date adjustments can get time vectors out of synch.
            // Here, we try and collapse similar dates which could cause
            // a mispricing.
            for (int i = 0; i < arguments_.exercise.dates().Count; i++)
            {
                Date exerciseDate = arguments_.exercise.date(i);
                for (int j = 0; j < arguments_.fixedPayDates.Count; j++)
                {
                    if (withinNextWeek(exerciseDate,
                                       arguments_.fixedPayDates[j])
                        // coupons in the future are dealt with below
                        && arguments_.fixedResetDates[j] < referenceDate)
                    {
                        arguments_.fixedPayDates[j] = exerciseDate;
                    }
                }
                for (int j = 0; j < arguments_.fixedResetDates.Count; j++)
                {
                    if (withinPreviousWeek(exerciseDate,
                                           arguments_.fixedResetDates[j]))
                    {
                        arguments_.fixedResetDates[j] = exerciseDate;
                    }
                }
                for (int j = 0; j < arguments_.floatingResetDates.Count; j++)
                {
                    if (withinPreviousWeek(exerciseDate,
                                           arguments_.floatingResetDates[j]))
                    {
                        arguments_.floatingResetDates[j] = exerciseDate;
                    }
                }
            }

            double lastFixedPayment =
                dayCounter.yearFraction(referenceDate,
                                        arguments_.fixedPayDates.Last());
            double lastFloatingPayment =
                dayCounter.yearFraction(referenceDate,
                                        arguments_.floatingPayDates.Last());

            lastPayment_ = Math.Max(lastFixedPayment, lastFloatingPayment);

            underlying_ = new DiscretizedSwap(arguments_,
                                              referenceDate,
                                              dayCounter);
        }
        // required for Handle
        public BlackVarianceCurve(Date referenceDate, List <Date> dates, List <double> blackVolCurve, DayCounter dayCounter,
                                  bool forceMonotoneVariance)
            : base(referenceDate)
        {
            dayCounter_ = dayCounter;
            maxDate_    = dates.Last();

            Utils.QL_REQUIRE(dates.Count == blackVolCurve.Count, () => "mismatch between date vector and black vol vector");

            // cannot have dates[0]==referenceDate, since the
            // value of the vol at dates[0] would be lost
            // (variance at referenceDate must be zero)
            Utils.QL_REQUIRE(dates[0] > referenceDate, () => "cannot have dates[0] <= referenceDate");

            variances_    = new InitializedList <double>(dates.Count + 1);
            times_        = new InitializedList <double>(dates.Count + 1);
            variances_[0] = 0.0;
            times_[0]     = 0.0;
            for (int j = 1; j <= blackVolCurve.Count; j++)
            {
                times_[j] = timeFromReference(dates[j - 1]);

                Utils.QL_REQUIRE(times_[j] > times_[j - 1], () => "dates must be sorted unique!");
                variances_[j] = times_[j] * blackVolCurve[j - 1] * blackVolCurve[j - 1];
                Utils.QL_REQUIRE(variances_[j] >= variances_[j - 1] || !forceMonotoneVariance, () => "variance must be non-decreasing");
            }

            // default: linear interpolation
            setInterpolation <Linear>();
        }