// 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()); }
//------------------------------------------------------------------------- public Trade parseTrade(FpmlDocument document, XmlElement tradeEl) { // supported elements: // 'buyerPartyReference' // 'sellerPartyReference' // 'adjustedTerminationDate' // 'paymentDate' // 'fixingDateOffset' // 'dayCountFraction' // 'notional' // 'fixedRate' // 'floatingRateIndex' // 'indexTenor+' // 'fraDiscounting' // ignored elements: // 'Product.model?' // 'buyerAccountReference?' // 'sellerAccountReference?' // 'calculationPeriodNumberOfDays' // 'additionalPayment*' TradeInfoBuilder tradeInfoBuilder = document.parseTradeInfo(tradeEl); XmlElement fraEl = tradeEl.getChild("fra"); Fra.Builder fraBuilder = Fra.builder(); // buy/sell and counterparty fraBuilder.buySell(document.parseBuyerSeller(fraEl, tradeInfoBuilder)); // start date fraBuilder.startDate(document.parseDate(fraEl.getChild("adjustedEffectiveDate"))); // end date fraBuilder.endDate(document.parseDate(fraEl.getChild("adjustedTerminationDate"))); // payment date fraBuilder.paymentDate(document.parseAdjustableDate(fraEl.getChild("paymentDate"))); // fixing offset fraBuilder.fixingDateOffset(document.parseRelativeDateOffsetDays(fraEl.getChild("fixingDateOffset"))); // dateRelativeTo required to refer to adjustedEffectiveDate, so ignored here // day count fraBuilder.dayCount(document.parseDayCountFraction(fraEl.getChild("dayCountFraction"))); // notional CurrencyAmount notional = document.parseCurrencyAmount(fraEl.getChild("notional")); fraBuilder.currency(notional.Currency); fraBuilder.notional(notional.Amount); // fixed rate fraBuilder.fixedRate(document.parseDecimal(fraEl.getChild("fixedRate"))); // index IList <Index> indexes = document.parseIndexes(fraEl); switch (indexes.Count) { case 1: fraBuilder.index((IborIndex)indexes[0]); break; case 2: fraBuilder.index((IborIndex)indexes[0]); fraBuilder.indexInterpolated((IborIndex)indexes[1]); break; default: throw new FpmlParseException("Expected one or two indexes, but found " + indexes.Count); } // discounting fraBuilder.discounting(FraDiscountingMethod.of(fraEl.getChild("fraDiscounting").Content)); return(FraTrade.builder().info(tradeInfoBuilder.build()).product(fraBuilder.build()).build()); }