*! cupfm.sthlp — Help file for cupfm v1.0.2 2026-04-18

Title

cupfm -- Panel Cointegration with Global Stochastic Trends
(CupFM, CupBC, Bai FM, LSDV estimators; Bai, Kao & Ng 2009; Bai & Kao 2005)

Syntax

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

depvar and all indepvars must be numeric variables.
Time-series operators (L., D., F.) are allowed.
Factor variables (i., c.) are not supported.

The data must be declared as a panel with xtset before calling cupfm.
A balanced panel is required.

Factor model
nfactors(#) number of common factors r; default 0 = auto-select
via Bai & Ng (2002) information criterion

autormax(#) maximum r considered in auto-selection; default 8

Long-run covariance
bwidth(#) Bartlett kernel bandwidth (lag truncation M); default 5

kernel(kname) kernel function: bartlett (default) or parzen

Iteration control
maxiter(#) maximum Cup iterations; default 20

tolerance(#) convergence tolerance on Omega_; default 0.0001

Output control
noicsummary suppress the factor structure diagnostics table

noisily show verbose Mata iteration output

Visualization
plot produce all three plots (coef, factors, loadings)

plotcoef coefficient comparison forest plot only

plotfactors estimated common factors time-series plot only

plotloadings factor loadings bar/scatter plot only

saving(filename) base filename prefix for saved plots and exports
(no extension; default = cupfm)

Export
export(fmt) export results: excel, latex, csv, or all

Description

cupfm estimates panel cointegration models in which cross-sectional
dependence arises from a small number of common global stochastic trends.
It implements all five estimators in
Bai, Kao & Ng (2009) (BKN) and
Bai & Kao (2005) (BK), and is translated directly
from the authors' official GAUSS source code (bkn).

Standard panel cointegration estimators (LSDV, FMOLS, DOLS) are inconsistent
when cross-sectional dependence derives from I(1) common factors.
cupfm achieves sqrt(NT)-consistency and asymptotic normality
under the null of no spurious regression.

The primary estimator is CupFM (BKN 2009, Theorem 3). All five estimators
are reported in the results table. Post-estimation, every set of coefficients
and t-statistics is accessible via e(beta_*) and e(tstat_*).

Model, Notation, and Identification

Panel cointegrating regression:

y_it = alpha_i + beta'x_it + e_it, i = 1,...,N; t = 1,...,T

Error decomposition (factor structure):

e_it = lambda_i'F_t + u_it

Regressors:

x_it = x_ + v_it (I(1) random walk)

Common factors (two cases):

F_t = F_ + eta_t [BKN 2009: I(1) global stochastic trends]

F_t ~ I(0) [BK 2005: stationary factors, but same corrections apply]

Notation:

y_it -- dependent variable (must be I(1))

x_it -- k×1 vector of I(1) regressors

F_t -- r×1 vector of common factors (I(1) or I(0))

lambda_i -- r×1 vector of heterogeneous factor loadings

u_it -- idiosyncratic error (stationary, may be serially correlated)

alpha_i -- unit-specific fixed effect (eliminated by demeaning)

beta -- k×1 vector of cointegrating coefficients (common across i)

Identification: beta is assumed homogeneous across units.
The model permits heterogeneous factor loadings (lambda_i),
heterogeneous fixed effects (alpha_i), and heterogeneous autocovariance
structure of u_it.

Long-run covariance matrices:

Omega = lim(1/T) * sum_s sum_t E[z_it z_is']

where z_it = (u_it, v_it')', partitioned as

Omega = [Omega_uu Omega_uv]
[Omega_vu Omega_vv]

The FM and Cup corrections remove the endogeneity bias term
Delta = Omega_uv * Omega_vv^{-1} (conditional long-run covariance)
using the Bartlett kernel estimator of Omega with bandwidth M = bandwidth().

Assumptions

A1. Panel data format

Data must be in Stata long format with xtset declared.
A balanced panel is required: every unit must have exactly T observations,
ordered consecutively. cupfm checks this internally and exits with error
if the panel is unbalanced.

A2. Integration order of y and x

All variables in varlist must be I(1). The cointegrating relationship
y_it = alpha_i + beta'x_it + e_it is assumed to hold in levels.
cupfm does not test for cointegration — use xtpedroni
or panel unit-root tests first.

A3. Common factor structure

Cross-sectional dependence must arise from r common factors F_t.
The number r can be specified with nfactors() or auto-selected
(see nfactors(0)). Misspecifying r (too low) causes inconsistency;
too high wastes efficiency. Use nfactors(0) with autormax()
if r is unknown.

A4. Stationarity of idiosyncratic error u_it

After removing the common factors, the idiosyncratic errors u_it must be
stationary (I(0)). They may be serially correlated and cross-sectionally
independent. This is the cointegration condition. The Bartlett kernel
bandwidth() controls the long-run variance estimate of u_it.

A5. Factor loadings

Factor loadings lambda_i are assumed to be heterogeneous across i.
They are allowed to be random or fixed, as long as they are drawn from
a distribution with non-degenerate second moments:
(1/N) sum lambda_i lambda_i' -> Sigma_lambda > 0.

A6. Common beta (slope homogeneity)

The cointegrating vector beta is assumed identical across all units.
If slopes are heterogeneous, consider pooled mean-group approaches
(xtpmg). Testing slope homogeneity before using cupfm
is advisable (Pesaran & Yamagata 2008 delta-test).

A7. Panel dimensions

Asymptotic theory requires N -> Inf and T -> Inf,
with T/N -> c (finite positive constant) — the "balanced" or "sequential"
limit. In practice, simulation studies show good performance for
N >= 10, T >= 20. Very small panels (N < 5, T < 15) may give
unreliable results.

A8. I(1) factors (BKN 2009) vs I(0) factors (BK 2005)

BKN (2009) allows F_t to be I(1) or I(0). When F_t ~ I(0),
the model reduces to a standard panel FM regression with
cross-sectional dependence; CupFM remains consistent in both cases.
LSDV is biased only when F_t is I(1).

Estimators

LSDV (Least-Squares Dummy Variable / within estimator)

The standard fixed-effects estimator. Eliminates alpha_i by within-unit
demeaning, then regresses demeaned y on demeaned x.
Biased and inconsistent when F_t is I(1): the factor component
lambda_i'F_t is not removed by within-demeaning (BKN 2009 Prop. 1).
Included as baseline for comparison.

beta_LSDV = (sum_i X_i'M_F X_i)^{-1} sum_i X_i'M_F Y_i

where M_F is the within-unit annihilator and demeaning uses a pooled
common-mean estimator under the factor structure.

Bai FM (Two-step Fully Modified)

Non-iterative FM estimator (BK 2005, Eq. 7-8).
Step 1: regress LSDV to get beta_0 and factor estimates F_hat, Lambda_hat.
Step 2: construct FM correction using Bartlett long-run covariance estimates
from residuals. Applied once (no iteration).
Consistent but carries non-negligible finite-sample bias (MC Tables 1-4).

CupFM (Continuously-Updated Fully Modified) — RECOMMENDED

BKN (2009) Theorem 3, Eq. 16. The recommended estimator.
Iterates the Bai FM procedure:
beta^(j) -> residuals -> PCA -> Omega_hat -> FM correction -> beta^(j+1)
until |Omega_hat^(j) - Omega_hat^(j-1)| < tolerance() or maxiter() reached.

Asymptotically: sqrt(NT)(beta_CupFM - beta) ->_d N(0, V)
where V = 6*Omega_ / Sigma_xx (BKN 2009 Theorem 3).

Exhibits smallest bias in all BKN Monte Carlo experiments.
Convergence typically occurs within 5-10 iterations.

CupFM-bar (CupFM with Z-bar instrument)

Variant of CupFM where the instrument matrix uses
Z_bar = x_bar - F_hat * delta_bar instead of X.
This alternative identification within the CupFM framework
may improve small-sample performance in some designs
(BKN 2009, Eq. 16 alternative). Reported as "CupFM-z" in output.

CupBC (Continuously-Updated Bias-Corrected)

BKN (2009) Theorem 2. Iterates plain Cup LS (no FM transformation),
then applies the BC correction once at convergence.
BC uses the Bartlett estimate of Omega to subtract the bias term
Delta_ = Omega_ * Omega_^{-1}.
Performance similar to CupFM in MC studies.

Summary table:

Estimator Correction Iterates Consistent if F_t~I(1)

LSDV none no NO
Bai FM FM (1-step) no yes
CupFM FM yes yes (RECOMMENDED)
CupFM-bar FM (Z-bar) yes yes
CupBC BC yes yes

Options — Detailed Description

Factor model

nfactors(#) specifies the number of common factors r.

If 0 (default), r is selected automatically by minimizing the
Bai & Ng (2002) information criterion:

IC_1(k) = log V(k,F) + k * g(N,T)

where V(k,F) = (NT)^{-1} sum_i sum_t (e_it - lambda_i'F_t)^2 and
g(N,T) = (N+T)/(NT) * log(NT/(N+T)).

The criterion is evaluated for r = 0, 1, ..., autormax().
r = 0 is allowed (no common factor structure).

If nfactors() > 0, the specified r is used directly; no IC computed.

autormax(#) sets the maximum r to consider in auto-selection.
Default 8. Should be set <= min(N,T)/2 for reliable IC computation.
Ignored if nfactors() > 0.

Long-run covariance

bandwidth(#) sets the Bartlett kernel lag truncation M.
The long-run covariance matrix is estimated as:

Omega_hat = (1/T) sum_^ w_j * sum_t z_t z_'

where w_j = 1 - |j|/(M+1) (Bartlett weights), z_t = (u_hat_t, v_hat_t').
BKN (2009) Monte Carlo uses M = 5 and finds results stable.
Larger M reduces bias but increases variance of Omega_hat.
A common rule is M = floor(4*(T/100)^{2/9}).
Default 5.

kernel(kname) selects the kernel function.

bartlett (default): w_j = 1 - |j|/(M+1). Positive semi-definite.
parzen: smoother taper. Both give consistent Omega_hat as M -> Inf.

Iteration control

maxiter(#) sets the maximum number of Cup iterations.
Default 20 (matching the BKN GAUSS code). Convergence criterion:
|Omega_^(j) - Omega_^(j-1)| < tolerance().
If convergence is not achieved, e(converged) = 0 and a warning is printed.
Stored: e(niter) = actual iterations performed.

tolerance(#) convergence threshold. Default 0.0001.
Applied to the conditional long-run variance Omega_ = Omega_uu - Omega_uv * Omega_vv^{-1} * Omega_vu.
Tighter tolerances may require more iterations but give more precise estimates.

Output control

noicsummary suppresses the "Factor Structure Diagnostics" table
(Bai-Ng IC values, factor loading column means, bandwidth).
Does not suppress the estimation results table.

noisily activates verbose Mata output: prints convergence progress,
Omega matrices, and intermediate factor estimates at each iteration.
Useful for debugging; not recommended for routine use.

Visualization

plot generates all three publication-quality plots (equivalent
to specifying plotcoef, plotfactors, and plotloadings together).
Plots are exported as PNG (1200x700 pixels for coef/factors, 1000x700 for loadings).

plotcoef produces a coefficient comparison forest plot for each regressor.
Shows the point estimates with 95% CI for all five estimators,
color-coded and overlaid for direct comparison.

plotfactors produces a time-series plot of the estimated common factors
F_hat_1,...,F_hat_r, using r color-coded lines.

plotloadings produces either (a) a bar chart of lambda_i1 across N units
if r=1, or (b) a scatter plot of lambda_i2 vs lambda_i1 (labelled by unit i)
if r>=2.

saving(filename) sets the base filename prefix for saved PNG files and
spreadsheet/LaTeX exports. No extension should be included.
Default: "cupfm". Plot files will be named
filename_coef_varname.png, filename_factors.png, filename_loadings.png.

Export

export(fmt) exports the estimation results table to an external file.

excel — writes an .xlsx file with formatted results tables
(requires Stata 14+ and the putexcel facility).

latex — writes a .tex file with booktabs-formatted table,
suitable for direct inclusion in LaTeX documents.

csv — writes a plain .csv file with all five estimators' results.

all — writes all three formats simultaneously.

Files are named saving_cupfm.xlsx, .tex, .csv.
If saving() is not specified, defaults to "cupfm_results".

Cautions and Important Notes

C1. No cointegration pre-test

cupfm assumes the variables are cointegrated. Spurious results will occur
if y and x are not cointegrated. Always test for panel cointegration first
using xtpedroni or Westerlund (2007) tests before using cupfm.

C2. LSDV is biased — do not use for inference

The LSDV estimator is systematically biased upward/downward when F_t ~ I(1).
It is shown in the output table for reference only. Do not base conclusions on it.
Bias grows with r and the signal-to-noise ratio of F_t.

C3. Bandwidth choice affects all estimators

All five estimators depend on the Bartlett estimate of Omega.
An inappropriate bandwidth M can cause inference distortions.
Check robustness by re-running with different bandwidth() values
(e.g., M = 3, 5, 8, 10). Results should be stable if the model is correctly specified.

C4. Factor number misspecification

Underspecifying r (too few factors) leaves correlated residuals and produces
inconsistent estimates — worse than LSDV in finite samples.
Overspecifying r wastes degrees of freedom but is less harmful.
When in doubt, use nfactors(0) (auto-selection) or compare results
across adjacent values of r.

C5. Convergence and maxiter

If e(converged) = 0, CupFM and CupBC reached maxiter() without
converging. This can happen with poorly conditioned data (near-singular Omega),
extreme serial correlation, or misspecified r.
Try increasing maxiter(), changing bandwidth(), or specifying r explicitly.
The printed "CupFM iterations" value shows how many steps were taken.

C6. Small N or small T

Asymptotic normality requires both N and T -> Inf. With N < 10 or T < 20,
the distribution of t-statistics may be non-normal. Significance stars
(based on 1.96 and 2.576 critical values) should be interpreted cautiously.

C7. Balanced panel requirement

An unbalanced panel will produce an error. If your data has gaps,
consider: (a) filling gaps with interpolation, (b) using a balanced subsample,
or (c) using estimators designed for unbalanced panels.

C8. Slope homogeneity

cupfm imposes a common beta across all i. If true slopes vary,
the "average" estimate from CupFM may mask economically important
heterogeneity. Pre-test with the Pesaran-Yamagata (2008) delta-test.

C9. The level option is fixed at 95%

Confidence intervals and significance stars are based on a fixed 95% CI.
The option level() is reserved by Stata's eclass system and cannot
be passed to cupfm. All CIs use z_{0.975} = 1.960.

C10. Plot export in batch mode

Graphical output (PNG plots) requires that Stata can access a display.
In server batch mode without a display, use capture around the
cupfm call with plot, or suppress plots and use export()
for tabular results instead.

Stored Results

cupfm stores the following in e().
The primary result e(b) and e(V) correspond to CupFM.

Scalars

e(Nobs) total observations N*T

e(Ng) number of cross-section units N

e(Tperiods) number of time periods T

e(nfactors) number of common factors r used in estimation

e(bw) bandwidth parameter M

e(maxiter) maximum iterations setting

e(niter) actual CupFM iterations performed

e(converged) 1 = CupFM converged before maxiter; 0 = reached maxiter

e(cvar_cupfm) conditional long-run variance Omega_ at CupFM convergence

e(cvar_cupbc) conditional long-run variance Omega_ at CupBC convergence

e(level) confidence level (always 95)

Matrices

e(b) 1×k CupFM coefficient row vector (primary result)

e(V) k×k CupFM variance-covariance matrix (diagonal: se_j^2)

e(beta_lsdv) 1×k LSDV coefficients

e(beta_baifm) 1×k Bai FM coefficients

e(beta_cupfm) 1×k CupFM coefficients

e(beta_cupfm2) 1×k CupFM-bar coefficients

e(beta_cupbc) 1×k CupBC coefficients

e(tstat_lsdv) 1×k LSDV t-statistics

e(tstat_baifm) 1×k Bai FM t-statistics

e(tstat_cupfm) 1×k CupFM t-statistics

e(tstat_cupfm2) 1×k CupFM-bar t-statistics

e(tstat_cupbc) 1×k CupBC t-statistics

e(F_hat) T×r matrix of estimated common factors F_hat

e(Lambda) N×r matrix of estimated factor loadings Lambda_hat

e(Omega) (k+1)×(k+1) long-run covariance Omega_hat (CupFM)

e(Omega_bc) (k+1)×(k+1) long-run covariance Omega_hat (CupBC)

e(Aik) N×N rotation weight matrix a_ik

Strings

e(cmd) cupfm

e(cmdline) full command as typed by the user

e(depvar) name of dependent variable

e(indepvars) names of independent variables

e(panelvar) panel unit variable (from xtset)

e(timevar) time variable (from xtset)

e(kernel) kernel used for long-run covariance

e(estimator) CupFM

e(papers) bibliographic references (BKN 2009, BK 2005)

e(vcetype) variance type description

Post-Estimation

After cupfm, all standard e()-retrieval commands work on the
primary CupFM result (e(b), e(V)):

. matrix list e(b)

. matrix list e(V)

. ereturn list

To retrieve individual estimator results:

. matrix cupfm_coef = e(beta_cupfm)

. matrix cupbc_coef = e(beta_cupbc)

. matrix lsdv_coef = e(beta_lsdv)

To extract the estimated common factors for further analysis:

. matrix F = e(F_hat)

. svmat F, names(factor)

To extract factor loadings:

. matrix L = e(Lambda)

. svmat L, names(lambda)

Standard errors (from e(V)) are constructed as:

se_j = |beta_j / t_j|

(back-computed from stored t-statistics). Confidence intervals:

CI_j = [beta_j +/- 1.960 * se_j] (95% level, fixed)

Note: predict is not supported after cupfm.
Residuals can be computed manually: gen resid = y - e(b)[1,1]*x1 - ...

Examples

Example 1: Basic usage with auto-selected factors

. xtset id year

. cupfm y x1

Example 2: Specify 2 factors, bandwidth 10, max 30 iterations

. cupfm y x1 x2, nfactors(2) bandwidth(10) maxiter(30)

Example 3: Auto-select r up to 5 factors, suppress IC table

. cupfm y x1 x2, nfactors(0) autormax(5) noicsummary

Example 4: With all plots, save PNG and export to all formats

. cupfm y x1 x2, nfactors(2) plot saving(myresults) export(all)

Example 5: Individual plots

. cupfm y x1 x2, nfactors(2) plotcoef saving(coef_only)

. cupfm y x1 x2, nfactors(2) plotfactors saving(factors_only)

Example 6: Reproduce BKN (2009) Monte Carlo design

. cupfm y x1, nfactors(1) bandwidth(5) maxiter(20)

Example 7: Post-estimation — access all coefficients

. cupfm y x1 x2, nfactors(2)

. matrix list e(beta_cupfm)

. matrix list e(beta_lsdv)

. scalar bias = e(beta_cupfm)[1,1] - e(beta_lsdv)[1,1]

. di "Bias reduction (x1): " %8.4f bias

Example 8: Extract factors for external use

. cupfm y x1, nfactors(2)

. matrix F = e(F_hat)

. svmat F, names(f)

. tsline f1 f2, legend(label(1 "Factor 1") label(2 "Factor 2"))

Example 9: Robustness check across bandwidths

. foreach bw in 3 5 8 10 {

. cupfm y x1, nfactors(2) bandwidth(`bw') noicsummary

. di "BW=`bw': beta=" %6.4f e(beta_cupfm)[1,1]

. }

Example 10: Parzen kernel

. cupfm y x1 x2, nfactors(2) kernel(parzen) bandwidth(8)

References

Bai, J., Kao, C. & Ng, S. (2009).
Panel cointegration with global stochastic trends.
Journal of Econometrics, 149(1), 82-99.
https://doi.org/10.1016/j.jeconom.2008.10.012

Bai, J. & Kao, C. (2005).
On the estimation and inference of a panel cointegration model
with cross-sectional dependence.
CPR Working Paper No. 75, Syracuse University.
SSRN-1815227

Bai, J. & Ng, S. (2002).
Determining the number of factors in approximate factor models.
Econometrica, 70(1), 191-221.
https://doi.org/10.1111/1468-0262.00273

Phillips, P.C.B. & Hansen, B.E. (1990).
Statistical inference in instrumental variables regression with I(1) processes.
Review of Economic Studies, 57(1), 99-125.

Phillips, P.C.B. & Moon, H.R. (1999).
Linear regression limit theory for nonstationary panel data.
Econometrica, 67(5), 1057-1111.

Pesaran, M.H. & Yamagata, T. (2008).
Testing slope homogeneity in large panels.
Journal of Econometrics, 142(1), 50-93.

Westerlund, J. (2007).
Testing for error correction in panel data.
Oxford Bulletin of Economics and Statistics, 69(6), 709-748.

Author

Dr. Merwan Roudane

Email: merwanroudane920@gmail.com

Package: search cupfm

This package implements all five estimators exactly as coded in the official
GAUSS source code (bkn folder) distributed by Bai, Kao & Ng (2009)

and Bai & Kao (2005). Numerical results are verified against the GAUSS output.

Bug reports and suggestions: merwanroudane920@gmail.com