34#include <ql/cashflows/averagebmacoupon.hpp>
35#include <ql/cashflows/capflooredcoupon.hpp>
36#include <ql/cashflows/cpicoupon.hpp>
37#include <ql/cashflows/floatingratecoupon.hpp>
38#include <ql/cashflows/yoyinflationcoupon.hpp>
39#include <ql/experimental/coupons/cmsspreadcoupon.hpp>
40#include <ql/experimental/coupons/digitalcmsspreadcoupon.hpp>
53 for (Size i = 0; i <= gap; ++i) {
55 if (index->isValidFixingDate(adjusted))
58 QL_FAIL(
"no valid fixing date found for index " << index->name() <<
" within gap from " << io::iso_date(d));
65void FixingManager::initialise(
const QuantLib::ext::shared_ptr<Portfolio>& portfolio,
const QuantLib::ext::shared_ptr<Market>& market,
66 const std::string& configuration) {
69 for (
auto const& [tradeId,t] : portfolio->trades()) {
70 auto r = t->requiredFixings();
72 for (
auto const& [
name, fixingDates] : r.fixingDatesIndices(QuantLib::Date::maxDate())) {
74 for (
const auto& [d, _] : fixingDates) {
79 if (
auto index = QuantLib::ext::dynamic_pointer_cast<EquityIndex2>(rawIndex)) {
81 fixingMap_[*market->equityCurve(index->familyName(), configuration)].insert(dates.begin(),
83 }
else if (
auto index = QuantLib::ext::dynamic_pointer_cast<BondIndex>(rawIndex)) {
84 QL_FAIL(
"BondIndex not handled");
85 }
else if (
auto index = QuantLib::ext::dynamic_pointer_cast<CommodityIndex>(rawIndex)) {
87 Date safeExpiryDate = index->expiryDate();
88 if (safeExpiryDate != Date() && !index->keepDays()) {
89 safeExpiryDate = Date::endOfMonth(safeExpiryDate);
92 market->commodityPriceCurve(index->underlyingName(), configuration))]
93 .insert(dates.begin(), dates.end());
94 }
else if (
auto index = QuantLib::ext::dynamic_pointer_cast<FxIndex>(rawIndex)) {
95 fixingMap_[*market->fxIndex(index->oreName(), configuration)].insert(dates.begin(), dates.end());
96 }
else if (
auto index = QuantLib::ext::dynamic_pointer_cast<GenericIndex>(rawIndex)) {
97 QL_FAIL(
"GenericIndex not handled");
98 }
else if (
auto index = QuantLib::ext::dynamic_pointer_cast<ConstantMaturityBondIndex>(rawIndex)) {
99 QL_FAIL(
"ConstantMaturityBondIndex not handled");
100 }
else if (
auto index = QuantLib::ext::dynamic_pointer_cast<IborIndex>(rawIndex)) {
101 fixingMap_[*market->iborIndex(
name, configuration)].insert(dates.begin(), dates.end());
102 }
else if (
auto index = QuantLib::ext::dynamic_pointer_cast<SwapIndex>(rawIndex)) {
103 fixingMap_[*market->swapIndex(
name, configuration)].insert(dates.begin(), dates.end());
104 }
else if (
auto index = QuantLib::ext::dynamic_pointer_cast<ZeroInflationIndex>(rawIndex)) {
105 fixingMap_[*market->zeroInflationIndex(
name, configuration)].insert(dates.begin(), dates.end());
107 }
catch (
const std::exception& e) {
108 ALOG(
"FixingManager: error " << e.what() <<
" - no fixings are added for '" <<
name <<
"'");
110 TLOG(
"Added " << dates.size() <<
" fixing dates for '" <<
name <<
"'");
116 fixingCache_[m.first] = IndexManager::instance().getHistory(m.first->name());
123 QL_REQUIRE(d >=
fixingsEnd_,
"Can't go back in time, fixings must be reset."
125 << d <<
" but current fixings go to " <<
fixingsEnd_);
136 IndexManager::instance().setHistory(kv.first->name(), kv.second);
145 Date fixStart = start;
147 Date currentFixingDate;
148 if (
auto zii = QuantLib::ext::dynamic_pointer_cast<ZeroInflationIndex>(m.first)) {
150 inflationPeriod(fixStart - zii->zeroInflationTermStructure()->observationLag(), zii->frequency()).first;
152 inflationPeriod(fixEnd - zii->zeroInflationTermStructure()->observationLag(), zii->frequency()).first +
154 currentFixingDate = fixEnd;
155 }
else if (
auto yii = QuantLib::ext::dynamic_pointer_cast<YoYInflationIndex>(m.first)) {
157 inflationPeriod(fixStart - yii->yoyInflationTermStructure()->observationLag(), yii->frequency()).first;
159 inflationPeriod(fixEnd - yii->yoyInflationTermStructure()->observationLag(), yii->frequency()).first +
161 currentFixingDate = fixEnd;
163 currentFixingDate = m.first->fixingCalendar().adjust(fixEnd, Following);
165 if (!m.first->isValidFixingDate(currentFixingDate))
170 bool needFixings =
false;
171 for (
auto const& d : m.second) {
172 if (d >= fixStart && d < fixEnd) {
180 if (
auto comm = QuantLib::ext::dynamic_pointer_cast<QuantExt::CommodityIndex>(m.first);
181 comm !=
nullptr && comm->expiryDate() < currentFixingDate) {
182 currentFixing = comm->priceCurve()->price(currentFixingDate);
184 currentFixing = m.first->fixing(currentFixingDate);
187 TimeSeries<Real> history;
188 for (
auto const& d : m.second) {
189 if (d >= fixStart && d < fixEnd) {
191 bool valid = m.first->isValidFixingDate(d);
193 history[d] = currentFixing;
200 m.first->addFixings(history,
true);
void applyFixings(Date start, Date end)
void update(Date d)
Update fixings to date d.
FixingManager(Date today)
bool modifiedFixingHistory_
void initialise(const QuantLib::ext::shared_ptr< Portfolio > &portfolio, const QuantLib::ext::shared_ptr< Market > &market, const std::string &configuration=Market::defaultConfiguration)
Initialise the manager with these flows and indices from the given portfolio.
void reset()
Reset fixings to t0 (today)
Controls the updating/reset of the QuantLib::IndexManager.
QuantLib::ext::shared_ptr< Index > parseIndex(const string &s)
Date nextValidFixingDate(Date d, const QuantLib::ext::shared_ptr< Index > &index, Size gap=7)