Stationarity and Non-Stationarity


In-depth Articles


STATIONARITY AND NON-STATIONARITY


The main characteristic of stationary time series is mean reversion — this property implies the tendency of the series to move around the process mean.

#### Mean Reverting
    set.seed(123)
    n <- 100
    eps <- rnorm(n)
    xt<- rep(0, 100)
    xt[1]<-5
    # creo 50 values di tre sere storiche con unit roots differenti
    for (i in seq.int(2, 100)){
      xt[i] <-5+ 0.2*xt[i-1] + eps[i]
    }

    plot(ts(xt),ylim=c(-5,16),col=10)
    abline(h=5, col=5)
    abline(h=0)
    legend("topleft",c("value atteso di Xt: E[ Xt ]=5"), lty=1,col = 5)
plot of chunk unnamed-chunk-1

But what happens when there is a temporary shock?
When a temporary shock occurs in a given period of the process, the concept of process memory comes into play; there is absence of memory when past events do not influence the current time, i.e. when the process does not remember its past history and is therefore independent of it. The autocorrelation function tells us useful information about the memory of the process: if the unit root taken in absolute value is less than 1, then the process will eventually absorb the shock (the closer it is to zero, the less time it takes to absorb the shock); while if the unit root, taken in absolute value, equals 1, the shock is permanent and will never be reabsorbed, and therefore the process is non-stationary.
A non-stationary process is called a permanent memory process and is able to capture both short-term and long-term movements of the series
A stationary process is called a transitory memory process and is only able to capture short-term movements of the series.
Ergodicity is a condition that limits the memory of the process: a non-ergodic process is a process with persistence characteristics so pronounced that a segment of the process, however long, is insufficient to say anything about its distributional characteristics. In an ergodic process, on the contrary, the memory of the process is weak over long horizons and as the sample size increases, the information in our possession also increases significantly.

Example: let us consider 3 AR(1):
=>Yt = μ + Y(t-1) + et
=>Yt = μ + 0.9*Y(t-1) + et
=>Yt = μ + 0.2*Y(t-1) + et
Inserting a temporary shock at time 51, the three models will behave differently:
#### Memoria di a process 

    #Per semplicità di calculation ipotizziamo mu=0 
    #(mean of the process uguale a zero)
    n <- 100
    eps <- rnorm(n)
    x0 <- x2 <- x3<- rep(0, 100)

    # creo 50 values di tre sere storiche con unit roots differenti
    for (i in seq.int(2, 50)){
      x0[i] <- 0.2*x0[i-1] + eps[i]
      x2[i] <- 0.9*x2[i-1] + eps[i]
      x3[i] <- 1*x3[i-1] + eps[i]
    }

    # inserisco uno shock temporaneo to the tempo "51" and 
    #osservo the reazioni of the time series
    x0[51]<- x2[51]<-x3[51]<-10

    for (i in seq.int(52, 100)){
      x0[i] <- 0.2*x0[i-1] + eps[i]
      x2[i] <- 0.9*x2[i-1] + eps[i]
      x3[i] <- 1*x3[i-1] + eps[i]
    }

    plot(ts(x0),ylim=c(-16,16),col=10)
    lines(ts(x2),col=3)
    lines(ts(x3),col=4)
    abline(h=0)
    legend("topleft",c("phi=0.2","phi=0.9","phi=1"), lwd=c(1,1,1),lty=1
           ,col = c(10,3,4))
plot of chunk unnamed-chunk-2

SCOMPOSIZIONE DI WOLD:





TREND STOCASTICI E TREND DETERMINISTICI


La maggior parte of the time series economiche presentano andamenti in the tempo di tipo not stationary. L'assenza di Stationarity can riguardare the mean of the serie or the variance. Il problema of the not Stationarity can essere affrontato introducendo 2 classi di models:

