// Date calculations public override Date maturityDate(Date valueDate) { Calendar cal = fixingCalendar(); Date fixingDate = cal.advance(valueDate, -1, TimeUnit.Days); Date nextWednesday = Utils.previousWednesday(fixingDate + 7); return(cal.advance(nextWednesday, 1, TimeUnit.Days)); }
/* Date calculations * * See <https://www.theice.com/marketdata/reports/170>. */ public override Date valueDate(Date fixingDate) { Utils.QL_REQUIRE(isValidFixingDate(fixingDate), () => "Fixing date " + fixingDate + " is not valid"); // http://www.bba.org.uk/bba/jsp/polopoly.jsp?d=225&a=1412 : // In the case of EUR the Value Date shall be two TARGET // business days after the Fixing Date. return(target_.advance(fixingDate, fixingDays_, TimeUnit.Days)); }
public IborCoupon(Date paymentDate, double nominal, Date startDate, Date endDate, int fixingDays, IborIndex iborIndex, double gearing = 1.0, double spread = 0.0, Date refPeriodStart = null, Date refPeriodEnd = null, DayCounter dayCounter = null, bool isInArrears = false) : base(paymentDate, nominal, startDate, endDate, fixingDays, iborIndex, gearing, spread, refPeriodStart, refPeriodEnd, dayCounter, isInArrears) { iborIndex_ = iborIndex; fixingDate_ = fixingDate(); Calendar fixingCalendar = index_.fixingCalendar(); int indexFixingDays = index_.fixingDays(); fixingValueDate_ = fixingCalendar.advance(fixingDate_, indexFixingDays, TimeUnit.Days); #if QL_USE_INDEXED_COUPON fixingEndDate_ = index_->maturityDate(fixingValueDate_); #else if (isInArrears_) { fixingEndDate_ = index_.maturityDate(fixingValueDate_); } else { // par coupon approximation Date nextFixingDate = fixingCalendar.advance(accrualEndDate_, -fixingDays_, TimeUnit.Days); fixingEndDate_ = fixingCalendar.advance(nextFixingDate, indexFixingDays, TimeUnit.Days); } #endif DayCounter dc = index_.dayCounter(); spanningTime_ = dc.yearFraction(fixingValueDate_, fixingEndDate_); Utils.QL_REQUIRE(spanningTime_ > 0.0, () => "\n cannot calculate forward rate between " + fixingValueDate_ + " and " + fixingEndDate_ + ":\n non positive time (" + spanningTime_ + ") using " + dc.name() + " daycounter"); }
public override void initialize(FloatingRateCoupon coupon) { coupon_ = coupon as RangeAccrualFloatersCoupon; Utils.QL_REQUIRE(coupon_ != null, () => "range-accrual coupon required"); gearing_ = coupon_.gearing(); spread_ = coupon_.spread(); Date paymentDate = coupon_.date(); IborIndex index = coupon_.index() as IborIndex; Utils.QL_REQUIRE(index != null, () => "invalid index"); Handle <YieldTermStructure> rateCurve = index.forwardingTermStructure(); discount_ = rateCurve.link.discount(paymentDate); accrualFactor_ = coupon_.accrualPeriod(); spreadLegValue_ = spread_ * accrualFactor_ * discount_; startTime_ = coupon_.startTime(); endTime_ = coupon_.endTime(); observationTimes_ = coupon_.observationTimes(); lowerTrigger_ = coupon_.lowerTrigger(); upperTrigger_ = coupon_.upperTrigger(); observationsNo_ = coupon_.observationsNo(); List <Date> observationDates = coupon_.observationsSchedule().dates(); Utils.QL_REQUIRE(observationDates.Count == observationsNo_ + 2, () => "incompatible size of initialValues vector"); initialValues_ = new InitializedList <double>(observationDates.Count, 0.0); Calendar calendar = index.fixingCalendar(); for (int i = 0; i < observationDates.Count; i++) { initialValues_[i] = index.fixing( calendar.advance(observationDates[i], -coupon_.fixingDays, TimeUnit.Days)); } }
// creator public override List <CashFlow> value() { if (couponRates_.Count == 0) { throw new ArgumentException("no coupon rates given"); } if (notionals_.Count == 0) { throw new ArgumentException("no nominals given"); } List <CashFlow> leg = new List <CashFlow>(); Calendar schCalendar = schedule_.calendar(); // first period might be short or long Date start = schedule_[0], end = schedule_[1]; Date paymentDate = calendar_.adjust(end, paymentAdjustment_); Date exCouponDate = null; InterestRate rate = couponRates_[0]; double nominal = notionals_[0]; if (exCouponPeriod_ != null) { exCouponDate = exCouponCalendar_.advance(paymentDate, -exCouponPeriod_, exCouponAdjustment_, exCouponEndOfMonth_); } if (schedule_.isRegular(1)) { if (!(firstPeriodDC_ == null || firstPeriodDC_ == rate.dayCounter())) { throw new ArgumentException("regular first coupon does not allow a first-period day count"); } leg.Add(new FixedRateCoupon(paymentDate, nominal, rate, start, end, start, end, exCouponDate)); } else { Date refer = end - schedule_.tenor(); refer = schCalendar.adjust(refer, schedule_.businessDayConvention()); InterestRate r = new InterestRate(rate.rate(), (firstPeriodDC_ == null || firstPeriodDC_.empty()) ? rate.dayCounter() : firstPeriodDC_, rate.compounding(), rate.frequency()); leg.Add(new FixedRateCoupon(paymentDate, nominal, r, start, end, refer, end, exCouponDate)); } // regular periods for (int i = 2; i < schedule_.Count - 1; ++i) { start = end; end = schedule_[i]; paymentDate = calendar_.adjust(end, paymentAdjustment_); if (exCouponPeriod_ != null) { exCouponDate = exCouponCalendar_.advance(paymentDate, -exCouponPeriod_, exCouponAdjustment_, exCouponEndOfMonth_); } if ((i - 1) < couponRates_.Count) { rate = couponRates_[i - 1]; } else { rate = couponRates_.Last(); } if ((i - 1) < notionals_.Count) { nominal = notionals_[i - 1]; } else { nominal = notionals_.Last(); } leg.Add(new FixedRateCoupon(paymentDate, nominal, rate, start, end, start, end, exCouponDate)); } if (schedule_.Count > 2) { // last period might be short or long int N = schedule_.Count; start = end; end = schedule_[N - 1]; paymentDate = calendar_.adjust(end, paymentAdjustment_); if (exCouponPeriod_ != null) { exCouponDate = exCouponCalendar_.advance(paymentDate, -exCouponPeriod_, exCouponAdjustment_, exCouponEndOfMonth_); } if ((N - 2) < couponRates_.Count) { rate = couponRates_[N - 2]; } else { rate = couponRates_.Last(); } if ((N - 2) < notionals_.Count) { nominal = notionals_[N - 2]; } else { nominal = notionals_.Last(); } InterestRate r = new InterestRate(rate.rate(), lastPeriodDC_ == null ? rate.dayCounter() : lastPeriodDC_, rate.compounding(), rate.frequency()); if (schedule_.isRegular(N - 1)) { leg.Add(new FixedRateCoupon(paymentDate, nominal, r, start, end, start, end, exCouponDate)); } else { Date refer = start + schedule_.tenor(); refer = schCalendar.adjust(refer, schedule_.businessDayConvention()); leg.Add(new FixedRateCoupon(paymentDate, nominal, r, start, end, start, refer, exCouponDate)); } } return(leg); }
protected override void performCalculations() { Calendar calendar = index_.fixingCalendar(); int fixingDays = index_.fixingDays(); Date exerciseDate = exerciseDate_; if (exerciseDate == null) { exerciseDate = calendar.advance(termStructure_.link.referenceDate(), maturity_, index_.businessDayConvention()); } Date startDate = calendar.advance(exerciseDate, fixingDays, TimeUnit.Days, index_.businessDayConvention()); Date endDate = endDate_; if (endDate == null) { endDate = calendar.advance(startDate, length_, index_.businessDayConvention()); } Schedule fixedSchedule = new Schedule(startDate, endDate, fixedLegTenor_, calendar, index_.businessDayConvention(), index_.businessDayConvention(), DateGeneration.Rule.Forward, false); Schedule floatSchedule = new Schedule(startDate, endDate, index_.tenor(), calendar, index_.businessDayConvention(), index_.businessDayConvention(), DateGeneration.Rule.Forward, false); IPricingEngine swapEngine = new DiscountingSwapEngine(termStructure_, false); VanillaSwap.Type type = VanillaSwap.Type.Receiver; VanillaSwap temp = new VanillaSwap(VanillaSwap.Type.Receiver, nominal_, fixedSchedule, 0.0, fixedLegDayCounter_, floatSchedule, index_, 0.0, floatingLegDayCounter_); temp.setPricingEngine(swapEngine); double forward = temp.fairRate(); if (!strike_.HasValue) { exerciseRate_ = forward; } else { exerciseRate_ = strike_.Value; type = strike_ <= forward ? VanillaSwap.Type.Receiver : VanillaSwap.Type.Payer; // ensure that calibration instrument is out of the money } swap_ = new VanillaSwap(type, nominal_, fixedSchedule, exerciseRate_, fixedLegDayCounter_, floatSchedule, index_, 0.0, floatingLegDayCounter_); swap_.setPricingEngine(swapEngine); Exercise exercise = new EuropeanExercise(exerciseDate); swaption_ = new Swaption(swap_, exercise); base.performCalculations(); }
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); }