This runs a couple of simulations to demonstrate the "exact" method for selected one dimensional processes.
First, it runs a simulation of equations 5.1 and 5.2 from the reference paper using the Euler scheme. The code outputs (some of) the paths generated. It also outputs the volatility smile. Note that the volatility smile matches the smile in Figure 1 on page 18 of the reference paper.
Next, it runs a simulation of the same two processes, this time using the "exact" method. The smiles for both equations and simulation types are saved in the data.frame allImpVols for a plot comparison at the end.
The output for each method is the $E[max(X_T-K, 0)]$ for a range of K, along with the implied volatility. Each method also generates a plot of (some of) the simulated paths.
Also included are two toy examples for a mean reverting and a linear deterministic drift process, though they appear insufficient at the moment.
In [1]:
source('coefficients.r')
source('general_euler.r')
source('driftless_exact.r')
source('drifted_exact.r')
source('simulations.r')
In [2]:
T <- 1
X0 <- 1
strikes <- seq(0.6, 1.5, by=0.1)
allImpVols <- data.frame(K=strikes) # Save to global object for overlaid plots
In [10]:
numPathsEuler <- 100000
numStepsEuler <- 100
In [4]:
# Some other mu and sigma functions to try out
#sigma <- make_affine_coefficient(1, 0) # Black-Scholes with sigma <- 1
#mu <- make_mean_reverting_coefficient(0.8, 1.0)
#sigma <- make_constant_coefficient(1)
euler51_process <- General_Euler(numPathsEuler, numStepsEuler,
mu=make_constant_coefficient(0),
sigma=sigma_from_paper,
T=T, X0=X0)
run_euler(euler51_process, strikes, T, X0, make_call_payoff, saveColumn='Euler 5.1')
In [11]:
euler52_process <- General_Euler(numPathsEuler, numStepsEuler,
mu_from_paper,
sigma=make_constant_coefficient(1),
T=T, X0=X0,
convert_y_to_x=convert_y_to_x_1d,
convert_x_to_y=convert_x_to_y_1d)
run_euler(euler52_process, strikes, T, X0, make_call_payoff, saveColumn='Euler 5.2')
In [4]:
numPathsExact <- 100000
beta <- 0.2
In [7]:
exact51_process <- Driftless_Exact(numPathsExact, beta, sigma_from_paper, sigma_deriv_from_paper, T, X0)
run_exact(exact51_process, strikes, T, X0, make_call_payoff, saveColumn='Exact 5.1')
In [8]:
exact52_process <- Drifted_Exact(numPathsExact, beta,
mu_from_paper,
sigma0=1,
T=T, X0=X0,
convert_y_to_x=convert_y_to_x_1d,
convert_x_to_y=convert_x_to_y_1d)
run_exact(exact52_process, strikes, T, X0, make_call_payoff, saveColumn='Exact 5.2')
In [9]:
matplot(allImpVols$K, allImpVols[names(allImpVols)!='K']*100,
xlab='K', ylab='Imp. Vol. x 100', type='l', lty=1, las=1)
legend('topright', inset=.2, legend=names(allImpVols)[names(allImpVols)!='K'], lty=1, col=1:(ncol(allImpVols)-1))
In [ ]:
drifted_process <- Drifted_Exact(numPathsExact, beta,
mu=make_mean_reverting_coefficient(-.8, 1),
sigma0=1,
T=T, X0=1)
run_exact(drifted_process, strikes, T, X0, saveColumn='Mean Reverting Exact')
In [ ]:
lin_drift_euler_process <- General_Euler(numPathsEuler, numStepsEuler,
mu=function(t,x) t,
sigma=make_constant_coefficient(1),
X0=1)
run_euler(lin_drift_euler_process, strikes, T, X0=1, saveColumn='Linear Drift Euler')
lin_drift_exact_process <- Drifted_Exact(numPathsExact, beta, mu=function(t,x) t, sigma0=1, X0=1)
run_exact(lin_drift_exact_process, strikes, T, X0=1, saveColumn='Linear Drift Exact')