//------------------------------------------------------------------------- // 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()); }
// adjust trade based on additional fields specified 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.Present && !stubConventionOpt.Present && !firstRegularStartDateOpt.Present && !lastRegEndDateOpt.Present && !dateCalOpt.Present) { return(trade); } ImmutableList.Builder <SwapLeg> legBuilder = ImmutableList.builder(); foreach (SwapLeg leg in trade.Product.Legs) { RateCalculationSwapLeg swapLeg = (RateCalculationSwapLeg)leg; PeriodicSchedule.Builder scheduleBuilder = swapLeg.AccrualSchedule.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())); }
// parses the accrual schedule private PeriodicSchedule parseSwapAccrualSchedule(XmlElement legEl, FpmlDocument document) { // supported elements: // 'calculationPeriodDates/effectiveDate' // 'calculationPeriodDates/relativeEffectiveDate' // 'calculationPeriodDates/terminationDate' // 'calculationPeriodDates/relativeTerminationDate' // 'calculationPeriodDates/calculationPeriodDates' // 'calculationPeriodDates/calculationPeriodDatesAdjustments' // 'calculationPeriodDates/firstPeriodStartDate?' // 'calculationPeriodDates/firstRegularPeriodStartDate?' // 'calculationPeriodDates/lastRegularPeriodEndDate?' // 'calculationPeriodDates/stubPeriodType?' // 'calculationPeriodDates/calculationPeriodFrequency' // ignored elements: // 'calculationPeriodDates/firstCompoundingPeriodEndDate?' PeriodicSchedule.Builder accrualScheduleBuilder = PeriodicSchedule.builder(); // calculation dates XmlElement calcPeriodDatesEl = legEl.getChild("calculationPeriodDates"); // business day adjustments BusinessDayAdjustment bda = document.parseBusinessDayAdjustments(calcPeriodDatesEl.getChild("calculationPeriodDatesAdjustments")); accrualScheduleBuilder.businessDayAdjustment(bda); // start date AdjustableDate startDate = calcPeriodDatesEl.findChild("effectiveDate").map(el => document.parseAdjustableDate(el)).orElseGet(() => document.parseAdjustedRelativeDateOffset(calcPeriodDatesEl.getChild("relativeEffectiveDate"))); accrualScheduleBuilder.startDate(startDate.Unadjusted); if (!bda.Equals(startDate.Adjustment)) { accrualScheduleBuilder.startDateBusinessDayAdjustment(startDate.Adjustment); } // end date AdjustableDate endDate = calcPeriodDatesEl.findChild("terminationDate").map(el => document.parseAdjustableDate(el)).orElseGet(() => document.parseAdjustedRelativeDateOffset(calcPeriodDatesEl.getChild("relativeTerminationDate"))); accrualScheduleBuilder.endDate(endDate.Unadjusted); if (!bda.Equals(endDate.Adjustment)) { accrualScheduleBuilder.endDateBusinessDayAdjustment(endDate.Adjustment); } // first period start date calcPeriodDatesEl.findChild("firstPeriodStartDate").ifPresent(el => { accrualScheduleBuilder.overrideStartDate(document.parseAdjustableDate(el)); }); // first regular date calcPeriodDatesEl.findChild("firstRegularPeriodStartDate").ifPresent(el => { accrualScheduleBuilder.firstRegularStartDate(document.parseDate(el)); }); // last regular date calcPeriodDatesEl.findChild("lastRegularPeriodEndDate").ifPresent(el => { accrualScheduleBuilder.lastRegularEndDate(document.parseDate(el)); }); // stub type calcPeriodDatesEl.findChild("stubPeriodType").ifPresent(el => { accrualScheduleBuilder.stubConvention(parseStubConvention(el, document)); }); // frequency XmlElement freqEl = calcPeriodDatesEl.getChild("calculationPeriodFrequency"); Frequency accrualFreq = document.parseFrequency(freqEl); accrualScheduleBuilder.frequency(accrualFreq); // roll convention accrualScheduleBuilder.rollConvention(document.convertRollConvention(freqEl.getChild("rollConvention").Content)); return(accrualScheduleBuilder.build()); }