//-------------------------------------------------------------------------
        /// <summary>
        /// Converts an FpML 'RelativeDateOffset' to a {@code DaysAdjustment}.
        /// </summary>
        /// <param name="baseEl">  the FpML adjustable date element </param>
        /// <returns> the days adjustment </returns>
        /// <exception cref="RuntimeException"> if unable to parse </exception>
        public DaysAdjustment parseRelativeDateOffsetDays(XmlElement baseEl)
        {
            // FpML content: ('periodMultiplier', 'period', 'dayType?',
            //                'businessDayConvention', 'BusinessCentersOrReference.model?'
            //                'dateRelativeTo', 'adjustedDate')
            // The 'dateRelativeTo' element is not used here
            // The 'adjustedDate' element is ignored
            Period period = parsePeriod(baseEl);

            if (period.toTotalMonths() != 0)
            {
                throw new FpmlParseException("Expected days-based period but found " + period);
            }
            Optional <XmlElement> dayTypeEl = baseEl.findChild("dayType");
            bool calendarDays = period.Zero || (dayTypeEl.Present && dayTypeEl.get().Content.Equals("Calendar"));
            BusinessDayConvention fixingBdc = convertBusinessDayConvention(baseEl.getChild("businessDayConvention").Content);
            HolidayCalendarId     calendar  = parseBusinessCenters(baseEl);

            if (calendarDays)
            {
                return(DaysAdjustment.ofCalendarDays(period.Days, BusinessDayAdjustment.of(fixingBdc, calendar)));
            }
            else
            {
                return(DaysAdjustment.ofBusinessDays(period.Days, calendar));
            }
        }
        public override DaysAdjustment toIborIndexFixingOffset()
        {
            DaysAdjustment @base = FloatingRateName.this.toIborIndexFixingOffset();

            if (fixingDateOffsetDays == null)
            {
                return(@base);
            }
            if (fixingDateOffsetDays == 0)
            {
                return(DaysAdjustment.ofCalendarDays(0, BusinessDayAdjustment.of(PRECEDING, @base.ResultCalendar)));
            }
            return(@base.toBuilder().days(fixingDateOffsetDays.Value).build().normalized());
        }
