public virtual void test_localVolatilityFromImpliedVolatility() { double r = 0.05; double q = 0.01; System.Func <double, double> interestRate = (double?x) => { return(r); }; System.Func <double, double> dividendRate = (double?x) => { return(q); }; foreach (double strike in TEST_STRIKES) { foreach (double time in TEST_TIMES) { double computedVol = CALC.localVolatilityFromImpliedVolatility(VOL_SURFACE, SPOT, interestRate, dividendRate).zValue(time, strike); double expectedVol = volFromFormula(r, q, time, strike, VOL_SURFACE); assertEquals(computedVol, expectedVol, FD_EPS); UnitParameterSensitivity computedSensi = CALC.localVolatilityFromImpliedVolatility(VOL_SURFACE, SPOT, interestRate, dividendRate).zValueParameterSensitivity(time, strike); for (int i = 0; i < VOLS.size(); ++i) { InterpolatedNodalSurface surfaceUp = VOL_SURFACE.withZValues(VOLS.with(i, VOLS.get(i) + FD_EPS)); InterpolatedNodalSurface surfaceDw = VOL_SURFACE.withZValues(VOLS.with(i, VOLS.get(i) - FD_EPS)); double volUp = CALC.localVolatilityFromImpliedVolatility(surfaceUp, SPOT, interestRate, dividendRate).zValue(time, strike); double volDw = CALC.localVolatilityFromImpliedVolatility(surfaceDw, SPOT, interestRate, dividendRate).zValue(time, strike); double expectedSensi = 0.5 * (volUp - volDw) / FD_EPS; assertEquals(computedSensi.Sensitivity.get(i), expectedSensi, FD_EPS * 10d); } } } }
private System.Func <DoubleArray, DoubleArray> getPriceFunction(IList <ResolvedIborCapFloorLeg> capList, RatesProvider ratesProvider, System.Func <Surface, IborCapletFloorletVolatilities> volatilitiesFunction, InterpolatedNodalSurface baseSurface) { int nCaps = capList.Count; System.Func <DoubleArray, DoubleArray> priceFunction = (DoubleArray capletVols) => { IborCapletFloorletVolatilities newVols = volatilitiesFunction(baseSurface.withZValues(capletVols)); return(DoubleArray.of(nCaps, n => LegPricer.presentValue(capList[n], ratesProvider, newVols).Amount)); }; return(priceFunction); }
private System.Func <DoubleArray, DoubleMatrix> getJacobianFunction(IList <ResolvedIborCapFloorLeg> capList, RatesProvider ratesProvider, System.Func <Surface, IborCapletFloorletVolatilities> volatilitiesFunction, InterpolatedNodalSurface baseSurface) { int nCaps = capList.Count; int nNodes = baseSurface.ParameterCount; System.Func <DoubleArray, DoubleMatrix> jacobianFunction = (DoubleArray capletVols) => { IborCapletFloorletVolatilities newVols = volatilitiesFunction(baseSurface.withZValues(capletVols)); return(DoubleMatrix.ofArrayObjects(nCaps, nNodes, n => newVols.parameterSensitivity(LegPricer.presentValueSensitivityModelParamsVolatility(capList[n], ratesProvider, newVols).build()).Sensitivities.get(0).Sensitivity)); }; return(jacobianFunction); }