HomeStatistical ModelKPSS Test Calculator: Free Online Stationarity Test | Stats Unlock

KPSS Test Calculator: Free Online Stationarity Test | Stats Unlock

KPSS Test Calculator: Free Online Stationarity Test

KPSS Test Calculator

Test whether a time series is stationary with the Kwiatkowski-Phillips-Schmidt-Shin (KPSS) test. Paste your data, pick level or trend stationarity, and get the KPSS statistic, p-value, critical values, four diagnostic charts and ready-to-paste APA wording, with matching Excel, R and Python code.

By StatsUnlock Team · Methods checked against R tseries and Python statsmodels · Last updated

Time SeriesStationarityLevel & TrendUnit RootAPA 7Excel, R & Python

⚡ 0. Quick Answer

The KPSS test checks whether a time series is stationary. Its null hypothesis is stationarity, so a large statistic means the series is not stationary.

Fit a mean (level) or a straight line (trend), add up the residuals over time, and compare the size of those running sums with the long-run variance. Reject stationarity at 5% when η is above 0.463 for level, or above 0.146 for trend.

η = Σ St² ÷ (T² × σ̂²LR)

Worked example: 24 months of rainfall anomaly give η = 0.0856 with lag 2. That is below 0.463, so p > 0.10 and the series is level-stationary.

Key Takeaways

  • The KPSS test has the opposite null to the ADF test: H0 = stationary.
  • 5% critical values are 0.463 (level) and 0.146 (trend), from Kwiatkowski et al. (1992).
  • The default lag is trunc(4(T/100)1/4), the same rule R's tseries::kpss.test uses.
  • p-values come from a table, so software reports p > 0.10 or p < 0.01 at the ends.
  • Always pair KPSS with ADF: agreement between the two is the strongest evidence you can report.

📚 1. What Is the KPSS Test?

The KPSS test (Kwiatkowski, Phillips, Schmidt and Shin, 1992) is a test for stationarity. A stationary series has a constant mean, a constant variance, and the same correlation pattern at every point in time. Most forecasting models, such as ARIMA and VAR, assume this.

What it measures: the test removes a mean (level version) or a straight line (trend version) from the data. It then adds up the leftover residuals one step at a time. If the series is stationary, these running sums wander a little and come back to zero. If the series has a unit root, the sums drift far away. η is the size of that drift, scaled by the long-run variance.

Two versions:

  • Level stationarity (ημ): the series moves around a fixed mean.
  • Trend stationarity (ητ): the series moves around a fixed straight-line trend.

A worked one-liner: rainfall anomaly over 24 months, mean 13.54 mm, sum of squared running sums 67.34, long-run variance 1.366, so η = 67.34 ÷ (576 × 1.366) = 0.0856, well under 0.463.

Time (t = 1 to 24)17.010.0Level-stationary series
Green: a stationary series around its mean (dashed red). The running sum of residuals stays near zero, so η is small.

Who uses it: economists before ARIMA, cointegration and VAR models; ecologists testing population counts and camera-trap indices; hydrologists checking streamflow; climate scientists checking temperature anomalies; finance analysts checking returns and spreads.

FeatureKPSS testADF testPhillips-Perron test
Null hypothesisStationaryUnit root (non-stationary)Unit root (non-stationary)
Reject meansNon-stationaryStationaryStationary
Handles autocorrelation byLong-run variance (kernel)Lagged differencesLong-run variance (kernel)
Main weaknessOver-rejects with strong autocorrelation or breaksLow power near a unit rootSize problems with MA errors
Best useConfirmation test beside ADFDefault unit-root testAlternative to ADF

🧮 2. Set Up Your Data

Commas, spaces, tabs or new lines all work. Blank entries are skipped. Text such as NA is ignored.
Supports .csv, .txt, .xlsx and .xls. Click a numeric column to use it as the series.

Type one value per row, in time order. Empty rows are ignored.

tValue

📊 3. Results

Load or paste your series above, then press Run KPSS Test. The KPSS statistic, p-value, critical values, assumption checks, four charts and auto-filled reporting text will appear here.

💡 4. Interpretation of Results, In Detail

▶ Run the analysis above to fill 4.1 to 4.4 with your own numbers. The run will replace every ___ placeholder.

4.1 What was found

η = ___, critical value = ___, decision ___.

4.2 What the p-value means

p = ___.

4.3 Lag choice and sensitivity

Lag = ___.

4.4 What to do next

___

4.5 Reading the KPSS statistic

η has no units. It compares how far the running sums travel with how noisy the data are. Values near 0.05 to 0.15 are typical of clearly stationary series. Values above 1 usually mean a strong trend or a unit root.

4.6 Decision guide: KPSS with ADF

ADF resultKPSS resultConclusionAction
Rejects unit rootDoes not reject stationarityStationaryModel in levels
Does not rejectRejects stationarityUnit rootDifference once and test again
RejectsRejectsConflictLook for breaks, long memory or a trend you missed
Does not rejectDoes not rejectNot enough dataBoth tests lack power; collect more data or use theory

4.7 Level result vs trend result

If the level test rejects but the trend test does not, the series is trend-stationary. Remove the straight line with a linear regression (detrend), do not difference. If both reject, the series is difference-stationary: take first differences.

4.8 Common mistakes this calculator prevents

  • Reading the p-value the ADF way round. Here a small p means non-stationary.
  • Reporting p = 0.10 as if it were exact. The calculator shows p > 0.10 when η is below the 10% value.
  • Forgetting to report the lag. The lag changes η, so the write-up templates always include it.
  • Using level critical values for a trend test. The calculator switches tables automatically.

✍ 5. How to Write Your Results in Research

▶ Run the analysis above to auto-fill all five examples with your results.

Example 1, APA 7th Edition
A KPSS test for ___ stationarity was ___, KPSS = ___, lag = ___, p ___.
📌 Key conventions for this style
  • Name the version: level or trend.
  • Report the statistic, the lag and the kernel.
  • Write p > .10 or p < .01 at the table ends; never p = .000.
  • Say what the null was, because KPSS is the opposite of ADF.
Example 2, Thesis / Dissertation
___
📌 Key conventions for this style
  • Cite Kwiatkowski et al. (1992) and your lag rule (Schwert, 1989).
  • Report ADF beside KPSS.
  • State what you did next: model in levels, detrend, or difference.
  • Name the software and version.