Ejemplo n.º 3
0
        // parses the payment schedule
        private PaymentSchedule parseSwapPaymentSchedule(XmlElement legEl, XmlElement calcEl, FpmlDocument document)
        {
            // supported elements:
            //  'paymentDates/paymentFrequency'
            //  'paymentDates/payRelativeTo'
            //  'paymentDates/paymentDaysOffset?'
            //  'paymentDates/paymentDatesAdjustments'
            //  'calculationPeriodAmount/calculation/compoundingMethod'
            //  'paymentDates/firstPaymentDate?'
            //  'paymentDates/lastRegularPaymentDate?'
            // ignored elements:
            //  'paymentDates/calculationPeriodDatesReference'
            //  'paymentDates/resetDatesReference'
            //  'paymentDates/valuationDatesReference'
            PaymentSchedule.Builder paymentScheduleBuilder = PaymentSchedule.builder();
            // payment dates
            XmlElement paymentDatesEl = legEl.getChild("paymentDates");

            // frequency
            paymentScheduleBuilder.paymentFrequency(document.parseFrequency(paymentDatesEl.getChild("paymentFrequency")));
            //default for IRS is pay relative to period end; Strata model will apply the defaulting but the values is needed
            //here for first and last payment date checks
            PaymentRelativeTo payRelativeTo = paymentDatesEl.findChild("payRelativeTo").map(el => parsePayRelativeTo(el)).orElse(PaymentRelativeTo.PERIOD_END);

            paymentScheduleBuilder.paymentRelativeTo(payRelativeTo);
            // dates
            if (payRelativeTo == PaymentRelativeTo.PERIOD_END)
            {
                // ignore data if not PeriodEnd and hope schedule is worked out correctly by other means
                // this provides compatibility for old code that ignored these FpML fields
                paymentDatesEl.findChild("firstPaymentDate").map(el => document.parseDate(el)).ifPresent(date => paymentScheduleBuilder.firstRegularStartDate(date));
                paymentDatesEl.findChild("lastRegularPaymentDate").map(el => document.parseDate(el)).ifPresent(date => paymentScheduleBuilder.lastRegularEndDate(date));
            }
            // offset
            Optional <XmlElement> paymentOffsetEl = paymentDatesEl.findChild("paymentDaysOffset");
            BusinessDayAdjustment payAdjustment   = document.parseBusinessDayAdjustments(paymentDatesEl.getChild("paymentDatesAdjustments"));

            if (paymentOffsetEl.Present)
            {
                Period period = document.parsePeriod(paymentOffsetEl.get());
                if (period.toTotalMonths() != 0)
                {
                    throw new FpmlParseException("Invalid 'paymentDatesAdjustments' value, expected days-based period: " + period);
                }
                Optional <XmlElement> dayTypeEl = paymentOffsetEl.get().findChild("dayType");
                bool fixingCalendarDays         = period.Zero || (dayTypeEl.Present && dayTypeEl.get().Content.Equals("Calendar"));
                if (fixingCalendarDays)
                {
                    paymentScheduleBuilder.paymentDateOffset(DaysAdjustment.ofCalendarDays(period.Days, payAdjustment));
                }
                else
                {
                    paymentScheduleBuilder.paymentDateOffset(DaysAdjustment.ofBusinessDays(period.Days, payAdjustment.Calendar));
                }
            }
            else
            {
                paymentScheduleBuilder.paymentDateOffset(DaysAdjustment.ofCalendarDays(0, payAdjustment));
            }
            // compounding
            calcEl.findChild("compoundingMethod").ifPresent(compoundingEl =>
            {
                paymentScheduleBuilder.compoundingMethod(CompoundingMethod.of(compoundingEl.Content));
            });
            return(paymentScheduleBuilder.build());
        }
 public virtual void test_builder_fail()
 {
     // negative settlement date offset
     assertThrowsIllegalArg(() => CapitalIndexedBond.builder().securityId(SECURITY_ID).notional(NOTIONAL).currency(USD).dayCount(ACT_ACT_ISDA).rateCalculation(RATE_CALC).exCouponPeriod(EX_COUPON).legalEntityId(LEGAL_ENTITY).yieldConvention(US_IL_REAL).settlementDateOffset(DaysAdjustment.ofBusinessDays(-2, USNY)).accrualSchedule(SCHEDULE).build());
     // positive ex-coupon days
     assertThrowsIllegalArg(() => CapitalIndexedBond.builder().securityId(SECURITY_ID).notional(NOTIONAL).currency(USD).dayCount(ACT_ACT_ISDA).rateCalculation(RATE_CALC).exCouponPeriod(DaysAdjustment.ofCalendarDays(7, BusinessDayAdjustment.of(BusinessDayConventions.FOLLOWING, USNY))).legalEntityId(LEGAL_ENTITY).yieldConvention(US_IL_REAL).settlementDateOffset(SETTLE_OFFSET).accrualSchedule(SCHEDULE).build());
 }
        static IsdaCompliantCreditCurveCalibratorBase()
        {
            ImmutableList.Builder <IsdaCreditCurveNode> dscNodeBuilder = ImmutableList.builder();
            for (int i = 0; i < NUM_MM; i++)
            {
                Tenor tenor = Tenor.ofMonths(MM_MONTHS[i]);
                dscNodeBuilder.add(DepositIsdaCreditCurveNode.of(QuoteId.of(StandardId.of("OG", ID_VALUES[i])), ADJ_3D, BUS_ADJ, tenor, ACT_360));
            }
            for (int i = NUM_MM; i < NUM_INSTRUMENTS; i++)
            {
                Tenor tenor = Tenor.ofYears(SWAP_YEARS[i - NUM_MM]);
                dscNodeBuilder.add(SwapIsdaCreditCurveNode.of(QuoteId.of(StandardId.of("OG", ID_VALUES[i])), ADJ_3D, BUS_ADJ, tenor, THIRTY_U_360, Frequency.P12M));
            }
            DSC_NODES       = dscNodeBuilder.build();
            EXP_NODE_CDS    = new ResolvedCdsTrade[NUM_TESTS][];
            NODE_CDS        = new CdsIsdaCreditCurveNode[NUM_TESTS][];
            CDS_MARKET_DATA = new ImmutableMarketData[NUM_TESTS];
            SPREADS         = new double[NUM_TESTS][];
            YIELD_CURVES    = new ImmutableCreditRatesProvider[NUM_TESTS];
            // case0
            LocalDate tradeDate0 = LocalDate.of(2011, 6, 19);
            LocalDate startDate0 = LocalDate.of(2011, 3, 21);

            YIELD_CURVES[0] = createRatesProvider(tradeDate0, tradeDate0, 1d, 0.4);
            Period[] tenors  = new Period[] { Period.ofMonths(6), Period.ofYears(1), Period.ofYears(3), Period.ofYears(5), Period.ofYears(7), Period.ofYears(10) };
            int      nTenors = tenors.Length;

            EXP_NODE_CDS[0] = new ResolvedCdsTrade[nTenors];
            NODE_CDS[0]     = new CdsIsdaCreditCurveNode[nTenors];
            ImmutableMarketDataBuilder builderCredit0 = ImmutableMarketData.builder(tradeDate0);

            SPREADS[0] = new double[] { 0.00886315689995649, 0.00886315689995649, 0.0133044689825873, 0.0171490070952563, 0.0183903639181293, 0.0194721890639724 };
            for (int i = 0; i < nTenors; ++i)
            {
                Cds product = Cds.of(BUY, LEGAL_ENTITY, EUR, 1d, startDate0, LocalDate.of(2011, 6, 20).plus(tenors[i]), Frequency.P3M, DEFAULT_CALENDAR, SPREADS[0][i]);
                EXP_NODE_CDS[0][i] = CdsTrade.builder().info(TradeInfo.builder().settlementDate(product.SettlementDateOffset.adjust(tradeDate0, REF_DATA)).build()).product(product).build().resolve(REF_DATA);
                CdsConvention conv = ImmutableCdsConvention.of("conv", EUR, ACT_360, Frequency.P3M, BUS_ADJ, CDS_SETTLE_STD);
                CdsTemplate   temp = DatesCdsTemplate.of(startDate0, LocalDate.of(2011, 6, 20).plus(tenors[i]), conv);
                QuoteId       id   = QuoteId.of(StandardId.of("OG", tenors[i].ToString()));
                NODE_CDS[0][i] = CdsIsdaCreditCurveNode.ofParSpread(temp, id, LEGAL_ENTITY);
                builderCredit0.addValue(id, SPREADS[0][i]);
            }
            CDS_MARKET_DATA[0] = builderCredit0.build();
            // case1
            LocalDate tradeDate1 = LocalDate.of(2011, 3, 21);
            LocalDate snapDate1  = LocalDate.of(2011, 3, 18);
            LocalDate effDate1   = LocalDate.of(2011, 3, 20);   //note this is a Sunday - for a standard CDS this would roll to the Monday.

            YIELD_CURVES[1] = createRatesProvider(tradeDate1, snapDate1, 1d, 0.4);
            tenors          = new Period[] { Period.ofMonths(6), Period.ofYears(1), Period.ofYears(3), Period.ofYears(5), Period.ofYears(7), Period.ofYears(10) };
            nTenors         = tenors.Length;
            NODE_CDS[1]     = new CdsIsdaCreditCurveNode[nTenors];
            ImmutableMarketDataBuilder builderCredit1 = ImmutableMarketData.builder(tradeDate1);

            EXP_NODE_CDS[1] = new ResolvedCdsTrade[nTenors];
            SPREADS[1]      = new double[] { 0.027, 0.018, 0.012, 0.009, 0.007, 0.006 };
            for (int i = 0; i < nTenors; ++i)
            {
                Cds product = Cds.of(BUY, LEGAL_ENTITY, EUR, 1d, effDate1, LocalDate.of(2011, 6, 20).plus(tenors[i]), P3M, DEFAULT_CALENDAR, SPREADS[1][i]);
                EXP_NODE_CDS[1][i] = CdsTrade.builder().info(TradeInfo.builder().settlementDate(product.SettlementDateOffset.adjust(tradeDate1, REF_DATA)).build()).product(product).build().resolve(REF_DATA);
                CdsConvention conv = ImmutableCdsConvention.builder().name("conv").currency(EUR).dayCount(ACT_360).paymentFrequency(P3M).startDateBusinessDayAdjustment(BusinessDayAdjustment.NONE).businessDayAdjustment(BUS_ADJ).settlementDateOffset(CDS_SETTLE_STD).build();
                CdsTemplate   temp = DatesCdsTemplate.of(effDate1, LocalDate.of(2011, 6, 20).plus(tenors[i]), conv);
                QuoteId       id   = QuoteId.of(StandardId.of("OG", tenors[i].ToString()));
                NODE_CDS[1][i] = CdsIsdaCreditCurveNode.ofParSpread(temp, id, LEGAL_ENTITY);
                builderCredit1.addValue(id, SPREADS[1][i]);
            }
            CDS_MARKET_DATA[1] = builderCredit1.build();
            // case2
            LocalDate tradeDate2 = LocalDate.of(2011, 5, 30);
            LocalDate snapDate2  = LocalDate.of(2011, 5, 29);

            YIELD_CURVES[2] = createRatesProvider(tradeDate2, snapDate2, 1d, 0.25);
            LocalDate[] matDates2  = new LocalDate[] { LocalDate.of(2011, 6, 20), LocalDate.of(2012, 5, 30), LocalDate.of(2014, 6, 20), LocalDate.of(2016, 6, 20), LocalDate.of(2018, 6, 20) };
            int         nMatDates2 = matDates2.Length;

            NODE_CDS[2] = new CdsIsdaCreditCurveNode[nMatDates2];
            ImmutableMarketDataBuilder builderCredit2 = ImmutableMarketData.builder(tradeDate2);

            EXP_NODE_CDS[2] = new ResolvedCdsTrade[nMatDates2];
            SPREADS[2]      = new double[] { 0.05, 0.05, 0.05, 0.05, 0.05 };
            for (int i = 0; i < nMatDates2; ++i)
            {
                Cds product = Cds.of(BUY, LEGAL_ENTITY, EUR, 1d, tradeDate2.plusDays(1), matDates2[i], P3M, DEFAULT_CALENDAR, SPREADS[2][i]).toBuilder().dayCount(THIRTY_U_360).build();
                EXP_NODE_CDS[2][i] = CdsTrade.builder().info(TradeInfo.builder().settlementDate(product.SettlementDateOffset.adjust(tradeDate2, REF_DATA)).build()).product(product).build().resolve(REF_DATA);
                CdsConvention conv = ImmutableCdsConvention.builder().name("conv").currency(EUR).dayCount(THIRTY_U_360).paymentFrequency(P3M).rollConvention(RollConventions.NONE).businessDayAdjustment(BUS_ADJ).settlementDateOffset(CDS_SETTLE_STD).build();
                CdsTemplate   temp = DatesCdsTemplate.of(tradeDate2.plusDays(1), matDates2[i], conv);
                QuoteId       id   = QuoteId.of(StandardId.of("OG", matDates2[i].ToString()));
                NODE_CDS[2][i] = CdsIsdaCreditCurveNode.ofParSpread(temp, id, LEGAL_ENTITY);
                builderCredit2.addValue(id, SPREADS[2][i]);
            }
            CDS_MARKET_DATA[2] = builderCredit2.build();
            // case3
            LocalDate tradeDate3 = LocalDate.of(2011, 5, 30);
            LocalDate snapDate3  = LocalDate.of(2011, 5, 29);
            LocalDate effDate3   = LocalDate.of(2011, 7, 31);

            YIELD_CURVES[3] = createRatesProvider(tradeDate3, snapDate3, 1d, 0.25);
            LocalDate[] matDates3  = new LocalDate[] { LocalDate.of(2011, 11, 30), LocalDate.of(2012, 5, 30), LocalDate.of(2014, 5, 30), LocalDate.of(2016, 5, 30), LocalDate.of(2018, 5, 30), LocalDate.of(2021, 5, 30) };
            int         nMatDates3 = matDates3.Length;

            NODE_CDS[3] = new CdsIsdaCreditCurveNode[nMatDates3];
            ImmutableMarketDataBuilder builderCredit3 = ImmutableMarketData.builder(tradeDate3);

            EXP_NODE_CDS[3] = new ResolvedCdsTrade[nMatDates3];
            SPREADS[3]      = new double[] { 0.07, 0.06, 0.05, 0.055, 0.06, 0.065 };
            for (int i = 0; i < nMatDates3; ++i)
            {
                Cds product = Cds.builder().buySell(BUY).legalEntityId(LEGAL_ENTITY).currency(EUR).dayCount(ACT_365F).fixedRate(SPREADS[3][i]).notional(1d).paymentSchedule(PeriodicSchedule.builder().businessDayAdjustment(BusinessDayAdjustment.of(FOLLOWING, DEFAULT_CALENDAR)).startDate(effDate3).endDate(matDates3[i]).startDateBusinessDayAdjustment(BusinessDayAdjustment.NONE).endDateBusinessDayAdjustment(BusinessDayAdjustment.NONE).frequency(Frequency.P6M).rollConvention(RollConventions.NONE).stubConvention(StubConvention.LONG_INITIAL).build()).paymentOnDefault(PaymentOnDefault.ACCRUED_PREMIUM).protectionStart(ProtectionStartOfDay.BEGINNING).stepinDateOffset(DaysAdjustment.ofCalendarDays(1)).settlementDateOffset(CDS_SETTLE_STD).build();
                EXP_NODE_CDS[3][i] = CdsTrade.builder().info(TradeInfo.builder().settlementDate(product.SettlementDateOffset.adjust(tradeDate3, REF_DATA)).build()).product(product).build().resolve(REF_DATA);
                CdsConvention conv = ImmutableCdsConvention.builder().name("conv").currency(EUR).dayCount(ACT_365F).paymentFrequency(Frequency.P6M).rollConvention(RollConventions.NONE).stubConvention(StubConvention.LONG_INITIAL).startDateBusinessDayAdjustment(BusinessDayAdjustment.NONE).businessDayAdjustment(BusinessDayAdjustment.of(FOLLOWING, DEFAULT_CALENDAR)).settlementDateOffset(CDS_SETTLE_STD).build();
                CdsTemplate   temp = DatesCdsTemplate.of(effDate3, matDates3[i], conv);
                QuoteId       id   = QuoteId.of(StandardId.of("OG", matDates3[i].ToString()));
                NODE_CDS[3][i] = CdsIsdaCreditCurveNode.ofParSpread(temp, id, LEGAL_ENTITY);
                builderCredit3.addValue(id, SPREADS[3][i]);
            }
            CDS_MARKET_DATA[3] = builderCredit3.build();
            // case4: designed to trip the low rates/low spreads branch
            LocalDate tradeDate4 = LocalDate.of(2014, 1, 14);
            LocalDate snapDate4  = LocalDate.of(2014, 1, 13);

            YIELD_CURVES[4] = createRatesProvider(tradeDate4, snapDate4, 1d / 1000d, 0.4);
            int nSpreads4 = 6;

            NODE_CDS[4] = new CdsIsdaCreditCurveNode[nSpreads4];
            ImmutableMarketDataBuilder builderCredit4 = ImmutableMarketData.builder(tradeDate4);

            SPREADS[4] = new double[nSpreads4];
            Arrays.fill(SPREADS[4], 1.0e-4);
            EXP_NODE_CDS[4] = new ResolvedCdsTrade[nSpreads4];
            for (int i = 0; i < nSpreads4; ++i)
            {
                Cds product = Cds.of(BUY, LEGAL_ENTITY, EUR, 1d, LocalDate.of(2013, 12, 20), LocalDate.of(2014, 3, 20).plus(tenors[i]), P3M, DEFAULT_CALENDAR, SPREADS[4][i]);
                EXP_NODE_CDS[4][i] = CdsTrade.builder().info(TradeInfo.builder().settlementDate(product.SettlementDateOffset.adjust(tradeDate4, REF_DATA)).build()).product(product).build().resolve(REF_DATA);
                CdsConvention conv = ImmutableCdsConvention.of("conv", EUR, ACT_360, P3M, BUS_ADJ, CDS_SETTLE_STD);
                CdsTemplate   temp = DatesCdsTemplate.of(LocalDate.of(2013, 12, 20), LocalDate.of(2014, 3, 20).plus(tenors[i]), conv);
                QuoteId       id   = QuoteId.of(StandardId.of("OG", tenors[i].ToString()));
                NODE_CDS[4][i] = CdsIsdaCreditCurveNode.ofParSpread(temp, id, LEGAL_ENTITY);
                builderCredit4.addValue(id, SPREADS[4][i]);
            }
            CDS_MARKET_DATA[4] = builderCredit4.build();
        }