Modelagem de Séries Temporais com Python

Python Sudeste 2018

Wilson Freitas

Wilson Freitas

  • físico
  • quant
  • corredor
  • padeiro

Agenda

  • Séries Temporais
  • Processos Estocásticos Lineares Estacionários
  • Modelos de Volatilidade

O que são Séries Temporais?




Qualquer conjunto de dados ordenados no tempo



  • Exemplos:
    • preços de ações na Bolsa de Valores
    • dados de tráfego do estado de São Paulo
    • registro de temperatura
    • Dados de GPS: posição, frequência cardíaca

Como são modeladas séries temporais?

  • Regressão
  • Modelos ARIMA
  • Modelos GARCH
  • Modelos VAR/Cointegração
  • Redes Neurais
    • multilayer perceptron
    • bayesian neural networks
    • radial basis functions
  • Lógica Fuzzy
  • K-nearest neighbor
  • Support vector machines
  • ...

O que vamos fazer?

  • Encontrar um modelo para a série de preços do dólar em reais $p_t$

  • O modelo deve reproduzir as propriedades estatíticas da série de preços

In [3]:
import quandl
dol = quandl.get('BCB/1', start_date = '2014-01-01', end_date = '2017-12-21').reset_index(drop=True)
plt.plot(dol);

A série de preços dá trabalho!

  • A série de preços não é estacionária

  • Os modelos de séries temporais são para séries estacionárias

In [4]:
r = dol.rolling(window=21)
plt.plot(dol, 'k-', alpha = 0.5)
plt.plot(r.mean(), 'r-');

Vamos trabalhar com a variação dos preços

  • A variação dos preços é tipicamente estacionária $x_t$

$$ \begin{split} x_t &= \log p_t - \log p_{t-1} \\ & = \log\left( \frac{p_t}{p_{t-1}} \right) \end{split} $$

In [5]:
dol_ret = np.log(dol).diff().dropna()
plt.plot(dol_ret);

Voltando para os preços

Reconstruindo a série de preços $p_t$ a partir da série de retornos $x_t$.

$$ x_t = \log\left( \frac{p_t}{p_{t-1}} \right) \longrightarrow p_{t} = p_{t-1} \exp{x_t} $$

In [6]:
#                       p_{t-1}        exp(x_t)
dol1 = np.cumprod(np.r_[dol.values[0], np.exp(dol_ret.values.reshape(len(dol_ret)))])
plt.plot(dol1);

Histograma de $x_t$

In [7]:
dol_ret.hist(bins=50);

Média Móvel de $x_t$

In [8]:
r = dol_ret.rolling(window=21)
plt.plot(dol_ret, 'k-', alpha = 0.5)
plt.plot(r.mean(), 'r-');

Desvio Padrão em Janela Móvel de $x_t$

In [9]:
plt.plot(dol_ret, 'k-', alpha = 0.5)
plt.plot(r.std(), 'r-');

O que observamos olhando $x_t$?

  • a média de $x_t$ varia muito pouco em torno de zero

  • o desvio padrão de $x_t$ tem uma dinâmica

Vamos usar uma técninca para modelar as propriedades estatísticas de $x_t$.

Vamos considerar o modelo abaixo para $x_t$

Estamos assumindo que o passado pode explicar o futuro.


$$ x_t = \mu + \phi_1 x_{t-1} + \epsilon_t $$


  • Esse modelo descreve um processo autoregressivo

  • É como um regressão de $x_t$ sobre o passado de $x_t$

statsmodels

  • Linear regression models
  • Generalized linear models
  • Discrete choice models
  • Robust linear models
  • Many models and functions for time series analysis
  • Nonparametric estimators
  • A collection of datasets for examples
  • A wide range of statistical tests
  • Input-output tools for producing tables in a number of formats (Text, LaTex, HTML) and for reading Stata files into NumPy and Pandas.
  • Plotting functions
  • Extensive unit tests to ensure correctness of results

fonte: http://statsmodels.sourceforge.net/

In [10]:
import statsmodels.tsa as tsa
import statsmodels.api as sm
In [11]:
model = sm.tsa.ARMA(dol_ret.as_matrix(), (1, 0)).fit(trend = 'c')
print(model.summary())
                              ARMA Model Results                              
==============================================================================
Dep. Variable:                      y   No. Observations:                  997
Model:                     ARMA(1, 0)   Log Likelihood                3196.990
Method:                       css-mle   S.D. of innovations              0.010
Date:                Fri, 30 Mar 2018   AIC                          -6387.980
Time:                        16:26:54   BIC                          -6373.266
Sample:                             0   HQIC                         -6382.387
                                                                              
==============================================================================
                 coef    std err          z      P>|z|      [0.025      0.975]
------------------------------------------------------------------------------
const          0.0003      0.000      1.030      0.303      -0.000       0.001
ar.L1.y        0.0071      0.032      0.223      0.824      -0.055       0.069
                                    Roots                                    
=============================================================================
                 Real           Imaginary           Modulus         Frequency
-----------------------------------------------------------------------------
AR.1          141.6541           +0.0000j          141.6541            0.0000
-----------------------------------------------------------------------------

Simulando $x_t$ com o modelo adotado

  • Tendo os parâmetros do modelo, $\mu$ e $\phi$, podemos fazer simulações usando $x_t = \mu + \phi_1 x_{t-1} + \epsilon_t$