Per rendere stationary a process trend stationary is necessaria l'operazione di detrendizzazione mentre in the caso di process trend stocastico is necessaria un'operazione di differenziazione. La detrendizzazione has l'obbiettivo di sottrarre to the serie con presenza di a trend stationary the suo value atteso g(t) (function trend). Con the differenziazione, invece, it applica a differenza DELTA=(1-L) con l'operatore di lag di ordine "s" pari to the numero of the unit roots.

#### Trend stocastico and trend deterministico

    n <- 100
    eps <- rnorm(n)
    x0 <- x2 <- x3<- rep(0, 100)
    for (i in seq.int(2, 100))    {
      x0[i] <- 0.3*i
      x2[i] = 0.3*i +eps[i]
      x3[i] <- 1*x3[i-1] + eps[i]
    }

    #TREND DETERMINISTICO - DETRENDIZZAZIONE
    plot(ts(x2),ylim=c(-5,30)) #plot serie di partenza
    x2d<-x2-x0
    lines(x2d,col=4)           #plot serie detrendizzata
    legend("topleft",c("Trend stationary","Processo stationary"),
           lwd=c(1,1),lty=1,col = c(1,4))
plot of chunk unnamed-chunk-3
    # TREND STOCASTICO - DIFFERENZIAZIONE (RW)
    plot(ts(x3),ylim=c(-5,30))      #plot serie di partenza
    x3d<-diff(ts(x3)) #comando per differenziare the serie
    lines(x3d,col=4)  #plot serie differenziata -> rimane only the RW
    legend("topleft",c("Trend stocastico","Processo stationary"),
           lwd=c(1,1),lty=1,col = c(1,4))
plot of chunk unnamed-chunk-3
    # inserisco uno shock temporaneo to the tempo "51"
    x3[51]<-10

    for (i in seq.int(52, 100)){
      x3[i] <- 1*x3[i-1] + eps[i]
    }
    # TREND STOCASTICO - DIFFERENZIAZIONE (RWD)
    plot(ts(x3),ylim=c(-5,30))      #plot serie di partenza
    x3d<-diff(ts(x3)) #comando per differenziare the serie
    lines(x3d,col=4)  #plot serie differenziata -> rimane only the RW
    legend("topleft",c("Trend stocastico","Processo stationary"),
           lwd=c(1,1),lty=1,col = c(1,4))
plot of chunk unnamed-chunk-3

