finMath.net

Algorithmic Differentiation to derive Forward Sensitivities

Getting started

The experiments below use Java JShell started from a Maven project as a starting point (if you already started JShell from finmath-experiments you may continue in that shell, although it is safer to /exit that shell and restart a new one).
  1. Open a command shell
  2. Type mkdir git (to create a folder git, if you do not have one)
  3. Type cd git (to enter your git folder)
  4. Next, clone (i.e. download) the repository (git), change to the cloned directory (cd) and start jshell via Maven (mvn) by typing the following three commands:
Terminal Window

				git clone https://github.com/finmath/finmath-experiments        
				cd finmath-experiments
				mvn clean compile jshell:run
			

Experiment 0: Monte-Carlo Simulation and Valuation (Recap)

Run the following experiment from your JShell (which was launched from finmath-experiments).

Initial Setup

In the experiments on the Monte-Carlo simulation a simulation object and a product object has been created and the delta of option has been evaluated using finite difference. Repeat this:

Create the model and its simulation:

JShell:

				import net.finmath.montecarlo.*;
				import net.finmath.montecarlo.assetderivativevaluation.*;
				import net.finmath.montecarlo.assetderivativevaluation.models.*;
				import net.finmath.montecarlo.automaticdifferentiation.*;
				import net.finmath.montecarlo.automaticdifferentiation.backward.*;
				import net.finmath.montecarlo.process.*;
				import net.finmath.time.*;
				
				double modelInitialValue = 100.0;
				double modelRiskFreeRate = 0.05;
				double modelVolatility = 0.20;
				
				RandomVariableFactory randomVariableFactory = new RandomVariableDifferentiableAADFactory();
				
				// Create a model
				var model = new BlackScholesModel(modelInitialValue, modelRiskFreeRate, modelVolatility, randomVariableFactory);
				
				// Create a corresponding MC process
				var td = new TimeDiscretizationFromArray(0.0, 300, 0.01);
				var brownianMotion = new BrownianMotionLazyInit(td, 1, 10000, 3231);
				var process = new EulerSchemeFromProcessModel(brownianMotion);
				
				// Using the process (Euler scheme), create an MC simulation of a Black-Scholes model
				var simulation = new MonteCarloAssetModel(model, process);
			

Create the product:

JShell:

				import net.finmath.montecarlo.assetderivativevaluation.products.*;
				
				double maturity = 3.0;
				double strike = 106.0;
				
				var europeanOption = new EuropeanOption(maturity, strike);
			

Experiment 1 - Dynamic delta hedge using algorithmic differentiation (requires run of "Initial Setup")

The class DeltaHedgedPortfolioWithAAD takes any financial product (any object implementing AssetMonteCarloProduct) and performs a so called “delta hedge” (on the simulation's time discretization). It uses AAD to calculate the delta \( \phi(t,\omega_{k}) = V(T,\omega_{k}) / S(t,\omega_{k}) \) and constructs the hedge portfolio (replication portfolio) from it.

Important: We will first conduct an experiment which will (likely) give wrong results. We will then fix the issue.

JShell: (continued)

				import net.finmath.plots.*;

				var hedge = new DeltaHedgedPortfolioWithAAD(europeanOption);
				var underlyingAtMaturity = simulation.getAssetValue(maturity, 0);
				var hedgeValue = hedge.getValue(maturity, simulation);

				var plot = Plots.createPlotScatter(underlyingAtMaturity, hedgeValue, 50.0, 110.0);
				plot.setTitle("Hedge Portfolio").setXAxisLabel("underlying").setYAxisLabel("portfolio value");
				plot.show();
			

The result of this experiment is a hedge portfolio which is constant at maturities. The reason is that all values of delta are 0 (except the one at the initial time t0). In the default setting, the algorithm implemented in RandomVariableDifferentiableAAD will only retain derivatives of the leaf nodes of the operator tree. It does not retain the derivatives of intermediate values (since this consumes a significant amount of memory). We can change this by passing a property to the RandomVariableDifferentiableAADFactory.

Re-create the model and its simulation (with the modified RandomVariableDifferentiableAADFactory):

JShell:

				import net.finmath.montecarlo.*;
				import net.finmath.montecarlo.automaticdifferentiation.*;
				import net.finmath.montecarlo.automaticdifferentiation.backward.*;
				
				Map<String, Object> properties = Map.of("isGradientRetainsLeafNodesOnly", false);		// CHANGE MADE HERE
				RandomVariableFactory randomVariableFactory = new RandomVariableDifferentiableAADFactory(properties);
				
				// Create a model
				var model = new BlackScholesModel(modelInitialValue, modelRiskFreeRate, modelVolatility, randomVariableFactory);
				
				// Create a corresponding MC process
				var td = new TimeDiscretizationFromArray(0.0, 300, 0.01);
				var brownianMotion = new BrownianMotionLazyInit(td, 1, 10000, 3231);
				var process = new EulerSchemeFromProcessModel(brownianMotion);
				
				// Using the process (Euler scheme), create an MC simulation of a Black-Scholes model
				var simulation = new MonteCarloAssetModel(model, process);
			
Now perform the hedge simulation on the newly created simulation.
JShell: (continued)

				import net.finmath.plots.*;

				var hedge = new DeltaHedgedPortfolioWithAAD(europeanOption);
				var underlyingAtMaturity = simulation.getAssetValue(maturity, 0);
				var hedgeValue = hedge.getValue(maturity, simulation);

				var plot = Plots.createPlotScatter(underlyingAtMaturity, hedgeValue, 50.0, 110.0);
				plot.setTitle("Hedge Portfolio").setXAxisLabel("underlying").setYAxisLabel("portfolio value");
				plot.show();