| Type: | Package |
| Title: | Johansen Cointegration Test with Fourier-Type Smooth Nonlinear Trends |
| Version: | 0.1.0 |
| Date: | 2026-05-29 |
| Maintainer: | Merwan Roudane <merwanroudane920@gmail.com> |
| Description: | Implements the Johansen cointegration test with Fourier-type smooth nonlinear deterministic trends restricted to cointegrating relations, as developed by Kurita and Shintani (2025) <doi:10.1080/07474938.2025.2530640>. Six model variants are supported: CNR (constant plus nonlinear, restricted in the cointegrating space), LNR (linear plus nonlinear, restricted), CNU (constant restricted, nonlinear unrestricted), LNU (linear restricted, nonlinear unrestricted), plus the standard constant- and linear-trend restricted Johansen models. The package also bundles the feasible generalised least squares (FGLS) Wald test of Perron, Shintani and Yabu (2017) <doi:10.1111/obes.12169> used as a frequency-selection pre-step, together with bundled critical-value tables, a vectorised simulator for the limiting distribution, publication-quality table exports (LaTeX and HTML) and 'ggplot2' figures matching those of the paper. |
| URL: | https://github.com/merwanroudane/fjohansen |
| BugReports: | https://github.com/merwanroudane/fjohansen/issues |
| License: | MIT + file LICENSE |
| Encoding: | UTF-8 |
| Depends: | R (≥ 4.0.0) |
| Imports: | stats, utils, grDevices, graphics, ggplot2 (≥ 3.4.0), scales |
| Suggests: | testthat (≥ 3.0.0), kableExtra, knitr, rmarkdown, patchwork |
| RoxygenNote: | 7.3.3 |
| NeedsCompilation: | no |
| Packaged: | 2026-05-29 12:04:25 UTC; HP |
| Author: | Merwan Roudane [aut, cre] |
| Repository: | CRAN |
| Date/Publication: | 2026-06-02 08:30:09 UTC |
fjohansen: Johansen Cointegration Test with Fourier-Type Smooth Nonlinear Trends
Description
Implements the Johansen cointegration test with Fourier-type smooth nonlinear deterministic trends restricted to cointegrating relations, as developed by Kurita and Shintani (2025, Econometric Reviews). Also bundles the FGLS Wald test of Perron, Shintani and Yabu (2017) as a frequency-selection pre-step.
Main entry points
-
johansen_fourier– the trace test. -
select_frequencies– pick the number of Fourier frequencies via PSY 2021. -
psy_wald_test– the univariate Wald test. -
simulate_limit_distribution– limit distribution of Proposition 3.1 of the paper.
Author / repository
| Author: | Merwan Roudane merwanroudane920@gmail.com |
| Repository: | https://github.com/merwanroudane/fjohansen |
| License: | MIT |
Author(s)
Maintainer: Merwan Roudane merwanroudane920@gmail.com
References
Kurita, T. and Shintani, M. (2025). Johansen test with Fourier-type smooth nonlinear trends in cointegrating relations. Econometric Reviews, 44(10), 1589-1616. doi:10.1080/07474938.2025.2530640
Perron, P., Shintani, M. and Yabu, T. (2017). Testing for flexible nonlinear trends with an integrated or stationary noise component. Oxford Bulletin of Economics and Statistics, 79, 822-850. doi:10.1111/obes.12169
See Also
Useful links:
Report bugs at https://github.com/merwanroudane/fjohansen/issues
Approximate limit quantiles for the CNR model (Table B1 of Kurita & Shintani 2025).
Description
Named-list keyed by string "p_minus_r,n". Values are numeric vectors with names
q90, q95, q975, q99, mean, var.
Usage
CNR_TABLE_B1
Format
An object of class list of length 35.
Moore-Penrose pseudo-inverse via SVD (no MASS dep).
Description
Moore-Penrose pseudo-inverse via SVD (no MASS dep).
Usage
MASS_ginv_local(M, tol = sqrt(.Machine$double.eps))
Build Z0, Z1, Z2 design matrices for the reduced-rank regression
Description
Build Z0, Z1, Z2 design matrices for the reduced-rank regression
Usage
build_design_matrices(X, k, n, model = "CNR")
Arguments
X |
T x p numeric matrix (levels). |
k |
VAR order in levels (>= 1). |
n |
Number of Fourier frequencies (0 disables them). |
model |
One of "CNR","LNR","CNU","LNU","constant","linear". |
Value
A list with elements Z0, Z1, Z2, info.
Clear the in-memory simulation cache.
Description
Clear the in-memory simulation cache.
Usage
clear_jf_cache()
Value
Invisible integer = number of cached entries cleared.
Coerce input data to a numeric matrix with names
Description
Accepts a data.frame, matrix, ts, mts, xts/zoo, or numeric vector.
Usage
ensure_matrix(data)
Arguments
data |
Input data. |
Value
List with elements X (matrix) and names (character).
Build the Fourier deterministic basis
Description
Constructs the matrix
F_{t,T} = [\sin(2\pi t/T), \cos(2\pi t/T), \ldots,
\sin(2\pi n t/T), \cos(2\pi n t/T)]
for t = t_start, ..., t_start + T - 1.
Usage
fourier_basis(T_len, n, t_start = 1)
Arguments
T_len |
Sample size used in the denominator (typically the full sample T). |
n |
Number of frequencies (>= 0). 0 returns a matrix with 0 columns. |
t_start |
First time index (default 1). |
Value
A numeric matrix of shape T_len x (2 n).
Gamma-distribution match to given mean & variance
Description
Gamma-distribution match to given mean & variance
Usage
gamma_from_moments(mean, var)
Data-generating processes from Section 5 of Kurita & Shintani (2025)
Description
Data-generating processes from Section 5 of Kurita & Shintani (2025)
Usage
generate_nf_dgp1(T = 400L, seed = 0L, ...)
generate_nf_dgp2(T = 400L, seed = 0L, ...)
generate_nf_dgp3(T = 400L, seed = 0L, ...)
generate_nf_dgp4(T = 400L, seed = 0L, ...)
generate_f_dgp1(T = 400L, seed = 0L)
generate_f_dgp2(T = 400L, seed = 0L)
Arguments
T |
Sample length. |
seed |
RNG seed (integer). |
... |
Additional arguments forwarded to the internal skeleton
(e.g. |
Value
A data.frame with two or four numeric columns.
Mean and variance of the limit distribution
Description
Mean and variance of the limit distribution
Usage
jf_moments(
p_minus_r,
n,
model = "CNR",
n_sims = 4000,
grid_size = 250,
seed = 12345
)
Arguments
p_minus_r |
Common stochastic trends p - r (>= 1). |
n |
Number of Fourier frequencies (>= 0). |
model |
One of "CNR","LNR","CNU","LNU","CONSTANT","LINEAR". |
n_sims |
Replications used if the cell is not tabulated. |
grid_size |
Discretisation of the unit interval (only used in simulation). |
seed |
RNG seed (only used in simulation). |
Value
Numeric vector of length 2: c(mean, var).
Gamma-approximation p-value of an observed trace statistic
Description
Gamma-approximation p-value of an observed trace statistic
Usage
jf_p_value(stat, p_minus_r, n, model = "CNR", ...)
Arguments
stat |
Observed value of -2 log LR. |
p_minus_r |
Common stochastic trends p - r (>= 1). |
n |
Number of Fourier frequencies (>= 0). |
model |
One of "CNR","LNR","CNU","LNU","CONSTANT","LINEAR". |
... |
Additional arguments forwarded to |
Value
Numeric scalar in [0,1].
Quantile of the limit distribution
Description
For tabulated CNR cells and the 90/95/97.5/99 percentiles the paper's hard-coded values are returned. Otherwise the Gamma approximation (Doornik 1998) is used.
Usage
jf_quantile(level, p_minus_r, n, model = "CNR", ...)
Arguments
level |
Probability (0 < level < 1) or one of "90%","95%","97.5%","99%". |
p_minus_r |
Common stochastic trends p - r (>= 1). |
n |
Number of Fourier frequencies (>= 0). |
model |
One of "CNR","LNR","CNU","LNU","CONSTANT","LINEAR". |
... |
Additional arguments forwarded to |
Value
Numeric scalar.
Publication-quality table formatters for the trace test
Description
Helpers that turn a fitted johansen_fourier result into a printable
table in three different formats.
Usage
format_trace_table(x)
format_trace_latex(x, caption = NULL, label = NULL)
format_trace_html(x, caption = NULL)
Arguments
x |
A |
caption |
Optional caption. |
label |
Optional label. |
Value
Each function returns a single character scalar containing the formatted table:
-
format_trace_table()– plain-text (ASCII) table suitable forcat()ormessage(). -
format_trace_latex()– a LaTeXtabularenvironment (booktabs style) wrapped in atablefloat. -
format_trace_html()– a self-contained HTML fragment with inline CSS, suitable for use in R Markdown / Quarto.
Johansen-Fourier cointegration test
Description
Performs the reduced-rank regression of Kurita & Shintani (2025) for a cointegrated VAR(k) with restricted Fourier-type smooth nonlinear trends in the cointegrating space.
Usage
johansen_fourier(
data,
k,
n = 1L,
model = "CNR",
sig_level = 0.05,
select_rank = TRUE,
n_sims = 5000L
)
Arguments
data |
T x p numeric matrix or data.frame of levels. |
k |
VAR order in levels (>= 1). Uses |
n |
Number of Fourier frequencies (0 = standard Johansen). |
model |
One of |
sig_level |
Significance level for the sequential rank rule. |
select_rank |
Logical; sequentially pick the cointegrating rank. |
n_sims |
Replications used to simulate cells not in the bundled tables. |
Value
An S3 object of class johansen_fourier with fields:
-
spec– model spec -
eigenvalues– generalised eigenvalues, descending -
trace_stats– data.frame, one row per H_0 -
selected_rank– chosen r -
alpha, beta, delta, gamma_const, gamma_trend, Gamma -
Sigma, residuals, fitted_long_run -
series_names, t_index
References
Kurita, T., Shintani, M. (2025). Econometric Reviews, 44(10), 1589-1616.
Examples
## Small fast example (tabulated critical-value cell, no simulation):
set.seed(1)
data <- sample_jgb_data(T = 60)
res <- johansen_fourier(data, k = 2, n = 1, model = "CNR",
n_sims = 200, select_rank = FALSE)
print(res)
## Full paper-style call (slower because of the limit-distribution
## simulation when the requested cell is not in the bundled tables):
data <- sample_jgb_data(T = 108)
res <- johansen_fourier(data, k = 3, n = 3, model = "CNR")
summary(res)
plot(res)
Log-determinant of a PD matrix via Cholesky
Description
Log-determinant of a PD matrix via Cholesky
Usage
log_det_pd(M)
Model specifications used by johansen_fourier
Description
A list of S3-tagged model specs with the following fields:
-
code: canonical name -
label: human-readable description -
z1_constant: restricted constant in cointegrating space -
z1_trend: restricted linear trend in cointegrating space -
z1_fourier: restricted Fourier in cointegrating space -
z2_constant: unrestricted constant -
z2_fourier: unrestricted Fourier
Usage
model_specs
Format
An object of class list of length 6.
Details
Use one of "CNR", "LNR", "CNU", "LNU", "constant", "linear".
OLS residuals of Y on X (matrix Y, matrix X)
Description
Returns Y unchanged if X has zero columns.
Usage
ols_residuals(Y, X)
Bar plot of the Johansen eigenvalues
Description
Bar plot of the Johansen eigenvalues
Usage
plot_eigenvalues(x)
Arguments
x |
A |
Value
A ggplot bar-chart object.
Plot the limit-distribution density (paper's Figs. 1-2)
Description
Plot the limit-distribution density (paper's Figs. 1-2)
Usage
plot_limit_density(
p_minus_r,
n_values = 0:4,
model = "CNR",
n_sims = 4000L,
grid_size = 300L,
title = NULL
)
Arguments
p_minus_r |
Number of common stochastic trends (>= 1). |
n_values |
Integer vector of n values to compare. |
model |
One of "CNR","LNR","CNU","LNU","CONSTANT","LINEAR". |
n_sims |
Number of Monte-Carlo replications. |
grid_size |
Grid size of |
title |
Optional plot title. |
Value
A ggplot object showing one kernel-density curve per
value of n.
Examples
## Fast preview with reduced Monte-Carlo size:
plot_limit_density(p_minus_r = 2, n_values = 0:2,
n_sims = 400, grid_size = 80)
Plot estimated cointegrating relations
Description
Plot estimated cointegrating relations
Usage
plot_long_run(x)
Arguments
x |
A |
Value
A ggplot object showing one panel per cointegrating
relation (the fitted beta' X_t series).
Residual diagnostics (paper's Fig. 12)
Description
Returns a ggplot showing standardised residuals only (a single panel per equation). Use directly with patchwork::wrap_plots to combine with other diagnostic graphics.
Usage
plot_residual_diagnostics(x, max_lag = 14L)
Arguments
x |
A |
max_lag |
Number of ACF lags to show. |
Value
A ggplot object with one panel of standardised residuals
per equation and +/- 2 reference bands.
Implied risk-premium decomposition (paper's Fig. 13)
Description
Implied risk-premium decomposition (paper's Fig. 13)
Usage
plot_risk_premium(x, index = NULL)
Arguments
x |
A |
index |
Optional x-axis vector (length |
Value
A ggplot object decomposing each cointegrating relation
into its estimated risk-premium (rho_t) and the Fourier
nonlinear component.
Plot a (T x p) data set as multi-panel time series (Fig. 11 of the paper)
Description
Plot a (T x p) data set as multi-panel time series (Fig. 11 of the paper)
Usage
plot_series(data, title = NULL, index = NULL)
Arguments
data |
data.frame or matrix. |
title |
Optional title. |
index |
Optional vector of x-axis values. |
Value
A ggplot object (one facet per series). Can be further
modified with + like any other ggplot.
Examples
df <- sample_jgb_data(T = 36)
p <- plot_series(df, title = "JGB yields")
Perron-Shintani-Yabu (2021) FGLS Wald test
Description
Tests for the presence of Fourier-type nonlinear components in a
univariate series. Robust to both I(0) and I(1) noise via
Prais-Winsten transformation with a super-efficient + Roy-Fuller
bias-corrected AR(1) estimator.
Usage
psy_wald_test(
y,
k_freqs,
p_d = 1,
subset_freq = NULL,
version = "upper-biased",
p_T_max = NULL
)
Arguments
y |
Numeric vector (length T). |
k_freqs |
Integer vector of frequencies. |
p_d |
Polynomial trend order (0 or 1). |
subset_freq |
If supplied, test only that one frequency's two coefficients. |
version |
"upper-biased" or "median-unbiased". |
p_T_max |
Upper bound for the augmentation lag. |
Value
An object of class psy_wald.
Resolve a model code / spec
Description
Resolve a model code / spec
Usage
resolve_model(model)
Synthetic JGB-yield surrogate (Section 6 illustration)
Description
Synthetic JGB-yield surrogate (Section 6 illustration)
Usage
sample_jgb_data(T = 108L, seed = 7L)
Arguments
T |
Sample length (default 108, matching the paper's monthly sample). |
seed |
RNG seed. |
Value
A data.frame with six columns (i_20yr, i_10yr, i_5yr, i_3yr, i_1yr, i_call) and a Date attribute starting 1986-12.
Frequency selection for a multivariate panel
Description
Each column is tested independently and the final n is the maximum
across columns – the same recipe as in Kurita & Shintani (2025).
Usage
select_frequencies(
data,
n_max = 5L,
p_d = 1L,
sig_level = 0.1,
version = "upper-biased"
)
Arguments
data |
Numeric matrix or data.frame. |
n_max |
Upper bound on the number of frequencies. |
p_d |
Polynomial trend order. |
sig_level |
Significance level for stopping the loop. |
version |
"upper-biased" or "median-unbiased". |
Value
A freq_selection object.
General-to-specific frequency selection for a univariate series
Description
General-to-specific frequency selection for a univariate series
Usage
select_frequencies_univariate(
y,
n_max = 5L,
p_d = 1L,
sig_level = 0.1,
version = "upper-biased"
)
Arguments
y |
Numeric vector. |
n_max |
Upper bound on the number of frequencies. |
p_d |
Polynomial trend order. |
sig_level |
Significance level for stopping the loop. |
version |
"upper-biased" or "median-unbiased". |
Value
A freq_selection object.
Apply the paper-style ggplot2 theme (sunny palette)
Description
Apply the paper-style ggplot2 theme (sunny palette)
Usage
set_paper_theme()
Value
Invisibly returns the ggplot2 theme object that has been
installed as the global default via ggplot2::theme_set().
Called primarily for its side effect.
Simulate the limiting Johansen-Fourier trace distribution
Description
Vectorised across replications. Results are kept in a per-session in-memory
cache; clear it with clear_jf_cache().
Usage
simulate_limit_distribution(
p_minus_r,
n,
model = "CNR",
n_sims = 5000,
grid_size = 300,
seed = 12345
)
Arguments
p_minus_r |
Number of common stochastic trends (>= 1). |
n |
Number of Fourier frequencies (>= 0). |
model |
One of "CNR","LNR","CNU","LNU","CONSTANT","LINEAR". |
n_sims |
Number of Monte-Carlo replications. |
grid_size |
Grid size of |
seed |
RNG seed. |
Value
Numeric vector of length n_sims.
Simulate moments of the limiting distribution
Description
Simulate moments of the limiting distribution
Usage
simulate_limit_moments(
p_minus_r,
n,
model = "CNR",
n_sims = 5000,
grid_size = 300,
seed = 12345
)
Arguments
p_minus_r |
Number of common stochastic trends (>= 1). |
n |
Number of Fourier frequencies (>= 0). |
model |
One of "CNR","LNR","CNU","LNU","CONSTANT","LINEAR". |
n_sims |
Number of Monte-Carlo replications. |
grid_size |
Grid size of |
seed |
RNG seed. |
Value
List with elements mean, var, draws.
Stack lagged differences as columns
Description
Returns [DX_{t-1}, DX_{t-2}, ..., DX_{t-(k-1)}] aligned with the
effective sample of the VAR(k).
Usage
stack_lags(X, k)