KPSS Test
Calculate the Kwiatkowski-Phillips-Schmidt-Shin (KPSS) test for stationarity, per asset.
KPSS is the natural complement to the Augmented Dickey-Fuller test: where the ADF null hypothesis is that the series HAS a unit root, the KPSS null hypothesis is that the series IS stationary, with a unit root as the alternative. Running both together is standard practice to triangulate a confident conclusion – ADF rejecting a unit root and KPSS failing to reject stationarity together give a confident stationarity conclusion, while the two tests disagreeing flags an ambiguous case.
The formula is as follows:
\[\text{Yₜ} = \alpha + \text{eₜ} \;\text{fitted by OLS on the}\; \text{column} \;\text{level} (\text{Adj Close by default}),\;\; \text{with regression="c" (the default); "ct" adds a trend beta*t}\] \[\text{Sₜ} = \operatorname{Σ}(i = 1..t) \text{êᵢ}\] \[\text{KPSS} = \operatorname{Σ}(t = 1..n) \text{Sₜ} ^{2} / (n ^{2} \cdot \lambda ^{2})\] \[\lambda ^{2} = (1 / n) \cdot \text{Σêₜ} ^{2} + (2 / n) \cdot \operatorname{Σ}(s = 1..l) (1 - s / (l + 1)) \cdot \operatorname{Σ}(t = s + 1..n) \text{êₜ} \cdot \text{êₜ₋ₛ},\;\; \text{with}\; l = \text{lags} \;\text{or},\;\; \text{by default},\;\; \text{the Hobijn},\;\; \text{Franses and Ooms (2004) automatic bandwidth}\]- The p-value is interpolated from the KPSS (1992) critical value table, so it is bounded between 0.01 and 0.10
For more information about the method, see the following paper:
- Kwiatkowski, D., Phillips, P.C.B., Schmidt, P., & Shin, Y. (1992). “Testing the Null Hypothesis of Stationarity against the Alternative of a Unit Root.” Journal of Econometrics, 54(1-3), 159-178.
Also known as: KPSS test, stationarity test.
KPSS Test in Python or via the MCP
Install the Finance Toolkit with:
pip install financetoolkit -U
Then call get_kpss_test as shown below.
from financetoolkit import Toolkit
toolkit = Toolkit(
["^GSPC", "^N225"],
api_key="FINANCIAL_MODELING_PREP_KEY",
start_date="2021-01-01",
end_date="2025-12-31",
)
toolkit.econometrics.get_kpss_test()
Or, after setting up the Finance Toolkit MCP, ask:
Were the S&P 500 and the Nikkei 225 stationary from 2021 to 2025, according to the KPSS test?
Which returns:
| ^GSPC | ^N225 | |
|---|---|---|
| KPSS Statistic | 4.73448 | 4.79639 |
| P-Value | 0.01 | 0.01 |
| Lags Used | 21 | 21 |
| Observations | 1299 | 1298 |
| Critical Value 1% | 0.739 | 0.739 |
| Critical Value 2.5% | 0.574 | 0.574 |
| Critical Value 5% | 0.463 | 0.463 |
| Critical Value 10% | 0.347 | 0.347 |
| Reject Stationarity (5%) | 1 | 1 |
Using Your Own Data
get_kpss_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_kpss_test()
Parameters
get_kpss_test accepts the following parameters.
| Parameter | Type | Description | Example |
|---|---|---|---|
period | str | The data frequency (daily, weekly, monthly, quarterly, or yearly). Defaults to “daily”. | "weekly" |
column | str | The historical data column to test. Defaults to “Adj Close”. | "Return" |
regression | str | Which deterministic term to remove before testing, one of “c” (constant, level-stationarity) or “ct” (constant and trend, trend-stationarity). Defaults to “c”. | "ct" |
lags | int | The truncation lag for the long-run variance estimate. Defaults to statsmodels’ automatic (Hobijn, Franses & Ooms, 2004) bandwidth selection. | 8 |
include_benchmark | bool | Whether to include “Benchmark” among the assets tested. Defaults to False. | True |
rounding | int | None | The number of decimals to round the results to. Defaults to None. | 2 |