*! version 1.1.0 20jul2026

Title

lsmlm -- Lee-Strazicich minimum LM unit root test with zero, one, or two structural breaks

Syntax

lsmlm varname [if] [in] [, options]

Main
breaks(#) number of structural breaks: 0, 1, or 2; default is breaks(2). breaks(0) is the Schmidt-Phillips no-break LM test

model(string) deterministic model: break (level and trend shift) or crash (level shift only); default break. Ignored when breaks(0)

Search / lag selection
maxlag(#) maximum number of augmenting lags for general-to-specific selection; default is data driven

trim(#) fraction of the sample trimmed at each end for the break search; default trim(0.10)

mindist(#) minimum distance (in observations) between the two breaks; two-break case only; default mindist(2)

Other
timevar(varname) time variable to use if the data are not tsset

noprint suppress the results table

The data must be tsset (a single time series), or a time variable must be
given through timevar(). Use if / in to restrict the command
to any sub-sample: a time window (e.g. if inrange(year,1946,1994)) and/or a
single panel unit (e.g. if id==1).

Description

lsmlm performs the Lee-Strazicich minimum LM unit root test with up to two
endogenous structural breaks. The null hypothesis is a unit root; rejection is
evidence of (trend-)stationarity around the estimated breaks. Two deterministic
models are available: the crash model (a level shift at each break) and the
break model (a level and trend shift at each break, i.e. Lee-Strazicich
Model C). With breaks(0) the command reports the Schmidt-Phillips no-break
LM test.

The procedure follows Lee and Strazicich (2003, 2013) and Schmidt and Phillips
(1992): for every candidate break date (or pair of dates) the first-differenced
series is regressed on the differenced deterministic terms to recover the shift
magnitudes; the LM-detrended series S(t) is built (with S(1)=0 and
D.S equal to the residual of D.y on the differenced deterministics); and
D.y is regressed on those deterministics, S(t-1) and lagged D.S
terms. Augmenting lags are chosen by a general-to-specific rule (from
maxlag() downward, keeping the highest lag whose |t| >= 1.645). The break
date(s) that minimise the t-statistic on S(t-1) are selected, and that
minimum statistic is the test statistic.

The test statistic is computed in native Stata (adapted from the author's own
ls1break_lm / ls2break_lm routines). The critical values are
interpolated over the sample size and, for the trend-break model, over the break
fraction(s); the CV tables and interpolation routines are ported from the
leestra package (Eruygur, SSC s459688, MIT License).

The test is computed on a single time series (the tsset series, restricted
by if / in). For a panel, loop over units and call lsmlm
once per unit (see Examples).

Note. The break search is a native-Stata grid search, so run time grows with
the sample length and, for the two-break case, roughly with the square of the
sample. For long series or many panel units this is slower than a Mata
implementation such as leestra.

Options

Main

breaks(#) sets the number of structural breaks: 0, 1, or
2. The default is breaks(2). breaks(0) gives the Schmidt-Phillips
no-break LM test (no break dummies; model() is ignored).

model(string) selects the deterministic model: break (a level and
trend shift at each break, Lee-Strazicich Model C) or crash (a level shift
only at each break, Model A). The default is break.

Search / lag selection

maxlag(#) is the maximum number of lagged D.S terms considered by the
general-to-specific search. If not specified, it defaults to
floor(4*(T/100)^0.25) (at least 1), where T is the sample size.

trim(#) is the fraction of observations trimmed at each end of the sample
when searching for break dates; it must lie in (0, 0.5). The default is
trim(0.10).

mindist(#) is the minimum number of observations required between the two
breaks (two-break case only). The default is mindist(2).

Other

timevar(varname) names the time variable when the data are not tsset.
If omitted, the tsset time variable is used.

noprint suppresses the results table. All results are still returned in
r().

Stored results

lsmlm stores the following in r(). Break-specific results are present
only for the corresponding number of breaks; trend-dummy t-stats
(r(tD1), r(tD2)) are present only for model(break).

Scalars

r(tau) minimum LM t-statistic on S(t-1) (the test statistic)

r(k) number of augmenting lags chosen

r(breaks) number of breaks

r(N) observations in the final regression

r(maxlag) maximum lag used in the search

r(trim) trimming fraction used

r(cv1) r(cv5) r(cv10) interpolated 1%, 5%, 10% critical values

r(reject1) r(reject5) r(reject10) 1/0 rejection indicators

r(tb1) r(tb1_index) r(lambda1) first break date, index, fraction

r(break1_sig10) 1 if break 1 dummies are relevant (|t|>=1.645)

r(tB1) r(tD1) t-stats on the break-1 level and trend dummies

r(mindist) minimum break distance (two-break case)

r(tb2) r(tb2_index) r(lambda2) second break date, index, fraction (two-break case)

r(break2_sig10) r(tB2) r(tD2) break-2 relevance and dummy t-stats (two-break case)

Macros

r(siglevel) significance level of rejection, or "Not significant"

r(model) deterministic model

r(timevar) time variable used

r(varname) series tested

Examples

The package ships an example dataset, lsmlm_oecd15.dta: log relative
per-capita income (y) for 15 OECD countries, 1870-1994. Load it with:

. sysuse lsmlm_oecd15, clear

One country (France), two breaks:

. keep if country=="France"

. tsset year

. lsmlm y, breaks(2) maxlag(8) mindist(5)

No break (Schmidt-Phillips):

. tsset year

. lsmlm y, breaks(0)

One break, trend-break model (the default model):

. lsmlm y, breaks(1)

Two breaks, crash model:

. lsmlm y, breaks(2) model(crash)

Restrict to a time window with if:

. lsmlm y if inrange(year,1946,1994), breaks(2)

Annual-data settings (8 lags, minimum break gap of 5):

. lsmlm y, breaks(2) maxlag(8) mindist(5) trim(0.10)

Use the returned results:

. lsmlm y, breaks(2)

. display "tau=" r(tau) " breaks at " r(tb1) " and " r(tb2)

Loop over panel units and collect results (single unit per call):

. xtset id year

. tempname P

. postfile `P' int id int tb1 int tb2 double tau double cv5 byte rej10 using res.dta, replace

. levelsof id, local(ids)

. foreach i of local ids {

. preserve

. keep if id==`i'

. tsset year

. quietly lsmlm y, breaks(2) maxlag(8) mindist(5)

. post `P' (`i') (r(tb1)) (r(tb2)) (r(tau)) (r(cv5)) (r(reject10))

. restore

. }

. postclose `P'

References

Lee, J., and M. C. Strazicich. 2003. Minimum Lagrange multiplier unit root test
with two structural breaks. Review of Economics and Statistics 85(4): 1082-1089.

Lee, J., and M. C. Strazicich. 2013. Minimum LM unit root test with one structural
break. Economics Bulletin 33(4): 2483-2492.

Schmidt, P., and P. C. B. Phillips. 1992. LM tests for a unit root in the presence
of deterministic trends. Oxford Bulletin of Economics and Statistics 54(3): 257-287.

Example data

lsmlm_oecd15.dta is derived from the Maddison Project Database 2023, which is
licensed under a Creative Commons Attribution 4.0 International License. When using
it, please cite:

Bolt, J., and J. L. van Zanden. 2024. Maddison style estimates of the evolution of
the world economy: A new 2023 update. Journal of Economic Surveys 1-41.

Acknowledgment

The critical-value tables and interpolation routines are ported from the
leestra package by H. Ozan Eruygur (ssc describe leestra),
distributed under the MIT License.

Author

Ibrahim Ongoren, Department of Economics, Pamukkale University, Denizli, Turkey.
Email: ongorenibrahim78@gmail.com. The test statistic is adapted from the author's
own ls1break_lm / ls2break_lm routines.