*! version 1.1.0 28mar2026
help xtcbc version 1.1.0

Title

xtcbc -- Coefficient-by-Coefficient Breaks in Panel Data Models

Version

Version 1.1.0, 28 March 2026

Author: Dr Merwan Roudane (merwanroudane920@gmail.com)

Implements the CBCL estimator of Kaddoura (2025, Journal of Econometrics).

Syntax

xtcbc depvar indepvars [if] [in] [, options]

Penalty settings
kappa(#) weight exponent for adaptive weights; default is kappa(2)

ngrid(#) number of lambda grid points; default is ngrid(50)

constant(#) BIC-type penalty constant c; default is constant(0.05)

Data transformation
csdemean cross-section demean data to partial out interactive effects

Reporting
graph produce coefficient path, IC, and break timeline graphs

level(#) set confidence level; default is level(95)

You must xtset your data before using xtcbc; see xtset.

The panel must be strongly balanced (no gaps).

Description

xtcbc implements the Coefficient-by-Coefficient Lasso (CBCL) break
estimator proposed by Kaddoura (2025). Unlike traditional structural break
methods that estimate vector breaks (where all parameters shift simultaneously),
xtcbc allows each coefficient to have its own number of breaks and
break dates.

In a panel regression y_it = x'_it * beta_t + u_it, the vector-break approach
assumes all p components of beta_t change at the same dates. The CBC approach
relaxes this: the kth component beta_ can have m_k breaks, independently
for each k = 1, ..., p.

The method is designed for panels with large N and fixed or small T.
Asymptotics rely on N -> infinity.

Key features:

1. Automatic break detection: Simultaneously determines the number and location of breaks for each coefficient.

2. Adaptive penalization: Uses L1 fused penalty with adaptive weights that are asymptotically oracle-equivalent.

3. Post-selection estimation: Re-estimates coefficients in each regime using sub-regime OLS (Appendix B).

4. Information criterion: Selects optimal lambda via a BIC-type IC (Theorem 1.4).

5. Fixed-effects handling: Eliminates individual effects via first-period deviation.

Options

Penalty settings

kappa(#) specifies the exponent for adaptive weights:

w_ = |beta_dot_ - beta_dot_|^(-kappa)

where beta_dot are the initial partialed-out OLS estimates. Larger kappa
puts stronger penalty on small differences. Default is kappa(2),
following Qian and Su (2016) and Kaddoura (2025).

ngrid(#) specifies the number of log-spaced grid points for lambda.
The algorithm evaluates the CBCL objective at each point and selects the
lambda minimizing the information criterion. Default is ngrid(50).

constant(#) specifies the constant c in the BIC-type penalty:

phi = c * log(N) / sqrt(N)

Default is constant(0.05). Results are not very sensitive to c
within a reasonable range (0.01 to 0.10).

Data transformation

csdemean cross-section demeans data before estimation. Removes
cross-sectional means from both dependent and independent variables at
each time period. Useful for models with interactive/common factor effects,
following Kaddoura and Westerlund (2023).

Reporting

graph produces three diagnostic graphs saved as PNG files:

1. xtcbc_coefficients.png: Multi-panel graph showing coefficient paths beta_ over time. Dashed red lines mark detected break dates.

2. xtcbc_ic.png: IC_1(lambda) vs log(lambda). Dashed red line marks optimal lambda*.

3. xtcbc_timeline.png: Break timeline with coefficients on y-axis, time on x-axis.

level(#) specifies confidence level. Default is level(95).

Methodology

1. Data Generating Process

Consider the fixed-effects panel model:

y_it = xi_i + x'_it * beta_t + epsilon_it, i = 1,...,N, t = 1,...,T

where xi_i are individual fixed effects. The kth component follows:

beta_ = alpha_ for T_ <= t < T_, j = 1,...,m_k+1

where m_k is the number of breaks for coefficient k. Each coefficient
is free to have a different m_k and different break dates.

2. Fixed Effects Elimination

Fixed effects are eliminated via first-period deviation:

ytilde_it = y_it - y_i1 = x'_it * beta_t - x'_i1 * beta_1 + (eps_it - eps_i1)

3. Initial Estimates (Partialed-Out OLS, Eq 2.4)

For each k and t, the initial estimate beta_dot_ is obtained by
partialing out all other regressors:

beta_dot_ = [X'_ M_{-k,t} X_]^(-1) * X'_ M_{-k,t} ytilde_t

where M_A = I - A*(A'A)^(-1)*A' and X_{-k,t} includes all other regressors
at time t plus all first-period regressors.

4. CBCL Objective Function (Eq 2.3)

The penalized estimates minimize:

L_lambda(beta) = (1/N) * SUM_i SUM_ [ytilde_it - xbar'_it * beta]^2

+ lambda * SUM_ SUM_k w_ * |beta_ - beta_|

The L1 fused penalty encourages consecutive coefficients to be equal (fusing
them into regimes). Adaptive weights ensure true breaks are not over-penalized.
The estimator uses block coordinate descent with soft-thresholding and
bidirectional sweeps.

5. Post-Selection Estimation (Eq 2.5, Appendix B)

After detecting breaks, the post-selection estimator computes regime-specific
coefficients using sub-regime OLS:

alpha_ = [X'_ M_ X_]^(-1) * X'_ M_ ytilde_r

where r = r_ is the jth regime and M_ projects out block-diagonal
matrices of other coefficients' sub-regimes.

Sub-regime construction: For coefficient k in regime j, the other
coefficients ell != k may break at different dates. The estimator creates
sub-regime intersection sets r^(k,j)_ = r_ INTERSECT ell's cth regime.
This builds block-diagonal regressor matrices X_breve_ell.

6. Asymptotic Distribution (Theorem 1.3)

sqrt(N) * O^(1/2) * (alpha_hat - alpha_0) -> N(0, Theta_0^{-1} * Sigma_0 * Theta_0^{-1})

Standard errors come from the post-selection residual variance
and the cross-products of partialed-out regressors.

7. Tuning Parameter Selection (Theorem 1.4)

Lambda is selected by minimizing a BIC-type information criterion:

IC_1(lambda) = sigma^2_hat(lambda) + phi * SUM_k [mhat_k(lambda) + 1]

where:

- sigma^2_hat is the post-selection residual variance

- mhat_k(lambda) is the detected number of breaks for coefficient k

- phi = c * log(N) / sqrt(N) is the model complexity penalty

By Theorem 1.4, minimizing IC_1 consistently selects the true number
of breaks as N -> infinity.

Output Tables

xtcbc produces four publication-quality output tables:

1. Header: Model specifications: dependent variable, regressors, panel dimensions (N, T), penalty settings (kappa, c), and optimal lambda.

2. Break Detection: For each coefficient k, reports the number of breaks mhat_k and estimated break dates. Non-breaking coefficients marked none.

3. Post-Selection Estimates: Regime-specific coefficients with standard errors, t-statistics, and significance stars (* p<0.10, ** p<0.05, *** p<0.01).

4. CBC Estimation Results (Table 6 format): Paper-style table with "No breaks" column for stable coefficients and regime-specific columns for breaking coefficients.

Stored Results

xtcbc stores the following in e():

Scalars

e(N) number of cross-sectional units

e(T) number of time periods

e(p) number of regressors

e(kappa) adaptive weight exponent

e(ngrid) number of lambda grid points

e(c_const) BIC penalty constant c

e(opt_lambda) optimal tuning parameter lambda*

e(total_breaks) total breaks across all coefficients

e(nbreaks_k) breaks for coefficient k (k=1,...,p)

Matrices

e(nbreaks) 1 x p vector of break counts

e(break_dates) max_breaks x p matrix of break dates

e(alpha_info) n_alpha x 6 matrix: col 1=k, col 2=regime j, col 3=start, col 4=end, col 5=coef, col 6=SE

e(beta_hat) T x p matrix of penalized estimates

e(ic_values) ngrid x 1 vector of IC values

Macros

e(cmd) xtcbc

e(cmdline) full command as typed

e(depvar) dependent variable name

e(indepvars) independent variable names

e(title) estimation title

Examples

Example 1: Basic usage

. xtset id year

. xtcbc gdp_growth invest trade inflation

Example 2: With graphs and custom penalty

. xtcbc gdp_growth invest trade inflation, graph kappa(2) ngrid(100) constant(0.05)

Example 3: With cross-section demeaning

. xtcbc gdp_growth invest trade inflation, csdemean graph

Example 4: Simulated data with known break structure

. set seed 12345

. set obs 500

. gen id = ceil(_n / 5)

. gen time = mod(_n-1, 5) + 1

. xtset id time

. gen xi = 0

. forvalues i = 1/100 {

. local xv = rnormal()

. qui replace xi = `xv' if id == `i'

. }

. gen x1 = 0.2*xi + rnormal()

. gen x2 = 0.2*xi + rnormal()

. gen y = xi + 1*x1 + cond(time<=3, 2, 5)*x2 + rnormal(0, 0.5)

. drop xi

. xtcbc y x1 x2, graph

Example 5: Accessing stored results

. xtcbc y x1 x2 x3

. mat list e(nbreaks)

. mat list e(alpha_info)

. display "Optimal lambda = " e(opt_lambda)

. display "Total breaks = " e(total_breaks)

. display "Breaks in x1 = " e(nbreaks_1)

Example 6: Monte Carlo DGP from Section 4.1

. * See xtcbc_demo.do for the full simulation

. * p=6, T=5, N=200, true breaks = [2, 3, 0, 0, 0, 1]

. do xtcbc_demo.do

Remarks

Comparison with vector-break estimators.

In classic structural break estimation (Bai and Perron 1998, Qian and Su 2016),
all coefficients share the same break dates ("vector break" assumption). When
some coefficients do not actually change at a detected break date, this
introduces unnecessary regime-splitting, reduces effective sample size, increases
variance, and can mask the significance of truly time-varying coefficients.

The CBCL estimator resolves this by allowing each coefficient to break
independently. In the empirical application to U.S. county crime data
(Cornwell and Trumbull 1994), the vector-break estimator finds 2 breaks in
all sixteen coefficients, while the CBC estimator correctly finds breaks only
in three control variables, leaving the deterrence coefficients unbroken
(see paper Table 6).

Choosing kappa.

The adaptive weight exponent kappa controls penalization: larger kappa means
stronger shrinkage of small differences, making the estimator more
conservative (fewer false breaks). The value kappa=2 is standard and is
recommended by both Qian and Su (2016) and Kaddoura (2025).

Computational considerations.

Complexity: O(G * iter * T * p * N), where G = ngrid, iter = coordinate
descent iterations per lambda. For typical panels (N=100-500, T=5-20, p=3-8),
this takes seconds. For N > 1000, consider reducing ngrid.

Balanced panels required.

The current implementation requires strongly balanced panels. Unbalanced panels
should be balanced before running xtcbc.

Data requirements.

The algorithm requires T >= 3 and N >= p+1. Small T limits break detection.
The paper's Monte Carlo shows good performance for T=5 and N >= 100.

References

Kaddoura, Y. (2025). Estimating coefficient-by-coefficient breaks in panel
data models. Journal of Econometrics, 249, 106005.

Qian, J. and Su, L. (2016). Shrinkage estimation of common breaks in panel
data models via adaptive group fused lasso. Journal of Econometrics,
191, 86-109.

Kaddoura, Y. and Westerlund, J. (2023). Estimation of panel data models
with random interactive effects and multiple structural breaks when T is
fixed. Journal of Business & Economic Statistics, 41, 778-790.

Bai, J. and Perron, P. (1998). Estimating and testing linear models with
multiple structural changes. Econometrica, 66, 47-78.

Bonhomme, S. and Manresa, E. (2015). Grouped patterns of heterogeneity in
panel data. Econometrica, 83, 1147-1184.

Cornwell, C. and Trumbull, W. N. (1994). Estimating the economic model of
crime with panel data. Review of Economics and Statistics, 76, 360-366.

Author

Dr Merwan Roudane

merwanroudane920@gmail.com

Please cite as:

Roudane, M. (2026). xtcbc: Stata module for coefficient-by-coefficient
breaks in panel data models.

Also see

xtpmg, xtlmbreak, xtset, regress