//------------------------------------------------------------------------- // accrual schedule private static PeriodicSchedule parseAccrualSchedule(CsvRow row, string leg) { PeriodicSchedule.Builder builder = PeriodicSchedule.builder(); // basics builder.startDate(LoaderUtils.parseDate(getValueWithFallback(row, leg, START_DATE_FIELD))); builder.endDate(LoaderUtils.parseDate(getValueWithFallback(row, leg, END_DATE_FIELD))); builder.frequency(Frequency.parse(getValue(row, leg, FREQUENCY_FIELD))); // adjustments BusinessDayAdjustment dateAdj = parseBusinessDayAdjustment(row, leg, DATE_ADJ_CNV_FIELD, DATE_ADJ_CAL_FIELD).orElse(BusinessDayAdjustment.NONE); Optional <BusinessDayAdjustment> startDateAdj = parseBusinessDayAdjustment(row, leg, START_DATE_CNV_FIELD, START_DATE_CAL_FIELD); Optional <BusinessDayAdjustment> endDateAdj = parseBusinessDayAdjustment(row, leg, END_DATE_CNV_FIELD, END_DATE_CAL_FIELD); builder.businessDayAdjustment(dateAdj); if (startDateAdj.Present && !startDateAdj.get().Equals(dateAdj)) { builder.startDateBusinessDayAdjustment(startDateAdj.get()); } if (endDateAdj.Present && !endDateAdj.get().Equals(dateAdj)) { builder.endDateBusinessDayAdjustment(endDateAdj.get()); } // optionals builder.stubConvention(findValueWithFallback(row, leg, STUB_CONVENTION_FIELD).map(s => StubConvention.of(s)).orElse(StubConvention.SMART_INITIAL)); findValue(row, leg, ROLL_CONVENTION_FIELD).map(s => LoaderUtils.parseRollConvention(s)).ifPresent(v => builder.rollConvention(v)); findValue(row, leg, FIRST_REGULAR_START_DATE_FIELD).map(s => LoaderUtils.parseDate(s)).ifPresent(v => builder.firstRegularStartDate(v)); findValue(row, leg, LAST_REGULAR_END_DATE_FIELD).map(s => LoaderUtils.parseDate(s)).ifPresent(v => builder.lastRegularEndDate(v)); parseAdjustableDate(row, leg, OVERRIDE_START_DATE_FIELD, OVERRIDE_START_DATE_CNV_FIELD, OVERRIDE_START_DATE_CAL_FIELD).ifPresent(d => builder.overrideStartDate(d)); return(builder.build()); }
// parse a trade based on a convention internal static SwapTrade parseWithConvention(CsvRow row, TradeInfo info, TradeCsvInfoResolver resolver, string conventionStr) { BuySell buySell = LoaderUtils.parseBuySell(row.getValue(BUY_SELL_FIELD)); double notional = LoaderUtils.parseDouble(row.getValue(NOTIONAL_FIELD)); double fixedRate = LoaderUtils.parseDoublePercent(row.getValue(FIXED_RATE_FIELD)); Optional <Period> periodToStartOpt = row.findValue(PERIOD_TO_START_FIELD).map(s => LoaderUtils.parsePeriod(s)); Optional <Tenor> tenorOpt = row.findValue(TENOR_FIELD).map(s => LoaderUtils.parseTenor(s)); Optional <LocalDate> startDateOpt = row.findValue(START_DATE_FIELD).map(s => LoaderUtils.parseDate(s)); Optional <LocalDate> endDateOpt = row.findValue(END_DATE_FIELD).map(s => LoaderUtils.parseDate(s)); Optional <RollConvention> rollCnvOpt = row.findValue(ROLL_CONVENTION_FIELD).map(s => LoaderUtils.parseRollConvention(s)); Optional <StubConvention> stubCnvOpt = row.findValue(STUB_CONVENTION_FIELD).map(s => StubConvention.of(s)); Optional <LocalDate> firstRegStartDateOpt = row.findValue(FIRST_REGULAR_START_DATE_FIELD).map(s => LoaderUtils.parseDate(s)); Optional <LocalDate> lastRegEndDateOpt = row.findValue(LAST_REGULAR_END_DATE_FIELD).map(s => LoaderUtils.parseDate(s)); BusinessDayConvention dateCnv = row.findValue(DATE_ADJ_CNV_FIELD).map(s => LoaderUtils.parseBusinessDayConvention(s)).orElse(BusinessDayConventions.MODIFIED_FOLLOWING); Optional <HolidayCalendarId> dateCalOpt = row.findValue(DATE_ADJ_CAL_FIELD).map(s => HolidayCalendarId.of(s)); double? fxRateOpt = row.findValue(FX_RATE_FIELD).map(str => LoaderUtils.parseDouble(str)); // explicit dates take precedence over relative ones if (startDateOpt.Present && endDateOpt.Present) { if (periodToStartOpt.Present || tenorOpt.Present) { throw new System.ArgumentException("Swap trade had invalid combination of fields. When these fields are found " + ImmutableList.of(CONVENTION_FIELD, START_DATE_FIELD, END_DATE_FIELD) + " then these fields must not be present " + ImmutableList.of(PERIOD_TO_START_FIELD, TENOR_FIELD)); } LocalDate startDate = startDateOpt.get(); LocalDate endDate = endDateOpt.get(); SwapTrade trade = createSwap(info, conventionStr, startDate, endDate, buySell, notional, fixedRate, fxRateOpt); return(adjustTrade(trade, rollCnvOpt, stubCnvOpt, firstRegStartDateOpt, lastRegEndDateOpt, dateCnv, dateCalOpt)); } // start date + tenor if (startDateOpt.Present && tenorOpt.Present) { if (periodToStartOpt.Present || endDateOpt.Present) { throw new System.ArgumentException("Swap trade had invalid combination of fields. When these fields are found " + ImmutableList.of(CONVENTION_FIELD, START_DATE_FIELD, TENOR_FIELD) + " then these fields must not be present " + ImmutableList.of(PERIOD_TO_START_FIELD, END_DATE_FIELD)); } LocalDate startDate = startDateOpt.get(); Tenor tenor = tenorOpt.get(); LocalDate endDate = startDate.plus(tenor); SwapTrade trade = createSwap(info, conventionStr, startDate, endDate, buySell, notional, fixedRate, fxRateOpt); return(adjustTrade(trade, rollCnvOpt, stubCnvOpt, firstRegStartDateOpt, lastRegEndDateOpt, dateCnv, dateCalOpt)); } // relative dates if (periodToStartOpt.Present && tenorOpt.Present && info.TradeDate.Present) { if (startDateOpt.Present || endDateOpt.Present) { throw new System.ArgumentException("Swap trade had invalid combination of fields. When these fields are found " + ImmutableList.of(CONVENTION_FIELD, PERIOD_TO_START_FIELD, TENOR_FIELD, TRADE_DATE_FIELD) + " then these fields must not be present " + ImmutableList.of(START_DATE_FIELD, END_DATE_FIELD)); } LocalDate tradeDate = info.TradeDate.get(); Period periodToStart = periodToStartOpt.get(); Tenor tenor = tenorOpt.get(); if (fxRateOpt.HasValue) { XCcyIborIborSwapConvention convention = XCcyIborIborSwapConvention.of(conventionStr); double notionalFlat = notional * fxRateOpt.Value; SwapTrade trade = convention.createTrade(tradeDate, periodToStart, tenor, buySell, notional, notionalFlat, fixedRate, resolver.ReferenceData); trade = trade.toBuilder().info(info).build(); return(adjustTrade(trade, rollCnvOpt, stubCnvOpt, firstRegStartDateOpt, lastRegEndDateOpt, dateCnv, dateCalOpt)); } else { SingleCurrencySwapConvention convention = SingleCurrencySwapConvention.of(conventionStr); SwapTrade trade = convention.createTrade(tradeDate, periodToStart, tenor, buySell, notional, fixedRate, resolver.ReferenceData); trade = trade.toBuilder().info(info).build(); return(adjustTrade(trade, rollCnvOpt, stubCnvOpt, firstRegStartDateOpt, lastRegEndDateOpt, dateCnv, dateCalOpt)); } } // no match throw new System.ArgumentException("Swap trade had invalid combination of fields. These fields are mandatory:" + ImmutableList.of(BUY_SELL_FIELD, NOTIONAL_FIELD, FIXED_RATE_FIELD) + " and one of these combinations is mandatory: " + ImmutableList.of(CONVENTION_FIELD, TRADE_DATE_FIELD, PERIOD_TO_START_FIELD, TENOR_FIELD) + " or " + ImmutableList.of(CONVENTION_FIELD, START_DATE_FIELD, TENOR_FIELD) + " or " + ImmutableList.of(CONVENTION_FIELD, START_DATE_FIELD, END_DATE_FIELD)); }