Пример #1
0
        public SwaptionHelper(Period maturity,
                              Period length,
                              Handle <Quote> volatility,
                              IborIndex index,
                              Period fixedLegTenor,
                              DayCounter fixedLegDayCounter,
                              DayCounter floatingLegDayCounter,
                              Handle <YieldTermStructure> termStructure,
                              bool calibrateVolatility /*= false*/)
            : base(volatility, termStructure, calibrateVolatility)
        {
            Calendar calendar   = index.fixingCalendar();
            Period   indexTenor = index.tenor();
            int      fixingDays = index.fixingDays();

            Date exerciseDate = calendar.advance(termStructure.link.referenceDate(),
                                                 maturity,
                                                 index.businessDayConvention());
            Date startDate = calendar.advance(exerciseDate,
                                              fixingDays, TimeUnit.Days,
                                              index.businessDayConvention());
            Date endDate = calendar.advance(startDate, length,
                                            index.businessDayConvention());

            Schedule fixedSchedule = new Schedule(startDate, endDate, fixedLegTenor, calendar,
                                                  index.businessDayConvention(),
                                                  index.businessDayConvention(),
                                                  DateGeneration.Rule.Forward, false);
            Schedule floatSchedule = new Schedule(startDate, endDate, index.tenor(), calendar,
                                                  index.businessDayConvention(),
                                                  index.businessDayConvention(),
                                                  DateGeneration.Rule.Forward, false);

            IPricingEngine swapEngine = new DiscountingSwapEngine(termStructure);

            VanillaSwap temp = new VanillaSwap(VanillaSwap.Type.Receiver, 1.0,
                                               fixedSchedule, 0.0, fixedLegDayCounter,
                                               floatSchedule, index, 0.0, floatingLegDayCounter);

            temp.setPricingEngine(swapEngine);
            exerciseRate_ = temp.fairRate();
            swap_         = new VanillaSwap(VanillaSwap.Type.Receiver, 1.0,
                                            fixedSchedule, exerciseRate_, fixedLegDayCounter,
                                            floatSchedule, index, 0.0, floatingLegDayCounter);
            swap_.setPricingEngine(swapEngine);

            Exercise exercise = new EuropeanExercise(exerciseDate);

            swaption_    = new Swaption(swap_, exercise);
            marketValue_ = blackPrice(volatility_.link.value());
        }
Пример #2
0
        public Swaption value()
        {
            Date     evaluationDate = Settings.evaluationDate();
            Calendar fixingCalendar = swapIndex_.fixingCalendar();

            fixingDate_ = fixingCalendar.advance(evaluationDate, optionTenor_, optionConvention_);

            if (exerciseDate_ == null)
            {
                exercise_ = new EuropeanExercise(fixingDate_);
            }
            else
            {
                Utils.QL_REQUIRE(exerciseDate_ <= fixingDate_, () =>
                                 "exercise date (" + exerciseDate_ + ") must be less " + "than or equal to fixing date (" + fixingDate_ + ")");
                exercise_ = new EuropeanExercise(exerciseDate_);
            }

            double usedStrike;

            if (strike_ == null)
            {
                // ATM on the forecasting curve
                Utils.QL_REQUIRE(!swapIndex_.forwardingTermStructure().empty(), () =>
                                 "no forecasting term structure set to " + swapIndex_.name());
                VanillaSwap temp = swapIndex_.underlyingSwap(fixingDate_);
                temp.setPricingEngine(new DiscountingSwapEngine(swapIndex_.forwardingTermStructure()));
                usedStrike = temp.fairRate();
            }
            else
            {
                usedStrike = strike_.Value;
            }

            BusinessDayConvention bdc = swapIndex_.fixedLegConvention();

            underlyingSwap_ = new MakeVanillaSwap(swapIndex_.tenor(),
                                                  swapIndex_.iborIndex(),
                                                  usedStrike)
                              .withEffectiveDate(swapIndex_.valueDate(fixingDate_))
                              .withFixedLegCalendar(swapIndex_.fixingCalendar())
                              .withFixedLegDayCount(swapIndex_.dayCounter())
                              .withFixedLegConvention(bdc)
                              .withFixedLegTerminationDateConvention(bdc);

            Swaption swaption = new Swaption(underlyingSwap_, exercise_, delivery_);

            swaption.setPricingEngine(engine_);
            return(swaption);
        }
