Ejemplo n.º 1
0
        public CPICashFlow(double notional,
                           ZeroInflationIndex index,
                           Date baseDate,
                           double baseFixing,
                           Date fixingDate,
                           Date paymentDate,
                           bool growthOnly = false,
                           InterpolationType interpolation = InterpolationType.AsIndex,
                           Frequency frequency             = Frequency.NoFrequency)
            : base(notional, index, baseDate, fixingDate, paymentDate, growthOnly)
        {
            baseFixing_    = baseFixing;
            interpolation_ = interpolation;
            frequency_     = frequency;

            Utils.QL_REQUIRE(Math.Abs(baseFixing_) > 1e-16, () => "|baseFixing|<1e-16, future divide-by-zero error");

            if (interpolation_ != InterpolationType.AsIndex)
            {
                Utils.QL_REQUIRE(frequency_ != Frequency.NoFrequency, () => "non-index interpolation w/o frequency");
            }
        }
Ejemplo n.º 2
0
 public CPILeg(Schedule schedule,
               ZeroInflationIndex index,
               double baseCPI,
               Period observationLag)
 {
     schedule_          = schedule;
     index_             = index;
     baseCPI_           = baseCPI;
     observationLag_    = observationLag;
     paymentDayCounter_ = new Thirty360();
     paymentAdjustment_ = BusinessDayConvention.ModifiedFollowing;
     paymentCalendar_   = schedule.calendar();
     fixingDays_        = new List <int>()
     {
         0
     };
     observationInterpolation_ = InterpolationType.AsIndex;
     subtractInflationNominal_ = true;
     spreads_ = new List <double>()
     {
         0
     };
 }
Ejemplo n.º 3
0
 public CPICoupon(double baseCPI, // user provided, could be arbitrary
                  Date paymentDate,
                  double nominal,
                  Date startDate,
                  Date endDate,
                  int fixingDays,
                  ZeroInflationIndex index,
                  Period observationLag,
                  InterpolationType observationInterpolation,
                  DayCounter dayCounter,
                  double fixedRate, // aka gearing
                  double spread       = 0.0,
                  Date refPeriodStart = null,
                  Date refPeriodEnd   = null,
                  Date exCouponDate   = null)
     : base(paymentDate, nominal, startDate, endDate, fixingDays, index,
            observationLag, dayCounter, refPeriodStart, refPeriodEnd, exCouponDate)
 {
     baseCPI_   = baseCPI;
     fixedRate_ = fixedRate;
     spread_    = spread;
     observationInterpolation_ = observationInterpolation;
     Utils.QL_REQUIRE(Math.Abs(baseCPI_) > 1e-16, () => "|baseCPI_| < 1e-16, future divide-by-zero problem");
 }
        /* Generally inflation indices are available with a lag of 1month
         * and then observed with a lag of 2-3 months depending whether
         * they use an interpolated fixing or not.  Here, we make the
         * swap use the interpolation of the index to avoid incompatibilities.
         */
        public ZeroCouponInflationSwap(Type type,
                                       double nominal,
                                       Date startDate, // start date of contract (only)
                                       Date maturity,  // this is pre-adjustment!
                                       Calendar fixCalendar,
                                       BusinessDayConvention fixConvention,
                                       DayCounter dayCounter,
                                       double fixedRate,
                                       ZeroInflationIndex infIndex,
                                       Period observationLag,
                                       bool adjustInfObsDates = false,
                                       Calendar infCalendar   = null,
                                       BusinessDayConvention?infConvention = null)
            : base(2)
        {
            type_              = type;
            nominal_           = nominal;
            startDate_         = startDate;
            maturityDate_      = maturity;
            fixCalendar_       = fixCalendar;
            fixConvention_     = fixConvention;
            fixedRate_         = fixedRate;
            infIndex_          = infIndex;
            observationLag_    = observationLag;
            adjustInfObsDates_ = adjustInfObsDates;
            infCalendar_       = infCalendar;
            dayCounter_        = dayCounter;

            // first check compatibility of index and swap definitions
            if (infIndex_.interpolated())
            {
                Period pShift = new Period(infIndex_.frequency());
                Utils.QL_REQUIRE(observationLag_ - pShift > infIndex_.availabilityLag(), () =>
                                 "inconsistency between swap observation of index " + observationLag_ +
                                 " index availability " + infIndex_.availabilityLag() +
                                 " interpolated index period " + pShift +
                                 " and index availability " + infIndex_.availabilityLag() +
                                 " need (obsLag-index period) > availLag");
            }
            else
            {
                Utils.QL_REQUIRE(infIndex_.availabilityLag() < observationLag_, () =>
                                 "index tries to observe inflation fixings that do not yet exist: "
                                 + " availability lag " + infIndex_.availabilityLag()
                                 + " versus obs lag = " + observationLag_);
            }

            if (infCalendar_ == null)
            {
                infCalendar_ = fixCalendar_;
            }
            if (infConvention == null)
            {
                infConvention_ = fixConvention_;
            }
            else
            {
                infConvention_ = infConvention.Value;
            }

            if (adjustInfObsDates_)
            {
                baseDate_ = infCalendar_.adjust(startDate - observationLag_, infConvention_);
                obsDate_  = infCalendar_.adjust(maturity - observationLag_, infConvention_);
            }
            else
            {
                baseDate_ = startDate - observationLag_;
                obsDate_  = maturity - observationLag_;
            }

            Date infPayDate   = infCalendar_.adjust(maturity, infConvention_);
            Date fixedPayDate = fixCalendar_.adjust(maturity, fixConvention_);

            // At this point the index may not be able to forecast
            // i.e. do not want to force the existence of an inflation
            // term structure before allowing users to create instruments.
            double T = Utils.inflationYearFraction(infIndex_.frequency(), infIndex_.interpolated(),
                                                   dayCounter_, baseDate_, obsDate_);
            // N.B. the -1.0 is because swaps only exchange growth, not notionals as well
            double fixedAmount = nominal * (Math.Pow(1.0 + fixedRate, T) - 1.0);

            legs_[0].Add(new SimpleCashFlow(fixedAmount, fixedPayDate));
            bool growthOnly = true;

            legs_[1].Add(new IndexedCashFlow(nominal, infIndex, baseDate_, obsDate_, infPayDate, growthOnly));

            for (int j = 0; j < 2; ++j)
            {
                legs_[j].ForEach((i, x) => x.registerWith(update));
            }

            switch (type_)
            {
            case Type.Payer:
                payer_[0] = +1.0;
                payer_[1] = -1.0;
                break;

            case Type.Receiver:
                payer_[0] = -1.0;
                payer_[1] = +1.0;
                break;

            default:
                Utils.QL_FAIL("Unknown zero-inflation-swap type");
                break;
            }
        }
