human
Complete this python program:
def coint_johansen(endog, det_order, k_ar_diff):
assistant
#Here is the Python code you requested.

    """Perform the Johansen cointegration test for determining the cointegration
    rank of a VECM.
    Parameters
    endog : array-like (nobs_tot x neqs)
    The data with presample.
    det_order : int
    * -1 - no deterministic terms
    * 0 - constant term
    * 1 - linear trend
    k_ar_diff : int, nonnegative
    Number of lagged differences in the model.
    Returns
    result : Holder
    An object containing the results which can be accessed using
    dot-notation. The object\s attributes are
    * eig: (neqs)
    Eigenvalues.
    * evec: (neqs x neqs)
    Eigenvectors.
    * lr1: (neqs)
    Trace statistic.
    * lr2: (neqs)
    Maximum eigenvalue statistic.
    * cvt: (neqs x 3)
    Critical values (90%, 95%, 99%) for trace statistic.
    * cvm: (neqs x 3)
    Critical values (90%, 95%, 99%) for maximum eigenvalue
    statistic.
    * method: str
    "johansen"
    * r0t: (nobs x neqs)
    Residuals for :math:`\Delta Y`. See p. 292 in [1]_.
    * rkt: (nobs x neqs)
    Residuals for :math:`Y_{-1}`. See p. 292 in [1]_.
    * ind: (neqs)
    Order of eigenvalues.
    Notes
    The implementation might change to make more use of the existing VECM
    framework.
    References
    .. [1] Lutkepohl, H. 2005. *New Introduction to Multiple Time Series Analysis*. Springer.
    """
    import warnings
    if (det_order not in [(-1), 0, 1]):
        warnings.warn('Critical    values    are    only    available    for    a    det_order    of    -1,    0,    or    1.', category=HypothesisTestWarning)
    if (endog.shape[1] > 12):
        warnings.warn('Critical    values    are    only    available    for    time    series    with    12    variables    at    most.', category=HypothesisTestWarning)
    from statsmodels.regression.linear_model import OLS
    tdiff = np.diff
    class Holder(object, ):
        pass
    def trimr(x, front, end):
        if (end > 0):
            return x[front:(- end)]
        else:
            return x[front:]
    import statsmodels.tsa.tsatools as tsat
    mlag = tsat.lagmat
    def lag(x, lags):
        return x[:(- lags)]
    def detrend(y, order):
        if (order == (-1)):
            return y
        return OLS(y, np.vander(np.linspace((-1), 1, len(y)), (order + 1))).fit().resid
    def resid(y, x):
        if (x.size == 0):
            return y
        r = (y - np.dot(x, np.dot(np.linalg.pinv(x), y)))
        return r
    (nobs, neqs) = endog.shape
    if (det_order > (-1)):
        f = 0
    else:
        f = det_order
    endog = detrend(endog, det_order)
    dx = tdiff(endog, 1, axis=0)
    z = mlag(dx, k_ar_diff)
    z = trimr(z, k_ar_diff, 0)
    z = detrend(z, f)
    dx = trimr(dx, k_ar_diff, 0)
    dx = detrend(dx, f)
    r0t = resid(dx, z)
    lx = lag(endog, k_ar_diff)
    lx = trimr(lx, 1, 0)
    dx = detrend(lx, f)
    rkt = resid(dx, z)
    skk = (np.dot(rkt.T, rkt) / rkt.shape[0])
    sk0 = (np.dot(rkt.T, r0t) / rkt.shape[0])
    s00 = (np.dot(r0t.T, r0t) / r0t.shape[0])
    sig = np.dot(sk0, np.dot(inv(s00), sk0.T))
    tmp = inv(skk)
    (au, du) = np.linalg.eig(np.dot(tmp, sig))
    temp = inv(np.linalg.cholesky(np.dot(du.T, np.dot(skk, du))))
    dt = np.dot(du, temp)
    auind = np.argsort(au)
    aind = np.flipud(auind)
    a = au[aind]
    d = dt[:, aind]
    lr1 = np.zeros(neqs)
    lr2 = np.zeros(neqs)
    cvm = np.zeros((neqs,...