示例#1
0
        public override void calculate()
        {
            Utils.QL_REQUIRE(arguments_.settlementMethod != Settlement.Method.ParYieldCurve, () =>
                             "cash-settled (ParYieldCurve) swaptions not priced with Lfm engine");

            VanillaSwap    swap = arguments_.swap;
            IPricingEngine pe   = new DiscountingSwapEngine(discountCurve_);

            swap.setPricingEngine(pe);

            double correction = swap.spread *
                                Math.Abs(swap.floatingLegBPS() / swap.fixedLegBPS());
            double fixedRate = swap.fixedRate - correction;
            double fairRate  = swap.fairRate() - correction;

            SwaptionVolatilityMatrix volatility =
                model_.link.getSwaptionVolatilityMatrix();

            Date       referenceDate = volatility.referenceDate();
            DayCounter dayCounter    = volatility.dayCounter();

            double exercise = dayCounter.yearFraction(referenceDate,
                                                      arguments_.exercise.date(0));
            double swapLength =
                dayCounter.yearFraction(referenceDate,
                                        arguments_.fixedPayDates.Last())
                - dayCounter.yearFraction(referenceDate,
                                          arguments_.fixedResetDates[0]);

            Option.Type w = arguments_.type == VanillaSwap.Type.Payer ?
                            Option.Type.Call : Option.Type.Put;
            double vol = volatility.volatility(exercise, swapLength,
                                               fairRate, true);

            results_.value = (swap.fixedLegBPS() / Const.BASIS_POINT) *
                             Utils.blackFormula(w, fixedRate, fairRate, vol * Math.Sqrt(exercise));
        }
示例#2
0
        public override void calculate()
        {
            Utils.QL_REQUIRE(arguments_.settlementType == Settlement.Type.Physical, () =>
                             "cash-settled swaptions not priced with G2 engine");

            // adjust the fixed rate of the swap for the spread on the
            // floating leg (which is not taken into account by the
            // model)
            VanillaSwap swap = arguments_.swap;

            swap.setPricingEngine(new DiscountingSwapEngine(model_.link.termStructure()));
            double correction = swap.spread *
                                Math.Abs(swap.floatingLegBPS() / swap.fixedLegBPS());
            double fixedRate = swap.fixedRate - correction;

            results_.value = model_.link.swaption(arguments_, fixedRate,
                                                  range_, intervals_);
        }
        public override void calculate()
        {
            Date exerciseDate = arguments_.exercise.date(0);

            // the part of the swap preceding exerciseDate should be truncated
            // to avoid taking into account unwanted cashflows
            // for the moment we add a check avoiding this situation
            VanillaSwap swap = arguments_.swap;

            double          strike      = swap.fixedRate;
            List <CashFlow> fixedLeg    = swap.fixedLeg();
            FixedRateCoupon firstCoupon = fixedLeg[0] as FixedRateCoupon;

            Utils.QL_REQUIRE(firstCoupon != null, () => "wrong coupon type");

            Utils.QL_REQUIRE(firstCoupon.accrualStartDate() >= exerciseDate,
                             () => "swap start (" + firstCoupon.accrualStartDate() + ") before exercise date ("
                             + exerciseDate + ") not supported in Black swaption engine");

            // using the forecasting curve
            swap.setPricingEngine(new DiscountingSwapEngine(swap.iborIndex().forwardingTermStructure()));
            double atmForward = swap.fairRate();

            // Volatilities are quoted for zero-spreaded swaps.
            // Therefore, any spread on the floating leg must be removed
            // with a corresponding correction on the fixed leg.
            if (swap.spread.IsNotEqual(0.0))
            {
                double correction = swap.spread * Math.Abs(swap.floatingLegBPS() / swap.fixedLegBPS());
                strike     -= correction;
                atmForward -= correction;
                results_.additionalResults["spreadCorrection"] = correction;
            }
            else
            {
                results_.additionalResults["spreadCorrection"] = 0.0;
            }
            results_.additionalResults["strike"]     = strike;
            results_.additionalResults["atmForward"] = atmForward;

            // using the discounting curve
            swap.setPricingEngine(new DiscountingSwapEngine(discountCurve_, false));
            double annuity = 0;

            if (arguments_.settlementType == Settlement.Type.Physical ||
                (arguments_.settlementType == Settlement.Type.Cash &&
                 arguments_.settlementMethod == Settlement.Method.CollateralizedCashPrice))
            {
                annuity = Math.Abs(swap.fixedLegBPS()) / Const.BASIS_POINT;
            }
            else if (arguments_.settlementType == Settlement.Type.Cash &&
                     arguments_.settlementMethod == Settlement.Method.ParYieldCurve)
            {
                DayCounter dayCount = firstCoupon.dayCounter();

                // we assume that the cash settlement date is equal
                // to the swap start date
                Date discountDate = model_ == CashAnnuityModel.DiscountCurve
                                ? firstCoupon.accrualStartDate()
                                : discountCurve_.link.referenceDate();

                double fixedLegCashBPS =
                    CashFlows.bps(fixedLeg,
                                  new InterestRate(atmForward, dayCount, Compounding.Compounded, Frequency.Annual), false,
                                  discountDate);

                annuity = Math.Abs(fixedLegCashBPS / Const.BASIS_POINT) * discountCurve_.link.discount(discountDate);
            }
            else
            {
                Utils.QL_FAIL("unknown settlement type");
            }
            results_.additionalResults["annuity"] = annuity;

            double swapLength = vol_.link.swapLength(swap.floatingSchedule().dates().First(),
                                                     swap.floatingSchedule().dates().Last());

            results_.additionalResults["swapLength"] = swapLength;

            double variance = vol_.link.blackVariance(exerciseDate,
                                                      swapLength,
                                                      strike);
            double displacement = displacement_ == null
                               ? vol_.link.shift(exerciseDate, swapLength)
                               : Convert.ToDouble(displacement_);

            double stdDev = Math.Sqrt(variance);

            results_.additionalResults["stdDev"] = stdDev;
            Option.Type w = (arguments_.type == VanillaSwap.Type.Payer) ? Option.Type.Call : Option.Type.Put;
            results_.value = new Spec().value(w, strike, atmForward, stdDev, annuity, displacement);

            double exerciseTime = vol_.link.timeFromReference(exerciseDate);

            results_.additionalResults["vega"] =
                new Spec().vega(strike, atmForward, stdDev, exerciseTime, annuity, displacement);
        }
