Skip to content

Commit

Permalink
Merge 0f27598 into b15c427
Browse files Browse the repository at this point in the history
  • Loading branch information
lballabio committed Jan 26, 2024
2 parents b15c427 + 0f27598 commit 3e42b35
Show file tree
Hide file tree
Showing 20 changed files with 984 additions and 166 deletions.
5 changes: 3 additions & 2 deletions ql/experimental/inflation/cpicapfloortermpricesurface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,11 @@ namespace QuantLib {
const std::vector<Period>& cfMaturities,
const Matrix& cPrice,
const Matrix& fPrice)
: InflationTermStructure(0, cal, baseRate, observationLag, zii->frequency(), dc),
: TermStructure(0, cal, dc),
zii_(zii), interpolationType_(interpolationType), nominalTS_(std::move(yts)),
cStrikes_(cStrikes), fStrikes_(fStrikes), cfMaturities_(cfMaturities),
cPrice_(cPrice), fPrice_(fPrice), nominal_(nominal), bdc_(bdc) {
cPrice_(cPrice), fPrice_(fPrice), nominal_(nominal), bdc_(bdc),
observationLag_(observationLag), baseRate_(baseRate) {

// does the index have a TS?
QL_REQUIRE(!zii_->zeroInflationTermStructure().empty(), "ZITS missing from index");
Expand Down
20 changes: 16 additions & 4 deletions ql/experimental/inflation/cpicapfloortermpricesurface.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ namespace QuantLib {
The observationLag is that for the referenced instrument prices.
Strikes are as-quoted not as-used.
*/
class CPICapFloorTermPriceSurface : public InflationTermStructure {
class CPICapFloorTermPriceSurface : public TermStructure {
public:
CPICapFloorTermPriceSurface(
Real nominal,
Expand All @@ -71,8 +71,10 @@ namespace QuantLib {

//! \name InflationTermStructure interface
//@{
Period observationLag() const override;
Date baseDate() const override;
virtual Period observationLag() const;
virtual Frequency frequency() const;
virtual Date baseDate() const;
virtual Rate baseRate() const;
//@}

//! inspectors
Expand Down Expand Up @@ -138,6 +140,8 @@ namespace QuantLib {
private:
Real nominal_;
BusinessDayConvention bdc_;
Period observationLag_;
Rate baseRate_;
};


Expand Down Expand Up @@ -326,13 +330,21 @@ namespace QuantLib {
// inline definitions

inline Period CPICapFloorTermPriceSurface::observationLag() const {
return zeroInflationIndex()->zeroInflationTermStructure()->observationLag();
return observationLag_;
}

inline Frequency CPICapFloorTermPriceSurface::frequency() const {
return zeroInflationIndex()->frequency();
}

inline Date CPICapFloorTermPriceSurface::baseDate() const {
return zeroInflationIndex()->zeroInflationTermStructure()->baseDate();
}

inline Rate CPICapFloorTermPriceSurface::baseRate() const {
return baseRate_;
}

inline Real CPICapFloorTermPriceSurface::nominal() const {
return nominal_;
}
Expand Down
6 changes: 2 additions & 4 deletions ql/experimental/inflation/yoycapfloortermpricesurface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@ namespace QuantLib {
const std::vector<Period>& cfMaturities,
const Matrix& cPrice,
const Matrix& fPrice)
: InflationTermStructure(0, cal, baseRate, lag, yii->frequency(), dc),
fixingDays_(fixingDays), bdc_(bdc), yoyIndex_(yii), nominalTS_(std::move(nominal)),
: TermStructure(0, cal, dc),
fixingDays_(fixingDays), bdc_(bdc), yoyIndex_(yii), observationLag_(lag), nominalTS_(std::move(nominal)),
cStrikes_(cStrikes), fStrikes_(fStrikes), cfMaturities_(cfMaturities), cPrice_(cPrice),
fPrice_(fPrice), indexIsInterpolated_(yii->interpolated()) {

Expand Down Expand Up @@ -128,7 +128,5 @@ namespace QuantLib {
return atmYoYRate(yoyOptionDateFromTenor(d), obsLag, extrapolate);
}



}

33 changes: 25 additions & 8 deletions ql/experimental/inflation/yoycapfloortermpricesurface.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ namespace QuantLib {
\todo deal with index interpolation.
*/
class YoYCapFloorTermPriceSurface : public InflationTermStructure {
class YoYCapFloorTermPriceSurface : public TermStructure {
public:
YoYCapFloorTermPriceSurface(Natural fixingDays,
const Period& yyLag,
Expand All @@ -56,6 +56,8 @@ namespace QuantLib {
const Matrix& fPrice);

bool indexIsInterpolated() const;
virtual Period observationLag() const;
virtual Frequency frequency() const;

//! atm yoy swaps from put-call parity on cap/floor data
/*! uses interpolation (on surface price data), yearly maturities. */
Expand All @@ -79,6 +81,7 @@ namespace QuantLib {
//@{
virtual BusinessDayConvention businessDayConvention() const {return bdc_;}
virtual Natural fixingDays() const {return fixingDays_;}
virtual Date baseDate() const = 0;
virtual Real price(const Date& d, Rate k) const = 0;
virtual Real capPrice(const Date& d, Rate k) const = 0;
virtual Real floorPrice(const Date& d, Rate k) const = 0;
Expand Down Expand Up @@ -124,6 +127,7 @@ namespace QuantLib {
Natural fixingDays_;
BusinessDayConvention bdc_;
ext::shared_ptr<YoYInflationIndex> yoyIndex_;
Period observationLag_;
Handle<YieldTermStructure> nominalTS_;
// data
std::vector<Rate> cStrikes_;
Expand Down Expand Up @@ -189,8 +193,9 @@ namespace QuantLib {
bool extrapolate = true) const override {
// work in terms of maturity-of-instruments
// so ask for rate with observation lag
Period p = (obsLag == Period(-1, Days)) ? observationLag() : obsLag;
// Third parameter = force linear interpolation of yoy
return yoy_->yoyRate(d, obsLag, false, extrapolate);
return yoy_->yoyRate(d, p, false, extrapolate);
}
//@}

Expand Down Expand Up @@ -234,6 +239,14 @@ namespace QuantLib {
return indexIsInterpolated_;
}

inline Period YoYCapFloorTermPriceSurface::observationLag() const {
return observationLag_;
}

inline Frequency YoYCapFloorTermPriceSurface::frequency() const {
return yoyIndex_->frequency();
}

// template definitions

#ifndef __DOXYGEN__
Expand Down Expand Up @@ -528,18 +541,22 @@ namespace QuantLib {
YYhelpers.push_back (anInstrument);
}

Date baseDate =
yoyIndex()->interpolated() ?
nominalTS_->referenceDate() - observationLag() :
inflationPeriod(nominalTS_->referenceDate() - observationLag(),
yoyIndex()->frequency()).first;
// usually this base rate is known
// however for the data to be self-consistent
// we pick this as the end of the curve
Rate baseYoYRate = atmYoYSwapRate( referenceDate() );//!

// Linear is OK because we have every year
ext::shared_ptr<PiecewiseYoYInflationCurve<Linear> > pYITS(
new PiecewiseYoYInflationCurve<Linear>(
nominalTS_->referenceDate(),
calendar(), dayCounter(), observationLag(), yoyIndex()->frequency(),
yoyIndex()->interpolated(), baseYoYRate,
YYhelpers));
auto pYITS =
ext::make_shared<PiecewiseYoYInflationCurve<Linear>>(
nominalTS_->referenceDate(), baseDate, baseYoYRate,
yoyIndex()->frequency(), yoyIndex()->interpolated(),
dayCounter(), YYhelpers);
pYITS->recalculate();
yoy_ = pYITS; // store

Expand Down
6 changes: 6 additions & 0 deletions ql/indexes/inflationindex.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,12 @@ namespace QuantLib {
}
}

Date ZeroInflationIndex::lastFixingDate() const {
const auto& fixings = timeSeries();
QL_REQUIRE(!fixings.empty(), "no fixings stored for " << name());
// attribute fixing to first day of the underlying period
return inflationPeriod(fixings.lastDate(), frequency_).first;
}

bool ZeroInflationIndex::needsForecast(const Date& fixingDate) const {

Expand Down
1 change: 1 addition & 0 deletions ql/indexes/inflationindex.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,7 @@ namespace QuantLib {
//@}
//! \name Other methods
//@{
Date lastFixingDate() const;
Handle<ZeroInflationTermStructure> zeroInflationTermStructure() const;
ext::shared_ptr<ZeroInflationIndex> clone(const Handle<ZeroInflationTermStructure>& h) const;
//@}
Expand Down
25 changes: 13 additions & 12 deletions ql/termstructures/inflation/inflationtraits.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,11 +44,15 @@ namespace QuantLib {

// start of curve data
static Date initialDate(const ZeroInflationTermStructure* t) {
return inflationPeriod(t->referenceDate() - t->observationLag(), t->frequency()).first;
if (t->hasExplicitBaseDate())
return t->baseDate();
else
return inflationPeriod(t->referenceDate() - t->observationLag(), t->frequency()).first;
}
// value at reference date
static Rate initialValue(const ZeroInflationTermStructure* t) {
return t->baseRate();
static Rate initialValue(const ZeroInflationTermStructure*) {
// this will be overwritten during bootstrap
return detail::avgInflation;
}

// guesses
Expand All @@ -61,10 +65,6 @@ namespace QuantLib {
if (validData) // previous iteration value
return c->data()[i];

if (i==1) // first pillar
return detail::avgInflation;

// could/should extrapolate
return detail::avgInflation;
}

Expand Down Expand Up @@ -101,6 +101,8 @@ namespace QuantLib {
Rate level,
Size i) {
data[i] = level;
if (i==1)
data[0] = level; // the first point is updated as well
}
// upper bound for convergence loop
// calibration is trivial, should be immediate
Expand All @@ -115,13 +117,16 @@ namespace QuantLib {

// start of curve data
static Date initialDate(const YoYInflationTermStructure* t) {
if (t->indexIsInterpolated()) {
if (t->hasExplicitBaseDate()) {
return t->baseDate();
} else if (t->indexIsInterpolated()) {
return t->referenceDate() - t->observationLag();
} else {
return inflationPeriod(t->referenceDate() - t->observationLag(),
t->frequency()).first;
}
}

// value at reference date
static Rate initialValue(const YoYInflationTermStructure* t) {
return t->baseRate();
Expand All @@ -137,10 +142,6 @@ namespace QuantLib {
if (validData) // previous iteration value
return c->data()[i];

if (i==1) // first pillar
return detail::avgInflation;

// could/should extrapolate
return detail::avgInflation;
}

Expand Down
90 changes: 86 additions & 4 deletions ql/termstructures/inflation/interpolatedyoyinflationcurve.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,20 @@ namespace QuantLib {
: public YoYInflationTermStructure,
protected InterpolatedCurve<Interpolator> {
public:
InterpolatedYoYInflationCurve(const Date& referenceDate,
std::vector<Date> dates,
const std::vector<Rate>& rates,
Frequency frequency,
bool indexIsInterpolated,
const DayCounter& dayCounter,
const ext::shared_ptr<Seasonality>& seasonality = {},
const Interpolator& interpolator = Interpolator());

/*! \deprecated Use the other overload and pass the base date directly
as the first date in the vector instead of using a lag.
Deprecated in version 1.34.
*/
QL_DEPRECATED
InterpolatedYoYInflationCurve(const Date& referenceDate,
const Calendar& calendar,
const DayCounter& dayCounter,
Expand Down Expand Up @@ -80,15 +94,28 @@ namespace QuantLib {
(or can't) provide the points for interpolation on
construction.
*/
InterpolatedYoYInflationCurve(const Date& referenceDate,
Date baseDate,
Rate baseYoYRate,
Frequency frequency,
bool indexIsInterpolated,
const DayCounter& dayCounter,
const ext::shared_ptr<Seasonality>& seasonality = {},
const Interpolator& interpolator = Interpolator());

/*! \deprecated Use the other overload and pass the base date directly
instead of using a lag.
Deprecated in version 1.34.
*/
QL_DEPRECATED
InterpolatedYoYInflationCurve(const Date& referenceDate,
const Calendar& calendar,
const DayCounter& dayCounter,
Rate baseYoYRate,
const Period& lag,
Frequency frequency,
bool indexIsInterpolated,
const Interpolator& interpolator
= Interpolator());
const Interpolator& interpolator = Interpolator());
};

typedef InterpolatedYoYInflationCurve<Linear> YoYInflationCurve;
Expand All @@ -97,6 +124,56 @@ namespace QuantLib {

// template definitions

template <class Interpolator>
InterpolatedYoYInflationCurve<Interpolator>::InterpolatedYoYInflationCurve(
const Date& referenceDate,
std::vector<Date> dates,
const std::vector<Rate>& rates,
Frequency frequency,
bool indexIsInterpolated,
const DayCounter& dayCounter,
const ext::shared_ptr<Seasonality>& seasonality,
const Interpolator& interpolator)
: YoYInflationTermStructure(referenceDate, dates.at(0), rates[0], frequency,
indexIsInterpolated, dayCounter, seasonality),
InterpolatedCurve<Interpolator>(std::vector<Time>(), rates, interpolator),
dates_(std::move(dates)) {

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

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

for (Size i = 1; i < dates_.size(); i++) {
// 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->setupTimes(dates_, referenceDate, dayCounter);
this->setupInterpolation();
this->interpolation_.update();
}

template <class Interpolator>
InterpolatedYoYInflationCurve<Interpolator>::
InterpolatedYoYInflationCurve(const Date& referenceDate,
Date baseDate,
Rate baseYoYRate,
Frequency frequency,
bool indexIsInterpolated,
const DayCounter& dayCounter,
const ext::shared_ptr<Seasonality>& seasonality,
const Interpolator& interpolator)
: YoYInflationTermStructure(referenceDate, baseDate, baseYoYRate, frequency,
indexIsInterpolated, dayCounter, seasonality),
InterpolatedCurve<Interpolator>(interpolator) {}


QL_DEPRECATED_DISABLE_WARNING

template <class Interpolator>
InterpolatedYoYInflationCurve<Interpolator>::InterpolatedYoYInflationCurve(
const Date& referenceDate,
Expand Down Expand Up @@ -154,10 +231,15 @@ namespace QuantLib {
lag, frequency, indexIsInterpolated),
InterpolatedCurve<Interpolator>(interpolator) {}

QL_DEPRECATED_ENABLE_WARNING


template <class T>
Date InterpolatedYoYInflationCurve<T>::baseDate() const{
return dates_.front();
Date InterpolatedYoYInflationCurve<T>::baseDate() const {
if (hasExplicitBaseDate())
return YoYInflationTermStructure::baseDate();
else
return dates_.front();
}

template <class T>
Expand Down
Loading

0 comments on commit 3e42b35

Please sign in to comment.