ARIMA para LTN

 UNIVERSIDADE FEDERAL DA PARAÍBA

Autor

Natan Henrique Alves

Data de Publicação

14 de junho de 2024

O que é LTN

As Letras do Tesouro Nacional (LTNs) são títulos públicos emitidos pelo governo federal do Brasil através do Tesouro Nacional. Elas são instrumentos financeiros utilizados para captar recursos para o financiamento da dívida pública e para o financiamento de diversas atividades do governo.

LTN são títulos pre fixados, o que significa que têm uma taxa de retorno definida no momento da compra.

Pacotes Usados

Código
library(showtext)
library(tidyverse)
library(GetTDData)
library(knitr)
library(rbcb)
library(ggthemes)
library(urca)
library(fBasics)
library(forecast)
library(FinTS)


first_year <- 2020
last_year <- 2024

Baixando Dados

Os dados foram requeridos através do pacote GetTDData, que usa a base de dados do próprio Tesouro Nacional. A série foi se inicia em 01/01/2020 até 16/06/2024, um pouco mais de 4 anos.

Código
df_td <- td_get("LTN", 
                first_year,
                last_year)

Visualização de Dados Requeridos

Código
kable(head(df_td))
ref_date yield_bid price_bid asset_code matur_date
2020-01-02 0.0451 957.18 LTN 010121 2021-01-01
2020-01-03 0.0453 957.16 LTN 010121 2021-01-01
2020-01-06 0.0448 957.78 LTN 010121 2021-01-01
2020-01-07 0.0448 957.95 LTN 010121 2021-01-01
2020-01-08 0.0445 958.38 LTN 010121 2021-01-01
2020-01-09 0.0440 959.00 LTN 010121 2021-01-01
Código
showtext_auto()
font_add_google("ubuntu", "ubuntu")

ggplot(data = df_td,
       aes(x = as.Date(ref_date), 
           y = yield_bid,
           color = asset_code))+
  geom_line(size = 1)+ scale_x_date() + labs(title = "", x = "Data")+
  theme_calc()+
  theme(legend.text = element_text(family = "ubuntu", face = "bold",
                                   color = "#11122233", size = 8),
        legend.key.size = unit(0.5, "cm"),
        axis.text.y = element_text(family = "ubuntu", color = "#22233344",
                                   size = 8, hjust = 1.25),
        plot.title = element_text(family = "ubuntu", face = "bold", size = 20),
        plot.subtitle = element_text(family = "ubuntu", face = "italic", size = 10),
        legend.title = element_text(size = 8),
        plot.margin = margin(t = 20, r = 8, b = 7, l = 5),
        panel.grid = element_blank())+
  labs(x = "ano",
       y = "Retorno",
       title = "Evolução dos Retornos da LTN",
       subtitle = "(2020-2024)",
       caption = "Fonte: Tesouro Direto")

Isolando LTN Mensal

A LTN mensal foi criada isolando as últimas observações de cada mês.

Código
# Isolando apenas o que será usado
LTN <- data.frame(data = as.Date(df_td$ref_date), retorno = df_td$yield_bid*100)

# Separando a Ultima Observação de cada mês

LTN_m <- LTN |> 
  group_by(ano_mes = format(data, "%Y-%m")) |> 
  slice_tail(n = 1) 
  
# Data Frame Final com Gráfico
ltn <- LTN_m[1:2]

ggplot(data = ltn,
       aes(x = data, y = retorno))+
  geom_line()

Trazendo IPCA e calculando a Diferença

O IPCA foi requerido através da função rbcb, em seguida os valores mensais do IPCA foi subtraido dos valores mensais da LTN para, por fim, se chegar ao valor da Diferença entre eles.

Código
IPCA <- get_series(13522, start_date = "2020-01-01", end_date = "2024-06-01")

desvio <- data.frame(data = ltn$data, retorno = ltn$retorno - IPCA$`13522`)

desvio |> 
  ggplot(aes(x = data, y = retorno))+
  geom_line()

Código
desvio_ts <- ts(desvio$retorno, frequency = 12, start = c(2020,01,01))

Transformando a Série em Ìndice

O índice será calculado dividindo-se todos os valores por um valor de referência, que nesse caso será o primeiro valor da série no periodo 2020/01/01 que será a base 100. O objetivo é tornar a série estacionaria.

Código
desvio_indice <- (desvio$retorno / desvio$retorno[1])*100

