/** * Copyright (C) 2014 - present by OpenGamma Inc. and the OpenGamma group of companies * * Please see distribution for license. */ package com.opengamma.sesame.swaption; import java.math.BigDecimal; import org.threeten.bp.LocalDate; import org.threeten.bp.OffsetTime; import org.threeten.bp.ZonedDateTime; import com.opengamma.analytics.financial.instrument.InstrumentDefinition; import com.opengamma.analytics.financial.interestrate.swaption.derivative.SwaptionPhysicalFixedIbor; import com.opengamma.analytics.financial.provider.curve.CurveBuildingBlockBundle; import com.opengamma.analytics.financial.provider.description.interestrate.MulticurveProviderDiscount; import com.opengamma.analytics.financial.provider.description.interestrate.SABRSwaptionProviderDiscount; import com.opengamma.core.position.Counterparty; import com.opengamma.core.position.Trade; import com.opengamma.core.position.impl.SimpleCounterparty; import com.opengamma.core.position.impl.SimpleTrade; import com.opengamma.financial.analytics.conversion.FixedIncomeConverterDataProvider; import com.opengamma.financial.analytics.conversion.SwaptionSecurityConverter; import com.opengamma.financial.analytics.timeseries.HistoricalTimeSeriesBundle; import com.opengamma.financial.security.option.SwaptionSecurity; import com.opengamma.id.ExternalId; import com.opengamma.sesame.DiscountingMulticurveCombinerFn; import com.opengamma.sesame.Environment; import com.opengamma.sesame.FixingsFn; import com.opengamma.sesame.MulticurveBundle; import com.opengamma.sesame.sabr.SabrParametersConfiguration; import com.opengamma.sesame.sabr.SabrParametersProviderFn; import com.opengamma.sesame.trade.SwaptionTrade; import com.opengamma.util.ArgumentChecker; import com.opengamma.util.result.Result; /** * Factory class for creating a calculator for a swaption using SABR data. */ public class SabrSwaptionCalculatorFactory implements SwaptionCalculatorFactory { /** * Converter for transforming a swaption into its derivative form. */ private final FixedIncomeConverterDataProvider _definitionToDerivativeConverter; /** * Function used to generate a combined multicurve bundle suitable * for use with a particular security. */ private final DiscountingMulticurveCombinerFn _discountingMulticurveCombinerFn; /** * Converter for transforming a swaption into its InstrumentDefinition form. */ private final SwaptionSecurityConverter _swaptionSecurityConverter; /** * Function used to retrieve time series data. */ // todo - the method for fixings should be moving from this function as per JIRA - SSM-215 private final FixingsFn _fixingsFn; /** * Function used to retrieve SABR parameter data. */ private final SabrParametersProviderFn _sabrParametersProviderFn; /** * Creates the factory. * * @param definitionToDerivativeConverter converter for transforming a swaption * into its derivative form, not null * @param discountingMulticurveCombinerFn function for creating multicurve * bundles, not null * @param swaptionSecurityConverter converter for transforming a swaption into * its InstrumentDefinition form, not null * @param fixingsFn function used to retrieve time series data, not null * @param sabrParametersProviderFn function used to retrieve SABR parameter * data, not null */ public SabrSwaptionCalculatorFactory(FixedIncomeConverterDataProvider definitionToDerivativeConverter, DiscountingMulticurveCombinerFn discountingMulticurveCombinerFn, SwaptionSecurityConverter swaptionSecurityConverter, FixingsFn fixingsFn, SabrParametersProviderFn sabrParametersProviderFn) { _definitionToDerivativeConverter = ArgumentChecker.notNull(definitionToDerivativeConverter, "definitionToDerivativeConverter"); _discountingMulticurveCombinerFn = ArgumentChecker.notNull(discountingMulticurveCombinerFn, "discountingMulticurveCombinerFn"); _swaptionSecurityConverter = ArgumentChecker.notNull(swaptionSecurityConverter, "swaptionSecurityConverter"); _fixingsFn = ArgumentChecker.notNull(fixingsFn, "htsFn"); _sabrParametersProviderFn = ArgumentChecker.notNull(sabrParametersProviderFn, "sabrParametersProviderFn"); } @Override public Result<SwaptionCalculator> createCalculator(Environment env, SwaptionSecurity security) { Trade trade = new SimpleTrade(security, BigDecimal.ONE, new SimpleCounterparty(ExternalId.of(Counterparty.DEFAULT_SCHEME, "CPARTY")), LocalDate.now(), OffsetTime.now()); SwaptionTrade tradeWrapper = new SwaptionTrade(trade); Result<MulticurveBundle> bundleResult = _discountingMulticurveCombinerFn.getMulticurveBundle(env, tradeWrapper); Result<HistoricalTimeSeriesBundle> fixingsResult = _fixingsFn.getFixingsForSecurity(env, security); Result<SabrParametersConfiguration> sabrResult = _sabrParametersProviderFn.getSabrParameters(env, security); if (Result.allSuccessful(bundleResult, fixingsResult, sabrResult)) { MulticurveProviderDiscount multicurveBundle = bundleResult.getValue().getMulticurveProvider(); CurveBuildingBlockBundle blockBundle = bundleResult.getValue().getCurveBuildingBlockBundle(); SwaptionPhysicalFixedIbor swaption = createInstrumentDerivative(security, env.getValuationTime(), fixingsResult.getValue()); SabrParametersConfiguration sabrConfig = sabrResult.getValue(); SwaptionCalculator calculator = new SabrSwaptionCalculator(swaption, buildSabrBundle(multicurveBundle, sabrConfig), blockBundle, sabrConfig.getSabrParameters()); return Result.success(calculator); } else { return Result.failure(bundleResult, fixingsResult, sabrResult); } } private SABRSwaptionProviderDiscount buildSabrBundle(MulticurveProviderDiscount multicurveBundle, SabrParametersConfiguration sabrConfig) { return new SABRSwaptionProviderDiscount(multicurveBundle, sabrConfig.getSabrParameters(), sabrConfig.getSwapConvention()); } private SwaptionPhysicalFixedIbor createInstrumentDerivative(SwaptionSecurity security, ZonedDateTime valuationTime, HistoricalTimeSeriesBundle fixings) { InstrumentDefinition<?> definition = security.accept(_swaptionSecurityConverter); // Cast is necessary due to IMPLIED_VOL_CALCULATOR requiring it on method calls // todo - this is soooooo brittle - SwaptionCashFixedIbor is equally probable - PLAT-6364 should address return (SwaptionPhysicalFixedIbor) _definitionToDerivativeConverter.convert(security, definition, valuationTime, fixings); } }