// constructors public FloatingRateCoupon(Date paymentDate, double nominal, Date startDate, Date endDate, int fixingDays, InterestRateIndex index, 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, refPeriodStart, refPeriodEnd) { index_ = index; dayCounter_ = dayCounter ?? new DayCounter(); fixingDays_ = fixingDays == default(int) ? index.fixingDays() : fixingDays; gearing_ = gearing; spread_ = spread; isInArrears_ = isInArrears; if (gearing_.IsEqual(0)) { throw new ArgumentException("Null gearing not allowed"); } if (dayCounter_.empty()) { dayCounter_ = index_.dayCounter(); } // add as observer index_.registerWith(update); Settings.Instance.registerWith(update); }
// 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); }