desvio_indice <- ts(desvio_indice, frequency = 12, start = c(2020,01,01))

kable(head(desvio_indice))
x
100.0000
121.3930
196.5174
233.3333
231.3433
209.9502

Testando a Série em Ìndice

Código
ggtsdisplay(desvio_indice)

Código
shapiro.test(desvio_indice)

    Shapiro-Wilk normality test

data:  desvio_indice
W = 0.92253, p-value = 0.001865
Código
jarqueberaTest(desvio_indice)

Title:
 Jarque - Bera Normalality Test

Test Results:
  STATISTIC:
    X-squared: 4.3523
  P VALUE:
    Asymptotic p Value: 0.1135 
Código
ddicky2 <- ur.df(desvio_indice, lags = 0, type="drift")
summary(ddicky2)

############################################### 
# Augmented Dickey-Fuller Test Unit Root Test # 
############################################### 

Test regression drift 


Call:
lm(formula = z.diff ~ z.lag.1 + 1)

Residuals:
    Min      1Q  Median      3Q     Max 
-69.153 -25.522  -0.712  21.692  85.664 

Coefficients:
            Estimate Std. Error t value Pr(>|t|)
(Intercept)  9.39774    8.76320   1.072    0.289
z.lag.1     -0.01938    0.03696  -0.524    0.602

Residual standard error: 36.01 on 51 degrees of freedom
Multiple R-squared:  0.005364,  Adjusted R-squared:  -0.01414 
F-statistic: 0.275 on 1 and 51 DF,  p-value: 0.6022


Value of test-statistic is: -0.5244 0.7793 

Critical values for test statistics: 
      1pct  5pct 10pct
tau2 -3.51 -2.89 -2.58
phi1  6.70  4.71  3.86
Código
#library(lmtest)
#length(residuos);length(residuos)*0.15
#gqtest(IS2, fraction=36, alternative = "greater")
#bptest(IS2)
#library(whitestrap)
#white_test(IS2)

#dwtest(IS2)
#bgtest(IS2, order=4)
#library(FinTS)
#ArchTest(residuos, lags = 4)

####  Teste de Estacionariedade do Resíduo   #######
#Box.test(residuos, lag=12, type="Box-Pierce")

Logarítimo do Desvio Calculado

Código
# serie temporal

log_desvio <- log(desvio_indice + sqrt(min(desvio_indice)**2)+0.001)

Testando a Série em log(Ìndice)

Código
ggtsdisplay(log_desvio)

Código
shapiro.test(log_desvio)

    Shapiro-Wilk normality test

data:  log_desvio
W = 0.56817, p-value = 2.339e-11
Código
jarqueberaTest(log_desvio)

Title:
 Jarque - Bera Normalality Test

Test Results:
  STATISTIC:
    X-squared: 1325.4869
  P VALUE:
    Asymptotic p Value: < 2.2e-16 
Código
ddicky2 <- ur.df(log_desvio, lags = 0, type="drift")
summary(ddicky2)

############################################### 
# Augmented Dickey-Fuller Test Unit Root Test # 
############################################### 

Test regression drift 


Call:
lm(formula = z.diff ~ z.lag.1 + 1)

Residuals:
     Min       1Q   Median       3Q      Max 
-10.5109   0.0531   0.3827   0.5418   3.7258 

Coefficients:
            Estimate Std. Error t value Pr(>|t|)    
(Intercept)   2.2835     0.6138   3.720 0.000497 ***
z.lag.1      -0.4765     0.1200  -3.972 0.000224 ***
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Residual standard error: 1.683 on 51 degrees of freedom
Multiple R-squared:  0.2363,    Adjusted R-squared:  0.2213 
F-statistic: 15.78 on 1 and 51 DF,  p-value: 0.0002243


Value of test-statistic is: -3.9721 7.8947 

Critical values for test statistics: 
      1pct  5pct 10pct
tau2 -3.51 -2.89 -2.58
phi1  6.70  4.71  3.86

Número de diferenças para ter uma Série Estacionaria

Código
# Numero de diferenças necessarias 

ndiffs(desvio_indice)
[1] 1

Testando a Série em diff(Ìndice)

Código
indice_dif <- diff(desvio_indice,1)

ggtsdisplay(indice_dif)

Código
shapiro.test(indice_dif)

    Shapiro-Wilk normality test

data:  indice_dif
W = 0.97584, p-value = 0.3551
Código
jarqueberaTest(indice_dif)

