protected SwaptionVolatilityCube(Handle <SwaptionVolatilityStructure> atmVol,
                                         List <Period> optionTenors,
                                         List <Period> swapTenors,
                                         List <double> strikeSpreads,
                                         List <List <Handle <Quote> > > volSpreads,
                                         SwapIndex swapIndexBase,
                                         SwapIndex shortSwapIndexBase,
                                         bool vegaWeightedSmileFit)
            : base(optionTenors, swapTenors, 0, atmVol.link.calendar(), atmVol.link.businessDayConvention(),
                   atmVol.link.dayCounter())
        {
            atmVol_               = atmVol;
            nStrikes_             = strikeSpreads.Count;
            strikeSpreads_        = strikeSpreads;
            localStrikes_         = new InitializedList <double>(nStrikes_);
            localSmile_           = new List <double>(nStrikes_);
            volSpreads_           = volSpreads;
            swapIndexBase_        = swapIndexBase;
            shortSwapIndexBase_   = shortSwapIndexBase;
            vegaWeightedSmileFit_ = vegaWeightedSmileFit;

            Utils.QL_REQUIRE(!atmVol_.empty(), () => "atm vol handle not linked to anything");
            for (int i = 1; i < nStrikes_; ++i)
            {
                Utils.QL_REQUIRE(strikeSpreads_[i - 1] < strikeSpreads_[i], () =>
                                 "non increasing strike spreads: " + i + " is " + strikeSpreads_[i - 1] + ", " +
                                 (i + 1) + " is " + strikeSpreads_[i]);
            }

            Utils.QL_REQUIRE(!volSpreads_.empty(), () => "empty vol spreads matrix");

            Utils.QL_REQUIRE(nOptionTenors_ * nSwapTenors_ == volSpreads_.Count, () =>
                             "mismatch between number of option tenors * swap tenors (" +
                             nOptionTenors_ * nSwapTenors_ + ") and number of rows (" +
                             volSpreads_.Count + ")");

            for (int i = 0; i < volSpreads_.Count; i++)
            {
                Utils.QL_REQUIRE(nStrikes_ == volSpreads_[i].Count, () =>
                                 "mismatch between number of strikes (" + nStrikes_ +
                                 ") and number of columns (" + volSpreads_[i].Count +
                                 ") in the " + (i + 1) + " row");
            }

            atmVol_.registerWith(update);
            atmVol_.link.enableExtrapolation();

            swapIndexBase_.registerWith(update);
            shortSwapIndexBase_.registerWith(update);

            Utils.QL_REQUIRE(shortSwapIndexBase_.tenor() < swapIndexBase_.tenor(), () =>
                             "short index tenor (" + shortSwapIndexBase_.tenor() +
                             ") is not less than index tenor (" +
                             swapIndexBase_.tenor() + ")");

            registerWithVolatilitySpread();
            Settings.registerWith(update);
            evaluationDate_ = Settings.evaluationDate();
        }
