public override double swapletRate() { OvernightIndex index = coupon_.index() as OvernightIndex; List <Date> fixingDates = coupon_.fixingDates(); List <double> dt = coupon_.dt(); int n = dt.Count; int i = 0; double compoundFactor = 1.0; // already fixed part Date today = Settings.Instance.evaluationDate(); while (fixingDates[i] < today && i < n) { // rate must have been fixed double?pastFixing = IndexManager.Instance.getHistory(index.name())[fixingDates[i]]; Utils.QL_REQUIRE(pastFixing != null, () => "Missing " + index.name() + " fixing for " + fixingDates[i].ToString()); compoundFactor *= (1.0 + pastFixing.GetValueOrDefault() * dt[i]); ++i; } // today is a border case if (fixingDates[i] == today && i < n) { // might have been fixed try { double?pastFixing = IndexManager.Instance.getHistory(index.name())[fixingDates[i]]; if (pastFixing != null) { compoundFactor *= (1.0 + pastFixing.GetValueOrDefault() * dt[i]); ++i; } else { // fall through and forecast } } catch (Exception) { // fall through and forecast } } // forward part using telescopic property in order // to avoid the evaluation of multiple forward fixings if (i < n) { Handle <YieldTermStructure> curve = index.forwardingTermStructure(); Utils.QL_REQUIRE(!curve.empty(), () => "null term structure set to this instance of" + index.name()); List <Date> dates = coupon_.valueDates(); double startDiscount = curve.link.discount(dates[i]); double endDiscount = curve.link.discount(dates[n]); compoundFactor *= startDiscount / endDiscount; } double rate = (compoundFactor - 1.0) / coupon_.accrualPeriod(); return(coupon_.gearing() * rate + coupon_.spread()); }
public OvernightIndexedSwap value() { Date startDate; if (effectiveDate_ != null) { startDate = effectiveDate_; } else { Date refDate = Settings.Instance.evaluationDate(); // if the evaluation date is not a business day // then move to the next business day refDate = calendar_.adjust(refDate); Date spotDate = calendar_.advance(refDate, new Period(settlementDays_, TimeUnit.Days)); startDate = spotDate + forwardStart_; if (forwardStart_.length() < 0) { startDate = calendar_.adjust(startDate, BusinessDayConvention.Preceding); } else { startDate = calendar_.adjust(startDate, BusinessDayConvention.Following); } } // OIS end of month default bool usedEndOfMonth = isDefaultEOM_ ? calendar_.isEndOfMonth(startDate) : endOfMonth_; Date endDate = terminationDate_; if (endDate == null) { if (usedEndOfMonth) { endDate = calendar_.advance(startDate, swapTenor_, BusinessDayConvention.ModifiedFollowing, usedEndOfMonth); } else { endDate = startDate + swapTenor_; } } Schedule schedule = new Schedule(startDate, endDate, new Period(paymentFrequency_), calendar_, BusinessDayConvention.ModifiedFollowing, BusinessDayConvention.ModifiedFollowing, rule_, usedEndOfMonth); double?usedFixedRate = fixedRate_; if (fixedRate_ == null) { OvernightIndexedSwap temp = new OvernightIndexedSwap(type_, nominal_, schedule, 0.0, // fixed rate fixedDayCount_, overnightIndex_, overnightSpread_); if (engine_ == null) { Handle <YieldTermStructure> disc = overnightIndex_.forwardingTermStructure(); Utils.QL_REQUIRE(!disc.empty(), () => "null term structure set to this instance of " + overnightIndex_.name()); bool includeSettlementDateFlows = false; IPricingEngine engine = new DiscountingSwapEngine(disc, includeSettlementDateFlows); temp.setPricingEngine(engine); } else { temp.setPricingEngine(engine_); } usedFixedRate = temp.fairRate(); } OvernightIndexedSwap ois = new OvernightIndexedSwap(type_, nominal_, schedule, usedFixedRate.Value, fixedDayCount_, overnightIndex_, overnightSpread_); if (engine_ == null) { Handle <YieldTermStructure> disc = overnightIndex_.forwardingTermStructure(); bool includeSettlementDateFlows = false; IPricingEngine engine = new DiscountingSwapEngine(disc, includeSettlementDateFlows); ois.setPricingEngine(engine); } else { ois.setPricingEngine(engine_); } return(ois); }