European option pricing in closed form and Monte-Carlo#

[2]:
from quant_analytics_torch.calculators.multivariatebrownianbridge import MultivariateBrownianBridge
from quant_analytics_torch.analytics.norminv import norminv
from quant_analytics_torch.analytics import maxsoft
from quant_analytics_torch.analytics import blackanalytics
import torch
[40]:
torch.set_default_dtype(torch.float64)

Illustrate the pricing of a European option with payoff function \(f(x)=\left(x-k\right)^+\) using both closed form solution and Monte-Carlo

[41]:
f = torch.tensor(1.0, requires_grad=True)
k = torch.tensor(1.0)
sigma = torch.tensor(0.2,requires_grad=True)
t = torch.tensor(1.0)

Use closed form pricing first, and show the \(\Delta\)

[42]:
v = blackanalytics.black_torch(f,k,t,sigma,0)
print(v)
dx, = torch.autograd.grad(v, f)
print(dx)
tensor(0.0797, grad_fn=<SubBackward0>)
tensor(0.5398)

Next we do the same using Monte-Carlo. First we build the forward covariance matrix

[43]:
states = 1
dim = 1

fm = torch.zeros(size=(states,states))

fm[0][0] = sigma*sigma*t
fwd_cov = torch.zeros(size=(dim, states, states))

for i in range(dim):
    fwd_cov[i] = fm

Initialise the multivariate Brownian bridge

[44]:
multivariate_brownian = MultivariateBrownianBridge(fwd_cov)

Initialise the SobolEngine. Note that we need to skip the first path

[45]:
    sobol_engine =  torch.quasirandom.SobolEngine(dim*states)
    x = sobol_engine.draw(1)
[51]:
paths = 2**13-1
x = sobol_engine.draw(paths,dtype=torch.float64)
[52]:
y = torch.transpose(norminv(x),0,1)
y = torch.reshape(y, shape=(dim,states,paths))
[53]:
dz = multivariate_brownian.path(y, True)

Simulate the underlying

[54]:
s = f*torch.exp(-fm[0][0]/2 + dz)

Evaluate the payoff. Note that value aligns very closely with the closed form solution

[55]:
v = torch.mean(maxsoft.soft_max_hyperbolic(s-k))
print(v)
dx, = torch.autograd.grad(v, f, create_graph=True, retain_graph=True, allow_unused=True)
print(dx)
tensor(0.0797, grad_fn=<MeanBackward0>)
tensor(0.5399, grad_fn=<SumBackward0>)
[ ]: