Skip to content

Commit

Permalink
Merge DatedOISRateHelper with OISRateHelper (#2103)
Browse files Browse the repository at this point in the history
  • Loading branch information
lballabio authored Oct 25, 2024
2 parents 5ee8f89 + 458f24b commit e3e33d4
Show file tree
Hide file tree
Showing 6 changed files with 160 additions and 159 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ int main(int, char* []) {
auto startDate = q.first.first;
auto endDate = q.first.second;
auto quote = q.second;
auto helper = ext::make_shared<DatedOISRateHelper>(
auto helper = ext::make_shared<OISRateHelper>(
startDate, endDate, Handle<Quote>(quote), eonia);
eoniaInstruments.push_back(helper);
}
Expand Down
3 changes: 2 additions & 1 deletion ql/instruments/makeois.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,8 @@ namespace QuantLib {

MakeOIS& MakeOIS::withTerminationDate(const Date& terminationDate) {
terminationDate_ = terminationDate;
swapTenor_ = Period();
if (terminationDate != Date())
swapTenor_ = Period();
return *this;
}

Expand Down
33 changes: 19 additions & 14 deletions ql/termstructures/bootstraphelper.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,7 @@
namespace QuantLib {

struct Pillar {
//! Enumeration for pillar determination alternatives
/*! These alternatives specify the determination of the pillar date. */
//! Alternatives ways of determining the pillar date
enum Choice {
MaturityDate, //! instruments maturity date
LastRelevantDate, //! last date relevant for instrument pricing
Expand Down Expand Up @@ -128,12 +127,14 @@ namespace QuantLib {
template <class TS>
class RelativeDateBootstrapHelper : public BootstrapHelper<TS> {
public:
explicit RelativeDateBootstrapHelper(const Handle<Quote>& quote);
explicit RelativeDateBootstrapHelper(Real quote);
explicit RelativeDateBootstrapHelper(const Handle<Quote>& quote,
bool updateDates = true);
explicit RelativeDateBootstrapHelper(Real quote,
bool updateDates = true);
//! \name Observer interface
//@{
void update() override {
if (evaluationDate_ != Settings::instance().evaluationDate()) {
if (updateDates_ && evaluationDate_ != Settings::instance().evaluationDate()) {
evaluationDate_ = Settings::instance().evaluationDate();
initializeDates();
}
Expand All @@ -143,6 +144,8 @@ namespace QuantLib {
protected:
virtual void initializeDates() = 0;
Date evaluationDate_;
private:
bool updateDates_;
};

// template definitions
Expand Down Expand Up @@ -210,20 +213,22 @@ namespace QuantLib {
QL_FAIL("not a bootstrap-helper visitor");
}


template <class TS>
RelativeDateBootstrapHelper<TS>::RelativeDateBootstrapHelper(
const Handle<Quote>& quote)
: BootstrapHelper<TS>(quote) {
this->registerWith(Settings::instance().evaluationDate());
evaluationDate_ = Settings::instance().evaluationDate();
const Handle<Quote>& quote, bool updateDates)
: BootstrapHelper<TS>(quote), updateDates_(updateDates) {
if (updateDates) {
this->registerWith(Settings::instance().evaluationDate());
evaluationDate_ = Settings::instance().evaluationDate();
}
}

template <class TS>
RelativeDateBootstrapHelper<TS>::RelativeDateBootstrapHelper(Real quote)
: BootstrapHelper<TS>(quote) {
this->registerWith(Settings::instance().evaluationDate());
evaluationDate_ = Settings::instance().evaluationDate();
}
RelativeDateBootstrapHelper<TS>::RelativeDateBootstrapHelper(
Real quote, bool updateDates)
: RelativeDateBootstrapHelper<TS>(makeQuoteHandle(quote), updateDates) {}


inline std::ostream& operator<<(std::ostream& out,
Pillar::Choice t) {
Expand Down
132 changes: 47 additions & 85 deletions ql/termstructures/yield/oisratehelper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,16 +50,53 @@ namespace QuantLib {
Natural lockoutDays,
bool applyObservationShift,
ext::shared_ptr<FloatingRateCouponPricer> pricer)
: RelativeDateRateHelper(fixedRate), pillarChoice_(pillar), settlementDays_(settlementDays), tenor_(tenor),
: RelativeDateRateHelper(fixedRate), settlementDays_(settlementDays), tenor_(tenor),
discountHandle_(std::move(discount)), telescopicValueDates_(telescopicValueDates),
paymentLag_(paymentLag), paymentConvention_(paymentConvention),
paymentFrequency_(paymentFrequency), paymentCalendar_(std::move(paymentCalendar)),
forwardStart_(forwardStart), overnightSpread_(overnightSpread),
forwardStart_(forwardStart), overnightSpread_(overnightSpread), pillarChoice_(pillar),
averagingMethod_(averagingMethod), endOfMonth_(endOfMonth),
fixedPaymentFrequency_(fixedPaymentFrequency), fixedCalendar_(std::move(fixedCalendar)),
lookbackDays_(lookbackDays), lockoutDays_(lockoutDays), applyObservationShift_(applyObservationShift),
pricer_(std::move(pricer)) {
initialize(overnightIndex, customPillarDate);
}

OISRateHelper::OISRateHelper(const Date& startDate,
const Date& endDate,
const Handle<Quote>& fixedRate,
const ext::shared_ptr<OvernightIndex>& overnightIndex,
Handle<YieldTermStructure> discount,
bool telescopicValueDates,
Integer paymentLag,
BusinessDayConvention paymentConvention,
Frequency paymentFrequency,
Calendar paymentCalendar,
const Spread overnightSpread,
Pillar::Choice pillar,
Date customPillarDate,
RateAveraging::Type averagingMethod,
ext::optional<bool> endOfMonth,
ext::optional<Frequency> fixedPaymentFrequency,
Calendar fixedCalendar,
Natural lookbackDays,
Natural lockoutDays,
bool applyObservationShift,
ext::shared_ptr<FloatingRateCouponPricer> pricer)
: RelativeDateRateHelper(fixedRate, false), startDate_(startDate), endDate_(endDate),
discountHandle_(std::move(discount)), telescopicValueDates_(telescopicValueDates),
paymentLag_(paymentLag), paymentConvention_(paymentConvention),
paymentFrequency_(paymentFrequency), paymentCalendar_(std::move(paymentCalendar)),
overnightSpread_(overnightSpread), pillarChoice_(pillar),
averagingMethod_(averagingMethod), endOfMonth_(endOfMonth),
fixedPaymentFrequency_(fixedPaymentFrequency), fixedCalendar_(std::move(fixedCalendar)),
lookbackDays_(lookbackDays), lockoutDays_(lockoutDays), applyObservationShift_(applyObservationShift),
pricer_(std::move(pricer)) {
initialize(overnightIndex, customPillarDate);
}

void OISRateHelper::initialize(const ext::shared_ptr<OvernightIndex>& overnightIndex,
Date customPillarDate) {
overnightIndex_ =
ext::dynamic_pointer_cast<OvernightIndex>(overnightIndex->clone(termStructureHandle_));
// We want to be notified of changes of fixings, but we don't
Expand All @@ -75,12 +112,13 @@ namespace QuantLib {
}

void OISRateHelper::initializeDates() {

// input discount curve Handle might be empty now but it could
// be assigned a curve later; use a RelinkableHandle here
MakeOIS tmp = MakeOIS(tenor_, overnightIndex_, 0.0, forwardStart_)
auto tmp = MakeOIS(tenor_, overnightIndex_, 0.0, forwardStart_)
.withDiscountingTermStructure(discountRelinkableHandle_)
.withSettlementDays(settlementDays_)
.withSettlementDays(settlementDays_) // resets effectiveDate
.withEffectiveDate(startDate_)
.withTerminationDate(endDate_)
.withTelescopicValueDates(telescopicValueDates_)
.withPaymentLag(paymentLag_)
.withPaymentAdjustment(paymentConvention_)
Expand Down Expand Up @@ -187,55 +225,10 @@ namespace QuantLib {
Natural lockoutDays,
bool applyObservationShift,
const ext::shared_ptr<FloatingRateCouponPricer>& pricer)
: RateHelper(fixedRate), discountHandle_(std::move(discount)),
telescopicValueDates_(telescopicValueDates), averagingMethod_(averagingMethod) {

auto clonedOvernightIndex =
ext::dynamic_pointer_cast<OvernightIndex>(overnightIndex->clone(termStructureHandle_));
// We want to be notified of changes of fixings, but we don't
// want notifications from termStructureHandle_ (they would
// interfere with bootstrapping.)
clonedOvernightIndex->unregisterWith(termStructureHandle_);

registerWith(clonedOvernightIndex);
registerWith(discountHandle_);

// input discount curve Handle might be empty now but it could
// be assigned a curve later; use a RelinkableHandle here
auto tmp = MakeOIS(Period(), clonedOvernightIndex, 0.0)
.withDiscountingTermStructure(discountRelinkableHandle_)
.withEffectiveDate(startDate)
.withTerminationDate(endDate)
.withTelescopicValueDates(telescopicValueDates_)
.withPaymentLag(paymentLag)
.withPaymentAdjustment(paymentConvention)
.withPaymentFrequency(paymentFrequency)
.withPaymentCalendar(paymentCalendar)
.withOvernightLegSpread(overnightSpread)
.withAveragingMethod(averagingMethod_)
.withLookbackDays(lookbackDays)
.withLockoutDays(lockoutDays)
.withObservationShift(applyObservationShift);
if (endOfMonth) {
tmp.withEndOfMonth(*endOfMonth);
}
if (fixedPaymentFrequency) {
tmp.withFixedLegPaymentFrequency(*fixedPaymentFrequency);
}
if (!fixedCalendar.empty()) {
tmp.withFixedLegCalendar(fixedCalendar);
}
swap_ = tmp;

if (pricer)
setCouponPricer(swap_->overnightLeg(), pricer);

earliestDate_ = swap_->startDate();
maturityDate_ = swap_->maturityDate();
Date lastPaymentDate = std::max(swap_->overnightLeg().back()->date(),
swap_->fixedLeg().back()->date());
latestRelevantDate_ = latestDate_ = std::max(maturityDate_, lastPaymentDate);
}
: OISRateHelper(startDate, endDate, fixedRate, overnightIndex, std::move(discount), telescopicValueDates,
paymentLag, paymentConvention, paymentFrequency, paymentCalendar, overnightSpread,
Pillar::LastRelevantDate, Date(), averagingMethod, endOfMonth, fixedPaymentFrequency,
fixedCalendar, lookbackDays, lockoutDays, applyObservationShift, pricer) {}

DatedOISRateHelper::DatedOISRateHelper(const Date& startDate,
const Date& endDate,
Expand All @@ -257,35 +250,4 @@ namespace QuantLib {
averagingMethod, paymentLag, paymentConvention, paymentFrequency, paymentCalendar,
overnightSpread, endOfMonth, fixedPaymentFrequency, fixedCalendar) {}

void DatedOISRateHelper::setTermStructure(YieldTermStructure* t) {
// do not set the relinkable handle as an observer -
// force recalculation when needed
bool observer = false;

ext::shared_ptr<YieldTermStructure> temp(t, null_deleter());
termStructureHandle_.linkTo(temp, observer);

if (discountHandle_.empty())
discountRelinkableHandle_.linkTo(temp, observer);
else
discountRelinkableHandle_.linkTo(*discountHandle_, observer);

RateHelper::setTermStructure(t);
}

Real DatedOISRateHelper::impliedQuote() const {
QL_REQUIRE(termStructure_ != nullptr, "term structure not set");
// we didn't register as observers - force calculation
swap_->deepUpdate();
return swap_->fairRate();
}

void DatedOISRateHelper::accept(AcyclicVisitor& v) {
auto* v1 = dynamic_cast<Visitor<DatedOISRateHelper>*>(&v);
if (v1 != nullptr)
v1->visit(*this);
else
RateHelper::accept(v);
}

}
Loading

0 comments on commit e3e33d4

Please sign in to comment.