public ResolvedCapitalIndexedBondTrade resolve(ReferenceData refData)
        {
            ResolvedCapitalIndexedBond resolvedProduct = product.resolve(refData);
            LocalDate settlementDate = calculateSettlementDate(refData);

            double accruedInterest = resolvedProduct.accruedInterest(settlementDate) / product.Notional;

            if (settlementDate.isBefore(resolvedProduct.StartDate))
            {
                throw new System.ArgumentException("Settlement date must not be before bond starts");
            }
            BondPaymentPeriod settlePeriod;

            if (product.YieldConvention.Equals(CapitalIndexedBondYieldConvention.GB_IL_FLOAT))
            {
                settlePeriod = KnownAmountBondPaymentPeriod.of(Payment.of(product.Currency, -product.Notional * quantity * (price + accruedInterest), settlementDate), SchedulePeriod.of(resolvedProduct.StartDate, settlementDate, product.AccrualSchedule.StartDate, settlementDate));
            }
            else
            {
                RateComputation rateComputation = product.RateCalculation.createRateComputation(settlementDate);
                settlePeriod = CapitalIndexedBondPaymentPeriod.builder().startDate(resolvedProduct.StartDate).unadjustedStartDate(product.AccrualSchedule.StartDate).endDate(settlementDate).rateComputation(rateComputation).currency(product.Currency).notional(-product.Notional * quantity * (price + accruedInterest)).realCoupon(1d).build();
            }

            return(ResolvedCapitalIndexedBondTrade.builder().info(info).product(resolvedProduct).quantity(quantity).settlement(ResolvedCapitalIndexedBondSettlement.of(settlementDate, price, settlePeriod)).build());
        }
        //-------------------------------------------------------------------------
        public virtual void coverage()
        {
            CapitalIndexedBondPaymentPeriod test1 = CapitalIndexedBondPaymentPeriod.builder().currency(USD).notional(NOTIONAL).detachmentDate(DETACHMENT).startDate(START).endDate(END).unadjustedStartDate(START_UNADJ).unadjustedEndDate(END_UNADJ).rateComputation(COMPUTE_INTERP).realCoupon(REAL_COUPON).build();

            coverImmutableBean(test1);
            CapitalIndexedBondPaymentPeriod test2 = CapitalIndexedBondPaymentPeriod.builder().currency(GBP).notional(5.0e6).startDate(LocalDate.of(2008, 1, 15)).endDate(LocalDate.of(2008, 7, 15)).rateComputation(InflationEndMonthRateComputation.of(GB_RPI, 155.32, REF_END)).realCoupon(1d).build();

            coverBeanEquals(test1, test2);
        }
        public virtual void test_builder_fail()
        {
            // not inflation rate observation
            FixedRateComputation fixedRate = FixedRateComputation.of(0.01);

            assertThrowsIllegalArg(() => CapitalIndexedBondPaymentPeriod.builder().currency(USD).notional(NOTIONAL).detachmentDate(DETACHMENT).startDate(START).endDate(END).unadjustedStartDate(START_UNADJ).unadjustedEndDate(END_UNADJ).rateComputation(fixedRate).realCoupon(REAL_COUPON).build());
            // wrong start date and end date
            assertThrowsIllegalArg(() => CapitalIndexedBondPaymentPeriod.builder().currency(USD).notional(NOTIONAL).detachmentDate(DETACHMENT).startDate(END.plusDays(1)).endDate(END).unadjustedStartDate(START_UNADJ).unadjustedEndDate(END_UNADJ).rateComputation(COMPUTE_INTERP).realCoupon(REAL_COUPON).build());
            // wrong unadjusted start date and unadjusted end date
            assertThrowsIllegalArg(() => CapitalIndexedBondPaymentPeriod.builder().currency(USD).notional(NOTIONAL).detachmentDate(DETACHMENT).startDate(START).endDate(END).unadjustedStartDate(START_UNADJ).unadjustedEndDate(START_UNADJ.minusWeeks(1)).rateComputation(COMPUTE_INTERP).realCoupon(REAL_COUPON).build());
        }
 static ResolvedCapitalIndexedBondTest()
 {
     LocalDate[] unAdjDates = new LocalDate[] { LocalDate.of(2008, 1, 13), LocalDate.of(2008, 7, 13), LocalDate.of(2009, 1, 13), LocalDate.of(2009, 7, 13), LocalDate.of(2010, 1, 13) };
     for (int i = 0; i < 4; ++i)
     {
         LocalDate       start           = SCHEDULE_ADJ.adjust(unAdjDates[i], REF_DATA);
         LocalDate       end             = SCHEDULE_ADJ.adjust(unAdjDates[i + 1], REF_DATA);
         RateComputation rateComputation = RATE_CALC.createRateComputation(end);
         PERIODIC[i] = CapitalIndexedBondPaymentPeriod.builder().currency(USD).startDate(start).endDate(end).unadjustedStartDate(unAdjDates[i]).unadjustedEndDate(unAdjDates[i + 1]).detachmentDate(end).realCoupon(COUPON).rateComputation(rateComputation).notional(NOTIONAL).build();
     }
 }
        public virtual void test_builder_min()
        {
            CapitalIndexedBondPaymentPeriod test = CapitalIndexedBondPaymentPeriod.builder().currency(USD).notional(NOTIONAL).startDate(START).endDate(END).rateComputation(COMPUTE_MONTH).realCoupon(REAL_COUPON).build();

            assertEquals(test.Currency, USD);
            assertEquals(test.Notional, NOTIONAL);
            assertEquals(test.DetachmentDate, END);
            assertEquals(test.StartDate, START);
            assertEquals(test.EndDate, END);
            assertEquals(test.UnadjustedStartDate, START);
            assertEquals(test.UnadjustedEndDate, END);
            assertEquals(test.RateComputation, COMPUTE_MONTH);
            assertEquals(test.RealCoupon, REAL_COUPON);
        }
        public virtual void test_methods()
        {
            CapitalIndexedBondPaymentPeriod test = CapitalIndexedBondPaymentPeriod.builder().currency(USD).notional(NOTIONAL).detachmentDate(DETACHMENT).startDate(START).endDate(END).unadjustedStartDate(START_UNADJ).unadjustedEndDate(END_UNADJ).rateComputation(COMPUTE_INTERP).realCoupon(REAL_COUPON).build();

            assertEquals(test.PaymentDate, END);
            assertEquals(test.adjustPaymentDate(TemporalAdjusters.ofDateAdjuster(d => d.plusDays(2))), test);
            ImmutableSet.Builder <Index> builder = ImmutableSet.builder();
            test.collectIndices(builder);
            ImmutableSet <Index> set = builder.build();

            assertEquals(set.size(), 1);
            assertEquals(set.asList().get(0), US_CPI_U);

            LocalDate bondStart      = LocalDate.of(2003, 1, 13);
            LocalDate bondStartUnadj = LocalDate.of(2003, 1, 12);
            CapitalIndexedBondPaymentPeriod expected = CapitalIndexedBondPaymentPeriod.builder().currency(USD).notional(NOTIONAL).detachmentDate(END).startDate(bondStart).endDate(END).unadjustedStartDate(bondStartUnadj).unadjustedEndDate(END_UNADJ).rateComputation(COMPUTE_INTERP).realCoupon(1d).build();

            assertEquals(test.withUnitCoupon(bondStart, bondStartUnadj), expected);
        }
        public virtual void test_resolve()
        {
            CapitalIndexedBond @base = sut();

            LocalDate[] unAdjDates = new LocalDate[] { LocalDate.of(2008, 1, 13), LocalDate.of(2008, 7, 13), LocalDate.of(2009, 1, 13), LocalDate.of(2009, 7, 13), LocalDate.of(2010, 1, 13) };
            CapitalIndexedBondPaymentPeriod[] periodic = new CapitalIndexedBondPaymentPeriod[4];
            for (int i = 0; i < 4; ++i)
            {
                LocalDate       start      = SCHEDULE_ADJ.adjust(unAdjDates[i], REF_DATA);
                LocalDate       end        = SCHEDULE_ADJ.adjust(unAdjDates[i + 1], REF_DATA);
                LocalDate       detachment = EX_COUPON.adjust(end, REF_DATA);
                RateComputation comp       = RATE_CALC.createRateComputation(end);
                periodic[i] = CapitalIndexedBondPaymentPeriod.builder().currency(USD).startDate(start).endDate(end).unadjustedStartDate(unAdjDates[i]).unadjustedEndDate(unAdjDates[i + 1]).detachmentDate(detachment).realCoupon(COUPONS[i]).rateComputation(comp).notional(NOTIONAL).build();
            }
            CapitalIndexedBondPaymentPeriod nominalExp = periodic[3].withUnitCoupon(periodic[0].StartDate, periodic[0].UnadjustedStartDate);
            ResolvedCapitalIndexedBond      expected   = ResolvedCapitalIndexedBond.builder().securityId(SECURITY_ID).dayCount(ACT_ACT_ISDA).legalEntityId(LEGAL_ENTITY).nominalPayment(nominalExp).periodicPayments(periodic).frequency(SCHEDULE.Frequency).rollConvention(SCHEDULE.calculatedRollConvention()).settlementDateOffset(SETTLE_OFFSET).yieldConvention(US_IL_REAL).rateCalculation(@base.RateCalculation).build();

            assertEquals(@base.resolve(REF_DATA), expected);
        }
        public virtual void test_serialization()
        {
            CapitalIndexedBondPaymentPeriod test = CapitalIndexedBondPaymentPeriod.builder().currency(USD).notional(NOTIONAL).detachmentDate(DETACHMENT).startDate(START).endDate(END).unadjustedStartDate(START_UNADJ).unadjustedEndDate(END_UNADJ).rateComputation(COMPUTE_INTERP).realCoupon(REAL_COUPON).build();

            assertSerialization(test);
        }
        public virtual void test_builder_fail()
        {
            CapitalIndexedBondPaymentPeriod period = CapitalIndexedBondPaymentPeriod.builder().startDate(PERIODIC[2].StartDate).endDate(PERIODIC[2].EndDate).currency(GBP).notional(NOTIONAL).rateComputation(PERIODIC[2].RateComputation).realCoupon(COUPON).build();

            assertThrowsIllegalArg(() => ResolvedCapitalIndexedBond.builder().dayCount(ACT_ACT_ISDA).legalEntityId(LEGAL_ENTITY).nominalPayment(NOMINAL).periodicPayments(PERIODIC[0], PERIODIC[1], period, PERIODIC[3]).settlementDateOffset(SETTLE_OFFSET).yieldConvention(US_IL_REAL).build());
        }