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 DigitalCmsLeg(Schedule schedule, SwapIndex index) { schedule_ = schedule; index_ = index; paymentAdjustment_ = BusinessDayConvention.Following; inArrears_ = false; longCallOption_ = Position.Type.Long; callATM_ = false; longPutOption_ = Position.Type.Long; putATM_ = false; }
public CmsCoupon(double nominal, Date paymentDate, Date startDate, Date endDate, int fixingDays, SwapIndex swapIndex, double gearing = 1.0, double spread = 0.0, Date refPeriodStart = null, Date refPeriodEnd = null, DayCounter dayCounter = null, bool isInArrears = false) : base(paymentDate, nominal, startDate, endDate, fixingDays, swapIndex, gearing, spread, refPeriodStart, refPeriodEnd, dayCounter, isInArrears) { swapIndex_ = swapIndex; }
public SwaptionVolCube2(Handle <SwaptionVolatilityStructure> atmVolStructure, List <Period> optionTenors, List <Period> swapTenors, List <double> strikeSpreads, List <List <Handle <Quote> > > volSpreads, SwapIndex swapIndexBase, SwapIndex shortSwapIndexBase, bool vegaWeightedSmileFit) : base(atmVolStructure, optionTenors, swapTenors, strikeSpreads, volSpreads, swapIndexBase, shortSwapIndexBase, vegaWeightedSmileFit) { volSpreadsInterpolator_ = new List <Interpolation2D>(); volSpreadsMatrix_ = new List <Matrix>(nStrikes_); for (int i = 0; i < nStrikes_; i++) { volSpreadsMatrix_.Add(new Matrix(optionTenors.Count, swapTenors.Count, 0.0)); } }
public MakeCms(Period swapTenor, SwapIndex swapIndex, IborIndex iborIndex, double iborSpread = 0.0, Period forwardStart = null, Date maturityDate = null) { swapTenor_ = swapTenor; swapIndex_ = swapIndex; iborIndex_ = iborIndex; iborSpread_ = iborSpread; iborCap_ = null; iborFloor_ = null; useAtmSpread_ = false; forwardStart_ = forwardStart ?? new Period(0, TimeUnit.Days); cmsSpread_ = 0.0; cmsGearing_ = 1.0; cmsCap_ = null; cmsFloor_ = null; effectiveDate_ = null; cmsCalendar_ = swapIndex.fixingCalendar(); floatCalendar_ = iborIndex.fixingCalendar(); payCms_ = true; nominal_ = 1.0; maturityDate_ = maturityDate; cmsTenor_ = new Period(3, TimeUnit.Months); floatTenor_ = iborIndex.tenor(); cmsConvention_ = BusinessDayConvention.ModifiedFollowing; cmsTerminationDateConvention_ = BusinessDayConvention.ModifiedFollowing; floatConvention_ = iborIndex.businessDayConvention(); floatTerminationDateConvention_ = iborIndex.businessDayConvention(); cmsRule_ = DateGeneration.Rule.Backward; floatRule_ = DateGeneration.Rule.Backward; cmsEndOfMonth_ = false; floatEndOfMonth_ = false; cmsFirstDate_ = null; cmsNextToLastDate_ = null; floatFirstDate_ = null; floatNextToLastDate_ = null; cmsDayCount_ = new Actual360(); floatDayCount_ = iborIndex.dayCounter(); engine_ = new DiscountingSwapEngine(swapIndex.forwardingTermStructure()); }
//===========================================================================// // GFunctionWithShifts // //===========================================================================// public GFunctionWithShifts(CmsCoupon coupon, Handle <Quote> meanReversion) { meanReversion_ = meanReversion; calibratedShift_ = 0.03; tmpRs_ = 10000000.0; accuracy_ = 1.0e-14; SwapIndex swapIndex = coupon.swapIndex(); VanillaSwap swap = swapIndex.underlyingSwap(coupon.fixingDate()); swapRateValue_ = swap.fairRate(); objectiveFunction_ = new ObjectiveFunction(this, swapRateValue_); Schedule schedule = swap.fixedSchedule(); Handle <YieldTermStructure> rateCurve = swapIndex.forwardingTermStructure(); DayCounter dc = swapIndex.dayCounter(); swapStartTime_ = dc.yearFraction(rateCurve.link.referenceDate(), schedule.startDate()); discountAtStart_ = rateCurve.link.discount(schedule.startDate()); double paymentTime = dc.yearFraction(rateCurve.link.referenceDate(), coupon.date()); shapedPaymentTime_ = shapeOfShift(paymentTime); List <CashFlow> fixedLeg = new List <CashFlow>(swap.fixedLeg()); int n = fixedLeg.Count; shapedSwapPaymentTimes_ = new List <double>(); swapPaymentDiscounts_ = new List <double>(); accruals_ = new List <double>(); for (int i = 0; i < n; ++i) { Coupon coupon1 = fixedLeg[i] as Coupon; accruals_.Add(coupon1.accrualPeriod()); Date paymentDate = new Date(coupon1.date().serialNumber()); double swapPaymentTime = dc.yearFraction(rateCurve.link.referenceDate(), paymentDate); shapedSwapPaymentTimes_.Add(shapeOfShift(swapPaymentTime)); swapPaymentDiscounts_.Add(rateCurve.link.discount(paymentDate)); } discountRatio_ = swapPaymentDiscounts_.Last() / discountAtStart_; }
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); } }
public AmortizingCmsRateBond(int settlementDays, List <double> notionals, Schedule schedule, SwapIndex index, DayCounter paymentDayCounter, BusinessDayConvention paymentConvention = BusinessDayConvention.Following, int fixingDays = 0, List <double> gearings = null, List <double> spreads = null, List <double?> caps = null, List <double?> floors = null, bool inArrears = false, Date issueDate = null) : base(settlementDays, schedule.calendar(), issueDate) { // Optional value check if (gearings == null) { gearings = new List <double>() { 1.0 } } ; if (spreads == null) { spreads = new List <double>() { 0 } } ; if (caps == null) { caps = new List <double?>(); } if (floors == null) { floors = new List <double?>(); } maturityDate_ = schedule.endDate(); cashflows_ = new CmsLeg(schedule, index) .withPaymentDayCounter(paymentDayCounter) .withFixingDays(fixingDays) .withGearings(gearings) .withSpreads(spreads) .withCaps(caps) .withFloors(floors) .inArrears(inArrears) .withNotionals(notionals) .withPaymentAdjustment(paymentConvention); addRedemptionsToCashflows(); Utils.QL_REQUIRE(!cashflows().empty(), () => "bond with no cashflows!"); index.registerWith(update); } } }
private void init(BusinessDayConvention?paymentConvention1, BusinessDayConvention?paymentConvention2) { Utils.QL_REQUIRE(nominal1_.Count == schedule1_.Count - 1, () => "nominal1 size (" + nominal1_.Count + ") does not match schedule1 size (" + schedule1_.size() + ")"); Utils.QL_REQUIRE(nominal2_.Count == schedule2_.Count - 1, () => "nominal2 size (" + nominal2_.Count + ") does not match schedule2 size (" + nominal2_.Count + ")"); Utils.QL_REQUIRE(gearing1_.Count == 0 || gearing1_.Count == nominal1_.Count, () => "nominal1 size (" + nominal1_.Count + ") does not match gearing1 size (" + gearing1_.Count + ")"); Utils.QL_REQUIRE(gearing2_.Count == 0 || gearing2_.Count == nominal2_.Count, () => "nominal2 size (" + nominal2_.Count + ") does not match gearing2 size (" + gearing2_.Count + ")"); Utils.QL_REQUIRE(cappedRate1_.Count == 0 || cappedRate1_.Count == nominal1_.Count, () => "nominal1 size (" + nominal1_.Count + ") does not match cappedRate1 size (" + cappedRate1_.Count + ")"); Utils.QL_REQUIRE(cappedRate2_.Count == 0 || cappedRate2_.Count == nominal2_.Count, () => "nominal2 size (" + nominal2_.Count + ") does not match cappedRate2 size (" + cappedRate2_.Count + ")"); Utils.QL_REQUIRE(flooredRate1_.Count == 0 || flooredRate1_.Count == nominal1_.Count, () => "nominal1 size (" + nominal1_.Count + ") does not match flooredRate1 size (" + flooredRate1_.Count + ")"); Utils.QL_REQUIRE(flooredRate2_.Count == 0 || flooredRate2_.Count == nominal2_.Count, () => "nominal2 size (" + nominal2_.Count + ") does not match flooredRate2 size (" + flooredRate2_.Count + ")"); if (paymentConvention1 != null) { paymentConvention1_ = paymentConvention1.Value; } else { paymentConvention1_ = schedule1_.businessDayConvention(); } if (paymentConvention2 != null) { paymentConvention2_ = paymentConvention2.Value; } else { paymentConvention2_ = schedule2_.businessDayConvention(); } if (gearing1_.Count == 0) { gearing1_ = new InitializedList <double>(nominal1_.Count, 1.0); } if (gearing2_.Count == 0) { gearing2_ = new InitializedList <double>(nominal2_.Count, 1.0); } if (spread1_.Count == 0) { spread1_ = new InitializedList <double>(nominal1_.Count, 0.0); } if (spread2_.Count == 0) { spread2_ = new InitializedList <double>(nominal2_.Count, 0.0); } if (cappedRate1_.Count == 0) { cappedRate1_ = new InitializedList <double?>(nominal1_.Count, null); } if (cappedRate2_.Count == 0) { cappedRate2_ = new InitializedList <double?>(nominal2_.Count, null); } if (flooredRate1_.Count == 0) { flooredRate1_ = new InitializedList <double?>(nominal1_.Count, null); } if (flooredRate2_.Count == 0) { flooredRate2_ = new InitializedList <double?>(nominal2_.Count, null); } bool isNull = cappedRate1_[0] == null; for (int i = 0; i < cappedRate1_.Count; i++) { if (isNull) { Utils.QL_REQUIRE(cappedRate1_[i] == null, () => "cappedRate1 must be null for all or none entry (" + (i + 1) + "th is " + cappedRate1_[i] + ")"); } else { Utils.QL_REQUIRE(cappedRate1_[i] != null, () => "cappedRate 1 must be null for all or none entry (" + "1st is " + cappedRate1_[0] + ")"); } } isNull = cappedRate2_[0] == null; for (int i = 0; i < cappedRate2_.Count; i++) { if (isNull) { Utils.QL_REQUIRE(cappedRate2_[i] == null, () => "cappedRate2 must be null for all or none entry (" + (i + 1) + "th is " + cappedRate2_[i] + ")"); } else { Utils.QL_REQUIRE(cappedRate2_[i] != null, () => "cappedRate2 must be null for all or none entry (" + "1st is " + cappedRate2_[0] + ")"); } } isNull = flooredRate1_[0] == null; for (int i = 0; i < flooredRate1_.Count; i++) { if (isNull) { Utils.QL_REQUIRE(flooredRate1_[i] == null, () => "flooredRate1 must be null for all or none entry (" + (i + 1) + "th is " + flooredRate1_[i] + ")"); } else { Utils.QL_REQUIRE(flooredRate1_[i] != null, () => "flooredRate 1 must be null for all or none entry (" + "1st is " + flooredRate1_[0] + ")"); } } isNull = flooredRate2_[0] == null; for (int i = 0; i < flooredRate2_.Count; i++) { if (isNull) { Utils.QL_REQUIRE(flooredRate2_[i] == null, () => "flooredRate2 must be null for all or none entry (" + (i + 1) + "th is " + flooredRate2_[i] + ")"); } else { Utils.QL_REQUIRE(flooredRate2_[i] != null, () => "flooredRate2 must be null for all or none entry (" + "1st is " + flooredRate2_[0] + ")"); } } // if the gearing is zero then the ibor / cms leg will be set up with // fixed coupons which makes trouble here in this context. We therefore // use a dirty trick and enforce the gearing to be non zero. for (int i = 0; i < gearing1_.Count; i++) { if (Utils.close(gearing1_[i], 0.0)) { gearing1_[i] = Const.QL_EPSILON; } } for (int i = 0; i < gearing2_.Count; i++) { if (Utils.close(gearing2_[i], 0.0)) { gearing2_[i] = Const.QL_EPSILON; } } IborIndex ibor1 = index1_ as IborIndex; IborIndex ibor2 = index2_ as IborIndex; SwapIndex cms1 = index1_ as SwapIndex; SwapIndex cms2 = index2_ as SwapIndex; SwapSpreadIndex cmsspread1 = index1_ as SwapSpreadIndex; SwapSpreadIndex cmsspread2 = index2_ as SwapSpreadIndex; Utils.QL_REQUIRE(ibor1 != null || cms1 != null || cmsspread1 != null, () => "index1 must be ibor or cms or cms spread"); Utils.QL_REQUIRE(ibor2 != null || cms2 != null || cmsspread2 != null, () => "index2 must be ibor or cms"); if (ibor1 != null) { IborLeg leg = new IborLeg(schedule1_, ibor1); leg = (IborLeg)leg.withPaymentDayCounter(dayCount1_) .withSpreads(spread1_) .withGearings(gearing1_) .withPaymentAdjustment(paymentConvention1_) .withNotionals(nominal1_); if (cappedRate1_[0] != null) { leg = (IborLeg)leg.withCaps(cappedRate1_); } if (flooredRate1_[0] != null) { leg = (IborLeg)leg.withFloors(flooredRate1_); } legs_[0] = leg; } if (ibor2 != null) { IborLeg leg = new IborLeg(schedule2_, ibor2); leg = (IborLeg)leg.withPaymentDayCounter(dayCount2_) .withSpreads(spread2_) .withGearings(gearing2_) .withPaymentAdjustment(paymentConvention2_) .withNotionals(nominal2_); if (cappedRate2_[0] != null) { leg = (IborLeg)leg.withCaps(cappedRate2_); } if (flooredRate2_[0] != null) { leg = (IborLeg)leg.withFloors(flooredRate2_); } legs_[1] = leg; } if (cms1 != null) { CmsLeg leg = new CmsLeg(schedule1_, cms1); leg = (CmsLeg)leg.withPaymentDayCounter(dayCount1_) .withSpreads(spread1_) .withGearings(gearing1_) .withNotionals(nominal1_) .withPaymentAdjustment(paymentConvention1_); if (cappedRate1_[0] != null) { leg = (CmsLeg)leg.withCaps(cappedRate1_); } if (flooredRate1_[0] != null) { leg = (CmsLeg)leg.withFloors(flooredRate1_); } legs_[0] = leg; } if (cms2 != null) { CmsLeg leg = new CmsLeg(schedule2_, cms2); leg = (CmsLeg)leg.withPaymentDayCounter(dayCount2_) .withSpreads(spread2_) .withGearings(gearing2_) .withNotionals(nominal2_) .withPaymentAdjustment(paymentConvention2_); if (cappedRate2_[0] != null) { leg = (CmsLeg)leg.withCaps(cappedRate2_); } if (flooredRate2_[0] != null) { leg = (CmsLeg)leg.withFloors(flooredRate2_); } legs_[1] = leg; } if (cmsspread1 != null) { CmsSpreadLeg leg = new CmsSpreadLeg(schedule1_, cmsspread1); leg = (CmsSpreadLeg)leg.withPaymentDayCounter(dayCount1_) .withSpreads(spread1_) .withGearings(gearing1_) .withNotionals(nominal1_) .withPaymentAdjustment(paymentConvention1_); if (cappedRate1_[0] != null) { leg = (CmsSpreadLeg)leg.withCaps(cappedRate1_); } if (flooredRate1_[0] != null) { leg = (CmsSpreadLeg)leg.withFloors(flooredRate1_); } legs_[0] = leg; } if (cmsspread2 != null) { CmsSpreadLeg leg = new CmsSpreadLeg(schedule2_, cmsspread2); leg = (CmsSpreadLeg)leg.withPaymentDayCounter(dayCount2_) .withSpreads(spread2_) .withGearings(gearing2_) .withNotionals(nominal2_) .withPaymentAdjustment(paymentConvention2_); if (cappedRate2_[0] != null) { leg = (CmsSpreadLeg)leg.withCaps(cappedRate2_); } if (flooredRate2_[0] != null) { leg = (CmsSpreadLeg)leg.withFloors(flooredRate2_); } legs_[1] = leg; } if (intermediateCapitalExchange_) { for (int i = 0; i < legs_[0].Count - 1; i++) { double cap = nominal1_[i] - nominal1_[i + 1]; if (!Utils.close(cap, 0.0)) { legs_[0].Insert(i + 1, new Redemption(cap, legs_[0][i].date())); nominal1_.Insert(i + 1, nominal1_[i]); i++; } } for (int i = 0; i < legs_[1].Count - 1; i++) { double cap = nominal2_[i] - nominal2_[i + 1]; if (!Utils.close(cap, 0.0)) { legs_[1].Insert(i + 1, new Redemption(cap, legs_[1][i].date())); nominal2_.Insert(i + 1, nominal2_[i]); i++; } } } if (finalCapitalExchange_) { legs_[0].Add(new Redemption(nominal1_.Last(), legs_[0].Last().date())); nominal1_.Add(nominal1_.Last()); legs_[1].Add(new Redemption(nominal2_.Last(), legs_[1].Last().date())); nominal2_.Add(nominal2_.Last()); } foreach (var c in legs_[0]) { c.registerWith(update); } foreach (var c in legs_[1]) { c.registerWith(update); } switch (type_) { case VanillaSwap.Type.Payer: payer_[0] = -1.0; payer_[1] = +1.0; break; case VanillaSwap.Type.Receiver: payer_[0] = +1.0; payer_[1] = -1.0; break; default: Utils.QL_FAIL("Unknown float float - swap type"); break; } }