Example 3, Plain-Language Summary
___
📌 Key conventions for this style
  • No symbols. Say "stable over time" for stationary.
  • Say the practical consequence.
  • Three or four short sentences.
Example 4, Structured Abstract / Poster
___
📌 Key conventions for this style
  • Background, Methods, Results, Conclusion.
  • Put n, lag and alpha in Methods.
  • The Conclusion states the modelling consequence.
Example 5, Replication / Pre-Registration
___
📌 Key conventions for this style
  • Fix the lag rule and kernel before seeing the data.
  • Report the exact decision rule.
  • Give the package and function, for example tseries::kpss.test.
  • Link data and code (OSF, GitHub, Zenodo).

∑ 6. Formulas Used

①
KPSS Test Statistic
η = (1 ÷ T²) × Σt=1T St² ÷ σ̂²LR
ηKPSS statistic, unitless. ημ for level, ητ for trend
TNumber of observations
StRunning sum of residuals up to time t, same units as the data
σ̂²LRLong-run variance of the residuals, data units squared
RuleReject stationarity when η is above the critical value
Example67.3403 ÷ (576 × 1.3661) = 0.0856
②
Residuals: Level or Trend
Level: et = yt − ȳ  ·  Trend: et = yt − α̂ − β̂t
ytObserved value at time t
ȳMean of the series
α̂, β̂OLS intercept and slope on t = 1, 2, ..., T
Use forLevel when the series is flat; trend when it rises or falls steadily
③
Partial (Running) Sums
St = e1 + e2 + … + et
StCumulative residual at time t
STAlways equals 0, because OLS residuals sum to zero
NoteLong excursions away from zero are what make η large
④
Autocovariance at Lag j
γ̂j = (1 ÷ T) × Σt=j+1T et et−j
γ̂0Ordinary variance of the residuals (divided by T, not T − 1)
jLag, 1 to l
Exampleγ̂0 = 3.6649, γ̂1 = −1.4532, γ̂2 = −0.5418
⑤
Long-Run Variance (Bartlett Kernel)
σ̂²LR = γ̂0 + 2 Σj=1l [1 − j ÷ (l + 1)] γ̂j
lLag truncation (bandwidth), a whole number
1 − j/(l+1)Bartlett weight. The rectangular kernel uses weight 1
RequiresA positive result. Bartlett guarantees this; rectangular may not
Example3.6649 + 2(2/3)(−1.4532) + 2(1/3)(−0.5418) = 1.3661
⑥
Lag Selection Rules
l4 = trunc[4(T ÷ 100)1/4]  ·  l12 = trunc[12(T ÷ 100)1/4]
l4Short rule (Schwert, 1989). R tseries default
l12Long rule. Safer with strong autocorrelation, lower power
ExampleT = 24: l4 = trunc(2.78) = 2
⑦
Critical Values and p-value
Level: 0.347 | 0.463 | 0.574 | 0.739  ·  Trend: 0.119 | 0.146 | 0.176 | 0.216
Orderα = 0.10, 0.05, 0.025, 0.01
pLinear interpolation between these points, as in R tseries
RangeReported as p > 0.10 or p < 0.01 outside the table

🔀 7. KPSS Test Calculation Flowchart, Step by Step

This flowchart shows how the KPSS test is calculated, step by step, for the worked example: 24 months of rainfall anomaly (mm), tested for level stationarity. The same numbers appear in Sections 9, 10, 11 and 13.

Start or resultData stepCalculation stepYes or no check
StartRaw series in time order24 monthly values: 12, 15, 11, 14, 16, 13, ..., 15, 13
CheckAre there gaps, text or missing months?
Yes, stopFill or remove gaps carefully. Dropping a month shifts every later time step.
NoAll 24 months are present and in order.
1
Choose level or trend, then fit itLevel: ȳ = Σy ÷ Tȳ = 325 ÷ 24 = 13.5417
2
Residualset = yt − ȳ−1.5417, 1.4583, −2.5417, 0.4583, 2.4583, ...
3
Running sums and their squaresSt = St−1 + et−1.5417, −0.0833, −2.6250, ... so ΣSt² = 67.3403
4
Pick the lagl = trunc[4(24 ÷ 100)1/4]l = 2
5
Long-run varianceγ̂0 + 2(2/3)γ̂1 + 2(1/3)γ̂23.6649 − 1.9376 − 0.3612 = 1.3661
CheckIs the long-run variance positive?
No, stopSwitch to the Bartlett kernel or a different lag.
Yes1.3661 is positive, carry on.
6
Compute ηη = ΣSt² ÷ (T² × σ̂²LR)67.3403 ÷ (576 × 1.3661) = 0.0856
CheckIs η above the 5% critical value of 0.463?
YesReject stationarity. Difference or detrend.
No0.0856 < 0.463, keep the null.
ResultKPSS level = 0.0856, lag = 2, p > 0.10Level-stationaryRule: reject H0 only if η > critical value at α.

Excel (Section 9), R (Section 10) and Python (Section 11) all return 0.0856 for this series with lag 2.

📖 8. How to Use This Calculator

  1. Load or paste your data. Paste values in time order, or load sample 1 (rainfall anomaly, 24 months).
  2. Name the series. Click the name box and type a label; it is used in every report.
  3. Or upload a file. Use the Upload tab for CSV or Excel and click the numeric column you want.
  4. Choose level or trend. Level for a flat series, trend for a steadily rising or falling one.
  5. Set alpha. 0.05 is standard. 0.10, 0.025 and 0.01 are available.
  6. Pick the lag rule. Keep the short rule to match R; try the long rule to check sensitivity.
  7. Choose the kernel. Keep Bartlett unless you have a reason to use rectangular.
  8. Press Run KPSS Test. For sample 1 you get KPSS = 0.0856, lag 2, p > 0.10.
  9. Read the verdict and charts. Check the running-sum chart and the assumption table.
  10. Copy the write-up. Copy an APA, thesis or plain-language sentence from Section 5, or download the Doc or PDF report.

📈 9. How to Run the KPSS Test in Excel

Excel has no KPSS function, and the Analysis ToolPak does not include one either. You can still build it with ordinary formulas in about five columns. The steps below reproduce η = 0.0856 for the rainfall example.