Title:
 Jarque - Bera Normalality Test

Test Results:
  STATISTIC:
    X-squared: 1.2166
  P VALUE:
    Asymptotic p Value: 0.5443 
Código
ddicky2 <- ur.df(indice_dif, lags = 0, type="drift")
summary(ddicky2)

############################################### 
# Augmented Dickey-Fuller Test Unit Root Test # 
############################################### 

Test regression drift 


Call:
lm(formula = z.diff ~ z.lag.1 + 1)

Residuals:
    Min      1Q  Median      3Q     Max 
-74.077 -17.401  -4.024  20.525  85.862 

Coefficients:
            Estimate Std. Error t value Pr(>|t|)    
(Intercept)   3.7549     4.9234   0.763    0.449    
z.lag.1      -0.7312     0.1360  -5.377    2e-06 ***
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Residual standard error: 35.05 on 50 degrees of freedom
Multiple R-squared:  0.3663,    Adjusted R-squared:  0.3537 
F-statistic: 28.91 on 1 and 50 DF,  p-value: 2.001e-06


Value of test-statistic is: -5.3766 14.4582 

Critical values for test statistics: 
      1pct  5pct 10pct
tau2 -3.51 -2.89 -2.58
phi1  6.70  4.71  3.86

Série Selecionada diff(ìndice)

Código
arima.1<- arima(indice_dif, order= c(1,1,0), method = c("CSS-ML"))
arima.1

Call:
arima(x = indice_dif, order = c(1, 1, 0), method = c("CSS-ML"))

Coefficients:
          ar1
      -0.4719
s.e.   0.1222

sigma^2 estimated as 1446:  log likelihood = -263.1,  aic = 530.21
Código
previsao <- predict(arima.1, n.ahead = 12)
previsao
$pred
             Jan         Feb         Mar         Apr         May         Jun
2024                                                                        
2025  0.09418747  0.07829393  0.08579339  0.08225473  0.08392447  0.08313659
             Jul         Aug         Sep         Oct         Nov         Dec
2024  1.06175308 -0.37825739  0.30121972 -0.01939541  0.13188866  0.06050441
2025                                                                        

$se
          Jan      Feb      Mar      Apr      May      Jun      Jul      Aug
2024                                                       38.02790 43.00578
2025 72.76105 77.19086 81.40954 85.40678 89.23115 92.89548                  
          Sep      Oct      Nov      Dec
2024 51.62034 57.16339 62.98240 67.96811
2025                                    
Código
autoplot(previsao$pred)

Testando os Residuos do Modelo

Código
residuos <- arima.1$residuals
Box.test(residuos, lag = 1)

    Box-Pierce test

data:  residuos
X-squared = 0.21638, df = 1, p-value = 0.6418
Código
shapiro.test(residuos)

    Shapiro-Wilk normality test

data:  residuos
W = 0.98963, p-value = 0.9249
Código
jarqueberaTest(residuos)

Title:
 Jarque - Bera Normalality Test

Test Results:
  STATISTIC:
    X-squared: 0.3554
  P VALUE:
    Asymptotic p Value: 0.8372 
Código
ArchTest(residuos, lags = 4)

    ARCH LM-test; Null hypothesis: no ARCH effects

data:  residuos
Chi-squared = 0.75406, df = 4, p-value = 0.9445
Código
ddicky2 <- ur.df(residuos, lags = 0, type="drift")
summary(ddicky2)

############################################### 
# Augmented Dickey-Fuller Test Unit Root Test # 
############################################### 

Test regression drift 


Call:
lm(formula = z.diff ~ z.lag.1 + 1)

Residuals:
   Min     1Q Median     3Q    Max 
-88.94 -29.59  -4.30  26.51  77.05 

Coefficients:
            Estimate Std. Error t value Pr(>|t|)    
(Intercept)  -0.7426     5.3660  -0.138     0.89    
z.lag.1      -1.0644     0.1416  -7.514 9.44e-10 ***
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Residual standard error: 38.69 on 50 degrees of freedom
Multiple R-squared:  0.5304,    Adjusted R-squared:  0.521 
F-statistic: 56.46 on 1 and 50 DF,  p-value: 9.44e-10


Value of test-statistic is: -7.5143 28.236 

Critical values for test statistics: 
      1pct  5pct 10pct
tau2 -3.51 -2.89 -2.58
phi1  6.70  4.71  3.86