.build(); NotionalSchedule notionalSchedule = NotionalSchedule.of(GBP, 1000d); RateCalculationSwapLeg test = RateCalculationSwapLeg.builder() .payReceive(PAY) .accrualSchedule(accrualSchedule) .calculation(rateCalc) .build(); assertEquals(test.getStartDate(), AdjustableDate.of(DATE_01_05, bda)); assertEquals(test.getEndDate(), AdjustableDate.of(DATE_04_05, bda)); assertEquals(test.getCurrency(), GBP); assertEquals(test.getPayReceive(), PAY); assertEquals(test.getAccrualSchedule(), accrualSchedule); assertEquals(test.getPaymentSchedule(), paymentSchedule); assertEquals(test.getNotionalSchedule(), notionalSchedule); assertEquals(test.getCalculation(), rateCalc);
public void test_pvbp_compounding_flat_ibor() { LocalDate tradeDate = RATES_USD.getValuationDate(); LocalDate effectiveDate = USD_LIBOR_3M_LIBOR_6M.calculateSpotDateFromTradeDate(tradeDate, REF_DATA); LocalDate endDate = effectiveDate.plus(TENOR_10Y); double spread = 0.0015; double shift = 1.0E-6; RateCalculationSwapLeg leg0 = IborIborSwapConventions.USD_LIBOR_3M_LIBOR_6M.getSpreadLeg() .toLeg(effectiveDate, endDate, RECEIVE, NOTIONAL, spread); RateCalculationSwapLeg legP = IborIborSwapConventions.USD_LIBOR_3M_LIBOR_6M.getSpreadLeg() .toLeg(effectiveDate, endDate, RECEIVE, NOTIONAL, spread + shift); double parSpread = PRICER_LEG.pvbp(leg0.resolve(REF_DATA), RATES_USD); double pv0 = PRICER_LEG.presentValue(leg0.resolve(REF_DATA), RATES_USD).getAmount(); double pvP = PRICER_LEG.presentValue(legP.resolve(REF_DATA), RATES_USD).getAmount(); double parSpreadExpected = (pvP - pv0) / shift; assertEquals(parSpread, parSpreadExpected, TOLERANCE_PVBP_FD); }
/** * Restricted copy constructor. * @param beanToCopy the bean to copy from, not null */ private Builder(RateCalculationSwapLeg beanToCopy) { this.payReceive = beanToCopy.getPayReceive(); this.accrualSchedule = beanToCopy.getAccrualSchedule(); this.paymentSchedule = beanToCopy.getPaymentSchedule(); this.notionalSchedule = beanToCopy.getNotionalSchedule(); this.calculation = beanToCopy.getCalculation(); }
@Override protected Object propertyGet(Bean bean, String propertyName, boolean quiet) { switch (propertyName.hashCode()) { case -885469925: // payReceive return ((RateCalculationSwapLeg) bean).getPayReceive(); case 304659814: // accrualSchedule return ((RateCalculationSwapLeg) bean).getAccrualSchedule(); case -1499086147: // paymentSchedule return ((RateCalculationSwapLeg) bean).getPaymentSchedule(); case 1447860727: // notionalSchedule return ((RateCalculationSwapLeg) bean).getNotionalSchedule(); case -934682935: // calculation return ((RateCalculationSwapLeg) bean).getCalculation(); case 3575610: // type return ((RateCalculationSwapLeg) bean).getType(); case -2129778896: // startDate return ((RateCalculationSwapLeg) bean).getStartDate(); case -1607727319: // endDate return ((RateCalculationSwapLeg) bean).getEndDate(); case 575402001: // currency return ((RateCalculationSwapLeg) bean).getCurrency(); } return super.propertyGet(bean, propertyName, quiet); }
private String notional(SwapLeg leg) { if (leg instanceof RateCalculationSwapLeg) { RateCalculationSwapLeg rcLeg = (RateCalculationSwapLeg) leg; NotionalSchedule notionalSchedule = rcLeg.getNotionalSchedule(); ValueSchedule amount = notionalSchedule.getAmount(); double notional = amount.getInitialValue(); String vary = !amount.getSteps().isEmpty() || amount.getStepSequence().isPresent() ? " variable" : ""; Currency currency = notionalSchedule.getFxReset().map(fxr -> fxr.getReferenceCurrency()).orElse(rcLeg.getCurrency()); return SummarizerUtils.amount(currency, notional) + vary; } if (leg instanceof RatePeriodSwapLeg) { RatePeriodSwapLeg rpLeg = (RatePeriodSwapLeg) leg; return SummarizerUtils.amount(rpLeg.getPaymentPeriods().get(0).getNotionalAmount()); } return ""; }
RateCalculation calculation = parseSwapCalculation(legEl, calcEl, accrualSchedule, document); legsBuilder.add(RateCalculationSwapLeg.builder() .payReceive(payReceive) .accrualSchedule(accrualSchedule)
ResolvedSwapLeg swapLeg = RateCalculationSwapLeg.builder() .payReceive(RECEIVE) .accrualSchedule(accrualSchedule) .calculation(rateCalc) .build() .resolve(REF_DATA); DiscountingSwapLegPricer pricer = DiscountingSwapLegPricer.DEFAULT; Map<Currency, Curve> dscCurve = RATES_GBP_INFLATION.getDiscountCurves();
public void test_collectIndices_simple() { RateCalculationSwapLeg test = RateCalculationSwapLeg.builder() .payReceive(PAY) .accrualSchedule(PeriodicSchedule.builder() .startDate(DATE_01_05) .endDate(DATE_04_05) .frequency(P1M) .businessDayAdjustment(BusinessDayAdjustment.of(FOLLOWING, GBLO)) .build()) .paymentSchedule(PaymentSchedule.builder() .paymentFrequency(P1M) .paymentDateOffset(PLUS_TWO_DAYS) .build()) .notionalSchedule(NotionalSchedule.of(GBP, 1000d)) .calculation(IborRateCalculation.builder() .dayCount(DayCounts.ACT_365F) .index(GBP_LIBOR_3M) .fixingDateOffset(MINUS_TWO_DAYS) .build()) .build(); ImmutableSet.Builder<Index> builder = ImmutableSet.builder(); test.collectIndices(builder); assertEquals(builder.build(), ImmutableSet.of(GBP_LIBOR_3M)); assertEquals(test.allIndices(), ImmutableSet.of(GBP_LIBOR_3M)); assertEquals(test.allCurrencies(), ImmutableSet.of(GBP)); }
private static SwapTrade adjustTrade( SwapTrade trade, Optional<RollConvention> rollConventionOpt, Optional<StubConvention> stubConventionOpt, Optional<LocalDate> firstRegularStartDateOpt, Optional<LocalDate> lastRegEndDateOpt, BusinessDayConvention dateCnv, Optional<HolidayCalendarId> dateCalOpt) { if (!rollConventionOpt.isPresent() && !stubConventionOpt.isPresent() && !firstRegularStartDateOpt.isPresent() && !lastRegEndDateOpt.isPresent() && !dateCalOpt.isPresent()) { return trade; } ImmutableList.Builder<SwapLeg> legBuilder = ImmutableList.builder(); for (SwapLeg leg : trade.getProduct().getLegs()) { RateCalculationSwapLeg swapLeg = (RateCalculationSwapLeg) leg; PeriodicSchedule.Builder scheduleBuilder = swapLeg.getAccrualSchedule().toBuilder(); rollConventionOpt.ifPresent(rc -> scheduleBuilder.rollConvention(rc)); stubConventionOpt.ifPresent(sc -> scheduleBuilder.stubConvention(sc)); firstRegularStartDateOpt.ifPresent(date -> scheduleBuilder.firstRegularStartDate(date)); lastRegEndDateOpt.ifPresent(date -> scheduleBuilder.lastRegularEndDate(date)); dateCalOpt.ifPresent(cal -> scheduleBuilder.businessDayAdjustment(BusinessDayAdjustment.of(dateCnv, cal))); legBuilder.add(swapLeg.toBuilder() .accrualSchedule(scheduleBuilder.build()) .build()); } return replaceLegs(trade, legBuilder.build()); }
private static SwapTrade parseVariableNotional(SwapTrade trade, List<CsvRow> variableRows) { // parse notionals ImmutableList.Builder<ValueStep> stepBuilder = ImmutableList.builder(); for (CsvRow row : variableRows) { LocalDate date = LoaderUtils.parseDate(row.getValue(START_DATE_FIELD)); row.findValue(NOTIONAL_FIELD) .map(str -> LoaderUtils.parseDouble(str)) .ifPresent(notional -> stepBuilder.add(ValueStep.of(date, ValueAdjustment.ofReplace(notional)))); } ImmutableList<ValueStep> varNotionals = stepBuilder.build(); if (varNotionals.isEmpty()) { return trade; } // adjust the trade, inserting the variable notionals ImmutableList.Builder<SwapLeg> legBuilder = ImmutableList.builder(); for (SwapLeg swapLeg : trade.getProduct().getLegs()) { RateCalculationSwapLeg leg = (RateCalculationSwapLeg) swapLeg; NotionalSchedule notionalSchedule = leg.getNotionalSchedule().toBuilder() .amount(ValueSchedule.of(leg.getNotionalSchedule().getAmount().getInitialValue(), varNotionals)) .build(); legBuilder.add(leg.toBuilder().notionalSchedule(notionalSchedule).build()); } return replaceLegs(trade, legBuilder.build()); }
private static SwapTrade parseVariableRates(SwapTrade trade, List<CsvRow> variableRows) { ImmutableList.Builder<ValueStep> stepBuilder = ImmutableList.builder(); for (CsvRow row : variableRows) { LocalDate date = LoaderUtils.parseDate(row.getValue(START_DATE_FIELD)); row.findValue(FIXED_RATE_FIELD) .map(str -> LoaderUtils.parseDoublePercent(str)) .ifPresent(fixedRate -> stepBuilder.add(ValueStep.of(date, ValueAdjustment.ofReplace(fixedRate)))); } ImmutableList<ValueStep> varRates = stepBuilder.build(); if (varRates.isEmpty()) { return trade; } // adjust the trade, inserting the variable rates ImmutableList.Builder<SwapLeg> legBuilder = ImmutableList.builder(); for (SwapLeg swapLeg : trade.getProduct().getLegs()) { RateCalculationSwapLeg leg = (RateCalculationSwapLeg) swapLeg; if (leg.getCalculation() instanceof FixedRateCalculation) { FixedRateCalculation baseCalc = (FixedRateCalculation) leg.getCalculation(); FixedRateCalculation calc = baseCalc.toBuilder() .rate(ValueSchedule.of(baseCalc.getRate().getInitialValue(), varRates)) .build(); legBuilder.add(leg.toBuilder().calculation(calc).build()); } else { legBuilder.add(leg); } } return replaceLegs(trade, legBuilder.build()); }
@ImmutableValidator private void validate() { ArgChecker.isFalse(underlyingSwap.isCrossCurrency(), "Underlying swap must not be cross currency"); for (SwapLeg swapLeg : underlyingSwap.getLegs()) { if (swapLeg.getType().equals(SwapLegType.FIXED)) { ArgChecker.isTrue(swapLeg.getPayReceive().isReceive(), "Underlying swap must receive the fixed leg"); } if (swapLeg instanceof RateCalculationSwapLeg) { RateCalculationSwapLeg leg = (RateCalculationSwapLeg) swapLeg; ArgChecker.isTrue(Math.abs(leg.getNotionalSchedule().getAmount().getInitialValue()) == 1d, "Underlying swap must have a notional of 1"); } } }
/** * Converts this swap leg to the equivalent {@code ResolvedSwapLeg}. * <p> * An {@link ResolvedSwapLeg} represents the same data as this leg, but with * a complete schedule of dates defined using {@link RatePaymentPeriod}. * * @return the equivalent resolved swap leg * @throws ReferenceDataNotFoundException if an identifier cannot be resolved in the reference data * @throws RuntimeException if unable to resolve due to an invalid swap schedule or definition */ @Override public ResolvedSwapLeg resolve(ReferenceData refData) { DayCount dayCount = calculation.getDayCount(); Schedule resolvedAccruals = accrualSchedule.createSchedule(refData); Schedule resolvedPayments = paymentSchedule.createSchedule(resolvedAccruals, refData); List<RateAccrualPeriod> accrualPeriods = calculation.createAccrualPeriods(resolvedAccruals, resolvedPayments, refData); List<NotionalPaymentPeriod> payPeriods = paymentSchedule.createPaymentPeriods( resolvedAccruals, resolvedPayments, accrualPeriods, dayCount, notionalSchedule, payReceive, refData); LocalDate startDate = accrualPeriods.get(0).getStartDate(); ImmutableList<SwapPaymentEvent> payEvents = notionalSchedule.createEvents(payPeriods, startDate, refData); return new ResolvedSwapLeg(getType(), payReceive, payPeriods, payEvents, getCurrency()); }
private String legSummary(SwapLeg leg) { if (leg instanceof RateCalculationSwapLeg) { RateCalculationSwapLeg rcLeg = (RateCalculationSwapLeg) leg; RateCalculation calculation = rcLeg.getCalculation(); if (calculation instanceof FixedRateCalculation) { FixedRateCalculation calc = (FixedRateCalculation) calculation;
@Override public void collectCurrencies(ImmutableSet.Builder<Currency> builder) { builder.add(getCurrency()); calculation.collectCurrencies(builder); notionalSchedule.getFxReset().ifPresent(fxReset -> builder.add(fxReset.getReferenceCurrency())); }
private static RateCalculationSwapLeg parseLeg( CsvRow row, String leg, FloatingRateIndex index, DayCount defaultFixedLegDayCount) { PayReceive payReceive = LoaderUtils.parsePayReceive(getValue(row, leg, DIRECTION_FIELD)); PeriodicSchedule accrualSch = parseAccrualSchedule(row, leg); PaymentSchedule paymentSch = parsePaymentSchedule(row, leg, accrualSch.getFrequency()); NotionalSchedule notionalSch = parseNotionalSchedule(row, leg); RateCalculation calc = parseRateCalculation( row, leg, index, defaultFixedLegDayCount, accrualSch.getBusinessDayAdjustment(), notionalSch.getCurrency()); return RateCalculationSwapLeg.builder() .payReceive(payReceive) .accrualSchedule(accrualSch) .paymentSchedule(paymentSch) .notionalSchedule(notionalSch) .calculation(calc) .build(); }
public void compoundSwap_cashFlows() { RateCalculationSwapLeg recLeg = RateCalculationSwapLeg.builder() .payReceive(RECEIVE) .accrualSchedule(PeriodicSchedule.builder() .build()) .build(); RateCalculationSwapLeg payLeg = RateCalculationSwapLeg.builder() .payReceive(PAY) .accrualSchedule(PeriodicSchedule.builder() HolidayCalendarIds.SAT_SUN, HolidayCalendars.SAT_SUN, HolidayCalendarIds.NO_HOLIDAYS, HolidayCalendars.NO_HOLIDAYS)); ResolvedSwapLeg expandedRecLeg = recLeg.resolve(refData); assertEquals(expandedRecLeg.getPaymentPeriods().size(), 4); assertIborPaymentPeriodCpd(expandedRecLeg, 0, 0, "2000-11-03", "2000-04-27", "2000-07-27", 100000000d, "2000-04-25"); ResolvedSwapLeg expandedPayLeg = payLeg.resolve(refData); assertEquals(expandedPayLeg.getPaymentPeriods().size(), 4); assertFixedPaymentPeriod(expandedPayLeg, 0, "2000-11-03", "2000-04-27", "2000-10-27", 100000000d, 0.0585d);
public void test_collectIndices_fxReset() { RateCalculationSwapLeg test = RateCalculationSwapLeg.builder() .payReceive(PAY) .accrualSchedule(PeriodicSchedule.builder() .build(); ImmutableSet.Builder<Index> builder = ImmutableSet.builder(); test.collectIndices(builder); assertEquals(builder.build(), ImmutableSet.of(GBP_LIBOR_3M, EUR_GBP_ECB)); assertEquals(test.allIndices(), ImmutableSet.of(GBP_LIBOR_3M, EUR_GBP_ECB)); assertEquals(test.allCurrencies(), ImmutableSet.of(GBP, EUR));
@ImmutableValidator private void validate() { ArgChecker.inOrderOrEqual( deliveryDate, underlyingSwap.getStartDate().getUnadjusted(), "deliveryDate", "underlyingSwap.startDate.unadjusted"); ArgChecker.isFalse(underlyingSwap.isCrossCurrency(), "Underlying swap must not be cross currency"); for (SwapLeg swapLeg : underlyingSwap.getLegs()) { if (swapLeg.getType().equals(SwapLegType.FIXED)) { ArgChecker.isTrue(swapLeg.getPayReceive().isReceive(), "Underlying swap must receive the fixed leg"); } if (swapLeg instanceof RateCalculationSwapLeg) { RateCalculationSwapLeg leg = (RateCalculationSwapLeg) swapLeg; ArgChecker.isTrue(Math.abs(leg.getNotionalSchedule().getAmount().getInitialValue()) == 1d, "Underlying swap must have a notional of 1"); } } ArgChecker.inOrderOrEqual(lastTradeDate, deliveryDate, "lastTradeDate", "deliveryDate"); }
public void test_toLeg1() { FixedRateSwapLegConvention base = FixedRateSwapLegConvention.of(GBP, ACT_365F, P3M, BDA_MOD_FOLLOW); LocalDate startDate = LocalDate.of(2015, 5, 5); LocalDate endDate = LocalDate.of(2020, 5, 5); RateCalculationSwapLeg test = base.toLeg(startDate, endDate, PAY, NOTIONAL_2M, 0.25d); RateCalculationSwapLeg expected = RateCalculationSwapLeg.builder() .payReceive(PAY) .accrualSchedule(PeriodicSchedule.builder() .frequency(P3M) .startDate(startDate) .endDate(endDate) .businessDayAdjustment(BDA_MOD_FOLLOW) .stubConvention(StubConvention.SMART_INITIAL) .build()) .paymentSchedule(PaymentSchedule.builder() .paymentFrequency(P3M) .paymentDateOffset(DaysAdjustment.NONE) .build()) .notionalSchedule(NotionalSchedule.of(GBP, NOTIONAL_2M)) .calculation(FixedRateCalculation.of(0.25d, ACT_365F)) .build(); assertEquals(test, expected); }