コード例 #1
0
ファイル: inflationindex.cpp プロジェクト: Barbour/quantlib
    bool ZeroInflationIndex::needsForecast(const Date& fixingDate) const {

        // Stored fixings are always non-interpolated.
        // If an interpolated fixing is required then
        // the availability lag + one inflation period
        // must have passed to use historical fixings
        // (because you need the next one to interpolate).
        // The interpolation is calculated (linearly) on demand.

        Date today = Settings::instance().evaluationDate();
        Date todayMinusLag = today - availabilityLag_;

        Date historicalFixingKnown =
            inflationPeriod(todayMinusLag, frequency_).first-1;
        Date latestNeededDate = fixingDate;

        if (interpolated_) { // might need the next one too
            std::pair<Date,Date> p = inflationPeriod(fixingDate, frequency_);
            if (fixingDate > p.first)
                latestNeededDate += Period(frequency_);
        }

        if (latestNeededDate <= historicalFixingKnown) {
            // the fixing date is well before the availability lag, so
            // we know that fixings were provided.
            return false;
        } else {
            // we're not sure, but the fixing might be there so we
            // check.  Todo: check which fixings are not possible, to
            // avoid using fixings in the future
            Real f = timeSeries()[latestNeededDate];
            return (f == Null<Real>());
        }
    }
コード例 #2
0
    Rate ZeroInflationIndex::fixing(const Date& aFixingDate,
                                    bool /*forecastTodaysFixing*/) const {
        if (!needsForecast(aFixingDate)) {
            std::pair<Date,Date> lim = inflationPeriod(aFixingDate, frequency_);
            const TimeSeries<Real>& ts = timeSeries();
            Real pastFixing = ts[lim.first];
            QL_REQUIRE(pastFixing != Null<Real>(),
                       "Missing " << name() << " fixing for " << lim.first);
            Real theFixing = pastFixing;
            if (interpolated_) {
                // fixings stored on first day of every period
                if (aFixingDate == lim.first) {
                    // we don't actually need the next fixing
                    theFixing = pastFixing;
                } else {
                    Real pastFixing2 = ts[lim.second+1];
                    QL_REQUIRE(pastFixing2 != Null<Real>(),
                               "Missing " << name() << " fixing for " << lim.second+1);

                    // Use lagged period for interpolation
                    std::pair<Date, Date> reference_period_lim = inflationPeriod(aFixingDate + zeroInflationTermStructure()->observationLag(), frequency_);
                    // now linearly interpolate
                    Real daysInPeriod = reference_period_lim.second + 1 - reference_period_lim.first;
                    theFixing = pastFixing
                        + (pastFixing2 - pastFixing)*(aFixingDate - lim.first) / daysInPeriod;
                }
            }
            return theFixing;
        } else {
            return forecastFixing(aFixingDate);
        }
    }
コード例 #3
0
ファイル: inflationindex.cpp プロジェクト: Barbour/quantlib
    Rate ZeroInflationIndex::forecastFixing(const Date& fixingDate) const {
        // the term structure is relative to the fixing value at the base date.
        Date baseDate = zeroInflation_->baseDate();
        QL_REQUIRE(!needsForecast(baseDate),
                   name() << " index fixing at base date is not available");
        Real baseFixing = fixing(baseDate);
        Date effectiveFixingDate;
        if (interpolated()) {
            effectiveFixingDate = fixingDate;
        } else {
            // start of period is the convention
            // so it's easier to do linear interpolation on fixings
            effectiveFixingDate = inflationPeriod(fixingDate, frequency()).first;
        }

        // no observation lag because it is the fixing for the date
        // but if index is not interpolated then that fixing is constant
        // for each period, hence the t uses the effectiveFixingDate
        // However, it's slightly safe to get the zeroRate with the
        // fixingDate to avoid potential problems at the edges of periods
        Time t = zeroInflation_->dayCounter().yearFraction(baseDate, effectiveFixingDate);
        bool forceLinearInterpolation = false;
        Rate zero = zeroInflation_->zeroRate(fixingDate, Period(0,Days), forceLinearInterpolation);
        // Annual compounding is the convention for zero inflation rates (or quotes)
        return baseFixing * std::pow(1.0 + zero, t);
    }
