google / google/tf-quant-finance

Discrete dividens for american options

Open
#70 24 comments 0 reactions 0 assignees View on GitHub
Dominant language
Python
Stars
5.5k
Forks
698
PR merge metrics
No merged PRs in 30d

Description

My goal is to compute american option prices with discrete dividends on a specific date. The example provided for American options does not indicate how could this be done.

```
# Define the coordinate grid
s_min = 0.01
s_max = 300.
grid = pde.grids.uniform_grid(minimums=[s_min],
maximums=[s_max],
sizes=[number_grid_points],
dtype=dtype)

# Define the values grid for the final condition
s = grid[0]
final_values_grid = tf.nn.relu(s - strike)

# Define the PDE coefficient functions
def second_order_coeff_fn(t, grid):
del t
s = grid[0]
return [[volatility ** 2 * s ** 2 / 2]]

def first_order_coeff_fn(t, grid):
del t
s = grid[0]
return [risk_free_rate * s]

def zeroth_order_coeff_fn(t, grid):
del t, grid
return -risk_free_rate

# Define the boundary conditions
@pde.boundary_conditions.dirichlet
def lower_boundary_fn(t, grid):
del t, grid
return tf.constant(0.0, dtype=dtype)

@pde.boundary_conditions.dirichlet
def upper_boundary_fn(t, grid):
del grid
return tf.squeeze(s_max - strike * tf.exp(-risk_free_rate * (expiry - t)))

# In order to price American option one needs to set option values to
# V(x) := max(V(x), max(x - strike, 0)) after each iteration
def values_transform_fn(t, grid, values):
del t
s = grid[0]
values_floor = tf.nn.relu(s - strike)
return grid, tf.maximum(values, values_floor)
```

Given that discrete options happen at a specific date I thought it would be possible to change the value of spot (s) by the respective dividend after the ex_date occurs. Lets say that expiry = 0.8 and for example ex_date = 0.5, with a dividend of 1.5%, then the code would become:

```
# Define the coordinate grid
s_min = 0.01
s_max = 300.
grid = pde.grids.uniform_grid(minimums=[s_min],
maximums=[s_max],
sizes=[number_grid_points],
dtype=dtype)

# Define the values grid for the final condition
s = grid[0]
final_values_grid = tf.nn.relu(s - strike)

# Define the PDE coefficient functions
def second_order_coeff_fn(t, grid):
s = grid[0]
if t.numpy() > 0.5:
s = s*(1 - 0.015)
del t
return [[volatility ** 2 * s ** 2 / 2]]

def first_order_coeff_fn(t, grid):
s = grid[0]
if t.numpy() > 0.5:
s = s*(1 - 0.015)
del t
return [risk_free_rate * s]

def zeroth_order_coeff_fn(t, grid):
del t, grid
return -risk_free_rate

# Define the boundary conditions
@pde.boundary_conditions.dirichlet
def lower_boundary_fn(t, grid):
del t, grid
return tf.constant(0.0, dtype=dtype)

@pde.boundary_conditions.dirichlet
def upper_boundary_fn(t, grid):
del grid
return tf.squeeze(s_max - strike * tf.exp(-risk_free_rate * (expiry - t)))

# In order to price American option one needs to set option values to
# V(x) := max(V(x), max(x - strike, 0)) after each iteration
def values_transform_fn(t, grid, values):
s = grid[0]
if t.numpy() > 0.5:
s = s*(1 - 0.015)
del t
values_floor = tf.nn.relu(s - strike)
return grid, tf.maximum(values, values_floor)
```

Unfortunately, this approach does not yield proper results when compared with Quantlib. Does the tff library allow for the computation of option prices using discrete dividends? Ideally the only thing that it is required is to shift all spot prices based on the dividend starting at ex date.

Thank you in advance

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.