In one line: put the data in A2:A25, residuals in B, running sums in C, then =SUMSQ(C2:C25)/(COUNT(A2:A25)^2*H5) where H5 holds the long-run variance.

9.1 The functions you need

You wantExcel formulaNote
Mean=AVERAGE($A$2:$A$25)Level version only
Trend residual=A2-TREND($A$2:$A$25,$D$2:$D$25,D2)D holds t = 1 to 24
Running sum=SUM($B$2:B2)Fill down
γ̂0=SUMSQ(B2:B25)/24Divide by T, not T − 1
γ̂j=SUMPRODUCT(B3:B25,B2:B24)/24Shift the second range by j rows
Lag=TRUNC(4*(24/100)^0.25)Short Schwert rule
VAR.S is the wrong variance. It divides by T − 1. KPSS uses T, so use SUMSQ/COUNT or VAR.P. Using VAR.S makes η about 4% smaller for T = 24.

9.2 Step by step

1 Data and residuals

Paste the 24 values into A2:A25. In B2 type the residual formula and fill down.

=A2-AVERAGE($A$2:$A$25)
Book1 - KPSSB2fx=A2-AVERAGE($A$2:$A$25)AB1RainResid e212-1.54173151.4583411-2.54175140.45836162.4583713-0.5417810-3.54179140.4583

The mean is 13.5417, so the first residual is 12 − 13.5417 = −1.5417.

2 Running sums

In C2 type a sum with an anchored start and fill down. C25 should come out as 0.

=SUM($B$2:B2)
Book1 - KPSSC4fx=SUM($B$2:B4)ABC1RainResid eS(t)212-1.5417-1.54173151.4583-0.0833411-2.5417-2.62505140.4583-2.16676162.45830.2917713-0.5417-0.2500810-3.5417-3.79179140.4583-3.3333

S3 = −2.6250. Then =SUMSQ(C2:C25) gives 67.3403.

3 Autocovariances and long-run variance

Compute γ̂0, γ̂1, γ̂2, then combine them with Bartlett weights.

=H2+2*(1-1/3)*H3+2*(1-2/3)*H4
Book1 - KPSSH5fx=H2+2*(1-1/3)*H3+2*(1-2/3)*H4AB1QuantityValue2gamma03.66493gamma1-1.45324gamma2-0.54185LR var1.3661

3.6649, −1.4532 and −0.5418 combine to a long-run variance of 1.3661.

4 The KPSS statistic and decision

Divide, then compare with the critical value.

=IF(H6>0.463,"Reject: non-stationary","Keep: stationary")
Book1 - KPSSH7fx=G6/(24^2*H5)AB1QuantityValue2Sum S^267.34033T244LR var1.36615KPSS0.08566DecisionKeep H0

η = 0.0856, below 0.463, so the series is level-stationary.

9.3 The awkward cases

For the trend version, put t in column D and use TREND in column B instead of AVERAGE. For a longer lag, add one more SUMPRODUCT row per lag and one more weighted term in the long-run variance formula. Blank cells break the shifted ranges, so remove gaps first.

Name the residual range e (Formulas, Define Name). Then γ̂1 reads =SUMPRODUCT(OFFSET(e,1,0,23),OFFSET(e,0,0,23))/24 and is easier to check.

9.4 Why your answer might differ across software

SoftwareDefault lagη for the examplep-value display
This calculatortrunc(4(T/100)1/4) = 20.0856p > 0.10
R tseries::kpss.testSame, lshort = TRUE0.08560.1 with a warning
R urca::ur.kpsslags = "short", same rule0.0856No p-value, critical values only
Python statsmodels kpssnlags="auto" (Hobijn et al., 2004)Differs unless you pass nlags=20.1 with InterpolationWarning
Excel (manual build)Whatever you type0.0856 with lag 2You read the table

The KPSS statistic itself is the same formula everywhere. Differences almost always come from the lag rule. Always state the lag you used.

9.5 Charting in Excel

Select column C and insert a Line chart. This is the running-sum plot from chart 3 of this calculator. A line that drifts away and does not come back is the visual sign of non-stationarity.

9.6 Error messages

ErrorCauseFix
#VALUE!Text inside the data rangeRemove labels or NA codes from A2:A25
#N/A in SUMPRODUCTRanges of different lengthBoth ranges must have T − j rows
#DIV/0!Long-run variance is zeroData are constant; KPSS cannot be computed
C25 is not 0Mean range not anchored with $Use $A$2:$A$25 in the residual formula

📈 10. How to Run the KPSS Test in R

R has two standard KPSS functions: kpss.test() in the tseries package and ur.kpss() in urca. The script below runs both, adds an ADF test, prints a plain-English verdict, and saves one 300 dpi figure.

Copy the whole block. Change only the y <- c(...) line. Run install.packages(c("tseries","urca")) once first.

10.1 The complete script

R, tseries + urca, saves kpss_plot.png

# KPSS stationarity test with ADF cross-check
# StatsUnlock - https://statsunlock.com/kpss-test-calculator/
library(tseries)
library(urca)
set.seed(1)

# ---- 1. Your data (time order, earliest first) ----
# y <- read.csv("data.csv")$value
# y <- y[!is.na(y)]
y <- c(12,15,11,14,16,13,10,14,17,12,15,13,
       11,16,14,12,15,13,17,12,14,11,15,13)
null_type <- "Level"   # or "Trend"

# ---- 2. KPSS (tseries) ----
k <- kpss.test(y, null = null_type, lshort = TRUE)
print(k)   # KPSS Level = 0.0856, Truncation lag parameter = 2

# ---- 3. Same test in urca, gives critical values ----
u <- ur.kpss(y, type = if (null_type == "Level") "mu" else "tau", lags = "short")
print(summary(u))

# ---- 4. ADF cross-check ----
a <- adf.test(y)
print(a)

# ---- 5. Plain-English verdict ----
cv5 <- if (null_type == "Level") 0.463 else 0.146
eta <- unname(k$statistic)
cat(sprintf("\nKPSS = %.4f (lag %d). 5%% critical value = %.3f.\n", eta, k$parameter, cv5))
if (eta > cv5) {
  cat("Reject stationarity: difference or detrend before modelling.\n")
} else {
  cat("Do not reject: the series is consistent with stationarity.\n")
}

