Last updated: 2023-03-16.
tf_quant_finance.models.hull_white.VectorHullWhiteModel#
Ensemble of correlated Hull-White Models.
Inherits From: GenericItoProcess
tf_quant_finance.models.hull_white.VectorHullWhiteModel(
dim, mean_reversion, volatility, initial_discount_rate_fn, corr_matrix=None,
dtype=None, name=None
)
Represents the Ito process:
dr_i(t) = (theta_i(t) - a_i(t) * r_i(t)) dt + sigma_i(t) * dW_{r_i}(t),
1 <= i <= n,
where W_{r_i} are 1D Brownian motions with a correlation matrix Rho(t).
For each i, r_i is the Hull-White process.
theta_i, a_i, sigma_i, Rho are positive functions of time.
a_i correspond to the mean-reversion rate, sigma_i is the volatility of
the process, theta_i(t) is the function that determines long run behaviour
of the process r(t) = (r_1(t), ..., r_n(t))
and is computed to match the initial (at t=0) discount curve:
\theta_i = df_i(t) / dt + a_i * f_i(t) + 0.5 * sigma_i**2 / a_i
* (1 - exp(-2 * a_i *t)), 1 <= i <= n
where f_i(t) is the instantaneous forward rate at time 0 for a maturity
t and df_i(t)/dt is the gradient of f_i with respect to the maturity.
See Section 3.3.1 of [1] for details.
The price at time t of a zero-coupon bond maturing at T is given by
(Ref. [2]):
P(t,T) = P(0,T) / P(0,t) *
exp(-(r(t) - f(0,t)) * G(t,T) - 0.5 * y(t) * G(t,T)^2)
y(t) = int_0^t [exp(-2 int_u^t (a(s) ds)) sigma(u)^2 du]
G(t,T) = int_t^T [exp(-int_t^u a(s) ds) du]
If mean-reversion, a_i, is constant and the volatility (sigma_i), and
correlation (Rho) are piecewise constant functions, the process is sampled
exactly. Otherwise, Euler sampling is used.
For n=1 this class represents Hull-White Model (see
tff.models.hull_white.HullWhiteModel1F).
References:#
[1]: D. Brigo, F. Mercurio. Interest Rate Models. 2007. [2]: Leif B. G. Andersen and Vladimir V. Piterbarg. Interest Rate Modeling. Volume II: Term Structure Models.
Args:#
dim: A Python scalar which corresponds to the number of correlated Hull-White Models.mean_reversion: A real positiveTensorof shape[dim]or a Python callable. The callable can be one of the following: (a) A left-continuous piecewise constant object (e.g.,tff.math.piecewise.PiecewiseConstantFunc) that has a propertyis_piecewise_constantset toTrue. In this case the object should have a methodjump_locations(self)that returns aTensorof shape[dim, num_jumps].mean_reversion(t)should return aTensorof shape[dim, num_points]wheretis either a rank 1Tensorof shape [num_points] or aTensorof shape[dim, num_points]. Herenum_pointsis arbitrary number of points. See example in the class docstring. (b) A callable that accepts scalars (stands for timet) and returns aTensorof shape[dim]. Corresponds to the mean reversion rate.volatility: A real positiveTensorof the samedtypeasmean_reversionor a callable with the same specs as above. Corresponds to the lond run price variance.initial_discount_rate_fn: A Python callable that accepts expiry time as a realTensorof the samedtypeasmean_reversionand returns aTensorof either shapeinput_shapeorinput_shape + [dim]. Corresponds to the zero coupon bond yield at the present time for the input expiry time.corr_matrix: ATensorof shape[dim, dim]and the samedtypeasmean_reversionor a Python callable. The callable can be one of the following: (a) A left-continuous piecewise constant object (e.g.,tff.math.piecewise.PiecewiseConstantFunc) that has a propertyis_piecewise_constantset toTrue. In this case the object should have a methodjump_locations(self)that returns aTensorof shape[num_jumps].corr_matrix(t)should return aTensorof shapet.shape + [dim, dim], wheretis a rank 1Tensorof the samedtypeas the output. (b) A callable that accepts scalars (stands for timet) and returns aTensorof shape[dim, dim]. Corresponds to the correlation matrixRho.dtype: The default dtype to use when converting values toTensors. Default value:Nonewhich maps totf.float32.name: Python string. The name to give to the ops created by this class. Default value:Nonewhich maps to the default namehull_white_model.
Attributes:#
mean_reversionvolatility
Raises:#
ValueError: (a) If eithermean_reversion,volatility, orcorr_matrixis a piecewise constant function wherejump_locationshave batch shape of rank > 1. (b): If batch rank of thejump_locationsis[n]withndifferent fromdim.
Methods#
dim
dim()
The dimension of the process.
discount_bond_price
discount_bond_price(
short_rate, times, maturities, name=None
)
Returns zero-coupon bond prices P(t,T) conditional on r(t).
Args:#
short_rate: ATensorof real dtype and shapebatch_shape + [dim]specifying the short rater(t).times: ATensorof real dtype and shapebatch_shape. The timetat which discount bond prices are computed.maturities: ATensorof real dtype and shapebatch_shape. The time to maturity of the discount bonds.name: Str. The name to give this op. Default value:discount_bond_prices.
Returns:#
A Tensor of real dtype and the same shape as batch_shape + [dim]
containing the price of zero-coupon bonds.
drift_fn
drift_fn()
Python callable calculating instantaneous drift.
The callable should accept two real Tensor arguments of the same dtype.
The first argument is the scalar time t, the second argument is the value of
Ito process X - Tensor of shape
batch_shape + sample_shape + [dim], where batch_shape represents a batch
of models and sample_shape represents samples for each of the models. The
result is value of drift a(t, X). The return value of the callable is a real
Tensor of the same dtype as the input arguments and of shape
batch_shape + sample_shape + [dim]. For example, sample_shape can stand
for [num_samples] for Monte Carlo sampling, or
[num_grid_points_1, ..., num_grid_points_dim] for Finite Difference
solvers.
Returns:#
The instantaneous drift rate callable.
dtype
dtype()
The data type of process realizations.
fd_solver_backward
fd_solver_backward(
start_time, end_time, coord_grid, values_grid, discounting=None,
one_step_fn=None, boundary_conditions=None, start_step_count=0, num_steps=None,
time_step=None, values_transform_fn=None, dtype=None, name=None, **kwargs
)
Returns a solver for Feynman-Kac PDE associated to the process.
This method applies a finite difference method to solve the final value problem as it appears in the Feynman-Kac formula associated to this Ito process. The Feynman-Kac PDE is closely related to the backward Kolomogorov equation associated to the stochastic process and allows for the inclusion of a discounting function.
For more details of the Feynman-Kac theorem see [1]. The PDE solved by this method is:
V_t + Sum[mu_i(t, x) V_i, 1<=i<=n] +
(1/2) Sum[ D_{ij} V_{ij}, 1 <= i,j <= n] - r(t, x) V = 0
In the above, V_t is the derivative of V with respect to t,
V_i is the partial derivative with respect to x_i and V_{ij} the
(mixed) partial derivative with respect to x_i and x_j. mu_i is the
drift of this process and D_{ij} are the components of the diffusion
tensor:
D_{ij}(t,x) = (Sigma(t,x) . Transpose[Sigma(t,x)])_{ij}
This method evolves a spatially discretized solution of the above PDE from
time t0 to time t1 < t0 (i.e. backwards in time).
The solution V(t,x) is assumed to be discretized on an n-dimensional
rectangular grid. A rectangular grid, G, in n-dimensions may be described
by specifying the coordinates of the points along each axis. For example,
a 2 x 4 grid in two dimensions can be specified by taking the cartesian
product of [1, 3] and [5, 6, 7, 8] to yield the grid points with
coordinates: [(1, 5), (1, 6), (1, 7), (1, 8), (3, 5) ... (3, 8)].
This method allows batching of solutions. In this context, batching means
the ability to represent and evolve multiple independent functions V
(e.g. V1, V2 …) simultaneously. A single discretized solution is specified
by stating its values at each grid point. This can be represented as a
Tensor of shape [d1, d2, … dn] where di is the grid size along the ith
axis. A batch of such solutions is represented by a Tensor of shape:
batch_shape + payoff_shape + [d1, d2, ... dn] where batch_shape is the
batch of processes as in the underlying drift_fn and volatility_fn and
payoff_shape are the equations to be solved for each batch element.
The evolution of the solution from t0 to t1 is often done by
discretizing the differential equation to a difference equation along
the spatial and temporal axes. The temporal discretization is given by a
(sequence of) time steps [dt_1, dt_2, … dt_k] such that the sum of the
time steps is equal to the total time step t0 - t1. If a uniform time
step is used, it may equivalently be specified by stating the number of
steps (n_steps) to take. This method provides both options via the
time_step and num_steps parameters. However, not all methods need
discretization along time direction (e.g. method of lines) so this argument
may not be applicable to some implementations.
The workhorse of this method is the one_step_fn. For the commonly used
methods, see functions in math.pde.steppers module.
The mapping between the arguments of this method and the above equation are described in the Args section below.
For a simple instructive example of implementation of this method, see
models.GenericItoProcess.fd_solver_backward.
Examples#
import tensorflow as tf
import numpy as np
import tf_quant_finance as tff
dtype = tf.float64
# Specify volatilities, interest rates and strikes for the options
volatilities = tf.constant([[0.3], [0.15], [0.1]], dtype)
rates = tf.constant([[0.01], [0.03], [0.01]], dtype)
expiries = 1.0
# Define Generic Ito Process
# Process dimensionality
dim = 1
# Batch size of the process
num_processes = 3
def drift_fn(t, x):
del t
# `x` is expected to be of shape [num_processes] + sample_shape + [dim]
# We need to expand rank of rates to
# `[num_processes] + extra_rank * [1] + [1]`
expand_rank = x.shape.rank - 2
rates_expand = tf.reshape(
rates, [num_processes] + (expand_rank + 1) * [1])
# Output is of shape [num_processes] + sample_shape + [dim]
return rates_expand * x
def vol_fn(t, x):
del t
# `x` is expected to be of shape [num_processes] + sample_shape + [dim]
# As before, need to expand rank of volatilities to
# `[num_processes] + extra_rank * [1] + [1]`
expand_rank = x.shape.rank - 2
volatilities_expand = tf.reshape(
volatilities, [num_processes] + (expand_rank + 1) * [1])
# Output is of shape [num_processes] + sample_shape + [dim, dim]
return (tf.expand_dims(volatilities_expand * x, axis=-1)
* tf.eye(dim, batch_shape=x.shape.as_list()[:-1], dtype=x.dtype))
process = tff.models.GenericItoProcess(dim=dim,
drift_fn=drift_fn,
volatility_fn=vol_fn,
dtype=dtype)
# Define a 2 strikes for each batch process,
num_strikes = 2
# Shape [num_processes, num_strikes, 1]. Here 1 at the end is just for
# convenience
strikes = tf.constant([[[50], [60]], [[100], [90]], [[120], [90]]], dtype)
# Price a batch of European call options
@tff.math.pde.boundary_conditions.dirichlet
def upper_boundary_fn(t, grid):
del grid
# Shape (num_processes, num_strikes)
return tf.squeeze(s_max - strikes * tf.exp(-rates * (expiries - t)))
# Define discounting function
def discounting(t, x):
del t, x
rates_expand = tf.expand_dims(rates, axis=-1)
# Shape compatible with (num_processes, num_strikes)
return rates_expand
# Build a uniform grid
s_min = 0
s_max = 200
num_grid_points = 256 # Number of grid points
grid = tff.math.pde.grids.uniform_grid(minimums=[s_min],
maximums=[s_max],
sizes=[num_grid_points],
dtype=dtype)
# Shape [num_processes, num_strikes, num_grid_points]
final_value_grid = tf.nn.relu(grid[0] - strikes)
# Estimated prices for the European options
process.fd_solver_backward(
start_time=expiries,
end_time=0,
time_step=0.1,
coord_grid=grid,
values_grid=final_value_grid,
discounting=discounting,
boundary_condtions=[(None, upper_boundary_fn)])[0]
# Shape of the output is [num_processes, num_strikes, num_grid_points]
Args:#
start_time: Real positive scalarTensor. The start time of the grid. Corresponds to timet0above.end_time: Real scalarTensorsmaller than thestart_timeand greater than zero. The time to step back to. Corresponds to timet1above.coord_grid: List ofnrank 1 realTensors.nis the dimension of the domain. The i-thTensorhas shape,[d_i]whered_iis the size of the grid along axisi. The coordinates of the grid points. Corresponds to the spatial gridGabove.values_grid: RealTensorcontaining the function values at timestart_timewhich have to be stepped back to timeend_time. The shape of theTensormust broadcast withbatch_shape + payoff_shape + [d_1, d_2, ..., d_n].batch_shaperepresents the batch of the processes as in the underlyingdrift_fnandvolatility_fn.payoff_shapespecifies equations to be solved for each batch element (with potentially different boundary/final conditions and for various coordinate grids). When the batch dimensionsbatch_shapeorpayoff_shapeare present, the shape of values_gridmust be at leastbatch_shape + payoff_shape + dim * [1]`.discounting: Callable corresponding tor(t,x)above. If not supplied, zero discounting is assumed.one_step_fn: The transition kernel. A callable that consumes the following arguments by keyword:‘time’: Current time
‘next_time’: The next time to step to. For the backwards in time evolution, this time will be smaller than the current time.
‘coord_grid’: The coordinate grid.
‘values_grid’: The values grid.
‘boundary_conditions’: The boundary conditions.
‘quadratic_coeff’: A callable returning the quadratic coefficients of the PDE (i.e.
(1/2)D_{ij}(t, x)above). The callable accepts the time and coordinate grid as keyword arguments and returns aTensorwith shape that broadcasts with[dim, dim].‘linear_coeff’: A callable returning the linear coefficients of the PDE (i.e.
mu_i(t, x)above). Accepts time and coordinate grid as keyword arguments and returns aTensorwith shape that broadcasts with[dim].‘constant_coeff’: A callable returning the coefficient of the linear homogeneous term (i.e.
r(t,x)above). Same spec as above. Theone_step_fncallable returns a 2-tuple containing the next coordinate grid, next values grid.
boundary_conditions: The boundary conditions. Only rectangular boundary conditions are supported. A list of tuples of sizen(space dimension of the PDE). The elements of the Tuple can be either a Python Callable orNonerepresenting the boundary conditions at the minimum and maximum values of the spatial variable indexed by the position in the list. E.g., forn=2, the length ofboundary_conditionsshould be 2,boundary_conditions[0][0]describes the boundary(y_min, x), andboundary_conditions[1][0]- the boundary(y, x_min).Nonevalues mean that the second order terms for that dimension on the boundary are assumed to be zero, i.e., ifboundary_conditions[k][0]isNone, ‘dV/dt + Sum[a_ij d2(A_ij V)/dx_i dx_j, 1 <= i, j <= n, i!=k+1, j!=k+1]Sum[b_i d(B_i V)/dx_i, 1 <= i <= n] + c V = 0.’ For not
Nonevalues, the boundary conditions are accepted in the formalpha(t, x) V + beta(t, x) V_n = gamma(t, x), whereV_nis the derivative with respect to the exterior normal to the boundary. Each callable receives the current timetand thecoord_gridat the current time, and should return a tuple ofalpha,beta, andgamma. Each can be a number, a zero-rankTensoror aTensorwhose shape is the grid shape with the corresponding dimension removed. For example, for a two-dimensional grid of shape(b, ny, nx), wherebis the batch size,boundary_conditions[0][i]withi = 0, 1should return a tuple of either numbers, zero-rank tensors or tensors of shape(b, nx). Similarly forboundary_conditions[1][i], except the tensor shape should be(b, ny).alphaandbetacan also beNonein case of Neumann and Dirichlet conditions, respectively. Default value:None. Unlike settingNoneto individual elements ofboundary_conditions, setting the entireboundary_conditionsobject toNonemeans Dirichlet conditions with zero value on all boundaries are applied.
start_step_count: Scalar integerTensor. Initial value for the number of time steps performed. Default value: 0 (i.e. no previous steps performed).num_steps: Positive int scalarTensor. The number of time steps to take when moving fromstart_timetoend_time. Either this argument or thetime_stepargument must be supplied (but not both). If num steps isk>=1, uniform time steps of size(t0 - t1)/kare taken to evolve the solution fromt0tot1. Corresponds to then_stepsparameter above.time_step: The time step to take. Either this argument or thenum_stepsargument must be supplied (but not both). The type of this argument may be one of the following (in order of generality): (a) None in which casenum_stepsmust be supplied. (b) A positive real scalarTensor. The maximum time step to take. If the value of this argument isdt, then the total number of steps taken is N = (t0 - t1) / dt rounded up to the nearest integer. The first N-1 steps are of size dt and the last step is of sizet0 - t1 - (N-1) * dt. (c) A callable accepting the current time and returning the size of the step to take. The input and the output are real scalarTensors.values_transform_fn: An optional callable applied to transform the solution values at each time step. The callable is invoked after the time step has been performed. The callable should accept the time of the grid, the coordinate grid and the values grid and should return the values grid. All input arguments to be passed by keyword.dtype: The dtype to use.name: The name to give to the ops. Default value: None which meanssolve_backwardis used.**kwargs: Additional keyword args: (1) pde_solver_fn: Function to solve the PDE that accepts all the above arguments by name and returns the same tuple object as required below. Defaults totff.math.pde.fd_solvers.solve_backward.
Returns:#
A tuple object containing at least the following attributes:
final_values_grid: A Tensor of same shape and dtype as values_grid.
Contains the final state of the values grid at time end_time.
final_coord_grid: A list of Tensors of the same specification as
the input coord_grid. Final state of the coordinate grid at time
end_time.
step_count: The total step count (i.e. the sum of the start_step_count
and the number of steps performed in this call.).
final_time: The final time at which the evolution stopped. This value
is given by max(min(end_time, start_time), 0).
fd_solver_forward
fd_solver_forward(
start_time, end_time, coord_grid, values_grid, one_step_fn=None,
boundary_conditions=None, start_step_count=0, num_steps=None, time_step=None,
values_transform_fn=None, dtype=None, name=None, **kwargs
)
Returns a solver for the Fokker Plank equation of this process.
The Fokker Plank equation (also known as the Kolmogorov Forward equation) associated to this Ito process is given by:
V_t + Sum[(mu_i(t, x) V)_i, 1<=i<=n]
- (1/2) Sum[ (D_{ij} V)_{ij}, 1 <= i,j <= n] = 0
with the initial value condition $\(V(0, x) = u(x)\)$.
This method evolves a spatially discretized solution of the above PDE from
time t0 to time t1 > t0 (i.e. forwards in time).
The solution V(t,x) is assumed to be discretized on an n-dimensional
rectangular grid. A rectangular grid, G, in n-dimensions may be described
by specifying the coordinates of the points along each axis. For example,
a 2 x 4 grid in two dimensions can be specified by taking the cartesian
product of [1, 3] and [5, 6, 7, 8] to yield the grid points with
coordinates: [(1, 5), (1, 6), (1, 7), (1, 8), (3, 5) ... (3, 8)].
This method allows batching of solutions. In this context, batching means
the ability to represent and evolve multiple independent functions V
(e.g. V1, V2 …) simultaneously. A single discretized solution is specified
by stating its values at each grid point. This can be represented as a
Tensor of shape [d1, d2, … dn] where di is the grid size along the ith
axis. A batch of such solutions is represented by a Tensor of shape:
batch_shape + payoff_shape + [d1, d2, ... dn] where batch_shape is the
batch of processes as in the underlying drift_fn and volatility_fn and
payoff_shape are the equations to be solved for each batch element.
The evolution of the solution from t0 to t1 is often done by
discretizing the differential equation to a difference equation along
the spatial and temporal axes. The temporal discretization is given by a
(sequence of) time steps [dt_1, dt_2, … dt_k] such that the sum of the
time steps is equal to the total time step t1 - t0. If a uniform time
step is used, it may equivalently be specified by stating the number of
steps (n_steps) to take. This method provides both options via the
time_step and num_steps parameters. However, not all methods need
discretization along time direction (e.g. method of lines) so this argument
may not be applicable to some implementations.
The workhorse of this method is the one_step_fn. For the commonly used
methods, see functions in math.pde.steppers module.
The mapping between the arguments of this method and the above equation are described in the Args section below.
For a simple instructive example of implementation of this method, see
models.GenericItoProcess.fd_solver_forward.
Args:#
start_time: Real positive scalarTensor. The start time of the grid. Corresponds to timet0above.end_time: Real scalarTensorsmaller than thestart_timeand greater than zero. The time to step back to. Corresponds to timet1above.coord_grid: List ofnrank 1 realTensors.nis the dimension of the domain. The i-thTensorhas shape,[d_i]whered_iis the size of the grid along axisi. The coordinates of the grid points. Corresponds to the spatial gridGabove.values_grid: RealTensorcontaining the function values at timestart_timewhich have to be stepped back to timeend_time. The shape of theTensormust broadcast withbatch_shape + payoff_shape + [d_1, d_2, ..., d_n].batch_shaperepresents the batch of the processes as in the underlyingdrift_fnandvolatility_fn.payoff_shapespecifies equations to be solved for each batch element (with potentially different boundary/final conditions and for various coordinate grids). When the batch dimensionsbatch_shapeorpayoff_shapeare present, the shape of values_gridmust be at leastbatch_shape + payoff_shape + dim * [1]`.one_step_fn: The transition kernel. A callable that consumes the following arguments by keyword:‘time’: Current time
‘next_time’: The next time to step to. For the backwards in time evolution, this time will be smaller than the current time.
‘coord_grid’: The coordinate grid.
‘values_grid’: The values grid.
‘quadratic_coeff’: A callable returning the quadratic coefficients of the PDE (i.e.
(1/2)D_{ij}(t, x)above). The callable accepts the time and coordinate grid as keyword arguments and returns aTensorwith shape that broadcasts with[dim, dim].‘linear_coeff’: A callable returning the linear coefficients of the PDE (i.e.
mu_i(t, x)above). Accepts time and coordinate grid as keyword arguments and returns aTensorwith shape that broadcasts with[dim].‘constant_coeff’: A callable returning the coefficient of the linear homogeneous term (i.e.
r(t,x)above). Same spec as above. Theone_step_fncallable returns a 2-tuple containing the next coordinate grid, next values grid.
boundary_conditions: The boundary conditions. Only rectangular boundary conditions are supported. A list of tuples of sizen(space dimension of the PDE). The elements of the Tuple can be either a Python Callable orNonerepresenting the boundary conditions at the minimum and maximum values of the spatial variable indexed by the position in the list. E.g., forn=2, the length ofboundary_conditionsshould be 2,boundary_conditions[0][0]describes the boundary(y_min, x), andboundary_conditions[1][0]- the boundary(y, x_min).Nonevalues mean that the second order terms for that dimension on the boundary are assumed to be zero, i.e., ifboundary_conditions[k][0]isNone, ‘dV/dt + Sum[a_ij d2(A_ij V)/dx_i dx_j, 1 <= i, j <= n, i!=k+1, j!=k+1]Sum[b_i d(B_i V)/dx_i, 1 <= i <= n] + c V = 0.’ For not
Nonevalues, the boundary conditions are accepted in the formalpha(t, x) V + beta(t, x) V_n = gamma(t, x), whereV_nis the derivative with respect to the exterior normal to the boundary. Each callable receives the current timetand thecoord_gridat the current time, and should return a tuple ofalpha,beta, andgamma. Each can be a number, a zero-rankTensoror aTensorwhose shape is the grid shape with the corresponding dimension removed. For example, for a two-dimensional grid of shape(b, ny, nx), wherebis the batch size,boundary_conditions[0][i]withi = 0, 1should return a tuple of either numbers, zero-rank tensors or tensors of shape(b, nx). Similarly forboundary_conditions[1][i], except the tensor shape should be(b, ny).alphaandbetacan also beNonein case of Neumann and Dirichlet conditions, respectively. Default value:None. Unlike settingNoneto individual elements ofboundary_conditions, setting the entireboundary_conditionsobject toNonemeans Dirichlet conditions with zero value on all boundaries are applied.
start_step_count: Scalar integerTensor. Initial value for the number of time steps performed. Default value: 0 (i.e. no previous steps performed).num_steps: Positive int scalarTensor. The number of time steps to take when moving fromstart_timetoend_time. Either this argument or thetime_stepargument must be supplied (but not both). If num steps isk>=1, uniform time steps of size(t0 - t1)/kare taken to evolve the solution fromt0tot1. Corresponds to then_stepsparameter above.time_step: The time step to take. Either this argument or thenum_stepsargument must be supplied (but not both). The type of this argument may be one of the following (in order of generality): (a) None in which casenum_stepsmust be supplied. (b) A positive real scalarTensor. The maximum time step to take. If the value of this argument isdt, then the total number of steps taken is N = (t1 - t0) / dt rounded up to the nearest integer. The first N-1 steps are of size dt and the last step is of sizet1 - t0 - (N-1) * dt. (c) A callable accepting the current time and returning the size of the step to take. The input and the output are real scalarTensors.values_transform_fn: An optional callable applied to transform the solution values at each time step. The callable is invoked after the time step has been performed. The callable should accept the time of the grid, the coordinate grid and the values grid and should return the values grid. All input arguments to be passed by keyword.dtype: The dtype to use.name: The name to give to the ops. Default value: None which meanssolve_forwardis used.**kwargs: Additional keyword args: (1) pde_solver_fn: Function to solve the PDE that accepts all the above arguments by name and returns the same tuple object as required below. Defaults totff.math.pde.fd_solvers.solve_forward.
Returns:#
A tuple object containing at least the following attributes:
final_values_grid: A Tensor of same shape and dtype as values_grid.
Contains the final state of the values grid at time end_time.
final_coord_grid: A list of Tensors of the same specification as
the input coord_grid. Final state of the coordinate grid at time
end_time.
step_count: The total step count (i.e. the sum of the start_step_count
and the number of steps performed in this call.).
final_time: The final time at which the evolution stopped. This value
is given by max(min(end_time, start_time), 0).
instant_forward_rate
instant_forward_rate(
t
)
Returns the instantaneous forward rate.
name
name()
The name to give to ops created by this class.
sample_discount_curve_paths
sample_discount_curve_paths(
times, curve_times, num_samples=1, random_type=None, seed=None, skip=0,
time_step=None, times_grid=None, normal_draws=None, validate_args=False,
name=None
)
Returns a sample of simulated discount curves for the Hull-white model.
References:#
[1]: Leif B.G. Andersen and Vladimir V. Piterbarg. Interest Rate Modeling, Volume II: Term Structure Models. 2010.
Args:#
times: Rank 1Tensorof positive real values. The times at which the discount curves are to be evaluated.curve_times: Rank 1Tensorof positive real values. The maturities at which discount curve is computed at each simulation time.num_samples: Positive scalarint. The number of paths to draw.random_type: Enum value ofRandomType. The type of (quasi)-random number generator to use to generate the paths. Default value: None which maps to the standard pseudo-random numbers.seed: Seed for the random number generator. The seed is only relevant ifrandom_typeis one of[STATELESS, PSEUDO, HALTON_RANDOMIZED, PSEUDO_ANTITHETIC, STATELESS_ANTITHETIC]. ForPSEUDO,PSEUDO_ANTITHETICandHALTON_RANDOMIZEDthe seed should be an Python integer. ForSTATELESSandSTATELESS_ANTITHETICmust be supplied as an integerTensorof shape[2]. Default value:Nonewhich means no seed is set.skip:int320-dTensor. The number of initial points of the Sobol or Halton sequence to skip. Used only whenrandom_typeis ‘SOBOL’, ‘HALTON’, or ‘HALTON_RANDOMIZED’, otherwise ignored. Default value:0.time_step: Scalar realTensor. Maximal distance between time grid points in Euler scheme. Used only when Euler scheme is applied. Default value:None.times_grid: An optional rank 1Tensorrepresenting time discretization grid. Iftimesare not on the grid, then the nearest points from the grid are used. When supplied,time_stepand jumps of the piecewise constant arguments are ignored. Default value:None, which means that the times grid is computed usingtime_step. When exact sampling is used, the shape should be equal to[num_time_points + 1]wherenum_time_pointsistf.shape(times)[0]plus the number of jumps of the Hull-White piecewise constant parameters. The grid should include the initial time point which is usually set to0.0.normal_draws: ATensorof shape[num_samples, num_time_points, dim]and the samedtypeastimes. Represents random normal draws to compute incrementsN(0, t_{n+1}) - N(0, t_n). When supplied,num_samplesargument is ignored and the first dimensions ofnormal_drawsis used instead. When exact sampling is used,num_time_pointsshould be equal totf.shape(times)[0]plus the number of jumps of the Hull-White piecewise constant parameters. Default value:Nonewhich means that the draws are generated by the algorithm.validate_args: Pythonbool. WhenTrueandnormal_drawsare supplied, checks thattf.shape(normal_draws)[1]is equal to the total number of time steps performed by the sampler. WhenFalseinvalid dimension may silently render incorrect outputs. Default value:False.name: Str. The name to give this op. Default value:sample_discount_curve_paths.
Returns:#
A tuple containing two Tensors. The first element is a Tensor of
shape [num_samples, m, k, dim] and contains the simulated bond curves
where m is the size of curve_times, k is the size of times and
dim is the dimension of the process. The second element is a Tensor
of shape [num_samples, k, dim] and contains the simulated short rate
paths.
Raises:#
ValueError: (a) Iftimeshas rank different from1. (b) If Euler scheme is used by times is not supplied. (c) When neithertimes_gridnortime_stepare supplied and Euler scheme is used. (d) Ifnormal_drawsis supplied anddimis mismatched.tf.errors.InvalidArgumentError: Ifnormal_drawsis supplied and the number of time steps implied bytimes_gridortimes_stepis mismatched. (e) If any of the parametersmean_reversion,volatility,corr_matrixis a generic callable.
sample_paths
sample_paths(
times, num_samples, random_type=None, seed=None, skip=0, time_step=None,
times_grid=None, normal_draws=None, validate_args=False, name=None
)
Returns a sample of paths from the correlated Hull-White process.
Uses exact sampling if self.mean_reversion is constant and
self.volatility and self.corr_matrix are all Tensors or piecewise
constant functions, and Euler scheme sampling otherwise.
The exact sampling implements the algorithm and notations in [1], section 10.1.6.1.
Args:#
times: Rank 1Tensorof positive real values. The times at which the path points are to be evaluated.num_samples: Positive scalarint32Tensor. The number of paths to draw.random_type: Enum value ofRandomType. The type of (quasi)-random number generator to use to generate the paths. Default value:Nonewhich maps to the standard pseudo-random numbers.seed: Seed for the random number generator. The seed is only relevant ifrandom_typeis one of[STATELESS, PSEUDO, HALTON_RANDOMIZED, PSEUDO_ANTITHETIC, STATELESS_ANTITHETIC]. ForPSEUDO,PSEUDO_ANTITHETICandHALTON_RANDOMIZEDthe seed should be an Python integer. ForSTATELESSandSTATELESS_ANTITHETICmust be supplied as an integerTensorof shape[2]. Default value:Nonewhich means no seed is set.skip:int320-dTensor. The number of initial points of the Sobol or Halton sequence to skip. Used only whenrandom_typeis ‘SOBOL’, ‘HALTON’, or ‘HALTON_RANDOMIZED’, otherwise ignored. Default value:0.time_step: Scalar realTensor. Maximal distance between time grid points in Euler scheme. Used only when Euler scheme is applied. Default value:None.times_grid: An optional rank 1Tensorrepresenting time discretization grid. Iftimesare not on the grid, then the nearest points from the grid are used. When supplied,time_stepand jumps of the piecewise constant arguments are ignored. Default value:None, which means that the times grid is computed usingtime_step. When exact sampling is used, the shape should be equal to[num_time_points + 1]wherenum_time_pointsistf.shape(times)[0]plus the number of jumps of the Hull-White piecewise constant parameters. The grid should include the initial time point which is usually set to0.0.normal_draws: ATensorof shape[num_samples, num_time_points, dim]and the samedtypeastimes. Represents random normal draws to compute incrementsN(0, t_{n+1}) - N(0, t_n). When supplied,num_samplesargument is ignored and the first dimensions ofnormal_drawsis used instead. When exact sampling is used,num_time_pointsshould be equal totf.shape(times)[0]plus the number of jumps of the Hull-White piecewise constant parameters. Default value:Nonewhich means that the draws are generated by the algorithm.validate_args: Pythonbool. WhenTrueandnormal_drawsare supplied, checks thattf.shape(normal_draws)[1]is equal to the total number of time steps performed by the sampler. WhenFalseinvalid dimension may silently render incorrect outputs. Default value:False.name: Python string. The name to give this op. Default value:sample_paths.
Returns:#
A Tensor of shape [num_samples, k, dim] where k is the size
of the times and dim is the dimension of the process.
Raises:#
ValueError: (a) Iftimeshas rank different from1. (b) If Euler scheme is used by times is not supplied. (c) When neithertimes_gridnortime_stepare supplied and Euler scheme is used. (d) Ifnormal_drawsis supplied anddimis mismatched.tf.errors.InvalidArgumentError: Ifnormal_drawsis supplied and the number of time steps implied bytimes_gridortimes_stepis mismatched.
volatility_fn
volatility_fn()
Python callable calculating the instantaneous volatility.
The callable should accept two real Tensor arguments of the same dtype and
shape times_shape. The first argument is the scalar time t, the second
argument is the value of Ito process X - Tensor of shape
batch_shape + sample_shape + [dim], where batch_shape represents a batch
of models and sample_shape represents samples for each of the models. The
result is value of volatility S_{ij}(t, X). The return value of the callable
is a real Tensor of the same dtype as the input arguments and of shape
batch_shape + sample_shape + [dim, dim]. For example, sample_shape can
stand for [num_samples] for Monte Carlo sampling, or
[num_grid_points_1, ..., num_grid_points_dim] for Finite Difference
solvers.
Returns:#
The instantaneous volatility callable.