@Override public DoubleMatrix2D evaluate(final DoubleMatrix1D x) { YieldCurveBundle curves = _curveBuilderFunction.evaluate(x); final YieldCurveBundle knownCurves = _data.getKnownCurves(); // set any known (i.e. fixed) curves if (knownCurves != null) { curves.addAll(knownCurves); } final int totalNodes = _data.getTotalNodes(); final List<String> curveNames = _data.getCurveNames(); final double[][] res = new double[_data.getNumInstruments()][totalNodes]; for (int i = 0; i < _data.getNumInstruments(); i++) { // loop over all instruments InstrumentDerivative deriv = _data.getDerivative(i); final Map<String, List<DoublesPair>> senseMap = _calculator.visit(deriv, curves).getSensitivities(); int offset = 0; for (final String name : curveNames) { // loop over all curves (by name) if (senseMap.containsKey(name)) { final Curve<Double, Double> curve = curves.getCurve(name).getCurve(); if (!(curve instanceof InterpolatedDoublesCurve)) { throw new IllegalArgumentException("Can only handle InterpolatedDoublesCurve"); } final InterpolatedDoublesCurve interpolatedCurve = (InterpolatedDoublesCurve) curve; final Interpolator1DDataBundle data = interpolatedCurve.getDataBundle(); final Interpolator1D sensitivityCalculator = _data.getInterpolatorForCurve(name); final List<DoublesPair> senseList = senseMap.get(name); if (senseList.size() != 0) { final double[][] sensitivity = new double[senseList.size()][]; int k = 0; for (final DoublesPair timeAndDF : senseList) { sensitivity[k++] = sensitivityCalculator.getNodeSensitivitiesForValue( data, timeAndDF.getFirst(), _data.useFiniteDifferenceForNodeSensitivities()); } for (int j = 0; j < sensitivity[0].length; j++) { double temp = 0.0; k = 0; for (final DoublesPair timeAndDF : senseList) { temp += timeAndDF.getSecond() * sensitivity[k++][j]; } res[i][j + offset] = temp; } } } offset += _data.getCurveNodePointsForCurve(name).length; } } return new DoubleMatrix2D(res); }
@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)); }
// Test in so that it will break when the drift curve is serialized @Test(expectedExceptions = OpenGammaRuntimeException.class) public void testDriftCurveNotSerialized1() { final double spot = 100; final Curve<Double, Double> driftCurve = InterpolatedDoublesCurve.from(EXPIRIES, FORWARD, INTERPOLATOR); final ForwardCurve curve = new ForwardCurve(spot, driftCurve); cycleObject(ForwardCurve.class, curve); }
@Test public void testCurve2() { final ForwardCurve curve1 = new ForwardCurve(InterpolatedDoublesCurve.from(EXPIRIES, FORWARD, INTERPOLATOR)); final ForwardCurve curve2 = cycleObject(ForwardCurve.class, curve1); assertEquals(curve1.getSpot(), curve2.getSpot(), EPS); assertTrue(curve2.getDriftCurve() instanceof FunctionalDoublesCurve); assertCurveEquals(curve1.getForwardCurve(), curve2.getForwardCurve()); assertCurveEquals(curve1.getDriftCurve(), curve2.getDriftCurve()); }
public static YieldCurveBundle getBundle() { YieldCurveBundle bundle = new YieldCurveBundle(); Interpolator1D extrapolator = CombinedInterpolatorExtrapolatorFactory.getInterpolator( Interpolator1DFactory.DOUBLE_QUADRATIC, LINEAR_EXTRAPOLATOR, FLAT_EXTRAPOLATOR); InterpolatedDoublesCurve fCurve = InterpolatedDoublesCurve.from(FUNDING_CURVE_TIMES, FUNDING_YIELDS, extrapolator); YieldCurve fundingCurve = YieldCurve.from(fCurve); bundle.setCurve(FUNDING_CURVE_NAME, fundingCurve); InterpolatedDoublesCurve lcurve = InterpolatedDoublesCurve.from(LIBOR_CURVE_TIMES, LIBOR_YIELDS, extrapolator); YieldCurve liborCurve = YieldCurve.from(lcurve); bundle.setCurve(LIBOR_CURVE_NAME, liborCurve); return bundle; }
@Override protected Object getResult( final PDELocalVolatilityCalculator<?> calculator, final LocalVolatilitySurfaceMoneyness localVolatility, final ForwardCurve forwardCurve, final EuropeanVanillaOption option, final YieldAndDiscountCurve discountingCurve) { final Interpolator1DDataBundle data = (Interpolator1DDataBundle) calculator.getResult(localVolatility, forwardCurve, option, discountingCurve); return InterpolatedDoublesCurve.from( data.getKeys(), data.getValues(), ((LocalVolatilityForwardPDEVolatilityGreeksGridCalculator) calculator).getInterpolator()); }
@Test public void convertNonEmpty() { final Map<Double, Double> map = new HashMap<Double, Double>(); map.put(1., 0.03); map.put(2., 0.04); map.put(3.5, 0.05); Map<String, Double> expected = new HashMap<String, Double>(); expected.put("Foo[1.0]", 0.03); expected.put("Foo[2.0]", 0.04); expected.put("Foo[3.5]", 0.05); Map<String, Double> actual = _converter.convert( "Foo", YieldCurve.from( InterpolatedDoublesCurve.from( map, Interpolator1DFactory.getInterpolator("Linear")))); assertEquals(expected, actual); }
public void test() throws Exception { IRSwapTradeParser tradeParser = new IRSwapTradeParser(); Resource resource = ResourceUtils.createResource( "classpath:com/opengamma/financial/analytics/test/Trades14Oct.csv"); List<IRSwapSecurity> trades = tradeParser.parseCSVFile(resource.getURL()); List<IRSwapSecurity> tradesClean = Lists.newArrayList(); for (IRSwapSecurity irSwapSecurity : trades) { String currency = irSwapSecurity.getRawInput().getString(PAY_CURRENCY); if (currency.equals(CURRENCY)) { tradesClean.add(irSwapSecurity); } } // Build the curve bundle final HashMap<String, Currency> ccyMap = new HashMap<>(); ccyMap.put(discountingCurvename, ccy); ccyMap.put(forward3MCurveName, ccy); ccyMap.put(forward6MCurveName, ccy); final FXMatrix fx = new FXMatrix(ccy); final YieldCurveBundle curvesClean = new YieldCurveBundle(fx, ccyMap); IRCurveParser curveParser = new IRCurveParser(); Resource resourceCurve = ResourceUtils.createResource( "classpath:com/opengamma/financial/analytics/test/Base_Curves_20131014_Clean.csv"); List<InterpolatedDoublesCurve> curves = curveParser.parseCSVFile(resourceCurve.getURL()); for (InterpolatedDoublesCurve interpolatedDoublesCurve : curves) { String name = interpolatedDoublesCurve.getName(); if (name.equals(ON_NAME)) { curvesClean.setCurve(discountingCurvename, DiscountCurve.from(interpolatedDoublesCurve)); } if (name.equals(ONE_MONTH_NAME)) { curvesClean.setCurve(forward1MCurveName, DiscountCurve.from(interpolatedDoublesCurve)); } if (name.equals(THREE_MONTH_NAME)) { curvesClean.setCurve(forward3MCurveName, DiscountCurve.from(interpolatedDoublesCurve)); } if (name.equals(SIX_MONTH_NAME)) { curvesClean.setCurve(forward6MCurveName, DiscountCurve.from(interpolatedDoublesCurve)); } } // Convert the swap security into a swap definition final SwapSecurityConverterDeprecated swapConverter = new SwapSecurityConverterDeprecated( _holidaySource, _conventionBundleSource, _regionSource, false); final FRASecurityConverterDeprecated fraConverter = new FRASecurityConverterDeprecated(_holidaySource, _regionSource, _conventionBundleSource); final ZeroDepositConverter ZeroCouponConverter = new ZeroDepositConverter(_conventionBundleSource, _holidaySource); List<SwapDefinition> swapsDefinition = Lists.newArrayList(); List<ForwardRateAgreementDefinition> frasDefinition = Lists.newArrayList(); List<DepositZeroDefinition> zcsDefinition = Lists.newArrayList(); /*for (IRSwapSecurity irSwapSecurity : tradesClean) { switch (irSwapSecurity.getRawInput().getString("PRODUCT_TYPE")) { case "SWAP": swapsDefinition.add((SwapDefinition) swapConverter.visitSwapSecurity(irSwapSecurity.getSwapSecurity())); // we don't treat the fra case at the moment case "FRA": frasDefinition.add((ForwardRateAgreementDefinition) fraConverter.visitSwapSecurity(irSwapSecurity.getSwapSecurity())); case "OIS": swapsDefinition.add((SwapDefinition) swapConverter.visitSwapSecurity(irSwapSecurity.getSwapSecurity())); // we don't treat the fra case at the moment case "ZCS": zcsDefinition.add((DepositZeroDefinition) ZeroCouponConverter.visitSwapSecurity(irSwapSecurity.getSwapSecurity())); } } */ // Load the historical time series from a csv file /* NonVersionedRedisHistoricalTimeSeriesSource source = new NonVersionedRedisHistoricalTimeSeriesSource(getJedisPool(), getRedisPrefix()); CMECurveFixingTSLoader loader = new CMECurveFixingTSLoader(source);*/ /* loader.loadCurveFixingCSVFile("/vols/ogdev/CME/curve-fixing/sample-cme-curve-fixing.csv"); HistoricalTimeSeries historicalTimeSeries = source.getHistoricalTimeSeries(UniqueId.of(ExternalSchemes.ISDA.getName(), "CHF-LIBOR-BBA-6M")); assertNotNull(historicalTimeSeries); LocalDateDoubleTimeSeries timeSeries = historicalTimeSeries.getTimeSeries(); assertNotNull(timeSeries); assertEquals(5996, timeSeries.size());*/ // convert the definition into a derivative /* List<Swap> swapDerivatives = Lists.newArrayList(); for (SwapDefinition swapDefinition : swapsDefinition) { swapDerivatives.add(swapDefinition.toDerivative(TODAY, data, curvesClean)); } List<Swap> frasDerivatives = Lists.newArrayList(); for (ForwardRateAgreementDefinition fraDefinition : frasDefinition) { frasDerivatives.add(fraDefinition.toDerivative(TODAY, data, curvesClean)); } List<Swap> zcsDerivatives = Lists.newArrayList(); for (DepositZeroDefinition zcDefinition : zcsDefinition) { zcsDerivatives.add(zcDefinition.toDerivative(TODAY, data, curvesClean)); }*/ // Check the npv s_logger.warn("Got {} trades", trades.size()); }
/** * Compute the sensitivity by finite difference on all points. The curves must be interpolated * yield curves. Only the discounting and forward curves sensitivity is computed. * * @param instrument The instrument. * @param hwcurves The provider: all discounting, forward and issuer curves should be of the type * YieldCurve with InterpolatedDoublesCurve. * @return The parameter sensitivity. */ public SimpleParameterSensitivity calculateSensitivity( final InstrumentDerivative instrument, final HullWhiteOneFactorProviderDiscount hwcurves) { SimpleParameterSensitivity result = new SimpleParameterSensitivity(); // Discounting final Set<Currency> ccyDiscounting = hwcurves.getMulticurveProvider().getCurrencies(); for (final Currency ccy : ccyDiscounting) { final YieldAndDiscountCurve curve = hwcurves.getMulticurveProvider().getCurve(ccy); ArgChecker.isTrue(curve instanceof YieldCurve, "Curve should be a YieldCurve"); final YieldCurve curveYield = (YieldCurve) curve; ArgChecker.isTrue( curveYield.getCurve() instanceof InterpolatedDoublesCurve, "Yield curve should be based on InterpolatedDoublesCurve"); final InterpolatedDoublesCurve curveInt = (InterpolatedDoublesCurve) curveYield.getCurve(); final int nbNodePoint = curveInt.getXDataAsPrimitive().length; final double[] sensitivity = new double[nbNodePoint]; for (int loopnode = 0; loopnode < nbNodePoint; loopnode++) { final double[] yieldBumpedPlus = curveInt.getYDataAsPrimitive().clone(); yieldBumpedPlus[loopnode] += _shift; final YieldAndDiscountCurve dscBumpedPlus = new YieldCurve( curveInt.getName(), new InterpolatedDoublesCurve( curveInt.getXDataAsPrimitive(), yieldBumpedPlus, curveInt.getInterpolator(), true)); final HullWhiteOneFactorProviderDiscount marketDscBumpedPlus = new HullWhiteOneFactorProviderDiscount( hwcurves.getMulticurveProvider().withDiscountFactor(ccy, dscBumpedPlus), hwcurves.getHullWhiteParameters(), hwcurves.getHullWhiteCurrency()); final double valueBumpedPlus = instrument.accept(_valueCalculator, marketDscBumpedPlus); final double[] yieldBumpedMinus = curveInt.getYDataAsPrimitive().clone(); yieldBumpedMinus[loopnode] -= _shift; final YieldAndDiscountCurve dscBumpedMinus = new YieldCurve( curveInt.getName(), new InterpolatedDoublesCurve( curveInt.getXDataAsPrimitive(), yieldBumpedMinus, curveInt.getInterpolator(), true)); final HullWhiteOneFactorProviderDiscount marketDscBumpedMinus = new HullWhiteOneFactorProviderDiscount( hwcurves.getMulticurveProvider().withDiscountFactor(ccy, dscBumpedMinus), hwcurves.getHullWhiteParameters(), hwcurves.getHullWhiteCurrency()); final double valueBumpedMinus = instrument.accept(_valueCalculator, marketDscBumpedMinus); sensitivity[loopnode] = (valueBumpedPlus - valueBumpedMinus) / (2 * _shift); } final String name = hwcurves.getMulticurveProvider().getName(ccy); result = result.plus(name, new DoubleMatrix1D(sensitivity)); } // Forward ON final Set<IndexON> indexON = hwcurves.getMulticurveProvider().getIndexesON(); for (final IndexON index : indexON) { final YieldAndDiscountCurve curve = hwcurves.getMulticurveProvider().getCurve(index); ArgChecker.isTrue(curve instanceof YieldCurve, "Curve should be a YieldCurve"); final YieldCurve curveYield = (YieldCurve) curve; ArgChecker.isTrue( curveYield.getCurve() instanceof InterpolatedDoublesCurve, "Yield curve should be based on InterpolatedDoublesCurve"); final InterpolatedDoublesCurve curveInt = (InterpolatedDoublesCurve) curveYield.getCurve(); final int nbNodePoint = curveInt.getXDataAsPrimitive().length; final double[] sensitivity = new double[nbNodePoint]; for (int loopnode = 0; loopnode < nbNodePoint; loopnode++) { final double[] yieldBumpedPlus = curveInt.getYDataAsPrimitive().clone(); yieldBumpedPlus[loopnode] += _shift; final YieldAndDiscountCurve dscBumpedPlus = new YieldCurve( curveInt.getName(), new InterpolatedDoublesCurve( curveInt.getXDataAsPrimitive(), yieldBumpedPlus, curveInt.getInterpolator(), true)); final HullWhiteOneFactorProviderDiscount marketFwdBumpedPlus = new HullWhiteOneFactorProviderDiscount( hwcurves.getMulticurveProvider().withForward(index, dscBumpedPlus), hwcurves.getHullWhiteParameters(), hwcurves.getHullWhiteCurrency()); final double valueBumpedPlus = instrument.accept(_valueCalculator, marketFwdBumpedPlus); final double[] yieldBumpedMinus = curveInt.getYDataAsPrimitive().clone(); yieldBumpedMinus[loopnode] -= _shift; final YieldAndDiscountCurve dscBumpedMinus = new YieldCurve( curveInt.getName(), new InterpolatedDoublesCurve( curveInt.getXDataAsPrimitive(), yieldBumpedMinus, curveInt.getInterpolator(), true)); final HullWhiteOneFactorProviderDiscount marketFwdBumpedMinus = new HullWhiteOneFactorProviderDiscount( hwcurves.getMulticurveProvider().withForward(index, dscBumpedMinus), hwcurves.getHullWhiteParameters(), hwcurves.getHullWhiteCurrency()); final double valueBumpedMinus = instrument.accept(_valueCalculator, marketFwdBumpedMinus); sensitivity[loopnode] = (valueBumpedPlus - valueBumpedMinus) / (2 * _shift); } final String name = hwcurves.getMulticurveProvider().getName(index); result = result.plus(name, new DoubleMatrix1D(sensitivity)); } // Forward Ibor - symmetrical final Set<IborIndex> indexForward = hwcurves.getMulticurveProvider().getIndexesIbor(); for (final IborIndex index : indexForward) { final YieldAndDiscountCurve curve = hwcurves.getMulticurveProvider().getCurve(index); ArgChecker.isTrue(curve instanceof YieldCurve, "Curve should be a YieldCurve"); final YieldCurve curveYield = (YieldCurve) curve; ArgChecker.isTrue( curveYield.getCurve() instanceof InterpolatedDoublesCurve, "Yield curve should be based on InterpolatedDoublesCurve"); final InterpolatedDoublesCurve curveInt = (InterpolatedDoublesCurve) curveYield.getCurve(); final int nbNodePoint = curveInt.getXDataAsPrimitive().length; final double[] sensitivity = new double[nbNodePoint]; for (int loopnode = 0; loopnode < nbNodePoint; loopnode++) { final double[] yieldBumpedPlus = curveInt.getYDataAsPrimitive().clone(); yieldBumpedPlus[loopnode] += _shift; final YieldAndDiscountCurve dscBumpedPlus = new YieldCurve( curveInt.getName(), new InterpolatedDoublesCurve( curveInt.getXDataAsPrimitive(), yieldBumpedPlus, curveInt.getInterpolator(), true)); final HullWhiteOneFactorProviderDiscount marketFwdBumpedPlus = new HullWhiteOneFactorProviderDiscount( hwcurves.getMulticurveProvider().withForward(index, dscBumpedPlus), hwcurves.getHullWhiteParameters(), hwcurves.getHullWhiteCurrency()); final double valueBumpedPlus = instrument.accept(_valueCalculator, marketFwdBumpedPlus); final double[] yieldBumpedMinus = curveInt.getYDataAsPrimitive().clone(); yieldBumpedMinus[loopnode] -= _shift; final YieldAndDiscountCurve dscBumpedMinus = new YieldCurve( curveInt.getName(), new InterpolatedDoublesCurve( curveInt.getXDataAsPrimitive(), yieldBumpedMinus, curveInt.getInterpolator(), true)); final HullWhiteOneFactorProviderDiscount marketFwdBumpedMinus = new HullWhiteOneFactorProviderDiscount( hwcurves.getMulticurveProvider().withForward(index, dscBumpedMinus), hwcurves.getHullWhiteParameters(), hwcurves.getHullWhiteCurrency()); final double valueBumpedMinus = instrument.accept(_valueCalculator, marketFwdBumpedMinus); sensitivity[loopnode] = (valueBumpedPlus - valueBumpedMinus) / (2 * _shift); } final String name = hwcurves.getMulticurveProvider().getName(index); result = result.plus(name, new DoubleMatrix1D(sensitivity)); } return result; }
@Test public void curveSensitivityFRA() { final YieldCurveBundle curves = TestsDataSetsSABR.createCurves1(); final double deltaShift = 1.0E-8; final double pv = FRA_METHOD.presentValue(FRA, curves).getAmount(); // 1. Forward curve sensitivity final String bumpedCurveName = "Bumped Curve"; final String[] bumpedCurvesForwardName = {FUNDING_CURVE_NAME, bumpedCurveName}; final ForwardRateAgreement fraBumpedForward = (ForwardRateAgreement) FRA_DEFINITION.toDerivative(REFERENCE_DATE, bumpedCurvesForwardName); final YieldAndDiscountCurve curveForward = curves.getCurve(FORWARD_CURVE_NAME); final double[] timeForward = new double[2]; timeForward[0] = FRA.getFixingPeriodStartTime(); timeForward[1] = FRA.getFixingPeriodEndTime(); final int nbForwardDate = timeForward.length; final double[] yieldsForward = new double[nbForwardDate + 1]; final double[] nodeTimesForward = new double[nbForwardDate + 1]; yieldsForward[0] = curveForward.getInterestRate(0.0); for (int i = 0; i < nbForwardDate; i++) { nodeTimesForward[i + 1] = timeForward[i]; yieldsForward[i + 1] = curveForward.getInterestRate(nodeTimesForward[i + 1]); } final YieldAndDiscountCurve tempCurveForward = YieldCurve.from( InterpolatedDoublesCurve.fromSorted( nodeTimesForward, yieldsForward, new LinearInterpolator1D())); final double[] sensiPvForwardFD = new double[nbForwardDate]; for (int i = 0; i < nbForwardDate; i++) { final YieldAndDiscountCurve bumpedCurveForward = tempCurveForward.withSingleShift(nodeTimesForward[i + 1], deltaShift); final YieldCurveBundle curvesBumpedForward = new YieldCurveBundle(); curvesBumpedForward.addAll(curves); curvesBumpedForward.setCurve("Bumped Curve", bumpedCurveForward); final double bumpedPv = FRA_METHOD.presentValue(fraBumpedForward, curvesBumpedForward).getAmount(); sensiPvForwardFD[i] = (bumpedPv - pv) / deltaShift; } final double[] nodeTimesForwardMethod = new double[] {FRA.getFixingPeriodStartTime(), FRA.getFixingPeriodEndTime()}; final double[] sensiForwardMethod = SensitivityFiniteDifference.curveSensitivity( fraBumpedForward, curves, pv, FORWARD_CURVE_NAME, bumpedCurveName, nodeTimesForwardMethod, deltaShift, FRA_METHOD); assertEquals( "Sensitivity finite difference method: number of node", 2, sensiForwardMethod.length); for (int loopnode = 0; loopnode < sensiForwardMethod.length; loopnode++) { assertEquals( "Sensitivity finite difference method: node sensitivity", sensiPvForwardFD[loopnode], sensiForwardMethod[loopnode]); } // 2. Funding curve sensitivity final String[] bumpedCurvesFundingName = {bumpedCurveName, FORWARD_CURVE_NAME}; final ForwardRateAgreement fraBumped = (ForwardRateAgreement) FRA_DEFINITION.toDerivative(REFERENCE_DATE, bumpedCurvesFundingName); final YieldAndDiscountCurve curveFunding = curves.getCurve(FUNDING_CURVE_NAME); final double[] yieldsFunding = new double[2]; final double[] nodeTimesFunding = new double[2]; yieldsFunding[0] = curveFunding.getInterestRate(0.0); nodeTimesFunding[1] = FRA.getPaymentTime(); yieldsFunding[1] = curveFunding.getInterestRate(nodeTimesFunding[1]); final YieldAndDiscountCurve tempCurveFunding = YieldCurve.from( InterpolatedDoublesCurve.fromSorted( nodeTimesFunding, yieldsFunding, new LinearInterpolator1D())); final YieldAndDiscountCurve bumpedCurve = tempCurveFunding.withSingleShift(nodeTimesFunding[1], deltaShift); final YieldCurveBundle curvesBumped = new YieldCurveBundle(); curvesBumped.addAll(curves); curvesBumped.replaceCurve("Bumped Curve", bumpedCurve); final double bumpedPvDsc = FRA_METHOD.presentValue(fraBumped, curvesBumped).getAmount(); final double[] resDsc = new double[1]; resDsc[0] = (bumpedPvDsc - pv) / deltaShift; final double[] nodeTimesFundingMethod = new double[] {FRA.getPaymentTime()}; final double[] sensiFundingMethod = SensitivityFiniteDifference.curveSensitivity( fraBumped, curves, pv, FUNDING_CURVE_NAME, bumpedCurveName, nodeTimesFundingMethod, deltaShift, FRA_METHOD); assertEquals( "Sensitivity finite difference method: number of node", 1, sensiFundingMethod.length); for (int loopnode = 0; loopnode < sensiFundingMethod.length; loopnode++) { assertEquals( "Sensitivity finite difference method: node sensitivity", resDsc[loopnode], sensiFundingMethod[loopnode]); } }
@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)); }