Ejemplo n.º 5
0
        public CPISwap(Type type,
                       double nominal,
                       bool subtractInflationNominal,
                       // float+spread leg
                       double spread,
                       DayCounter floatDayCount,
                       Schedule floatSchedule,
                       BusinessDayConvention floatPaymentRoll,
                       int fixingDays,
                       IborIndex floatIndex,
                       // fixed x inflation leg
                       double fixedRate,
                       double baseCPI,
                       DayCounter fixedDayCount,
                       Schedule fixedSchedule,
                       BusinessDayConvention fixedPaymentRoll,
                       Period observationLag,
                       ZeroInflationIndex fixedIndex,
                       InterpolationType observationInterpolation = InterpolationType.AsIndex,
                       double?inflationNominal = null)
            : base(2)
        {
            type_    = type;
            nominal_ = nominal;
            subtractInflationNominal_ = subtractInflationNominal;
            spread_                   = spread;
            floatDayCount_            = floatDayCount;
            floatSchedule_            = floatSchedule;
            floatPaymentRoll_         = floatPaymentRoll;
            fixingDays_               = fixingDays;
            floatIndex_               = floatIndex;
            fixedRate_                = fixedRate;
            baseCPI_                  = baseCPI;
            fixedDayCount_            = fixedDayCount;
            fixedSchedule_            = fixedSchedule;
            fixedPaymentRoll_         = fixedPaymentRoll;
            fixedIndex_               = fixedIndex;
            observationLag_           = observationLag;
            observationInterpolation_ = observationInterpolation;

            Utils.QL_REQUIRE(floatSchedule_.Count > 0, () => "empty float schedule");
            Utils.QL_REQUIRE(fixedSchedule_.Count > 0, () => "empty fixed schedule");
            // todo if roll!=unadjusted then need calendars ...

            inflationNominal_ = inflationNominal ?? nominal_;

            List <CashFlow> floatingLeg;

            if (floatSchedule_.Count > 1)
            {
                floatingLeg = new IborLeg(floatSchedule_, floatIndex_)
                              .withFixingDays(fixingDays_)
                              .withPaymentDayCounter(floatDayCount_)
                              .withSpreads(spread_)
                              .withNotionals(nominal_)
                              .withPaymentAdjustment(floatPaymentRoll_);
            }
            else
            {
                floatingLeg = new List <CashFlow>();
            }

            if (floatSchedule_.Count == 1 ||
                !subtractInflationNominal_ ||
                (subtractInflationNominal && Math.Abs(nominal_ - inflationNominal_) > 0.00001)
                )
            {
                Date payNotional;
                if (floatSchedule_.Count == 1)
                {
                    // no coupons
                    payNotional = floatSchedule_[0];
                    payNotional = floatSchedule_.calendar().adjust(payNotional, floatPaymentRoll_);
                }
                else
                {
                    // use the pay date of the last coupon
                    payNotional = floatingLeg.Last().date();
                }

                double   floatAmount = subtractInflationNominal_ ? nominal_ - inflationNominal_ : nominal_;
                CashFlow nf          = new SimpleCashFlow(floatAmount, payNotional);
                floatingLeg.Add(nf);
            }

            // a CPIleg know about zero legs and inclusion of base inflation notional
            List <CashFlow> cpiLeg = new CPILeg(fixedSchedule_, fixedIndex_, baseCPI_, observationLag_)
                                     .withFixedRates(fixedRate_)
                                     .withPaymentDayCounter(fixedDayCount_)
                                     .withObservationInterpolation(observationInterpolation_)
                                     .withSubtractInflationNominal(subtractInflationNominal_)
                                     .withNotionals(inflationNominal_)
                                     .withPaymentAdjustment(fixedPaymentRoll_);

            foreach (CashFlow cashFlow in cpiLeg)
            {
                cashFlow.registerWith(update);
            }

            if (floatingLeg.Count > 0)
            {
                foreach (CashFlow cashFlow in floatingLeg)
                {
                    cashFlow.registerWith(update);
                }
            }

            legs_[0] = cpiLeg;
            legs_[1] = floatingLeg;


            if (type_ == Type.Payer)
            {
                payer_[0] = 1.0;
                payer_[1] = -1.0;
            }
            else
            {
                payer_[0] = -1.0;
                payer_[1] = 1.0;
            }
        }