Calculate the Zivot-Andrews test for a unit root, per asset, allowing for a single structural break at an unknown (endogenously estimated) date.

The (A)DF/KPSS/PP tests above all assume the deterministic component of the series (its constant and/or trend) is stable throughout the sample. If a series instead has a single one-time break – e.g. a permanent level shift or a change in trend slope, such as a stock split, spin-off, or a structural shift in the business – the ordinary ADF test is biased towards not rejecting the unit root even for a genuinely (trend-)stationary series with a break. The Zivot-Andrews test corrects for this by adding a break dummy to the ADF regression and choosing, for each asset, the break date that is most favorable to the stationary alternative – which is why it needs its own (more negative) critical values rather than the ordinary ADF ones.

The formula is as follows:

\[\Delta \text{Yₜ} = \mu + \theta \cdot \text{DUₜ} + \beta \cdot t + \alpha \cdot \text{Yₜ₋₁} + \operatorname{Σ}(i = 1..p) \text{cᵢ} \cdot \Delta \text{Yₜ₋ᵢ} + \text{epsilonₜ},\;\; \text{with}\; \text{Yₜ} \;\text{the}\; \text{column} \;\text{level} (\text{Adj Close by default}) \text{and}\; \text{DUₜ} = 1 \;\text{after the break date}\; T_{B} \;\text{and}\; 0 \;\text{before it} (\text{regression} = \text{"c"},\; \text{the default})\] \[\text{regression="t" replaces theta*DUₜ by a trend break γ*DTₜ},\;\; \text{with}\; \text{DTₜ} = t - T_{B} \;\text{after the break and}\; 0 \;\text{before it},\;\; \text{and regression="ct" includes both}\] \[\text{ZA} = \text{min over}\; T_{B} \;\text{of}\; \text{alphâ} / \operatorname{SE}(\text{alphâ}),\;\; \text{searching every break date outside the first and last trim (15\% by default) of the sample}\] \[p = \text{the number of lags that minimises the AIC},\;\; \text{up to max\_lag (same default as get\_augmented\_dickey\_fuller)}\]

For more information about the method, see the following papers:

  • Zivot, E., & Andrews, D.W.K. (1992). “Further Evidence on the Great Crash, the Oil-Price Shock, and the Unit-Root Hypothesis.” Journal of Business & Economic Statistics, 10(3), 251-270.
  • Perron, P. (1989). “The Great Crash, the Oil Price Shock, and the Unit Root Hypothesis.” Econometrica, 57(6), 1361-1401.

Also known as: ZA test, structural break unit root test.

Zivot-Andrews Test in Python or via the MCP

Install the Finance Toolkit with:

pip install financetoolkit -U

Then call get_zivot_andrews_test as shown below.

from financetoolkit import Toolkit

toolkit = Toolkit(
    ["CLUSD"],
    api_key="FINANCIAL_MODELING_PREP_KEY",
    start_date="2021-01-01",
    end_date="2025-12-31",
)

toolkit.econometrics.get_zivot_andrews_test()

Or, after setting up the Finance Toolkit MCP, ask:

Did the price of WTI crude oil have a unit root from 2021 to 2025 once a single structural break is allowed for?

Which returns:

  CLUSD
Zivot-Andrews Statistic -4.1369
P-Value 0.271885
Break Index 243
Observations 1280
Lags Used 10
Critical Value 1% -5.27644
Critical Value 5% -4.81067
Critical Value 10% -4.56618
Reject Unit Root (5%) 0

Using Your Own Data

get_zivot_andrews_test runs on any data, not only prices: ratios, economic indicators, yield curves or your own dataset. Pass a DataFrame, a Series or a dictionary of them to Econometrics as data, with the dates in the rows or the columns, and set changes to how its changes are calculated: "percentage", "log", "difference" for rates and ratios, or None when the data are changes already. For example, for the monthly unemployment rates of the United States and Germany:

from financetoolkit import Economics, Econometrics

economics = Economics(start_date="2000-01-01")

unemployment = economics.get_unemployment_rate(
    countries=["United States", "Germany"], period="monthly"
)

econometrics = Econometrics(data=unemployment, changes="difference")

econometrics.get_zivot_andrews_test()

Parameters

get_zivot_andrews_test accepts the following parameters.

ParameterTypeDescriptionExample
periodstrThe data frequency (daily, weekly, monthly, quarterly, or yearly). Defaults to “daily”."weekly"
columnstrThe historical data column to test. Defaults to “Adj Close”."Return"
max_lagintThe maximum number of lagged differences to consider when selecting the (single, reused) lag length. Defaults to the Schwert (1989) rule of thumb, capped at (n - 5) // 3 for short samples.12
regressionstrWhich break to allow for, one of “c” (a break in the level/intercept), “t” (a break in the trend slope) or “ct” (both). Defaults to “c”."ct"
trimfloatThe fraction of observations excluded from the candidate break date search at the start and end of the sample. Must be in [0, 1/3). Defaults to 0.15.0.1
include_benchmarkboolWhether to include “Benchmark” among the assets tested. Defaults to False.True
roundingint | NoneThe number of decimals to round the results to. Defaults to None.2
Share