# Johansen Cointegration test in Python (statsmodels)

I have three time series df['a'], df['b'] and df['c'] which I want to test for cointegration using the statsmodels.tsa.vector_ar.vecm.coint_johansen function (and obtain a cointegration vector).

I start by making sure all three time series are I(1) using the ADF test.

ADF test in level: statsmodels.tsa.stattools.adfuller(df['a']) gives a large p-value, so we conclude that the time series is non-stationary. The test gives an optimal lag length of 2 based on AIC. The ADF test on df['b'] and df['c'] similarly give large p-values with optimal lag lengths of 4 and 7, respectively.

ADF test in first difference: statsmodels.tsa.stattools.adfuller(df['a'].diff().dropna()) gives a p-value < 0.05 so we conclude that the time series is stationary in first difference, and is therefore I(1). Similarly, we conclude that df['b'] and df['c'] are I(1).

I'm now ready to test for cointegration using the Johansen test...

result = statsmodels.tsa.vector_ar.vecm.coint_johansen(df[['a','b','c']], det_order=0, k_ar_diff=???)

...but I'm not sure what to use as the lag length. Should it be 2, should it be 4, should it be 7 or should it be determined some other way?

Furthermore, I have a couple of questions about the results of the Johansen test:

1. Do we conclude from the above results that the cointegration rank is 3 meaning that there are 3 independent cointegration vectors?
2. If so, how do we choose which cointegration vector to use to form a stationary time series? Is it appropriate to just use the first one coint_vec = result.evec[:,0]?
3. Finally, are there any steps missing in my analysis? I read something about checking to see if the residuals of the VAR model are not auto-correlated - would we use one of the result.r0t or result.rkt outputs from the Johansen test to do this?
• It looks like you have screen shot an output of a Pandas dataframe. Note that Pandas dataframes have a .to_markdown method whose output you can print then copy-paste into a stack exchange post. Commented May 14, 2023 at 19:35
• Commented May 14, 2023 at 20:08

2. If you have cointegration you can choose the first values and get weights  weights = list(jres.evec.T[0] / jres.evec.T[0][0])
vecm.VECM(timeseries, deterministic="n", k_ar_diff=order, coint_rank=rank)
vecm.select_order(timeseries, maxlags=max_lag, deterministic="co")