/** * Calculates the effective date from the fixing date. * <p> * The fixing date is the date on which the index is to be observed. * The effective date is the date on which the implied deposit starts. * <p> * No error is thrown if the input date is not a valid fixing date. * Instead, the fixing date is moved to the next valid fixing date and then processed. * * @param fixingDate the fixing date * @return the effective date */ public default LocalDate calculateEffectiveFromFixing(LocalDate fixingDate) { return getFixingCalendar().shift(getFixingCalendar().nextOrSame(fixingDate), getIndex().getEffectiveDateOffset()); }
/** * Creates an observation object for the specified fixing date. * * @param fixingDate the fixing date * @return the index observation */ public default OvernightIndexObservation observeOn(LocalDate fixingDate) { LocalDate publicationDate = calculatePublicationFromFixing(fixingDate); LocalDate effectiveDate = calculateEffectiveFromFixing(fixingDate); LocalDate maturityDate = calculateMaturityFromEffective(effectiveDate); return OvernightIndexObservation.builder() .index(getIndex()) .fixingDate(fixingDate) .publicationDate(publicationDate) .effectiveDate(effectiveDate) .maturityDate(maturityDate) .yearFraction(getIndex().getDayCount().yearFraction(effectiveDate, maturityDate)) .build(); }
private RateComputation createRateComputation(SchedulePeriod period, Schedule paymentSchedule, ReferenceData refData) { int effectiveRateCutOffDaysOffset = (isLastAccrualInPaymentPeriod(period, paymentSchedule) ? rateCutOffDays : 0); return OvernightRateComputation.of( index, period.getStartDate(), period.getEndDate(), effectiveRateCutOffDaysOffset, accrualMethod, refData); }
/** * Calculates the price of the Overnight rate future product. * <p> * The price of the product is the price on the valuation date. * * @param future the future * @param ratesProvider the rates provider * @return the price of the product, in decimal form */ public double price(ResolvedOvernightFuture future, RatesProvider ratesProvider) { double forwardRate = rateComputationFn.rate( future.getOvernightRate(), future.getOvernightRate().getStartDate(), future.getOvernightRate().getEndDate(), ratesProvider); return 1d - forwardRate; }
/** * Gets the Overnight index that the future is based on. * * @return the Overnight index */ public OvernightIndex getIndex() { return overnightRate.getIndex(); }
/** * Calculates the maturity date from the effective date. * <p> * The effective date is the date on which the implied deposit starts. * The maturity date is the date on which the implied deposit ends. * <p> * No error is thrown if the input date is not a valid effective date. * Instead, the effective date is moved to the next valid effective date and then processed. * * @param effectiveDate the effective date * @return the maturity date */ public default LocalDate calculateMaturityFromEffective(LocalDate effectiveDate) { return getFixingCalendar().shift(getFixingCalendar().nextOrSame(effectiveDate), 1); }
@Override public ResolvedOvernightFuture resolve(ReferenceData refData) { OvernightRateComputation overnightAveragedRate = OvernightRateComputation.of( index, startDate, endDate, 0, accrualMethod, refData); return ResolvedOvernightFuture.builder() .securityId(securityId) .accrualFactor(accrualFactor) .currency(currency) .notional(notional) .lastTradeDate(lastTradeDate) .overnightRate(overnightAveragedRate) .rounding(rounding) .build(); }
/** * Calculates the price sensitivity of the Overnight rate future product. * <p> * The price sensitivity of the product is the sensitivity of the price to the underlying curves. * * @param future the future * @param ratesProvider the rates provider * @return the price curve sensitivity of the product */ public PointSensitivities priceSensitivity(ResolvedOvernightFuture future, RatesProvider ratesProvider) { PointSensitivityBuilder forwardRateSensitivity = rateComputationFn.rateSensitivity( future.getOvernightRate(), future.getOvernightRate().getStartDate(), future.getOvernightRate().getEndDate(), ratesProvider); // The sensitivity should be to no currency or currency XXX. To avoid useless conversion, the dimension-less // price sensitivity is reported in the future currency. return forwardRateSensitivity.build().multipliedBy(-1d); }
@Override public default void collectIndices(ImmutableSet.Builder<Index> builder) { builder.add(getIndex()); }
public void test_resolve() { OvernightFuture base = sut(); ResolvedOvernightFuture expected = ResolvedOvernightFuture.builder() .securityId(SECURITY_ID) .currency(USD) .notional(NOTIONAL) .accrualFactor(ACCRUAL_FACTOR) .overnightRate(OvernightRateComputation.of( USD_FED_FUND, START_DATE, END_DATE, 0, OvernightAccrualMethod.AVERAGED_DAILY, REF_DATA)) .lastTradeDate(LAST_TRADE_DATE) .rounding(ROUNDING) .build(); assertEquals(base.resolve(REF_DATA), expected); }
/** * Calculates the publication date from the fixing date. * <p> * The fixing date is the date on which the index is to be observed. * The publication date is the date on which the fixed rate is actually published. * <p> * No error is thrown if the input date is not a valid fixing date. * Instead, the fixing date is moved to the next valid fixing date and then processed. * * @param fixingDate the fixing date * @return the publication date */ public default LocalDate calculatePublicationFromFixing(LocalDate fixingDate) { return getFixingCalendar().shift(getFixingCalendar().nextOrSame(fixingDate), getIndex().getPublicationDateOffset()); }
@ImmutablePreBuild private static void preBuild(Builder builder) { if (builder.overnightRate != null) { if (builder.currency == null) { builder.currency = builder.overnightRate.getIndex().getCurrency(); } } }
public void coverage() { ResolvedOvernightFuture test1 = ResolvedOvernightFuture.builder() .currency(USD) .accrualFactor(ACCRUAL_FACTOR_1M) .lastTradeDate(LAST_TRADE_DATE) .overnightRate(RATE_COMPUTATION) .notional(NOTIONAL) .rounding(ROUNDING) .securityId(SECURITY_ID) .build(); coverImmutableBean(test1); ResolvedOvernightFuture test2 = ResolvedOvernightFuture.builder() .currency(GBP) .accrualFactor(0.25) .lastTradeDate(date(2018, 9, 28)) .overnightRate(OvernightRateComputation.of( GBP_SONIA, date(2018, 9, 1), date(2018, 9, 30), 0, OvernightAccrualMethod.AVERAGED_DAILY, REF_DATA)) .notional(1.0e8) .securityId(SecurityId.of("OG-Test", "OnFuture2")) .build(); coverBeanEquals(test1, test2); }
/** * Calculates the maturity date from the fixing date. * <p> * The fixing date is the date on which the index is to be observed. * The maturity date is the date on which the implied deposit ends. * <p> * No error is thrown if the input date is not a valid fixing date. * Instead, the fixing date is moved to the next valid fixing date and then processed. * * @param fixingDate the fixing date * @return the maturity date */ public default LocalDate calculateMaturityFromFixing(LocalDate fixingDate) { return getFixingCalendar().shift(getFixingCalendar().nextOrSame(fixingDate), getIndex().getEffectiveDateOffset() + 1); }
/** * Calculates the fixing date from the effective date. * <p> * The fixing date is the date on which the index is to be observed. * The effective date is the date on which the implied deposit starts. * <p> * No error is thrown if the input date is not a valid effective date. * Instead, the effective date is moved to the next valid effective date and then processed. * * @param effectiveDate the effective date * @return the fixing date */ public default LocalDate calculateFixingFromEffective(LocalDate effectiveDate) { return getFixingCalendar().shift(getFixingCalendar().nextOrSame(effectiveDate), -getIndex().getEffectiveDateOffset()); }