Johansen Cointegration
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 μ
- 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.
| Parameter | Type | Description | Example |
|---|---|---|---|
period | str | The data frequency (daily, weekly, monthly, quarterly, or yearly). Defaults to “daily”. | "weekly" |
column | str | The historical data column to test. Defaults to “Adj Close”. | "Close" |
det_order | int | Which 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_diff | int | The number of lagged first differences to include as short-run dynamics. Defaults to 1. | 2 |
include_benchmark | bool | Whether to include “Benchmark” among the tickers tested jointly. Defaults to False. | True |
rounding | int | None | The number of decimals to round the results to. Defaults to None. | 2 |