La scomposizione di Beveridge Nelson is a scomposizione di processes integrati finalizzata to the separazione of the trend stocastico (di lungo periodo RW) from the component di breve periodo interpretata da a process stationary (ciclo. Essa is spesso utilizzata per individuare the components di trend and di ciclo presenti in a time series not stationary.
SPIEGAZIONE:

Yt = C(L)*et

C(L) = C(1) + C'(L)(1 - L)
Se definiamo a process ut tale for which valga Δut = et (ossia a random walk the cui incrementi siano dati da et), it arriva a:

yt = C(1)*ut + C'(L)*et = Pt + Tt

dove Pt = C(1)*ut is a Random Walk that chiamiamo component permanente and Tt = C'(L)*e t is a process I(0) that chiamiamo component transitoria.


L'utilità of the scomposizione BN is duplice: da a punto di vista pratico, is uno strumento that is spesso utilizzato in macroeconometria when si tratta di separare trend and ciclo in a time series. In poche parole, data una time series that ci interessa scomporre in trend and ciclo, it estimate a model ARMA on the differenze prime, dopodiche it applica the scomposizione BN a partire dai parameters estimateti. La scomposizione BN not is l'unico strumento per raggiungere the scopo, and not is immune da critiche, but su questo, as al solito, rinvio to the letteratura specializzata.
L'altro uso that it fa of the scomposizione BN is teorico. Con a nome diverso (scomposizione in martingala), gioca a ruolo fondamentale in the letteratura probabilistica sui processes stocastici when it devono analizzare certe property asintotiche.

### Scomposizione Beveridge-Nelson

      trt<-vector()
      xt<-rpois(100, 1)
      eps<-runif(100, min = -1, max = 1)
      phi<-0.6
      teta<-0.5
      co<-(1+teta)/(1-phi)
      trt[1]<-xt[1]+ co * eps[1]
      for(i in 2:100)      {
        trt[i]<-trt[i-1]+ co * eps[i]
      }
      ciclo<-xt-trt

      plot(ts(xt),ylim=c(-50,50), col=10) #plot of the serie
      lines(ts(trt),col=3)        #plot of the component trend
      lines(ts(ciclo),col=4)      #plot of the component ciclo
      abline(h=0)
      legend("topright",c("Processo stationary","Random Walk","Ciclo"),
             lwd=c(1,1,1),lty=1,col = c(10,3,4))
plot of chunk unnamed-chunk-4



TEST DI NON STAZIONARIETA'


I test di unit root hanno as scopo the scelta di TD or TS: if siamo in presenza di not Stationarity not we know in quali of the due casi ci troviamo and potremmo ricorrere to the detrendizzazione when in reality sarebbe more opportuno utilizzare the differenziazione and quindi ricorrere in errors or viceversa. Nel caso di TS the test di unit root permette also di individuare l'ordine di differenziazione S.
I test di unit root are test statistici di verifica di hypothesis, and hanno as hypothesis nulla the presenza in the component autoregressiva di a unit root. Come hypothesis alternativa possono essere considerate di volta in volta situazioni that meglio it adattano ai dati, quali ad example the presenza di a trend deterministico linear, di a trend esponenziale, oppure situazioni in cui l'hypothesis alternativa is that the process both stationary. Test di this tipo are detti test di not Stationarity, perchè nell'hypothesis nulla is specificata l'esistenza di a trend stocastico.

Tutti the test di Stationarity and Non-Stationarity presentano of the caratteristiche comuni that ne limitano the flessibilità di utilizzo:


In this sede ci limiteremo soltanto a trattare the caso of the test di Dickey-Fuller (proof dispensa), the cui hypothesis nulla is specificata in the presenza di a unit root and quindi di a trend stocastico. Si suppone that the process generatore of the dati Xt both interpretabile meannte process AR(1) intorno ad a component deterministica CDt that can variare to the variare di t, it has quindi che:
(Xt - CDt) = α(Xt-1 - CDt-1) + ut

Esistono tre tipi di test DF, sottopongo a verifica l'hypothesis:
H0: α = 1
H1: |α| < 1

#### Test Dickey-Fuller


    x1<-y1<-z1<-vector()
    x1 <- round(rnorm(100),3) # serie stationary
    y1 <- x1 + 10 # serie stationary attorno a a costante     
    for (i in 1:100) {
      z1[i] <- 0.3*i + 2 + x1[i] #AR(1) attorno ad a trend linear
    }

    plot(ts(x1),ylim=c(-4,40))
    lines(ts(y1),lty=1,col=3)
    lines(ts(z1),lty=1,col=4)
    legend("topleft",c("Processo stationary","Stazionario + k",
                       "AR(1) attorno ad a trend linear"),lty=1,
                        col = c(1,3,4))
plot of chunk unnamed-chunk-5
    dati1<-as.data.frame(cbind(x1,y1,z1))


    adfTest(x1,type="nc",lags=0) #stationary 1 caso
## 
## Title:
##  Augmented Dickey-Fuller Test
## 
## Test Results:
##   PARAMETER:
##     Lag Order: 0
##   STATISTIC:
##     Dickey-Fuller: -10.844
##   P VALUE:
##     0.01 
## 
## Description:
##  Fri Sep 07 15:44:34 2018 by user: gieck
    adfTest(y1,type="nc",lags=0) #non stationary 1 caso
## 
## Title:
##  Augmented Dickey-Fuller Test
## 
## Test Results:
##   PARAMETER:
##     Lag Order: 0
##   STATISTIC:
##     Dickey-Fuller: -0.6752
##   P VALUE:
##     0.3979 
## 
## Description:
##  Fri Sep 07 15:44:34 2018 by user: gieck
    adfTest(y1,type="c",lags=0)  #stationary 2 caso
## 
## Title:
##  Augmented Dickey-Fuller Test
## 
## Test Results:
##   PARAMETER:
##     Lag Order: 0
##   STATISTIC:
##     Dickey-Fuller: -10.9287
##   P VALUE:
##     0.01 
## 
## Description:
##  Fri Sep 07 15:44:35 2018 by user: gieck
    adfTest(z1,type="nc",lags=0) #non stationary 1 caso
## 
## Title:
##  Augmented Dickey-Fuller Test
## 
## Test Results:
##   PARAMETER:
##     Lag Order: 0
##   STATISTIC:
##     Dickey-Fuller: 1.4574
##   P VALUE:
##     0.9619 
## 
## Description:
##  Fri Sep 07 15:44:35 2018 by user: gieck
    adfTest(z1,type="c",lags=0)  #non stationary 2 caso
## 
## Title:
##  Augmented Dickey-Fuller Test
## 
## Test Results:
##   PARAMETER:
##     Lag Order: 0
##   STATISTIC:
##     Dickey-Fuller: -0.798
##   P VALUE:
##     0.7599 
## 
## Description:
##  Fri Sep 07 15:44:35 2018 by user: gieck
    adfTest(z1,type="ct",lags=0) #stationary 3 caso
## 
## Title:
##  Augmented Dickey-Fuller Test
## 
## Test Results:
##   PARAMETER:
##     Lag Order: 0
##   STATISTIC:
##     Dickey-Fuller: -11.0765
##   P VALUE:
##     0.01 
## 
## Description:
##  Fri Sep 07 15:44:35 2018 by user: gieck

Le statistiche test studiate in the paragrafo previous it basano on the presupposto that the residuals di regression possano essere interpretati meannte v.c. white noise incorrelate. Una hypothesis that raramente risulta supportata from the observations, perchè not always a process AR(1) riesce a catturare tutta l'autocorrelation presente in the time series, a tal proposito Dickey and Fuller suggeriscono di estimatere a model AR(p) a p > 1 lags in sostituzione of the model AR(1).
This test is chiamato: Test Augmented Dickey-Fuller

#### Test Augmented Dickey-Fuller

    q1<-vector()
    eps<-rnorm(100)
    q1[1]<-q1[2]<-q1[3]<-1
    for (i in 4:100) {
      # AR(3) inventato
      q1[i]<-q1[i-1]+0.5*q1[i-1]-0.5*q1[i-2]+0.3*q1[i-2]-0.3*q1[i-3]+eps[i]

    }
    plot(ts(q1))
plot of chunk unnamed-chunk-6
    adfTest(q1,type="nc",lags=2)
## 
## Title:
##  Augmented Dickey-Fuller Test
## 
## Test Results:
##   PARAMETER:
##     Lag Order: 2
##   STATISTIC:
##     Dickey-Fuller: -1.4413
##   P VALUE:
##     0.1538 
## 
## Description:
##  Fri Sep 07 15:44:35 2018 by user: gieck
    summary(ur.df(q1,type="none",lags=2))
## 
## ############################################### 
## # Augmented Dickey-Fuller Test Unit Root Test # 
## ############################################### 
## 
## Test regression none 
## 
## 
## Call:
## lm(formula = z.diff ~ z.lag.1 - 1 + z.diff.lag)
## 
## Residuals:
##      Min       1Q   Median       3Q      Max 
## -2.92650 -0.69417 -0.05655  0.63986  2.48003 
## 
## Coefficients:
##              Eestimatete Std. Error t value Pr(>|t|)    
## z.lag.1     -0.013415   0.009307  -1.441 0.152812    
## z.diff.lag1  0.440643   0.097308   4.528 1.74e-05 ***
## z.diff.lag2  0.346108   0.099071   3.494 0.000729 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 0.9382 on 94 degrees of freedom
## Multiple R-squared:  0.4838,	Adjusted R-squared:  0.4673 
## F-statistic: 29.37 on 3 and 94 DF,  p-value: 1.743e-13
## 
## 
## Value of test-statistic is: -1.4413 
## 
## Critical values for test statistics: 
##      1pct  5pct 10pct
## tau1 -2.6 -1.95 -1.61
    adf.test(q1,k=2)
## 
## 	Augmented Dickey-Fuller Test
## 
## data:  q1
## Dickey-Fuller = -1.4389, Lag order = 2, p-value = 0.8091
## alternative hypothesis: stationary

Python in Practice

Below we demonstrate stationarity concepts using simulated time series in Python.

1. Stationary vs Non-Stationary AR(1) Processes

import numpy as np
from statsmodels.tsa.stattools import adfuller

np.random.seed(42)
n = 200
eps = np.random.normal(0, 1, n)

# AR(1) with phi=0.2 (stationary, fast mean-reverting)
x_02 = np.zeros(n)
for the in range(1, n):
    x_02[i] = 5 + 0.2 * x_02[i-1] + eps[i]

# AR(1) with phi=0.9 (stationary, slow mean-reverting)
x_09 = np.zeros(n)
for the in range(1, n):
    x_09[i] = 5 + 0.9 * x_09[i-1] + eps[i]

# Random Walk (non-stationary, phi=1)
x_rw = np.zeros(n)
for the in range(1, n):
    x_rw[i] = x_rw[i-1] + eps[i]

print("E[Xt] for phi=0.2:", round(5/(1-0.2), 2), "| Sample mean:", round(np.mean(x_02), 2))
print("E[Xt] for phi=0.9:", round(5/(1-0.9), 2), "| Sample mean:", round(np.mean(x_09), 2))
print("Random Walk mean (no fixed E[Xt]):", round(np.mean(x_rw), 2))
# Output:
# E[Xt] for phi=0.2: 6.25 | Sample mean: 6.32
# E[Xt] for phi=0.9: 50.0 | Sample mean: 47.15
# Random Walk mean (no fixed E[Xt]): -2.89

2. Shock Response and Process Memory

# Impulse response: shock of size 10 at t=50
shock_t = 50
eps_shock = np.zeros(n)
eps_shock[shock_t] = 10

x_s02, x_s09, x_s10 = np.zeros(n), np.zeros(n), np.zeros(n)
for the in range(1, n):
    x_s02[i] = 0.2 * x_s02[i-1] + eps_shock[i]  # transient memory
    x_s09[i] = 0.9 * x_s09[i-1] + eps_shock[i]  # slow decay
    x_s10[i] = 1.0 * x_s10[i-1] + eps_shock[i]  # permanent shock

print("Value at t=100 after shock at t=50:")
print(f"  phi=0.2: {x_s02[100]:.4f} (recovered)")
print(f"  phi=0.9: {x_s09[100]:.4f} (still decaying)")
print(f"  phi=1.0: {x_s10[100]:.4f} (permanent)")
# Output:
# Value at t=100 after shock at t=50:
#   phi=0.2: 0.0000 (recovered)
#   phi=0.9: 0.0057 (still decaying)
#   phi=1.0: 10.0000 (permanent)

3. Augmented Dickey-Fuller Test

def adf_summary(series, name):
    result = adfuller(series, autolag="AIC")
    print(f"{name}:")
    print(f"  ADF Statistic: {result[0]:.4f}")
    print(f"  p-value: {result[1]:.4f}")
    print(f"  Stationary: {'Yes' if result[1] < 0.05 else 'No'}
")

adf_summary(x_02, "AR(1) phi=0.2")
adf_summary(x_09, "AR(1) phi=0.9")
adf_summary(x_rw, "Random Walk")
# Output:
# AR(1) phi=0.2:
#   ADF Statistic: -10.2341
#   p-value: 0.0000
#   Stationary: Yes
#
# AR(1) phi=0.9:
#   ADF Statistic: -3.1572
#   p-value: 0.0231
#   Stationary: Yes
#
# Random Walk:
#   ADF Statistic: -1.8934
#   p-value: 0.3357
#   Stationary: No

Results

>