/**
* Copyright (C) 2013 - present by OpenGamma Inc. and the OpenGamma group of companies
*
* Please see distribution for license.
*/
package com.opengamma.financial.security;
import com.google.common.base.Preconditions;
import com.opengamma.OpenGammaRuntimeException;
import com.opengamma.core.security.Security;
import com.opengamma.core.security.SecuritySource;
import com.opengamma.financial.currency.CurrencyPair;
import com.opengamma.financial.currency.CurrencyPairs;
import com.opengamma.financial.security.bond.CorporateBondSecurity;
import com.opengamma.financial.security.bond.GovernmentBondSecurity;
import com.opengamma.financial.security.bond.MunicipalBondSecurity;
import com.opengamma.financial.security.cash.CashBalanceSecurity;
import com.opengamma.financial.security.cash.CashSecurity;
import com.opengamma.financial.security.cashflow.CashFlowSecurity;
import com.opengamma.financial.security.cds.CreditDefaultSwapIndexSecurity;
import com.opengamma.financial.security.cds.LegacyVanillaCDSSecurity;
import com.opengamma.financial.security.cds.StandardVanillaCDSSecurity;
import com.opengamma.financial.security.credit.IndexCDSSecurity;
import com.opengamma.financial.security.credit.LegacyCDSSecurity;
import com.opengamma.financial.security.credit.StandardCDSSecurity;
import com.opengamma.financial.security.equity.EquitySecurity;
import com.opengamma.financial.security.fra.FRASecurity;
import com.opengamma.financial.security.fra.ForwardRateAgreementSecurity;
import com.opengamma.financial.security.future.BondFutureSecurity;
import com.opengamma.financial.security.future.EquityFutureSecurity;
import com.opengamma.financial.security.future.FederalFundsFutureSecurity;
import com.opengamma.financial.security.future.InterestRateFutureSecurity;
import com.opengamma.financial.security.future.MetalFutureSecurity;
import com.opengamma.financial.security.fx.FXForwardSecurity;
import com.opengamma.financial.security.fx.FXVolatilitySwapSecurity;
import com.opengamma.financial.security.irs.InterestRateSwapLeg;
import com.opengamma.financial.security.irs.InterestRateSwapSecurity;
import com.opengamma.financial.security.option.CreditDefaultSwapOptionSecurity;
import com.opengamma.financial.security.option.EquityIndexOptionSecurity;
import com.opengamma.financial.security.option.EquityOptionSecurity;
import com.opengamma.financial.security.option.FXBarrierOptionSecurity;
import com.opengamma.financial.security.option.FXDigitalOptionSecurity;
import com.opengamma.financial.security.option.FXOptionSecurity;
import com.opengamma.financial.security.option.IRFutureOptionSecurity;
import com.opengamma.financial.security.option.NonDeliverableFXDigitalOptionSecurity;
import com.opengamma.financial.security.option.NonDeliverableFXOptionSecurity;
import com.opengamma.financial.security.option.SwaptionSecurity;
import com.opengamma.financial.security.swap.BillTotalReturnSwapSecurity;
import com.opengamma.financial.security.swap.BondTotalReturnSwapSecurity;
import com.opengamma.financial.security.swap.EquityTotalReturnSwapSecurity;
import com.opengamma.financial.security.swap.InterestRateNotional;
import com.opengamma.financial.security.swap.SwapLeg;
import com.opengamma.financial.security.swap.SwapSecurity;
import com.opengamma.id.ExternalIdBundle;
import com.opengamma.util.money.Currency;
import com.opengamma.util.money.CurrencyAmount;
/**
* Obtain notional from a security, null if not applicable.
*/
public class NotionalVisitor extends FinancialSecurityVisitorAdapter<CurrencyAmount> {
private final CurrencyPairs _currencyPairs;
private final SecuritySource _securitySource;
public NotionalVisitor(final CurrencyPairs currencyPairs, final SecuritySource securitySource) {
_currencyPairs = currencyPairs;
_securitySource = securitySource;
}
@Override
public CurrencyAmount visitSwapSecurity(final SwapSecurity security) {
final SwapLeg payNotional = security.getPayLeg();
final SwapLeg receiveNotional = security.getReceiveLeg();
if (payNotional.getNotional() instanceof InterestRateNotional && receiveNotional.getNotional() instanceof InterestRateNotional) {
final InterestRateNotional pay = (InterestRateNotional) payNotional.getNotional();
final InterestRateNotional receive = (InterestRateNotional) receiveNotional.getNotional();
if (Double.compare(pay.getAmount(), receive.getAmount()) == 0) {
return CurrencyAmount.of(pay.getCurrency(), pay.getAmount());
}
}
throw new OpenGammaRuntimeException("Can only handle interest rate notionals with the same amounts");
}
@Override
public CurrencyAmount visitInterestRateSwapSecurity(final InterestRateSwapSecurity security) {
//TODO: Handle more than 2 legs
final InterestRateSwapLeg payNotional = security.getPayLeg();
final InterestRateSwapLeg receiveNotional = security.getReceiveLeg();
final InterestRateNotional pay = payNotional.getNotional();
final InterestRateNotional receive = receiveNotional.getNotional();
if (Double.compare(pay.getAmount(), receive.getAmount()) == 0) {
return CurrencyAmount.of(pay.getCurrency(), pay.getAmount());
}
throw new OpenGammaRuntimeException("Can only handle interest rate notionals with the same amounts");
}
@Override
public CurrencyAmount visitFXOptionSecurity(final FXOptionSecurity security) {
final Currency currency1 = security.getPutCurrency();
final double amount1 = security.getPutAmount();
final Currency currency2 = security.getCallCurrency();
final double amount2 = security.getCallAmount();
final CurrencyPair currencyPair = _currencyPairs.getCurrencyPair(currency1, currency2);
if (currencyPair.getBase().equals(currency1)) {
return CurrencyAmount.of(currency1, amount1);
}
return CurrencyAmount.of(currency2, amount2);
}
@Override
public CurrencyAmount visitFXBarrierOptionSecurity(final FXBarrierOptionSecurity security) {
final Currency currency1 = security.getPutCurrency();
final double amount1 = security.getPutAmount();
final Currency currency2 = security.getCallCurrency();
final double amount2 = security.getCallAmount();
final CurrencyPair currencyPair = _currencyPairs.getCurrencyPair(currency1, currency2);
if (currencyPair.getBase().equals(currency1)) {
return CurrencyAmount.of(currency1, amount1);
}
return CurrencyAmount.of(currency2, amount2);
}
@Override
public CurrencyAmount visitNonDeliverableFXOptionSecurity(final NonDeliverableFXOptionSecurity security) {
final Currency currency = security.getDeliveryCurrency();
final double amount = security.getCallCurrency().equals(currency) ? security.getCallAmount() : security.getPutAmount();
return CurrencyAmount.of(currency, amount);
}
@Override
public CurrencyAmount visitFXDigitalOptionSecurity(final FXDigitalOptionSecurity security) {
final Currency currency1 = security.getPutCurrency();
final double amount1 = security.getPutAmount();
final Currency currency2 = security.getCallCurrency();
final double amount2 = security.getCallAmount();
final CurrencyPair currencyPair = _currencyPairs.getCurrencyPair(currency1, currency2);
if (currencyPair.getBase().equals(currency1)) {
return CurrencyAmount.of(currency1, amount1);
}
return CurrencyAmount.of(currency2, amount2);
}
@Override
public CurrencyAmount visitNonDeliverableFXDigitalOptionSecurity(final NonDeliverableFXDigitalOptionSecurity security) {
final Currency currency = security.getPaymentCurrency();
final double amount = security.getCallCurrency().equals(currency) ? security.getCallAmount() : security.getPutAmount();
return CurrencyAmount.of(currency, amount);
}
@Override
public CurrencyAmount visitFXForwardSecurity(final FXForwardSecurity security) {
final Currency currency1 = security.getPayCurrency();
final double amount1 = security.getPayAmount();
final Currency currency2 = security.getReceiveCurrency();
final double amount2 = security.getReceiveAmount();
final CurrencyPair currencyPair = _currencyPairs.getCurrencyPair(currency1, currency2);
if (currencyPair.getBase().equals(currency1)) {
return CurrencyAmount.of(currency1, amount1);
}
return CurrencyAmount.of(currency2, amount2);
}
@Override
public CurrencyAmount visitStandardVanillaCDSSecurity(final StandardVanillaCDSSecurity security) {
final InterestRateNotional notional = security.getNotional();
final int sign = security.isBuy() ? -1 : 1;
return CurrencyAmount.of(notional.getCurrency(), sign * notional.getAmount());
}
@Override
public CurrencyAmount visitLegacyVanillaCDSSecurity(final LegacyVanillaCDSSecurity security) {
final InterestRateNotional notional = security.getNotional();
final int sign = security.isBuy() ? -1 : 1;
return CurrencyAmount.of(notional.getCurrency(), sign * notional.getAmount());
}
@Override
public CurrencyAmount visitGovernmentBondSecurity(final GovernmentBondSecurity security) {
final Currency currency = security.getCurrency();
final double notional = security.getMinimumAmount();
return CurrencyAmount.of(currency, notional);
}
@Override
public CurrencyAmount visitCorporateBondSecurity(final CorporateBondSecurity security) {
final Currency currency = security.getCurrency();
final double notional = security.getMinimumAmount();
return CurrencyAmount.of(currency, notional);
}
@Override
public CurrencyAmount visitMunicipalBondSecurity(final MunicipalBondSecurity security) {
final Currency currency = security.getCurrency();
final double notional = security.getMinimumAmount();
return CurrencyAmount.of(currency, notional);
}
@Override
public CurrencyAmount visitSwaptionSecurity(final SwaptionSecurity security) {
final Security underlying = _securitySource.getSingle(ExternalIdBundle.of(security.getUnderlyingId()));
Preconditions.checkState(underlying instanceof SwapSecurity,
"Failed to resolve underlying SwapSecurity. DB record potentially corrupted. '%s' returned.",
underlying);
final CurrencyAmount notional = ((SwapSecurity) underlying).accept(this);
if (security.isLong()) {
return notional;
}
return notional.multipliedBy(-1);
}
@Override
public CurrencyAmount visitEquityIndexOptionSecurity(final EquityIndexOptionSecurity security) {
final Currency currency = security.getCurrency();
final double notional = security.getPointValue();
return CurrencyAmount.of(currency, notional);
}
@Override
public CurrencyAmount visitEquityOptionSecurity(final EquityOptionSecurity security) {
final Currency currency = security.getCurrency();
final double notional = security.getPointValue();
return CurrencyAmount.of(currency, notional);
}
@Override
public CurrencyAmount visitEquitySecurity(final EquitySecurity security) {
final Currency currency = security.getCurrency();
return CurrencyAmount.of(currency, 1.0);
}
@Override
public CurrencyAmount visitEquityFutureSecurity(final EquityFutureSecurity security) {
final Currency currency = security.getCurrency();
return CurrencyAmount.of(currency, security.getUnitAmount());
}
@Override
public CurrencyAmount visitMetalFutureSecurity(final MetalFutureSecurity security) {
final Currency currency = security.getCurrency();
return CurrencyAmount.of(currency, security.getUnitAmount());
}
@Override
public CurrencyAmount visitBondFutureSecurity(final BondFutureSecurity security) {
final Currency currency = security.getCurrency();
final double notional = security.getUnitAmount();
return CurrencyAmount.of(currency, notional);
}
@Override
public CurrencyAmount visitInterestRateFutureSecurity(final InterestRateFutureSecurity security) {
final Currency currency = security.getCurrency();
final double notional = security.getUnitAmount();
return CurrencyAmount.of(currency, notional);
}
@Override
public CurrencyAmount visitIRFutureOptionSecurity(final IRFutureOptionSecurity security) {
final Security underlying = _securitySource.getSingle(security.getUnderlyingId().toBundle());
Preconditions.checkState(underlying instanceof InterestRateFutureSecurity,
"Failed to resolve underlying InterestRateFutureSecurity. " +
"DB record potentially corrupted. '%s' returned.",
underlying);
return ((InterestRateFutureSecurity) underlying).accept(this);
}
@Override
public CurrencyAmount visitFederalFundsFutureSecurity(final FederalFundsFutureSecurity security) {
final Currency currency = security.getCurrency();
final double notional = security.getUnitAmount();
return CurrencyAmount.of(currency, notional);
}
@Override
public CurrencyAmount visitCreditDefaultSwapIndexSecurity(final CreditDefaultSwapIndexSecurity security) {
final InterestRateNotional notional = security.getNotional();
final int sign = security.isBuy() ? -1 : 1;
return CurrencyAmount.of(notional.getCurrency(), sign * notional.getAmount());
}
@Override
public CurrencyAmount visitCreditDefaultSwapOptionSecurity(final CreditDefaultSwapOptionSecurity security) {
final Currency currency = security.getCurrency();
final double notional = security.getNotional();
return CurrencyAmount.of(currency, notional);
}
@Override
public CurrencyAmount visitCashFlowSecurity(final CashFlowSecurity security) {
return CurrencyAmount.of(security.getCurrency(), security.getAmount());
}
@Override
public CurrencyAmount visitCashBalanceSecurity(final CashBalanceSecurity security) {
return CurrencyAmount.of(security.getCurrency(), security.getAmount());
}
@Override
public CurrencyAmount visitCashSecurity(final CashSecurity security) {
return CurrencyAmount.of(security.getCurrency(), security.getAmount());
}
@Override
public CurrencyAmount visitFXVolatilitySwapSecurity(final FXVolatilitySwapSecurity security) {
return CurrencyAmount.of(security.getCurrency(), security.getNotional());
}
@Override
public CurrencyAmount visitFRASecurity(final FRASecurity security) {
return CurrencyAmount.of(security.getCurrency(), security.getAmount());
}
@Override
public CurrencyAmount visitForwardRateAgreementSecurity(final ForwardRateAgreementSecurity security) {
return CurrencyAmount.of(security.getCurrency(), security.getAmount());
}
@Override
public CurrencyAmount visitEquityTotalReturnSwapSecurity(final EquityTotalReturnSwapSecurity security) {
return CurrencyAmount.of(security.getNotionalCurrency(), security.getNotionalAmount());
}
@Override
public CurrencyAmount visitBondTotalReturnSwapSecurity(final BondTotalReturnSwapSecurity security) {
return CurrencyAmount.of(security.getNotionalCurrency(), security.getNotionalAmount());
}
@Override
public CurrencyAmount visitBillTotalReturnSwapSecurity(final BillTotalReturnSwapSecurity security) {
return CurrencyAmount.of(security.getNotionalCurrency(), security.getNotionalAmount());
}
@Override
public CurrencyAmount visitIndexCDSSecurity(IndexCDSSecurity security) {
final InterestRateNotional notional = security.getNotional();
final int sign = security.isBuyProtection() ? -1 : 1;
return CurrencyAmount.of(notional.getCurrency(), sign * notional.getAmount());
}
@Override
public CurrencyAmount visitLegacyCDSSecurity(LegacyCDSSecurity security) {
final InterestRateNotional notional = security.getNotional();
final int sign = security.isBuyProtection() ? -1 : 1;
return CurrencyAmount.of(notional.getCurrency(), sign * notional.getAmount());
}
@Override
public CurrencyAmount visitStandardCDSSecurity(StandardCDSSecurity security) {
final InterestRateNotional notional = security.getNotional();
final int sign = security.isBuyProtection() ? -1 : 1;
return CurrencyAmount.of(notional.getCurrency(), sign * notional.getAmount());
}
}