Пример #3
0
            public SwaptionImpliedVolatilityHelper(Swaption swaption, Handle <YieldTermStructure> discountCurve, double targetValue)
            {
                discountCurve_ = discountCurve;
                targetValue_   = targetValue;

                // set an implausible value, so that calculation is forced
                // at first ImpliedVolHelper::operator()(Volatility x) call
                vol_ = new SimpleQuote(-1.0);
                Handle <Quote> h = new Handle <Quote>(vol_);

                engine_ = new BlackSwaptionEngine(discountCurve_, h);
                swaption.setupArguments(engine_.getArguments());
                results_ = engine_.getResults() as Results;
            }
Пример #4
0
        protected override void performCalculations()
        {
            Calendar calendar   = index_.fixingCalendar();
            int      fixingDays = index_.fixingDays();

            Date exerciseDate = exerciseDate_;

            if (exerciseDate == null)
            {
                exerciseDate = calendar.advance(termStructure_.link.referenceDate(),
                                                maturity_,
                                                index_.businessDayConvention());
            }

            Date startDate = calendar.advance(exerciseDate,
                                              fixingDays, TimeUnit.Days,
                                              index_.businessDayConvention());

            Date endDate = endDate_;

            if (endDate == null)
            {
                endDate = calendar.advance(startDate, length_,
                                           index_.businessDayConvention());
            }

            Schedule fixedSchedule = new Schedule(startDate, endDate, fixedLegTenor_, calendar,
                                                  index_.businessDayConvention(),
                                                  index_.businessDayConvention(),
                                                  DateGeneration.Rule.Forward, false);
            Schedule floatSchedule = new Schedule(startDate, endDate, index_.tenor(), calendar,
                                                  index_.businessDayConvention(),
                                                  index_.businessDayConvention(),
                                                  DateGeneration.Rule.Forward, false);

            IPricingEngine swapEngine = new DiscountingSwapEngine(termStructure_, false);

            VanillaSwap.Type type = VanillaSwap.Type.Receiver;

            VanillaSwap temp = new VanillaSwap(VanillaSwap.Type.Receiver, nominal_,
                                               fixedSchedule, 0.0, fixedLegDayCounter_,
                                               floatSchedule, index_, 0.0, floatingLegDayCounter_);

            temp.setPricingEngine(swapEngine);
            double forward = temp.fairRate();

            if (!strike_.HasValue)
            {
                exerciseRate_ = forward;
            }
            else
            {
                exerciseRate_ = strike_.Value;
                type          = strike_ <= forward ? VanillaSwap.Type.Receiver : VanillaSwap.Type.Payer;
                // ensure that calibration instrument is out of the money
            }
            swap_ = new VanillaSwap(type, nominal_,
                                    fixedSchedule, exerciseRate_, fixedLegDayCounter_,
                                    floatSchedule, index_, 0.0, floatingLegDayCounter_);
            swap_.setPricingEngine(swapEngine);

            Exercise exercise = new EuropeanExercise(exerciseDate);

            swaption_ = new Swaption(swap_, exercise);

            base.performCalculations();
        }
