/** * Copyright (C) 2013 - present by OpenGamma Inc. and the OpenGamma group of companies * * Please see distribution for license. */ package com.opengamma.financial.analytics.curve.exposure; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; import com.opengamma.core.position.Trade; import com.opengamma.core.security.Security; import com.opengamma.core.security.SecuritySource; import com.opengamma.financial.security.FinancialSecurity; import com.opengamma.financial.security.FinancialSecurityVisitorSameValueAdapter; import com.opengamma.financial.security.bond.FloatingRateNoteSecurity; import com.opengamma.financial.security.capfloor.CapFloorCMSSpreadSecurity; import com.opengamma.financial.security.capfloor.CapFloorSecurity; import com.opengamma.financial.security.credit.IndexCDSSecurity; import com.opengamma.financial.security.fra.FRASecurity; import com.opengamma.financial.security.fra.ForwardRateAgreementSecurity; import com.opengamma.financial.security.future.FederalFundsFutureSecurity; import com.opengamma.financial.security.future.InterestRateFutureSecurity; import com.opengamma.financial.security.irs.FloatingInterestRateSwapLeg; import com.opengamma.financial.security.irs.InterestRateSwapLeg; import com.opengamma.financial.security.irs.InterestRateSwapSecurity; import com.opengamma.financial.security.option.SwaptionSecurity; import com.opengamma.financial.security.swap.BondTotalReturnSwapSecurity; import com.opengamma.financial.security.swap.EquityTotalReturnSwapSecurity; import com.opengamma.financial.security.swap.FloatingInterestRateLeg; import com.opengamma.financial.security.swap.ForwardSwapSecurity; import com.opengamma.financial.security.swap.InflationIndexSwapLeg; import com.opengamma.financial.security.swap.SwapLeg; import com.opengamma.financial.security.swap.SwapSecurity; import com.opengamma.financial.security.swap.YearOnYearInflationSwapSecurity; import com.opengamma.financial.security.swap.ZeroCouponInflationSwapSecurity; import com.opengamma.id.ExternalId; import com.opengamma.id.ExternalIdBundle; import com.opengamma.util.ArgumentChecker; /** * Exposure function that returns the underlying security of the given trade. If there is no underlying, then null is * returned. */ public class UnderlyingExposureFunction implements ExposureFunction { /** * The name of the exposure function. */ public static final String NAME = "Underlying"; private final UnderlyingVisitor _visitor; public UnderlyingExposureFunction(final SecuritySource securitySource) { _visitor = new UnderlyingVisitor(ArgumentChecker.notNull(securitySource, "security source")); } @Override public String getName() { return NAME; } @Override public List<ExternalId> getIds(Trade trade) { Security security = trade.getSecurity(); if (security instanceof FinancialSecurity) { return ((FinancialSecurity) security).accept(_visitor); } return null; } private static final class UnderlyingVisitor extends FinancialSecurityVisitorSameValueAdapter<List<ExternalId>> { private final SecuritySource _securitySource; public UnderlyingVisitor(SecuritySource securitySource) { super(null); _securitySource = ArgumentChecker.notNull(securitySource, "securitySource"); } @Override public List<ExternalId> visitInterestRateFutureSecurity(final InterestRateFutureSecurity security) { return Arrays.asList(security.getUnderlyingId()); } @Override public List<ExternalId> visitFederalFundsFutureSecurity(final FederalFundsFutureSecurity security) { return Arrays.asList(security.getUnderlyingId()); } @Override public List<ExternalId> visitCapFloorCMSSpreadSecurity(final CapFloorCMSSpreadSecurity security) { final List<ExternalId> result = new ArrayList<>(); result.add(security.getLongId()); result.add(security.getShortId()); return result; } @Override public List<ExternalId> visitCapFloorSecurity(final CapFloorSecurity security) { return Arrays.asList(security.getUnderlyingId()); } @Override public List<ExternalId> visitFRASecurity(final FRASecurity security) { return Arrays.asList(security.getUnderlyingId()); } @Override public List<ExternalId> visitForwardRateAgreementSecurity(final ForwardRateAgreementSecurity security) { return Arrays.asList(security.getUnderlyingId()); } @Override public List<ExternalId> visitForwardSwapSecurity(final ForwardSwapSecurity security) { final List<ExternalId> result = new ArrayList<>(); final SwapLeg payLeg = security.getPayLeg(); final SwapLeg receiveLeg = security.getReceiveLeg(); if (payLeg instanceof FloatingInterestRateLeg) { result.add(((FloatingInterestRateLeg) payLeg).getFloatingReferenceRateId()); } if (receiveLeg instanceof FloatingInterestRateLeg) { result.add(((FloatingInterestRateLeg) receiveLeg).getFloatingReferenceRateId()); } if (result.isEmpty()) { return null; } return result; } @Override public List<ExternalId> visitSwapSecurity(final SwapSecurity security) { final List<ExternalId> result = new ArrayList<>(); final SwapLeg payLeg = security.getPayLeg(); final SwapLeg receiveLeg = security.getReceiveLeg(); if (payLeg instanceof FloatingInterestRateLeg) { result.add(((FloatingInterestRateLeg) payLeg).getFloatingReferenceRateId()); } if (receiveLeg instanceof FloatingInterestRateLeg) { result.add(((FloatingInterestRateLeg) receiveLeg).getFloatingReferenceRateId()); } if (result.isEmpty()) { return null; } return result; } @Override public List<ExternalId> visitSwaptionSecurity(final SwaptionSecurity security) { final List<ExternalId> result = new ArrayList<>(); final SwapSecurity underlyingSwap = (SwapSecurity) _securitySource.getSingle(ExternalIdBundle.of(security.getUnderlyingId())); //TODO version final SwapLeg payLeg = underlyingSwap.getPayLeg(); final SwapLeg receiveLeg = underlyingSwap.getReceiveLeg(); if (payLeg instanceof FloatingInterestRateLeg) { result.add(((FloatingInterestRateLeg) payLeg).getFloatingReferenceRateId()); } if (receiveLeg instanceof FloatingInterestRateLeg) { result.add(((FloatingInterestRateLeg) receiveLeg).getFloatingReferenceRateId()); } if (result.isEmpty()) { return null; } return result; } @Override public List<ExternalId> visitZeroCouponInflationSwapSecurity(final ZeroCouponInflationSwapSecurity security) { final List<ExternalId> result = new ArrayList<>(); final SwapLeg payLeg = security.getPayLeg(); final SwapLeg receiveLeg = security.getReceiveLeg(); if (payLeg instanceof InflationIndexSwapLeg) { result.add(((InflationIndexSwapLeg) payLeg).getIndexId()); } if (receiveLeg instanceof InflationIndexSwapLeg) { result.add(((InflationIndexSwapLeg) receiveLeg).getIndexId()); } if (result.isEmpty()) { return null; } return result; } @Override public List<ExternalId> visitYearOnYearInflationSwapSecurity(final YearOnYearInflationSwapSecurity security) { final List<ExternalId> result = new ArrayList<>(); final SwapLeg payLeg = security.getPayLeg(); final SwapLeg receiveLeg = security.getReceiveLeg(); if (payLeg instanceof InflationIndexSwapLeg) { result.add(((InflationIndexSwapLeg) payLeg).getIndexId()); } if (receiveLeg instanceof InflationIndexSwapLeg) { result.add(((InflationIndexSwapLeg) receiveLeg).getIndexId()); } if (result.isEmpty()) { return null; } return result; } @Override public List<ExternalId> visitInterestRateSwapSecurity(final InterestRateSwapSecurity security) { final List<ExternalId> result = new ArrayList<>(); for (final InterestRateSwapLeg leg : security.getLegs()) { if (leg instanceof FloatingInterestRateSwapLeg) { final ExternalIdBundle ids = ((FloatingInterestRateSwapLeg) leg).getFloatingReferenceRateId().toBundle(); for (final ExternalId id : ids) { result.add(id); // only add the first id per leg, if multiple ids resolving to the same rate were returned // the caller could over estimate their exposure break; } } } if (result.isEmpty()) { return null; } return result; } @Override public List<ExternalId> visitFloatingRateNoteSecurity(final FloatingRateNoteSecurity security) { return Collections.singletonList(security.getBenchmarkRateId()); } @Override public List<ExternalId> visitEquityTotalReturnSwapSecurity(final EquityTotalReturnSwapSecurity security) { return Collections.singletonList(security.getFundingLeg().getFloatingReferenceRateId()); } @Override public List<ExternalId> visitBondTotalReturnSwapSecurity(final BondTotalReturnSwapSecurity security) { return Collections.singletonList(security.getFundingLeg().getFloatingReferenceRateId()); } @Override public List<ExternalId> visitIndexCDSSecurity(IndexCDSSecurity security) { return security.getUnderlyingIndex().resolve().getExternalIdBundle().getExternalIds().asList(); } } }