*! _xtpvarcoint_rscoef.ado — Response Surface Coefficients *! Doornik (1998), Johansen et al. (2000), Trenkler et al. (2008), *! Kurita & Nielsen (2019), Trenkler (2008) *! Author: Dr Merwan Roudane (merwanroudane920@gmail.com) capture program drop _xpvc_rscoef_load program define _xpvc_rscoef_load version 14.0 end mata: // ============================================================ // Response surface coefficients for moments of asymptotic // LR test distributions under d = K - r_H0 stochastic trends // ============================================================ // Doornik (1998:591, Tab.7-8): Basic Johansen cases // Returns: 4-column matrix (TR_EZ, TR_VZ, ME_EZ, ME_VZ) // Input: d_H0 vector (K-r_H0), type string real matrix _xpvc_rscoef(real colvector d_H0, string scalar type) { real matrix coef, rs_term, moments real scalar n real colvector d2, d, sd, ones, d1, d2dum n = rows(d_H0) d2 = d_H0:^2 d = d_H0 sd = sqrt(d_H0) ones = J(n, 1, 1) d1 = (d_H0 :== 1) d2dum = (d_H0 :== 2) // rs_term: [d^2, d, sqrt(d), 1, dum(d=1), dum(d=2)] rs_term = d2, d, sd, ones, d1, d2dum if (type == "Case1") { coef = (2, -1.0000, 0.00000, 0.07000, 0.07000, 0.000000 \ 3, -0.3300, 0.00000, -0.55000, 0.00000, 0.000000 \ 0, 6.0019, -2.77640, -2.75580, 0.67185, 0.114900 \ 0, 1.8806, 14.71400, -15.4990, 1.11360, 0.070508) moments = rs_term * coef' } else if (type == "Case2") { coef = (2, 2.0100, 0.00000, 0.00000, 0.06000, 0.050000 \ 3, 3.6000, 0.00000, 0.75000, -0.40000, -0.300000 \ 0, 5.9498, -2.36690, 0.43402, 0.04836, 0.018198 \ 0, 2.2231, 12.05800, -7.90640, 0.58592, -0.034324) moments = rs_term * coef' } else if (type == "Case3") { coef = (2, 1.0500, 0.00000, -1.55000, -0.50000, -0.230000 \ 3, 1.8000, 0.00000, 0.00000, -2.80000, -1.100000 \ 0, 5.8271, -1.56660, -1.64870, -1.61180, -0.259490 \ 0, 2.0785, 13.07400, -9.78460, -3.36800, -0.245280) moments = rs_term * coef' } else if (type == "Case4") { coef = (2, 4.0500, 0.00000, 0.50000, -0.23000, -0.070000 \ 3, 5.7000, 0.00000, 3.20000, -1.30000, -0.500000 \ 0, 5.8658, -1.75520, 2.55950, -0.34443, -0.077991 \ 0, 1.9955, 12.84100, -5.54280, 1.24250, 0.419490) moments = rs_term * coef' } else if (type == "Case5") { coef = (2, 2.8500, 1.35000, -5.10000, -0.10000, -0.060000 \ 3, 4.0000, 0.00000, 0.80000, -5.80000, -2.660000 \ 0, 5.6364, -0.21447, -0.90531, -3.51660, -0.479660 \ 0, 2.0899, 12.39300, -5.33030, -7.15230, -0.252600) moments = rs_term * coef' } else if (type == "SL_trend") { coef = (1.9996, 0.0000, 0.0000, 1.0365, -0.3469, -0.1112 \ 2.9715, 0.0000, 0.0000, 1.4089, 0.0000, 0.4297 \ -0.0039, 6.1600, -3.3281, -0.5071, 0.3725, 0.0850 \ -0.0418, 3.4915, 9.2061, -8.9114, 0.6652, 0.0000) moments = rs_term * coef' } else if (type == "SL_mean") { coef = (2.0000, -1.0134, 0.0000, 0.1309, 0.0218, 0.0000 \ 2.9778, 0.0000, 0.0000, -1.7144, 0.9507, 0.4259 \ -0.0035, 6.1365, -3.2161, -2.3701, 0.5970, 0.1007 \ -0.0258, 2.6655, 12.4462, -13.6992, 0.8563, 0.0000) moments = rs_term * coef' } else { moments = J(n, 4, .) } return(moments) } // Full moment lookup function that dispatches to the right method real matrix _xpvc_CointMoments(real scalar dim_K, real colvector r_H0, string scalar type) { real colvector d_H0 d_H0 = dim_K :- r_H0 return(_xpvc_rscoef(d_H0, type)) } // ============================================================ // SL_ortho response surface (Trenkler 2008:Tab.7) // ============================================================ real matrix _xpvc_rscoef_SLortho(real colvector d_H0) { real matrix coef, rs_term, moments real scalar n real colvector d2, d, sd, ones, d1, d2dum n = rows(d_H0) d2 = d_H0:^2 d = d_H0 sd = sqrt(d_H0) ones = J(n, 1, 1) d1 = (d_H0 :== 1) d2dum = (d_H0 :== 2) rs_term = d2, d, sd, ones, d1, d2dum coef = (2.0008, -2.0990, 0.4463, 0.0000, 0.0000, -0.0503 \ 3.0152, -3.0099, 2.1117, 0.0000, 0.0000, -0.8004 \ 0.0000, 5.8766, -1.9791, -4.8042, 0.0000, 0.0000 \ 0.0000, 1.3279, 17.6880, 1.3279, 0.0000, 0.0000) moments = rs_term * coef' return(moments) } // ============================================================ // JMN STRUCTURAL BREAK COEFFICIENTS // Johansen, Mosconi, Nielsen (2000:229, Tab.4) // Log-moments for trace test with up to 2 breaks // ============================================================ real matrix _xpvc_rscoef_JMN(real colvector d_H0, real scalar dim_T, real colvector t_break, string scalar type) { real matrix moments real scalar n, dim_q, j real colvector vs, ls real scalar l1, l2 real colvector rs_subs real matrix rs_term, coef_EZ, coef_VZ n = rows(d_H0) dim_q = rows(t_break) + 1 if (dim_q > 3 | dim_q < 2) { moments = J(n, 4, .) return(moments) } // Compute relative sub-sample lengths real colvector zeros zeros = J(4 - dim_q, 1, 0) vs = sort((zeros \ (t_break :- 1) \ dim_T), 1) ls = sort(vs[2..rows(vs)] - vs[1..rows(vs)-1], 1) / dim_T l1 = ls[1] l2 = ls[2] rs_subs = (3 - dim_q) * d_H0 if (type == "Case2") { // JMN Case2 (H_c) coefficients rs_term = J(n, 1, 1), d_H0, J(n, 1, l1), J(n, 1, l2), /// d_H0:^2, d_H0*l1, d_H0*l2, J(n, 1, l1^2), J(n, 1, l1*l2), J(n, 1, l2^2), /// d_H0:^3, d_H0:*(l1^2), J(n, 1, l1^3), J(n, 1, l1*l2^2), J(n, 1, l1^2*l2), J(n, 1, l2^3), /// 1:/d_H0, l1:/d_H0, l2:/d_H0, (l1^2):/d_H0, (l1*l2):/d_H0, (l2^2):/d_H0, (l1^3):/d_H0, (l1*l2^2):/d_H0, (l2^3):/d_H0, /// 1:/(d_H0:^2), l2:/(d_H0:^2), (l1^2):/(d_H0:^2), (l2^2):/(d_H0:^2), (l1^3):/(d_H0:^2), (l2^3):/(d_H0:^3) coef_EZ = (2.8000, 0.5010, 1.4300, 0.399, -0.03090, -0.0600, 0.0000, -5.7200, -1.1200, -1.7000, /// 0.000974, 0.168, 6.34, 1.89, 0.00, 1.850, /// -2.19, -0.438, 1.79, 6.03, 3.08, -1.97, -8.08, -5.79, 0.00, /// 0.717, -1.290, -1.52, 2.87, 0.0, -2.03)' coef_VZ = (3.7800, 0.3460, 0.8590, 0.000, -0.01060, -0.0339, 0.0000, -2.3500, 0.0000, 0.0000, /// 0.000000, 0.000, 3.95, 0.00, 0.00, -0.282, /// -2.73, 0.874, 2.36, -2.88, 0.00, -4.44, 0.00, 0.00, 4.31, /// 1.020, -0.807, 0.00, 0.00, 0.0, 0.00)' } else if (type == "Case4") { // JMN Case4 (H_l) coefficients rs_term = J(n, 1, 1), d_H0, J(n, 1, l1), J(n, 1, l2), /// d_H0:^2, d_H0*l1, d_H0*l2, J(n, 1, l1^2), J(n, 1, l1*l2), J(n, 1, l2^2), /// d_H0:^3, d_H0:*(l1^2), J(n, 1, l1^3), J(n, 1, l1*l2^2), J(n, 1, l1^2*l2), J(n, 1, l2^3), /// 1:/d_H0, l1:/d_H0, l2:/d_H0, (l1^2):/d_H0, (l1*l2):/d_H0, (l2^2):/d_H0, (l1^3):/d_H0, (l1*l2^2):/d_H0, (l2^3):/d_H0, /// 1:/(d_H0:^2), l2:/(d_H0:^2), (l1^2):/(d_H0:^2), (l2^2):/(d_H0:^2), (l1^3):/(d_H0:^2), (l2^3):/(d_H0:^3) coef_EZ = (3.0600, 0.4560, 1.4700, 0.993, -0.02690, -0.0363, -0.0195, -4.2100, 0.0000, -2.3500, /// 0.000840, 0.000, 6.01, 0.00, -1.33, 2.040, /// -2.05, -0.304, 1.06, 9.35, 3.82, 2.12, -22.80, -7.15, -4.95, /// 0.681, -0.828, -5.43, 0.00, 13.1, 1.50)' coef_VZ = (3.9700, 0.3140, 1.7900, 0.256, -0.00898, -0.0688, 0.0000, -4.0800, 0.0000, 0.0000, /// 0.000000, 0.000, 4.75, 0.00, 0.00, -0.587, /// -2.47, 1.620, 3.13, -4.52, -1.21, -5.87, 0.00, 0.00, 4.89, /// 0.874, -0.865, 0.00, 0.00, 0.0, 0.00)' } else { moments = J(n, 4, .) return(moments) } // Log-moments → moments real colvector log_EZ, log_VZ log_EZ = rs_term * coef_EZ log_VZ = rs_term * coef_VZ moments = exp(log_EZ) - rs_subs, /// exp(log_VZ) - 2 * rs_subs, /// J(n, 1, .), J(n, 1, .) return(moments) } // ============================================================ // TSL STRUCTURAL BREAK COEFFICIENTS // Trenkler, Saikkonen, Luetkepohl (2008:349, Tab.AI) // Log-moments for trace test with trend breaks // ============================================================ real matrix _xpvc_rscoef_TSL(real colvector d_H0, real scalar dim_T, real colvector t_break) { real matrix moments real scalar n, dim_q real colvector vs, ls real scalar l1, l2 real matrix rs_term real colvector coef_EZ, coef_VZ n = rows(d_H0) dim_q = rows(t_break) + 1 if (dim_q > 3 | dim_q < 2) { moments = J(n, 4, .) return(moments) } // Compute relative sub-sample lengths (TSL use t_sub-1+1) real colvector zeros zeros = J(4 - dim_q, 1, 0) vs = sort((zeros \ t_break \ dim_T), 1) ls = sort(vs[2..rows(vs)] - vs[1..rows(vs)-1], 1) / dim_T l1 = ls[1] l2 = ls[2] // TSL coefficients (Trenkler et al 2008:349, Tab.AI) rs_term = J(n, 1, 1), d_H0, J(n, 1, l1), J(n, 1, l2), /// d_H0:^2, d_H0*l1, d_H0*l2, J(n, 1, l1^2), J(n, 1, l1*l2), J(n, 1, l2^2), /// d_H0:^3, (d_H0:^2)*l1, (d_H0:^2)*l2, d_H0*(l1^2), d_H0*(l1*l2), d_H0*(l2^2), /// J(n, 1, l1^3), J(n, 1, l1^2*l2), J(n, 1, l1*l2^2), J(n, 1, l2^3), /// 1:/d_H0, l1:/d_H0, l2:/d_H0, (l1^2):/d_H0, (l1*l2):/d_H0, (l2^2):/d_H0, /// (l1^3):/d_H0, (l1^2*l2):/d_H0, (l1*l2^2):/d_H0, (l2^3):/d_H0, /// 1:/(d_H0:^2), l1:/(d_H0:^2), l2:/(d_H0:^2), (l1^2):/(d_H0:^2), (l2^2):/(d_H0:^2), /// (l1^3):/(d_H0:^2), (l1^2*l2):/(d_H0:^2), (l1*l2^2):/(d_H0:^2), (l2^3):/(d_H0:^2) coef_EZ = (2.4402, 0.5664, 1.6881, -0.1674, -0.0367, -0.1265, 0.0286, -7.2613, -1.9837, -1.6794, /// 0.0012, 0.0044, -0.0014, 0.1830, 0.0293, 0.0303, 11.8030, -2.4871, 4.0200, 2.1430, /// -3.0135, 1.1124, 5.1272, 4.3452, 3.5022, -8.6823, -16.7672, 5.9728, -7.0978, 5.7110, /// 1.0331, -0.6479, -2.9655, 0.0000, 7.6083, 5.7696, -6.5948, 0.0000, -6.9392)' coef_VZ = (2.2377, 0.6725, -1.8646, 1.5842, -0.0440, 0.0000, -0.2485, 12.0954, 5.0822, -1.5583, /// 0.0013, 0.0105, 0.0135, -0.4765, -0.2405, 0.0898, -22.1045, 7.7659, -8.7651, -0.3356, /// -1.6753, 11.7097, -1.8672, -60.2299, -10.1422, 4.5029, 129.7558, -58.2770, 32.3138, 0.0000, /// 0.2956, -4.9776, 4.3265, 30.9656, -14.4186, -82.5994, 48.3167, -15.3335, 10.8817)' // Log-moments → moments (TSL uses exp() ) real colvector log_EZ, log_VZ log_EZ = rs_term * coef_EZ log_VZ = rs_term * coef_VZ moments = exp(log_EZ), exp(log_VZ), J(n, 1, .), J(n, 1, .) return(moments) } // ============================================================ // ENHANCED CointMoments with structural break support // Dispatches to JMN, TSL, or basic Doornik // ============================================================ real matrix _xpvc_CointMoments_break(real scalar dim_K, real colvector r_H0, string scalar type, real scalar dim_T, real colvector t_break) { real colvector d_H0 d_H0 = dim_K :- r_H0 if (type == "JMN_Case2" | type == "JMN_Case4") { string scalar base_type if (type == "JMN_Case2") base_type = "Case2" else base_type = "Case4" return(_xpvc_rscoef_JMN(d_H0, dim_T, t_break, base_type)) } else if (type == "TSL_trend") { return(_xpvc_rscoef_TSL(d_H0, dim_T, t_break)) } else if (type == "SL_ortho") { return(_xpvc_rscoef_SLortho(d_H0)) } else { // Fall back to basic Doornik (1998) coefficients return(_xpvc_rscoef(d_H0, type)) } } end