/**
* Copyright (C) 2016 - present by OpenGamma Inc. and the OpenGamma group of companies
*
* Please see distribution for license.
*/
package com.opengamma.strata.pricer.capfloor;
import static com.opengamma.strata.basics.currency.Currency.EUR;
import static com.opengamma.strata.basics.date.DayCounts.ACT_360;
import static com.opengamma.strata.basics.date.HolidayCalendarIds.EUTA;
import java.time.LocalDate;
import com.opengamma.strata.basics.ReferenceData;
import com.opengamma.strata.basics.currency.CurrencyAmount;
import com.opengamma.strata.basics.date.BusinessDayAdjustment;
import com.opengamma.strata.basics.date.BusinessDayConventions;
import com.opengamma.strata.basics.date.DaysAdjustment;
import com.opengamma.strata.basics.index.IborIndex;
import com.opengamma.strata.basics.schedule.Frequency;
import com.opengamma.strata.basics.schedule.PeriodicSchedule;
import com.opengamma.strata.basics.schedule.RollConventions;
import com.opengamma.strata.basics.schedule.StubConvention;
import com.opengamma.strata.basics.value.ValueSchedule;
import com.opengamma.strata.product.capfloor.IborCapFloorLeg;
import com.opengamma.strata.product.capfloor.ResolvedIborCapFloorLeg;
import com.opengamma.strata.product.common.PayReceive;
import com.opengamma.strata.product.common.PutCall;
import com.opengamma.strata.product.swap.FixedRateCalculation;
import com.opengamma.strata.product.swap.IborRateCalculation;
import com.opengamma.strata.product.swap.NotionalSchedule;
import com.opengamma.strata.product.swap.PaymentSchedule;
import com.opengamma.strata.product.swap.RateCalculationSwapLeg;
import com.opengamma.strata.product.swap.ResolvedSwapLeg;
import com.opengamma.strata.product.swap.SwapLeg;
/**
* Data set of Ibor cap/floor securities.
*/
public class IborCapFloorDataSet {
private static final ReferenceData REF_DATA = ReferenceData.standard();
private static final BusinessDayAdjustment BUSINESS_ADJ = BusinessDayAdjustment.of(
BusinessDayConventions.MODIFIED_FOLLOWING, EUTA);
//-------------------------------------------------------------------------
/**
* Creates an Ibor cap/floor leg.
* <p>
* The Ibor index should be {@code EUR_EURIBOR_3M} or {@code EUR_EURIBOR_6M} to match the availability of the curve
* data in {@link IborCapletFloorletDataSet}.
*
* @param index the index
* @param startDate the start date
* @param endDate the end date
* @param strikeSchedule the strike
* @param notionalSchedule the notional
* @param putCall cap or floor
* @param payRec pay or receive
* @return the instance
*/
public static ResolvedIborCapFloorLeg createCapFloorLeg(
IborIndex index,
LocalDate startDate,
LocalDate endDate,
ValueSchedule strikeSchedule,
ValueSchedule notionalSchedule,
PutCall putCall,
PayReceive payRec) {
IborCapFloorLeg leg =
createCapFloorLegUnresolved(index, startDate, endDate, strikeSchedule, notionalSchedule, putCall, payRec);
return leg.resolve(REF_DATA);
}
/**
* Creates an Ibor cap/floor leg.
* <p>
* The Ibor index should be {@code EUR_EURIBOR_3M} or {@code EUR_EURIBOR_6M} to match the availability of the curve
* data in {@link IborCapletFloorletDataSet}.
*
* @param index the index
* @param startDate the start date
* @param endDate the end date
* @param strikeSchedule the strike
* @param notionalSchedule the notional
* @param putCall cap or floor
* @param payRec pay or receive
* @return the instance
*/
public static IborCapFloorLeg createCapFloorLegUnresolved(
IborIndex index,
LocalDate startDate,
LocalDate endDate,
ValueSchedule strikeSchedule,
ValueSchedule notionalSchedule,
PutCall putCall,
PayReceive payRec) {
Frequency frequency = Frequency.of(index.getTenor().getPeriod());
PeriodicSchedule paySchedule =
PeriodicSchedule.of(startDate, endDate, frequency, BUSINESS_ADJ, StubConvention.NONE, RollConventions.NONE);
IborRateCalculation rateCalculation = IborRateCalculation.of(index);
if (putCall.isCall()) {
return IborCapFloorLeg.builder()
.calculation(rateCalculation)
.capSchedule(strikeSchedule)
.notional(notionalSchedule)
.paymentSchedule(paySchedule)
.payReceive(payRec)
.build();
}
return IborCapFloorLeg.builder()
.calculation(rateCalculation)
.floorSchedule(strikeSchedule)
.notional(notionalSchedule)
.paymentSchedule(paySchedule)
.payReceive(payRec)
.build();
}
//-------------------------------------------------------------------------
/**
* Create a pay leg.
* <p>
* The pay leg created is periodic fixed rate payments without compounding.
* The Ibor index is used to specify the payment frequency.
*
* @param index the Ibor index
* @param startDate the start date
* @param endDate the end date
* @param fixedRate the fixed rate
* @param notional the notional
* @param payRec pay or receive
* @return the instance
*/
public static ResolvedSwapLeg createFixedPayLeg(
IborIndex index,
LocalDate startDate,
LocalDate endDate,
double fixedRate,
double notional,
PayReceive payRec) {
SwapLeg leg = createFixedPayLegUnresolved(index, startDate, endDate, fixedRate, notional, payRec);
return leg.resolve(REF_DATA);
}
/**
* Create a pay leg.
* <p>
* The pay leg created is periodic fixed rate payments without compounding.
* The Ibor index is used to specify the payment frequency.
*
* @param index the Ibor index
* @param startDate the start date
* @param endDate the end date
* @param fixedRate the fixed rate
* @param notional the notional
* @param payRec pay or receive
* @return the instance
*/
public static SwapLeg createFixedPayLegUnresolved(
IborIndex index,
LocalDate startDate,
LocalDate endDate,
double fixedRate,
double notional,
PayReceive payRec) {
Frequency frequency = Frequency.of(index.getTenor().getPeriod());
PeriodicSchedule accSchedule =
PeriodicSchedule.of(startDate, endDate, frequency, BUSINESS_ADJ, StubConvention.NONE, RollConventions.NONE);
return RateCalculationSwapLeg.builder()
.payReceive(payRec)
.accrualSchedule(accSchedule)
.calculation(
FixedRateCalculation.of(fixedRate, ACT_360))
.paymentSchedule(
PaymentSchedule.builder().paymentFrequency(frequency).paymentDateOffset(DaysAdjustment.NONE).build())
.notionalSchedule(
NotionalSchedule.of(CurrencyAmount.of(EUR, notional)))
.build();
}
}