const Real Gaussian1dModel::swapRate(const Date &fixing, const Period &tenor, const Date &referenceDate, const Real y, boost::shared_ptr<SwapIndex> swapIdx) const { QL_REQUIRE(swapIdx != NULL, "no swap index given"); calculate(); if (fixing <= (evaluationDate_ + (enforcesTodaysHistoricFixings_ ? 0 : -1))) return swapIdx->fixing(fixing); Handle<YieldTermStructure> ytsf = swapIdx->iborIndex()->forwardingTermStructure(); Handle<YieldTermStructure> ytsd = swapIdx->discountingTermStructure(); // either might be empty, then // use model curve Schedule sched, floatSched; boost::shared_ptr<VanillaSwap> underlying = underlyingSwap(swapIdx, fixing, tenor); sched = underlying->fixedSchedule(); boost::shared_ptr<OvernightIndexedSwapIndex> oisIdx = boost::dynamic_pointer_cast<OvernightIndexedSwapIndex>(swapIdx); if (oisIdx != NULL) { floatSched = sched; } else { floatSched = underlying->floatingSchedule(); } Real annuity = swapAnnuity(fixing, tenor, referenceDate, y, swapIdx); // should be fine for // overnightindexed swap indices as // well Rate floatleg = 0.0; if (ytsf.empty() && ytsd.empty()) { // simple 100-formula can be used // only in one curve setup floatleg = (zerobond(sched.dates().front(), referenceDate, y) - zerobond(sched.calendar().adjust( sched.dates().back(), underlying->paymentConvention()), referenceDate, y)); } else { for (Size i = 1; i < floatSched.size(); i++) { floatleg += (zerobond(floatSched[i - 1], referenceDate, y, ytsf) / zerobond(floatSched[i], referenceDate, y, ytsf) - 1.0) * zerobond( floatSched.calendar().adjust( floatSched[i], underlying->paymentConvention()), referenceDate, y, ytsd); } } return floatleg / annuity; }
Real LiborCurve::swap2TerminalMeasure(Size reference, Size fixing, Size delay, Size length, Size payFreq) { return discountFactor(reference,fixing+delay)/discountFactorT0(0,fixing+delay) * swapAnnuityT0(fixing,length,payFreq)/swapAnnuity(reference,fixing,length,payFreq); }
Real LiborCurve::rRate(Size reference, Size fixing, Size delay, Size length, Size payFreq) { QL_REQUIRE(reference<=fixing,"reference index " << reference << " must be leq fixing " << fixing); double sumD=rateTimes_[fixing+length]-rateTimes_[fixing]; return swapAnnuityT0(fixing,length,payFreq)/(discountFactorT0(0,fixing+delay)*sumD)* (discountFactor(reference,fixing+delay)*sumD/swapAnnuity(reference,fixing,length,payFreq)-1.0); }