/* 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.
    */
    ZeroCouponInflationSwap::ZeroCouponInflationSwap(
        Type type,
        Real nominal,
        const Date& startDate,  // start date of contract (only)
        const Date& maturity,   // this is pre-adjustment!
        const Calendar& fixCalendar,
        BusinessDayConvention fixConvention,
        const DayCounter& dayCounter,
        Rate fixedRate,
        const boost::shared_ptr<ZeroInflationIndex> &infIndex,
        const Period& observationLag,
        bool adjustInfObsDates,
        Calendar infCalendar,
        BusinessDayConvention infConvention)
    : Swap(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(infIndex_->frequency());
            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 {
            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==Calendar()) infCalendar = fixCalendar;
        if (infConvention==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.
        Real T = inflationYearFraction(infIndex_->frequency(), infIndex_->interpolated(),
                                       dayCounter_, baseDate_, obsDate_);
        // N.B. the -1.0 is because swaps only exchange growth, not notionals as well
        Real fixedAmount = nominal * ( std::pow(1.0 + fixedRate, T) - 1.0 );

        legs_[0].push_back(boost::shared_ptr<CashFlow>(
            new SimpleCashFlow(fixedAmount, fixedPayDate)));
        bool growthOnly = true;
        legs_[1].push_back(boost::shared_ptr<CashFlow>(
            new IndexedCashFlow(nominal,infIndex,baseDate_,obsDate_,infPayDate,growthOnly)));

        for (Size j=0; j<2; ++j) {
            for (Leg::iterator i = legs_[j].begin(); i!= legs_[j].end(); ++i)
                registerWith(*i);
        }

        switch (type_) {
            case Payer:
                payer_[0] = +1.0;
                payer_[1] = -1.0;
                break;
            case Receiver:
                payer_[0] = -1.0;
                payer_[1] = +1.0;
                break;
            default:
                QL_FAIL("Unknown zero-inflation-swap type");
        }

    }
Esempio n. 2
0
	inline const double shiftedP (void) const {return isGhost? (*_pression)+pShift() :(*_pression) ;}