DickeyFullerTest

class DickeyFullerTest(*args)

The Dickey-Fuller stationarity test.

Notes

The Dickey-Fuller test checks the stationarity of a scalar time series using one time series. It assumes that the X: \Omega \times \cD \rightarrow \Rset process with \cD \in \Rset, discretized on the time grid (t_0, \dots, t_{N-1}) writes:

(1)X_t = a + bt + \rho X_{t-1} + \varepsilon_{t}

where \rho > 0 and where a or b or both (a,b) can be assumed to be equal to 0.

The Dickey-Fuller test checks whether the random perturbation at time t vanishes with time.

When a \neq 0 and b=0, the model (1) is said to have a drift. When a = 0 and b \neq 0, the model (1) is said to have a linear trend.

In the model (1), the only way to have stochastic non stationarity is to have \rho = 1 (if \rho > 1, then the process diverges with time which is readily seen in the data). In the general case, the Dickey-Fuller test is a unit root test to detect whether \rho=1 against \rho < 1:

The test statistics and its limit distribution depend on the a priori knowledge we have on a and b. In case of absence of a priori knowledge on the structure of the model, several authors have proposed a global strategy to cover all the subcases of the model (1), depending on the possible values on a and b.

The strategy implemented in OpenTURNS, is recommended by Enders (Applied Econometric Times Series, Enders, W., second edition, John Wiley & sons editions, 2004.).

We note (X_1, \hdots, X_n) the data, by W(r) the Wiener process, and W^{a}(r) = W(r) - \int_{0}^{1} W(r)\di{r}, W^{b}(r) = W^{a}(r) - 12 \left(r - \frac{1}{2} \right) \int_{0}^{1} \left(s - \frac{1}{2} \right) W(s)\di{s}.

1. We assume the model (2):

(2)\boldsymbol{X_t = a + bt + \rho X_{t-1} + \varepsilon_{t}}

The coefficients (a,b,\rho) are estimated by (\Hat{a}_n, \Hat{b}_n, \Hat{\rho}_n) using ordinary least-squares fitting, which leads to:

(3)\underbrace{\left(
   \begin{array}{lll}
     \displaystyle n-1 &\sum_{i=1}^n t_{i} &\sum_{i=2}^n y_{i-1}\\
     \displaystyle \sum_{i=1}^n t_{i} &\sum_{i=1}^n t_{i}^2 &\sum_{i=2}^n t_{i} y_{i-1}\\
     \displaystyle \sum_{i=2}^n y_{i-1}& \sum_{i=2}^n t_{i}y_{i-1} &\sum_{i=2}^n y_{i-1}^2
   \end{array}
   \right)}_{\mat{M}}
 \left(
   \begin{array}{c}
    \hat{a}_n\\
    \hat{b}_n\\
    \hat{\rho}_n
   \end{array}
 \right)=
 \left(
 \begin{array}{l}
   \displaystyle \sum_{i=1}^n y_{i} \\
   \displaystyle \sum_{i=1}^n t_{i} y_{i}\\
   \displaystyle \sum_{i=2}^n y_{i-1} y_{i}
 \end{array}
 \right)

We first test:

