Guest User

Untitled

a guest
Sep 24th, 2018
113
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.80 KB | None | 0 0
  1. import numpy as np
  2. from statsmodels.tsa.tsatools import lagmat
  3.  
  4.  
  5. def johansen(ts, lags):
  6. """
  7. Calculate the Johansen Test for the given time series
  8. """
  9. # Make sure we are working with arrays, convert if necessary
  10. ts = np.asarray(ts)
  11.  
  12. # nobs is the number of observations
  13. # m is the number of series
  14. nobs, m = ts.shape
  15.  
  16. # Obtain the cointegrating vectors and corresponding eigenvalues
  17. eigenvectors, eigenvalues = maximum_likelihood_estimation(ts, lags)
  18.  
  19. # Build table of critical values for the hypothesis test
  20. critical_values_string = """2.71 3.84 6.63
  21. 13.43 15.50 19.94
  22. 27.07 29.80 35.46
  23. 44.49 47.86 54.68
  24. 65.82 69.82 77.82
  25. 91.11 95.75 104.96
  26. 120.37 125.61 135.97
  27. 153.63 159.53 171.09
  28. 190.88 197.37 210.06
  29. 232.11 239.25 253.24
  30. 277.38 285.14 300.29
  31. 326.53 334.98 351.25"""
  32. select_critical_values = np.array(
  33. critical_values_string.split(),
  34. float).reshape(-1, 3)
  35. critical_values = select_critical_values[:, 1]
  36.  
  37. # Calculate numbers of cointegrating relations for which
  38. # the null hypothesis is rejected
  39. rejected_r_values = []
  40. for r in range(m):
  41. if h_test(eigenvalues, r, nobs, lags, critical_values):
  42. rejected_r_values.append(r)
  43.  
  44. return eigenvectors, rejected_r_values
  45.  
  46.  
  47. def h_test(eigenvalues, r, nobs, lags, critical_values):
  48. """
  49. Helper to execute the hypothesis test
  50. """
  51. # Calculate statistic
  52. t = nobs - lags - 1
  53. m = len(eigenvalues)
  54. statistic = -t * np.sum(np.log(np.ones(m) - eigenvalues)[r:])
  55.  
  56. # Get the critical value
  57. critical_value = critical_values[m - r - 1]
  58.  
  59. # Finally, check the hypothesis
  60. if statistic > critical_value:
  61. return True
  62. else:
  63. return False
  64.  
  65.  
  66. def maximum_likelihood_estimation(ts, lags):
  67. """
  68. Obtain the cointegrating vectors and corresponding eigenvalues
  69. """
  70. # Make sure we are working with array, convert if necessary
  71. ts = np.asarray(ts)
  72.  
  73. # Calculate the differences of ts
  74. ts_diff = np.diff(ts, axis=0)
  75.  
  76. # Calculate lags of ts_diff.
  77. ts_diff_lags = lagmat(ts_diff, lags, trim='both')
  78.  
  79. # First lag of ts
  80. ts_lag = lagmat(ts, 1, trim='both')
  81.  
  82. # Trim ts_diff and ts_lag
  83. ts_diff = ts_diff[lags:]
  84. ts_lag = ts_lag[lags:]
  85.  
  86. # Include intercept in the regressions
  87. ones = np.ones((ts_diff_lags.shape[0], 1))
  88. ts_diff_lags = np.append(ts_diff_lags, ones, axis=1)
  89.  
  90. # Calculate the residuals of the regressions of diffs and lags
  91. # into ts_diff_lags
  92. inverse = np.linalg.pinv(ts_diff_lags)
  93. u = ts_diff - np.dot(ts_diff_lags, np.dot(inverse, ts_diff))
  94. v = ts_lag - np.dot(ts_diff_lags, np.dot(inverse, ts_lag))
  95.  
  96. # Covariance matrices of the calculated residuals
  97. t = ts_diff_lags.shape[0]
  98. Svv = np.dot(v.T, v) / t
  99. Suu = np.dot(u.T, u) / t
  100. Suv = np.dot(u.T, v) / t
  101. Svu = Suv.T
  102.  
  103. # ToDo: check for singular matrices and exit
  104. Svv_inv = np.linalg.inv(Svv)
  105. Suu_inv = np.linalg.inv(Suu)
  106.  
  107. # Calculate eigenvalues and eigenvectors of the product of covariances
  108. cov_prod = np.dot(Svv_inv, np.dot(Svu, np.dot(Suu_inv, Suv)))
  109. eigenvalues, eigenvectors = np.linalg.eig(cov_prod)
  110.  
  111. # Use Cholesky decomposition on eigenvectors
  112. evec_Svv_evec = np.dot(eigenvectors.T, np.dot(Svv, eigenvectors))
  113. cholesky_factor = np.linalg.cholesky(evec_Svv_evec)
  114. eigenvectors = np.dot(eigenvectors, np.linalg.inv(cholesky_factor.T))
  115.  
  116. # Order the eigenvalues and eigenvectors
  117. indices_ordered = np.argsort(eigenvalues)
  118. indices_ordered = np.flipud(indices_ordered)
  119.  
  120. # Return the calculated values
  121. return eigenvalues[indices_ordered], eigenvectors[:, indices_ordered]
Add Comment
Please, Sign In to add comment