コード例 #4
0
ファイル: inflationindex.cpp プロジェクト: Barbour/quantlib
 Rate ZeroInflationIndex::fixing(const Date& aFixingDate,
                                 bool /*forecastTodaysFixing*/) const {
     if (!needsForecast(aFixingDate)) {
         const TimeSeries<Real>& ts = timeSeries();
         Real pastFixing = ts[aFixingDate];
         QL_REQUIRE(pastFixing != Null<Real>(),
                    "Missing " << name() << " fixing for " << aFixingDate);
         Real theFixing = pastFixing;
         if (interpolated_) {
             // fixings stored flat & for every day
             std::pair<Date,Date> lim =
                 inflationPeriod(aFixingDate, frequency_);
             if (aFixingDate == lim.first) {
                 // we don't actually need the next fixing
                 theFixing = pastFixing;
             } else {
                 Date fixingDate2 = aFixingDate + Period(frequency_);
                 Real pastFixing2 = ts[fixingDate2];
                 QL_REQUIRE(pastFixing2 != Null<Real>(),
                            "Missing " << name() << " fixing for " << fixingDate2);
                 // now linearly interpolate
                 Real daysInPeriod = lim.second+1 - lim.first;
                 theFixing = pastFixing
                     + (pastFixing2-pastFixing)*(aFixingDate-lim.first)/daysInPeriod;
             }
         }
         return theFixing;
     } else {
         return forecastFixing(aFixingDate);
     }
 }
コード例 #5
0
ファイル: seasonality.cpp プロジェクト: AAthresh/quantlib
    bool MultiplicativePriceSeasonality::isConsistent(const InflationTermStructure& iTS) const
    {
        // If multi-year is the specification consistent with the term structure start date?
        // We do NOT test daily seasonality because this will, in general, never be consistent
        // given weekends, holidays, leap years, etc.
        if(this->frequency() == Daily) return true;
        if(Size(this->frequency()) == seasonalityFactors().size()) return true;

        // how many years do you need to test?
        Size nTest = seasonalityFactors().size() / this->frequency();
        // ... relative to the start of the inflation curve
        std::pair<Date,Date> lim = inflationPeriod(iTS.baseDate(), iTS.frequency());
        Date curveBaseDate = lim.second;
        Real factorBase = this->seasonalityFactor(curveBaseDate);

        Real eps = 0.00001;
        for (Size i = 1; i < nTest; i++) {
            Real factorAt = this->seasonalityFactor(curveBaseDate+Period(i,Years));
            QL_REQUIRE(std::fabs(factorAt-factorBase)<eps,"seasonality is inconsistent with inflation term structure, factors "
                       << factorBase << " and later factor " << factorAt << ", " << i << " years later from inflation curve "
                       <<" with base date at " << curveBaseDate);
        }

        return true;
    }
コード例 #6
0
ファイル: cpicoupon.cpp プロジェクト: androidYibo/documents
    Real CPICashFlow::amount() const {
        Real I0 = baseFixing();
        Real I1;

        // what interpolation do we use? Index / flat / linear
        if (interpolation() == CPI::AsIndex ) {
            I1 = index()->fixing(fixingDate());
        } else {
            // work out what it should be
            //std::cout << fixingDate() << " and " << frequency() << std::endl;
            //std::pair<Date,Date> dd = inflationPeriod(fixingDate(), frequency());
            //std::cout << fixingDate() << " and " << dd.first << " " << dd.second << std::endl;
            // work out what it should be
            std::pair<Date,Date> dd = inflationPeriod(fixingDate(), frequency());
            Real indexStart = index()->fixing(dd.first);
            if (interpolation() == CPI::Linear) {
                Real indexEnd = index()->fixing(dd.second+Period(1,Days));
                // linear interpolation
                //std::cout << indexStart << " and " << indexEnd << std::endl;
                I1 = indexStart + (indexEnd - indexStart) * (fixingDate() - dd.first)
                / ( (dd.second+Period(1,Days)) - dd.first); // can't get to next period's value within current period
            } else {
                // no interpolation, i.e. flat = constant, so use start-of-period value
                I1 = indexStart;
            }

        }


        if (growthOnly())
            return notional() * (I1 / I0 - 1.0);
        else
            return notional() * (I1 / I0);
    }
コード例 #7
0
ファイル: seasonality.cpp プロジェクト: AAthresh/quantlib
 Rate MultiplicativePriceSeasonality::correctYoYRate(const Date &d,
                                                     const Rate r,
                                                     const InflationTermStructure& iTS) const {
     std::pair<Date,Date> lim = inflationPeriod(iTS.baseDate(), iTS.frequency());
     Date curveBaseDate = lim.second;
     return seasonalityCorrection(r, d, iTS.dayCounter(), curveBaseDate, false);
 }
