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
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 não é estacionária
Os modelos de séries temporais são para séries estacionárias
r = dol.rolling(window=21)
plt.plot(dol, 'k-', alpha = 0.5)
plt.plot(r.mean(), 'r-');
$$ \begin{split} x_t &= \log p_t - \log p_{t-1} \\ & = \log\left( \frac{p_t}{p_{t-1}} \right) \end{split} $$
dol_ret = np.log(dol).diff().dropna()
plt.plot(dol_ret);
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} $$
# 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);
dol_ret.hist(bins=50);
r = dol_ret.rolling(window=21)
plt.plot(dol_ret, 'k-', alpha = 0.5)
plt.plot(r.mean(), 'r-');
plt.plot(dol_ret, 'k-', alpha = 0.5)
plt.plot(r.std(), 'r-');
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$.
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
¶import statsmodels.tsa as tsa
import statsmodels.api as sm
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 -----------------------------------------------------------------------------
model.params
array([ 0.00032177, 0.00705945])
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')
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')
plot_two(dol_ret, model.resid, [-0.1,0.1], 'Retorno do dólar', 'Resíduos do modelo')
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
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
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
res.params
mu 0.029881 omega 0.046921 alpha[1] 0.116672 beta[1] 0.845103 Name: params, dtype: float64
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')
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')
plot_two(dol_ret, (res.resid/res.conditional_volatility)/100, [-0.1,0.1], 'Retorno do dólar', 'Resíduo do modelo')
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');
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: