/** * Copyright (C) 2012 - present by OpenGamma Inc. and the OpenGamma group of companies * * Please see distribution for license. */ package com.opengamma.financial.analytics.conversion; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.threeten.bp.LocalDate; import org.threeten.bp.ZonedDateTime; import com.opengamma.OpenGammaRuntimeException; import com.opengamma.analytics.financial.ExerciseDecisionType; import com.opengamma.analytics.financial.commodity.definition.SettlementType; import com.opengamma.analytics.financial.equity.future.definition.EquityFutureDefinition; import com.opengamma.analytics.financial.equity.future.definition.IndexFutureDefinition; import com.opengamma.analytics.financial.equity.option.EquityIndexFutureOptionDefinition; import com.opengamma.analytics.financial.equity.option.EquityIndexOptionDefinition; import com.opengamma.analytics.financial.equity.option.EquityOptionDefinition; import com.opengamma.analytics.financial.instrument.InstrumentDefinition; import com.opengamma.core.security.Security; import com.opengamma.core.security.SecuritySource; import com.opengamma.financial.security.ExerciseTypeAnalyticsVisitorAdapter; import com.opengamma.financial.security.FinancialSecurityVisitorAdapter; import com.opengamma.financial.security.future.EquityFutureSecurity; import com.opengamma.financial.security.future.IndexFutureSecurity; import com.opengamma.financial.security.option.EquityIndexFutureOptionSecurity; import com.opengamma.financial.security.option.EquityIndexOptionSecurity; import com.opengamma.financial.security.option.EquityOptionSecurity; import com.opengamma.financial.security.option.OptionType; import com.opengamma.id.ExternalId; import com.opengamma.id.ExternalIdBundle; import com.opengamma.util.ArgumentChecker; import com.opengamma.util.money.Currency; /** * Converts equity index options, equity options and equity index future options into something that OG-Analytics can use. */ public class EquityOptionsConverter extends FinancialSecurityVisitorAdapter<InstrumentDefinition<?>> { private final FutureSecurityConverterDeprecated _futureSecurityConverter; private final SecuritySource _securitySource; public EquityOptionsConverter() { this(null, null); } public EquityOptionsConverter(final FutureSecurityConverterDeprecated futureSecurityConverter, final SecuritySource securitySource) { _futureSecurityConverter = futureSecurityConverter; _securitySource = securitySource; } @Override public InstrumentDefinition<?> visitEquityIndexOptionSecurity(final EquityIndexOptionSecurity security) { ArgumentChecker.notNull(security, "security"); final boolean isCall = security.getOptionType() == OptionType.CALL; final double strike = security.getStrike(); final ZonedDateTime expiryDT = security.getExpiry().getExpiry(); final Currency ccy = security.getCurrency(); final double unitNotional = security.getPointValue(); final ExerciseDecisionType exerciseType = security.getExerciseType().accept(ExerciseTypeAnalyticsVisitorAdapter.getInstance()); // TODO We need to know how long after expiry settlement occurs? // IndexOptions are obviously Cash Settled final LocalDate settlementDate = expiryDT.toLocalDate(); // FIXME Needs to come from convention //TODO settlement type needs to come from trade or convention return new EquityIndexOptionDefinition(isCall, strike, ccy, exerciseType, expiryDT, settlementDate, unitNotional, SettlementType.CASH); } @Override public InstrumentDefinition<?> visitEquityOptionSecurity(final EquityOptionSecurity security) { ArgumentChecker.notNull(security, "security"); final boolean isCall = security.getOptionType() == OptionType.CALL; final double strike = security.getStrike(); final ZonedDateTime expiryDT = security.getExpiry().getExpiry(); final Currency ccy = security.getCurrency(); final double unitNotional = security.getPointValue(); final ExerciseDecisionType exerciseType = security.getExerciseType().accept(ExerciseTypeAnalyticsVisitorAdapter.getInstance()); // TODO We need to know how long after expiry settlement occurs? // IndexOptions are obviously Cash Settled final LocalDate settlementDate = expiryDT.toLocalDate(); // FIXME Needs to come from convention //TODO settlement type needs to come from trade or convention return new EquityOptionDefinition(isCall, strike, ccy, exerciseType, expiryDT, settlementDate, unitNotional, SettlementType.PHYSICAL); } @Override public InstrumentDefinition<?> visitEquityIndexFutureOptionSecurity(final EquityIndexFutureOptionSecurity security) { ArgumentChecker.notNull(security, "security"); if (_securitySource == null) { throw new OpenGammaRuntimeException("Need a security source to convert equity index future option securities"); } if (_futureSecurityConverter == null) { throw new OpenGammaRuntimeException("Need a future security converter to convert equity index future option securities"); } final ZonedDateTime expiryDate = security.getExpiry().getExpiry(); final ExternalId underlyingIdentifier = security.getUnderlyingId(); // REVIEW Andrew -- This call to getSingle is not correct as the resolution time of the view cycle will not be considered Security underlyingSecurity = _securitySource.getSingle(ExternalIdBundle.of(underlyingIdentifier)); if (underlyingSecurity == null) { throw new OpenGammaRuntimeException("Underlying security " + underlyingIdentifier + " of option " + security.getExternalIdBundle().toString() + " was not found in database"); } IndexFutureDefinition underlying = null; if (underlyingSecurity instanceof IndexFutureSecurity) { final IndexFutureSecurity underlyingFuture = ((IndexFutureSecurity) underlyingSecurity); underlying = (IndexFutureDefinition) underlyingFuture.accept(_futureSecurityConverter); } else if (underlyingSecurity instanceof EquityFutureSecurity) { final EquityFutureSecurity underlyingFuture = ((EquityFutureSecurity) underlyingSecurity); EquityFutureDefinition eqFut = (EquityFutureDefinition) underlyingFuture.accept(_futureSecurityConverter); underlying = new IndexFutureDefinition(eqFut.getExpiryDate(), eqFut.getSettlementDate(), eqFut.getStrikePrice(), eqFut.getCurrency(), eqFut.getUnitAmount(), underlyingFuture.getUnderlyingId()); } final double strike = security.getStrike(); final ExerciseDecisionType exerciseType = security.getExerciseType().accept(ExerciseTypeAnalyticsVisitorAdapter.getInstance()); final boolean isCall = security.getOptionType() == OptionType.CALL; final double pointValue = security.getPointValue(); // FIXME Need the true referencePrice. 0.0 is just a stub as this converter acts upon a FinancialSecurity, not a Trade. return new EquityIndexFutureOptionDefinition(expiryDate, underlying, strike, exerciseType, isCall, pointValue, 0.0); } private static final Logger s_logger = LoggerFactory.getLogger(EquityOptionsConverter.class); }