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(); }
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); }
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(); }
//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(); }
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); } }