# ---- 6. One 300 dpi figure: series + running sums ----
e <- if (null_type == "Level") y - mean(y) else resid(lm(y ~ seq_along(y)))
S <- cumsum(e)
png("kpss_plot.png", width = 7, height = 5, units = "in", res = 300)
par(mfrow = c(2, 1), mar = c(4, 4, 2, 1))
plot(y, type = "o", pch = 16, col = "#16a34a", xlab = "Time", ylab = "Value",
     main = sprintf("KPSS %s = %.4f", null_type, eta))
lines(y - e, col = "#dc2626", lty = 2, lwd = 2)
plot(S, type = "l", lwd = 2, col = "#7c3aed", xlab = "Time", ylab = "Running sum S(t)")
abline(h = 0, lty = 3)
dev.off()

10.2 What each line does

LineWhat it does
kpss.test(y, null = "Level")Runs KPSS. lshort = TRUE sets lag = trunc(4(T/100)1/4)
ur.kpss(type = "mu")Same statistic, prints the 10%, 5%, 2.5% and 1% critical values
adf.test(y)The opposite-null test for the decision table in 4.6
cumsum(e)The running sums St used in the statistic
png(..., res = 300)Saves a journal-ready figure

10.3 What the figure shows

The top panel is the series with the fitted mean or trend. The bottom panel is the running sum. For the rainfall data it stays within about ±3 and returns to zero, which is why η is small.

10.4 Problems and fixes

MessageMeaningFix
p-value greater than printed p-valueη is below the 10% valueReport p > .10
p-value smaller than printed p-valueη is above the 1% valueReport p < .01
could not find function "kpss.test"tseries not loadedinstall.packages("tseries")
NAs in yMissing valuesRemove or impute them before the test

10.5 One-liners

tseries::kpss.test(y, null = "Trend")
tseries::kpss.test(diff(y))          # test the differenced series
forecast::ndiffs(y, test = "kpss")  # how many differences are needed

📈 11. How to Run the KPSS Test in Python

In Python the KPSS test lives in statsmodels. The script below sets the lag to match R and this calculator, runs ADF beside it, prints a verdict and saves one 300 dpi figure.

numpy matplotlib statsmodels   Install once: pip install numpy matplotlib statsmodels

11.1 The complete script

Python 3, statsmodels, saves kpss_plot.png

# KPSS stationarity test with ADF cross-check
# StatsUnlock - https://statsunlock.com/kpss-test-calculator/
import warnings
import numpy as np
import matplotlib.pyplot as plt
from statsmodels.tsa.stattools import kpss, adfuller
np.random.seed(1)

# ---- 1. Your data (time order, earliest first) ----
# import pandas as pd
# y = pd.read_csv("data.csv")["value"].dropna().to_numpy()
y = np.array([12,15,11,14,16,13,10,14,17,12,15,13,
              11,16,14,12,15,13,17,12,14,11,15,13], dtype=float)
y = y[~np.isnan(y)]
regression = "c"   # "c" = level, "ct" = trend

# ---- 2. Lag rule that matches R tseries ----
T = len(y)
lag = int(4 * (T / 100) ** 0.25)   # = 2 for T = 24

# ---- 3. KPSS ----
with warnings.catch_warnings():
    warnings.simplefilter("ignore")   # p-value is table-limited
    stat, p, used_lag, crit = kpss(y, regression=regression, nlags=lag)
print(f"KPSS = {stat:.4f}, lag = {used_lag}, p = {p}")   # 0.0856, 2, 0.1
print("Critical values:", crit)

# ---- 4. ADF cross-check ----
adf_stat, adf_p, *_ = adfuller(y, autolag="AIC")
print(f"ADF = {adf_stat:.4f}, p = {adf_p:.4f}")

# ---- 5. Plain-English verdict ----
if stat > crit["5%"]:
    print("Reject stationarity: difference or detrend before modelling.")
else:
    print("Do not reject: the series is consistent with stationarity.")

# ---- 6. One 300 dpi figure ----
t = np.arange(1, T + 1)
fit = np.full(T, y.mean()) if regression == "c" else np.polyval(np.polyfit(t, y, 1), t)
S = np.cumsum(y - fit)
fig, ax = plt.subplots(2, 1, figsize=(7, 5), sharex=True)
ax[0].plot(t, y, "o-", color="#16a34a")
ax[0].plot(t, fit, "--", color="#dc2626")
ax[0].set_title(f"KPSS = {stat:.4f} (lag {used_lag})")
ax[1].plot(t, S, color="#7c3aed")
ax[1].axhline(0, ls=":", color="grey")
ax[1].set_xlabel("Time"); ax[1].set_ylabel("Running sum S(t)")
fig.tight_layout(); fig.savefig("kpss_plot.png", dpi=300)

11.2 What each line does

LineWhat it does
kpss(y, regression="c", nlags=lag)Level KPSS. Use "ct" for trend
nlags=lagForces the R lag rule. Leaving the default "auto" changes η
crit["5%"]The 5% critical value from the same table as this page
adfuller(y)The opposite-null unit-root test
savefig(dpi=300)Publication-quality figure

11.3 What the figure shows

The same two panels as the R figure: the series with its fit, and the running sums. Both scripts give KPSS = 0.0856 with lag 2.

11.4 Problems and fixes

MessageMeaningFix
InterpolationWarning: p-value is greater than the indicated p-valueη below the 10% critical valueReport p > .10
InterpolationWarning: p-value is smallerη above the 1% critical valueReport p < .01
Answer differs from RDefault nlags="auto"Pass the same lag as R
ValueError on NaNMissing valuesDrop or impute them first

11.5 One-liners

kpss(y, regression="ct", nlags=2)        # trend version
kpss(np.diff(y), regression="c")      # after first differencing
from pmdarima.arima import ndiffs; ndiffs(y, test="kpss")

📋 12. Reference Tables

Table 1. KPSS critical values (Kwiatkowski et al., 1992)

Version10%5%2.5%1%
Level (ημ)0.3470.4630.5740.739
Trend (ητ)0.1190.1460.1760.216

What to conclude: if η is above the value in your α column, reject stationarity.

Table 2. Default lag by sample size

TShort l4Long l12floor(3√T/13)
24281
503101
1004122
2004143
5005175
10007217

