Example #1
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_);
        }
Example #2
0
        ////////////////////////////////////////////////////
        //! RateHelper interface
        public override double impliedQuote()
        {
            if (termStructure_ == null)
            {
                throw new ArgumentException("term structure not set");
            }
            // we didn't register as observers - force calculation
            swap_.recalculate();                // it is from lazy objects
            // weak implementation... to be improved
            const double basisPoint     = 1.0e-4;
            double       floatingLegNPV = swap_.floatingLegNPV();
            double       spread         = this.spread();
            double       spreadNPV      = swap_.floatingLegBPS() / basisPoint * spread;
            double       totNPV         = -(floatingLegNPV + spreadNPV);
            double       result         = totNPV / (swap_.fixedLegBPS() / basisPoint);

            return(result);
        }
Example #3
0
        public override void calculate()
        {
            if (!(arguments_.settlementType == Settlement.Type.Physical))
            {
                throw new ApplicationException("cash-settled swaptions not priced with Lfm engine");
            }

            double basisPoint = 1.0e-4;

            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_.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() / basisPoint) *
                             Utils.blackFormula(w, fixedRate, fairRate, vol * Math.Sqrt(exercise));
        }
Example #4
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));
        }
Example #5
0
        public override void calculate()
        {
            double basisPoint = 1.0e-4;

            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;

            switch (arguments_.settlementType)
            {
            case Settlement.Type.Physical:
            {
                annuity = Math.Abs(swap.fixedLegBPS()) / basisPoint;
                break;
            }

            case Settlement.Type.Cash:
            {
                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 / basisPoint) * discountCurve_.link.discount(discountDate);
                break;
            }

            default:
                Utils.QL_FAIL("unknown settlement type");
                break;
            }
            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);
        }
Example #6
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.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();

                double bp = 1.0e-4;
                annuity_ = (swap.floatingLegBPS() / bp);

                int        q        = (int)swapIndex.fixedLegTenor().frequency();
                Schedule   schedule = swap.fixedSchedule();
                DayCounter dc       = swapIndex.dayCounter();
                //DayCounter dc = coupon.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:
                    throw new ApplicationException("unknown/illegal gFunction type");
                }
                vanillaOptionPricer_ = new BlackVanillaOptionPricer(swapRateValue_, fixingDate_, swapTenor_, swaptionVolatility().link);
            }
        }
Example #7
0
        public override void calculate()
        {
            double basisPoint = 1.0e-4;

            Date exerciseDate = arguments_.exercise.date(0);

            // the part of the swap preceding exerciseDate should be truncated
            // to avoid taking into account unwanted cashflows
            VanillaSwap swap = arguments_.swap;

            double strike = swap.fixedRate;

            // 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 != 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(termStructure_));
            double annuity;

            switch (arguments_.settlementType)
            {
            case Settlement.Type.Physical: {
                annuity = Math.Abs(swap.fixedLegBPS()) / basisPoint;
                break;
            }

            case Settlement.Type.Cash: {
                List <CashFlow> fixedLeg        = swap.fixedLeg();
                FixedRateCoupon firstCoupon     = (FixedRateCoupon)fixedLeg[0];
                DayCounter      dayCount        = firstCoupon.dayCounter();
                double          fixedLegCashBPS =
                    CashFlows.bps(fixedLeg,
                                  new InterestRate(atmForward, dayCount, QLNet.Compounding.Compounded, Frequency.Annual), false,
                                  termStructure_.link.referenceDate());
                annuity = Math.Abs(fixedLegCashBPS / basisPoint);
                break;
            }

            default:
                throw new ApplicationException("unknown settlement type");
            }
            results_.additionalResults["annuity"] = annuity;

            // the swap length calculation might be improved using the value date
            // of the exercise date
            double swapLength = volatility_.link.swapLength(exerciseDate,
                                                            arguments_.floatingPayDates.Last());

            results_.additionalResults["swapLength"] = swapLength;

            double variance = volatility_.link.blackVariance(exerciseDate,
                                                             swapLength,
                                                             strike);
            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 = Utils.blackFormula(w, strike, atmForward, stdDev, annuity);

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

            results_.additionalResults["vega"] = Math.Sqrt(exerciseTime) *
                                                 Utils.blackFormulaStdDevDerivative(strike, atmForward, stdDev, annuity);
        }