Package com.opengamma.analytics.financial.model.finitedifference

Examples of com.opengamma.analytics.financial.model.finitedifference.PDEResults1D


  public void runBackwardsPDESolver(final PrintStream ps, final double expiry, final double strike) {

    final double forward = _marketData.getForwardCurve().getForward(expiry);
    final double maxSpot = 3.5 * forward;

    final PDEResults1D res = runBackwardsPDESolver(strike, _localVolatilityStrike, _isCall, _theta, expiry, maxSpot,
        _timeSteps, _spaceSteps, _timeGridBunching, _spaceGridBunching, forward);
    final int n = res.getGrid().getNumSpaceNodes();
    for (int i = 0; i < n; i++) {
      final double price = res.getFunctionValue(i);
      final double f = res.getSpaceValue(i);
      try {
        final double vol = BlackFormulaRepository.impliedVolatility(price, f, strike, expiry, _isCall);
        ps.println(f + "\t" + price + "\t" + vol);
      } catch (final Exception e) {

View Full Code Here


    //Now run the backwards solver and get delta and gamma off the grid
    ps.println("Result of running backwards PDE solver - this gives you a set of prices at different spot levels for a" +
        " single expiry and strike. Delta and gamma are calculated by finite difference on the grid");
    ps.println("Spot\tVol\tBS Delta\tDelta\tBS Gamma\tGamma");

    PDEResults1D res = runBackwardsPDESolver(strike, localVol, _isCall, _theta, expiry, maxForward,
        _timeSteps, _spaceSteps, _timeGridBunching, _spaceGridBunching, forward);

    for (int i = 0; i < n; i++) {
      final double price = res.getFunctionValue(i);
      final double fwd = res.getGrid().getSpaceNode(i);
      double impVol = 0;
      try {
        impVol = BlackFormulaRepository.impliedVolatility(price, fwd, strike, expiry, _isCall);
      } catch (final Exception e) {
      }
      final double bsDelta = BlackFormulaRepository.delta(fwd, strike, expiry, impVol, _isCall);
      final double bsGamma = BlackFormulaRepository.gamma(fwd, strike, expiry, impVol);

      final double modelDelta = res.getFirstSpatialDerivative(i);
      final double modelGamma = res.getSecondSpatialDerivative(i);

      ps.println(fwd + "\t" + impVol + "\t" + bsDelta + "\t" + modelDelta + "\t" + bsGamma + "\t" + modelGamma);
    }
    ps.print("\n");

    //finally run the backwards PDE solver 100 times with different strikes,  interpolating to get vol, delta and gamma at the forward
    final int xIndex = res.getGrid().getLowerBoundIndexForSpace(forward);
    final double actForward = res.getSpaceValue(xIndex);
    final double f1 = res.getSpaceValue(xIndex);
    final double f2 = res.getSpaceValue(xIndex + 1);
    final double w = (f2 - forward) / (f2 - f1);
    ps.println("True forward: " + forward + ", grid forward: " + actForward);
    ps.println("Result of running 100 backwards PDE solvers all with different strikes. Delta and gamma for each strike" +
        " is calculated from finite difference on the grid");
    ps.println("Strike\tVol\tDelta\tGamma");
    for (int i = 0; i < 100; i++) {
      final double k = forward * (0.3 + 2.7 * i / 99.0);
      res = runBackwardsPDESolver(k, localVol, _isCall, _theta, expiry, maxForward,
          _timeSteps, _spaceSteps, _timeGridBunching, _spaceGridBunching, forward);

      double vol = 0;
      try {
        final double vol1 = BlackFormulaRepository.impliedVolatility(res.getFunctionValue(xIndex), f1, k, expiry, _isCall);
        final double vol2 = BlackFormulaRepository.impliedVolatility(res.getFunctionValue(xIndex + 1), f2, k, expiry, _isCall);
        vol = w * vol1 + (1 - w) * vol2;
      } catch (final Exception e) {
      }
      final double modelDelta = w * res.getFirstSpatialDerivative(xIndex) + (1 - w) * res.getFirstSpatialDerivative(xIndex + 1);
      final double modelGamma = w * res.getSecondSpatialDerivative(xIndex) + (1 - w) * res.getSecondSpatialDerivative(xIndex + 1);
      ps.println(k + "\t" + vol + "\t" + modelDelta + "\t" + modelGamma);
    }
  }
View Full Code Here

    }
    ps.print("\n");

    //finally run the backwards PDE solver 100 times with different strikes,  interpolating to get vol
    final double maxForward = 3.5 * forward;
    PDEResults1D res = runBackwardsPDESolver(forward, localVol, _isCall, _theta, expiry, maxForward,
        _timeSteps, _spaceSteps, _timeGridBunching, _spaceGridBunching, forward);
    final int xIndex = res.getGrid().getLowerBoundIndexForSpace(forward);
    final double f1 = res.getSpaceValue(xIndex);
    final double f2 = res.getSpaceValue(xIndex + 1);
    final double w = (f2 - forward) / (f2 - f1);

    ps.println("Result of running 100 backwards PDE solvers all with different strikes. Delta and gamma for each strike" +
        " is calculated from finite difference on the grid");
    ps.println("Strike\tVol\tDelta\tGamma");
    for (int i = 0; i < 100; i++) {
      final double k = forward * (0.3 + 2.7 * i / 99.0);
      res = runBackwardsPDESolver(k, localVol, _isCall, _theta, expiry, maxForward,
          _timeSteps, _spaceSteps, _timeGridBunching, _spaceGridBunching, forward);

      double vol = 0;
      try {
        final double vol1 = BlackFormulaRepository.impliedVolatility(res.getFunctionValue(xIndex), f1, k, expiry, _isCall);
        final double vol2 = BlackFormulaRepository.impliedVolatility(res.getFunctionValue(xIndex + 1), f2, k, expiry, _isCall);
        vol = w * vol1 + (1 - w) * vol2;
      } catch (final Exception e) {
      }

      ps.println(k + "\t" + vol);
View Full Code Here

    final int n = _marketData.getNumExpiries();
    final double[][] strikes = _marketData.getStrikes();
    final double forward = _marketData.getForwardCurve().getForward(option.getTimeToExpiry());
    final double maxFwd = 3.5 * Math.max(option.getStrike(), forward);
    final PDEResults1D pdeRes = runBackwardsPDESolver(option.getStrike(), _localVolatilityStrike, option.isCall(), _theta, option.getTimeToExpiry(),
        maxFwd, _timeSteps, _spaceSteps, _timeGridBunching, _spaceGridBunching, option.getStrike());

    final double exampleVol;
    final double[] fwdNodes = pdeRes.getGrid().getSpaceNodes();
    int index = getLowerBoundIndex(fwdNodes, forward);
    if (index >= 1) {
      index--;
    }
    if (index >= _spaceSteps - 1) {
      index--;
      if (index >= _spaceSteps - 1) {
        index--;
      }
    }
    final double[] vols = new double[4];
    final double[] fwds = new double[4];
    System.arraycopy(fwdNodes, index, fwds, 0, 4);
    for (int i = 0; i < 4; i++) {
      vols[i] = BlackFormulaRepository.impliedVolatility(pdeRes.getFunctionValue(index + i), fwds[i], option.getStrike(), option.getTimeToExpiry(), option.isCall());
    }
    Interpolator1DDoubleQuadraticDataBundle db = INTERPOLATOR_1D.getDataBundle(fwds, vols);
    exampleVol = INTERPOLATOR_1D.interpolate(db, forward);

    final double shiftAmount = 1e-4; //1bps

    final double[][] res = new double[n][];

    for (int i = 0; i < n; i++) {
      final int m = strikes[i].length;
      res[i] = new double[m];
      for (int j = 0; j < m; j++) {
        final BlackVolatilitySurfaceMoneyness bumpedSurface = _surfaceFitter.getBumpedVolatilitySurface(_marketData, i, j, shiftAmount);
        final LocalVolatilitySurfaceStrike bumpedLV = LocalVolatilitySurfaceConverter.toStrikeSurface(DUPIRE.getLocalVolatility(bumpedSurface));
        final PDEResults1D pdeResBumped = runBackwardsPDESolver(option.getStrike(), bumpedLV, option.isCall(), _theta, option.getTimeToExpiry(),
            maxFwd, _timeSteps, _spaceSteps, _timeGridBunching, _spaceGridBunching, option.getStrike());
        for (int k = 0; k < 4; k++) {
          vols[k] = BlackFormulaRepository.impliedVolatility(pdeResBumped.getFunctionValue(index + k), fwds[k], option.getStrike(), option.getTimeToExpiry(), option.isCall());
        }
        db = INTERPOLATOR_1D.getDataBundle(fwds, vols);
        final double vol = INTERPOLATOR_1D.interpolate(db, forward);
        res[i][j] = (vol - exampleVol) / shiftAmount;
      }
View Full Code Here

    final LocalVolatilitySurfaceStrike lvDown = new LocalVolatilitySurfaceStrike(SurfaceShiftFunctionFactory.getShiftedSurface(localVol.getSurface(), -volShift, true));

    //first order shifts
    final PDEFullResults1D pdeRes = runForwardPDESolver(forwardCurve, localVol, _isCall, _theta, maxT, maxProxyDelta,
        _timeSteps, _spaceSteps, _timeGridBunching, _spaceGridBunching, 1.0);
    final PDEResults1D pdeResUp = runForwardPDESolver(forwardCurve, lvUp, _isCall, _theta, maxT, maxProxyDelta,
        _timeSteps, _spaceSteps, _timeGridBunching, _spaceGridBunching, 1.0);
    final PDEResults1D pdeResDown = runForwardPDESolver(forwardCurve, lvDown, _isCall, _theta, maxT, maxProxyDelta,
        _timeSteps, _spaceSteps, _timeGridBunching, _spaceGridBunching, 1.0);

    //second order shifts
    final PDEResults1D pdeResUpUp = runForwardPDESolver(forwardCurve.withFractionalShift(fwdShift), lvUp, _isCall, _theta, maxT, maxProxyDelta,
        _timeSteps, _spaceSteps, _timeGridBunching, _spaceGridBunching, 1.0);
    final PDEFullResults1D pdeResUpDown = runForwardPDESolver(forwardCurve.withFractionalShift(fwdShift), lvDown, _isCall, _theta, maxT, maxProxyDelta,
        _timeSteps, _spaceSteps, _timeGridBunching, _spaceGridBunching, 1.0);
    final PDEFullResults1D pdeResDownUp = runForwardPDESolver(forwardCurve.withFractionalShift(-fwdShift), lvUp, _isCall, _theta, maxT, maxProxyDelta,
        _timeSteps, _spaceSteps, _timeGridBunching, _spaceGridBunching, 1.0);
    final PDEFullResults1D pdeResDownDown = runForwardPDESolver(forwardCurve.withFractionalShift(-fwdShift), lvDown, _isCall, _theta, maxT, maxProxyDelta,
        _timeSteps, _spaceSteps, _timeGridBunching, _spaceGridBunching, 1.0);

    ps.println("Strike\tBS Vega\tVega\tBS Vanna\tVanna\tBS Vomma\tVomma");
    final int n = pdeRes.getNumberSpaceNodes();
    for (int i = 0; i < n; i++) {
      final double x = pdeRes.getSpaceValue(i);
      final double k = x * forward;
      final double mPrice = pdeRes.getFunctionValue(i);
      try {
        final double bsVol = BlackFormulaRepository.impliedVolatility(mPrice, 1.0, x, maxT, _isCall);
        final double bsVega = BlackFormulaRepository.vega(forward, k, maxT, bsVol);
        final double bsVanna = BlackFormulaRepository.vanna(forward, k, maxT, bsVol);
        final double bsVomma = BlackFormulaRepository.vomma(forward, k, maxT, bsVol);
        final double modelVega = forward * (pdeResUp.getFunctionValue(i) - pdeResDown.getFunctionValue(i)) / 2 / volShift;

        //xVanna is the vanna if the moneyness parameterised local vol surface was invariant to changes in the forward curve
        final double xVanna = (pdeResUp.getFunctionValue(i) - pdeResDown.getFunctionValue(i)
            - x * (pdeResUp.getFirstSpatialDerivative(i) - pdeResDown.getFirstSpatialDerivative(i))) / 2 / volShift;
        //this is the vanna coming purely from deformation of the local volatility surface
        final double surfaceVanna = (pdeResUpUp.getFunctionValue(i) + pdeResDownDown.getFunctionValue(i) -
            pdeResUpDown.getFunctionValue(i) - pdeResDownUp.getFunctionValue(i)) / 4 / fwdShift / volShift;
        final double modelVanna = xVanna + surfaceVanna;
        final double modelVomma = forward * (pdeResUp.getFunctionValue(i) + pdeResDown.getFunctionValue(i)
            - 2 * pdeRes.getFunctionValue(i)) / volShift / volShift;
        ps.println(k + "\t" + bsVega + "\t" + modelVega + "\t" + bsVanna + "\t" + modelVanna + "\t" + bsVomma + "\t" + modelVomma);
View Full Code Here

    final MeshingFunction timeMesh = new DoubleExponentialMeshing(0, expiry, expiry / 2, nTimeNodes, timeMeshLambda, -timeMeshLambda);
    //keep the grid the same regardless of spot (useful for finite-difference)
    final MeshingFunction spaceMesh = new HyperbolicMeshing(0.0, maxFwd, fwdNodeCentre, nFwdNodes, spotMeshBunching);
    final PDEGrid1D grid = new PDEGrid1D(timeMesh, spaceMesh);
    final PDE1DDataBundle<ConvectionDiffusionPDE1DCoefficients> db = new PDE1DDataBundle<>(pde, payoff, lower, upper, grid);
    final PDEResults1D res = solver.solve(db);
    return res;
  }
View Full Code Here

    final BoundaryCondition lower = new DirichletBoundaryCondition(0, 0);
    final BoundaryCondition upper = new NeumannBoundaryCondition(1.0, upperLevel, false);
    final MeshingFunction timeMesh = new ExponentialMeshing(0.0, EXPIRY, nTimeNodes, 6.0);
    final MeshingFunction spaceMesh = new HyperbolicMeshing(0, upperLevel, STRIKE, nSpotNodes, 0.05);
    final PDEGrid1D grid = new PDEGrid1D(timeMesh, spaceMesh);
    final PDEResults1D res = solver.solve(new PDE1DDataBundle<>(pde, payoff, lower, upper, grid));

    final int fwdIndex = grid.getLowerBoundIndexForSpace(forward);
    final double[] fwd = new double[4];
    final double[] vol = new double[4];
    for (int i = 0; i < 4; i++) {
      fwd[i] = grid.getSpaceNode(i + fwdIndex - 1);
      final double price = res.getFunctionValue(i + fwdIndex - 1);
      vol[i] = BlackFormulaRepository.impliedVolatility(price, fwd[i], STRIKE, EXPIRY, true);
    }
    final Interpolator1DDoubleQuadraticDataBundle idb = INTERPOLATOR_1D.getDataBundle(fwd, vol);

    final double sabrVol = SABR_SURFACE.getVolatility(EXPIRY, STRIKE);
View Full Code Here

      BoundaryCondition lowerB = new NeumannBoundaryCondition(isCall ? 0 : -1, sL, true);
      BoundaryCondition upperB = new NeumannBoundaryCondition(isCall ? 1 : 0, sH, false);

      Function1D<Double, Double> bkdIC = initialConProvider.getEuropeanPayoff(k, isCall);
      PDE1DDataBundle<ConvectionDiffusionPDE1DCoefficients> dbB = new PDE1DDataBundle<ConvectionDiffusionPDE1DCoefficients>(pdeB, bkdIC, lowerB, upperB, gridB);
      PDEResults1D resB = solver.solve(dbB);
      double price1 = resB.getFunctionValue(index);
      double price2 = resB.getFunctionValue(index + 1);
      double vol1 = BlackFormulaRepository.impliedVolatility(price1, s1, k, t, isCall);
      double vol2 = BlackFormulaRepository.impliedVolatility(price2, s2, k, t, isCall);
      double volBPDE = w * vol1 + (1 - w) * vol2;

      //      double price = BlackFormulaRepository.price(fwd, k, t, vol, isCall);
View Full Code Here

    final MeshingFunction timeMesh = new ExponentialMeshing(0.0, EXPIRY, 100, 0.0);
    final MeshingFunction spaceMesh = new ExponentialMeshing(yL, yH, 101, 0.0);

    final PDEGrid1D grid = new PDEGrid1D(timeMesh, spaceMesh);
    final PDE1DDataBundle<ConvectionDiffusionPDE1DCoefficients> db = new PDE1DDataBundle<>(pde, PURE_LOG_PAY_OFF, lower, upper, grid);
    final PDEResults1D res = solver.solve(db);

    final int n = res.getNumberSpaceNodes();

    final double val = res.getFunctionValue(n / 2);
    return val;
  }
View Full Code Here

    final MeshingFunction timeMesh = new ExponentialMeshing(0, EXPIRY, 100, 0.0);
    final MeshingFunction spaceMesh = new ExponentialMeshing(fL, fH, 101, 0.0);

    final PDEGrid1D grid = new PDEGrid1D(timeMesh, spaceMesh);
    final PDE1DDataBundle<ConvectionDiffusionPDE1DCoefficients> db = new PDE1DDataBundle<>(PDE, INITIAL_COND, lower, upper, grid);
    final PDEResults1D res = solver.solve(db);

    final int n = res.getNumberSpaceNodes();
    //    for (int i = 0; i < n; i++) {
    //      System.out.println(res.getSpaceValue(i) + "\t" + res.getFunctionValue(i));
    //    }

    //System.out.println("debug " + res.getFunctionValue(n / 2));

    final double kVol = Math.sqrt(-2 * (res.getFunctionValue(n / 2) - Math.log(ft)) / EXPIRY);
    //  System.out.println("expected:" + FLAT_VOL + " actual:" + kVol);
    assertEquals(FLAT_VOL, kVol, 1e-6);

    //test the new backwards local vol method for expected variance
    final YieldAndDiscountCurve yieldCurve = new YieldCurve("test", ConstantDoublesCurve.from(DRIFT));
View Full Code Here

TOP

Related Classes of com.opengamma.analytics.financial.model.finitedifference.PDEResults1D

Copyright © 2018 www.massapicom. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.