// At-the-money rate of the cash flows. // The result is the fixed rate for which a fixed rate cash flow vector, equivalent to the input vector, has the required NPV according to the given term structure. If the required NPV is // not given, the input cash flow vector's NPV is used instead. public static double atmRate(Leg leg, YieldTermStructure discountCurve, bool includeSettlementDateFlows, Date settlementDate = null, Date npvDate = null, double?targetNpv = null) { if (settlementDate == null) { settlementDate = Settings.evaluationDate(); } if (npvDate == null) { npvDate = settlementDate; } double npv = 0.0; BPSCalculator calc = new BPSCalculator(discountCurve); for (int i = 0; i < leg.Count; ++i) { CashFlow cf = leg[i]; if (!cf.hasOccurred(settlementDate, includeSettlementDateFlows) && !cf.tradingExCoupon(settlementDate)) { npv += cf.amount() * discountCurve.discount(cf.date()); cf.accept(calc); } } if (targetNpv == null) { targetNpv = npv - calc.nonSensNPV(); } else { targetNpv *= discountCurve.discount(npvDate); targetNpv -= calc.nonSensNPV(); } if (targetNpv.IsEqual(0.0)) { return(0.0); } double bps = calc.bps(); Utils.QL_REQUIRE(bps.IsNotEqual(0.0), () => "null bps: impossible atm rate"); return(targetNpv.Value / bps); }