コード例 #8
0
ファイル: cpicoupon.cpp プロジェクト: androidYibo/documents
    Rate CPICoupon::indexFixing(const Date &d) const {
        // you may want to modify the interpolation of the index
        // this gives you the chance

        Rate I1;
        // what interpolation do we use? Index / flat / linear
        if (observationInterpolation() == CPI::AsIndex) {
            I1 = cpiIndex()->fixing(d);

        } else {
            // work out what it should be
            std::pair<Date,Date> dd = inflationPeriod(d, cpiIndex()->frequency());
            Real indexStart = cpiIndex()->fixing(dd.first);
            if (observationInterpolation() == CPI::Linear) {
                Real indexEnd = cpiIndex()->fixing(dd.second+Period(1,Days));
                // linear interpolation
                I1 = indexStart + (indexEnd - indexStart) * (d - dd.first)
                / (Real)( (dd.second+Period(1,Days)) - dd.first); // can't get to next period's value within current period
            } else {
                // no interpolation, i.e. flat = constant, so use start-of-period value
                I1 = indexStart;
            }

        }
        return I1;
    }
コード例 #9
0
ファイル: inflationindex.cpp プロジェクト: lab616/third_party
    Rate ZeroInflationIndex::fixing(const Date& aFixingDate,
                                    bool /*forecastTodaysFixing*/) const {

        // Stored fixings are always non-interpolated.
        // If an interpolated fixing is required then
        // the availability lag + one inflation period
        // must have passsed to use historical fixings
        // (because you need the next one to interpolate).
        // The interpolation is calculated (linearly) on demand.

        Date today = Settings::instance().evaluationDate();
        Date todayMinusLag = today - availabilityLag_;

        std::pair<Date,Date> lim = inflationPeriod(todayMinusLag, frequency_);
        Date historicalFixingKnown = lim.first-1;
        Date fixingDateNeeded = aFixingDate;
        if (interpolated_) { // need the next one too
            fixingDateNeeded = fixingDateNeeded + Period(frequency_);
        }

        if (fixingDateNeeded <= historicalFixingKnown) {

            Real pastFixing =
                IndexManager::instance().getHistory(name())[aFixingDate];
            QL_REQUIRE(pastFixing != Null<Real>(),
                       "Missing " << name() << " fixing for " << aFixingDate);
            Real theFixing = pastFixing;

            if (interpolated_) {
                // fixings stored flat & for every day
                Date fixingDate2 = aFixingDate + Period(frequency_);
                Real pastFixing2 =
                    IndexManager::instance().getHistory(name())[fixingDate2];
                QL_REQUIRE(pastFixing2 != Null<Real>(),
                           "Missing " << name() << " fixing for " << fixingDate2);
                // now linearly interpolate
                std::pair<Date,Date> lim = inflationPeriod(aFixingDate, frequency_);
                Real daysInPeriod = lim.second+1 - lim.first;
                theFixing = pastFixing
                    + (pastFixing2-pastFixing)*(aFixingDate-lim.first)/daysInPeriod;
            }
            return theFixing;
        } else {
            return forecastFixing(aFixingDate);
        }
    }
コード例 #10
0
ファイル: inflationtraits.hpp プロジェクト: 21hub/QuantLib
 // start of curve data
 static Date initialDate(const ZeroInflationTermStructure* t) {
     if (t->indexIsInterpolated()) {
         return t->referenceDate() - t->observationLag();
     } else {
         return inflationPeriod(t->referenceDate() - t->observationLag(),
                                t->frequency()).first;
     }
 }