Exemple #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
            {
                if (exerciseDate_ <= fixingDate_)
                {
                    throw new ArgumentException(
                              "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
                if (!swapIndex_.forwardingTermStructure().empty())
                {
                    throw new ArgumentException(
                              "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);
        }
Exemple #3
0
        public SwapSpreadIndex(String familyName,
                               SwapIndex swapIndex1,
                               SwapIndex swapIndex2,
                               double gearing1 = 1.0,
                               double gearing2 = -1.0)
            : base(familyName, swapIndex1.tenor(), // does not make sense, but we have to provide one
                   swapIndex1.fixingDays(), swapIndex1.currency(), swapIndex1.fixingCalendar(), swapIndex1.dayCounter())
        {
            swapIndex1_ = swapIndex1;
            swapIndex2_ = swapIndex2;
            gearing1_   = gearing1;
            gearing2_   = gearing2;

            swapIndex1_.registerWith(update);
            swapIndex2_.registerWith(update);

            name_ = swapIndex1_.name() + "(" + gearing1 + ") + "
                    + swapIndex2_.name() + "(" + gearing1 + ")";

            Utils.QL_REQUIRE(swapIndex1_.fixingDays() == swapIndex2_.fixingDays(), () =>
                             "index1 fixing days ("
                             + swapIndex1_.fixingDays() + ")"
                             + "must be equal to index2 fixing days ("
                             + swapIndex2_.fixingDays() + ")");

            Utils.QL_REQUIRE(swapIndex1_.fixingCalendar() == swapIndex2_.fixingCalendar(), () =>
                             "index1 fixingCalendar ("
                             + swapIndex1_.fixingCalendar() + ")"
                             + "must be equal to index2 fixingCalendar ("
                             + swapIndex2_.fixingCalendar() + ")");

            Utils.QL_REQUIRE(swapIndex1_.currency() == swapIndex2_.currency(), () =>
                             "index1 currency (" + swapIndex1_.currency() + ")"
                             + "must be equal to index2 currency ("
                             + swapIndex2_.currency() + ")");

            Utils.QL_REQUIRE(swapIndex1_.dayCounter() == swapIndex2_.dayCounter(), () =>
                             "index1 dayCounter ("
                             + swapIndex1_.dayCounter() + ")"
                             + "must be equal to index2 dayCounter ("
                             + swapIndex2_.dayCounter() + ")");

            Utils.QL_REQUIRE(swapIndex1_.fixedLegTenor() == swapIndex2_.fixedLegTenor(), () =>
                             "index1 fixedLegTenor ("
                             + swapIndex1_.fixedLegTenor() + ")"
                             + "must be equal to index2 fixedLegTenor ("
                             + swapIndex2_.fixedLegTenor());

            Utils.QL_REQUIRE(swapIndex1_.fixedLegConvention() == swapIndex2_.fixedLegConvention(), () =>
                             "index1 fixedLegConvention ("
                             + swapIndex1_.fixedLegConvention() + ")"
                             + "must be equal to index2 fixedLegConvention ("
                             + swapIndex2_.fixedLegConvention());
        }
        //public SwapRateHelper(Quote rate, SwapIndex swapIndex) :
        //    this(rate, swapIndex, new SimpleQuote(), new Period(0, TimeUnit.Days)) { }
        //public SwapRateHelper(Quote rate, SwapIndex swapIndex, Quote spread) :
        //    this(rate, swapIndex, spread, new Period(0, TimeUnit.Days)) { }
        public SwapRateHelper(Handle<Quote> rate, SwapIndex swapIndex, Handle<Quote> spread, Period fwdStart)
            : base(rate)
        {
            tenor_ = swapIndex.tenor();
            calendar_ = swapIndex.fixingCalendar();
            fixedConvention_ = swapIndex.fixedLegConvention();
            fixedFrequency_ = swapIndex.fixedLegTenor().frequency();
            fixedDayCount_ = swapIndex.dayCounter();
            iborIndex_ = swapIndex.iborIndex();
            spread_ = spread;
            fwdStart_ = fwdStart;

            // add observers
            iborIndex_.registerWith(update);
            spread_.registerWith(update);

            initializeDates();
        }
Exemple #5
0
        //public SwapRateHelper(double rate, SwapIndex swapIndex)
        //    : this(rate, swapIndex, new SimpleQuote()) { }
        //public SwapRateHelper(double rate, SwapIndex swapIndex, Quote spread)
        //    : this(rate, swapIndex, spread, new Period(0, TimeUnit.Days)) { }
        public SwapRateHelper(double rate, SwapIndex swapIndex, Handle <Quote> spread, Period fwdStart)
            : base(rate)
        {
            tenor_           = swapIndex.tenor();
            calendar_        = swapIndex.fixingCalendar();
            fixedConvention_ = swapIndex.fixedLegConvention();
            fixedFrequency_  = swapIndex.fixedLegTenor().frequency();
            fixedDayCount_   = swapIndex.dayCounter();
            iborIndex_       = swapIndex.iborIndex();
            spread_          = spread;
            fwdStart_        = fwdStart;

            // add observers
            iborIndex_.registerWith(update);
            spread_.registerWith(update);

            initializeDates();
        }
Exemple #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);
            }
        }