//------------------------------------------------------------------------- private double forecastValueFwdSensitivity(ResolvedFra fra, double forwardRate, double eps) { RateComputationFn<RateComputation> obsFuncNew = mock(typeof(RateComputationFn)); RatesProvider provNew = mock(typeof(RatesProvider)); when(provNew.ValuationDate).thenReturn(VAL_DATE); when(obsFuncNew.rate(fra.FloatingRate, fra.StartDate, fra.EndDate, provNew)).thenReturn(forwardRate + eps); CurrencyAmount upValue = (new DiscountingFraProductPricer(obsFuncNew)).forecastValue(fra, provNew); when(obsFuncNew.rate(fra.FloatingRate, fra.StartDate, fra.EndDate, provNew)).thenReturn(forwardRate - eps); CurrencyAmount downValue = (new DiscountingFraProductPricer(obsFuncNew)).forecastValue(fra, provNew); return upValue.minus(downValue).multipliedBy(0.5 / eps).Amount; }
private double dscSensitivity(ResolvedFra fra, double forwardRate, double discountFactor, double paymentTime, double eps) { RatesProvider provNew = mock(typeof(RatesProvider)); when(provNew.ValuationDate).thenReturn(VAL_DATE); RateComputationFn<RateComputation> obsFuncNew = mock(typeof(RateComputationFn)); when(obsFuncNew.rate(fra.FloatingRate, fra.StartDate, fra.EndDate, provNew)).thenReturn(forwardRate); when(provNew.discountFactor(fra.Currency, fra.PaymentDate)).thenReturn(discountFactor * Math.Exp(-eps * paymentTime)); CurrencyAmount upDscValue = (new DiscountingFraProductPricer(obsFuncNew)).presentValue(fra, provNew); when(provNew.discountFactor(fra.Currency, fra.PaymentDate)).thenReturn(discountFactor * Math.Exp(eps * paymentTime)); CurrencyAmount downDscValue = (new DiscountingFraProductPricer(obsFuncNew)).presentValue(fra, provNew); return upDscValue.minus(downDscValue).multipliedBy(0.5 / eps).Amount; }
// XCcy swap with exchange of notional and FX Reset on the USD leg public virtual void test_XCcyFixedInitialNotional() { DiscountingSwapTradePricer pricer = swapPricer(); //Create an MTM swap with initial notional override double notional = 1_000_000d; ResolvedSwapTrade fixedNotionalMtmTrade = getMtmTrade(true, true, true, notional).resolve(REF_DATA); ExplainMap explainMap = pricer.explainPresentValue(fixedNotionalMtmTrade, provider()); CurrencyAmount fixedNotional = CurrencyAmount.of(Currency.USD, notional); ExplainMap fixedNotionalMtmLeg = explainMap.get(ExplainKey.LEGS).get().get(1); IList <ExplainMap> events = fixedNotionalMtmLeg.get(ExplainKey.PAYMENT_EVENTS).get(); //First two payment events should use fixed initial notional ExplainMap firstPaymentEvent = events[0]; assertFixedNotionalPaymentEvent(firstPaymentEvent, fixedNotional.negated()); ExplainMap secondPaymentEvent = events[1]; assertFixedNotionalPaymentEvent(secondPaymentEvent, fixedNotional); //First coupon also uses fixed notional ExplainMap firstCoupon = fixedNotionalMtmLeg.get(ExplainKey.PAYMENT_PERIODS).get().get(0); assertEquals(firstCoupon.get(ExplainKey.TRADE_NOTIONAL), fixedNotional); assertEquals(firstCoupon.get(ExplainKey.NOTIONAL), fixedNotional); //Sum of all pv amounts which are impacted by overriding the first period with a fixed notional CurrencyAmount firstPaymentPv = firstPaymentEvent.get(ExplainKey.PRESENT_VALUE).get(); CurrencyAmount secondPaymentPv = secondPaymentEvent.get(ExplainKey.PRESENT_VALUE).get(); CurrencyAmount firstCouponPv = firstCoupon.get(ExplainKey.PRESENT_VALUE).get(); CurrencyAmount fixedNotionalImpactedEventsPv = firstPaymentPv.plus(secondPaymentPv).plus(firstCouponPv); //---------------------------------------------------------------------------------------------------------- //Build identical trade but with no fixed notional ResolvedSwapTrade noFixedNotionalMtmTrade = getMtmTrade(true, true, true, null).resolve(REF_DATA); ExplainMap noFixedNotionalMtmLeg = pricer.explainPresentValue(noFixedNotionalMtmTrade, provider()).get(ExplainKey.LEGS).get().get(1); //Sum the pvs for the same combination of payments and events that are impacted by fixed notional in first trade //JAVA TO C# CONVERTER TODO TASK: Method reference arbitrary object instance method syntax is not converted by Java to C# Converter: CurrencyAmount noFixedNotionalEventsPv = noFixedNotionalMtmLeg.get(ExplainKey.PAYMENT_EVENTS).get().subList(0, 2).Select(payment => payment.get(ExplainKey.PRESENT_VALUE).get()).Aggregate(CurrencyAmount.zero(Currency.USD), CurrencyAmount::plus); CurrencyAmount noFixedNotionalCouponsPv = noFixedNotionalMtmLeg.get(ExplainKey.PAYMENT_PERIODS).get().get(0).get(ExplainKey.PRESENT_VALUE).get(); CurrencyAmount noFixedNotionalImpactedEventsPv = noFixedNotionalCouponsPv.plus(noFixedNotionalEventsPv); //---------------------------------------------------------------------------------------------------------- //PV difference of the events impacted by fixing notional CurrencyAmount paymentsPvDifference = fixedNotionalImpactedEventsPv.minus(noFixedNotionalImpactedEventsPv); //Calculate PV of the full trades MultiCurrencyAmount fixedNotionalLegPv = pricer.presentValue(fixedNotionalMtmTrade, provider()); MultiCurrencyAmount noFixedNotionalLegPv = pricer.presentValue(noFixedNotionalMtmTrade, provider()); //EUR PV should not have changed assertEquals(fixedNotionalLegPv.getAmount(Currency.EUR).Amount, noFixedNotionalLegPv.getAmount(Currency.EUR).Amount, TOLERANCE_PV); //Difference in USD PV should be equal the difference in PV of the three events impacted by the initial notional //All else should remain equal CurrencyAmount tradePvDifference = fixedNotionalLegPv.getAmount(Currency.USD).minus(noFixedNotionalLegPv.getAmount(Currency.USD)); assertEquals(tradePvDifference.Amount, paymentsPvDifference.Amount, TOLERANCE_PV); }