コード例 #11
0
    InterpolatedYoYInflationCurve<Interpolator>::
    InterpolatedYoYInflationCurve(const Date& referenceDate,
                                  const Calendar& calendar,
                                  const DayCounter& dayCounter,
                                  const Period& lag,
                                  Frequency frequency,
                                  bool indexIsInterpolated,
                                  const Handle<YieldTermStructure>& yTS,
                                  const std::vector<Date>& dates,
                                  const std::vector<Rate>& rates,
                                  const Interpolator& interpolator)
    : YoYInflationTermStructure(referenceDate, calendar, dayCounter, rates[0],
                                lag, frequency, indexIsInterpolated,  yTS),
      InterpolatedCurve<Interpolator>(std::vector<Time>(), rates, interpolator),
      dates_(dates) {

        QL_REQUIRE(dates_.size()>1, "too few dates: " << dates_.size());

        // check that the data starts from the beginning,
        // i.e. referenceDate - lag, at least must be in the relevant
        // period
        std::pair<Date,Date> lim =
            inflationPeriod(yTS->referenceDate() - this->observationLag(), frequency);
        QL_REQUIRE(lim.first <= dates_[0] && dates_[0] <= lim.second,
                   "first data date is not in base period, date: " << dates_[0]
                   << " not within [" << lim.first << "," << lim.second << "]");

        QL_REQUIRE(this->data_.size() == dates_.size(),
                   "indices/dates count mismatch: "
                   << this->data_.size() << " vs " << dates_.size());

        this->times_.resize(dates_.size());
        this->times_[0] = timeFromReference(dates_[0]);

        for (Size i = 1; i < dates_.size(); i++) {
            QL_REQUIRE(dates_[i] > dates_[i-1],
                       "dates not sorted");
            // YoY inflation data may be positive or negative
            // but must be greater than -1
            QL_REQUIRE(this->data_[i] > -1.0,
                       "year-on-year inflation data < -100 %");

            // this can be negative
            this->times_[i] = timeFromReference(dates_[i]);

            QL_REQUIRE(!close(this->times_[i],this->times_[i-1]),
                       "two dates correspond to the same time "
                       "under this curve's day count convention");
        }

        this->interpolation_ =
            this->interpolator_.interpolate(this->times_.begin(),
                                            this->times_.end(),
                                            this->data_.begin());
        this->interpolation_.update();
    }
コード例 #12
0
    Rate YoYInflationTermStructure::yoyRate(const Date &d, const Period& instObsLag,
                                              bool forceLinearInterpolation,
                                              bool extrapolate) const {

        Period useLag = instObsLag;
        if (instObsLag == Period(-1,Days)) {
            useLag = observationLag();
        }

        Rate yoyRate;
        if (forceLinearInterpolation) {
            std::pair<Date,Date> dd = inflationPeriod(d-useLag, frequency());
            dd.second = dd.second + Period(1,Days);
            Real dp = dd.second - dd.first;
            Real dt = (d-useLag) - dd.first;
            // if we are interpolating we only check the exact point
            // this prevents falling off the end at curve maturity
            InflationTermStructure::checkRange(d, extrapolate);
            Time t1 = timeFromReference(dd.first);
            Time t2 = timeFromReference(dd.second);
            Rate y1 = yoyRateImpl(t1);
            Rate y2 = yoyRateImpl(t2);
            yoyRate = y1 + (y2-y1) * (dt/dp);
        } else {
            if (indexIsInterpolated()) {
                InflationTermStructure::checkRange(d-useLag, extrapolate);
                Time t = timeFromReference(d-useLag);
                yoyRate = yoyRateImpl(t);
            } else {
                std::pair<Date,Date> dd = inflationPeriod(d-useLag, frequency());
                InflationTermStructure::checkRange(dd.first, extrapolate);
                Time t = timeFromReference(dd.first);
                yoyRate = yoyRateImpl(t);
            }
        }

        if (hasSeasonality()) {
            yoyRate = seasonality()->correctYoYRate(d-useLag, yoyRate, *this);
        }
        return yoyRate;
    }
コード例 #13
0
Time inflationYearFraction(Frequency f, bool indexIsInterpolated,
                           const DayCounter &dayCounter,
                           const Date &d1, const Date &d2) {

    Time t=0;
    if (indexIsInterpolated) {
        // N.B. we do not use linear interpolation between flat
        // fixing forecasts for forecasts.  This avoids awkwardnesses
        // when bootstrapping the inflation curve.
        t = dayCounter.yearFraction(d1, d2);
    } else {
        // I.e. fixing is constant for the whole inflation period.
        // Use the value for half way along the period.
        // But the inflation time is the time between period starts
        std::pair<Date,Date> limD1 = inflationPeriod(d1, f);
        std::pair<Date,Date> limD2 = inflationPeriod(d2, f);
        t = dayCounter.yearFraction(limD1.first, limD2.first);
    }

    return t;
}
コード例 #14
0
ファイル: inflationindex.cpp プロジェクト: Barbour/quantlib
    Real YoYInflationIndex::forecastFixing(const Date& fixingDate) const {

        Date d;
        if (interpolated()) {
            d = fixingDate;
        } else {
            // if the value is not interpolated use the starting value
            // by internal convention this will be consistent
            std::pair<Date,Date> lim = inflationPeriod(fixingDate, frequency_);
            d = lim.first;
        }
        return yoyInflation_->yoyRate(d,0*Days);
    }
    Date
    YoYOptionletVolatilitySurface::baseDate() const {

        // Depends on interpolation, or not, of observed index
        // and observation lag with which it was built.
        // We want this to work even if the index does not
        // have a yoy term structure.
        if (indexIsInterpolated()) {
            return referenceDate() - observationLag();
        } else {
            return inflationPeriod(referenceDate() - observationLag(),
                                   frequency()).first;
        }
    }
