tf_quant_finance.models.sabr.calibration

Last updated: 2023-03-16.

tf_quant_finance.models.sabr.calibration#

View source

Calibrates the SABR model using European option prices.

tf_quant_finance.models.sabr.calibration(
    *, prices, strikes, expiries, forwards, is_call_options, beta, volvol, rho,
    volatility_type=None, approximation_type=None,
    volatility_based_calibration=True, alpha=None, alpha_lower_bound=None,
    alpha_upper_bound=None, calibrate_beta=False, beta_lower_bound=0.0,
    beta_upper_bound=1.0, volvol_lower_bound=0.0, volvol_upper_bound=1.0,
    rho_lower_bound=-1.0, rho_upper_bound=1.0, optimizer_fn=None, tolerance=1e-06,
    maximum_iterations=100, validate_args=False, dtype=None, name=None
)

The SABR model specifies the risk neutral dynamics of the underlying as the following set of stochastic differential equations:

  dF = sigma F^beta dW_1
  dsigma = volvol sigma dW_2
  dW1 dW2 = rho dt

  F(0) = f
  sigma(0) = alpha

where F(t) represents the value of the forward price as a function of time, and sigma(t) is the volatility.

Given a set of European option prices, this function estimates the SABR model parameters which best describe the input data. Calibration is done using the closed-form approximations for European option pricing.

Example#

import tf_quant_finance as tff
import tensorflow as tf

dtype = np.float64

# Set some market conditions.
observed_prices = np.array(
    [[20.09689284, 10.91953054, 4.25012702, 1.11561839, 0.20815853],
     [3.34813209, 6.03578711, 10.2874194, 16.26824328, 23.73850935]],
    dtype=dtype)
strikes = np.array(
    [[80.0, 90.0, 100.0, 110.0, 120.0], [80.0, 90.0, 100.0, 110.0, 120.0]],
    dtype=dtype)
expiries = np.array([[0.5], [1.0]], dtype=dtype)
forwards = 100.0
is_call_options = np.array([[True], [False]])

# Calibrate the model.
# In this example, we are calibrating a SABR model using the lognormal
# volatility approximation for implied volatility, and we explicitly fix the
# betas ourselves.
beta = np.array([0.5, 0.5], dtype=dtype)
models, is_converged, _ = tff.models.sabr.approximations.calibration(
    prices=observed_prices,
    strikes=strikes,
    expiries=expiries,
    forwards=forwards,
    is_call_options=is_call_options,
    beta=beta,
    calibrate_beta=False,
    volvol=np.array([1.0, 1.0], dtype=dtype),
    volvol_lower_bound=0.0,
    volvol_upper_bound=10.0,
    rho=np.array([0.0, 0.0], dtype=dtype),
    rho_lower_bound=-0.75,
    rho_upper_bound=0.75,
    maximum_iterations=1000)

# This will return two `SabrModel`s, where:
# Model 1 has alpha = 1.5, beta = 0.5, volvol = 0.33, and rho = 0.1
# Model 2 has alpha = 2.5, beta = 0.5, volvol = 0.66, and rho = -0.1

