Title: | Discrete Nonlinear Filtering for Stochastic Volatility Models |
---|---|
Description: | Implements the discrete nonlinear filter (DNF) of Kitagawa (1987) <doi:10.1080/01621459.1987.10478534> to a wide class of stochastic volatility (SV) models with return and volatility jumps following the work of Bégin and Boudreault (2021) <doi:10.1080/10618600.2020.1840995> to obtain likelihood evaluations and maximum likelihood parameter estimates. Offers several built-in SV models and a flexible framework for users to create customized models by specifying drift and diffusion functions along with an arrival distribution for the return and volatility jumps. Allows for the estimation of factor models with stochastic volatility (e.g., heteroskedastic volatility CAPM) by incorporating expected return predictors. Also includes functions to compute filtering and prediction distribution estimates, to simulate data from built-in and custom SV models with jumps, and to forecast future returns and volatility values using Monte Carlo simulation from a given SV model. |
Authors: | Louis Arsenault-Mahjoubi [aut, cre], Jean-François Bégin [aut], Mathieu Boudreault [aut] |
Maintainer: | Louis Arsenault-Mahjoubi <[email protected]> |
License: | GPL-3 |
Version: | 0.1.11 |
Built: | 2024-10-29 06:50:34 UTC |
Source: | CRAN |
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.
## S3 method for class 'dynamicsSVM' DNF(dynamics, data, factors = NULL, N = 50, K = 20, R = 1, grids, ...)
## S3 method for class 'dynamicsSVM' DNF(dynamics, data, factors = NULL, N = 50, K = 20, R = 1, grids, ...)
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. This should be a vector or an |
factors |
Series of values taken by |
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. |
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. |
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.
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
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
The DNFOptim
function finds maximum likelihood estimates for stochastic volatility models parameters using the DNF
function.
## S3 method for class 'dynamicsSVM' DNFOptim(dynamics, data, par, factors, tol, N = 50, K = 20, R = 1, grids = 'Default', rho = 0, delta = 0, alpha = 0, rho_z = 0, nu = 0, jump_params_list = "dummy", ...)
## S3 method for class 'dynamicsSVM' DNFOptim(dynamics, data, par, factors, tol, N = 50, K = 20, R = 1, grids = 'Default', rho = 0, delta = 0, alpha = 0, rho_z = 0, nu = 0, jump_params_list = "dummy", ...)
dynamics |
A dynamicsSVM object representing the model dynamics to be used by the optimizer to find maximum likelihood parameter estimates.This should be a vector or an |
data |
A series of asset returns for which we want to find maximum likelihood estimates. |
par |
Initial values for the parameters to be optimized over. Information about how to pass the initial parameters is given in the 'Note' section. |
factors |
Series of values taken by |
tol |
Tolerance hyperparameter for the optimization. The |
N |
Number of nodes in the variance grid. |
K |
Number of nodes in the jump size grid. |
grids |
Grids to be used for numerical integration by the |
R |
Maximum number of jumps used in the numerical integration at each timestep. |
rho , delta , alpha , rho_z , nu
|
See |
jump_params_list |
List of the names of the arguments in the jump parameter distribution in the order that they are used by the |
... |
Further arguments to be passed to the |
optim |
Returns a list obtained from R's |
SVDNF |
Returns a SVDNF object obtained from running the |
rho , delta , alpha , rho_z , nu
|
See |
When passing the initial parameter vector par
to the optim
function (via ...
), the parameters should follow a specific order.
For the PittMalikDoucet
model, the parameters should be in the following order: phi
, theta
, sigma
, rho
, delta
, alpha
, and p
.
For the DuffiePanSingleton
model, the parameters should be in the following order: mu
, alpha
, delta
, rho_z
, nu
, omega
, kappa
, theta
, sigma
, and rho
.
For the CAPM_SV
model, the parameters should be in the following order: c_0
, c_1
, phi
, theta
, and sigma
.
All other built-in models can be seen as being nested within these models (i.e., Heston
and Bates
models are nested in the DuffiePanSingleton
model, while Taylor
and TaylorWithLeverage
are nested in the PittMalikDoucet
model). Their parameters should be passed in the same order as those in the more general models, minus the parameters not found in these nested models.
For example, the Taylor
model contains neither jumps nor correlation between volatility and returns innovations. Thus, its three parameters are passed in the order: phi
, theta
, and sigma
.
When models = "Custom"
, parameters should be passed in the following order: mu_y_params
, sigma_y_params
, mu_x_params
, sigma_x_params
, rho
, delta
, alpha
, rho_z
, nu
, and jump_params
. If an argument is repeated (e.g., both mu_y_params
and sigma_y_params
use the same parameter), write it only when it first appears in the custom model order.
R Core Team (2019). R: A language and environment for statistical computing. R Foundation for Statistical Computing, Vienna, Austria. URL https://www.R-project.org/.
set.seed(1) # Generating return data Taylor_mod <- dynamicsSVM(model = "Taylor", phi = 0.9, theta = -7.36, sigma = 0.363) Taylor_sim <- modelSim(t = 30, dynamics = Taylor_mod, init_vol = -7.36) plot(Taylor_sim$volatility_factor, type = 'l') plot(Taylor_sim$returns, type = 'l') # Initial values and optimization bounds init_par <- c(0.7, -5, 0.3) lower <- c(0.01, -20, 0.1); upper <- c(0.99, 0, 1) # Running DNFOptim to get MLEs optim_test <- DNFOptim(data = Taylor_sim$returns, dynamics = Taylor_mod, par = init_par, lower = lower, upper = upper, method = "L-BFGS-B") # Parameter estimates summary(optim_test) # Plot prediction and filtering distributions plot(optim_test)
set.seed(1) # Generating return data Taylor_mod <- dynamicsSVM(model = "Taylor", phi = 0.9, theta = -7.36, sigma = 0.363) Taylor_sim <- modelSim(t = 30, dynamics = Taylor_mod, init_vol = -7.36) plot(Taylor_sim$volatility_factor, type = 'l') plot(Taylor_sim$returns, type = 'l') # Initial values and optimization bounds init_par <- c(0.7, -5, 0.3) lower <- c(0.01, -20, 0.1); upper <- c(0.99, 0, 1) # Running DNFOptim to get MLEs optim_test <- DNFOptim(data = Taylor_sim$returns, dynamics = Taylor_mod, par = init_par, lower = lower, upper = upper, method = "L-BFGS-B") # Parameter estimates summary(optim_test) # Plot prediction and filtering distributions plot(optim_test)
dynamicsSVM
creates stochastic volatility model dynamics by either choosing from a set of built-in model dynamics or using custom drift and diffusion functions, as well as custom jump distributions. See Note for information about how to define custom functions.
dynamicsSVM(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, p = 0.01, phi = 0.965, h = 1/252, coefs = NULL, model = "Heston", mu_x, mu_y, sigma_x, sigma_y, jump_dist = rpois, jump_density = dpois, jump_params = 0, mu_x_params, mu_y_params, sigma_x_params, sigma_y_params)
dynamicsSVM(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, p = 0.01, phi = 0.965, h = 1/252, coefs = NULL, model = "Heston", mu_x, mu_y, sigma_x, sigma_y, jump_dist = rpois, jump_density = dpois, jump_params = 0, mu_x_params, mu_y_params, sigma_x_params, sigma_y_params)
mu |
Annual expected rate of return. |
kappa |
Variance rate of mean reversion. |
theta |
Unconditional mean variance. |
sigma |
Volatility of the variance. |
rho |
Correlation between the return and the variance noise terms. |
omega |
Jump arrival intensity for models with Poisson jumps. |
delta |
Standard deviation of return jumps. |
alpha |
Mean of return jumps. |
rho_z |
Pseudo-correlation parameter between return and variance jumps. |
nu |
Mean for variance jumps. |
p |
Jump probability for models with Bernoulli jumps. |
phi |
Volatility persistence parameter. |
h |
Time interval between observations (e.g., |
coefs |
Vector of regression coefficients for factor stochastic volatility models. This vector should be of the same lenght as the number of explanatory variables provided. |
model |
Model used by the discrete nonlinear filter. The options are |
mu_x |
Function for variance drift (to be used with a custom model). |
mu_y |
Function for returns drift (to be used with a custom model). |
sigma_x |
Function for variance diffusion (to be used with a custom model). |
sigma_y |
Function for returns diffusion (to be used with a custom model). |
jump_dist |
Distribution used to generate return or volatility jumps at each timestep (if both types of jumps are in the model, they are assumed to occur simulaneously). |
jump_density |
Probability mass function used to compute the probability of return or volatility jumps at each timestep (if both types of jumps are in the model, they are assumed to occur simulaneously). |
jump_params |
List of parameters to be used as arguments in the |
mu_x_params |
List of parameters to be used as arguments in the |
mu_y_params |
List of parameters to be used as arguments in the |
sigma_x_params |
List of parameters to be used as arguments in the |
sigma_y_params |
List of parameters to be used as arguments in the |
Returns an object of type dynamicsSVM.
Custom functions should have x
(the volatility factor) as well as the function's other parameters as arguments.
If the custom function does not use any parameters, one should include an argument called dummy and its parameters as a list(0)
. For example, for the Taylor model,
sigma_y_taylor <- function(x, dummy) {
return(exp(x / 2))
}
sigma_y_params <- list(0)
It should also be noted that the custom function is a vector for x
. This means that users should use vectorized version of functions. For example, pmax(0,x)
instead of max(0,x)
as code seen in the Example section below.
# Create a dynamicsSVM object with model DuffiePanSingleton and default parameters DuffiePanSingleton_mod <- dynamicsSVM(model = "DuffiePanSingleton") # Here, we define the same DuffiePanSingleton model # using the custom model 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_DPS <- 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)
# Create a dynamicsSVM object with model DuffiePanSingleton and default parameters DuffiePanSingleton_mod <- dynamicsSVM(model = "DuffiePanSingleton") # Here, we define the same DuffiePanSingleton model # using the custom model 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_DPS <- 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)
Function to extract filtering and prediction distribution percentiles from SVDNF
and DNFOptim
objects.
## S3 method for class 'SVDNF' extractVolPerc(x, p = 0.5, pred = F, ...)
## S3 method for class 'SVDNF' extractVolPerc(x, p = 0.5, pred = F, ...)
x |
An |
p |
Distribution percentile to return. |
pred |
Return the prediction distribution percentile if |
... |
Other parameters to be passed through to function. |
Return a vector of the p
th percentile filtering or prediction distribution volatility factor values depending on whether pred = TRUE
or not.
set.seed(1) # Define the built-in model using the dynamicsSVM function Heston_mod <- dynamicsSVM(model = "Heston") # Generate the data from the Duffie, Pan, and Singleton model Heston_sim <- modelSim(t = 10, dynamics = Heston_mod) Heston_dnf <- DNF(dynamics = Heston_mod, data = Heston_sim$returns) extractVolPerc(Heston_dnf, p = 0.75)
set.seed(1) # Define the built-in model using the dynamicsSVM function Heston_mod <- dynamicsSVM(model = "Heston") # Generate the data from the Duffie, Pan, and Singleton model Heston_sim <- modelSim(t = 10, dynamics = Heston_mod) Heston_dnf <- DNF(dynamics = Heston_mod, data = Heston_sim$returns) extractVolPerc(Heston_dnf, p = 0.75)
SVDNF
and DNFOptim
ObjectsReturns the log-likelihood value of the stochastic volatility
model represented by object
evaluated at the parameters given in the DNF
function.
## S3 method for class 'SVDNF' logLik(object, ...)
## S3 method for class 'SVDNF' logLik(object, ...)
object |
an object of class |
... |
further arguments passed to or from other methods. |
The log-likelihood of the stochastic volatility model given by
object
evaluated at the parameters given to the DNF
function. For DNFOptim
objects, this returns the log-likelihood at the MLE parameter values and the number of free parameters in the model.
It will always be the case df = NULL
for SVDNF
objects as they are evaluations of the DNF algorithm for a fixed set of parameters. However, for DNFOptim
objects, df
will be the number of free parameters in the optimization.
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)
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)
The modelSim
function generates returns and variances for a wide class of stochastic volatility models.
## S3 method for class 'dynamicsSVM' modelSim(dynamics, t, init_vol = 0.032, ...)
## S3 method for class 'dynamicsSVM' modelSim(dynamics, t, init_vol = 0.032, ...)
dynamics |
A |
t |
Number of observations to be simulated. |
init_vol |
Initial value of the volatility factor (e.i., value of |
... |
Further arguments passed to or from other methods. |
volatility_factor |
Vector of the instantaneous volatility factor values generated by the |
returns |
Vector of the returns generated by the |
set.seed(1) # Generate 250 returns from the DuffiePanSingleton model DuffiePanSingleton_mod <- dynamicsSVM(model = "DuffiePanSingleton") DuffiePanSingleton_sim <- modelSim(t = 200, dynamics = DuffiePanSingleton_mod) # Plot the volatility factor and returns that were generated plot(DuffiePanSingleton_sim$volatility_factor, type = 'l', main = 'DuffiePanSingleton Model Simulated Volatility Factor', ylab = 'Volatility Factor') plot(DuffiePanSingleton_sim$returns, type = 'l', main = 'DuffiePanSingleton Model Simulated Returns', ylab = 'Returns') # Generate 250 steps from a custom model # Set parameters kappa <- 100; theta <- 0.05; sigma <- 2.3; h <- 1/252 ; mu <- 0.04 rho <- -0.8; omega <- 5; alpha <- -0.025; nu <- 0.01; rho_z <- -1; delta <- 0.025 # Jump compensator alpha_bar <- exp(alpha + 0.5 * delta^2) / (1 - rho_z * nu) - 1 # Define returns drift and diffusion functions # 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, sigma){ return(sigma * sqrt(h) * pmax(x,0)) } sigma_y_params <- list(h, sigma) # Volatility factor drift and diffusion functions mu_x <- function(x, h, kappa, theta){ return(x + h * kappa * pmax(0,x) * (theta - pmax(0,x))) } mu_x_params <- list(h, kappa, theta) sigma_x <- function(x, sigma, h){ return(sigma * sqrt(h) * pmax(0,x)) } sigma_x_params <- list(sigma, h) # Include simultaneous return and volatility factor jumps # based on the Poisson distribution for jump times jump_dist <- rpois jump_params <- list(omega * h) 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_dist = jump_dist, jump_params = jump_params, nu = nu, rho_z = rho_z, omega = omega, alpha = alpha, delta = delta) custom <- modelSim(t = 250, dynamics = custom_mod) plot(custom$volatility_factor, type = 'l', main = 'Custom Model Simulated Volatility Factor', ylab = 'Volatility Factor') plot(custom$returns, type = 'l', main = 'Custom Model Simulated Returns', ylab = 'Returns')
set.seed(1) # Generate 250 returns from the DuffiePanSingleton model DuffiePanSingleton_mod <- dynamicsSVM(model = "DuffiePanSingleton") DuffiePanSingleton_sim <- modelSim(t = 200, dynamics = DuffiePanSingleton_mod) # Plot the volatility factor and returns that were generated plot(DuffiePanSingleton_sim$volatility_factor, type = 'l', main = 'DuffiePanSingleton Model Simulated Volatility Factor', ylab = 'Volatility Factor') plot(DuffiePanSingleton_sim$returns, type = 'l', main = 'DuffiePanSingleton Model Simulated Returns', ylab = 'Returns') # Generate 250 steps from a custom model # Set parameters kappa <- 100; theta <- 0.05; sigma <- 2.3; h <- 1/252 ; mu <- 0.04 rho <- -0.8; omega <- 5; alpha <- -0.025; nu <- 0.01; rho_z <- -1; delta <- 0.025 # Jump compensator alpha_bar <- exp(alpha + 0.5 * delta^2) / (1 - rho_z * nu) - 1 # Define returns drift and diffusion functions # 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, sigma){ return(sigma * sqrt(h) * pmax(x,0)) } sigma_y_params <- list(h, sigma) # Volatility factor drift and diffusion functions mu_x <- function(x, h, kappa, theta){ return(x + h * kappa * pmax(0,x) * (theta - pmax(0,x))) } mu_x_params <- list(h, kappa, theta) sigma_x <- function(x, sigma, h){ return(sigma * sqrt(h) * pmax(0,x)) } sigma_x_params <- list(sigma, h) # Include simultaneous return and volatility factor jumps # based on the Poisson distribution for jump times jump_dist <- rpois jump_params <- list(omega * h) 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_dist = jump_dist, jump_params = jump_params, nu = nu, rho_z = rho_z, omega = omega, alpha = alpha, delta = delta) custom <- modelSim(t = 250, dynamics = custom_mod) plot(custom$volatility_factor, type = 'l', main = 'Custom Model Simulated Volatility Factor', ylab = 'Volatility Factor') plot(custom$returns, type = 'l', main = 'Custom Model Simulated Returns', ylab = 'Returns')
The pars
function returns the names of the parameters in a dynamicsSVM
object in the order that they should be passed to the DNFOptim
function.
## S3 method for class 'dynamicsSVM' pars(dynamics, rho = NULL, delta = NULL, alpha = NULL, rho_z = NULL, nu = NULL, jump_params_list = "dummy", ...)
## S3 method for class 'dynamicsSVM' pars(dynamics, rho = NULL, delta = NULL, alpha = NULL, rho_z = NULL, nu = NULL, jump_params_list = "dummy", ...)
dynamics |
A |
rho , delta , alpha , rho_z , nu
|
See |
jump_params_list |
List of the names of the arguments in the jump parameter distribution in the order that they are used by the |
... |
Other parameters to be passed through to function. |
Returns a vector of strings with the names of the parameters in the given dynamicsSVM
object. The parameters names are returned in the order the parameters should be passed to the DNFOptim
function
mod <- dynamicsSVM(model = "Taylor") pars(mod)
mod <- dynamicsSVM(model = "Taylor") pars(mod)
DNFOptim
or SVDNF
ObjectsPlot predictions from a DNFOptim
or SVDNF
object, including volatility and return mean predictions with confidence intervals.
## S3 method for class 'predict.DNFOptim' plot(x, ...) ## S3 method for class 'predict.SVDNF' plot(x, ...)
## S3 method for class 'predict.DNFOptim' plot(x, ...) ## S3 method for class 'predict.SVDNF' plot(x, ...)
x |
an object of class |
... |
further arguments passed to or from other methods. |
This function plots the volatility and return predictions with confidence intervals obtained from a DNFOptim
object.
For the volatility plot, it displays the DNF's filtering distribution median volatility for all time points in the series and, after the last observation, plots the predicted mean volatility with its confidence interval.
For the returns plot, it displays the observed returns for all time points in the series and, after the last observation, plots the predicted mean return with its confidence interval.
No return value; this function generates two plots.
The first has the median volatility from the filtering distribution as well as the mean predicted volatility from Monte Carlo simulated paths with its confidence interval.
The second has the observed asset returns as well as the mean predicted returns from Monte Carlo simulated paths with its confidence interval.
# Generating return data Taylor_mod <- dynamicsSVM(model = "Taylor", phi = 0.9, theta = -7.36, sigma = 0.363) Taylor_sim <- modelSim(t = 100, dynamics = Taylor_mod, init_vol = -7.36) # Run the DNF DNF_Taylor <- DNF(dynamics = Taylor_mod, data = Taylor_sim$returns) # Predict the next 10 time steps predict_Taylor <- predict(DNF_Taylor, n_ahead = 10) # Plot the predictions plot(predict_Taylor)
# Generating return data Taylor_mod <- dynamicsSVM(model = "Taylor", phi = 0.9, theta = -7.36, sigma = 0.363) Taylor_sim <- modelSim(t = 100, dynamics = Taylor_mod, init_vol = -7.36) # Run the DNF DNF_Taylor <- DNF(dynamics = Taylor_mod, data = Taylor_sim$returns) # Predict the next 10 time steps predict_Taylor <- predict(DNF_Taylor, n_ahead = 10) # Plot the predictions plot(predict_Taylor)
This function plots the median of the filtering and prediction distributions estimated from the DNF
along with user-selected upper and lower percentiles.
## S3 method for class 'SVDNF' plot(x, lower_p = 0.05, upper_p = 0.95, tlim = 'default', type = "l", location = 'topright', ...)
## S3 method for class 'SVDNF' plot(x, lower_p = 0.05, upper_p = 0.95, tlim = 'default', type = "l", location = 'topright', ...)
x |
An |
lower_p |
Lower percentile of the filtering distribution to plot. |
upper_p |
Upper percentile of the filtering distribution to plot. |
tlim |
The For example to plot the first If If the data are passed in an |
location |
Location keyword passed to the |
type |
Line type argument passed to the |
... |
Other parameters to be passed through to function. |
No return value; this function generates two plots.
The first has the median of the volatility factor obtained from the prediction distribution as well as its upper and lower percentiles from lower_p
and upper_p
.
The second has the median of the volatility factor obtained from the filtering distribution as well as its upper and lower percentiles from lower_p
and upper_p
.
set.seed(1) # Generate 500 returns from the Bates model. Bates_mod <- dynamicsSVM(model = "Bates") Bates_sim <- modelSim(t = 500, dynamics = Bates_mod) # Runs DNF on the data. dnf_filter <- DNF(data = Bates_sim$returns, dynamics = Bates_mod) # Plot whole interval (default) plot(dnf_filter, ylim = c(0, 0.15), ylab = "Volatility Factor", xlab = 'Time') # Plot specific interval tlim <- c(100,350) plot(dnf_filter, ylim = c(0, 0.15), ylab = "Volatility Factor", xlab = 'Time', tlim = tlim) # Plot specific point tlim <- c(100) plot(dnf_filter, ylim = c(0, 0.15), type = 'l', ylab = "Volatility Factor", xlab = 'Time', tlim = tlim)
set.seed(1) # Generate 500 returns from the Bates model. Bates_mod <- dynamicsSVM(model = "Bates") Bates_sim <- modelSim(t = 500, dynamics = Bates_mod) # Runs DNF on the data. dnf_filter <- DNF(data = Bates_sim$returns, dynamics = Bates_mod) # Plot whole interval (default) plot(dnf_filter, ylim = c(0, 0.15), ylab = "Volatility Factor", xlab = 'Time') # Plot specific interval tlim <- c(100,350) plot(dnf_filter, ylim = c(0, 0.15), ylab = "Volatility Factor", xlab = 'Time', tlim = tlim) # Plot specific point tlim <- c(100) plot(dnf_filter, ylim = c(0, 0.15), type = 'l', ylab = "Volatility Factor", xlab = 'Time', tlim = tlim)
DNFOptim
and SVDNF
Objects
This function generates Monte Carlo predictions for DNFOptim
objects. The function does this by sampling volatilities from the discrete nonlinear filter's last filtering distribution. Then, using these volatilities as inital values for the modelSim
function, the predict method generates n_sim
path and estimates the means and confidence intervals for future volatility factor and return values.
## S3 method for class 'DNFOptim' predict(object, n_ahead = 15, new_data = NULL, n_sim = 1000, confidence = 0.95, ...)
## S3 method for class 'DNFOptim' predict(object, n_ahead = 15, new_data = NULL, n_sim = 1000, confidence = 0.95, ...)
object |
An object of class |
n_ahead |
Number of periods ahead to predict. |
new_data |
An optional data frame of new predictor values for models with factors (e.g., the CAPM-SV model) for which we want to forecast returns and volatility values. |
n_sim |
Number of simulated paths used to estimate the future volatility factor and return means and confidence intervals. |
confidence |
Confidence level for prediction intervals. Should be between 0 and 1. |
... |
Other parameters to be passed through to function. |
This function uses Monte Carlo paths simulated from the MLE dynamics obtained via a DNFOptim
object to generate predictions for a specified number of periods ahead.
It returns predicted mean volatility and return values based on simulations with confidence intervals.
A list containing the following components:
volatility_pred |
A list with mean volatility values and confidence intervals. Contains the following components:
|
ret_pred |
A list with mean return values and confidence intervals. Contains the following components:
(1) |
object |
The |
confidence |
The specified confidence level. |
set.seed(1) # Generating return data Taylor_mod <- dynamicsSVM(model = "Taylor", phi = 0.9, theta = -7.36, sigma = 0.363) Taylor_sim <- modelSim(t = 30, dynamics = Taylor_mod, init_vol = -7.36) # Initial values and optimization bounds init_par <- c( 0.7, -5, 0.3) lower <- c(0.01, -20, 0.1); upper <- c(0.99, 0, 1) # Running DNFOptim to get MLEs optim_test <- DNFOptim(data = Taylor_sim$returns, dynamics = Taylor_mod, par = init_par, lower = lower, upper = upper, method = "L-BFGS-B") # Parameter estimates summary(optim_test) # Predict 5 steps ahead preds <- predict(optim_test, n_ahead = 5) # Plot predictions with 95 percent confidence interval plot(preds)
set.seed(1) # Generating return data Taylor_mod <- dynamicsSVM(model = "Taylor", phi = 0.9, theta = -7.36, sigma = 0.363) Taylor_sim <- modelSim(t = 30, dynamics = Taylor_mod, init_vol = -7.36) # Initial values and optimization bounds init_par <- c( 0.7, -5, 0.3) lower <- c(0.01, -20, 0.1); upper <- c(0.99, 0, 1) # Running DNFOptim to get MLEs optim_test <- DNFOptim(data = Taylor_sim$returns, dynamics = Taylor_mod, par = init_par, lower = lower, upper = upper, method = "L-BFGS-B") # Parameter estimates summary(optim_test) # Predict 5 steps ahead preds <- predict(optim_test, n_ahead = 5) # Plot predictions with 95 percent confidence interval plot(preds)
Summary method for DNFOptim
objects.
## S3 method for class 'DNFOptim' summary(object, confidence, ...) ## S3 method for class 'summary.DNFOptim' print(x, digits = max(3, getOption("digits") - 3), ...)
## S3 method for class 'DNFOptim' summary(object, confidence, ...) ## S3 method for class 'summary.DNFOptim' print(x, digits = max(3, getOption("digits") - 3), ...)
object |
an object of class |
x |
an object of class |
confidence |
Confidence level for computing confidence intervals. Should be between 0 and 1. Default is 0.95. |
digits |
The number of digits to be printed in the |
... |
further arguments passed to or from other methods. |
Returns the summary of the output of a DNFOptim
object.
Returns a list with the model used and its estimated parameters.
model |
The model that was estimated with the |
coefficients |
Table with the maximum likelihood parameters estimates. If |
logLik |
Log-likelihood value at the parameter maximum likelihood estimates and the model's degrees of freedom |
## For examples see example(DNFOptim)
## For examples see example(DNFOptim)