In [12]:
model.params
Out[12]:
array([ 0.00032177,  0.00705945])
In [13]:
dol_ar_proc = tsa.arima_process.ArmaProcess(np.r_[1, -model.params], [1])
dol_ar_sim = dol_ar_proc.generate_sample(len(dol_ret))*model.resid.std()
plot_two(dol_ret, dol_ar_sim, [-0.1,0.1], 'Retorno do dólar', 'Retorno do dólar simulado')

Voltando para a série de $p_t$

In [14]:
dol1 = np.cumprod(np.r_[dol.values[1], np.exp(dol_ar_sim)])
plot_two(dol, dol1, [1,4.5], 'Dólar', 'Dólar simulado')

Olhando os resíduos

In [15]:
plot_two(dol_ret, model.resid, [-0.1,0.1], 'Retorno do dólar', 'Resíduos do modelo')

Vamos tentar algo diferente

  • Sabendo que o desvio padrão tem uma dinâmica, vamos usar um modelo que possa descrever o desvio padrão.

  • Os modelos da família GARCH podem fazer isso!

$$ x_t = \mu + \epsilon_t $$

onde

$$ \begin{align} \epsilon_t & = z_t \sigma_t \\ \sigma^2_t & = \omega + \alpha_1 e^2_{t-1} + \beta_1 \sigma^2_{t-1} \end{align} $$

  • $z_t \sim N(0, 1)$.

  • A variância do processo é um processo autoregressivo

arch

The ARCH toolbox currently contains routines for

  • Univariate volatility models
  • Bootstrapping
  • Multiple comparison procedures
  • Unit root tests

fonte: http://arch.readthedocs.io/en/latest/

In [16]:
from arch import arch_model
am = arch_model(dol_ret*100, p=1, q=1)
res = am.fit(disp='off')
print(res.summary())
                     Constant Mean - GARCH Model Results                      
==============================================================================
Dep. Variable:                  Value   R-squared:                      -0.000
Mean Model:             Constant Mean   Adj. R-squared:                 -0.000
Vol Model:                      GARCH   Log-Likelihood:               -1342.72
Distribution:                  Normal   AIC:                           2693.45
Method:            Maximum Likelihood   BIC:                           2713.06
                                        No. Observations:                  997
Date:                Fri, Mar 30 2018   Df Residuals:                      993
Time:                        16:26:55   Df Model:                            4
                                 Mean Model                                
===========================================================================
                 coef    std err          t      P>|t|     95.0% Conf. Int.
---------------------------------------------------------------------------
mu             0.0299  3.888e-02      0.769      0.442 [-4.632e-02,  0.106]
                              Volatility Model                             
===========================================================================
                 coef    std err          t      P>|t|     95.0% Conf. Int.
---------------------------------------------------------------------------
omega          0.0469  4.816e-02      0.974      0.330 [-4.748e-02,  0.141]
alpha[1]       0.1167  6.011e-02      1.941  5.228e-02 [-1.149e-03,  0.234]
beta[1]        0.8451  8.267e-02     10.223  1.571e-24    [  0.683,  1.007]
===========================================================================

Covariance estimator: robust
In [17]:
def simulate_garch(params, nobs, var=0):
    e = np.random.randn(nobs)
    var = np.zeros(len(e)) + var
    x = np.zeros(len(e))

    for t in range(len(e)):
        var[t] = params[1] + params[2] * x[t-1]**2 + params[3] * var[t-1]
        x[t] = params[0] + e[t] * np.sqrt(var[t])
    
    return x

Simulando $x_t$ com o modelo GARCH estimado

  • Tendo os parâmetros do modelo, $\omega$, $\beta$ e $\alpha$, podemos fazer simulações de $x_t$ usando o modelo GARCH
In [18]:
res.params
Out[18]:
mu          0.029881
omega       0.046921
alpha[1]    0.116672
beta[1]     0.845103
Name: params, dtype: float64
In [19]:
dol_am_sim = simulate_garch(res.params, len(dol_ret))/100
plot_two(dol_ret, dol_am_sim, [-0.1,0.1], 'Retorno do dólar', 'Retorno do dólar simulado')

Voltando para a série de $p_t$

In [20]:
dol1 = np.cumprod(np.r_[dol.values[1], np.exp(dol_am_sim)])
plot_two(dol, dol1, [2,4.5], 'Dólar', 'Dólar simulado')

Olhando os resíduos

In [21]:
plot_two(dol_ret, (res.resid/res.conditional_volatility)/100, [-0.1,0.1], 'Retorno do dólar', 'Resíduo do modelo')

Simulando o futuro

In [22]:
dol.tail(252).plot()
paths = np.zeros((100,21))
for i in range(100):
    dol_am_sim = simulate_garch(res.params, 20)/100
    path = np.cumprod(np.r_[dol.values[-1], np.exp(dol_am_sim)])
    paths[i,:] = path
    plt.plot(range(999, 999+21), path, '-g', alpha = 0.25)
plt.plot(range(999, 999+21), np.mean(paths, 0), '-r');

Conclusões

Aqui vimos um breve exemplo de como realizar Modelagem de Séries Temporais com Python.

A Modelagem de Séries Temporais é fundamental para a compreensão da dinâmica das séries temporais, particularmente utilizada para modelar séries financeiras.

A modelagem de séries temporais financeiras é utilizada para:

  • Trading de Índices de Volatilidade
  • Gestão de risco
  • Apreçamento de derivativos financeiros
  • Modelos de Volatilidade em Séries Intradiárias para avaliação de Risco Intradiário
  • Modelos de Cointegração para trading de pares (pairs trading)
  • Modelos de execução de ordens em condições heterogêneas

Dúvidas?