Rate InterestRateIndex::fixing(const Date& fixingDate, bool forecastTodaysFixing) const { QL_REQUIRE(isValidFixingDate(fixingDate), "Fixing date " << fixingDate << " is not valid"); Date today = Settings::instance().evaluationDate(); if (fixingDate>today || (fixingDate==today && forecastTodaysFixing)) return forecastFixing(fixingDate); if (fixingDate<today || Settings::instance().enforcesTodaysHistoricFixings()) { // must have been fixed // do not catch exceptions Rate result = pastFixing(fixingDate); QL_REQUIRE(result != Null<Real>(), "Missing " << name() << " fixing for " << fixingDate); return result; } try { // might have been fixed Rate result = pastFixing(fixingDate); if (result!=Null<Real>()) return result; else ; // fall through and forecast } catch (Error&) { ; // fall through and forecast } return forecastFixing(fixingDate); }
Rate ZeroInflationIndex::fixing(const Date& aFixingDate, bool /*forecastTodaysFixing*/) const { if (!needsForecast(aFixingDate)) { const TimeSeries<Real>& ts = timeSeries(); Real pastFixing = ts[aFixingDate]; QL_REQUIRE(pastFixing != Null<Real>(), "Missing " << name() << " fixing for " << aFixingDate); Real theFixing = pastFixing; if (interpolated_) { // fixings stored flat & for every day std::pair<Date,Date> lim = inflationPeriod(aFixingDate, frequency_); if (aFixingDate == lim.first) { // we don't actually need the next fixing theFixing = pastFixing; } else { Date fixingDate2 = aFixingDate + Period(frequency_); Real pastFixing2 = ts[fixingDate2]; QL_REQUIRE(pastFixing2 != Null<Real>(), "Missing " << name() << " fixing for " << fixingDate2); // now linearly interpolate Real daysInPeriod = lim.second+1 - lim.first; theFixing = pastFixing + (pastFixing2-pastFixing)*(aFixingDate-lim.first)/daysInPeriod; } } return theFixing; } else { return forecastFixing(aFixingDate); } }
Rate ZeroInflationIndex::fixing(const Date& aFixingDate, bool /*forecastTodaysFixing*/) const { if (!needsForecast(aFixingDate)) { std::pair<Date,Date> lim = inflationPeriod(aFixingDate, frequency_); const TimeSeries<Real>& ts = timeSeries(); Real pastFixing = ts[lim.first]; QL_REQUIRE(pastFixing != Null<Real>(), "Missing " << name() << " fixing for " << lim.first); Real theFixing = pastFixing; if (interpolated_) { // fixings stored on first day of every period if (aFixingDate == lim.first) { // we don't actually need the next fixing theFixing = pastFixing; } else { Real pastFixing2 = ts[lim.second+1]; QL_REQUIRE(pastFixing2 != Null<Real>(), "Missing " << name() << " fixing for " << lim.second+1); // Use lagged period for interpolation std::pair<Date, Date> reference_period_lim = inflationPeriod(aFixingDate + zeroInflationTermStructure()->observationLag(), frequency_); // now linearly interpolate Real daysInPeriod = reference_period_lim.second + 1 - reference_period_lim.first; theFixing = pastFixing + (pastFixing2 - pastFixing)*(aFixingDate - lim.first) / daysInPeriod; } } return theFixing; } else { return forecastFixing(aFixingDate); } }
Rate IborIndex::forecastFixing(const Date& fixingDate) const { Date d1 = valueDate(fixingDate); Date d2 = maturityDate(d1); Time t = dayCounter_.yearFraction(d1, d2); QL_REQUIRE(t>0.0, "\n cannot calculate forward rate between " << d1 << " and " << d2 << ":\n non positive time (" << t << ") using " << dayCounter_.name() << " daycounter"); return forecastFixing(d1, d2, t); }
Rate ZeroInflationIndex::fixing(const Date& aFixingDate, bool /*forecastTodaysFixing*/) const { // Stored fixings are always non-interpolated. // If an interpolated fixing is required then // the availability lag + one inflation period // must have passsed to use historical fixings // (because you need the next one to interpolate). // The interpolation is calculated (linearly) on demand. Date today = Settings::instance().evaluationDate(); Date todayMinusLag = today - availabilityLag_; std::pair<Date,Date> lim = inflationPeriod(todayMinusLag, frequency_); Date historicalFixingKnown = lim.first-1; Date fixingDateNeeded = aFixingDate; if (interpolated_) { // need the next one too fixingDateNeeded = fixingDateNeeded + Period(frequency_); } if (fixingDateNeeded <= historicalFixingKnown) { Real pastFixing = IndexManager::instance().getHistory(name())[aFixingDate]; QL_REQUIRE(pastFixing != Null<Real>(), "Missing " << name() << " fixing for " << aFixingDate); Real theFixing = pastFixing; if (interpolated_) { // fixings stored flat & for every day Date fixingDate2 = aFixingDate + Period(frequency_); Real pastFixing2 = IndexManager::instance().getHistory(name())[fixingDate2]; QL_REQUIRE(pastFixing2 != Null<Real>(), "Missing " << name() << " fixing for " << fixingDate2); // now linearly interpolate std::pair<Date,Date> lim = inflationPeriod(aFixingDate, frequency_); Real daysInPeriod = lim.second+1 - lim.first; theFixing = pastFixing + (pastFixing2-pastFixing)*(aFixingDate-lim.first)/daysInPeriod; } return theFixing; } else { return forecastFixing(aFixingDate); } }
Rate YoYInflationIndex::fixing(const Date& fixingDate, bool /*forecastTodaysFixing*/) const { Date today = Settings::instance().evaluationDate(); Date todayMinusLag = today - availabilityLag_; std::pair<Date,Date> lim = inflationPeriod(todayMinusLag, frequency_); Date lastFix = lim.first-1; Date flatMustForecastOn = lastFix+1; Date interpMustForecastOn = lastFix+1 - Period(frequency_); if (interpolated() && fixingDate >= interpMustForecastOn) { return forecastFixing(fixingDate); } if (!interpolated() && fixingDate >= flatMustForecastOn) { return forecastFixing(fixingDate); } // four cases with ratio() and interpolated() const TimeSeries<Real>& ts = timeSeries(); if (ratio()) { if(interpolated()){ // IS ratio, IS interpolated std::pair<Date,Date> lim = inflationPeriod(fixingDate, frequency_); Date fixMinus1Y=NullCalendar().advance(fixingDate, -1*Years, ModifiedFollowing); std::pair<Date,Date> limBef = inflationPeriod(fixMinus1Y, frequency_); Real dp= lim.second + 1 - lim.first; Real dpBef=limBef.second + 1 - limBef.first; Real dl = fixingDate-lim.first; // potentially does not work on 29th Feb Real dlBef = fixMinus1Y - limBef.first; // get the four relevant fixings // recall that they are stored flat for every day Rate limFirstFix = ts[lim.first]; QL_REQUIRE(limFirstFix != Null<Rate>(), "Missing " << name() << " fixing for " << lim.first ); Rate limSecondFix = ts[lim.second+1]; QL_REQUIRE(limSecondFix != Null<Rate>(), "Missing " << name() << " fixing for " << lim.second+1 ); Rate limBefFirstFix = ts[limBef.first]; QL_REQUIRE(limBefFirstFix != Null<Rate>(), "Missing " << name() << " fixing for " << limBef.first ); Rate limBefSecondFix = IndexManager::instance().getHistory(name())[limBef.second+1]; QL_REQUIRE(limBefSecondFix != Null<Rate>(), "Missing " << name() << " fixing for " << limBef.second+1 ); Real linearNow = limFirstFix + (limSecondFix-limFirstFix)*dl/dp; Real linearBef = limBefFirstFix + (limBefSecondFix-limBefFirstFix)*dlBef/dpBef; Rate wasYES = linearNow / linearBef - 1.0; return wasYES; } else { // IS ratio, NOT interpolated Rate pastFixing = ts[fixingDate]; QL_REQUIRE(pastFixing != Null<Rate>(), "Missing " << name() << " fixing for " << fixingDate); Date previousDate = fixingDate - 1*Years; Rate previousFixing = ts[previousDate]; QL_REQUIRE(previousFixing != Null<Rate>(), "Missing " << name() << " fixing for " << previousDate ); return pastFixing/previousFixing - 1.0; } } else { // NOT ratio if (interpolated()) { // NOT ratio, IS interpolated std::pair<Date,Date> lim = inflationPeriod(fixingDate, frequency_); Real dp= lim.second + 1 - lim.first; Real dl = fixingDate-lim.first; Rate limFirstFix = ts[lim.first]; QL_REQUIRE(limFirstFix != Null<Rate>(), "Missing " << name() << " fixing for " << lim.first ); Rate limSecondFix = ts[lim.second+1]; QL_REQUIRE(limSecondFix != Null<Rate>(), "Missing " << name() << " fixing for " << lim.second+1 ); Real linearNow = limFirstFix + (limSecondFix-limFirstFix)*dl/dp; return linearNow; } else { // NOT ratio, NOT interpolated // so just flat Rate pastFixing = ts[fixingDate]; QL_REQUIRE(pastFixing != Null<Rate>(), "Missing " << name() << " fixing for " << fixingDate); return pastFixing; } } // QL_FAIL("YoYInflationIndex::fixing, should never get here"); }