What to conclude: the long rule is safer with persistent data but weakens the test in short series.

Table 3. Reading η (level version)

ημp (approx.)Verdict
below 0.347> 0.10Stationary
0.347 to 0.4630.05 to 0.10Weak evidence against
0.463 to 0.7390.01 to 0.05Non-stationary at 5%
above 0.739< 0.01Strongly non-stationary

What to conclude: values in the amber band call for a second test (ADF) and a look at the chart.

Table 4. Reading η (trend version)

ητp (approx.)Verdict
below 0.119> 0.10Trend-stationary
0.119 to 0.1460.05 to 0.10Weak evidence against
0.146 to 0.2160.01 to 0.05Non-stationary at 5%
above 0.216< 0.01Strongly non-stationary

What to conclude: rejecting the trend version usually means a unit root, so difference the series.

Table 5. Minimum series length

TReliability
under 20Poor: critical values are asymptotic and size is distorted
20 to 49Fair: report with ADF and a plot
50 to 99Good
100 or moreVery good, but small drifts become significant

What to conclude: under 20 points, treat the result as a hint, not a decision.

Table 6. Which transformation after KPSS

Level testTrend testDo this
Not rejectedNot rejectedUse the series as it is
RejectedNot rejectedDetrend (remove the straight line)
RejectedRejectedFirst difference, then test again
Not rejectedRejectedRare. Check for a break or a curved trend

What to conclude: never difference a trend-stationary series; it adds a non-invertible MA term.

📈 13. Example Results

Eight worked KPSS examples. Each uses the default short lag and the Bartlett kernel. Example 1 is the same worked dataset used in Sections 7, 9, 10 and 11.

1
TEXTBOOK CASE

Rainfall anomaly, 24 months

The worked example from Sections 7, 9, 10 and 11.

Monthly rainfall anomaly in mm. Is the series stable around its mean?

T = 24levelη = 0.0856lag 2Do not reject
StatisticValueNote
T24Observations
Lag2trunc(4(T/100)^0.25)
Long-run variance1.3661Bartlett kernel
KPSS level0.0856Test statistic
5% critical value0.463Kwiatkowski et al. (1992)
p-value> 0.10Table interpolation
Time (t = 1 to 24)17.010.0eta = 0.0856
The series bounces around its mean (dashed) with no drift.

What it means: η = 0.0856 is far below 0.463. The running sums stay near zero, so there is no evidence against level stationarity. Model the series in levels.

How to write it: "A KPSS level test did not reject stationarity, KPSS = 0.0856, lag = 2, p > 0.10."

2
CLEARLY SIGNIFICANT

Weekly stock price index

A trend tested as level stationarity.

52 weeks of a price index that rises almost every week.

T = 52levelη = 1.4001lag 3Reject at 5%
StatisticValueNote
T52Observations
Lag3trunc(4(T/100)^0.25)
Long-run variance188791.3346Bartlett kernel
KPSS level1.4001Test statistic
5% critical value0.463Kwiatkowski et al. (1992)
p-value< 0.01Table interpolation
Time (t = 1 to 52)1757.0990.0eta = 1.4001
Every early value sits below the mean and every late value above it.

What it means: η = 1.4001 is above even the 1% value of 0.739. The mean line misses the data badly at both ends. Re-test with the trend version, then difference if needed.

How to write it: "KPSS rejected level stationarity, KPSS = 1.4001, lag = 3, p < 0.01."

3
BORDERLINE

Daily river flow, 50 days

The decision depends on alpha.

River flow with a short cycle and a slow fall in level.

T = 50levelη = 0.7181lag 3Reject at 5%
StatisticValueNote
T50Observations
Lag3trunc(4(T/100)^0.25)
Long-run variance1.4579Bartlett kernel
KPSS level0.7181Test statistic
5% critical value0.463Kwiatkowski et al. (1992)
p-value0.012Table interpolation
Time (t = 1 to 50)48.142.9eta = 0.7181
A slow downward drift pulls the series away from its mean.

What it means: η = 0.7181 is above 0.463 (5%) but below 0.739 (1%). At α = .05 we reject; at α = .01 we would not. Report the exact p and confirm with ADF.

How to write it: "A KPSS level test rejected stationarity at the 5% level, KPSS = 0.7181, lag = 3, p = 0.012."

4
NULL RESULT

Annual GDP growth, 40 years

Growth rates are usually stationary.

Year-on-year GDP growth for 40 years.

T = 40levelη = 0.0772lag 3Do not reject
StatisticValueNote
T40Observations
Lag3trunc(4(T/100)^0.25)
Long-run variance0.1019Bartlett kernel
KPSS level0.0772Test statistic
5% critical value0.463Kwiatkowski et al. (1992)
p-value> 0.10Table interpolation
Time (t = 1 to 40)4.12.4eta = 0.0772
Regular ups and downs around a fixed mean.

What it means: η = 0.0772 gives no evidence against stationarity. Growth rates can be modelled directly in an ARMA model.

How to write it: "Stationarity was not rejected, KPSS = 0.0772, lag = 3, p > 0.10."

5
SMALL SAMPLE

First 12 weeks of the price index

Too few points for a firm decision.

Only 12 weekly prices are available.

T = 12levelη = 0.5193lag 2Reject at 5%
StatisticValueNote
T12Observations
Lag2trunc(4(T/100)^0.25)
Long-run variance1214.6049Bartlett kernel
KPSS level0.5193Test statistic
5% critical value0.463Kwiatkowski et al. (1992)
p-value0.037Table interpolation
Time (t = 1 to 12)1080.01000.0eta = 0.5193
Twelve points and a visible upward drift.

What it means: η = 0.5193 is above 0.463, but with T = 12 the asymptotic critical values are unreliable and KPSS tends to over-reject. Treat this as a warning, not a verdict.

How to write it: "With only 12 observations, KPSS rejected level stationarity (KPSS = 0.5193, lag = 2, p = 0.037); this result should be interpreted with caution."

6
SIGNIFICANT BUT TRIVIAL

400 daily sensor readings

Large T finds tiny drifts.

A sensor drifts by 0.004 units per day while daily noise has an SD of about 1.

