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; } }