コード例 #16
0
ファイル: inflationindex.cpp プロジェクト: Barbour/quantlib
    void InflationIndex::addFixing(const Date& fixingDate,
                                   Real fixing,
                                   bool forceOverwrite) {

        std::pair<Date,Date> lim = inflationPeriod(fixingDate, frequency_);
        Size n = lim.second - lim.first + 1;
        std::vector<Date> dates(n);
        std::vector<Rate> rates(n);
        for (Size i=0; i<n; ++i) {
            dates[i] = lim.first + i;
            rates[i] = fixing;
        }

        Index::addFixings(dates.begin(), dates.end(),
                          rates.begin(), forceOverwrite);
    }
コード例 #17
0
ファイル: seasonality.cpp プロジェクト: AAthresh/quantlib
    Real MultiplicativePriceSeasonality::seasonalityFactor(const Date &to) const {

        Date from = seasonalityBaseDate();
        Frequency factorFrequency = frequency();
        Size nFactors = seasonalityFactors().size();
        Period factorPeriod(factorFrequency);
        Size which = 0;
        if (from==to) {
            which = 0;
        } else {
            // days, weeks, months, years are the only time unit possibilities
            Integer diffDays = std::abs(to - from);  // in days
            Integer dir = 1;
            if(from > to)dir = -1;
            Integer diff;
            if (factorPeriod.units() == Days) {
                diff = dir*diffDays;
            } else if (factorPeriod.units() == Weeks) {
                diff = dir * (diffDays / 7);
            } else if (factorPeriod.units() == Months) {
                std::pair<Date,Date> lim = inflationPeriod(to, factorFrequency);
                diff = diffDays / (31*factorPeriod.length());
                Date go = from + dir*diff*factorPeriod;
                while ( !(lim.first <= go && go <= lim.second) ) {
                    go += dir*factorPeriod;
                    diff++;
                }
                diff=dir*diff;
            } else if (factorPeriod.units() == Years) {
                QL_FAIL("seasonality period time unit is not allowed to be : " << factorPeriod.units());
            } else {
                QL_FAIL("Unknown time unit: " << factorPeriod.units());
            }
            // now adjust to the available number of factors, direction dependent

            if (dir==1) {
                which = diff % nFactors;
            } else {
                which = (nFactors - (-diff % nFactors)) % nFactors;
            }
        }

        return seasonalityFactors()[which];
    }
    //! needed for total variance calculations
    Time
    YoYOptionletVolatilitySurface::timeFromBase(const Date &maturityDate,
                                                const Period& obsLag) const {

        Period useLag = obsLag;
        if (obsLag==Period(-1,Days)) {
            useLag = observationLag();
        }

        Date useDate;
        if (indexIsInterpolated()) {
            useDate = maturityDate - useLag;
        } else {
            useDate = inflationPeriod(maturityDate - useLag,
                                      frequency()).first;
        }

        // This assumes that the inflation term structure starts
        // as late as possible given the inflation index definition,
        // which is the usual case.
        return dayCounter().yearFraction(baseDate(), useDate);
    }
    Volatility
    YoYOptionletVolatilitySurface::volatility(const Date& maturityDate,
                                              Rate strike,
                                              const Period &obsLag,
                                              bool extrapolate) const {

        Period useLag = obsLag;
        if (obsLag==Period(-1,Days)) {
            useLag = observationLag();
        }

        if (indexIsInterpolated()) {
            YoYOptionletVolatilitySurface::checkRange(maturityDate-useLag, strike, extrapolate);
            Time t = timeFromReference(maturityDate-useLag);
            return volatilityImpl(t,strike);
        } else {
            std::pair<Date,Date> dd = inflationPeriod(maturityDate-useLag, frequency());
            YoYOptionletVolatilitySurface::checkRange(dd.first, strike, extrapolate);
            Time t = timeFromReference(dd.first);
            return volatilityImpl(t,strike);
        }
    }
