--- title: "Introduction to wqrr: Wavelet Quantile Regression Toolbox" author: "Dr Merwan Roudane" date: "`r Sys.Date()`" output: rmarkdown::html_vignette: toc: true toc_depth: 2 number_sections: true vignette: > %\VignetteIndexEntry{Introduction to wqrr: Wavelet Quantile Regression Toolbox} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} --- ```{r setup, include = FALSE} knitr::opts_chunk$set( collapse = TRUE, comment = "#>", fig.width = 7.5, fig.height = 4.8, message = FALSE, warning = FALSE ) ``` # Overview `wqrr` bundles eight estimators that combine the *Maximal Overlap Discrete Wavelet Transform* (MODWT) with quantile regression so that you can study how the relationship between two (or more) time series changes both *across the frequency spectrum* and *across the conditional distribution*. All visualisations default to the **MATLAB Parula** colour map. | Function | Method | |---|---| | `wavelet_qr()` | Wavelet Quantile Regression — band-by-quantile slopes | | `multivariate_wqr()` | Multivariate WQR — multiple regressors per band | | `wavelet_qqr()` | Wavelet QQR — (θ, τ) coefficient and p-value surfaces | | `np_quantile_causality()` | Nonparametric Causality-in-Quantiles | | `wavelet_np_causality()` | Wavelet variant of the above | | `wavelet_mediation()` | Direct, interaction, paths a / b, indirect | | `wavelet_quantile_correlation()` | Wavelet Quantile Correlation with CIs | | `wavelet_quantile_density()` | Wavelet nonparametric quantile density | For plain bivariate Quantile-on-Quantile regression please use the companion CRAN package **`QuantileOnQuantile`**. ```{r} library(wqrr) ``` # Example data The package ships a 360-month synthetic dataset of macro-financial returns: ```{r} dat <- read.csv(system.file("extdata", "wqrr_data.csv", package = "wqrr")) str(dat) head(dat) ``` For speed in this vignette we use the last 192 observations. ```{r} dat <- tail(dat, 192) ``` # 1. Wavelet Quantile Regression (WQR) Decompose `sp500_return` and `oil_return` with the MODWT, aggregate into Short / Medium / Long bands, and run a quantile regression at each quantile within each band. ```{r} wqr_fit <- wavelet_qr( y = dat$sp500_return, x = dat$oil_return, quantiles = seq(0.1, 0.9, by = 0.1), wavelet = "la8", J = 5, verbose = FALSE ) print(wqr_fit) ``` The band x quantile slope matrix: ```{r} wqr_to_matrix(wqr_fit) ``` Pretty heatmap with significance stars (MATLAB Parula default colour scale is provided package-wide; for WQR / mediation the *Green-Orange-Red* sequential scale is conventional): ```{r, eval = FALSE} plot_wqr_heatmap(wqr_fit, colorscale = "Parula") ``` Or just call `plot()`: ```{r, eval = FALSE} plot(wqr_fit) ``` A formatted coefficient table with stars: ```{r} results_table(wqr_fit, digits = 3) ``` # 2. Multivariate WQR Same idea but with several regressors in the same QR per band: ```{r} mwqr_fit <- multivariate_wqr( y = dat$sp500_return, X_list = list(oil = dat$oil_return, epu = dat$epu), quantiles = c(0.10, 0.25, 0.50, 0.75, 0.90), wavelet = "la8", J = 5, verbose = FALSE ) print(mwqr_fit) ``` ```{r, eval = FALSE} plot(mwqr_fit, variable = "oil", colorscale = "Parula") ``` # 3. Wavelet Quantile-on-Quantile Regression (WQQR) For the *long*-horizon band of the response and predictor, build the full (θ, τ) coefficient + p-value surface: ```{r} wqqr_fit <- wavelet_qqr( y = dat$sp500_return, x = dat$oil_return, quantile_step = 0.10, wavelet = "la8", J = 5, band = "long", verbose = FALSE ) print(wqqr_fit) ``` ```{r, eval = FALSE} plot(wqqr_fit, type = "3d", colorscale = "Parula") plot(wqqr_fit, type = "pvalue") plot(wqqr_fit, type = "compare") ``` # 4. Nonparametric Causality-in-Quantiles Tests whether `oil_return` Granger-causes `sp500_return` in each quantile of the conditional distribution, using a Gaussian-kernel local-constant quantile estimator and the Song-Whang-Shin statistic (standard-normal critical values at 1.96 / 1.645 for 5% / 10%). ```{r} cause_fit <- np_quantile_causality( x = dat$oil_return, y = dat$sp500_return, test_type = "mean", q = seq(0.1, 0.9, by = 0.1) ) print(cause_fit) ``` ```{r, eval = FALSE} plot(cause_fit) ``` The wavelet variant (decomposes both series first): ```{r} wcr_fit <- wavelet_np_causality( x = dat$oil_return, y = dat$sp500_return, q = seq(0.1, 0.9, by = 0.1), wavelet = "la8", J = 5, verbose = FALSE ) print(wcr_fit) ``` ```{r, eval = FALSE} plot(wcr_fit, colorscale = "Parula") ``` # 5. Wavelet Quantile Mediation & Moderation Direct, interaction (moderation), path a, path b, and indirect (a·b) effects for the triplet `(sp500_return, oil_return, epu)`: ```{r} med_fit <- wavelet_mediation( y = dat$sp500_return, x = dat$oil_return, z = dat$epu, quantiles = c(0.10, 0.25, 0.50, 0.75, 0.90), wavelet = "la8", J = 5, dep_name = "SP500", main_name = "OIL", mod_name = "EPU", verbose = FALSE ) print(med_fit) ``` ```{r, eval = FALSE} panels <- plot_mediation_panel(med_fit, colorscale = "Parula") panels$Direct panels$Indirect ``` # 6. Wavelet Quantile Correlation Quantile correlation between MODWT detail levels of two series with parametric-bootstrap 95% CIs: ```{r} wc_fit <- wavelet_quantile_correlation( x = dat$oil_return, y = dat$sp500_return, quantiles = c(0.10, 0.25, 0.50, 0.75, 0.90), wavelet = "la8", J = 5, n_sim = 100, verbose = FALSE ) print(wc_fit) head(wc_fit$results) ``` ```{r, eval = FALSE} plot(wc_fit, colorscale = "Parula") ``` # 7. Wavelet Quantile Density Estimation ```{r} qd_fit <- wavelet_quantile_density(dat$sp500_return, j0 = 4, bandwidth = 0.15) print(qd_fit) ``` ```{r, eval = FALSE} plot(qd_fit) ``` # 8. Colour palettes ```{r} wqrr_colorscales(show_preview = TRUE) ``` The MATLAB Parula colormap is reproduced exactly from MathWorks' 64 RGB stops: ```{r, fig.height = 1.2} op <- par(mar = c(0, 0, 0, 0)) image(matrix(1:256, ncol = 1), col = parula_colors(256), axes = FALSE) par(op) ``` # References - Sim, N., Zhou, H. (2015). *Journal of Banking and Finance*, 55, 1-12. - Adebayo, T.S., Ozkan, O. (2024). *Journal of Cleaner Production*, 440, 140832. - Balcilar, M., Gupta, R., Pierdzioch, C. (2016). *Resources Policy*, 49, 74-80.