Args:#

  • prices: Real Tensor of shape [batch_size, num_strikes] specifying the observed options prices. Here, batch_size refers to the number of SABR models calibrated in this invocation.

  • strikes: Real Tensor of shape [batch_size, num_strikes] specifying the strike prices of the options.

  • expiries: Real Tensor of shape compatible with [batch_size, num_strikes] specifying the options expiries.

  • forwards: Real Tensor of shape compatible with [batch_size, num_strikes] specifying the observed forward prices/rates.

  • is_call_options: Boolean Tensor of shape compatible with [batch_size, num_strikes] specifying whether or not the prices correspond to a call option (=True) or a put option (=False).

  • beta: Real Tensor of shape [batch_size], specifying the initial estimate of the model beta. Values must satisfy 0 <= beta <= 1

  • volvol: Real Tensor of shape [batch_size], specifying the initial estimate of the vol-vol parameter. Values must satisfy 0 <= volvol.

  • rho: Real Tensor of shape [batch_size], specifying the initial estimate of the correlation between the forward price and the volatility. Values must satisfy -1 < rho < 1.

  • volatility_type: Either SabrImpliedVolatility.NORMAL or LOGNORMAL. Default value: None which maps to LOGNORMAL

  • approximation_type: Instance of SabrApproxmationScheme. Default value: None which maps to HAGAN.

  • volatility_based_calibration: Boolean. If True, then the options prices are first converted to implied volatilities, and the calibration is then performed by minimizing the difference between input implied volatilities and the model implied volatilities. Otherwise, the calibration is performed by minimizing the mean-squared-loss of the log1p of the input and estimated European options prices. Default value: True

  • alpha: Real Tensor of shape [batch_size], specifying the initial estimate of initial level of the volatility. Values must be strictly positive. If this is not provided, then an initial value will be estimated, along with lower and upper bounds. Default value: None, indicating that the routine should try to find a reasonable initial estimate.

  • alpha_lower_bound: Real Tensor compatible with that of alpha, specifying the lower bound for the calibrated value. This is ignored if alpha is None. Default value: None.

  • alpha_upper_bound: Real Tensor compatible with that of alpha, specifying the upper bound for the calibrated value. This is ignored if alpha is None. Default value: None.

  • calibrate_beta: Boolean value indicating whether or not the beta parameters should be calibrated. If True, then the beta_lower_bound and beta_upper_bound must be specified. If False, then the model will use the values specified in beta. Default value: False.

  • beta_lower_bound: Only used if calibrate_beta is True. Real Tensor compatible with that of beta, specifying the lower bound for the calibrated value. Default value: 0.0.

  • beta_upper_bound: Only used if calibrate_beta is True. Real Tensor compatible with that of beta, specifying the upper bound for the calibrated value. Default value: 1.0

  • volvol_lower_bound: Real Tensor compatible with that of volvol, specifying the lower bound for the calibrated value. Default value: 0.0.

  • volvol_upper_bound: Real Tensor compatible with that of volvol, specifying the lower bound for the calibrated value. Default value: 1.0.

  • rho_lower_bound: Real Tensor compatible with that of rho, specifying the lower bound for the calibrated value. Default value: -1.0.

  • rho_upper_bound: Real Tensor compatible with that of rho, specifying the upper bound for the calibrated value. Default value: 1.0.

  • optimizer_fn: Optional Python callable which implements the algorithm used to minimize the objective function during calibration. It should have the following interface: result = optimizer_fn(value_and_gradients_function, initial_position, tolerance, max_iterations) value_and_gradients_function is a Python callable that accepts a point as a real Tensor and returns a tuple of Tensors of real dtype containing the value of the function and its gradient at that point. ‘initial_position’ is a real Tensor containing the starting point of the optimization, ‘tolerance’ is a real scalar Tensor for stopping tolerance for the procedure and max_iterations specifies the maximum number of iterations. optimizer_fn should return a namedtuple containing the items: position (a tensor containing the optimal value), converged (a boolean indicating whether the optimize converged according the specified criteria), failed (a boolean indicating if the optimization resulted in a failure), num_iterations (the number of iterations used), and objective_value ( the value of the objective function at the optimal value). The default value for optimizer_fn is None and conjugate gradient algorithm is used. Default value: None - indicating LBFGS minimizer.

  • tolerance: Scalar Tensor of real dtype. The absolute tolerance for terminating the iterations. Default value: 1e-6.

  • maximum_iterations: Scalar positive integer Tensor. The maximum number of iterations during the optimization. Default value: 100.

  • validate_args: Boolean value indicating whether or not to validate the shape and values of the input arguments, at the potential expense of performance degredation. Default value: False.

  • dtype: The default dtype to use when converting values to Tensors. Default value: None, which means that default dtypes inferred by TensorFlow are used.

  • name: String. The name to give to the ops created by this function. Default value: None, which maps to the default name ‘sabr_calibration’.

Returns:#

A Tuple of three elements:

  • The first is a CalibrationResult holding the calibrated alpha, beta, volvol, and rho, where alpha[i] corresponds to the calibrated alpha of the i-th batch, etc.

  • A Tensor of optimization status for each batch element (whether the optimization algorithm has found the optimal point based on the specified convergance criteria).

  • A Tensor containing the number of iterations performed by the optimization algorithm.