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); } } }
public Swap value() { Date startDate; if (effectiveDate_ != null) { startDate = effectiveDate_; } else { int fixingDays = iborIndex_.fixingDays(); Date refDate = Settings.Instance.evaluationDate(); // if the evaluation date is not a business day // then move to the next business day refDate = floatCalendar_.adjust(refDate); Date spotDate = floatCalendar_.advance(refDate, new Period(fixingDays, TimeUnit.Days)); startDate = spotDate + forwardStart_; } Date terminationDate = maturityDate_ == null ? startDate + swapTenor_ : maturityDate_; Schedule cmsSchedule = new Schedule(startDate, terminationDate, cmsTenor_, cmsCalendar_, cmsConvention_, cmsTerminationDateConvention_, cmsRule_, cmsEndOfMonth_, cmsFirstDate_, cmsNextToLastDate_); Schedule floatSchedule = new Schedule(startDate, terminationDate, floatTenor_, floatCalendar_, floatConvention_, floatTerminationDateConvention_, floatRule_, floatEndOfMonth_, floatFirstDate_, floatNextToLastDate_); List <CashFlow> cmsLeg = new CmsLeg(cmsSchedule, swapIndex_) .withPaymentDayCounter(cmsDayCount_) .withFixingDays(swapIndex_.fixingDays()) .withGearings(cmsGearing_) .withSpreads(cmsSpread_) .withCaps(cmsCap_) .withFloors(cmsFloor_) .withNotionals(nominal_) .withPaymentAdjustment(cmsConvention_); if (couponPricer_ != null) { Utils.setCouponPricer(cmsLeg, couponPricer_); } double?usedSpread = iborSpread_; if (useAtmSpread_) { Utils.QL_REQUIRE(!iborIndex_.forwardingTermStructure().empty(), () => "null term structure set to this instance of " + iborIndex_.name()); Utils.QL_REQUIRE(!swapIndex_.forwardingTermStructure().empty(), () => "null term structure set to this instance of " + swapIndex_.name()); Utils.QL_REQUIRE(couponPricer_ != null, () => "no CmsCouponPricer set (yet)"); List <CashFlow> fLeg = new IborLeg(floatSchedule, iborIndex_) .withPaymentDayCounter(floatDayCount_) .withFixingDays(iborIndex_.fixingDays()) .withCaps(iborCap_) .withFloors(iborFloor_) .withNotionals(nominal_) .withPaymentAdjustment(floatConvention_); if (iborCouponPricer_ != null) { Utils.setCouponPricer(fLeg, iborCouponPricer_); } Swap temp = new Swap(cmsLeg, fLeg); temp.setPricingEngine(engine_); double?npv = temp.legNPV(0) + temp.legNPV(1); usedSpread = -npv / temp.legBPS(1) * 1e-4; } else { Utils.QL_REQUIRE(usedSpread.HasValue, () => "null spread set"); } List <CashFlow> floatLeg = new IborLeg(floatSchedule, iborIndex_) .withSpreads(usedSpread.Value) .withPaymentDayCounter(floatDayCount_) .withFixingDays(iborIndex_.fixingDays()) .withGearings(iborGearing_) .withCaps(iborCap_) .withFloors(iborFloor_) .withPaymentAdjustment(floatConvention_) .withNotionals(nominal_); if (iborCouponPricer_ != null) { Utils.setCouponPricer(floatLeg, iborCouponPricer_); } Swap swap; if (payCms_) { swap = new Swap(cmsLeg, floatLeg); } else { swap = new Swap(floatLeg, cmsLeg); } swap.setPricingEngine(engine_); return(swap); }
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; } }