/**
* Copyright (C) 2013 - present by OpenGamma Inc. and the OpenGamma group of companies
*
* Please see distribution for license.
*/
package com.opengamma.financial.analytics.conversion;
import org.threeten.bp.Period;
import com.opengamma.OpenGammaRuntimeException;
import com.opengamma.analytics.financial.instrument.InstrumentDefinition;
import com.opengamma.analytics.financial.instrument.index.IndexPrice;
import com.opengamma.analytics.financial.instrument.swap.SwapFixedInflationYearOnYearDefinition;
import com.opengamma.analytics.financial.instrument.swap.SwapFixedInflationZeroCouponDefinition;
import com.opengamma.core.convention.ConventionSource;
import com.opengamma.core.holiday.HolidaySource;
import com.opengamma.core.region.RegionSource;
import com.opengamma.core.security.Security;
import com.opengamma.core.security.SecuritySource;
import com.opengamma.financial.convention.businessday.BusinessDayConvention;
import com.opengamma.financial.convention.calendar.Calendar;
import com.opengamma.financial.convention.daycount.DayCount;
import com.opengamma.financial.security.FinancialSecurityUtils;
import com.opengamma.financial.security.FinancialSecurityVisitorAdapter;
import com.opengamma.financial.security.swap.FixedInflationSwapLeg;
import com.opengamma.financial.security.swap.InflationIndexSwapLeg;
import com.opengamma.financial.security.swap.InterestRateNotional;
import com.opengamma.financial.security.swap.SwapLeg;
import com.opengamma.financial.security.swap.YearOnYearInflationSwapSecurity;
import com.opengamma.financial.security.swap.ZeroCouponInflationSwapSecurity;
import com.opengamma.util.ArgumentChecker;
import com.opengamma.util.money.Currency;
import com.opengamma.util.time.DateUtils;
/**
* Converts {@link YearOnYearInflationSwapSecurity} and {@link ZeroCouponInflationSwapSecurity} into the
* classes that the analytics library requires to calculate prices and risk.
*/
public class InflationSwapSecurityConverter extends FinancialSecurityVisitorAdapter<InstrumentDefinition<?>> {
/** A security source */
private final SecuritySource _securitySource;
/** The convention source */
private final ConventionSource _conventionSource;
/** The region source */
private final RegionSource _regionSource;
/** The holiday source */
private final HolidaySource _holidaySource;
/**
* @param securitySource The security source, not null
* @param conventionSource The convention source, not null
* @param regionSource The region source, not null
* @param holidaySource The holiday source, not null
*/
public InflationSwapSecurityConverter(final SecuritySource securitySource, final ConventionSource conventionSource, final RegionSource regionSource,
final HolidaySource holidaySource) {
ArgumentChecker.notNull(conventionSource, "convention source");
ArgumentChecker.notNull(regionSource, "region source");
ArgumentChecker.notNull(holidaySource, "holiday source");
_securitySource = securitySource;
_conventionSource = conventionSource;
_regionSource = regionSource;
_holidaySource = holidaySource;
}
@Override
public InstrumentDefinition<?> visitYearOnYearInflationSwapSecurity(final YearOnYearInflationSwapSecurity security) {
final SwapLeg payLeg = security.getPayLeg();
final SwapLeg receiveLeg = security.getReceiveLeg();
final FixedInflationSwapLeg fixedLeg;
final InflationIndexSwapLeg indexLeg;
final boolean isPayer;
if (payLeg instanceof FixedInflationSwapLeg && receiveLeg instanceof InflationIndexSwapLeg) {
fixedLeg = (FixedInflationSwapLeg) payLeg;
indexLeg = (InflationIndexSwapLeg) receiveLeg;
isPayer = true;
} else if (payLeg instanceof InflationIndexSwapLeg && receiveLeg instanceof FixedInflationSwapLeg) {
fixedLeg = (FixedInflationSwapLeg) receiveLeg;
indexLeg = (InflationIndexSwapLeg) payLeg;
isPayer = false;
} else {
throw new OpenGammaRuntimeException("Can only convert fixed / float inflation swaps");
}
final Security sec = _securitySource.getSingle(indexLeg.getIndexId().toBundle());
if (sec == null) {
throw new OpenGammaRuntimeException("Price index with id " + indexLeg.getIndexId() + " was null");
}
final com.opengamma.financial.security.index.PriceIndex indexSecurity = (com.opengamma.financial.security.index.PriceIndex) sec;
final Currency currency = FinancialSecurityUtils.getCurrency(security);
final IndexPrice priceIndex = new IndexPrice(indexSecurity.getName(), currency);
final boolean isEOM = fixedLeg.isEom();
final DayCount fixedLegDayCount = fixedLeg.getDayCount();
final BusinessDayConvention businessDayConvention = fixedLeg.getBusinessDayConvention();
final Calendar calendar = CalendarUtils.getCalendar(_regionSource, _holidaySource, fixedLeg.getRegionId());
final Period paymentPeriod = ConversionUtils.getTenor(indexLeg.getFrequency());
final Period maturityTenor = security.getMaturityTenor().getPeriod();
boolean isInterpolated;
switch (indexLeg.getInterpolationMethod()) {
case MONTH_START_LINEAR:
isInterpolated = true;
break;
case NONE:
isInterpolated = false;
break;
default:
throw new OpenGammaRuntimeException("Cannot handle interpolation method of type " + indexLeg.getInterpolationMethod());
}
final double fixedRate = fixedLeg.getRate();
final int conventionalMonthLag = indexLeg.getConventionalIndexationLag();
final int quotationMonthLag = indexLeg.getQuotationIndexationLag();
final boolean exchangeNotional = security.isExchangeInitialNotional() && security.isExchangeFinalNotional();
final double notional = ((InterestRateNotional) fixedLeg.getNotional()).getAmount();
if (!isInterpolated) {
return SwapFixedInflationYearOnYearDefinition.fromMonthly(priceIndex, security.getEffectiveDate(), paymentPeriod, (int) (maturityTenor.toTotalMonths() / 12), fixedRate,
notional, isPayer, businessDayConvention, calendar, isEOM, fixedLegDayCount, conventionalMonthLag, quotationMonthLag, exchangeNotional);
}
return SwapFixedInflationYearOnYearDefinition.fromInterpolation(priceIndex, security.getEffectiveDate(), paymentPeriod, maturityTenor, fixedRate,
notional, isPayer, businessDayConvention, calendar, isEOM, fixedLegDayCount, conventionalMonthLag, quotationMonthLag, exchangeNotional);
}
@Override
public InstrumentDefinition<?> visitZeroCouponInflationSwapSecurity(final ZeroCouponInflationSwapSecurity security) {
final SwapLeg payLeg = security.getPayLeg();
final SwapLeg receiveLeg = security.getReceiveLeg();
final FixedInflationSwapLeg fixedLeg;
final InflationIndexSwapLeg indexLeg;
final boolean isPayer;
if (payLeg instanceof FixedInflationSwapLeg && receiveLeg instanceof InflationIndexSwapLeg) {
fixedLeg = (FixedInflationSwapLeg) payLeg;
indexLeg = (InflationIndexSwapLeg) receiveLeg;
isPayer = true;
} else if (payLeg instanceof InflationIndexSwapLeg && receiveLeg instanceof FixedInflationSwapLeg) {
fixedLeg = (FixedInflationSwapLeg) receiveLeg;
indexLeg = (InflationIndexSwapLeg) payLeg;
isPayer = false;
} else {
throw new OpenGammaRuntimeException("Can only convert fixed / float inflation swaps");
}
final Security sec = _securitySource.getSingle(indexLeg.getIndexId().toBundle());
if (sec == null) {
throw new OpenGammaRuntimeException("Price index with id " + indexLeg.getIndexId() + " was null");
}
final com.opengamma.financial.security.index.PriceIndex indexSecurity = (com.opengamma.financial.security.index.PriceIndex) sec;
final Currency currency = FinancialSecurityUtils.getCurrency(security);
final IndexPrice priceIndex = new IndexPrice(indexSecurity.getName(), currency);
final boolean isEOM = fixedLeg.isEom();
final BusinessDayConvention businessDayConvention = fixedLeg.getBusinessDayConvention();
final Calendar calendar = CalendarUtils.getCalendar(_regionSource, _holidaySource, fixedLeg.getRegionId());
final int swapMaturityTenor = (int) Math.round(DateUtils.getDifferenceInYears(security.getEffectiveDate(), security.getMaturityDate()));
boolean isInterpolated;
switch (indexLeg.getInterpolationMethod()) {
case MONTH_START_LINEAR:
isInterpolated = true;
break;
case NONE:
isInterpolated = false;
break;
default:
throw new OpenGammaRuntimeException("Cannot handle interpolation method of type " + indexLeg.getInterpolationMethod());
}
final double fixedRate = fixedLeg.getRate();
final int conventionalMonthLag = indexLeg.getConventionalIndexationLag();
final int quotationMonthLag = indexLeg.getQuotationIndexationLag();
final double notional = ((InterestRateNotional) fixedLeg.getNotional()).getAmount();
if (!isInterpolated) {
return SwapFixedInflationZeroCouponDefinition.fromMonthly(priceIndex, security.getEffectiveDate(), swapMaturityTenor, fixedRate,
notional, isPayer, businessDayConvention, calendar, isEOM, conventionalMonthLag, quotationMonthLag);
}
return SwapFixedInflationZeroCouponDefinition.fromInterpolation(priceIndex, security.getEffectiveDate(), swapMaturityTenor, fixedRate,
notional, isPayer, businessDayConvention, calendar, isEOM, conventionalMonthLag, quotationMonthLag);
}
}