QuantLib
QuantLib copied to clipboard
OISRateHelper use in curve bootstrapping throwing exception TODAY, likely something to do with Labor Day holiday
This is with actual data from today, 1st day this has failed. Removing the OISRateHelper adds to "helpers", does not fail. If I move the businessDate forward to Sep 3 (and add some fixings), exception does not occur. Dates Aug 29, Aug 30 also fail.
{
struct SOFRQuotes {
QuantLib::Frequency freq;
QuantLib::Month month;
QuantLib::Year year;
QuantLib::Real price;
QuantLib::Real convx;
};
const QuantLib::Integer OISSettlementDays{ 2 };
const QuantLib::Real SOFRConvx = 0.0000;
QuantLib::Calendar calendar = QuantLib::UnitedStates(QuantLib::UnitedStates::SOFR);
QuantLib::Date today = QuantLib::Date(28, QuantLib::August, 2024);
QuantLib::Date businessDate = today;
while (!calendar.isBusinessDay(businessDate))
businessDate--;
QuantLib::Settings::instance().evaluationDate() = businessDate;
auto sofrIndex = QuantLib::ext::make_shared<QuantLib::Sofr>();
sofrIndex->clearFixings();
#if 1
sofrIndex->addFixing(QuantLib::Date(27, QuantLib::August, 2024), 0.0535);
sofrIndex->addFixing(QuantLib::Date(26, QuantLib::August, 2024), 0.0534);
sofrIndex->addFixing(QuantLib::Date(23, QuantLib::August, 2024), 0.0533);
sofrIndex->addFixing(QuantLib::Date(22, QuantLib::August, 2024), 0.0531);
sofrIndex->addFixing(QuantLib::Date(21, QuantLib::August, 2024), 0.0531);
sofrIndex->addFixing(QuantLib::Date(20, QuantLib::August, 2024), 0.0532);
sofrIndex->addFixing(QuantLib::Date(19, QuantLib::August, 2024), 0.0532);
sofrIndex->addFixing(QuantLib::Date(16, QuantLib::August, 2024), 0.0532);
sofrIndex->addFixing(QuantLib::Date(15, QuantLib::August, 2024), 0.0535);
sofrIndex->addFixing(QuantLib::Date(14, QuantLib::August, 2024), 0.0533);
sofrIndex->addFixing(QuantLib::Date(13, QuantLib::August, 2024), 0.0534);
sofrIndex->addFixing(QuantLib::Date(12, QuantLib::August, 2024), 0.0534);
sofrIndex->addFixing(QuantLib::Date(9, QuantLib::August, 2024), 0.0534);
sofrIndex->addFixing(QuantLib::Date(8, QuantLib::August, 2024), 0.0534);
sofrIndex->addFixing(QuantLib::Date(7, QuantLib::August, 2024), 0.0533);
sofrIndex->addFixing(QuantLib::Date(6, QuantLib::August, 2024), 0.0533);
sofrIndex->addFixing(QuantLib::Date(5, QuantLib::August, 2024), 0.0532);
sofrIndex->addFixing(QuantLib::Date(2, QuantLib::August, 2024), 0.0535);
sofrIndex->addFixing(QuantLib::Date(1, QuantLib::August, 2024), 0.0535);
sofrIndex->addFixing(QuantLib::Date(31, QuantLib::July, 2024), 0.0538);
sofrIndex->addFixing(QuantLib::Date(30, QuantLib::July, 2024), 0.0533);
sofrIndex->addFixing(QuantLib::Date(29, QuantLib::July, 2024), 0.0533);
sofrIndex->addFixing(QuantLib::Date(26, QuantLib::July, 2024), 0.0535);
sofrIndex->addFixing(QuantLib::Date(25, QuantLib::July, 2024), 0.0535);
sofrIndex->addFixing(QuantLib::Date(24, QuantLib::July, 2024), 0.0534);
sofrIndex->addFixing(QuantLib::Date(23, QuantLib::July, 2024), 0.0534);
sofrIndex->addFixing(QuantLib::Date(22, QuantLib::July, 2024), 0.0533);
sofrIndex->addFixing(QuantLib::Date(19, QuantLib::July, 2024), 0.0534);
sofrIndex->addFixing(QuantLib::Date(18, QuantLib::July, 2024), 0.0534);
sofrIndex->addFixing(QuantLib::Date(17, QuantLib::July, 2024), 0.0535);
sofrIndex->addFixing(QuantLib::Date(16, QuantLib::July, 2024), 0.0535);
sofrIndex->addFixing(QuantLib::Date(15, QuantLib::July, 2024), 0.0534);
sofrIndex->addFixing(QuantLib::Date(12, QuantLib::July, 2024), 0.0534);
sofrIndex->addFixing(QuantLib::Date(11, QuantLib::July, 2024), 0.0534);
sofrIndex->addFixing(QuantLib::Date(10, QuantLib::July, 2024), 0.0534);
sofrIndex->addFixing(QuantLib::Date(9, QuantLib::July, 2024), 0.0534);
sofrIndex->addFixing(QuantLib::Date(8, QuantLib::July, 2024), 0.0532);
sofrIndex->addFixing(QuantLib::Date(5, QuantLib::July, 2024), 0.0532);
sofrIndex->addFixing(QuantLib::Date(3, QuantLib::July, 2024), 0.0533);
sofrIndex->addFixing(QuantLib::Date(2, QuantLib::July, 2024), 0.0535);
sofrIndex->addFixing(QuantLib::Date(1, QuantLib::July, 2024), 0.0540);
sofrIndex->addFixing(QuantLib::Date(28, QuantLib::June, 2024), 0.0533);
sofrIndex->addFixing(QuantLib::Date(27, QuantLib::June, 2024), 0.0534);
sofrIndex->addFixing(QuantLib::Date(26, QuantLib::June, 2024), 0.0534);
sofrIndex->addFixing(QuantLib::Date(25, QuantLib::June, 2024), 0.0533);
sofrIndex->addFixing(QuantLib::Date(24, QuantLib::June, 2024), 0.0531);
sofrIndex->addFixing(QuantLib::Date(21, QuantLib::June, 2024), 0.0531);
sofrIndex->addFixing(QuantLib::Date(20, QuantLib::June, 2024), 0.0532);
sofrIndex->addFixing(QuantLib::Date(18, QuantLib::June, 2024), 0.0533);
sofrIndex->addFixing(QuantLib::Date(17, QuantLib::June, 2024), 0.0533);
sofrIndex->addFixing(QuantLib::Date(14, QuantLib::June, 2024), 0.0531);
sofrIndex->addFixing(QuantLib::Date(13, QuantLib::June, 2024), 0.0531);
sofrIndex->addFixing(QuantLib::Date(12, QuantLib::June, 2024), 0.0531);
sofrIndex->addFixing(QuantLib::Date(11, QuantLib::June, 2024), 0.0532);
sofrIndex->addFixing(QuantLib::Date(10, QuantLib::June, 2024), 0.0532);
sofrIndex->addFixing(QuantLib::Date(7, QuantLib::June, 2024), 0.0533);
sofrIndex->addFixing(QuantLib::Date(6, QuantLib::June, 2024), 0.0533);
sofrIndex->addFixing(QuantLib::Date(5, QuantLib::June, 2024), 0.0533);
sofrIndex->addFixing(QuantLib::Date(4, QuantLib::June, 2024), 0.0535);
sofrIndex->addFixing(QuantLib::Date(3, QuantLib::June, 2024), 0.0535);
sofrIndex->addFixing(QuantLib::Date(31, QuantLib::May, 2024), 0.0534);
sofrIndex->addFixing(QuantLib::Date(30, QuantLib::May, 2024), 0.0533);
sofrIndex->addFixing(QuantLib::Date(29, QuantLib::May, 2024), 0.0533);
sofrIndex->addFixing(QuantLib::Date(28, QuantLib::May, 2024), 0.0532);
sofrIndex->addFixing(QuantLib::Date(24, QuantLib::May, 2024), 0.0532);
sofrIndex->addFixing(QuantLib::Date(23, QuantLib::May, 2024), 0.0531);
sofrIndex->addFixing(QuantLib::Date(22, QuantLib::May, 2024), 0.0531);
sofrIndex->addFixing(QuantLib::Date(21, QuantLib::May, 2024), 0.0531);
sofrIndex->addFixing(QuantLib::Date(20, QuantLib::May, 2024), 0.0531);
sofrIndex->addFixing(QuantLib::Date(17, QuantLib::May, 2024), 0.0531);
sofrIndex->addFixing(QuantLib::Date(16, QuantLib::May, 2024), 0.0531);
sofrIndex->addFixing(QuantLib::Date(15, QuantLib::May, 2024), 0.0531);
sofrIndex->addFixing(QuantLib::Date(14, QuantLib::May, 2024), 0.0531);
sofrIndex->addFixing(QuantLib::Date(13, QuantLib::May, 2024), 0.0531);
sofrIndex->addFixing(QuantLib::Date(10, QuantLib::May, 2024), 0.0531);
#endif
const SOFRQuotes SOFRQuotes[] = {
{QuantLib::Monthly, QuantLib::Aug, 2024, 94.66375, SOFRConvx},
{QuantLib::Monthly, QuantLib::Sep, 2024, 94.7875, SOFRConvx},
{QuantLib::Monthly, QuantLib::Oct, 2024, 94.9775, SOFRConvx},
{QuantLib::Monthly, QuantLib::Nov, 2024, 95.2325, SOFRConvx},
{QuantLib::Monthly, QuantLib::Dec, 2024, 95.4475, SOFRConvx},
{QuantLib::Monthly, QuantLib::Jan, 2025, 95.6725, SOFRConvx},
{QuantLib::Monthly, QuantLib::Feb, 2025, 95.9475, SOFRConvx},
{QuantLib::Monthly, QuantLib::Mar, 2025, 96.0575, SOFRConvx},
{QuantLib::Monthly, QuantLib::Apr, 2025, 96.2325, SOFRConvx},
{QuantLib::Monthly, QuantLib::May, 2025, 96.3775, SOFRConvx},
{QuantLib::Quarterly, QuantLib::Jun, 2024, 94.62625, SOFRConvx},
{QuantLib::Quarterly, QuantLib::Jul, 2024, 94.72375, SOFRConvx},
{QuantLib::Quarterly, QuantLib::Aug, 2024, 94.8925, SOFRConvx},
{QuantLib::Quarterly, QuantLib::Sep, 2024, 95.09125, SOFRConvx},
{QuantLib::Quarterly, QuantLib::Oct, 2024, 95.295, SOFRConvx},
{QuantLib::Quarterly, QuantLib::Nov, 2024, 95.58, SOFRConvx},
{QuantLib::Quarterly, QuantLib::Dec, 2024, 95.7825, SOFRConvx},
{QuantLib::Quarterly, QuantLib::Jan, 2025, 95.9675, SOFRConvx},
{QuantLib::Quarterly, QuantLib::Feb, 2025, 96.1525, SOFRConvx},
{QuantLib::Quarterly, QuantLib::Mar, 2025, 96.2975, SOFRConvx},
{QuantLib::Quarterly, QuantLib::Jun, 2025, 96.6075, SOFRConvx},
};
std::vector<QuantLib::ext::shared_ptr<QuantLib::RateHelper>> helpers;
for (const auto& sofrQuote : SOFRQuotes)
helpers.push_back(QuantLib::ext::make_shared<QuantLib::SofrFutureRateHelper>(QuantLib::Real(sofrQuote.price), sofrQuote.month, sofrQuote.year, sofrQuote.freq, sofrQuote.convx / 100));
#if 1
const auto OIS3YR = QuantLib::ext::make_shared<QuantLib::SimpleQuote>(3.4820 / 100);
const auto OIS5YR = QuantLib::ext::make_shared<QuantLib::SimpleQuote>(3.3530 / 100);
const auto OIS7YR = QuantLib::ext::make_shared<QuantLib::SimpleQuote>(3.3460 / 100);
const auto OIS10YR = QuantLib::ext::make_shared<QuantLib::SimpleQuote>(3.3850 / 100);
const auto OIS15YR = QuantLib::ext::make_shared<QuantLib::SimpleQuote>(3.4560 / 100);
const auto OIS30YR = QuantLib::ext::make_shared<QuantLib::SimpleQuote>(3.3190 / 100);
helpers.push_back(QuantLib::ext::make_shared<QuantLib::OISRateHelper>(OISSettlementDays, QuantLib::Period(3, QuantLib::Years), QuantLib::Handle<QuantLib::Quote>(OIS3YR), sofrIndex));
helpers.push_back(QuantLib::ext::make_shared<QuantLib::OISRateHelper>(OISSettlementDays, QuantLib::Period(5, QuantLib::Years), QuantLib::Handle<QuantLib::Quote>(OIS5YR), sofrIndex));
helpers.push_back(QuantLib::ext::make_shared<QuantLib::OISRateHelper>(OISSettlementDays, QuantLib::Period(7, QuantLib::Years), QuantLib::Handle<QuantLib::Quote>(OIS7YR), sofrIndex));
helpers.push_back(QuantLib::ext::make_shared<QuantLib::OISRateHelper>(OISSettlementDays, QuantLib::Period(10, QuantLib::Years), QuantLib::Handle<QuantLib::Quote>(OIS10YR), sofrIndex));
helpers.push_back(QuantLib::ext::make_shared<QuantLib::OISRateHelper>(OISSettlementDays, QuantLib::Period(15, QuantLib::Years), QuantLib::Handle<QuantLib::Quote>(OIS15YR), sofrIndex));
helpers.push_back(QuantLib::ext::make_shared<QuantLib::OISRateHelper>(OISSettlementDays, QuantLib::Period(30, QuantLib::Years), QuantLib::Handle<QuantLib::Quote>(OIS30YR), sofrIndex));
#endif
auto oisTermStructureDayCounter = QuantLib::Actual360();
auto curve1 = QuantLib::ext::make_shared<QuantLib::PiecewiseYieldCurve<QuantLib::Discount, QuantLib::Cubic, QuantLib::IterativeBootstrap>>(businessDate, helpers, oisTermStructureDayCounter, QuantLib::Cubic(QuantLib::CubicInterpolation::Spline, true, QuantLib::CubicInterpolation::SecondDerivative, 0.0, QuantLib::CubicInterpolation::SecondDerivative, 0.0));
curve1->enableExtrapolation();
for (int y = 2025; y <= 2025; y++)
{
for (int m = 1; m <= 12; m++)
{
try
{
auto rate = curve1->zeroRate(QuantLib::Date(1, QuantLib::Month(m), y), oisTermStructureDayCounter, QuantLib::Compounded, QuantLib::Monthly).rate();
}
catch (QuantLib::Error& e) {
TRACE((std::string("yield curve building failed for curve ") + e.what()).c_str());
}
}
}
for (int y = 2026; y <= 2050; y++)
{
try
{
auto rate = curve1->zeroRate(QuantLib::Date(1, QuantLib::Month(1), y), oisTermStructureDayCounter, QuantLib::Compounded, QuantLib::Monthly).rate();
}
catch (QuantLib::Error& e) {
TRACE((std::string("yield curve building failed for curve ") + e.what()).c_str());
}
}
}