//! NPV and BPS of the cash flows. // The NPV and BPS of the cash flows calculated together for performance reason public static void npvbps(Leg leg, YieldTermStructure discountCurve, bool includeSettlementDateFlows, Date settlementDate, Date npvDate, out double npv, out double bps) { npv = bps = 0.0; if (leg.empty()) { bps = 0.0; return; } for (int i = 0; i < leg.Count; ++i) { CashFlow cf = leg[i]; if (!cf.hasOccurred(settlementDate, includeSettlementDateFlows) && !cf.tradingExCoupon(settlementDate)) { Coupon cp = leg[i] as Coupon; double df = discountCurve.discount(cf.date()); npv += cf.amount() * df; if (cp != null) { bps += cp.nominal() * cp.accrualPeriod() * df; } } } double d = discountCurve.discount(npvDate); npv /= d; bps = Const.BASIS_POINT * bps / d; }
public GFunctionExactYield(CmsCoupon coupon) { SwapIndex swapIndex = coupon.swapIndex(); VanillaSwap swap = swapIndex.underlyingSwap(coupon.fixingDate()); Schedule schedule = swap.fixedSchedule(); Handle <YieldTermStructure> rateCurve = swapIndex.forwardingTermStructure(); DayCounter dc = swapIndex.dayCounter(); double swapStartTime = dc.yearFraction(rateCurve.link.referenceDate(), schedule.startDate()); double swapFirstPaymentTime = dc.yearFraction(rateCurve.link.referenceDate(), schedule.date(1)); double paymentTime = dc.yearFraction(rateCurve.link.referenceDate(), coupon.date()); delta_ = (paymentTime - swapStartTime) / (swapFirstPaymentTime - swapStartTime); List <CashFlow> fixedLeg = new List <CashFlow>(swap.fixedLeg()); int n = fixedLeg.Count; accruals_ = new List <double>(); for (int i = 0; i < n; ++i) { Coupon coupon1 = fixedLeg[i] as Coupon; accruals_.Add(coupon1.accrualPeriod()); } }
public void visit(Coupon c) { double bps = c.nominal() * c.accrualPeriod() * discountCurve_.discount(c.date()); bps_ += bps; }
private static double couponRate(List <CashFlow> leg, CashFlow cf) { if (cf == null) { return(0.0); } Date paymentDate = cf.date(); bool firstCouponFound = false; double nominal = 0; double accrualPeriod = 0; DayCounter dc = null; double result = 0.0; foreach (CashFlow x in leg.Where(x => x.date() == paymentDate)) { Coupon cp = x as Coupon; if (cp != null) { if (firstCouponFound) { if (!(nominal == cp.nominal() && accrualPeriod == cp.accrualPeriod() && dc == cp.dayCounter())) { throw new ApplicationException("cannot aggregate two different coupons on " + paymentDate); } } else { firstCouponFound = true; nominal = cp.nominal(); accrualPeriod = cp.accrualPeriod(); dc = cp.dayCounter(); } result += cp.rate(); } } if (!firstCouponFound) { throw new ApplicationException("next cashflow (" + paymentDate + ") is not a coupon"); } return(result); }
public double accruedAmount(Date settlement) { if (settlement == null) { settlement = settlementDate(); } CashFlow cf = CashFlows.nextCashFlow(cashflows_, false, settlement); if (cf == cashflows_.Last()) { return(0.0); } Date paymentDate = cf.date(); bool firstCouponFound = false; double nominal = 0; double accrualPeriod = 0; DayCounter dc = null; double result = 0.0; foreach (CashFlow x in cashflows_.FindAll(x => x.date() == paymentDate && x.GetType().IsSubclassOf(typeof(Coupon)))) { Coupon cp = (Coupon)x; if (firstCouponFound) { if (!(nominal == cp.nominal() && accrualPeriod == cp.accrualPeriod() && dc == cp.dayCounter())) { throw new ApplicationException("cannot aggregate accrued amount of two different coupons on " + paymentDate); } } else { firstCouponFound = true; nominal = cp.nominal(); accrualPeriod = cp.accrualPeriod(); dc = cp.dayCounter(); } result += cp.accruedAmount(settlement); } return(result / notional(settlement) * 100.0); }
private static double aggregateRate(Leg leg, CashFlow cf) { if (cf == null) { return(0.0); } Date paymentDate = cf.date(); bool firstCouponFound = false; double nominal = 0.0; double accrualPeriod = 0.0; DayCounter dc = null; double result = 0.0; foreach (CashFlow x in leg.Where(x => x.date() == paymentDate)) { Coupon cp = x as Coupon; if (cp != null) { if (firstCouponFound) { Utils.QL_REQUIRE(nominal.IsEqual(cp.nominal()) && accrualPeriod.IsEqual(cp.accrualPeriod()) && dc == cp.dayCounter(), () => "cannot aggregate two different coupons on " + paymentDate); } else { firstCouponFound = true; nominal = cp.nominal(); accrualPeriod = cp.accrualPeriod(); dc = cp.dayCounter(); } result += cp.rate(); } } Utils.QL_REQUIRE(firstCouponFound, () => "no coupon paid at cashflow date " + paymentDate); return(result); }
//===========================================================================// // GFunctionWithShifts // //===========================================================================// public GFunctionWithShifts(CmsCoupon coupon, Handle <Quote> meanReversion) { meanReversion_ = meanReversion; calibratedShift_ = 0.03; tmpRs_ = 10000000.0; accuracy_ = 1.0e-14; SwapIndex swapIndex = coupon.swapIndex(); VanillaSwap swap = swapIndex.underlyingSwap(coupon.fixingDate()); swapRateValue_ = swap.fairRate(); objectiveFunction_ = new ObjectiveFunction(this, swapRateValue_); Schedule schedule = swap.fixedSchedule(); Handle <YieldTermStructure> rateCurve = swapIndex.forwardingTermStructure(); DayCounter dc = swapIndex.dayCounter(); swapStartTime_ = dc.yearFraction(rateCurve.link.referenceDate(), schedule.startDate()); discountAtStart_ = rateCurve.link.discount(schedule.startDate()); double paymentTime = dc.yearFraction(rateCurve.link.referenceDate(), coupon.date()); shapedPaymentTime_ = shapeOfShift(paymentTime); List <CashFlow> fixedLeg = new List <CashFlow>(swap.fixedLeg()); int n = fixedLeg.Count; shapedSwapPaymentTimes_ = new List <double>(); swapPaymentDiscounts_ = new List <double>(); accruals_ = new List <double>(); for (int i = 0; i < n; ++i) { Coupon coupon1 = fixedLeg[i] as Coupon; accruals_.Add(coupon1.accrualPeriod()); Date paymentDate = new Date(coupon1.date().serialNumber()); double swapPaymentTime = dc.yearFraction(rateCurve.link.referenceDate(), paymentDate); shapedSwapPaymentTimes_.Add(shapeOfShift(swapPaymentTime)); swapPaymentDiscounts_.Add(rateCurve.link.discount(paymentDate)); } discountRatio_ = swapPaymentDiscounts_.Last() / discountAtStart_; }
public static double accrualPeriod(List <CashFlow> leg, bool includeSettlementDateFlows, Date settlementDate = null) { CashFlow cf = nextCashFlow(leg, includeSettlementDateFlows, settlementDate); if (cf == null) { return(0); } Date paymentDate = cf.date(); foreach (CashFlow x in leg.Where(x => x.date() == paymentDate)) { Coupon cp = x as Coupon; if (cp != null) { return(cp.accrualPeriod()); } } return(0); }
public void visit(Coupon c) { result_ += c.accrualPeriod() * c.nominal() * termStructure_.discount(c.date()); }
public override void initialize(FloatingRateCoupon coupon) { coupon_ = coupon as CmsCoupon; Utils.QL_REQUIRE(coupon_ != null, () => "CMS coupon needed"); gearing_ = coupon_.gearing(); spread_ = coupon_.spread(); fixingDate_ = coupon_.fixingDate(); paymentDate_ = coupon_.date(); swapIndex_ = coupon_.swapIndex(); forwardCurve_ = swapIndex_.forwardingTermStructure(); if (swapIndex_.exogenousDiscount()) { discountCurve_ = swapIndex_.discountingTermStructure(); } else { discountCurve_ = forwardCurve_; } // if no coupon discount curve is given just use the discounting curve // from the swap index. for rate calculation this curve cancels out in // the computation, so e.g. the discounting swap engine will produce // correct results, even if the couponDiscountCurve is not set here. // only the price member function in this class will be dependent on the // coupon discount curve. today_ = QLNet.Settings.evaluationDate(); if (paymentDate_ > today_ && !couponDiscountCurve_.empty()) { couponDiscountRatio_ = couponDiscountCurve_.link.discount(paymentDate_) / discountCurve_.link.discount(paymentDate_); } else { couponDiscountRatio_ = 1.0; } spreadLegValue_ = spread_ * coupon_.accrualPeriod() * discountCurve_.link.discount(paymentDate_) * couponDiscountRatio_; if (fixingDate_ > today_) { swapTenor_ = swapIndex_.tenor(); swap_ = swapIndex_.underlyingSwap(fixingDate_); swapRateValue_ = swap_.fairRate(); annuity_ = 1.0E4 * Math.Abs(swap_.fixedLegBPS()); SmileSection sectionTmp = swaptionVolatility().link.smileSection(fixingDate_, swapTenor_); // adjust bounds by section's shift shiftedLowerBound_ = settings_.lowerRateBound_ - sectionTmp.shift(); shiftedUpperBound_ = settings_.upperRateBound_ - sectionTmp.shift(); // if the section does not provide an atm level, we enhance it to // have one, no need to exit with an exception ... if (sectionTmp.atmLevel() == null) { smileSection_ = new AtmSmileSection(sectionTmp, swapRateValue_); } else { smileSection_ = sectionTmp; } // compute linear model's parameters double gx = 0.0, gy = 0.0; for (int i = 0; i < swap_.fixedLeg().Count; i++) { Coupon c = swap_.fixedLeg()[i] as Coupon; double yf = c.accrualPeriod(); Date d = c.date(); double pv = yf * discountCurve_.link.discount(d); gx += pv * GsrG(d); gy += pv; } double gamma = gx / gy; Date lastd = swap_.fixedLeg().Last().date(); a_ = discountCurve_.link.discount(paymentDate_) * (gamma - GsrG(paymentDate_)) / (discountCurve_.link.discount(lastd) * GsrG(lastd) + swapRateValue_ * gy * gamma); b_ = discountCurve_.link.discount(paymentDate_) / gy - a_ * swapRateValue_; } }