Package {fjohansen}


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

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:


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. s, start, no_cointegration).

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 jf_moments() when the requested cell is not tabulated.

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 jf_moments() when the requested cell is not tabulated.

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 johansen_fourier object.

caption

Optional caption.

label

Optional label.

Value

Each function returns a single character scalar containing the formatted table:


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 k - 1 lagged differences as unrestricted regressors.

n

Number of Fourier frequencies (0 = standard Johansen).

model

One of "CNR","LNR","CNU","LNU","constant","linear".

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:

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:

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 johansen_fourier object.

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 ⁠[0,1]⁠.

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 johansen_fourier object.

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 johansen_fourier object.

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 johansen_fourier object.

index

Optional x-axis vector (length T_eff).

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 ⁠[0,1]⁠.

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 ⁠[0,1]⁠.

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)