Skip to content

Commit

Permalink
Deprecate most of the IndexManager public interface.
Browse files Browse the repository at this point in the history
It will not be removed, but moved to the private section for use
by Index.  Client code will go through indexes.
  • Loading branch information
lballabio committed Oct 15, 2024
1 parent 8d297ba commit 9f78db2
Show file tree
Hide file tree
Showing 13 changed files with 94 additions and 71 deletions.
4 changes: 1 addition & 3 deletions ql/cashflows/digitalcoupon.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -238,9 +238,7 @@ namespace QuantLib {
rate_ = underlyingRate + callCsi_ * callPayoff() + putCsi_ * putPayoff();
} else if (fixingDate == today) {
// might have been fixed
Rate pastFixing =
IndexManager::instance().getHistory((underlying_->index())->name())[fixingDate];
if (pastFixing != Null<Real>()) {
if (underlying_->index()->hasHistoricalFixing(fixingDate)) {
rate_ = underlyingRate + callCsi_ * callPayoff() + putCsi_ * putPayoff();
} else {
rate_ = underlyingRate + callCsi_ * callOptionRate() + putCsi_ * putOptionRate();
Expand Down
9 changes: 5 additions & 4 deletions ql/cashflows/overnightindexedcouponpricer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ namespace QuantLib {

const ext::shared_ptr<OvernightIndex> index =
ext::dynamic_pointer_cast<OvernightIndex>(coupon_->index());
const auto& pastFixings = IndexManager::instance().getHistory(index->name());
const auto& pastFixings = index->timeSeries();

const auto& fixingDates = coupon_->fixingDates();
const auto& valueDates = coupon_->valueDates();
Expand Down Expand Up @@ -194,11 +194,13 @@ namespace QuantLib {

Real accumulatedRate = 0.0;

const auto& pastFixings = index->timeSeries();

// already fixed part
Date today = Settings::instance().evaluationDate();
while (i < n && fixingDates[i] < today) {
// rate must have been fixed
Rate pastFixing = IndexManager::instance().getHistory(index->name())[fixingDates[i]];
Rate pastFixing = pastFixings[fixingDates[i]];
QL_REQUIRE(pastFixing != Null<Real>(),
"Missing " << index->name() << " fixing for " << fixingDates[i]);
accumulatedRate += pastFixing * dt[i];
Expand All @@ -209,8 +211,7 @@ namespace QuantLib {
if (i < n && fixingDates[i] == today) {
// might have been fixed
try {
Rate pastFixing =
IndexManager::instance().getHistory(index->name())[fixingDates[i]];
Rate pastFixing = pastFixings[fixingDates[i]];
if (pastFixing != Null<Real>()) {
accumulatedRate += pastFixing * dt[i];
++i;
Expand Down
2 changes: 1 addition & 1 deletion ql/experimental/commodities/commodityindex.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ namespace QuantLib {
forwardCurve_(std::move(forwardCurve)), exchangeContracts_(std::move(exchangeContracts)),
nearbyOffset_(nearbyOffset) {
registerWith(Settings::instance().evaluationDate());
registerWith(IndexManager::instance().notifier(name()));
registerWith(notifier());

if (forwardCurve_ != nullptr)
// registerWith(forwardCurve_);
Expand Down
2 changes: 2 additions & 0 deletions ql/index.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,9 @@ namespace QuantLib {

void Index::clearFixings() {
checkNativeFixingsAllowed();
QL_DEPRECATED_DISABLE_WARNING
IndexManager::instance().clearHistory(name());
QL_DEPRECATED_ENABLE_WARNING
}

void Index::checkNativeFixingsAllowed() {
Expand Down
12 changes: 12 additions & 0 deletions ql/index.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,9 @@ namespace QuantLib {
virtual Real pastFixing(const Date& fixingDate) const;
//! returns the fixing TimeSeries
const TimeSeries<Real>& timeSeries() const {
QL_DEPRECATED_DISABLE_WARNING
return IndexManager::instance().getHistory(name());
QL_DEPRECATED_ENABLE_WARNING
}
//! check if index allows for native fixings.
/*! If this returns false, calls to addFixing and similar
Expand Down Expand Up @@ -107,13 +109,23 @@ namespace QuantLib {
//! clears all stored historical fixings
void clearFixings();

protected:
ext::shared_ptr<Observable> notifier() const {
QL_DEPRECATED_DISABLE_WARNING
return IndexManager::instance().notifier(name());
QL_DEPRECATED_ENABLE_WARNING
}

private:
//! check if index allows for native fixings
void checkNativeFixingsAllowed();

};

inline bool Index::hasHistoricalFixing(const Date& fixingDate) const {
QL_DEPRECATED_DISABLE_WARNING
return IndexManager::instance().hasHistoricalFixing(name(), fixingDate);
QL_DEPRECATED_ENABLE_WARNING
}

inline Real Index::pastFixing(const Date& fixingDate) const {
Expand Down
4 changes: 2 additions & 2 deletions ql/indexes/equityindex.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ namespace QuantLib {
registerWith(dividend_);
registerWith(spot_);
registerWith(Settings::instance().evaluationDate());
registerWith(IndexManager::instance().notifier(EquityIndex::name()));
registerWith(notifier());
}

Real EquityIndex::fixing(const Date& fixingDate, bool forecastTodaysFixing) const {
Expand Down Expand Up @@ -107,4 +107,4 @@ namespace QuantLib {
return ext::make_shared<EquityIndex>(name(), fixingCalendar(), currency(), interest,
dividend, spot);
}
}
}
6 changes: 6 additions & 0 deletions ql/indexes/indexmanager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,9 @@ namespace QuantLib {
}

void IndexManager::setHistory(const std::string& name, TimeSeries<Real> history) {
QL_DEPRECATED_DISABLE_WARNING
notifier(name)->notifyObservers();
QL_DEPRECATED_ENABLE_WARNING
data_[name] = std::move(history);
}

Expand Down Expand Up @@ -59,13 +61,17 @@ namespace QuantLib {
}

void IndexManager::clearHistory(const std::string& name) {
QL_DEPRECATED_DISABLE_WARNING
notifier(name)->notifyObservers();
QL_DEPRECATED_ENABLE_WARNING
data_.erase(name);
}

void IndexManager::clearHistories() {
QL_DEPRECATED_DISABLE_WARNING
for (auto const& d : data_)
notifier(d.first)->notifyObservers();
QL_DEPRECATED_ENABLE_WARNING
data_.clear();
}

Expand Down
91 changes: 60 additions & 31 deletions ql/indexes/indexmanager.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,67 @@ namespace QuantLib {
/*! \note index names are case insensitive */
class IndexManager : public Singleton<IndexManager> {
friend class Singleton<IndexManager>;
friend class Index;

private:
IndexManager() = default;
friend class Index;

public:
//! returns all names of the indexes for which fixings were stored
std::vector<std::string> histories() const;
//! clears all stored fixings
void clearHistories();

// deprecated in order to be moved into the private section

/*! \deprecated Use Index::hasHistoricalFixing instead.
Deprecated in version 1.37.
*/
[[deprecated("Use Index::hasHistoricalFixing instead")]]
bool hasHistory(const std::string& name) const;

/*! \deprecated Use Index::timeSeries instead.
Deprecated in version 1.37.
*/
[[deprecated("Use Index::timeSeries instead")]]
const TimeSeries<Real>& getHistory(const std::string& name) const;

/*! \deprecated Use Index::clearFixings instead.
Deprecated in version 1.37.
*/
[[deprecated("Use Index::clearFixings instead")]]
void clearHistory(const std::string& name);

/*! \deprecated Use Index::hasHistoricalFixing instead.
Deprecated in version 1.37.
*/
[[deprecated("Use Index::hasHistoricalFixing instead")]]
bool hasHistoricalFixing(const std::string& name, const Date& fixingDate) const;

/*! \deprecated Use Index::addFixings instead.
Deprecated in version 1.37.
*/
[[deprecated("Use Index::addFixings instead")]]
void setHistory(const std::string& name, TimeSeries<Real> history);

/*! \deprecated Register with the relevant index instead.
Deprecated in version 1.37.
*/
[[deprecated("Register with the relevant index instead")]]
ext::shared_ptr<Observable> notifier(const std::string& name) const;

private:
struct CaseInsensitiveCompare {
bool operator()(const std::string& s1, const std::string& s2) const {
return std::lexicographical_compare(s1.begin(), s1.end(), s2.begin(), s2.end(), [](const auto& c1, const auto& c2) {
return std::toupper(static_cast<unsigned char>(c1)) < std::toupper(static_cast<unsigned char>(c2));
});
}
};

mutable std::map<std::string, TimeSeries<Real>, CaseInsensitiveCompare> data_;
mutable std::map<std::string, ext::shared_ptr<Observable>> notifiers_;

//! add a fixing
void addFixing(const std::string& name,
const Date& fixingDate,
Expand Down Expand Up @@ -81,7 +138,9 @@ namespace QuantLib {
invalidValue = *(vBegin++);
}
}
QL_DEPRECATED_DISABLE_WARNING
notifier(name)->notifyObservers();
QL_DEPRECATED_ENABLE_WARNING
QL_REQUIRE(noInvalidFixing, "At least one invalid fixing provided: "
<< invalidDate.weekday() << " " << invalidDate << ", "
<< invalidValue);
Expand All @@ -90,36 +149,6 @@ namespace QuantLib {
<< " while " << h[duplicatedDate]
<< " value is already present");
}

public:
//! returns whether historical fixings were stored for the index
bool hasHistory(const std::string& name) const;
//! returns the (possibly empty) history of the index fixings
const TimeSeries<Real>& getHistory(const std::string& name) const;
//! stores the historical fixings of the index
void setHistory(const std::string& name, TimeSeries<Real> history);
//! observer notifying of changes in the index fixings_
ext::shared_ptr<Observable> notifier(const std::string& name) const;
//! returns all names of the indexes for which fixings were stored
std::vector<std::string> histories() const;
//! clears the historical fixings of the index
void clearHistory(const std::string& name);
//! clears all stored fixings
void clearHistories();
//! returns whether a specific historical fixing was stored for the index and date
bool hasHistoricalFixing(const std::string& name, const Date& fixingDate) const;

private:
struct CaseInsensitiveCompare {
bool operator()(const std::string& s1, const std::string& s2) const {
return std::lexicographical_compare(s1.begin(), s1.end(), s2.begin(), s2.end(), [](const auto& c1, const auto& c2) {
return std::toupper(static_cast<unsigned char>(c1)) < std::toupper(static_cast<unsigned char>(c2));
});
}
};

mutable std::map<std::string, TimeSeries<Real>, CaseInsensitiveCompare> data_;
mutable std::map<std::string, ext::shared_ptr<Observable>> notifiers_;
};

}
Expand Down
2 changes: 1 addition & 1 deletion ql/indexes/inflationindex.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ namespace QuantLib {
frequency_(frequency), availabilityLag_(availabilityLag), currency_(std::move(currency)) {
name_ = region_.name() + " " + familyName_;
registerWith(Settings::instance().evaluationDate());
registerWith(IndexManager::instance().notifier(InflationIndex::name()));
registerWith(notifier());
}

Calendar InflationIndex::fixingCalendar() const {
Expand Down
2 changes: 1 addition & 1 deletion ql/indexes/interestrateindex.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ namespace QuantLib {
name_ = out.str();

registerWith(Settings::instance().evaluationDate());
registerWith(IndexManager::instance().notifier(InterestRateIndex::name()));
registerWith(notifier());
}

Rate InterestRateIndex::fixing(const Date& fixingDate,
Expand Down
6 changes: 2 additions & 4 deletions ql/instruments/overnightindexfuture.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,7 @@ namespace QuantLib {
Date d1 = valueDate_;
// d1 could be a holiday
Date fixingDate = calendar.adjust(d1, Preceding);
const TimeSeries<Real>& history = IndexManager::instance()
.getHistory(overnightIndex_->name());
const auto& history = overnightIndex_->timeSeries();
Real fwd;
while (d1 < maturityDate_) {
Date d2 = calendar.advance(d1, 1, Days);
Expand Down Expand Up @@ -86,8 +85,7 @@ namespace QuantLib {
forwardDiscountStart = today;
// for valuations inside the reference period, index quotes
// must have been populated in the history
const TimeSeries<Real>& history = IndexManager::instance()
.getHistory(overnightIndex_->name());
const auto& history = overnightIndex_->timeSeries();
Date d1 = valueDate_;
// d1 could be a holiday
Date fixingDate = calendar.adjust(d1, Preceding);
Expand Down
20 changes: 0 additions & 20 deletions test-suite/indexes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -96,39 +96,19 @@ BOOST_AUTO_TEST_CASE(testFixingHasHistoricalFixing) {

name = euribor3M->name();
testCase(name, fixingNotFound, euribor3M->hasHistoricalFixing(today));
testCase(name, fixingNotFound, IndexManager::instance().hasHistoricalFixing(name, today));
name = boost::to_upper_copy(euribor3M->name());
testCase(name, fixingNotFound, IndexManager::instance().hasHistoricalFixing(name, today));
name = boost::to_lower_copy(euribor3M->name());
testCase(name, fixingNotFound, IndexManager::instance().hasHistoricalFixing(name, today));

name = euribor6M->name();
testCase(name, fixingFound, euribor6M->hasHistoricalFixing(today));
testCase(name, fixingFound, euribor6M_a->hasHistoricalFixing(today));
testCase(name, fixingFound, IndexManager::instance().hasHistoricalFixing(name, today));
name = boost::to_upper_copy(euribor6M->name());
testCase(name, fixingFound, IndexManager::instance().hasHistoricalFixing(name, today));
name = boost::to_lower_copy(euribor6M->name());
testCase(name, fixingFound, IndexManager::instance().hasHistoricalFixing(name, today));

IndexManager::instance().clearHistories();

name = euribor3M->name();
testCase(name, fixingNotFound, euribor3M->hasHistoricalFixing(today));
testCase(name, fixingNotFound, IndexManager::instance().hasHistoricalFixing(name, today));
name = boost::to_upper_copy(euribor3M->name());
testCase(name, fixingNotFound, IndexManager::instance().hasHistoricalFixing(name, today));
name = boost::to_lower_copy(euribor3M->name());
testCase(name, fixingNotFound, IndexManager::instance().hasHistoricalFixing(name, today));

name = euribor6M->name();
testCase(name, fixingNotFound, euribor6M->hasHistoricalFixing(today));
testCase(name, fixingNotFound, euribor6M_a->hasHistoricalFixing(today));
testCase(name, fixingNotFound, IndexManager::instance().hasHistoricalFixing(name, today));
name = boost::to_upper_copy(euribor6M->name());
testCase(name, fixingNotFound, IndexManager::instance().hasHistoricalFixing(name, today));
name = boost::to_lower_copy(euribor6M->name());
testCase(name, fixingNotFound, IndexManager::instance().hasHistoricalFixing(name, today));
}

BOOST_AUTO_TEST_CASE(testTenorNormalization) {
Expand Down
5 changes: 1 addition & 4 deletions test-suite/shortratemodels.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -342,10 +342,7 @@ BOOST_AUTO_TEST_CASE(testSwaps) {
Date startDate = calendar.advance(settlement,start[i],Months);
if (startDate < today) {
Date fixingDate = calendar.advance(startDate,-2,Days);
TimeSeries<Real> pastFixings;
pastFixings[fixingDate] = 0.03;
IndexManager::instance().setHistory(euribor->name(),
pastFixings);
euribor->addFixing(fixingDate, 0.03);
}

for (Size j=0; j<std::size(length); j++) {
Expand Down

0 comments on commit 9f78db2

Please sign in to comment.