/// <summary> /// Computes cash flow equivalent of Ibor leg. /// <para> /// The return type is {@code ResolvedSwapLeg} in which individual payments are /// represented in terms of {@code NotionalExchange}. /// /// </para> /// </summary> /// <param name="iborLeg"> the Ibor leg </param> /// <param name="ratesProvider"> the rates provider </param> /// <returns> the cash flow equivalent </returns> public static ResolvedSwapLeg cashFlowEquivalentIborLeg(ResolvedSwapLeg iborLeg, RatesProvider ratesProvider) { ArgChecker.isTrue(iborLeg.Type.Equals(SwapLegType.IBOR), "Leg type should be IBOR"); ArgChecker.isTrue(iborLeg.PaymentEvents.Empty, "PaymentEvent should be empty"); IList <NotionalExchange> paymentEvents = new List <NotionalExchange>(); foreach (SwapPaymentPeriod paymentPeriod in iborLeg.PaymentPeriods) { ArgChecker.isTrue(paymentPeriod is RatePaymentPeriod, "rate payment should be RatePaymentPeriod"); RatePaymentPeriod ratePaymentPeriod = (RatePaymentPeriod)paymentPeriod; ArgChecker.isTrue(ratePaymentPeriod.AccrualPeriods.size() == 1, "rate payment should not be compounding"); RateAccrualPeriod rateAccrualPeriod = ratePaymentPeriod.AccrualPeriods.get(0); CurrencyAmount notional = ratePaymentPeriod.NotionalAmount; LocalDate paymentDate = ratePaymentPeriod.PaymentDate; IborIndexObservation obs = ((IborRateComputation)rateAccrualPeriod.RateComputation).Observation; IborIndex index = obs.Index; LocalDate fixingStartDate = obs.EffectiveDate; double fixingYearFraction = obs.YearFraction; double beta = (1d + fixingYearFraction * ratesProvider.iborIndexRates(index).rate(obs)) * ratesProvider.discountFactor(paymentPeriod.Currency, paymentPeriod.PaymentDate) / ratesProvider.discountFactor(paymentPeriod.Currency, fixingStartDate); double ycRatio = rateAccrualPeriod.YearFraction / fixingYearFraction; NotionalExchange payStart = NotionalExchange.of(notional.multipliedBy(beta * ycRatio), fixingStartDate); NotionalExchange payEnd = NotionalExchange.of(notional.multipliedBy(-ycRatio), paymentDate); paymentEvents.Add(payStart); paymentEvents.Add(payEnd); } ResolvedSwapLeg leg = ResolvedSwapLeg.builder().paymentEvents(paymentEvents).payReceive(PayReceive.RECEIVE).type(SwapLegType.OTHER).build(); return(leg); }
/// <summary> /// Computes parallel CS01 for CDS index using a single credit curve. /// <para> /// This is coherent to the pricer <seealso cref="IsdaHomogenousCdsIndexTradePricer"/>. /// The relevant credit curve must be stored in {@code RatesProvider}. /// /// </para> /// </summary> /// <param name="trade"> the trade </param> /// <param name="bucketCdsIndex"> the CDS index bucket </param> /// <param name="ratesProvider"> the rates provider </param> /// <param name="refData"> the reference data </param> /// <returns> the parallel CS01 </returns> public virtual CurrencyAmount parallelCs01(ResolvedCdsIndexTrade trade, IList <ResolvedCdsIndexTrade> bucketCdsIndex, CreditRatesProvider ratesProvider, ReferenceData refData) { ResolvedCdsTrade cdsTrade = trade.toSingleNameCds(); //JAVA TO C# CONVERTER TODO TASK: Method reference arbitrary object instance method syntax is not converted by Java to C# Converter: IList <ResolvedCdsTrade> bucketCds = bucketCdsIndex.Select(ResolvedCdsIndexTrade::toSingleNameCds).ToList(); CurrencyAmount cs01Cds = parallelCs01(cdsTrade, bucketCds, ratesProvider, refData); double indexFactor = getIndexFactor(cdsTrade.Product, ratesProvider); return(cs01Cds.multipliedBy(indexFactor)); }
private void assertFixedNotionalPaymentEvent(ExplainMap paymentEvent, CurrencyAmount expectedNotional) { assertEquals(paymentEvent.get(ExplainKey.TRADE_NOTIONAL), expectedNotional); assertEquals(paymentEvent.get(ExplainKey.FORECAST_VALUE), expectedNotional); double firstDiscountFactor = paymentEvent.get(ExplainKey.DISCOUNT_FACTOR).Value; //Fixed notional, so PV is notional * DCF CurrencyAmount expectedPv = expectedNotional.multipliedBy(firstDiscountFactor); assertEquals(paymentEvent.get(ExplainKey.PRESENT_VALUE), expectedPv); }
/// <summary> /// Computes cash flow equivalent and sensitivity of Ibor leg. /// <para> /// The return type is a map of {@code NotionalExchange} and {@code PointSensitivityBuilder}. /// /// </para> /// </summary> /// <param name="iborLeg"> the Ibor leg </param> /// <param name="ratesProvider"> the rates provider </param> /// <returns> the cash flow equivalent and sensitivity </returns> public static ImmutableMap <Payment, PointSensitivityBuilder> cashFlowEquivalentAndSensitivityIborLeg(ResolvedSwapLeg iborLeg, RatesProvider ratesProvider) { ArgChecker.isTrue(iborLeg.Type.Equals(SwapLegType.IBOR), "Leg type should be IBOR"); ArgChecker.isTrue(iborLeg.PaymentEvents.Empty, "PaymentEvent should be empty"); IDictionary <Payment, PointSensitivityBuilder> res = new Dictionary <Payment, PointSensitivityBuilder>(); foreach (SwapPaymentPeriod paymentPeriod in iborLeg.PaymentPeriods) { ArgChecker.isTrue(paymentPeriod is RatePaymentPeriod, "rate payment should be RatePaymentPeriod"); RatePaymentPeriod ratePaymentPeriod = (RatePaymentPeriod)paymentPeriod; ArgChecker.isTrue(ratePaymentPeriod.AccrualPeriods.size() == 1, "rate payment should not be compounding"); RateAccrualPeriod rateAccrualPeriod = ratePaymentPeriod.AccrualPeriods.get(0); CurrencyAmount notional = ratePaymentPeriod.NotionalAmount; LocalDate paymentDate = ratePaymentPeriod.PaymentDate; IborIndexObservation obs = ((IborRateComputation)rateAccrualPeriod.RateComputation).Observation; IborIndex index = obs.Index; LocalDate fixingStartDate = obs.EffectiveDate; double fixingYearFraction = obs.YearFraction; double factorIndex = (1d + fixingYearFraction * ratesProvider.iborIndexRates(index).rate(obs)); double dfPayment = ratesProvider.discountFactor(paymentPeriod.Currency, paymentPeriod.PaymentDate); double dfStart = ratesProvider.discountFactor(paymentPeriod.Currency, fixingStartDate); double beta = factorIndex * dfPayment / dfStart; double ycRatio = rateAccrualPeriod.YearFraction / fixingYearFraction; Payment payStart = Payment.of(notional.multipliedBy(beta * ycRatio), fixingStartDate); Payment payEnd = Payment.of(notional.multipliedBy(-ycRatio), paymentDate); double factor = ycRatio * notional.Amount / dfStart; PointSensitivityBuilder factorIndexSensi = ratesProvider.iborIndexRates(index).ratePointSensitivity(obs).multipliedBy(fixingYearFraction * dfPayment * factor); PointSensitivityBuilder dfPaymentSensitivity = ratesProvider.discountFactors(paymentPeriod.Currency).zeroRatePointSensitivity(paymentPeriod.PaymentDate).multipliedBy(factorIndex * factor); PointSensitivityBuilder dfStartSensitivity = ratesProvider.discountFactors(paymentPeriod.Currency).zeroRatePointSensitivity(fixingStartDate).multipliedBy(-factorIndex * dfPayment * factor / dfStart); res[payStart] = factorIndexSensi.combinedWith(dfPaymentSensitivity).combinedWith(dfStartSensitivity); res[payEnd] = PointSensitivityBuilder.none(); } return(ImmutableMap.copyOf(res)); }
//------------------------------------------------------------------------- /// <summary> /// Creates a {@code CashFlow} representing a single cash flow from /// payment date, present value and discount factor. /// </summary> /// <param name="paymentDate"> the payment date </param> /// <param name="presentValue"> the present value as a currency amount </param> /// <param name="discountFactor"> the discount factor </param> /// <returns> the cash flow instance </returns> public static CashFlow ofPresentValue(LocalDate paymentDate, CurrencyAmount presentValue, double discountFactor) { return(new CashFlow(paymentDate, presentValue, presentValue.multipliedBy(1d / discountFactor), discountFactor)); }
/// <summary> /// Creates a {@code CashFlow} representing a single cash flow from /// payment date, forecast value and discount factor. /// </summary> /// <param name="paymentDate"> the payment date </param> /// <param name="forecastValue"> the forecast value as a currency amount </param> /// <param name="discountFactor"> the discount factor </param> /// <returns> the cash flow instance </returns> public static CashFlow ofForecastValue(LocalDate paymentDate, CurrencyAmount forecastValue, double discountFactor) { return(new CashFlow(paymentDate, forecastValue.multipliedBy(discountFactor), forecastValue, discountFactor)); }