public virtual void comparisonDupireVolTest() { double tol = 1.0e-2; ImpliedTrinomialTreeLocalVolatilityCalculator calc = new ImpliedTrinomialTreeLocalVolatilityCalculator(28, 1.45d, INTERP_LINEAR); System.Func <double, double> interestRate = (double?x) => { return(0.03d); }; System.Func <double, double> dividendRate = (double?x) => { return(0.01d); }; InterpolatedNodalSurface resTri = calc.localVolatilityFromImpliedVolatility(VOL_SURFACE, SPOT, interestRate, dividendRate); DeformedSurface resDup = (new DupireLocalVolatilityCalculator()).localVolatilityFromImpliedVolatility(VOL_SURFACE, SPOT, interestRate, dividendRate); double[][] sampleStrikes = new double[][] { new double[] { 0.7 * SPOT, SPOT, 1.1 * SPOT, 1.4 * SPOT }, new double[] { 0.5 * SPOT, 0.9 * SPOT, SPOT, 1.3 * SPOT, 1.9 * SPOT } }; double[] sampleTimes = new double[] { 0.8, 1.1 }; for (int i = 0; i < sampleTimes.Length; ++i) { double time = sampleTimes[i]; foreach (double strike in sampleStrikes[i]) { double volTri = resTri.zValue(time, strike); double volDup = resDup.zValue(time, strike); assertEquals(volTri, volDup, tol); } } }
public virtual void comparisonDupirePriceTest() { double tol = 7.0e-2; ImpliedTrinomialTreeLocalVolatilityCalculator calc = new ImpliedTrinomialTreeLocalVolatilityCalculator(22, 1.1d, INTERP_LINEAR); System.Func <double, double> interestRate = (double?x) => { return(0.003d); }; System.Func <double, double> dividendRate = (double?x) => { return(0.01d); }; InterpolatedNodalSurface resTri = calc.localVolatilityFromPrice(PRICE_SURFACE, SPOT, interestRate, dividendRate); DeformedSurface resDup = (new DupireLocalVolatilityCalculator()).localVolatilityFromPrice(PRICE_SURFACE, SPOT, interestRate, dividendRate); // limited range due to interpolation/extrapolation of price surface -> negative call/put price reached double[][] sampleStrikes = new double[][] { new double[] { 0.95 * SPOT, 1.05 * SPOT }, new double[] { 0.9 * SPOT, SPOT, 1.1 * SPOT } }; double[] sampleTimes = new double[] { 0.7, 1.05 }; for (int i = 0; i < sampleTimes.Length; ++i) { double time = sampleTimes[i]; foreach (double strike in sampleStrikes[i]) { double volTri = resTri.zValue(time, strike); double volDup = resDup.zValue(time, strike); assertEquals(volTri, volDup, tol); } } }
private void testSurfaceSensitivity(CurrencyParameterSensitivity computed, NormalIborCapletFloorletExpiryStrikeVolatilities vols, System.Func <IborCapletFloorletVolatilities, CurrencyAmount> valueFn) { double pvBase = valueFn(vols).Amount; InterpolatedNodalSurface surfaceBase = (InterpolatedNodalSurface)vols.Surface; int nParams = surfaceBase.ParameterCount; for (int i = 0; i < nParams; ++i) { DoubleArray zBumped = surfaceBase.ZValues.with(i, surfaceBase.ZValues.get(i) + EPS_FD); InterpolatedNodalSurface surfaceBumped = surfaceBase.withZValues(zBumped); NormalIborCapletFloorletExpiryStrikeVolatilities volsBumped = NormalIborCapletFloorletExpiryStrikeVolatilities.of(vols.Index, vols.ValuationDateTime, surfaceBumped); double fd = (valueFn(volsBumped).Amount - pvBase) / EPS_FD; assertEquals(computed.Sensitivity.get(i), fd, NOTIONAL * EPS_FD); } }
public virtual void flatVolTest() { double tol = 2.0e-2; double constantVol = 0.15; ConstantSurface impliedVolSurface = ConstantSurface.of("impliedVol", constantVol); System.Func <double, double> zeroRate = (double?x) => { return(0.05d); }; System.Func <double, double> zeroRate1 = (double?x) => { return(0.02d); }; ImpliedTrinomialTreeLocalVolatilityCalculator calc = new ImpliedTrinomialTreeLocalVolatilityCalculator(45, 1d, INTERP_TIMESQ_LINEAR); InterpolatedNodalSurface localVolSurface = calc.localVolatilityFromImpliedVolatility(impliedVolSurface, 100d, zeroRate, zeroRate1); assertEquals(localVolSurface.ZValues.Where(d => !DoubleMath.fuzzyEquals(d, constantVol, tol)).Count(), 0); }
//------------------------------------------------------------------------- public virtual void test_parameterSensitivity() { double expiry = ACT_365F.relativeYearFraction(VAL_DATE, LocalDate.of(2015, 8, 14)); LocalDate fixing = LocalDate.of(2016, 9, 14); double strikePrice = 1.0025; double futurePrice = 0.9975; double sensitivity = 123456; IborFutureOptionSensitivity point = IborFutureOptionSensitivity.of(VOL_SIMPLE_MONEY_RATE.Name, expiry, fixing, strikePrice, futurePrice, EUR, sensitivity); CurrencyParameterSensitivities ps = VOL_SIMPLE_MONEY_RATE.parameterSensitivity(point); double shift = 1.0E-6; double v0 = VOL_SIMPLE_MONEY_RATE.volatility(expiry, fixing, strikePrice, futurePrice); for (int i = 0; i < NORMAL_VOL_RATES.size(); i++) { DoubleArray v = NORMAL_VOL_RATES.with(i, NORMAL_VOL_RATES.get(i) + shift); InterpolatedNodalSurface param = InterpolatedNodalSurface.of(Surfaces.normalVolatilityByExpirySimpleMoneyness("Rate", ACT_365F, MoneynessType.RATES), TIMES, MONEYNESS_RATES, v, INTERPOLATOR_2D); NormalIborFutureOptionExpirySimpleMoneynessVolatilities vol = NormalIborFutureOptionExpirySimpleMoneynessVolatilities.of(EUR_EURIBOR_3M, VAL_DATE_TIME, param); double vP = vol.volatility(expiry, fixing, strikePrice, futurePrice); double s = ps.getSensitivity(PARAMETERS_RATE.Name, EUR).Sensitivity.get(i); assertEquals(s, (vP - v0) / shift * sensitivity, TOLERANCE_DELTA); } }
public virtual void flatVolPriceTest() { double tol = 2.0e-2; double constantVol = 0.15; double spot = 100d; double maxTime = 1d; int nSteps = 9; ConstantSurface impliedVolSurface = ConstantSurface.of("impliedVol", constantVol); System.Func <double, double> zeroRate = (double?x) => { return(0d); }; System.Func <DoublesPair, ValueDerivatives> func = (DoublesPair x) => { double price = BlackFormulaRepository.price(spot, x.Second, x.First, constantVol, true); return(ValueDerivatives.of(price, DoubleArray.EMPTY)); }; DeformedSurface priceSurface = DeformedSurface.of(DefaultSurfaceMetadata.of("price"), impliedVolSurface, func); ImpliedTrinomialTreeLocalVolatilityCalculator calc = new ImpliedTrinomialTreeLocalVolatilityCalculator(nSteps, maxTime, INTERP_TIMESQ_LINEAR); InterpolatedNodalSurface localVolSurface = calc.localVolatilityFromPrice(priceSurface, spot, zeroRate, zeroRate); assertEquals(localVolSurface.ZValues.Where(d => !DoubleMath.fuzzyEquals(d, constantVol, tol)).Count(), 0); }