T = 400levelη = 4.4776lag 5Reject at 5%
StatisticValueNote
T400Observations
Lag5trunc(4(T/100)^0.25)
Long-run variance2.4255Bartlett kernel
KPSS level4.4776Test statistic
5% critical value0.463Kwiatkowski et al. (1992)
p-value< 0.01Table interpolation
Time (t = 1 to 400)53.847.6eta = 4.4776
The mean line hides a gentle upward slope over 400 days.

What it means: η = 4.4776 is huge, yet the drift is about 0.4% of the daily noise per day. With large T even small trends are detected. Ask whether the trend matters for your purpose; the trend version is not rejected.

How to write it: "KPSS rejected level stationarity, KPSS = 4.4776, lag = 5, p < 0.01, although the implied drift was small (0.004 units per day)."

7
ASSUMPTION FAILURE

Water level before and after a dam

A break, not a unit root.

80 months of water level. A dam opened at month 41 and raised the level by about 8 units.

T = 80levelη = 1.7379lag 3Reject at 5%
StatisticValueNote
T80Observations
Lag3trunc(4(T/100)^0.25)
Long-run variance57.9962Bartlett kernel
KPSS level1.7379Test statistic
5% critical value0.463Kwiatkowski et al. (1992)
p-value< 0.01Table interpolation
Time (t = 1 to 80)41.626.4eta = 1.7379
Two flat regimes joined by a jump; the overall mean fits neither.

What it means: η = 1.7379 strongly rejects, but each half is stationary on its own. The break, not a unit root, drives the result. Use a KPSS test with a break, or test each regime separately.

How to write it: "KPSS rejected level stationarity (KPSS = 1.7379, lag = 3, p < 0.01); the rejection reflected a structural break at month 41."

8
APPLIED

Forest cover index, 60 years

Level rejects, trend does not.

A forest cover index rising steadily with yearly noise, tested for trend stationarity.

T = 60trendη = 0.0375lag 3Do not reject
StatisticValueNote
T60Observations
Lag3trunc(4(T/100)^0.25)
Long-run variance0.7963Bartlett kernel
KPSS trend0.0375Test statistic
5% critical value0.146Kwiatkowski et al. (1992)
p-value> 0.10Table interpolation
Time (t = 1 to 60)57.119.9eta = 0.0375
The data follow the fitted trend line (dashed) closely all the way.

What it means: ητ = 0.0375 is below 0.146, so the series is trend-stationary (its level test gives 1.60 and rejects). Remove the linear trend instead of differencing.

How to write it: "A KPSS trend test did not reject trend stationarity, KPSS = 0.0375, lag = 3, p > 0.10."

🧪 14. Data Collection Protocol

Design statement: one variable, measured at equal time intervals, in time order, with no gaps.

  1. Fix the time step (day, week, month, year) before collecting data.
  2. Record the same quantity in the same units every time.
  3. Keep the method constant. A new instrument or survey design can create a false break.
  4. Record a date for every value.
  5. Leave missing periods blank, never as 0.
  6. Write down any known events (policy change, dam, new trap layout) with dates.
  7. Decide on seasonal adjustment before testing if the data are monthly or quarterly.
  8. Collect at least 50 points where you can; 20 is the practical minimum.
  9. Pre-register the version (level or trend), lag rule and α.
  10. Run KPSS and ADF together and report both.
datevaluenote
2024-0112
2024-0215
2024-0311gauge recalibrated

Minimum sample: 20 observations, 50 or more preferred. Pre-registration line: "Stationarity will be assessed with a KPSS level test, lag = trunc(4(T/100)^0.25), Bartlett kernel, α = .05." Common mistakes: mixing time steps, filling gaps with zeros, testing before removing a known seasonal cycle.

🎯 15. When to Use This Calculator

Use it when

  • You have one numeric series in time order.
  • You need to decide between levels, detrending and differencing.
  • You want to confirm an ADF result.
  • You are preparing data for ARIMA, VAR, cointegration or regression on time series.

Do not use it when

  • The data are not in time order (use a normality or group test instead).
  • There are fewer than about 15 points.
  • There is a known structural break (use a KPSS test with breaks).
  • Strong seasonality has not been removed.

Four real examples

  • Ecology: monthly sloth bear detections per camera trap before fitting a count time-series model.
  • Economics: inflation rates before an ARIMA forecast.
  • Hydrology: annual peak flow to check for a climate trend.
  • Public health: weekly case counts before outbreak forecasting.

Decision tree

  • Want to test a unit root directly? Use the ADF test or Phillips-Perron test.
  • Suspect one break at an unknown date? Use Zivot-Andrews or KPSS with breaks.
  • Checking residuals of a fitted model? Use the Ljung-Box test.
  • Seasonal unit root? Use OCSB or Canova-Hansen tests.

🔧 16. Troubleshooting and Common Errors

The p-value just says > 0.10 or < 0.01

Cause: The KPSS p-value comes from a four-point table.

Fix: Report it as p > .10 or p < .01. That is the correct, honest report.

My result differs from Python

Cause: statsmodels uses nlags="auto" by default.

Fix: Pass nlags equal to the lag shown here, e.g. kpss(y, nlags=2).

My result differs from EViews or Stata

Cause: Those programs default to other bandwidth rules (Newey-West automatic or a fixed maxlag).

Fix: Set the same lag and kernel in both programs.

KPSS rejects but the plot looks stable

Cause: A short lag with strong positive autocorrelation, or a break.

Fix: Try the long lag rule and inspect chart 1 for a jump.

Both KPSS and ADF reject

Cause: Break, long memory or a missed trend.

Fix: Run the trend version, split at the suspected break, or use Zivot-Andrews.

Long-run variance not positive

Cause: Rectangular kernel with negative autocovariances.

Fix: Switch to the Bartlett kernel.

Error: all values are identical

Cause: Zero variance.

Fix: KPSS cannot be computed on a constant series.

Fewer values than expected

Cause: Text, NA or currency symbols in the input.

Fix: Clean the column so it contains only numbers and a decimal point.

Seasonal data pass KPSS

Cause: Seasonal cycles average out over the sample.

Fix: Check the residual ACF at lag 12 and deseasonalise.

Differenced series still rejects

Cause: Possible I(2) series or remaining break.

Fix: Difference again and test, or look for a break first.

⚠ 17. Assumptions and Limitations