示例#4
0
        public override void initialize(FloatingRateCoupon coupon)
        {
            coupon_ = coupon as CmsCoupon;
            Utils.QL_REQUIRE(coupon_ != null, () => "CMS coupon needed");
            gearing_ = coupon_.gearing();
            spread_  = coupon_.spread();

            fixingDate_  = coupon_.fixingDate();
            paymentDate_ = coupon_.date();
            SwapIndex swapIndex = coupon_.swapIndex();

            rateCurve_ = swapIndex.forwardingTermStructure().link;

            Date today = Settings.Instance.evaluationDate();

            if (paymentDate_ > today)
            {
                discount_ = rateCurve_.discount(paymentDate_);
            }
            else
            {
                discount_ = 1.0;
            }

            spreadLegValue_ = spread_ * coupon_.accrualPeriod() * discount_;

            if (fixingDate_ > today)
            {
                swapTenor_ = swapIndex.tenor();
                VanillaSwap swap = swapIndex.underlyingSwap(fixingDate_);

                swapRateValue_ = swap.fairRate();

                annuity_ = Math.Abs(swap.fixedLegBPS() / Const.BASIS_POINT);

                int        q                    = (int)swapIndex.fixedLegTenor().frequency();
                Schedule   schedule             = swap.fixedSchedule();
                DayCounter dc                   = swapIndex.dayCounter();
                double     startTime            = dc.yearFraction(rateCurve_.referenceDate(), swap.startDate());
                double     swapFirstPaymentTime = dc.yearFraction(rateCurve_.referenceDate(), schedule.date(1));
                double     paymentTime          = dc.yearFraction(rateCurve_.referenceDate(), paymentDate_);
                double     delta                = (paymentTime - startTime) / (swapFirstPaymentTime - startTime);

                switch (modelOfYieldCurve_)
                {
                case GFunctionFactory.YieldCurveModel.Standard:
                    gFunction_ = GFunctionFactory.newGFunctionStandard(q, delta, swapTenor_.length());
                    break;

                case GFunctionFactory.YieldCurveModel.ExactYield:
                    gFunction_ = GFunctionFactory.newGFunctionExactYield(coupon_);
                    break;

                case GFunctionFactory.YieldCurveModel.ParallelShifts:
                {
                    Handle <Quote> nullMeanReversionQuote = new Handle <Quote>(new SimpleQuote(0.0));
                    gFunction_ = GFunctionFactory.newGFunctionWithShifts(coupon_, nullMeanReversionQuote);
                }
                break;

                case GFunctionFactory.YieldCurveModel.NonParallelShifts:
                    gFunction_ = GFunctionFactory.newGFunctionWithShifts(coupon_, meanReversion_);
                    break;

                default:
                    Utils.QL_FAIL("unknown/illegal gFunction type");
                    break;
                }
                vanillaOptionPricer_ = new BlackVanillaOptionPricer(swapRateValue_, fixingDate_, swapTenor_, swaptionVolatility().link);
            }
        }