예제 #1
0
        public CapFloor value()
        {
            VanillaSwap swap = makeVanillaSwap_;

            List <CashFlow> leg = swap.floatingLeg();

            if (firstCapletExcluded_)
            {
                leg.RemoveAt(0);
            }

            // only leaves the last coupon
            if (asOptionlet_ && leg.Count > 1)
            {
                leg.RemoveRange(0, leg.Count - 2); // Sun Studio needs an lvalue
            }

            List <double> strikeVector;

            if (strike_ == null)
            {
                // temporary patch...
                // should be fixed for every CapFloor::Engine
                BlackCapFloorEngine temp = engine_ as BlackCapFloorEngine;
                Utils.QL_REQUIRE(temp != null, () => "cannot calculate ATM without a BlackCapFloorEngine");
                Handle <YieldTermStructure> discountCurve = temp.termStructure();
                strikeVector = new InitializedList <double>(1, CashFlows.atmRate(leg, discountCurve, false, discountCurve.link.referenceDate()));
            }
            else
            {
                strikeVector = new InitializedList <double>(1, strike_.Value);
            }

            CapFloor capFloor = new CapFloor(capFloorType_, leg, strikeVector);

            capFloor.setPricingEngine(engine_);
            return(capFloor);
        }
예제 #2
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));
        }
 public FdmAffineModelSwapInnerValue(
     ModelType disModel,
     ModelType fwdModel,
     VanillaSwap swap,
     Dictionary <double, Date> exerciseDates,
     FdmMesher mesher,
     int direction)
 {
     disModel_  = disModel;
     fwdModel_  = fwdModel;
     mesher_    = mesher;
     direction_ = direction;
     swap_      = new VanillaSwap(swap.swapType,
                                  swap.nominal,
                                  swap.fixedSchedule(),
                                  swap.fixedRate,
                                  swap.fixedDayCount(),
                                  swap.floatingSchedule(),
                                  swap.iborIndex().clone(fwdTs_),
                                  swap.spread,
                                  swap.floatingDayCount(),
                                  null);
     exerciseDates_ = exerciseDates;
 }
예제 #4
0
        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);
        }
예제 #5
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();
        }
예제 #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.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);
            }
        }