コード例 #20
0
ファイル: inflationindex.cpp プロジェクト: Barbour/quantlib
    Rate YoYInflationIndex::fixing(const Date& fixingDate,
                                   bool /*forecastTodaysFixing*/) const {

        Date today = Settings::instance().evaluationDate();
        Date todayMinusLag = today - availabilityLag_;
        std::pair<Date,Date> lim = inflationPeriod(todayMinusLag, frequency_);
        Date lastFix = lim.first-1;

        Date flatMustForecastOn = lastFix+1;
        Date interpMustForecastOn = lastFix+1 - Period(frequency_);


        if (interpolated() && fixingDate >= interpMustForecastOn) {
            return forecastFixing(fixingDate);
        }

        if (!interpolated() && fixingDate >= flatMustForecastOn) {
            return forecastFixing(fixingDate);
        }

        // four cases with ratio() and interpolated()

        const TimeSeries<Real>& ts = timeSeries();
        if (ratio()) {

            if(interpolated()){ // IS ratio, IS interpolated

                std::pair<Date,Date> lim = inflationPeriod(fixingDate, frequency_);
                Date fixMinus1Y=NullCalendar().advance(fixingDate, -1*Years, ModifiedFollowing);
                std::pair<Date,Date> limBef = inflationPeriod(fixMinus1Y, frequency_);
                Real dp= lim.second + 1 - lim.first;
                Real dpBef=limBef.second + 1 - limBef.first;
                Real dl = fixingDate-lim.first;
                // potentially does not work on 29th Feb
                Real dlBef = fixMinus1Y - limBef.first;
                // get the four relevant fixings
                // recall that they are stored flat for every day
                Rate limFirstFix = ts[lim.first];
                QL_REQUIRE(limFirstFix != Null<Rate>(),
                            "Missing " << name() << " fixing for "
                            << lim.first );
                Rate limSecondFix = ts[lim.second+1];
                QL_REQUIRE(limSecondFix != Null<Rate>(),
                            "Missing " << name() << " fixing for "
                            << lim.second+1 );
                Rate limBefFirstFix = ts[limBef.first];
                QL_REQUIRE(limBefFirstFix != Null<Rate>(),
                            "Missing " << name() << " fixing for "
                            << limBef.first );
                Rate limBefSecondFix =
                IndexManager::instance().getHistory(name())[limBef.second+1];
                QL_REQUIRE(limBefSecondFix != Null<Rate>(),
                            "Missing " << name() << " fixing for "
                            << limBef.second+1 );

                Real linearNow = limFirstFix + (limSecondFix-limFirstFix)*dl/dp;
                Real linearBef = limBefFirstFix + (limBefSecondFix-limBefFirstFix)*dlBef/dpBef;
                Rate wasYES = linearNow / linearBef - 1.0;

                return wasYES;

            } else {    // IS ratio, NOT interpolated
                Rate pastFixing = ts[fixingDate];
                QL_REQUIRE(pastFixing != Null<Rate>(),
                            "Missing " << name() << " fixing for "
                            << fixingDate);
                Date previousDate = fixingDate - 1*Years;
                Rate previousFixing = ts[previousDate];
                QL_REQUIRE(previousFixing != Null<Rate>(),
                           "Missing " << name() << " fixing for "
                           << previousDate );

                return pastFixing/previousFixing - 1.0;
            }

        } else {  // NOT ratio

            if (interpolated()) { // NOT ratio, IS interpolated

                std::pair<Date,Date> lim = inflationPeriod(fixingDate, frequency_);
                Real dp= lim.second + 1 - lim.first;
                Real dl = fixingDate-lim.first;
                Rate limFirstFix = ts[lim.first];
                QL_REQUIRE(limFirstFix != Null<Rate>(),
                            "Missing " << name() << " fixing for "
                            << lim.first );
                Rate limSecondFix = ts[lim.second+1];
                QL_REQUIRE(limSecondFix != Null<Rate>(),
                            "Missing " << name() << " fixing for "
                            << lim.second+1 );
                Real linearNow = limFirstFix + (limSecondFix-limFirstFix)*dl/dp;

                return linearNow;

            } else { // NOT ratio, NOT interpolated
                    // so just flat

                Rate pastFixing = ts[fixingDate];
                QL_REQUIRE(pastFixing != Null<Rate>(),
                           "Missing " << name() << " fixing for "
                           << fixingDate);
                return pastFixing;

            }
        }

        // QL_FAIL("YoYInflationIndex::fixing, should never get here");

    }