예제 #1
0
        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;
            }
        }