Пример #5
0
        public override void calculate()
        {
            /* both DTS, YTS ref dates and pricing date consistency
             * checks? settlement... */
            Utils.QL_REQUIRE(!discountCurve_.empty(), () => "no discount term structure set");
            Utils.QL_REQUIRE(!defaultTS_.empty(), () => "no ctpty default term structure set");
            Utils.QL_REQUIRE(!swaptionletEngine_.empty(), () => "no swap option engine set");

            Date priceDate = defaultTS_.link.referenceDate();

            double cumOptVal = 0.0, cumPutVal = 0.0;
            // Vanilla swap so 0 leg is floater

            int  index        = 0;
            Date nextFD       = arguments_.fixedPayDates[index];
            Date swapletStart = priceDate;

            while (nextFD < priceDate)
            {
                index++;
                nextFD = arguments_.fixedPayDates[index];
            }


            // Compute fair spread for strike value:
            // copy args into the non risky engine
            Swap.Arguments noCVAArgs = baseSwapEngine_.link.getArguments() as Swap.Arguments;

            noCVAArgs.legs  = this.arguments_.legs;
            noCVAArgs.payer = this.arguments_.payer;

            baseSwapEngine_.link.calculate();

            double baseSwapRate = ((FixedRateCoupon)arguments_.legs[0][0]).rate();

            Swap.Results vSResults = baseSwapEngine_.link.getResults() as Swap.Results;

            double?baseSwapFairRate = -baseSwapRate * vSResults.legNPV[1] / vSResults.legNPV[0];
            double?baseSwapNPV      = vSResults.value;

            VanillaSwap.Type reversedType = arguments_.type == VanillaSwap.Type.Payer
                                         ? VanillaSwap.Type.Receiver
                                         : VanillaSwap.Type.Payer;

            // Swaplet options summatory:
            while (nextFD != arguments_.fixedPayDates.Last())
            {
                // iFD coupon not fixed, create swaptionlet:
                IborIndex swapIndex = ((FloatingRateCoupon)arguments_.legs[1][0]).index() as IborIndex;

                // Alternatively one could cap this period to, say, 1M
                Period baseSwapsTenor = new Period(arguments_.fixedPayDates.Last().serialNumber()
                                                   - swapletStart.serialNumber(), TimeUnit.Days);
                VanillaSwap swaplet = new MakeVanillaSwap(baseSwapsTenor, swapIndex, baseSwapFairRate)
                                      .withType(arguments_.type)
                                      .withNominal(arguments_.nominal)
                                      .withEffectiveDate(swapletStart)
                                      .withTerminationDate(arguments_.fixedPayDates.Last()).value();

                VanillaSwap revSwaplet = new MakeVanillaSwap(baseSwapsTenor, swapIndex, baseSwapFairRate)
                                         .withType(reversedType)
                                         .withNominal(arguments_.nominal)
                                         .withEffectiveDate(swapletStart)
                                         .withTerminationDate(arguments_.fixedPayDates.Last()).value();

                Swaption swaptionlet = new Swaption(swaplet, new EuropeanExercise(swapletStart));
                Swaption putSwaplet  = new Swaption(revSwaplet, new EuropeanExercise(swapletStart));
                swaptionlet.setPricingEngine(swaptionletEngine_.currentLink());
                putSwaplet.setPricingEngine(swaptionletEngine_.currentLink());

                // atm underlying swap means that the value of put = value
                // call so this double pricing is not needed
                cumOptVal += swaptionlet.NPV() * defaultTS_.link.defaultProbability(
                    swapletStart, nextFD);
                cumPutVal += putSwaplet.NPV() * invstDTS_.link.defaultProbability(swapletStart, nextFD);

                swapletStart = nextFD;
                index++;
                nextFD = arguments_.fixedPayDates[index];
            }

            results_.value    = baseSwapNPV - (1.0 - ctptyRecoveryRate_) * cumOptVal + (1.0 - invstRecoveryRate_) * cumPutVal;
            results_.fairRate = -baseSwapRate * (vSResults.legNPV[1] - (1.0 - ctptyRecoveryRate_) * cumOptVal +
                                                 (1.0 - invstRecoveryRate_) * cumPutVal) / vSResults.legNPV[0];
        }