DNF.dynamicsSVM {SVDNF} | R Documentation |
Discrete Nonlinear Filtering Algorithm for Stochastic Volatility Models
Description
The DNF
function applies the discrete nonlinear filter (DNF) of Kitagawa (1987) as per the implementation of Bégin & Boudreault (2020) to obtain likelihood evaluations and filtering distribution estimates for a wide class of stochastic volatility models.
Usage
## S3 method for class 'dynamicsSVM'
DNF(dynamics, data, N = 50, K = 20, R = 1, grids, ...)
Arguments
dynamics |
A dynamicsSVM object representing the model dynamics to be used by the DNF. |
data |
A series of asset returns for which we want to run the DNF. |
N |
Number of nodes in the variance grid. |
K |
Number of nodes in the jump size grid. |
R |
Maximum number of jumps used in the numerical integration at each timestep. |
grids |
Grids to be used for numerical integration by the |
... |
Further arguments passed to or from other methods. |
Value
log_likelihood |
Log-likelihood evaluation based on the DNF. |
filter_grid |
Grid of dimensions |
likelihoods |
Likelihood contribution at each time-step throughout the series. |
grids |
List of grids used for numerical integration by the DNF. |
dynamics |
The model dynamics used by the DNF. |
data |
The series of asset returns to which the DNF was applied. |
References
Bégin, J.F., Boudreault, M. (2021) Likelihood evaluation of jump-diffusion models using deterministic nonlinear filters. Journal of Computational and Graphical Statistics, 30(2), 452–466.
Kitagawa, G. (1987) Non-Gaussian state-space modeling of nonstationary time series. Journal of the American Statistical Association, 82(400), 1032–1041.
Examples
set.seed(1)
# Generate 200 returns from the DuffiePanSingleton model
DuffiePanSingleton_mod <- dynamicsSVM(model = "DuffiePanSingleton")
DuffiePanSingleton_sim <- modelSim(t = 200, dynamics = DuffiePanSingleton_mod)
# Run DNF on the data
dnf_filter <- DNF(data = DuffiePanSingleton_sim$returns,
dynamics = DuffiePanSingleton_mod)
# Print log-likelihood evaluation.
logLik(dnf_filter)
# Using a custom model.
# Here, we define the DuffiePanSingleton model as a custom model
# to get the same log-likelihood found using the built-in option
# Daily observations
h <- 1/252
# Parameter values
mu <- 0.038; kappa <- 3.689; theta <- 0.032
sigma <- 0.446; rho <- -0.745; omega <- 5.125
delta <- 0.03; alpha <- -0.014; rho_z <- -1.809; nu <- 0.004
# Jump compensator
alpha_bar <- exp(alpha + 0.5 * delta^2) / (1 - rho_z * nu) - 1
# Returns drift and diffusion
mu_y <- function(x, mu, alpha_bar, omega, h) {
return(h * (mu - x / 2 - alpha_bar * omega))
}
mu_y_params <- list(mu, alpha_bar, omega, h)
sigma_y <- function(x, h) {
return(sqrt(h * pmax(x, 0)))
}
sigma_y_params <- list(h)
# Volatility factor drift and diffusion
mu_x <- function(x, kappa, theta, h) {
return(x + h * kappa * (theta - pmax(0, x)))
}
mu_x_params <- list(kappa, theta, h)
sigma_x <- function(x, sigma, h) {
return(sigma * sqrt(h * pmax(x, 0)))
}
sigma_x_params <- list(sigma, h)
# Jump distribution for the DuffiePanSingleton Model
jump_density <- dpois
jump_dist <- rpois
jump_params <- c(h * omega)
# Create the custom model
custom_mod <- dynamicsSVM(model = 'Custom',
mu_x = mu_x, mu_y = mu_y, sigma_x = sigma_x, sigma_y = sigma_y,
mu_x_params = mu_x_params, mu_y_params = mu_y_params,
sigma_x_params = sigma_x_params, sigma_y_params = sigma_y_params,
jump_params = jump_params, jump_dist = jump_dist, jump_density = jump_density,
nu = nu, rho_z = rho_z, rho = rho)
# Define the grid for DNF
N <- 50; R <- 1; K <- 20
var_mid_points <- seq(from = sqrt(0.0000001),
to = sqrt(theta + (3 + log(N)) * sqrt(0.5 * theta * sigma^2 / kappa)), length = N)^2
j_nums <- seq(from = 0, to = R, by = 1)
jump_mid_points <- seq(from = 0.000001, to = (3 + log(K)) * sqrt(R) * nu, length = K)
grids <- list(var_mid_points = var_mid_points,
j_nums = j_nums, jump_mid_points = jump_mid_points)
# Run the DNF function with the custom model
dnf_custom <- DNF(data = DuffiePanSingleton_sim$returns, grids = grids,
dynamics = custom_mod)
# Check if we get the same log-likelihoods
dnf_custom$log_likelihood; dnf_filter$log_likelihood