protected void calculateNotionalsFromCashflows() { notionalSchedule_.Clear(); notionals_.Clear(); Date lastPaymentDate = new Date(); //notionalSchedule_.Add((Coupon)(cashflows_[0])accrualStartDate()); for (int i = 0; i < cashflows_.Count; ++i) { Coupon coupon = cashflows_[i] as Coupon; if (coupon == null) { continue; } if (i == 0) { notionalSchedule_.Add(coupon.accrualStartDate()); } double notional = coupon.nominal(); // we add the notional only if it is the first one... if (notionals_.empty()) { notionals_.Add(coupon.nominal()); lastPaymentDate = coupon.date(); } else if (!Utils.close(notional, notionals_.Last())) { // ...or if it has changed. if (!(notional < notionals_.Last())) { throw new ApplicationException("increasing coupon notionals"); } notionals_.Add(coupon.nominal()); // in this case, we also add the last valid date for // the previous one... notionalSchedule_.Add(lastPaymentDate); // ...and store the candidate for this one. lastPaymentDate = coupon.date(); } else { // otherwise, we just extend the valid range of dates // for the current notional. lastPaymentDate = coupon.date(); } } if (notionals_.empty()) { throw new ApplicationException("no coupons provided"); } notionals_.Add(0.0); notionalSchedule_.Add(lastPaymentDate); }
// helper function used to calculate Time-To-Discount for each stage when calculating discount factor stepwisely public static double getStepwiseDiscountTime(CashFlow cashFlow, DayCounter dc, Date npvDate, Date lastDate) { Date cashFlowDate = cashFlow.date(); Date refStartDate, refEndDate; Coupon coupon = cashFlow as Coupon; if (coupon != null) { refStartDate = coupon.referencePeriodStart; refEndDate = coupon.referencePeriodEnd; } else { if (lastDate == npvDate) { // we don't have a previous coupon date, // so we fake it refStartDate = cashFlowDate - new Period(1, TimeUnit.Years); } else { refStartDate = lastDate; } refEndDate = cashFlowDate; } if (coupon != null && lastDate != coupon.accrualStartDate()) { double couponPeriod = dc.yearFraction(coupon.accrualStartDate(), cashFlowDate, refStartDate, refEndDate); double accruedPeriod = dc.yearFraction(coupon.accrualStartDate(), lastDate, refStartDate, refEndDate); return(couponPeriod - accruedPeriod); } else { return(dc.yearFraction(lastDate, cashFlowDate, refStartDate, refEndDate)); } }
public static Date startDate(Leg leg) { Utils.QL_REQUIRE(!leg.empty(), () => "empty leg"); Date d = Date.maxDate(); for (int i = 0; i < leg.Count; ++i) { Coupon c = leg[i] as Coupon; if (c != null) { d = Date.Min(d, c.accrualStartDate()); } else { d = Date.Min(d, leg[i].date()); } } return(d); }
public static Date accrualStartDate(List <CashFlow> leg, bool includeSettlementDateFlows, Date settlementDate = null) { CashFlow cf = nextCashFlow(leg, includeSettlementDateFlows, settlementDate); if (cf == null) { return(null); } Date paymentDate = cf.date(); foreach (CashFlow x in leg.Where(x => x.date() == paymentDate)) { Coupon cp = x as Coupon; if (cp != null) { return(cp.accrualStartDate()); } } return(null); }
public static double npv(List <CashFlow> leg, InterestRate y, bool includeSettlementDateFlows, Date settlementDate = null, Date npvDate = null) { if (leg == null || leg.empty()) { return(0.0); } if (settlementDate == null) { settlementDate = Settings.evaluationDate(); } if (npvDate == null) { npvDate = settlementDate; } double npv = 0.0; double discount = 1.0; Date lastDate = npvDate; Date refStartDate, refEndDate; for (int i = 0; i < leg.Count; ++i) { if (leg[i].hasOccurred(settlementDate, includeSettlementDateFlows)) { continue; } Date couponDate = leg[i].date(); double amount = leg[i].amount(); Coupon coupon = leg[i] as Coupon; if (coupon != null) { refStartDate = coupon.accrualStartDate(); refEndDate = coupon.accrualEndDate(); } else { if (lastDate == npvDate) { // we don't have a previous coupon date, // so we fake it refStartDate = couponDate - new Period(1, TimeUnit.Years); } else { refStartDate = lastDate; } refEndDate = couponDate; } double b = y.discountFactor(lastDate, couponDate, refStartDate, refEndDate); discount *= b; lastDate = couponDate; npv += amount * discount; } return(npv); }