Beispiel #1
0
        public ZeroCouponInflationSwapHelper(
            Handle <Quote> quote,
            Period swapObsLag, // lag on swap observation of index
            Date maturity,
            Calendar calendar, // index may have null calendar as valid on every day
            BusinessDayConvention paymentConvention,
            DayCounter dayCounter,
            ZeroInflationIndex zii)
            : base(quote)
        {
            swapObsLag_        = swapObsLag;
            maturity_          = maturity;
            calendar_          = calendar;
            paymentConvention_ = paymentConvention;
            dayCounter_        = dayCounter;
            zii_ = zii;

            if (zii_.interpolated())
            {
                // if interpolated then simple
                earliestDate_ = maturity_ - swapObsLag_;
                latestDate_   = maturity_ - swapObsLag_;
            }
            else
            {
                // but if NOT interpolated then the value is valid
                // for every day in an inflation period so you actually
                // get an extended validity, however for curve building
                // just put the first date because using that convention
                // for the base date throughout
                KeyValuePair <Date, Date> limStart = Utils.inflationPeriod(maturity_ - swapObsLag_,
                                                                           zii_.frequency());
                earliestDate_ = limStart.Key;
                latestDate_   = limStart.Key;
            }

            // check that the observation lag of the swap
            // is compatible with the availability lag of the index AND
            // it's interpolation (assuming the start day is spot)
            if (zii_.interpolated())
            {
                Period pShift = new Period(zii_.frequency());
                if ((swapObsLag_ - pShift) <= zii_.availabilityLag())
                {
                    throw new ApplicationException(
                              "inconsistency between swap observation of index "
                              + swapObsLag_ +
                              " index availability " + zii_.availabilityLag() +
                              " index period " + pShift +
                              " and index availability " + zii_.availabilityLag() +
                              " need (obsLag-index period) > availLag");
                }
            }
            Settings.registerWith(update);
        }
        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,
                                       Calendar infCalendar,
                                       BusinessDayConvention infConvention)
            : base(2)
        {
            type_           = type;
            nominal_        = nominal;
            fixedRate_      = fixedRate;
            infIndex_       = infIndex;
            observationLag_ = observationLag;
            dayCounter_     = dayCounter;

            // first check compatibility of index and swap definitions
            if (infIndex_.interpolated())
            {
                Period pShift = new Period(infIndex_.frequency());
                if ((observationLag_ - pShift) <= infIndex_.availabilityLag())
                {
                    throw new ApplicationException(
                              "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
            {
                if (infIndex_.availabilityLag() >= observationLag_)
                {
                    throw new  ApplicationException(
                              "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 == new BusinessDayConvention())
            {
                infConvention = fixConvention;
            }

            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)
            {
                for (int i = 0; i < legs_[j].Count; i++)
                {
                    legs_[j][i].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:
                throw new ApplicationException("Unknown zero-inflation-swap type");
            }
        }