Assumptions

  1. Equally spaced, ordered data. Check: dates. If broken, the running sums mean nothing.
  2. No structural break. Check: chart 1. If broken, KPSS over-rejects (says non-stationary when each part is stationary).
  3. Seasonality removed. Check: ACF spikes at lag 12 or 4. If broken, results can go either way.
  4. Linear trend (trend version). Check: chart 1. A curved trend makes KPSS over-reject.
  5. Enough lags for the autocorrelation. Check: chart 4. Too few lags with strong positive autocorrelation makes KPSS over-reject; too many reduce power.
  6. Large sample. Critical values are asymptotic. With T < 20 the size is distorted, usually toward over-rejection.

Limitations

  • Cannot handle breaks. Alternative: KPSS with structural breaks (Carrion-i-Silvestre et al., 2005) or Zivot-Andrews.
  • Sensitive to lag choice. Alternative: report both short and long lags.
  • Over-rejects near-unit-root but stationary series (Caner and Kilian, 2001). Alternative: confirm with ADF or ERS DF-GLS.
  • Cannot detect seasonal unit roots. Alternative: Canova-Hansen test.
  • Cannot separate long memory from a unit root. Alternative: fractional integration (d) estimation.

🏁 18. Conclusion

The KPSS test asks one question: can this series be treated as stable around a mean or a straight trend? It is the natural partner to the ADF test because its null hypothesis is the opposite one.

▶ Run the analysis above and this paragraph will summarise your result: η = ___, lag = ___, decision ___.

Always report the version, the lag and the kernel, show a plot of the series, and pair the result with ADF. When the two tests disagree, look for breaks and seasonality before you difference anything.

Used this way, the KPSS test calculator gives you a defensible, reproducible answer to whether your time series is stationary.

❓ 19. Frequently Asked Questions

Q1. What is the KPSS test?

The KPSS test (Kwiatkowski-Phillips-Schmidt-Shin, 1992) is a test of whether a time series is stationary. It fits a mean or a linear trend, sums the residuals over time, and checks whether those running sums drift too far to be explained by a stationary process.

Q2. What is the null hypothesis of the KPSS test?

The null hypothesis is that the series is stationary, either around a constant mean (level) or around a linear trend (trend). The alternative is a unit root. This is the opposite of the ADF test.

Q3. How do I interpret KPSS test results?

Compare the KPSS statistic with the critical value. If it is larger (for example above 0.463 for level at 5%), reject stationarity. If it is smaller, the series is consistent with stationarity.

Q4. What does a KPSS p-value of 0.1 mean?

Software reports 0.1 when the statistic is below the 10% critical value. The true p-value is larger than 0.1, so report p > .10 and conclude the series is consistent with stationarity.

Q5. What is the difference between the KPSS and ADF tests?

ADF assumes a unit root and tries to reject it. KPSS assumes stationarity and tries to reject it. Running both gives four possible outcomes; agreement between them is the strongest evidence.

Q6. What if KPSS and ADF both reject?

The tests conflict. Common causes are a structural break, long memory (fractional integration), a curved trend or strong autocorrelation with too short a lag. Plot the data, test sub-periods and try a break test.

Q7. What if neither KPSS nor ADF rejects?

Both tests lack power, usually because the series is short. Collect more data, use theory, or report the result as inconclusive.

Q8. Should I choose level or trend in the KPSS test?

Choose level if the series moves around a flat mean. Choose trend if it rises or falls steadily. If level rejects but trend does not, the series is trend-stationary and should be detrended, not differenced.

Q9. What are the KPSS critical values?

Level: 0.347 (10%), 0.463 (5%), 0.574 (2.5%), 0.739 (1%). Trend: 0.119, 0.146, 0.176, 0.216. They come from Kwiatkowski et al. (1992).

Q10. How do I choose the lag in the KPSS test?

The common default is trunc(4(T/100)^0.25), used by R tseries. The long rule trunc(12(T/100)^0.25) is safer with strong autocorrelation. Report the lag you used and check that the decision does not flip between rules.

Q11. Why does the KPSS statistic change with the lag?

The lag controls how many autocovariances enter the long-run variance. Positive autocorrelation increases it as the lag grows, which lowers the statistic. Negative autocorrelation does the opposite.

Q12. How many observations do I need for the KPSS test?

At least 20, preferably 50 or more. The critical values are asymptotic, so short series tend to over-reject stationarity.

Q13. Can the KPSS test detect seasonality?

No. A seasonal cycle can pass KPSS because it averages out. Check the ACF at the seasonal lag and deseasonalise first, or use a seasonal unit-root test.

Q14. Does a structural break affect the KPSS test?

Yes. A shift in the mean makes the running sums drift, so KPSS rejects stationarity even when each part of the series is stationary. Use a KPSS test with breaks or split the series.

Q15. Do I need to difference my data if KPSS rejects?

Only if the trend version also rejects. If level rejects but trend does not, remove the linear trend instead. Differencing a trend-stationary series adds an unwanted moving-average term.

Q16. Is the KPSS test a unit root test?

It is a stationarity test whose alternative is a unit root, so it is often grouped with unit-root tests. It complements ADF and Phillips-Perron rather than replacing them.

Q17. How do I report a KPSS test in APA style?

Example: A KPSS test for level stationarity did not reject the null hypothesis, KPSS = 0.086, lag = 2, p > .10. Always state the version, lag and kernel.

Q18. How do I do a KPSS test in Excel?

Excel has no KPSS function. Compute residuals from the mean, take running sums with =SUM($B$2:B2), get autocovariances with SUMPRODUCT, combine them with Bartlett weights, then divide SUMSQ of the running sums by T squared times the long-run variance. Section 9 shows each step.

Q19. How do I run a KPSS test in R?

Use tseries::kpss.test(y, null = "Level") or "Trend". The default lag is trunc(4(T/100)^0.25). urca::ur.kpss(y, type = "mu", lags = "short") gives the same statistic with critical values.

Q20. How do I run a KPSS test in Python?

Use statsmodels: from statsmodels.tsa.stattools import kpss; kpss(y, regression="c", nlags=2). Use "ct" for trend. Set nlags yourself to match R, because the default nlags="auto" uses a different rule.

📑 20. Cite This Tool

