public double fairRate()
        {
            // What does this mean before or after trade date?
            // Always means that NPV is zero for _this_ instrument
            // if it was created with _this_ rate
            // _knowing_ the time from base to obs (etc).

            IndexedCashFlow icf = legs_[1][0] as IndexedCashFlow;

            if (icf == null)
            {
                throw new ApplicationException("failed to downcast to IndexedCashFlow in ::fairRate()");
            }

            // +1 because the IndexedCashFlow has growthOnly=true
            double growth = icf.amount() / icf.notional() + 1.0;
            double T      = Utils.inflationYearFraction(infIndex_.frequency(),
                                                        infIndex_.interpolated(),
                                                        dayCounter_, baseDate_, obsDate_);

            return(Math.Pow(growth, 1.0 / T) - 1.0);

            // we cannot use this simple definition because
            // it does not work for already-issued instruments
            // return infIndex_->zeroInflationTermStructure()->zeroRate(
            //      maturityDate(), observationLag(), infIndex_->interpolated());
        }
コード例 #2
0
        public double fairRate()
        {
            // What does this mean before or after trade date?
            // Always means that NPV is zero for _this_ instrument
            // if it was created with _this_ rate
            // _knowing_ the time from base to obs (etc).

            IndexedCashFlow icf = legs_[1][0] as IndexedCashFlow;

            Utils.QL_REQUIRE(icf != null, () => "failed to downcast to IndexedCashFlow in ::fairRate()");

            // +1 because the IndexedCashFlow has growthOnly=true
            double growth = icf.amount() / icf.notional() + 1.0;
            double T      = Utils.inflationYearFraction(infIndex_.frequency(),
                                                        infIndex_.interpolated(),
                                                        dayCounter_, baseDate_, obsDate_);

            return(Math.Pow(growth, 1.0 / T) - 1.0);
        }
        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");
            }
        }