@Override public Set<ComputedValue> execute( final FunctionExecutionContext executionContext, final FunctionInputs inputs, final ComputationTarget target, final Set<ValueRequirement> desiredValues) { final ValueRequirement desiredValue = desiredValues.iterator().next(); final String curveName = desiredValue.getConstraint(ValuePropertyNames.CURVE); final String interpolatorName = desiredValue.getConstraint( ForwardCurveValuePropertyNames.PROPERTY_FORWARD_CURVE_INTERPOLATOR); final String leftExtrapolatorName = desiredValue.getConstraint( ForwardCurveValuePropertyNames.PROPERTY_FORWARD_CURVE_LEFT_EXTRAPOLATOR); final String rightExtrapolatorName = desiredValue.getConstraint( ForwardCurveValuePropertyNames.PROPERTY_FORWARD_CURVE_RIGHT_EXTRAPOLATOR); final Object objectFuturePriceData = inputs.getValue(ValueRequirementNames.FUTURE_PRICE_CURVE_DATA); if (objectFuturePriceData == null) { throw new OpenGammaRuntimeException("Could not get futures curve " + curveName); } final NodalDoublesCurve futurePriceData = (NodalDoublesCurve) objectFuturePriceData; final Interpolator1D interpolator = CombinedInterpolatorExtrapolatorFactory.getInterpolator( interpolatorName, leftExtrapolatorName, rightExtrapolatorName); final ForwardCurve curve = new ForwardCurve( InterpolatedDoublesCurve.from( futurePriceData.getXData(), futurePriceData.getYData(), interpolator)); final ValueProperties properties = createValueProperties() .with( ForwardCurveValuePropertyNames.PROPERTY_FORWARD_CURVE_CALCULATION_METHOD, ForwardCurveValuePropertyNames.PROPERTY_FUTURE_PRICE_METHOD) .with(ValuePropertyNames.CURVE, curveName) .with( ForwardCurveValuePropertyNames.PROPERTY_FORWARD_CURVE_INTERPOLATOR, interpolatorName) .with( ForwardCurveValuePropertyNames.PROPERTY_FORWARD_CURVE_LEFT_EXTRAPOLATOR, leftExtrapolatorName) .with( ForwardCurveValuePropertyNames.PROPERTY_FORWARD_CURVE_RIGHT_EXTRAPOLATOR, rightExtrapolatorName) .with( InstrumentTypeProperties.PROPERTY_SURFACE_INSTRUMENT_TYPE, InstrumentTypeProperties.EQUITY_FUTURE_PRICE) .get(); final ValueSpecification resultSpec = new ValueSpecification( ValueRequirementNames.FORWARD_CURVE, target.toSpecification(), properties); return Collections.singleton(new ComputedValue(resultSpec, curve)); }
@Override public Set<ComputedValue> execute( final FunctionExecutionContext executionContext, final FunctionInputs inputs, final ComputationTarget target, final Set<ValueRequirement> desiredValues) { final Clock snapshotClock = executionContext.getValuationClock(); final ZonedDateTime now = snapshotClock.zonedDateTime(); final FinancialSecurity security = (FinancialSecurity) target.getSecurity(); final Currency payCurrency, receiveCurrency; if (security instanceof FXForwardSecurity) { final FXForwardSecurity forward = (FXForwardSecurity) security; payCurrency = forward.getPayCurrency(); receiveCurrency = forward.getReceiveCurrency(); } else { final NonDeliverableFXForwardSecurity ndf = (NonDeliverableFXForwardSecurity) security; payCurrency = ndf.getPayCurrency(); receiveCurrency = ndf.getReceiveCurrency(); } final ForexDefinition definition = (ForexDefinition) security.accept(VISITOR); final ValueRequirement desiredValue = desiredValues.iterator().next(); final String payCurveName = desiredValue.getConstraint(ValuePropertyNames.PAY_CURVE); final String receiveCurveName = desiredValue.getConstraint(ValuePropertyNames.RECEIVE_CURVE); final String payCurveConfig = desiredValue.getConstraint(PAY_CURVE_CALC_CONFIG); final String receiveCurveConfig = desiredValue.getConstraint(RECEIVE_CURVE_CALC_CONFIG); final String fullPutCurveName = payCurveName + "_" + payCurrency.getCode(); final String fullCallCurveName = receiveCurveName + "_" + receiveCurrency.getCode(); final YieldAndDiscountCurve payFundingCurve = getCurve(inputs, payCurrency, payCurveName, payCurveConfig); final YieldAndDiscountCurve receiveFundingCurve = getCurve(inputs, receiveCurrency, receiveCurveName, receiveCurveConfig); final YieldAndDiscountCurve[] curves; final Map<String, Currency> curveCurrency = new HashMap<String, Currency>(); curveCurrency.put(fullPutCurveName, payCurrency); curveCurrency.put(fullCallCurveName, receiveCurrency); final String[] allCurveNames; if (FXUtils.isInBaseQuoteOrder( payCurrency, receiveCurrency)) { // To get Base/quote in market standard order. curves = new YieldAndDiscountCurve[] {payFundingCurve, receiveFundingCurve}; allCurveNames = new String[] {fullPutCurveName, fullCallCurveName}; } else { curves = new YieldAndDiscountCurve[] {receiveFundingCurve, payFundingCurve}; allCurveNames = new String[] {fullCallCurveName, fullPutCurveName}; } final YieldCurveBundle yieldCurves = new YieldCurveBundle(allCurveNames, curves); final ValueProperties.Builder properties = getResultProperties( payCurveName, receiveCurveName, payCurveConfig, receiveCurveConfig, target); final ValueSpecification spec = new ValueSpecification( ValueRequirementNames.VALUE_THETA, target.toSpecification(), properties.get()); final ConstantSpreadHorizonThetaCalculator calculator = ConstantSpreadHorizonThetaCalculator.getInstance(); final MultipleCurrencyAmount theta = calculator.getTheta(definition, now, allCurveNames, yieldCurves, DAYS_TO_MOVE_FORWARD); return Collections.singleton(new ComputedValue(spec, theta)); }
@Override protected PresentValueNodeSensitivityCalculator getNodeSensitivityCalculator( final ValueRequirement desiredValue) { final Double cutoff = Double.parseDouble( desiredValue.getConstraint(SABRRightExtrapolationFunction.PROPERTY_CUTOFF_STRIKE)); final Double mu = Double.parseDouble( desiredValue.getConstraint( SABRRightExtrapolationFunction.PROPERTY_TAIL_THICKNESS_PARAMETER)); return PresentValueNodeSensitivityCalculator.using( new PresentValueCurveSensitivitySABRExtrapolationCalculator(cutoff, mu)); }
private ValueProperties getResultProperties(final ValueRequirement desiredValue) { return createValueProperties() .with( ValuePropertyNames.SAMPLING_PERIOD, desiredValue.getConstraint(ValuePropertyNames.SAMPLING_PERIOD)) .with( ValuePropertyNames.SCHEDULE_CALCULATOR, desiredValue.getConstraint(ValuePropertyNames.SCHEDULE_CALCULATOR)) .with( ValuePropertyNames.SAMPLING_FUNCTION, desiredValue.getConstraint(ValuePropertyNames.SAMPLING_FUNCTION)) .with( ValuePropertyNames.RETURN_CALCULATOR, desiredValue.getConstraint(ValuePropertyNames.RETURN_CALCULATOR)) .with( ValuePropertyNames.STD_DEV_CALCULATOR, desiredValue.getConstraint(ValuePropertyNames.STD_DEV_CALCULATOR)) .with( ValuePropertyNames.EXCESS_RETURN_CALCULATOR, desiredValue.getConstraint(ValuePropertyNames.EXCESS_RETURN_CALCULATOR)) .with( ValuePropertyNames.COVARIANCE_CALCULATOR, desiredValue.getConstraint(ValuePropertyNames.COVARIANCE_CALCULATOR)) .with( ValuePropertyNames.VARIANCE_CALCULATOR, desiredValue.getConstraint(ValuePropertyNames.VARIANCE_CALCULATOR)) .get(); }
@Override protected LocalDateDoubleTimeSeries getReturnSeries( LocalDateDoubleTimeSeries ts, ValueRequirement desiredValue) { LocalDateDoubleTimeSeries differenceSeries = super.getReturnSeries(ts, desiredValue); double lambda = Double.parseDouble( desiredValue.getConstraint( VolatilityWeightingFunctionUtils.VOLATILITY_WEIGHTING_LAMBDA_PROPERTY)); TimeSeriesWeightedVolatilityOperator weightedVol = new TimeSeriesWeightedVolatilityOperator(lambda); LocalDateDoubleTimeSeries weightedVolSeries = (LocalDateDoubleTimeSeries) weightedVol.evaluate(ts); int n = weightedVolSeries.size(); double endDateWeightedVol = weightedVolSeries.getLatestValueFast(); double[] volWeightedDifferences = new double[n]; for (int i = 0; i < n; i++) { System.out.println( differenceSeries.getTimeAtIndex(i) + "," + differenceSeries.getValueAtIndexFast(i) + "," + weightedVolSeries.getValueAtIndexFast(i)); volWeightedDifferences[i] = differenceSeries.getValueAtIndexFast(i) * endDateWeightedVol / weightedVolSeries.getValueAtIndexFast(i); } LocalDateDoubleTimeSeries volWeightedDifferenceSeries = ImmutableLocalDateDoubleTimeSeries.of( weightedVolSeries.timesArrayFast(), volWeightedDifferences); return volWeightedDifferenceSeries; }
@Override protected Object getResult( final InstrumentDerivative derivative, final SABRInterestRateDataBundle data, final ValueRequirement desiredValue) { final Double cutoff = Double.parseDouble( desiredValue.getConstraint(SABRRightExtrapolationFunction.PROPERTY_CUTOFF_STRIKE)); final Double mu = Double.parseDouble( desiredValue.getConstraint( SABRRightExtrapolationFunction.PROPERTY_TAIL_THICKNESS_PARAMETER)); final PresentValueSABRSensitivitySABRRightExtrapolationCalculator calculator = new PresentValueSABRSensitivitySABRRightExtrapolationCalculator(cutoff, mu); return getResultAsMatrix(derivative.accept(calculator, data)); }
@SuppressWarnings("unchecked") @Override public Set<ComputedValue> execute( final FunctionExecutionContext executionContext, final FunctionInputs inputs, final ComputationTarget target, final Set<ValueRequirement> desiredValues) { final HistoricalTimeSeriesSource timeSeriesSource = OpenGammaExecutionContext.getHistoricalTimeSeriesSource(executionContext); final ValueRequirement desiredValue = desiredValues.iterator().next(); Object value = timeSeriesSource.getLatestDataPoint(target.getUniqueId()); if (value == null) { value = MissingMarketDataSentinel.getInstance(); } else { final String adjusterString = desiredValue.getConstraint(HistoricalTimeSeriesFunctionUtils.ADJUST_PROPERTY); final HistoricalTimeSeriesAdjustment htsa = HistoricalTimeSeriesAdjustment.parse(adjusterString); value = htsa.adjust(((Pair<LocalDate, Double>) value).getValue()); } return Collections.singleton( new ComputedValue( new ValueSpecification( desiredValue.getValueName(), desiredValue.getTargetSpecification(), desiredValue.getConstraints()), value)); }
@Override public Set<ComputedValue> execute( final FunctionExecutionContext executionContext, final FunctionInputs inputs, final ComputationTarget target, final Set<ValueRequirement> desiredValues) { final ValueRequirement desiredValue = desiredValues.iterator().next(); final String surfaceName = desiredValue.getConstraint(SURFACE); final Object interpolatorObject = inputs.getValue(getInterpolatorRequirement(target, desiredValue)); if (interpolatorObject == null) { throw new OpenGammaRuntimeException("Could not get volatility surface interpolator"); } final VolatilitySurfaceInterpolator surfaceInterpolator = (VolatilitySurfaceInterpolator) interpolatorObject; final SmileSurfaceDataBundle data = getData( inputs, getVolatilityDataRequirement( target, surfaceName, getInstrumentType(), getSurfaceQuoteType(), getSurfaceQuoteUnits()), getForwardCurveRequirement(target, desiredValue)); final BlackVolatilitySurfaceMoneyness impliedVolatilitySurface = surfaceInterpolator.getVolatilitySurface(data); final ValueProperties properties = getResultProperties(desiredValue); final ValueSpecification spec = new ValueSpecification( ValueRequirementNames.BLACK_VOLATILITY_SURFACE, target.toSpecification(), properties); return Collections.singleton(new ComputedValue(spec, impliedVolatilitySurface)); }
@Override protected ValueProperties.Builder getResultProperties( final ComputationTarget target, final ValueRequirement desiredValue) { final String daysForward = desiredValue.getConstraint(PROPERTY_DAYS_TO_MOVE_FORWARD); final ValueProperties.Builder properties = super.getResultProperties(target, desiredValue) .with(PROPERTY_THETA_CALCULATION_METHOD, THETA_CONSTANT_SPREAD) .with(PROPERTY_DAYS_TO_MOVE_FORWARD, daysForward); return properties; }
@Override public Set<ValueSpecification> getResults( final FunctionCompilationContext context, final ComputationTarget target, final Map<ValueSpecification, ValueRequirement> inputs) { if (inputs.size() == 1) { final ValueSpecification input = Iterables.getOnlyElement(inputs.keySet()); if (ValueRequirementNames.PNL_SERIES.equals(input.getValueName())) { return Collections.singleton(input); } } final FXForwardSecurity security = (FXForwardSecurity) target.getPosition().getSecurity(); final CurrencyPair currencyPair = _currencyPairs.getCurrencyPair(security.getPayCurrency(), security.getReceiveCurrency()); if (currencyPair == null) { return null; } final Currency currencyBase = currencyPair.getBase(); String resultCurrency = null; final ValueProperties.Builder builder = createValueProperties(); for (final Map.Entry<ValueSpecification, ValueRequirement> entry : inputs.entrySet()) { final ValueSpecification inputSpec = entry.getKey(); final ValueRequirement inputReq = entry.getValue(); if (inputReq.getValueName().equals(RETURN_SERIES)) { final Set<String> resultCurrencies = inputReq.getConstraints().getValues(CURRENCY); if (resultCurrencies != null && resultCurrencies.size() == 1) { resultCurrency = inputReq.getConstraint(CURRENCY); } else { resultCurrency = currencyBase.getCode(); } } for (final String propertyName : inputSpec.getProperties().getProperties()) { if (ValuePropertyNames.FUNCTION.equals(propertyName)) { continue; } final Set<String> values = inputSpec.getProperties().getValues(propertyName); if (values == null || values.isEmpty()) { builder.withAny(propertyName); } else { builder.with(propertyName, values); } } } if (resultCurrency == null) { return null; } builder .with(ValuePropertyNames.CURRENCY, resultCurrency) .with( ValuePropertyNames.PROPERTY_PNL_CONTRIBUTIONS, ValueRequirementNames.FX_CURRENCY_EXPOSURE); return ImmutableSet.of( new ValueSpecification( ValueRequirementNames.PNL_SERIES, target.toSpecification(), builder.get())); }
@Override public Set<ComputedValue> execute( final FunctionExecutionContext executionContext, final FunctionInputs inputs, final ComputationTarget target, final Set<ValueRequirement> desiredValues) { final ValueRequirement desiredValue = Iterables.getOnlyElement(desiredValues); final String curveName = desiredValue.getConstraint(ValuePropertyNames.CURVE); final String curveCalculationConfig = desiredValue.getConstraint(ValuePropertyNames.CURVE_CALCULATION_CONFIG); // 1. Get the expiry _time_ from the trade final EquityVarianceSwapSecurity security = (EquityVarianceSwapSecurity) target.getSecurity(); final double expiry = TimeCalculator.getTimeBetween( executionContext.getValuationClock().zonedDateTime(), security.getLastObservationDate()); // 2. Get the discount curve and spot value final Object discountObject = inputs.getValue(getDiscountRequirement(security, curveName, curveCalculationConfig)); if (discountObject == null) { throw new OpenGammaRuntimeException("Could not get Discount Curve"); } final YieldAndDiscountCurve discountCurve = (YieldAndDiscountCurve) discountObject; final Object spotObject = inputs.getValue(getSpotRequirement(security)); if (spotObject == null) { throw new OpenGammaRuntimeException("Could not get Underlying's Spot value"); } final double spot = (Double) spotObject; // 3. Compute the forward final double discountFactor = discountCurve.getDiscountFactor(expiry); Validate.isTrue( discountFactor != 0, "The discount curve has returned a zero value for a discount bond. Check rates."); final double forward = spot / discountFactor; final ValueSpecification valueSpec = getValueSpecification(security); return Collections.singleton(new ComputedValue(valueSpec, forward)); }
@Override protected ValueProperties.Builder getResultProperties( final ComputationTarget target, final ValueRequirement desiredValue, final CurrencyPair baseQuotePair) { final String daysForward = desiredValue.getConstraint(PROPERTY_DAYS_TO_MOVE_FORWARD); final ValueProperties.Builder properties = super.getResultProperties(target, desiredValue, baseQuotePair); properties .with(PROPERTY_THETA_CALCULATION_METHOD, THETA_FORWARD_SLIDE_YIELD_CURVES) .with(PROPERTY_DAYS_TO_MOVE_FORWARD, daysForward); return properties; }
@Override protected ValueProperties.Builder createValueProperties( final ComputationTarget target, final ValueRequirement desiredValue) { final String cubeDefinitionName = desiredValue.getConstraint(SurfaceAndCubePropertyNames.PROPERTY_CUBE_DEFINITION); final String cubeSpecificationName = desiredValue.getConstraint(SurfaceAndCubePropertyNames.PROPERTY_CUBE_SPECIFICATION); final String surfaceDefinitionName = desiredValue.getConstraint(SurfaceAndCubePropertyNames.PROPERTY_SURFACE_DEFINITION); final String surfaceSpecificationName = desiredValue.getConstraint(SurfaceAndCubePropertyNames.PROPERTY_SURFACE_SPECIFICATION); final String currency = FinancialSecurityUtils.getCurrency(target.getSecurity()).getCode(); final String curveCalculationConfig = desiredValue.getConstraint(ValuePropertyNames.CURVE_CALCULATION_CONFIG); final String fittingMethod = desiredValue.getConstraint(SmileFittingPropertyNamesAndValues.PROPERTY_FITTING_METHOD); final String curveName = desiredValue.getConstraint(ValuePropertyNames.CURVE); final String cutoff = desiredValue.getConstraint(SABRRightExtrapolationFunction.PROPERTY_CUTOFF_STRIKE); final String mu = desiredValue.getConstraint( SABRRightExtrapolationFunction.PROPERTY_TAIL_THICKNESS_PARAMETER); return createValueProperties() .with(ValuePropertyNames.CURRENCY, currency) .with(ValuePropertyNames.CURVE_CURRENCY, currency) .with(ValuePropertyNames.CURVE_CALCULATION_CONFIG, curveCalculationConfig) .with(ValuePropertyNames.CURVE, curveName) .with(SurfaceAndCubePropertyNames.PROPERTY_CUBE_DEFINITION, cubeDefinitionName) .with(SurfaceAndCubePropertyNames.PROPERTY_CUBE_SPECIFICATION, cubeSpecificationName) .with(SurfaceAndCubePropertyNames.PROPERTY_SURFACE_DEFINITION, surfaceDefinitionName) .with(SurfaceAndCubePropertyNames.PROPERTY_SURFACE_SPECIFICATION, surfaceSpecificationName) .with(SABRRightExtrapolationFunction.PROPERTY_CUTOFF_STRIKE, cutoff) .with(SABRRightExtrapolationFunction.PROPERTY_TAIL_THICKNESS_PARAMETER, mu) .with(SmileFittingPropertyNamesAndValues.PROPERTY_FITTING_METHOD, fittingMethod) .with( SmileFittingPropertyNamesAndValues.PROPERTY_VOLATILITY_MODEL, SmileFittingPropertyNamesAndValues.SABR) .with(ValuePropertyNames.CALCULATION_METHOD, SABRFunction.SABR_RIGHT_EXTRAPOLATION); }
@Override public Set<ComputedValue> execute( final FunctionExecutionContext executionContext, final FunctionInputs inputs, final ComputationTarget target, final Set<ValueRequirement> desiredValues) { final FinancialSecurity security = (FinancialSecurity) target.getSecurity(); final Currency currency = FinancialSecurityUtils.getCurrency(security); final Clock snapshotClock = executionContext.getValuationClock(); final ZonedDateTime now = snapshotClock.zonedDateTime(); final HistoricalTimeSeriesBundle timeSeries = HistoricalTimeSeriesFunctionUtils.getHistoricalTimeSeriesInputs(executionContext, inputs); final ValueRequirement desiredValue = desiredValues.iterator().next(); final String curveCalculationConfigName = desiredValue.getConstraint(ValuePropertyNames.CURVE_CALCULATION_CONFIG); final ConfigSource configSource = OpenGammaExecutionContext.getConfigSource(executionContext); final ConfigDBCurveCalculationConfigSource curveCalculationConfigSource = new ConfigDBCurveCalculationConfigSource(configSource); final MultiCurveCalculationConfig curveCalculationConfig = curveCalculationConfigSource.getConfig(curveCalculationConfigName); if (curveCalculationConfig == null) { throw new OpenGammaRuntimeException( "Could not find curve calculation configuration named " + curveCalculationConfigName); } final String[] curveNames = curveCalculationConfig.getYieldCurveNames(); final String[] yieldCurveNames = curveNames.length == 1 ? new String[] {curveNames[0], curveNames[0]} : curveNames; final String[] curveNamesForSecurity = FixedIncomeInstrumentCurveExposureHelper.getCurveNamesForSecurity( security, yieldCurveNames[0], yieldCurveNames[1]); final YieldCurveBundle bundle = YieldCurveFunctionUtils.getAllYieldCurves( inputs, curveCalculationConfig, curveCalculationConfigSource); final InstrumentDefinition<?> definition = security.accept(_visitor); if (definition == null) { throw new OpenGammaRuntimeException("Definition for security " + security + " was null"); } final InstrumentDerivative derivative = getDerivative( security, now, timeSeries, curveNamesForSecurity, definition, _definitionConverter); return getComputedValues( derivative, bundle, security, target, curveCalculationConfigName, currency.getCode()); }
@Override public Set<ComputedValue> execute( final FunctionExecutionContext context, final FunctionInputs inputs, final ComputationTarget target, final Set<ValueRequirement> desiredValues) throws AsynchronousExecution { final MultipleCurrencyParameterSensitivity sensitivities = (MultipleCurrencyParameterSensitivity) inputs.getValue(BLOCK_CURVE_SENSITIVITIES); final ValueRequirement desiredValue = desiredValues.iterator().next(); final ValueProperties properties = desiredValue.getConstraints(); final String desiredCurveName = desiredValue.getConstraint(CURVE); final Map<Pair<String, Currency>, DoubleMatrix1D> entries = sensitivities.getSensitivities(); final Set<ComputedValue> results = new HashSet<>(); for (final Map.Entry<Pair<String, Currency>, DoubleMatrix1D> entry : entries.entrySet()) { final String curveName = entry.getKey().getFirst(); if (desiredCurveName.equals(curveName)) { final ValueProperties curveSpecificProperties = properties.copy().withoutAny(CURVE).with(CURVE, curveName).get(); final CurveDefinition curveDefinition = (CurveDefinition) inputs.getValue( new ValueRequirement( CURVE_DEFINITION, ComputationTargetSpecification.NULL, ValueProperties.builder().with(CURVE, curveName).get())); final DoubleLabelledMatrix1D ycns = MultiCurveUtils.getLabelledMatrix(entry.getValue(), curveDefinition); final ValueSpecification spec = new ValueSpecification( YIELD_CURVE_NODE_SENSITIVITIES, target.toSpecification(), curveSpecificProperties); results.add(new ComputedValue(spec, ycns)); return results; } } s_logger.info( "Could not get sensitivities to " + desiredCurveName + " for " + target.getName()); return Collections.emptySet(); }
public static ForexOptionDataBundle<?> buildMarketBundle( final ZonedDateTime now, final FunctionInputs inputs, final ComputationTarget target, final Set<ValueRequirement> desiredValues) { final FinancialSecurity security = (FinancialSecurity) target.getSecurity(); final Currency putCurrency = security.accept(ForexVisitors.getPutCurrencyVisitor()); final Currency callCurrency = security.accept(ForexVisitors.getCallCurrencyVisitor()); if (now.isAfter(security.accept(ForexVisitors.getExpiryVisitor()))) { throw new OpenGammaRuntimeException( "FX option " + putCurrency.getCode() + "/" + callCurrency + " has expired"); } final ValueRequirement desiredValue = desiredValues.iterator().next(); final String putCurveName = desiredValue.getConstraint(PUT_CURVE); final String callCurveName = desiredValue.getConstraint(CALL_CURVE); final String putCurveConfig = desiredValue.getConstraint(PUT_CURVE_CALC_CONFIG); final String callCurveConfig = desiredValue.getConstraint(CALL_CURVE_CALC_CONFIG); final Object baseQuotePairsObject = inputs.getValue(ValueRequirementNames.CURRENCY_PAIRS); if (baseQuotePairsObject == null) { throw new OpenGammaRuntimeException("Could not get base/quote pair data"); } final CurrencyPairs baseQuotePairs = (CurrencyPairs) baseQuotePairsObject; final String fullPutCurveName = putCurveName + "_" + putCurrency.getCode(); final String fullCallCurveName = callCurveName + "_" + callCurrency.getCode(); final YieldAndDiscountCurve putFundingCurve = getCurveForCurrency(inputs, putCurrency, putCurveName, putCurveConfig); final YieldAndDiscountCurve callFundingCurve = getCurveForCurrency(inputs, callCurrency, callCurveName, callCurveConfig); final YieldAndDiscountCurve[] curves; final Map<String, Currency> curveCurrency = new HashMap<>(); curveCurrency.put(fullPutCurveName, putCurrency); curveCurrency.put(fullCallCurveName, callCurrency); final String[] allCurveNames; final Currency ccy1; final Currency ccy2; final Object spotObject = inputs.getValue(ValueRequirementNames.SPOT_RATE); if (spotObject == null) { throw new OpenGammaRuntimeException("Could not get spot requirement"); } double spot = (Double) spotObject; final CurrencyPair baseQuotePair = baseQuotePairs.getCurrencyPair(putCurrency, callCurrency); if (baseQuotePair == null) { throw new OpenGammaRuntimeException( "Could not get base/quote pair for currency pair (" + putCurrency + ", " + callCurrency + ")"); } if (baseQuotePair .getBase() .equals(putCurrency)) { // To get Base/quote in market standard order. ccy1 = putCurrency; ccy2 = callCurrency; curves = new YieldAndDiscountCurve[] {putFundingCurve, callFundingCurve}; allCurveNames = new String[] {fullPutCurveName, fullCallCurveName}; } else { curves = new YieldAndDiscountCurve[] {callFundingCurve, putFundingCurve}; allCurveNames = new String[] {fullCallCurveName, fullPutCurveName}; ccy1 = callCurrency; ccy2 = putCurrency; spot = 1. / spot; } final YieldCurveBundle yieldCurves = new YieldCurveBundle(allCurveNames, curves); final Object volatilitySurfaceObject = inputs.getValue(ValueRequirementNames.STANDARD_VOLATILITY_SURFACE_DATA); if (volatilitySurfaceObject == null) { throw new OpenGammaRuntimeException("Could not get volatility surface data"); } final FXMatrix fxMatrix = new FXMatrix(ccy1, ccy2, spot); final YieldCurveBundle curvesWithFX = new YieldCurveBundle(fxMatrix, curveCurrency, yieldCurves.getCurvesMap()); final Pair<Currency, Currency> currencyPair = Pair.of(ccy1, ccy2); if (volatilitySurfaceObject instanceof SmileDeltaTermStructureParametersStrikeInterpolation) { final SmileDeltaTermStructureParametersStrikeInterpolation smiles = (SmileDeltaTermStructureParametersStrikeInterpolation) volatilitySurfaceObject; final SmileDeltaTermStructureDataBundle smileBundle = new SmileDeltaTermStructureDataBundle(curvesWithFX, smiles, currencyPair); return smileBundle; } final BlackForexTermStructureParameters termStructure = (BlackForexTermStructureParameters) volatilitySurfaceObject; final YieldCurveWithBlackForexTermStructureBundle flatData = new YieldCurveWithBlackForexTermStructureBundle(curvesWithFX, termStructure, currencyPair); return flatData; }
@Override public Set<ComputedValue> execute( final FunctionExecutionContext executionContext, final FunctionInputs inputs, final ComputationTarget target, final Set<ValueRequirement> desiredValues) { final Clock snapshotClock = executionContext.getValuationClock(); final ZonedDateTime now = ZonedDateTime.now(snapshotClock); final SecuritySource securitySource = OpenGammaExecutionContext.getSecuritySource(executionContext); final SwaptionSecurity security = (SwaptionSecurity) target.getSecurity(); final ValueRequirement desiredValue = desiredValues.iterator().next(); final Currency currency = FinancialSecurityUtils.getCurrency(security); final String surfaceName = desiredValue.getConstraint(ValuePropertyNames.SURFACE); final String curveCalculationConfigName = desiredValue.getConstraint(ValuePropertyNames.CURVE_CALCULATION_CONFIG); final ConfigSource configSource = OpenGammaExecutionContext.getConfigSource(executionContext); final ConfigDBCurveCalculationConfigSource curveCalculationConfigSource = new ConfigDBCurveCalculationConfigSource(configSource); final MultiCurveCalculationConfig curveCalculationConfig = curveCalculationConfigSource.getConfig(curveCalculationConfigName); if (curveCalculationConfig == null) { throw new OpenGammaRuntimeException( "Could not find curve calculation configuration named " + curveCalculationConfigName); } String[] curveNames = curveCalculationConfig.getYieldCurveNames(); // TODO if (curveNames.length == 1) { curveNames = new String[] {curveNames[0], curveNames[0]}; } final String[] fullCurveNames = new String[curveNames.length]; for (int i = 0; i < curveNames.length; i++) { fullCurveNames[i] = curveNames[i] + "_" + currency.getCode(); } final YieldCurveBundle curves = YieldCurveFunctionUtils.getYieldCurves(inputs, curveCalculationConfig); final Object volatilitySurfaceObject = inputs.getValue(getVolatilityRequirement(surfaceName, currency)); if (volatilitySurfaceObject == null) { throw new OpenGammaRuntimeException("Could not get volatility surface"); } final VolatilitySurface volatilitySurface = (VolatilitySurface) volatilitySurfaceObject; if (!(volatilitySurface.getSurface() instanceof InterpolatedDoublesSurface)) { throw new OpenGammaRuntimeException( "Expecting an InterpolatedDoublesSurface; got " + volatilitySurface.getSurface().getClass()); } final InstrumentDefinition<?> definition = security.accept(_visitor); final HistoricalTimeSeriesBundle timeSeries = HistoricalTimeSeriesFunctionUtils.getHistoricalTimeSeriesInputs(executionContext, inputs); final InstrumentDerivative swaption = _definitionConverter.convert(security, definition, now, fullCurveNames, timeSeries); final ValueProperties properties = getResultProperties(currency.getCode(), curveCalculationConfigName, surfaceName); final ValueSpecification spec = new ValueSpecification(_valueRequirementName, target.toSpecification(), properties); final BlackFlatSwaptionParameters parameters = new BlackFlatSwaptionParameters( volatilitySurface.getSurface(), SwaptionUtils.getSwapGenerator(security, definition, securitySource)); final YieldCurveWithBlackSwaptionBundle data = new YieldCurveWithBlackSwaptionBundle(parameters, curves); return getResult(swaption, data, spec); }
@Override public Set<ComputedValue> execute( final FunctionExecutionContext executionContext, final FunctionInputs inputs, final ComputationTarget target, final Set<ValueRequirement> desiredValues) { final Clock snapshotClock = executionContext.getValuationClock(); final ZonedDateTime now = ZonedDateTime.now(snapshotClock); final FinancialSecurity security = (FinancialSecurity) target.getSecurity(); final Currency payCurrency = security.accept(ForexVisitors.getPayCurrencyVisitor()); final Currency receiveCurrency = security.accept(ForexVisitors.getReceiveCurrencyVisitor()); if (now.isAfter(security.accept(ForexVisitors.getExpiryVisitor()))) { throw new OpenGammaRuntimeException( "FX forward " + payCurrency.getCode() + "/" + receiveCurrency + " has expired"); } final ValueRequirement desiredValue = desiredValues.iterator().next(); final String payCurveName = desiredValue.getConstraint(ValuePropertyNames.PAY_CURVE); final String receiveCurveName = desiredValue.getConstraint(ValuePropertyNames.RECEIVE_CURVE); final String payCurveConfig = desiredValue.getConstraint(ValuePropertyNames.PAY_CURVE_CALCULATION_CONFIG); final String receiveCurveConfig = desiredValue.getConstraint(ValuePropertyNames.RECEIVE_CURVE_CALCULATION_CONFIG); final String daysForward = desiredValue.getConstraint(PROPERTY_DAYS_TO_MOVE_FORWARD); final String fullPayCurveName = payCurveName + "_" + payCurrency.getCode(); final String fullReceiveCurveName = receiveCurveName + "_" + receiveCurrency.getCode(); final YieldAndDiscountCurve payFundingCurve = getPayCurve(inputs, payCurrency, payCurveName, payCurveConfig); final YieldAndDiscountCurve receiveFundingCurve = getReceiveCurve(inputs, receiveCurrency, receiveCurveName, receiveCurveConfig); final YieldAndDiscountCurve[] curves; final Map<String, Currency> curveCurrency = new HashMap<>(); curveCurrency.put(fullPayCurveName, payCurrency); curveCurrency.put(fullReceiveCurveName, receiveCurrency); final String[] allCurveNames; final Object baseQuotePairsObject = inputs.getValue(ValueRequirementNames.CURRENCY_PAIRS); if (baseQuotePairsObject == null) { throw new OpenGammaRuntimeException("Could not get base/quote pair data"); } final CurrencyPairs baseQuotePairs = (CurrencyPairs) baseQuotePairsObject; final CurrencyPair baseQuotePair = baseQuotePairs.getCurrencyPair(payCurrency, receiveCurrency); if (baseQuotePair == null) { throw new OpenGammaRuntimeException( "Could not get base/quote pair for currency pair (" + payCurrency + ", " + receiveCurrency + ")"); } if (baseQuotePair .getBase() .equals(payCurrency)) { // To get Base/quote in market standard order. curves = new YieldAndDiscountCurve[] {payFundingCurve, receiveFundingCurve}; allCurveNames = new String[] {fullPayCurveName, fullReceiveCurveName}; } else { curves = new YieldAndDiscountCurve[] {receiveFundingCurve, payFundingCurve}; allCurveNames = new String[] {fullReceiveCurveName, fullPayCurveName}; } final ForexSecurityConverter converter = new ForexSecurityConverter(baseQuotePairs); final ForexDefinition definition = (ForexDefinition) security.accept(converter); final YieldCurveBundle yieldCurves = new YieldCurveBundle(allCurveNames, curves); final ValueProperties.Builder properties = getResultProperties(target, desiredValue); final ValueSpecification spec = new ValueSpecification( getValueRequirementName(), target.toSpecification(), properties.get()); final ConstantSpreadHorizonThetaCalculator calculator = ConstantSpreadHorizonThetaCalculator.getInstance(); final MultipleCurrencyAmount theta = calculator.getTheta( definition, now, allCurveNames, yieldCurves, Integer.parseInt(daysForward)); return Collections.singleton(new ComputedValue(spec, theta)); }
@Override public Set<ComputedValue> execute( final FunctionExecutionContext executionContext, final FunctionInputs inputs, final ComputationTarget target, final Set<ValueRequirement> desiredValues) { final Clock snapshotClock = executionContext.getValuationClock(); final ZonedDateTime now = snapshotClock.zonedDateTime(); final SecuritySource securitySource = OpenGammaExecutionContext.getSecuritySource(executionContext); final SwaptionSecurity security = (SwaptionSecurity) target.getSecurity(); final ValueRequirement desiredValue = desiredValues.iterator().next(); final Currency currency = FinancialSecurityUtils.getCurrency(security); final String forwardCurveName = desiredValue.getConstraint(YieldCurveFunction.PROPERTY_FORWARD_CURVE); final String fundingCurveName = desiredValue.getConstraint(YieldCurveFunction.PROPERTY_FUNDING_CURVE); final String curveCalculationMethod = desiredValue.getConstraint(ValuePropertyNames.CURVE_CALCULATION_METHOD); final String surfaceName = desiredValue.getConstraint(ValuePropertyNames.SURFACE); final Object forwardCurveObject = inputs.getValue( YieldCurveFunction.getCurveRequirement( currency, forwardCurveName, forwardCurveName, fundingCurveName, curveCalculationMethod)); if (forwardCurveObject == null) { throw new OpenGammaRuntimeException("Could not get forward curve"); } final Object fundingCurveObject = inputs.getValue( YieldCurveFunction.getCurveRequirement( currency, fundingCurveName, forwardCurveName, fundingCurveName, curveCalculationMethod)); if (fundingCurveObject == null) { throw new OpenGammaRuntimeException("Could not get funding curve"); } final Object volatilitySurfaceObject = inputs.getValue(getVolatilityRequirement(surfaceName, currency)); if (volatilitySurfaceObject == null) { throw new OpenGammaRuntimeException("Could not get volatility surface"); } final VolatilitySurface volatilitySurface = (VolatilitySurface) volatilitySurfaceObject; if (!(volatilitySurface.getSurface() instanceof InterpolatedDoublesSurface)) { throw new OpenGammaRuntimeException( "Expecting an InterpolatedDoublesSurface; got " + volatilitySurface.getSurface().getClass()); } final YieldAndDiscountCurve forwardCurve = (YieldAndDiscountCurve) forwardCurveObject; final YieldAndDiscountCurve fundingCurve = (YieldAndDiscountCurve) fundingCurveObject; final InstrumentDefinition<?> definition = security.accept(_visitor); final InstrumentDerivative swaption = definition.toDerivative(now, new String[] {fundingCurveName, forwardCurveName}); final ValueProperties properties = getResultProperties( currency.getCode(), forwardCurveName, fundingCurveName, curveCalculationMethod, surfaceName); final ValueSpecification spec = new ValueSpecification(_valueRequirementName, target.toSpecification(), properties); final YieldCurveBundle curves = new YieldCurveBundle( new String[] {fundingCurveName, forwardCurveName}, new YieldAndDiscountCurve[] {fundingCurve, forwardCurve}); final BlackSwaptionParameters parameters = new BlackSwaptionParameters( volatilitySurface.getSurface(), SwaptionUtils.getSwapGenerator(security, definition, securitySource)); final YieldCurveWithBlackSwaptionBundle data = new YieldCurveWithBlackSwaptionBundle(parameters, curves); return getResult(swaption, data, spec); }
@Override public Set<ValueSpecification> getResults( final FunctionCompilationContext context, final ComputationTarget target, final Map<ValueSpecification, ValueRequirement> inputs) { String currencyPairConfigName = null; String payCurveName = null; String payCurveCalculationConfig = null; String receiveCurveName = null; String receiveCurveCalculationConfig = null; String daysForward = null; for (final Map.Entry<ValueSpecification, ValueRequirement> entry : inputs.entrySet()) { final ValueSpecification specification = entry.getKey(); final ValueRequirement requirement = entry.getValue(); if (specification.getValueName().equals(ValueRequirementNames.CURRENCY_PAIRS)) { currencyPairConfigName = specification.getProperty(CurrencyPairsFunction.CURRENCY_PAIRS_NAME); daysForward = requirement.getConstraint(PROPERTY_DAYS_TO_MOVE_FORWARD); } else if (requirement.getValueName().equals(ValueRequirementNames.YIELD_CURVE)) { final ValueProperties constraints = requirement.getConstraints(); if (constraints.getProperties().contains(ValuePropertyNames.PAY_CURVE)) { payCurveName = Iterables.getOnlyElement(constraints.getValues(ValuePropertyNames.CURVE)); payCurveCalculationConfig = Iterables.getOnlyElement( constraints.getValues(ValuePropertyNames.CURVE_CALCULATION_CONFIG)); } else if (constraints.getProperties().contains(ValuePropertyNames.RECEIVE_CURVE)) { receiveCurveName = Iterables.getOnlyElement(constraints.getValues(ValuePropertyNames.CURVE)); receiveCurveCalculationConfig = Iterables.getOnlyElement( constraints.getValues(ValuePropertyNames.CURVE_CALCULATION_CONFIG)); } } } assert currencyPairConfigName != null; final CurrencyPairs baseQuotePairs = OpenGammaCompilationContext.getCurrencyPairsSource(context) .getCurrencyPairs(currencyPairConfigName); final FinancialSecurity security = (FinancialSecurity) target.getSecurity(); final Currency payCurrency = security.accept(ForexVisitors.getPayCurrencyVisitor()); final Currency receiveCurrency = security.accept(ForexVisitors.getReceiveCurrencyVisitor()); final CurrencyPair baseQuotePair = baseQuotePairs.getCurrencyPair(payCurrency, receiveCurrency); if (baseQuotePair == null) { s_logger.error( "Could not get base/quote pair for currency pair (" + payCurrency + ", " + receiveCurrency + ")"); return null; } final ValueSpecification resultSpec = new ValueSpecification( getValueRequirementName(), target.toSpecification(), getResultProperties( target, payCurveName, receiveCurveName, payCurveCalculationConfig, receiveCurveCalculationConfig, baseQuotePair, daysForward) .get()); return Collections.singleton(resultSpec); }
@Override public Set<ValueRequirement> getRequirements( final FunctionCompilationContext context, final ComputationTarget target, final ValueRequirement desiredValue) { final LegacyVanillaCDSSecurity cds = (LegacyVanillaCDSSecurity) target.getSecurity(); final Currency ccy = cds.getNotional().getCurrency(); final CreditCurveIdentifier isdaIdentifier = getISDACurveIdentifier(cds); final CreditCurveIdentifier spreadIdentifier = getSpreadCurveIdentifier(cds); final String isdaOffset = desiredValue.getConstraint(ISDAFunctionConstants.ISDA_CURVE_OFFSET); if (isdaOffset == null) { return null; } final String isdaCurveDate = desiredValue.getConstraint(ISDAFunctionConstants.ISDA_CURVE_DATE); if (isdaCurveDate == null) { return null; } final String isdaCurveMethod = desiredValue.getConstraint(ISDAFunctionConstants.ISDA_IMPLEMENTATION); if (isdaCurveMethod == null) { return null; } // isda curve final ValueProperties isdaProperties = ValueProperties.builder() .with(ValuePropertyNames.CURVE, isdaIdentifier.toString()) .with( ValuePropertyNames.CURVE_CALCULATION_METHOD, ISDAFunctionConstants.ISDA_METHOD_NAME) .with(ISDAFunctionConstants.ISDA_CURVE_OFFSET, isdaOffset) .with(ISDAFunctionConstants.ISDA_CURVE_DATE, isdaCurveDate) .with(ISDAFunctionConstants.ISDA_IMPLEMENTATION, isdaCurveMethod) .get(); final ValueRequirement isdaRequirment = new ValueRequirement( ValueRequirementNames.YIELD_CURVE, ComputationTargetType.CURRENCY, ccy.getUniqueId(), isdaProperties); final String quoteConvention = desiredValue.getConstraint(ISDAFunctionConstants.CDS_QUOTE_CONVENTION); if (quoteConvention == null) { return null; } final String bucketTenors = desiredValue.getConstraint(ISDAFunctionConstants.ISDA_BUCKET_TENORS); if (bucketTenors == null) { return null; } // market spreads final ValueProperties spreadProperties = ValueProperties.builder() .with(ISDAFunctionConstants.CDS_QUOTE_CONVENTION, quoteConvention) .with( ValuePropertyNames.CURVE_CALCULATION_METHOD, ISDAFunctionConstants.ISDA_METHOD_NAME) .with(ISDAFunctionConstants.ISDA_CURVE_OFFSET, isdaOffset) .with(ISDAFunctionConstants.ISDA_CURVE_DATE, isdaCurveDate) .with(ISDAFunctionConstants.ISDA_IMPLEMENTATION, isdaCurveMethod) .with(ISDAFunctionConstants.ISDA_BUCKET_TENORS, bucketTenors) .get(); final ValueRequirement spreadRequirment = new ValueRequirement( ValueRequirementNames.BUCKETED_SPREADS, target.toSpecification(), spreadProperties); final ValueRequirement pillarRequirment = new ValueRequirement( ValueRequirementNames.PILLAR_SPREADS, target.toSpecification(), spreadProperties); final ValueRequirement creditCurveRequirement = new ValueRequirement( ValueRequirementNames.HAZARD_RATE_CURVE, target.toSpecification(), spreadProperties); // get individual spread for this cds (ignore business day adjustment on either) final Period period = Period.between( cds.getStartDate().toLocalDate().withDayOfMonth(20), cds.getMaturityDate().toLocalDate().withDayOfMonth(20)); final ValueRequirement cdsSpreadRequirement = new ValueRequirement( MarketDataRequirementNames.MARKET_VALUE, ComputationTargetType.PRIMITIVE, ExternalId.of("Tenor", period.toString())); final CdsRecoveryRateIdentifier recoveryRateIdentifier = cds.accept(new CreditSecurityToRecoveryRateVisitor(context.getSecuritySource())); final ValueRequirement recoveryRateRequirement = new ValueRequirement( "PX_LAST", ComputationTargetType.PRIMITIVE, recoveryRateIdentifier.getExternalId()); return Sets.newHashSet( isdaRequirment, spreadRequirment, cdsSpreadRequirement, creditCurveRequirement, pillarRequirment, recoveryRateRequirement); }
@Override public Set<ComputedValue> execute( final FunctionExecutionContext executionContext, final FunctionInputs inputs, final ComputationTarget target, final Set<ValueRequirement> desiredValues) throws AsynchronousExecution { final ZonedDateTime now = ZonedDateTime.now(executionContext.getValuationClock()); final ValueRequirement requirement = desiredValues.iterator().next(); final ValueProperties properties = requirement.getConstraints().copy().get(); final LegacyVanillaCDSSecurity security = (LegacyVanillaCDSSecurity) target.getSecurity(); // LegacyVanillaCreditDefaultSwapDefinition cds = // _converter.visitLegacyVanillaCDSSecurity(security); final ValueRequirement desiredValue = desiredValues.iterator().next(); // all same constraints final String quoteConventionString = desiredValue.getConstraint(ISDAFunctionConstants.CDS_QUOTE_CONVENTION); final StandardCDSQuotingConvention quoteConvention = StandardCDSQuotingConvention.parse(quoteConventionString); final CdsRecoveryRateIdentifier recoveryRateIdentifier = security.accept( new CreditSecurityToRecoveryRateVisitor(executionContext.getSecuritySource())); Object recoveryRateObject = inputs.getValue( new ValueRequirement( "PX_LAST", ComputationTargetType.PRIMITIVE, recoveryRateIdentifier.getExternalId())); if (recoveryRateObject == null) { throw new OpenGammaRuntimeException("Could not get recovery rate"); // s_logger.warn("Could not get recovery rate, defaulting to 0.4: " + recoveryRateIdentifier); // recoveryRateObject = 0.4; } final double recoveryRate = (Double) recoveryRateObject; // get the isda curve final Object isdaObject = inputs.getValue(ValueRequirementNames.YIELD_CURVE); if (isdaObject == null) { throw new OpenGammaRuntimeException("Couldn't get isda curve"); } final ISDACompliantYieldCurve yieldCurve = (ISDACompliantYieldCurve) isdaObject; // spreads NodalTenorDoubleCurve spreadObject = (NodalTenorDoubleCurve) inputs.getValue(ValueRequirementNames.BUCKETED_SPREADS); if (spreadObject == null) { throw new OpenGammaRuntimeException("Unable to get spreads"); } final double[] spreads = ArrayUtils.toPrimitive(spreadObject.getYData()); // final String pillarString = IMMDateGenerator.isIMMDate(security.getMaturityDate()) ? // requirement.getConstraint(ISDAFunctionConstants.ISDA_BUCKET_TENORS) : // ISDACompliantCreditCurveFunction.NON_IMM_PILLAR_TENORS; final ZonedDateTime[] bucketDates = SpreadCurveFunctions.getPillarDates(now, spreadObject.getXData()); final CDSQuoteConvention[] quotes = SpreadCurveFunctions.getQuotes( security.getMaturityDate(), spreads, security.getParSpread(), quoteConvention, false); // spreads NodalTenorDoubleCurve pillarObject = (NodalTenorDoubleCurve) inputs.getValue(ValueRequirementNames.PILLAR_SPREADS); if (pillarObject == null) { throw new OpenGammaRuntimeException("Unable to get pillars"); } // CDS analytics for credit curve (possible performance improvement if earlier result obtained) // final LegacyVanillaCreditDefaultSwapDefinition curveCDS = cds.withStartDate(now); // security.setStartDate(now); // needed for curve instruments final CDSAnalytic[] bucketCDSs = new CDSAnalytic[bucketDates.length]; for (int i = 0; i < bucketCDSs.length; i++) { // security.setMaturityDate(bucketDates[i]); final CDSAnalyticVisitor visitor = new CDSAnalyticVisitor( now.toLocalDate(), _holidaySource, _regionSource, security.getStartDate().toLocalDate(), bucketDates[i].toLocalDate(), recoveryRate); bucketCDSs[i] = security.accept(visitor); } final ZonedDateTime[] pillarDates = SpreadCurveFunctions.getPillarDates(now, pillarObject.getXData()); final CDSAnalytic[] pillarCDSs = new CDSAnalytic[pillarDates.length]; for (int i = 0; i < pillarCDSs.length; i++) { // security.setMaturityDate(bucketDates[i]); final CDSAnalyticVisitor visitor = new CDSAnalyticVisitor( now.toLocalDate(), _holidaySource, _regionSource, security.getStartDate().toLocalDate(), pillarDates[i].toLocalDate(), recoveryRate); pillarCDSs[i] = security.accept(visitor); } final ISDACompliantCreditCurve creditCurve = (ISDACompliantCreditCurve) inputs.getValue(ValueRequirementNames.HAZARD_RATE_CURVE); if (creditCurve == null) { throw new OpenGammaRuntimeException("Couldnt get credit curve"); } // final CDSAnalytic analytic = CDSAnalyticConverter.create(cds, now.toLocalDate()); final CDSAnalyticVisitor visitor = new CDSAnalyticVisitor(now.toLocalDate(), _holidaySource, _regionSource, recoveryRate); final CDSAnalytic analytic = security.accept(visitor); final BuySellProtection buySellProtection = security.isBuy() ? BuySellProtection.BUY : BuySellProtection.SELL; // final String term = new Tenor(Period.between(security.getStartDate().toLocalDate(), // security.getMaturityDate().toLocalDate())).getPeriod().toString(); // final Double cdsQuoteDouble = (Double) inputs.getValue(new // ValueRequirement(MarketDataRequirementNames.MARKET_VALUE, // ComputationTargetType.PRIMITIVE, ExternalId.of("Tenor", term))); final Double cdsQuoteDouble = (Double) inputs.getValue(MarketDataRequirementNames.MARKET_VALUE); if (cdsQuoteDouble == null) { throw new OpenGammaRuntimeException("Couldn't get spread for " + security); } final CDSQuoteConvention quote = SpreadCurveFunctions.getQuotes( security.getMaturityDate(), new double[] {cdsQuoteDouble}, security.getParSpread(), quoteConvention, true)[0]; boolean isNonIMMFAndFromPUF = !IMMDateLogic.isIMMDate(security.getMaturityDate().toLocalDate()) && quote instanceof PointsUpFront; boolean isNonIMMAndFromSpread = !IMMDateLogic.isIMMDate(security.getMaturityDate().toLocalDate()) && (quote instanceof QuotedSpread || quote instanceof ParSpread); int buySellPremiumFactor = security.isBuy() ? -1 : 1; final double notional = security.getNotional().getAmount(); final double coupon = security.getParSpread() * ONE_BPS; final PointsUpFront puf = getPointsUpfront(quote, buySellProtection, yieldCurve, analytic, creditCurve); final double accruedPremiumPrim = isNonIMMAndFromSpread || isNonIMMFAndFromPUF ? 0 : analytic.getAccruedPremium(coupon); // final double accruedPremium = isNonIMMAndFromSpread || isNonIMMFAndFromPUF ? 0 : // analytic.getAccruedPremium(coupon) * notional * buySellPremiumFactor; final double accruedPremium = isNonIMMAndFromSpread || isNonIMMFAndFromPUF ? 0 : accruedPremiumPrim * notional * buySellPremiumFactor; final int accruedDays = isNonIMMAndFromSpread || isNonIMMFAndFromPUF ? 0 : analytic.getAccuredDays(); final double quotedSpread = getQuotedSpread(quote, puf, buySellProtection, yieldCurve, analytic).getQuotedSpread(); final double upfrontAmount = isNonIMMAndFromSpread ? 0 : getUpfrontAmount(analytic, puf, notional, accruedPremiumPrim, buySellProtection); final double cleanPV = puf.getPointsUpFront() * notional; final double principal = isNonIMMAndFromSpread ? 0 : cleanPV; final double cleanPrice = getCleanPrice(puf); final TenorLabelledMatrix1D bucketedCS01 = getBucketedCS01( analytic, bucketCDSs, spreadObject.getXData(), quote, notional, yieldCurve, creditCurve); final double parallelCS01 = getParallelCS01( quote, analytic, yieldCurve, notional, pillarCDSs, ArrayUtils.toPrimitive(pillarObject.getYData())); final Set<ComputedValue> results = Sets.newHashSetWithExpectedSize(_valueRequirements.length); results.add( new ComputedValue( new ValueSpecification( ValueRequirementNames.ACCRUED_PREMIUM, target.toSpecification(), properties), accruedPremium)); results.add( new ComputedValue( new ValueSpecification( ValueRequirementNames.ACCRUED_DAYS, target.toSpecification(), properties), accruedDays)); results.add( new ComputedValue( new ValueSpecification( ValueRequirementNames.QUOTED_SPREAD, target.toSpecification(), properties), quotedSpread / ONE_BPS)); results.add( new ComputedValue( new ValueSpecification( ValueRequirementNames.UPFRONT_AMOUNT, target.toSpecification(), properties), upfrontAmount)); results.add( new ComputedValue( new ValueSpecification( ValueRequirementNames.DIRTY_PRESENT_VALUE, target.toSpecification(), properties), upfrontAmount)); results.add( new ComputedValue( new ValueSpecification( ValueRequirementNames.CLEAN_PRESENT_VALUE, target.toSpecification(), properties), cleanPV)); results.add( new ComputedValue( new ValueSpecification( ValueRequirementNames.PRINCIPAL, target.toSpecification(), properties), principal)); results.add( new ComputedValue( new ValueSpecification( ValueRequirementNames.CLEAN_PRICE, target.toSpecification(), properties), cleanPrice)); results.add( new ComputedValue( new ValueSpecification( ValueRequirementNames.BUCKETED_CS01, target.toSpecification(), properties), bucketedCS01)); results.add( new ComputedValue( new ValueSpecification( ValueRequirementNames.PARALLEL_CS01, target.toSpecification(), properties), parallelCS01)); results.add( new ComputedValue( new ValueSpecification( ValueRequirementNames.POINTS_UPFRONT, target.toSpecification(), properties), puf.getPointsUpFront())); return results; }
@Override public Set<ComputedValue> execute( final FunctionExecutionContext executionContext, final FunctionInputs inputs, final ComputationTarget target, final Set<ValueRequirement> desiredValues) throws AsynchronousExecution { final Object originalCurveObject = inputs.getValue(YIELD_CURVE); if (originalCurveObject == null) { throw new OpenGammaRuntimeException("Could not get original curve"); } ValueProperties resultCurveProperties = null; String absoluteToleranceName = null; String relativeToleranceName = null; String iterationsName = null; String decompositionName = null; String useFiniteDifferenceName = null; for (final ValueRequirement desiredValue : desiredValues) { if (desiredValue.getValueName().equals(YIELD_CURVE)) { absoluteToleranceName = desiredValue.getConstraint( MultiYieldCurvePropertiesAndDefaults.PROPERTY_ROOT_FINDER_ABSOLUTE_TOLERANCE); relativeToleranceName = desiredValue.getConstraint( MultiYieldCurvePropertiesAndDefaults.PROPERTY_ROOT_FINDER_RELATIVE_TOLERANCE); iterationsName = desiredValue.getConstraint( MultiYieldCurvePropertiesAndDefaults.PROPERTY_ROOT_FINDER_MAX_ITERATIONS); decompositionName = desiredValue.getConstraint( MultiYieldCurvePropertiesAndDefaults.PROPERTY_DECOMPOSITION); useFiniteDifferenceName = desiredValue.getConstraint( MultiYieldCurvePropertiesAndDefaults.PROPERTY_USE_FINITE_DIFFERENCE); resultCurveProperties = desiredValue.getConstraints().copy().get(); break; } } if (resultCurveProperties == null) { throw new OpenGammaRuntimeException("Could not get result curve properties"); } final ValueProperties resultJacobianProperties = resultCurveProperties.withoutAny(CURVE); ZonedDateTime valuationDateTime = executionContext .getValuationTime() .atZone(executionContext.getValuationClock().getZone()); final HolidaySource holidaySource = OpenGammaExecutionContext.getHolidaySource(executionContext); final ConventionSource conventionSource = OpenGammaExecutionContext.getConventionSource(executionContext); final Calendar calendar = CalendarUtils.getCalendar(holidaySource, _currency); final DepositConvention convention = conventionSource.getSingle( ExternalId.of(SCHEME_NAME, getConventionName(_currency, DEPOSIT)), DepositConvention.class); final int spotLag = convention.getSettlementDays(); final ExternalId conventionSettlementRegion = convention.getRegionCalendar(); ZonedDateTime spotDate; if (spotLag == 0 && conventionSettlementRegion == null) { spotDate = valuationDateTime; } else { spotDate = ScheduleCalculator.getAdjustedDate(valuationDateTime, spotLag, calendar); ; } final YieldCurveBundle curves = new YieldCurveBundle(); final String fullYieldCurveName = _originalCurveName + "_" + _currency; curves.setCurve(fullYieldCurveName, (YieldAndDiscountCurve) originalCurveObject); final int n = _impliedDefinition.getStrips().size(); final double[] t = new double[n]; final double[] r = new double[n]; int i = 0; final DayCount dayCount = DayCountFactory.INSTANCE.getDayCount( "Act/360"); // TODO: Get the convention from the curve. final String impliedDepositCurveName = _curveCalculationConfig + "_" + _currency.getCode(); final List<InstrumentDerivative> derivatives = new ArrayList<>(); for (final FixedIncomeStrip strip : _impliedDefinition.getStrips()) { final Tenor tenor = strip.getCurveNodePointTime(); final ZonedDateTime paymentDate = ScheduleCalculator.getAdjustedDate( spotDate, tenor.getPeriod(), MOD_FOL, calendar, true); final double startTime = TimeCalculator.getTimeBetween(valuationDateTime, spotDate); final double endTime = TimeCalculator.getTimeBetween(valuationDateTime, paymentDate); final double accrualFactor = dayCount.getDayCountFraction(spotDate, paymentDate, calendar); final Cash cashFXCurve = new Cash(_currency, startTime, endTime, 1, 0, accrualFactor, fullYieldCurveName); final double parRate = METHOD_CASH.parRate(cashFXCurve, curves); final Cash cashDepositCurve = new Cash(_currency, startTime, endTime, 1, 0, accrualFactor, impliedDepositCurveName); derivatives.add(cashDepositCurve); t[i] = endTime; r[i++] = parRate; } final CombinedInterpolatorExtrapolator interpolator = CombinedInterpolatorExtrapolatorFactory.getInterpolator( _interpolatorName, _leftExtrapolatorName, _rightExtrapolatorName); final double absoluteTolerance = Double.parseDouble(absoluteToleranceName); final double relativeTolerance = Double.parseDouble(relativeToleranceName); final int iterations = Integer.parseInt(iterationsName); final Decomposition<?> decomposition = DecompositionFactory.getDecomposition(decompositionName); final boolean useFiniteDifference = Boolean.parseBoolean(useFiniteDifferenceName); final LinkedHashMap<String, double[]> curveNodes = new LinkedHashMap<>(); final LinkedHashMap<String, Interpolator1D> interpolators = new LinkedHashMap<>(); curveNodes.put(impliedDepositCurveName, t); interpolators.put(impliedDepositCurveName, interpolator); final FXMatrix fxMatrix = new FXMatrix(); final YieldCurveBundle knownCurve = new YieldCurveBundle(); final MultipleYieldCurveFinderDataBundle data = new MultipleYieldCurveFinderDataBundle( derivatives, r, knownCurve, curveNodes, interpolators, useFiniteDifference, fxMatrix); final NewtonVectorRootFinder rootFinder = new BroydenVectorRootFinder( absoluteTolerance, relativeTolerance, iterations, decomposition); final Function1D<DoubleMatrix1D, DoubleMatrix1D> curveCalculator = new MultipleYieldCurveFinderFunction(data, PAR_RATE_CALCULATOR); final Function1D<DoubleMatrix1D, DoubleMatrix2D> jacobianCalculator = new MultipleYieldCurveFinderJacobian(data, PAR_RATE_SENSITIVITY_CALCULATOR); final double[] fittedYields = rootFinder.getRoot(curveCalculator, jacobianCalculator, new DoubleMatrix1D(r)).getData(); final DoubleMatrix2D jacobianMatrix = jacobianCalculator.evaluate(new DoubleMatrix1D(fittedYields)); final YieldCurve impliedDepositCurve = new YieldCurve( impliedDepositCurveName, InterpolatedDoublesCurve.from(t, fittedYields, interpolator)); final ValueSpecification curveSpec = new ValueSpecification(YIELD_CURVE, target.toSpecification(), resultCurveProperties); final ValueSpecification jacobianSpec = new ValueSpecification( YIELD_CURVE_JACOBIAN, target.toSpecification(), resultJacobianProperties); return Sets.newHashSet( new ComputedValue(curveSpec, impliedDepositCurve), new ComputedValue(jacobianSpec, jacobianMatrix)); }
@Override public Set<ComputedValue> execute( final FunctionExecutionContext executionContext, final FunctionInputs inputs, final ComputationTarget target, final Set<ValueRequirement> desiredValues) { final Clock snapshotClock = executionContext.getValuationClock(); final ZonedDateTime now = snapshotClock.zonedDateTime(); final FinancialSecurity security = (FinancialSecurity) target.getSecurity(); final InstrumentDefinition<InstrumentDerivative> definition = (InstrumentDefinition<InstrumentDerivative>) security.accept(VISITOR); final Currency putCurrency = security.accept(ForexVisitors.getPutCurrencyVisitor()); final Currency callCurrency = security.accept(ForexVisitors.getCallCurrencyVisitor()); final ValueRequirement desiredValue = desiredValues.iterator().next(); final String putCurveName = desiredValue.getConstraint(PROPERTY_PUT_CURVE); final String callCurveName = desiredValue.getConstraint(PROPERTY_CALL_CURVE); final String surfaceName = desiredValue.getConstraint(ValuePropertyNames.SURFACE); final String putForwardCurveName = desiredValue.getConstraint(PROPERTY_PUT_FORWARD_CURVE); final String callForwardCurveName = desiredValue.getConstraint(PROPERTY_CALL_FORWARD_CURVE); final String putCurveCalculationMethod = desiredValue.getConstraint(PROPERTY_PUT_CURVE_CALCULATION_METHOD); final String callCurveCalculationMethod = desiredValue.getConstraint(PROPERTY_CALL_CURVE_CALCULATION_METHOD); final String interpolatorName = desiredValue.getConstraint(InterpolatedDataProperties.X_INTERPOLATOR_NAME); final String leftExtrapolatorName = desiredValue.getConstraint(InterpolatedDataProperties.LEFT_X_EXTRAPOLATOR_NAME); final String rightExtrapolatorName = desiredValue.getConstraint(InterpolatedDataProperties.RIGHT_X_EXTRAPOLATOR_NAME); final String spread = desiredValue.getConstraint(PROPERTY_CALL_SPREAD_VALUE); final double spreadValue = Double.parseDouble(spread); final String fullPutCurveName = putCurveName + "_" + putCurrency.getCode(); final String fullCallCurveName = callCurveName + "_" + callCurrency.getCode(); final String[] curveNames; if (FXUtils.isInBaseQuoteOrder( putCurrency, callCurrency)) { // To get Base/quote in market standard order. curveNames = new String[] {fullPutCurveName, fullCallCurveName}; } else { curveNames = new String[] {fullCallCurveName, fullPutCurveName}; } final YieldAndDiscountCurve putFundingCurve = getCurve(inputs, putCurrency, putCurveName); final YieldAndDiscountCurve callFundingCurve = getCurve(inputs, callCurrency, callCurveName); final YieldAndDiscountCurve[] curves; final Map<String, Currency> curveCurrency = new HashMap<String, Currency>(); curveCurrency.put(fullPutCurveName, putCurrency); curveCurrency.put(fullCallCurveName, callCurrency); final String[] allCurveNames; final Currency ccy1; final Currency ccy2; if (FXUtils.isInBaseQuoteOrder( putCurrency, callCurrency)) { // To get Base/quote in market standard order. ccy1 = putCurrency; ccy2 = callCurrency; curves = new YieldAndDiscountCurve[] {putFundingCurve, callFundingCurve}; allCurveNames = new String[] {fullPutCurveName, fullCallCurveName}; } else { curves = new YieldAndDiscountCurve[] {callFundingCurve, putFundingCurve}; allCurveNames = new String[] {fullCallCurveName, fullPutCurveName}; ccy1 = callCurrency; ccy2 = putCurrency; } final InstrumentDerivative fxOption = definition.toDerivative(now, curveNames); final YieldCurveBundle yieldCurves = new YieldCurveBundle(allCurveNames, curves); final Object spotObject = inputs.getValue(ValueRequirementNames.SPOT_RATE); if (spotObject == null) { throw new OpenGammaRuntimeException("Could not get spot rate"); } final double spot = (Double) spotObject; final ValueRequirement fxVolatilitySurfaceRequirement = getSurfaceRequirement( surfaceName, putCurrency, callCurrency, interpolatorName, leftExtrapolatorName, rightExtrapolatorName); final Object volatilitySurfaceObject = inputs.getValue(fxVolatilitySurfaceRequirement); if (volatilitySurfaceObject == null) { throw new OpenGammaRuntimeException("Could not get " + fxVolatilitySurfaceRequirement); } final SmileDeltaTermStructureParametersStrikeInterpolation smiles = (SmileDeltaTermStructureParametersStrikeInterpolation) volatilitySurfaceObject; final FXMatrix fxMatrix = new FXMatrix(ccy1, ccy2, spot); final ValueProperties.Builder properties = getResultProperties( putCurveName, putForwardCurveName, putCurveCalculationMethod, callCurveName, callForwardCurveName, callCurveCalculationMethod, surfaceName, spread, interpolatorName, leftExtrapolatorName, rightExtrapolatorName, target); final ValueSpecification spec = new ValueSpecification(_valueRequirementName, target.toSpecification(), properties.get()); final YieldCurveBundle curvesWithFX = new YieldCurveBundle(fxMatrix, curveCurrency, yieldCurves.getCurvesMap()); final SmileDeltaTermStructureDataBundle smileBundle = new SmileDeltaTermStructureDataBundle(curvesWithFX, smiles, Pair.of(ccy1, ccy2)); return getResult(fxOption, spreadValue, smileBundle, spec); }
@Override public Set<ComputedValue> execute( final FunctionExecutionContext executionContext, final FunctionInputs inputs, final ComputationTarget target, final Set<ValueRequirement> desiredValues) { final Clock snapshotClock = executionContext.getValuationClock(); final ZonedDateTime now = snapshotClock.zonedDateTime(); final FinancialSecurity security = (FinancialSecurity) target.getSecurity(); final Currency putCurrency = security.accept(ForexVisitors.getPutCurrencyVisitor()); final Currency callCurrency = security.accept(ForexVisitors.getCallCurrencyVisitor()); final ValueRequirement desiredValue = desiredValues.iterator().next(); final String putCurveName = desiredValue.getConstraint(PUT_CURVE); final String callCurveName = desiredValue.getConstraint(CALL_CURVE); final String surfaceName = desiredValue.getConstraint(ValuePropertyNames.SURFACE); final String putCurveConfig = desiredValue.getConstraint(PUT_CURVE_CALC_CONFIG); final String callCurveConfig = desiredValue.getConstraint(CALL_CURVE_CALC_CONFIG); final String interpolatorName = desiredValue.getConstraint(InterpolatedDataProperties.X_INTERPOLATOR_NAME); final String leftExtrapolatorName = desiredValue.getConstraint(InterpolatedDataProperties.LEFT_X_EXTRAPOLATOR_NAME); final String rightExtrapolatorName = desiredValue.getConstraint(InterpolatedDataProperties.RIGHT_X_EXTRAPOLATOR_NAME); final String daysForward = desiredValue.getConstraint(PROPERTY_DAYS_TO_MOVE_FORWARD); final String fullPutCurveName = putCurveName + "_" + putCurrency.getCode(); final String fullCallCurveName = callCurveName + "_" + callCurrency.getCode(); final YieldAndDiscountCurve putFundingCurve = FXOptionFunctionUtils.getCurveForCurrency( inputs, putCurrency, putCurveName, putCurveConfig); final YieldAndDiscountCurve callFundingCurve = FXOptionFunctionUtils.getCurveForCurrency( inputs, callCurrency, callCurveName, callCurveConfig); final YieldAndDiscountCurve[] curves; final Map<String, Currency> curveCurrency = new HashMap<String, Currency>(); curveCurrency.put(fullPutCurveName, putCurrency); curveCurrency.put(fullCallCurveName, callCurrency); final Object baseQuotePairsObject = inputs.getValue(ValueRequirementNames.CURRENCY_PAIRS); if (baseQuotePairsObject == null) { throw new OpenGammaRuntimeException("Could not get base/quote pair data"); } final CurrencyPairs baseQuotePairs = (CurrencyPairs) baseQuotePairsObject; final CurrencyPair baseQuotePair = baseQuotePairs.getCurrencyPair(putCurrency, callCurrency); if (baseQuotePair == null) { throw new OpenGammaRuntimeException( "Could not get base/quote pair for currency pair (" + putCurrency + ", " + callCurrency + ")"); } final String[] allCurveNames; final Currency ccy1; final Currency ccy2; if (baseQuotePair .getBase() .equals(putCurrency)) { // To get Base/quote in market standard order. ccy1 = putCurrency; ccy2 = callCurrency; curves = new YieldAndDiscountCurve[] {putFundingCurve, callFundingCurve}; allCurveNames = new String[] {fullPutCurveName, fullCallCurveName}; } else { curves = new YieldAndDiscountCurve[] {callFundingCurve, putFundingCurve}; allCurveNames = new String[] {fullCallCurveName, fullPutCurveName}; ccy1 = callCurrency; ccy2 = putCurrency; } final YieldCurveBundle yieldCurves = new YieldCurveBundle(allCurveNames, curves); final Object spotObject = inputs.getValue(ValueRequirementNames.SPOT_RATE); if (spotObject == null) { throw new OpenGammaRuntimeException("Could not get spot requirement"); } final double spot = (Double) spotObject; final ValueRequirement fxVolatilitySurfaceRequirement = getSurfaceRequirement( surfaceName, putCurrency, callCurrency, interpolatorName, leftExtrapolatorName, rightExtrapolatorName); final Object volatilitySurfaceObject = inputs.getValue(fxVolatilitySurfaceRequirement); if (volatilitySurfaceObject == null) { throw new OpenGammaRuntimeException("Could not get " + fxVolatilitySurfaceRequirement); } final SmileDeltaTermStructureParametersStrikeInterpolation smiles = (SmileDeltaTermStructureParametersStrikeInterpolation) volatilitySurfaceObject; final FXMatrix fxMatrix = new FXMatrix(ccy1, ccy2, spot); final ValueProperties.Builder properties = getResultProperties(target, desiredValue, baseQuotePair); final ValueSpecification spec = new ValueSpecification( ValueRequirementNames.VALUE_THETA, target.toSpecification(), properties.get()); final YieldCurveBundle curvesWithFX = new YieldCurveBundle(fxMatrix, curveCurrency, yieldCurves.getCurvesMap()); final SmileDeltaTermStructureDataBundle smileBundle = new SmileDeltaTermStructureDataBundle(curvesWithFX, smiles, Pair.of(ccy1, ccy2)); final ForexSecurityConverter converter = new ForexSecurityConverter(baseQuotePairs); final ForexOptionVanillaDefinition definition = (ForexOptionVanillaDefinition) security.accept(converter); final MultipleCurrencyAmount theta = CALCULATOR.getTheta( definition, now, allCurveNames, smileBundle, Integer.parseInt(daysForward)); return Collections.singleton(new ComputedValue(spec, HorizonUtils.getNonZeroValue(theta))); }