APA 7th edition
StatsUnlock. (2026). KPSS test calculator [Interactive statistical tool]. https://statsunlock.com/kpss-test-calculator/
BibTeX
@misc{statsunlock_kpss_2026, title={KPSS Test Calculator}, author={{StatsUnlock}}, year={2026}, note={Interactive statistical tool}, url={https://statsunlock.com/kpss-test-calculator/}}
Methods wording
Stationarity was assessed with the KPSS test (Kwiatkowski et al., 1992) using the StatsUnlock KPSS Test Calculator (2026), with a Bartlett kernel and lag truncation trunc(4(T/100)^0.25) (Schwert, 1989). Results were cross-checked with the augmented Dickey-Fuller test.

🔗 21. Related Tools

📖 22. Glossary of Terms

TermPlain-English meaning
ACFAutocorrelation function: the correlation of a series with itself at each lag.
ADF testAugmented Dickey-Fuller test; its null hypothesis is a unit root.
AutocovarianceHow much a value and the value j steps earlier move together.
BandwidthAnother word for the lag used in the long-run variance.
Bartlett kernelWeights that fall in a straight line from 1 toward 0 as the lag grows.
Critical valueThe cut-off the statistic must pass to reject the null.
DetrendingRemoving a fitted straight line from the series.
DifferencingReplacing each value with its change from the previous value.
KernelThe weighting rule applied to autocovariances.
KPSS statisticη; the scaled size of the running sums of residuals.
LagThe number of time steps between two values.
Level stationarityStationary around a fixed mean.
Long-run varianceVariance adjusted for autocorrelation over time.
Null hypothesisThe claim the test assumes true; stationarity for KPSS.
Partial sumA running total of residuals, written St.
ResidualThe data value minus the fitted mean or trend.
Stationary seriesA series whose mean, variance and correlation pattern do not change over time.
Structural breakA sudden lasting change in the level or trend.
Trend stationarityStationary around a straight-line trend.
Unit rootA property that makes shocks permanent, so the series wanders without returning.

📚 23. References

Peer-reviewed sources behind the methods in this KPSS test calculator: stationarity and unit-root testing, long-run variance estimation, lag selection and structural breaks.

  1. 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. https://doi.org/10.1016/0304-4076(92)90104-Y
  2. Dickey, D. A., & Fuller, W. A. (1979). Distribution of the estimators for autoregressive time series with a unit root. Journal of the American Statistical Association, 74(366), 427–431. https://doi.org/10.1080/01621459.1979.10482531
  3. Phillips, P. C. B., & Perron, P. (1988). Testing for a unit root in time series regression. Biometrika, 75(2), 335–346. https://doi.org/10.1093/biomet/75.2.335
  4. Newey, W. K., & West, K. D. (1987). A simple, positive semi-definite, heteroskedasticity and autocorrelation consistent covariance matrix. Econometrica, 55(3), 703–708. https://doi.org/10.2307/1913610
  5. Newey, W. K., & West, K. D. (1994). Automatic lag selection in covariance matrix estimation. Review of Economic Studies, 61(4), 631–653. https://doi.org/10.2307/2297912
  6. Andrews, D. W. K. (1991). Heteroskedasticity and autocorrelation consistent covariance matrix estimation. Econometrica, 59(3), 817–858. https://doi.org/10.2307/2938229
  7. Schwert, G. W. (1989). Tests for unit roots: A Monte Carlo investigation. Journal of Business & Economic Statistics, 7(2), 147–159. https://doi.org/10.1080/07350015.1989.10509723
  8. Hobijn, B., Franses, P. H., & Ooms, M. (2004). Generalizations of the KPSS-test for stationarity. Statistica Neerlandica, 58(4), 483–502. https://doi.org/10.1111/j.1467-9574.2004.00272.x
  9. Leybourne, S. J., & McCabe, B. P. M. (1994). A consistent test for a unit root. Journal of Business & Economic Statistics, 12(2), 157–166. https://doi.org/10.1080/07350015.1994.10510004
  10. Caner, M., & Kilian, L. (2001). Size distortions of tests of the null hypothesis of stationarity: Evidence and implications for the PPP debate. Journal of International Money and Finance, 20(5), 639–657. https://doi.org/10.1016/S0261-5606(01)00011-0
  11. Lee, D., & Schmidt, P. (1996). On the power of the KPSS test of stationarity against fractionally-integrated alternatives. Journal of Econometrics, 73(1), 285–302. https://doi.org/10.1016/0304-4076(95)01741-0
  12. Lee, J., Huang, C. J., & Shin, Y. (1997). On stationary tests in the presence of structural breaks. Economics Letters, 55(2), 165–172. https://doi.org/10.1016/S0165-1765(97)00065-7
  13. Carrion-i-Silvestre, J. L., del Barrio-Castro, T., & López-Bazo, E. (2005). Breaking the panels: An application to the GDP per capita. Econometrics Journal, 8(2), 159–175. https://doi.org/10.1111/j.1368-423X.2005.00158.x
  14. 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. https://doi.org/10.1080/07350015.1992.10509904
  15. Elliott, G., Rothenberg, T. J., & Stock, J. H. (1996). Efficient tests for an autoregressive unit root. Econometrica, 64(4), 813–836. https://doi.org/10.2307/2171846
  16. Ng, S., & Perron, P. (2001). Lag length selection and the construction of unit root tests with good size and power. Econometrica, 69(6), 1519–1554. https://doi.org/10.1111/1468-0262.00256
  17. Shin, Y. (1994). A residual-based test of the null of cointegration against the alternative of no cointegration. Econometric Theory, 10(1), 91–115. https://doi.org/10.1017/S0266466600008240
  18. Nelson, C. R., & Plosser, C. I. (1982). Trends and random walks in macroeconomic time series. Journal of Monetary Economics, 10(2), 139–162. https://doi.org/10.1016/0304-3932(82)90012-5
  19. Granger, C. W. J., & Newbold, P. (1974). Spurious regressions in econometrics. Journal of Econometrics, 2(2), 111–120. https://doi.org/10.1016/0304-4076(74)90034-7
  20. Ljung, G. M., & Box, G. E. P. (1978). On a measure of lack of fit in time series models. Biometrika, 65(2), 297–303. https://doi.org/10.1093/biomet/65.2.297
RELATED ARTICLES

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Most Popular

Important Plots & Charts

Calculators and Converters