The futurize package allows you to easily turn sequential code
into parallel code by piping the sequential code to the futurize()
function. Easy!
library(futurize)
plan(multisession)
library(rugarch)
data(sp500ret, package = "rugarch")
spec <- ugarchspec()
roll <- ugarchroll(spec, sp500ret, n.start = 1000, refit.window = "moving", refit.every = 100) |> futurize()
This vignette demonstrates how to use this approach to parallelize rugarch
functions such as ugarchroll(), ugarchdistribution(), and ugarchboot().
The rugarch package provides a comprehensive set of methods for Generalized Autoregressive Conditional Heteroskedasticity (GARCH) modeling. Many of its functions, especially those involving rolling estimation or bootstrapping, are computationally intensive and benefit greatly from parallelization.
The ugarchroll() function performs rolling estimation and
forecasting. This can be time-consuming as it involves multiple fits
of the GARCH model.
library(futurize)
plan(multisession)
library(rugarch)
data(sp500ret, package = "rugarch")
spec <- ugarchspec()
## Perform rolling estimation
roll <- ugarchroll(spec, sp500ret, n.start = 1000,
refit.window = "moving", refit.every = 100) |> futurize()
The ugarchdistribution() function simulates and estimates the
parameter distribution of a GARCH model.
library(futurize)
plan(multisession)
library(rugarch)
data(sp500ret, package = "rugarch")
spec <- ugarchspec()
fit <- ugarchfit(spec, sp500ret)
## Estimate parameter distribution
dist <- ugarchdistribution(fit, n.sim = 100, n.hist = 10) |> futurize()
The following rugarch functions are supported by futurize():
arfimacv() with seed = TRUE as the defaultarfimadistribution() with seed = TRUE as the defaultarfimaroll() with seed = TRUE as the defaultautoarfima() with seed = TRUE as the defaultmultifilter() with seed = TRUE as the defaultmultifit() with seed = TRUE as the defaultmultiforecast() with seed = TRUE as the defaultugarchboot() with seed = TRUE as the defaultugarchdistribution() with seed = TRUE as the defaultugarchroll() with seed = TRUE as the defaultFor comparison, here is what it takes to parallelize ugarchroll() using
the parallel package directly, without futurize:
library(rugarch)
library(parallel)
data(sp500ret, package = "rugarch")
spec <- ugarchspec()
## Set up a PSOCK cluster
ncpus <- 4L
cl <- makeCluster(ncpus)
## Run rolling estimation in parallel
roll <- ugarchroll(spec, sp500ret, n.start = 1000,
refit.window = "moving", refit.every = 100,
cluster = cl)
## Tear down the cluster
stopCluster(cl)
This requires you to manually create and manage the cluster
lifecycle. If you forget to call stopCluster(), or if your code
errors out before reaching it, you leak background R processes. You
also have to decide upfront how many CPUs to use and what cluster
type to use. Switching to another parallel backend, e.g. a Slurm
cluster, would require a completely different setup. With
futurize, all of this is handled for you - just pipe to
futurize() and control the backend with plan().