Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 8 additions & 4 deletions ql/indexes/inflationindex.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,11 @@ namespace QuantLib {

Real ZeroInflationIndex::fixing(const Date& fixingDate,
bool /*forecastTodaysFixing*/) const {
return fixing(fixingDate, false, true);
}

Real ZeroInflationIndex::fixing(const Date& fixingDate,
bool /*forecastTodaysFixing*/, bool applySeasonality) const {
if (!needsForecast(fixingDate)) {
const Real I1 = pastFixing(fixingDate);
QL_REQUIRE(I1 != Null<Real>(),
Expand All @@ -209,7 +214,7 @@ namespace QuantLib {

return I1;
} else {
return forecastFixing(fixingDate);
return forecastFixing(fixingDate, applySeasonality);
}
}

Expand Down Expand Up @@ -254,8 +259,7 @@ namespace QuantLib {
}
}


Real ZeroInflationIndex::forecastFixing(const Date& fixingDate) const {
Real ZeroInflationIndex::forecastFixing(const Date& fixingDate, bool applySeasonality) const {
// the term structure is relative to the fixing value at the base date.
Date baseDate = zeroInflation_->baseDate();
QL_REQUIRE(!needsForecast(baseDate),
Expand All @@ -265,7 +269,7 @@ namespace QuantLib {
std::pair<Date, Date> fixingPeriod = inflationPeriod(fixingDate, frequency_);

Date firstDateInPeriod = fixingPeriod.first;
Rate Z1 = zeroInflation_->zeroRate(firstDateInPeriod, Period(0,Days), false);
Rate Z1 = zeroInflation_->zeroRate(firstDateInPeriod, Period(0,Days), false, false, applySeasonality);
Time t1 = inflationYearFraction(frequency_, false, zeroInflation_->dayCounter(),
baseDate, firstDateInPeriod);
return baseFixing * std::pow(1.0 + Z1, t1);
Expand Down
7 changes: 5 additions & 2 deletions ql/indexes/inflationindex.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,10 @@ namespace QuantLib {
/*! \warning the forecastTodaysFixing parameter (required by
the Index interface) is currently ignored.
*/
Real fixing(const Date& fixingDate, bool forecastTodaysFixing = false) const override;
Real fixing(const Date& fixingDate, bool forecastTodaysFixing = false) const override; // required
Real fixing(const Date& fixingDate,
bool forecastTodaysFixing,
bool applySeasonality) const; // overload
Real pastFixing(const Date& fixingDate) const override;
//@}
//! \name Other methods
Expand All @@ -178,7 +181,7 @@ namespace QuantLib {
bool needsForecast(const Date& fixingDate) const;
//@}
private:
Real forecastFixing(const Date& fixingDate) const;
Real forecastFixing(const Date& fixingDate, bool applySeasonality = true) const;
Handle<ZeroInflationTermStructure> zeroInflation_;
};

Expand Down
5 changes: 4 additions & 1 deletion ql/instruments/zerocouponinflationswap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,8 @@ namespace QuantLib {
inflationYearFraction(infIndex_->frequency(),
detail::CPI::isInterpolated(observationInterpolation_),
dayCounter_, baseDate_, obsDate_);
// Mimic yearly compounding 1/1 DC with Year (which can return zero).
T = T == 0 ? 1 : T;
// 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);

Expand Down Expand Up @@ -134,7 +136,8 @@ namespace QuantLib {
inflationYearFraction(infIndex_->frequency(),
detail::CPI::isInterpolated(observationInterpolation_),
dayCounter_, baseDate_, obsDate_);

// Year DC can return zero which is not wanted
T = T == 0 ? 1 : T;
return std::pow(growth,1.0/T) - 1.0;

// we cannot use this simple definition because
Expand Down
4 changes: 2 additions & 2 deletions ql/termstructures/inflation/seasonality.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -248,8 +248,8 @@ namespace QuantLib {
Time timeFromCurveBase = dc.yearFraction(curveBaseDate, p.first);
f = std::pow(seasonalityAt, 1 / timeFromCurveBase);
} else {
Rate factor1Ybefore = this->seasonalityFactor(atDate - Period(1, Years));
f = factorAt / factor1Ybefore;
Rate factorBefore = this->seasonalityFactor(curveBaseDate);
f = factorAt / factorBefore;
}

return (rate + 1) / f - 1;
Expand Down
5 changes: 3 additions & 2 deletions ql/termstructures/inflationtermstructure.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,8 @@ namespace QuantLib {

Rate ZeroInflationTermStructure::zeroRate(const Date &d, const Period& instObsLag,
bool forceLinearInterpolation,
bool extrapolate) const {
bool extrapolate,
bool applySeasonality) const {

Period useLag = instObsLag;
if (instObsLag == Period(-1,Days)) {
Expand Down Expand Up @@ -256,7 +257,7 @@ namespace QuantLib {
zeroRate = zeroRateImpl(t);
}

if (hasSeasonality()) {
if (hasSeasonality() && applySeasonality) {
zeroRate = seasonality()->correctZeroRate(d-useLag, zeroRate, *this);
}
return zeroRate;
Expand Down
3 changes: 2 additions & 1 deletion ql/termstructures/inflationtermstructure.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -242,7 +242,8 @@ namespace QuantLib {
*/
Rate zeroRate(const Date& d, const Period& instObsLag = Period(-1,Days),
bool forceLinearInterpolation = false,
bool extrapolate = false) const;
bool extrapolate = false,
bool applySeasonality = true) const;
//! zero-coupon inflation rate.
/*! \warning Since inflation is highly linked to dates (lags,
interpolation, months for seasonality, etc) this
Expand Down