Calculate the Johansen test for cointegration among every ticker in the Toolkit instance.

The Engle-Granger test only handles two assets and imposes an arbitrary normalization (which asset is “dependent”). Johansen’s test generalizes this to N >= 2 assets at once by testing the rank of the long-run coefficient matrix in a Vector Error Correction Model (VECM) fit to all assets jointly. The estimated rank equals the number of independent cointegrating (long-run equilibrium) relationships among the assets: rank 0 means none of them are cointegrated, rank N means the whole system is already stationary in levels, and a rank in between means that many independent stationary combinations exist among the N individually non-stationary price series.

The formula is as follows:

\[\Delta \text{Yₜ} = \text{Π} \cdot \text{Yₜ₋₁} + \operatorname{Σ}(i = 1..k) \text{Γᵢ} \cdot \Delta \text{Yₜ₋ᵢ} + \mu + \text{epsilonₜ},\;\; \text{with Yₜ the vector of column levels (Adj Close by default)},\;\; k = \text{k\_ar\_diff} (1 \;\text{by default}) \text{and the deterministic term}\; \mu \;\text{set by}\; \text{det\_order:} \;\text{none} (- 1,\; \text{Johansen's case}\; 1),\;\; \text{an unrestricted constant mu₀ (0, the default, case 3) or a linear trend (1: the levels are linearly detrended before the test, evaluated against the case 5 critical values)}\]
  • λ₁ ≥ … ≥ λ_N: the eigenvalues of the reduced-rank regression of ΔYₜ on Yₜ₋₁, both corrected for the lagged differences and μ
\[\operatorname{Trace}(r) = - T \cdot \operatorname{Σ}(i = r + 1..N) \ln(1 - \text{lambdaᵢ})\] \[\operatorname{Max-Eigenvalue}(r) = - T \cdot \ln(1 - \text{lambdaᵣ₊₁})\]
  • Each statistic rejects “rank ≤ r” at the 5% level when it exceeds its 95% critical value

For more information about the method, see the following papers:

  • Johansen, S. (1988). “Statistical Analysis of Cointegration Vectors.” Journal of Economic Dynamics and Control, 12(2-3), 231-254.
  • Johansen, S. (1991). “Estimation and Hypothesis Testing of Cointegration Vectors in Gaussian Vector Autoregressive Models.” Econometrica, 59(6), 1551-1580.
  • MacKinnon, J.G., Haug, A.A., & Michelis, L. (1999). “Numerical Distribution Functions of Likelihood Ratio Tests for Cointegration.” Journal of Applied Econometrics, 14(5), 563-577.

Also known as: Johansen test, Johansen procedure, VECM rank test.

Johansen Cointegration in Python or via the MCP

Install the Finance Toolkit with:

pip install financetoolkit -U

Then call get_johansen_cointegration as shown below.

from financetoolkit import Toolkit

toolkit = Toolkit(
    ["V", "MA"],
    api_key="FINANCIAL_MODELING_PREP_KEY",
    start_date="2021-01-01",
    end_date="2025-12-31",
)

johansen = toolkit.econometrics.get_johansen_cointegration()

# The maximum eigenvalue statistic columns follow the same pattern as the trace ones.
johansen[["Eigenvalue", "Trace Statistic", "Trace Critical Value 95%", "Reject (Trace, 5%)"]]

Or, after setting up the Finance Toolkit MCP, ask:

Were the share prices of Visa and Mastercard cointegrated from 2021 to 2025, according to the Johansen trace test?

Which returns:

  Eigenvalue Trace Statistic Trace Critical Value 95% Reject (Trace, 5%)
r <= 0 0.0107 13.9015 15.4943 False
r <= 1 0.0003 0.3612 3.8415 False

Using Your Own Data

get_johansen_cointegration runs on any data, not only prices: ratios, economic indicators, yield curves or your own dataset. Pass a DataFrame, a Series or a dictionary of them to Econometrics as data, with the dates in the rows or the columns, and set changes to how its changes are calculated: "percentage", "log", "difference" for rates and ratios, or None when the data are changes already. For example, for the monthly unemployment rates of the United States and Germany:

from financetoolkit import Economics, Econometrics

economics = Economics(start_date="2000-01-01")

unemployment = economics.get_unemployment_rate(
    countries=["United States", "Germany"], period="monthly"
)

econometrics = Econometrics(data=unemployment, changes="difference")

econometrics.get_johansen_cointegration()

Parameters

get_johansen_cointegration accepts the following parameters.

ParameterTypeDescriptionExample
periodstrThe data frequency (daily, weekly, monthly, quarterly, or yearly). Defaults to “daily”."weekly"
columnstrThe historical data column to test. Defaults to “Adj Close”."Close"
det_orderintWhich deterministic term to include: -1 (none, Johansen’s case 1), 0 (an unrestricted constant, case 3) or 1 (a linear trend, evaluated against the case 5 critical values). The critical values are those of MacKinnon, Haug & Michelis (1999). Defaults to 0.1
k_ar_diffintThe number of lagged first differences to include as short-run dynamics. Defaults to 1.2
include_benchmarkboolWhether to include “Benchmark” among the tickers tested jointly. Defaults to False.True
roundingint | NoneThe number of decimals to round the results to. Defaults to None.2
Share