(4)\left\{
\begin{array}{lr}
  \cH_0: & \rho = 1 \\
  \cH_1: & \rho < 1
\end{array}
\right.

thanks to the Student statistics:

t_{\rho=1} = \frac{\rho_n-1}{\hat{\sigma}_{\rho_n}}

where \sigma_{\rho_n} is the least square estimate of the standard deviation of \Hat{\rho}_n, given by:

\sigma_{\rho_n}=\mat{M}^{-1}_{33}\sqrt{\frac{1}{n-1}\sum_{i=2}^n\left(y_{i}-(\hat{a}_n+\hat{b}_nt_i+\hat{\rho}_ny_{i-1})\right)^2}

which converges in distribution to the Dickey-Fuller distribution associated to the model with drift and trend:

t_{\rho = 1} \stackrel{\mathcal{L}}{\longrightarrow} \frac{\int_{0}^{1}W^{b}(r) \di{W(r)}}{\int_{1}^{0} W^{b}(r)^2 \di{r}}

The null hypothesis \cH_0 from (4) is accepted when t_{\rho=1} > C_{\alpha} where C_{\alpha} is the test threshold of level \alpha.

The quantiles of the Dickey-Fuller statistics for the model with drift and linear trend are:

\left\{
\begin{array}{ll}
    \alpha = 0.01, & C_{\alpha} = -3.96 \\
    \alpha = 0.05, & C_{\alpha} = -3.41 \\
    \alpha = 0.10, & C_{\alpha} = -3.13
\end{array}
\right.

1.1. Case 1: The null hypothesis \cH_0 from (4) is rejected

We test whether b=0:

(5)\left\{
\begin{array}{lr}
  \cH_0: & b = 0 \\
  \cH_1: & b \neq 0
\end{array}
\right.

where the statistics t_n = \frac{|\hat{b}_n|}{\sigma_{b_n}} converges in distribution to the Student distribution Student with \nu=n-4, where \sigma_{b_n} is the least square estimate of the standard deviation of \Hat{b}_n, given by:

\sigma_{b_n}=\mat{M}^{-1}_{22}\sqrt{\frac{1}{n-1}\sum_{i=2}^n\left(y_{i}-(\hat{a}_n+\hat{b}_nt_i+\hat{\rho}_ny_{i-1})\right)^2}

The decision to be taken is:
  • If \cH_0 from (5) is rejected, then the model 1 (2) is confirmed. And the test (4) proved that the unit root is rejected : \rho < 1. We then conclude that the final model is : \boldsymbol{X_t = a + bt + \rho X_{t-1} + \varepsilon_{t}} whith \boldsymbol{\rho < 1} which is a trend stationary model.
  • If \cH_0 from (5) is accepted, then the model 1 (2) is not confirmed, since the trend presence is rejected and the test (4) is not conclusive (since based on a wrong model). We then have to test the second model (7).

1.2. Case 2: The null hypothesis \cH_0 from (4) is accepted

We test whether (\rho, b) = (1,0):

(6)\left\{
\begin{array}{lr}
  \cH_0: & (\rho, b) = (1,0) \\
  \cH_1: & (\rho, b) \neq (1,0)
\end{array}
\right.

with the Fisher statistics:

\displaystyle \hat{F}_1 = \frac{(S_{1,0} - S_{1,b})/2}{S_{1,b}/(n-3)}

where S_{1,0}=\sum_{i=2}^n\left(y_i-(\hat{a}_n+y_{i-1})\right)^2 is the sum of the square errors of the model 1 (2) assuming \cH_0 from (6) and S_{1,b}=\sum_{i=2}^n\left(y_i-(\hat{a}_n+\hat{b}_nt_i+\hat{\rho}_ny_{i-1})\right)^2 is the same sum when we make no assumption on \rho and b.

The statistics \hat{F}_1 converges in distribution to the Fisher-Snedecor distribution FisherSnedecor with d_1=2, d_2=n-3. The null hypothesis \cH_0 from (4) is accepted when \hat{F}_1 < \Phi_{\alpha} where \Phi_{\alpha} is the test threshold of level \alpha.

The decision to be taken is:
  • If \cH_0 from (6) is rejected, then the model 1 (2) is confirmed since the presence of linear trend is confirmed. And the test (4) proved that the unit root is accepted: \rho = 1. We then conclude that the model is: \boldsymbol{X_t = a + bt + X_{t-1} + \varepsilon_{t}} which is a non stationary model.
  • If \cH_0 from (6) is accepted, then the model 1 (2) is not confirmed, since the presence of the linear trend is rejected and the test (4) is not conclusive (since based on a wrong model). We then have to test the second model (7).

2. We assume the model (7):

(7)\boldsymbol{X_t = a + \rho X_{t-1} + \varepsilon_{t}}

The coefficients (a,\rho) are estimated as follows:

(8)\underbrace{\left(\begin{array}{lll}
   \displaystyle n-1 &\sum_{i=2}^n y_{i-1}\\
   \displaystyle \sum_{i=2}^n y_{i-1} &\sum_{i=2}^n y_{i-1}^2
                  \end{array}
 \right)}_{\mat{N}}
 \left(
  \begin{array}{c}
    \hat{a}_n\\
    \hat{\rho}_n
  \end{array}
 \right)=
 \left(
  \begin{array}{l}
    \displaystyle \sum_{i=1}^n y_{i} \\
    \displaystyle \sum_{i=2}^n y_{i-1} y_{i}
   \end{array}
 \right)

We first test:

(9)\left\{
 \begin{array}{lr}
   \mathcal{H}_0: & \rho = 1 \\
   \mathcal{H}_1: & \rho < 1
 \end{array}
 \right.

thanks to the Student statistics:

t_{\rho=1} = \frac{\rho_n-1}{\sigma_{\rho_n}}

where \sigma_{\rho_n} is the least square estimate of the standard deviation of \Hat{\rho}_n, given by:

\sigma_{\rho_n}=\mat{N}^{-1}_{22}\sqrt{\frac{1}{n-1}\sum_{i=2}^n\left(y_{i}-(\hat{a}_n+\hat{\rho}_ny_{i-1})\right)^2}

which converges in distribution to the Dickey-Fuller distribution associated to the model with drift and no linear trend:

t_{\rho = 1} \stackrel{\mathcal{L}}{\longrightarrow} \frac{\int_{0}^{1}W^{a}(r) \di{W(r)}}{\int_{1}^{0} W^{a}(r)^2 \di{r}}

The null hypothesis \cH_0 from (9) is accepted when t_{\rho=1} > C_{\alpha} where C_{\alpha} is the test threshold of level \alpha.

The quantiles of the Dickey-Fuller statistics for the model with drift are:

\left\{
\begin{array}{ll}
    \alpha = 0.01, & C_{\alpha} = -3.43 \\
    \alpha = 0.05, & C_{\alpha} = -2.86 \\
    \alpha = 0.10, & C_{\alpha} = -2.57
\end{array}
\right.

2.1. Case 1: The null hypothesis \cH_0 from (9) is rejected

We test whether a=0:

(10)\left\{
\begin{array}{lr}
  \mathcal{H}_0: & a = 0 \\
  \mathcal{H}_1: & a \neq 0
\end{array}
\right.

where the statistics t_n = \frac{|\hat{a}_n|}{\sigma_{a_n}} converges in distribution to the Student distribution Student with \nu=n-3, where \sigma_{a_n} is the least square estimate of the standard deviation of \Hat{a}_n, given by:

\sigma_{a_n}=\mat{N}^{-1}_{11}\sqrt{\frac{1}{n-1}\sum_{i=2}^n\left(y_{i}-(\hat{a}_n+\hat{\rho}_ny_{i-1})\right)^2}

The decision to be taken is:
  • If \cH_0 from (10) is rejected, then the model 2 (7) is confirmed. And the test (9) proved that the unit root is rejected: \rho < 1. We then conclude that the final model is: \boldsymbol{X_t = a + \rho X_{t-1} + \varepsilon_{t}} whith \boldsymbol{\rho < 1} which is a stationary model.
  • If \cH_0 from (10) is accepted, then the model 2 (7) is not confirmed, since the drift presence is rejected and the test (4) is not conclusive (since based on a wrong model). We then have to test the third model (12).

2.2. Case 2: The null hypothesis \cH_0 from (9) is accepted

We test whether (\rho, a) = (1,0):

(11)\left\{
\begin{array}{lr}
  \mathcal{H}_0: & (\rho, a) = (1,0) \\
  \mathcal{H}_1: & (\rho, a) \neq (1,0)
\end{array}
\right.

with a Fisher test. The statistics is:

\displaystyle \hat{F}_2 = \frac{(SCR_{2,c} - SCR_{2})/2}{SCR_{2}/(n-2)}

where SCR_{2,c} is the sum of the square errors of the model 2 (7) assuming \cH_0 from (11) and SCR_{2} is the same sum when we make no assumption on \rho and a.

The statistics \hat{F}_2 converges in distribution to the Fisher-Snedecor distribution FisherSnedecor with d_1=2, d_2=n-2. The null hypothesis \cH_0 from (4) is accepted if when \hat{F}_2 < \Phi_{\alpha} where \Phi_{\alpha} is the test threshold of level \alpha.

The decision to be taken is:
  • If \cH_0 from (11) is rejected, then the model 2 (7) is confirmed since the presence of the drift is confirmed. And the test (9) proved that the unit root is accepted: \rho =1. We then conclude that the model is: \boldsymbol{X_t = a + X_{t-1} + \varepsilon_{t}} which is a non stationary model.
  • If \cH_0 from (11) is accepted, then the model 2 (7) is not confirmed, since the drift presence is rejected and the test (9) is not conclusive (since based on a wrong model). We then have to test the third model (12).

3. We assume the model (12):

(12)\boldsymbol{X_t = \rho X_{t-1} + \varepsilon_{t}}

The coefficients \rho are estimated as follows:

(13)\hat{\rho}_n=\frac{\sum_{i=2}^ny_{i-1}y_i}{\sum_{i=2}^ny_{i-1}^2}

We first test:

(14)\left\{
\begin{array}{lr}
  \mathcal{H}_0: & \rho = 1 \\
  \mathcal{H}_1: & \rho < 1
\end{array}
\right.

thanks to the Student statistics:

t_{\rho=1} = \frac{\hat{\rho}_n-1}{\sigma_{\rho_n}}

where \sigma_{\rho_n} is the least square estimate of the standard deviation of \Hat{\rho}_n, given by:

\sigma_{\rho_n}=\sqrt{\frac{1}{n-1}\sum_{i=2}^n\left(y_{i}-\hat{\rho}_ny_{i-1}\right)^2}/\sqrt{\sum_{i=2}^ny_{i-1}^2}

which converges in distribution to the Dickey-Fuller distribution associated to the random walk model:

t_{\rho = 1} \stackrel{\mathcal{L}}{\longrightarrow} \frac{\int_{0}^{1}W(r) \di{W(r)}}{\int_{1}^{0} W(r)^2 \di{r}}

The null hypothesis \cH_0 from (14) is accepted when t_{\rho=1} > C_{\alpha} where C_{\alpha} is the test threshold of level \alpha.

The quantiles of the Dickey-Fuller statistics for the random walk model are:

\left\{
\begin{array}{ll}
    \alpha = 0.01, & C_{\alpha} = -2.57 \\
    \alpha = 0.05, & C_{\alpha} = -1.94 \\
    \alpha = 0.10, & C_{\alpha} = -1.62
\end{array}
\right.

The decision to be taken is:
  • If \cH_0 from (14) is rejected, we then conclude that the model is : \boldsymbol{X_t = \rho X_{t-1} + \varepsilon_{t}} where \rho < 1 which is a stationary model.
  • If \cH_0 from (14) is accepted, we then conclude that the model is: \boldsymbol{X_t = X_{t-1} + \varepsilon_{t}} which is a non stationary model.

Examples

Create an ARMA process and generate a time series:

>>> import openturns as ot
>>> arcoefficients = ot.ARMACoefficients([0.3])
>>> macoefficients = ot.ARMACoefficients(0)
>>> timeGrid = ot.RegularGrid(0.0, 0.1, 10)
>>> whiteNoise = ot.WhiteNoise(ot.Normal(), timeGrid)
>>> myARMA = ot.ARMA(arcoefficients, macoefficients, whiteNoise)
>>> realization = ot.TimeSeries(myARMA.getRealization())
>>> test = ot.DickeyFullerTest(realization)

Test the stationarity of the data without any asumption on the model:

>>> globalRes = test.runStrategy()

Test the stationarity knowing you have a drift and linear trend model:

>>> res1 = test.testUnitRootInDriftAndLinearTrendModel(0.95)

Test the stationarity knowing you have a drift model:

>>> res2 = test.testUnitRootInDriftModel(0.95)

Test the stationarity knowing you have an AR1 model:

>>> res3 = test.testUnitRootInAR1Model(0.95)

Methods

getClassName() Accessor to the object’s name.
getId() Accessor to the object’s id.
getName() Accessor to the object’s name.
getShadowedId() Accessor to the object’s shadowed id.
getVerbose()
getVisibility() Accessor to the object’s visibility state.
hasName() Test if the object is named.
hasVisibleName() Test if the object has a distinguishable name.
runStrategy([level]) Test the stationarity without any assumption on the model.
setName(name) Accessor to the object’s name.
setShadowedId(id) Accessor to the object’s shadowed id.
setVerbose(verbose)
setVisibility(visible) Accessor to the object’s visibility state.
testNoUnitRootAndNoDriftInDriftModel([level]) Test for null drift in model without unit root.
testNoUnitRootAndNoLinearTrendInDriftAndLinearTrendModel([level]) Test for trend in model without unit root.
testUnitRootAndNoDriftInDriftModel([level]) Test for null drift in model with unit root.
testUnitRootAndNoLinearTrendInDriftAndLinearTrendModel([level]) Test for linear trend in model with unit root.
testUnitRootInAR1Model([level]) Test for unit root in AR1 model.
testUnitRootInDriftAndLinearTrendModel([level]) Test for unit root in model with drift and trend.
testUnitRootInDriftModel([level]) Test for unit root in model with drift.
__init__(*args)
getClassName()

Accessor to the object’s name.

Returns:

class_name : str

The object class name (object.__class__.__name__).

getId()

Accessor to the object’s id.

Returns:

id : int

Internal unique identifier.

getName()

Accessor to the object’s name.

Returns:

name : str

The name of the object.

getShadowedId()

Accessor to the object’s shadowed id.

Returns:

id : int

Internal unique identifier.

getVisibility()

Accessor to the object’s visibility state.

Returns:

visible : bool

Visibility flag.

hasName()

Test if the object is named.

Returns:

hasName : bool

True if the name is not empty.

hasVisibleName()

Test if the object has a distinguishable name.

Returns:

hasVisibleName : bool

True if the name is not empty and not the default one.

runStrategy(level=0.95)

Test the stationarity without any assumption on the model.

Parameters:

alpha : float, 0 < \alpha < 1

The first order error of the test.

By default, \alpha=0.95.

Returns:

testResult : TestResult

Results container of the tests. The strategy if the one described above.

setName(name)

Accessor to the object’s name.

Parameters:

name : str

The name of the object.

setShadowedId(id)

Accessor to the object’s shadowed id.

Parameters:

id : int

Internal unique identifier.

setVisibility(visible)

Accessor to the object’s visibility state.

Parameters:

visible : bool

Visibility flag.

testNoUnitRootAndNoDriftInDriftModel(level=0.95)

Test for null drift in model without unit root.

Parameters:

alpha : float, 0 < \alpha < 1

The first order error of the test.

By default, \alpha=0.95.

Returns:

testResult : TestResult

Results container of the test detailed in (10).

testNoUnitRootAndNoLinearTrendInDriftAndLinearTrendModel(level=0.95)

Test for trend in model without unit root.

Parameters:

alpha : float, 0 < \alpha < 1

The first order error of the test.

By default, \alpha=0.95.

Returns:

testResult : TestResult

Results container of the test detailed in (5).

testUnitRootAndNoDriftInDriftModel(level=0.95)

Test for null drift in model with unit root.

Parameters:

alpha : float, 0 < \alpha < 1

The first order error of the test.

By default, \alpha=0.95.

Returns:

testResult : TestResult

Results container of the test detailed in (11).

testUnitRootAndNoLinearTrendInDriftAndLinearTrendModel(level=0.95)

Test for linear trend in model with unit root.

Parameters:

alpha : float, 0 < \alpha < 1

The first order error of the test.

By default, \alpha=0.95

Returns:

testResult : TestResult

Results container of the test detailed in (6).

testUnitRootInAR1Model(level=0.95)

Test for unit root in AR1 model.

Parameters:

alpha : float, 0 < \alpha < 1

The first order error of the test.

By default, \alpha=0.95.

Returns:

testResult : TestResult

Results container of the test detailed in (14).

testUnitRootInDriftAndLinearTrendModel(level=0.95)

Test for unit root in model with drift and trend.

Parameters:

alpha : float, 0 < \alpha < 1

The first order error of the test.

By default, \alpha=0.95.

Returns:

testResult : TestResult

Results container of the test detailed in (4).

testUnitRootInDriftModel(level=0.95)

Test for unit root in model with drift.

Parameters:

alpha : float, 0 < \alpha < 1

The first order error of the test.

By default, \alpha=0.95.

Returns:

testResult : TestResult

Results container of the test detailed in (9).