Licença
This work is licensed under the Creative Commons Attribution-ShareAlike 4.0 International License. To view a copy of this license, visit http://creativecommons.org/licenses/by-sa/4.0/ or send a letter to Creative Commons, PO Box 1866, Mountain View, CA 94042, USA.
Citação
Sugestão de citação: FIGUEIREDO, Adriano Marcos Rodrigues. Séries temporais: GARCH exemplo em R. Campo Grande-MS,Brasil: RStudio/Rpubs, 2021. Disponível em http://rpubs.com/amrofi/ST_GARCHsim.
Simulando um GARCH
Este exercício é uma reprodução adaptada de Perlin (2020).
Farei o tipo do GARCH a simular ARIMA(1,0,0)-GARCH(1,1):
\[
y_t=\mu+\theta y_{t-1}+\varepsilon_t \\
\varepsilon_t \sim N(0,h_t) \\
h_t=\omega +\alpha \varepsilon^2_{t-1}+\beta h_{t-1}
\]
Conforme Perlin (2020), a primeira é a equação para a média da série temporal \(y_t\) , a segunda define a distribuição heteroscedástica de dos resíduos, e a terceira é a equação para modelar a variância, comumente definida como \(h_t\) para heteroscedasticidade. Portanto, se desejar outro modelo GARCH, altera-se a expressão de \(h_t\).
Seja o exemplo numérico conforme Perlin (2020):
\[
y_t=0.02+0.1y_{t-1}+\varepsilon_t \\
\varepsilon_t \sim N(0,h_t) \\
h_t=0.001+0.15\varepsilon^2_{t-1}+0.8h_{t-1}
\]
Para fazer isso, usarei o pacote fGarch
inserindo a lista de valores dos parâmetros e especificando o conjunto de dados para o GARCH via função garchSpec
.
library(fGarch)
# estabelecer lista para a especificação do modelo
my_model = list(omega = 0.001, alpha = 0.15, beta = 0.8, mu = 0.02, ar = 0.1)
# especificar o garch spec ele ainda não executa o modelo, apenas especifica.
spec = garchSpec(model = my_model)
# resultados da especificação
print(spec)
Formula:
~ ar(1) + garch(1, 1)
Model:
ar: 0.1
mu: 0.02
omega: 0.001
alpha: 0.15
beta: 0.8
Distribution:
norm
Presample:
time z h y
1 0 -2.288252 0.02 0.02222222
Feito isto, meu modelo pode ser executado pela função garchSim
. Neste caso, especificou-se n=1000 para o número de observações a serem simuladas.
set.seed(20) # semente para garantir reprodução idêntica
# simular o modelo garch conforme a especificação 'spec'
sim_garch = garchSim(spec, n = 1000)
A série pode ser visualizada graficamente utilizando o pacote e a função ggplot2::ggplot
:
# fazer um dataframe temp_df para usar no ggplot
temp_df <- tibble::tibble(sim.ret = sim_garch$garch, idx = seq_along(sim_garch$garch))
library(ggplot2)
p <- ggplot(temp_df, aes(x = idx, y = sim.ret)) + geom_line() + labs(title = "Plot da série simulada ARIMA(1,0,0)-GARCH(1,1)",
x = "Índice temporal", y = "Simulação dos retornos")
print(p)

O gráfico de um GARCH simulado para os retornos de uma ação terá variância diferente conforme a subamostra, ou seja, muda com o tempo. A volatilidade da série simulada pode ser obtida pela função volatility()
, para o objeto da simulação (sim_garch
).
volatilidade <- volatility(sim_garch)
plot(volatilidade, main = "Volatilidade de um GARCH simulado", xlab = "Tempo - genérico 1000 observações",
ylab = "garch simulado", sub = "Perlin (2020) - edição Kindle")

Estimulo o leitor a realizar alterações nos parâmetros e novas simulações para entender o que cada um pode influenciar na volatilidade, lembrando que são simulações. Se o leitor alterar apenas a semente em set.seed
, haverá a simulação do mesmo modelo, com os mesmos parâmetros, porém a geração dos resíduos aleatórios terá outros valores de partida.
Sugiro alterar os parâmetros um a um (\(\mu, \theta,\omega,\alpha,\beta\)), de modo a ter melhor controle das alterações. No caso, fiz apenas com o GARCH tipo ARIMA(1,0,0)-GARCH(1,1):
\[
y_t=\mu+\theta y_{t-1}+\varepsilon_t \\
\varepsilon_t \sim N(0,h_t) \\
h_t=\omega +\alpha \varepsilon^2_{t-1}+\beta h_{t-1}
\]
Exemplo 1 - alterando apenas \(\beta = 0.50\):
library(fGarch)
# estabelecer lista para a especificação do modelo
my_model = list(omega = 0.001, alpha = 0.15, beta = 0.5, mu = 0.02, ar = 0.1)
# especificar o garch spec ele ainda não executa o modelo, apenas especifica.
spec = garchSpec(model = my_model)
# resultados da especificação
print(spec)
Formula:
~ ar(1) + garch(1, 1)
Model:
ar: 0.1
mu: 0.02
omega: 0.001
alpha: 0.15
beta: 0.5
Distribution:
norm
Presample:
time z h y
1 0 0.31394 0.002857143 0.02222222
set.seed(20) # semente para garantir reprodução idêntica
# simular o modelo garch conforme a especificação 'spec'
sim_garch = garchSim(spec, n = 1000)
# fazer um dataframe temp_df para usar no ggplot
temp_df <- tibble::tibble(sim.ret = sim_garch$garch, idx = seq_along(sim_garch$garch))
library(ggplot2)
p <- ggplot(temp_df, aes(x = idx, y = sim.ret)) + geom_line() + labs(title = "Plot da série simulada ARIMA(1,0,0)-GARCH(1,1)",
x = "Índice temporal", y = "Simulação dos retornos")
print(p)

volatilidade <- volatility(sim_garch)
plot(volatilidade, main = "Volatilidade de um GARCH simulado", xlab = "Tempo - genérico 1000 observações",
ylab = "garch simulado", sub = "Perlin (2020) - edição Kindle")

Investigando a volatilidade
Alguns autores sugerem investigar a volatilidade de uma série por meio de gráficos do quadrado dos retornos, ou dos seus valores absolutos, olhando se existem autocorrelações expressivas.
Seja o exemplo 1 realizado anteriormente neste post, observaremos a série armazenada em temp_df
. Farei os plots de temp_df\(^2\), e depois para o seu valor absoluto, |temp_df|.
temp_df$sim.ret2 <- temp_df$sim.ret^2
temp_df$sim.ret.abs <- abs(temp_df$sim.ret)
# plots
library(ggplot2)
p <- ggplot(temp_df, aes(x = idx, y = sim.ret2)) + geom_line() + labs(title = "Plot da série simulada ao quadrado",
subtitle = "ARIMA(1,0,0)-GARCH(1,1)", x = "Índice temporal", y = "Simulação dos retornos quadráticos")
print(p)

library(ggplot2)
p <- ggplot(temp_df, aes(x = idx, y = sim.ret.abs)) + geom_line() + labs(title = "Plot da série simulada em valor absoluto",
subtitle = "ARIMA(1,0,0)-GARCH(1,1)", x = "Índice temporal", y = "Simulação dos retornos absolutos")
print(p)

Agora observarei as autocorrelações dessas séries:
temp_df.tsb <- tsibble::as_tsibble(temp_df, index = idx)
# plots ACF
library(feasts)
temp_df.tsb %>% ACF(sim.ret2) %>% autoplot() + labs(title = "ACF Plot dos retornos simulados quadráticos",
y = "Retornos quadráticos", x = "Tempo")

temp_df.tsb %>% ACF(sim.ret.abs) %>% autoplot() + labs(title = "ACF Plot dos retornos simulados absolutos",
y = "Retornos absolutos", x = "Tempo")

O leitor pode observar o lag significativo nos correlogramas.
Referências
Perlin, Marcelo S. (2020) Análise de Dados Financeiros e Econômicos com o R (p. 481). Edição do Kindle.
LS0tDQp0aXRsZTogIlPDqXJpZXMgdGVtcG9yYWlzOiBHQVJDSCBleGVtcGxvIGVtIFIiDQphdXRob3I6ICJBZHJpYW5vIE1hcmNvcyBSb2RyaWd1ZXMgRmlndWVpcmVkbyINCmUtbWFpbDogImFkcmlhbm8uZmlndWVpcmVkb0B1Zm1zLmJyIg0KYWJzdHJhY3Q6ICJUaGlzIGlzIGFuIHVuZGVyZ3JhZCBzdHVkZW50IGxldmVsIGluc3RydWN0aW9uIGZvciBjbGFzcyB1c2UuIg0KZGF0ZTogImByIGZvcm1hdChTeXMuRGF0ZSgpLCAnJWQgJUIgJVknKWAiDQpvdXRwdXQ6DQogIGh0bWxfZG9jdW1lbnQ6DQogICAgY29kZV9kb3dubG9hZDogdHJ1ZQ0KICAgIHRoZW1lOiBkZWZhdWx0DQogICAgbnVtYmVyX3NlY3Rpb25zOiB0cnVlDQogICAgdG9jOiB5ZXMNCiAgICB0b2NfZmxvYXQ6IG5vDQogICAgZGZfcHJpbnQ6IHBhZ2VkDQogICAgZmlnX2NhcHRpb246IHRydWUNCiAgcGRmX2RvY3VtZW50Og0KICAgIHRvYzogeWVzDQotLS0NCg0KYGBge3Iga25pdHJfaW5pdCwgZWNobz1GQUxTRSwgY2FjaGU9RkFMU0V9DQpsaWJyYXJ5KGtuaXRyKQ0KbGlicmFyeShybWFya2Rvd24pDQpsaWJyYXJ5KHJtZGZvcm1hdHMpDQoNCiMjIEdsb2JhbCBvcHRpb25zDQpvcHRpb25zKG1heC5wcmludD0iMTAwIikNCm9wdHNfY2h1bmskc2V0KGVjaG89VFJVRSwNCgkgICAgICAgICAgICAgY2FjaGU9VFJVRSwNCiAgICAgICAgICAgICAgIHByb21wdD1GQUxTRSwNCiAgICAgICAgICAgICAgIHRpZHk9VFJVRSwNCiAgICAgICAgICAgICAgIGNvbW1lbnQ9TkEsDQogICAgICAgICAgICAgICBtZXNzYWdlPUZBTFNFLA0KICAgICAgICAgICAgICAgd2FybmluZz1GQUxTRSwNCiAgICAgICAgICAgICAgIG91dC53aWR0aD03NTAsIA0KICAgICAgICAgICAgICAgZmlnLmhlaWdodD04LCANCiAgICAgICAgICAgICAgIGZpZy53aWR0aD04KQ0Kb3B0c19rbml0JHNldCh3aWR0aD0xMDApDQpgYGANCg0KIyBMaWNlbsOnYSB7I0xpY2Vuw6dhIC51bm51bWJlcmVkfQ0KDQpUaGlzIHdvcmsgaXMgbGljZW5zZWQgdW5kZXIgdGhlIENyZWF0aXZlIENvbW1vbnMgQXR0cmlidXRpb24tU2hhcmVBbGlrZSA0LjAgSW50ZXJuYXRpb25hbCBMaWNlbnNlLiBUbyB2aWV3IGEgY29weSBvZiB0aGlzIGxpY2Vuc2UsIHZpc2l0IDxodHRwOi8vY3JlYXRpdmVjb21tb25zLm9yZy9saWNlbnNlcy9ieS1zYS80LjAvPiBvciBzZW5kIGEgbGV0dGVyIHRvIENyZWF0aXZlIENvbW1vbnMsIFBPIEJveCAxODY2LCBNb3VudGFpbiBWaWV3LCBDQSA5NDA0MiwgVVNBLg0KDQohW0xpY2Vuc2U6IENDIEJZLVNBIDQuMF0oaHR0cHM6Ly9taXJyb3JzLmNyZWF0aXZlY29tbW9ucy5vcmcvcHJlc3NraXQvYnV0dG9ucy84OHgzMS9wbmcvYnktc2EucG5nKXt3aWR0aD0iMjUlIn0NCg0KIyBDaXRhw6fDo28geyNDaXRhw6fDo28gLnVubnVtYmVyZWR9DQoNClN1Z2VzdMOjbyBkZSBjaXRhw6fDo286IEZJR1VFSVJFRE8sIEFkcmlhbm8gTWFyY29zIFJvZHJpZ3Vlcy4gU8OpcmllcyB0ZW1wb3JhaXM6IEdBUkNIIGV4ZW1wbG8gZW0gUi4gQ2FtcG8gR3JhbmRlLU1TLEJyYXNpbDogUlN0dWRpby9ScHVicywgMjAyMS4gRGlzcG9uw612ZWwgZW0gPGh0dHA6Ly9ycHVicy5jb20vYW1yb2ZpL1NUX0dBUkNIc2ltPi4NCg0KIyBTaW11bGFuZG8gdW0gR0FSQ0gNCg0KRXN0ZSBleGVyY8OtY2lvIMOpIHVtYSByZXByb2R1w6fDo28gYWRhcHRhZGEgZGUgUGVybGluICgyMDIwKS4NCg0KRmFyZWkgbyB0aXBvIGRvIEdBUkNIIGEgc2ltdWxhciBBUklNQSgxLDAsMCktR0FSQ0goMSwxKToNCg0KJCQNCnlfdD1cbXUrXHRoZXRhIHlfe3QtMX0rXHZhcmVwc2lsb25fdCBcXA0KXHZhcmVwc2lsb25fdCBcc2ltIE4oMCxoX3QpIFxcDQpoX3Q9XG9tZWdhICtcYWxwaGEgXHZhcmVwc2lsb25eMl97dC0xfStcYmV0YSBoX3t0LTF9DQokJA0KDQpDb25mb3JtZSBQZXJsaW4gKDIwMjApLCBhIHByaW1laXJhIMOpIGEgZXF1YcOnw6NvIHBhcmEgYSBtw6lkaWEgZGEgc8OpcmllIHRlbXBvcmFsICR5X3QkICwgYSBzZWd1bmRhIGRlZmluZSBhIGRpc3RyaWJ1acOnw6NvIGhldGVyb3NjZWTDoXN0aWNhIGRlIGRvcyByZXPDrWR1b3MsIGUgYSB0ZXJjZWlyYSDDqSBhIGVxdWHDp8OjbyBwYXJhIG1vZGVsYXIgYSB2YXJpw6JuY2lhLCBjb211bWVudGUgZGVmaW5pZGEgY29tbyAkaF90JCBwYXJhIGhldGVyb3NjZWRhc3RpY2lkYWRlLiBQb3J0YW50bywgc2UgZGVzZWphciBvdXRybyBtb2RlbG8gR0FSQ0gsIGFsdGVyYS1zZSBhIGV4cHJlc3PDo28gZGUgJGhfdCQuDQoNClNlamEgbyBleGVtcGxvIG51bcOpcmljbyBjb25mb3JtZSBQZXJsaW4gKDIwMjApOg0KDQokJA0KeV90PTAuMDIrMC4xeV97dC0xfStcdmFyZXBzaWxvbl90IFxcDQpcdmFyZXBzaWxvbl90IFxzaW0gTigwLGhfdCkgXFwNCmhfdD0wLjAwMSswLjE1XHZhcmVwc2lsb25eMl97dC0xfSswLjhoX3t0LTF9DQokJA0KDQpQYXJhIGZhemVyIGlzc28sIHVzYXJlaSBvIHBhY290ZSBgZkdhcmNoYCBpbnNlcmluZG8gYSBsaXN0YSBkZSB2YWxvcmVzIGRvcyBwYXLDom1ldHJvcyBlIGVzcGVjaWZpY2FuZG8gbyBjb25qdW50byBkZSBkYWRvcyBwYXJhIG8gR0FSQ0ggdmlhIGZ1bsOnw6NvIGBnYXJjaFNwZWNgLg0KDQpgYGB7cn0NCmxpYnJhcnkoZkdhcmNoKSANCg0KIyBlc3RhYmVsZWNlciBsaXN0YSBwYXJhIGEgZXNwZWNpZmljYcOnw6NvIGRvIG1vZGVsbyANCm15X21vZGVsID0gbGlzdChvbWVnYT0wLjAwMSwNCiAgICAgICAgICAgICAgICBhbHBoYT0wLjE1LA0KICAgICAgICAgICAgICAgIGJldGE9MC44LA0KICAgICAgICAgICAgICAgIG11PTAuMDIsDQogICAgICAgICAgICAgICAgYXIgPSAwLjEpIA0KDQojIGVzcGVjaWZpY2FyIG8gZ2FyY2ggc3BlYyANCiMgZWxlIGFpbmRhIG7Do28gZXhlY3V0YSBvIG1vZGVsbywgYXBlbmFzIGVzcGVjaWZpY2EuDQpzcGVjID0gZ2FyY2hTcGVjKG1vZGVsID0gbXlfbW9kZWwpIA0KDQojIHJlc3VsdGFkb3MgZGEgZXNwZWNpZmljYcOnw6NvDQpwcmludChzcGVjKQ0KYGBgDQoNCkZlaXRvIGlzdG8sIG1ldSBtb2RlbG8gcG9kZSBzZXIgZXhlY3V0YWRvIHBlbGEgZnVuw6fDo28gYGdhcmNoU2ltYC4gTmVzdGUgY2FzbywgZXNwZWNpZmljb3Utc2Ugbj0xMDAwIHBhcmEgbyBuw7ptZXJvIGRlIG9ic2VydmHDp8O1ZXMgYSBzZXJlbSBzaW11bGFkYXMuDQoNCmBgYHtyfQ0Kc2V0LnNlZWQoMjApICMgc2VtZW50ZSBwYXJhIGdhcmFudGlyIHJlcHJvZHXDp8OjbyBpZMOqbnRpY2ENCiMgc2ltdWxhciBvIG1vZGVsbyBnYXJjaCBjb25mb3JtZSBhIGVzcGVjaWZpY2HDp8OjbyAnc3BlYycNCnNpbV9nYXJjaCA9IGdhcmNoU2ltKHNwZWMsIG4gPSAxMDAwKQ0KYGBgDQoNCkEgc8OpcmllIHBvZGUgc2VyIHZpc3VhbGl6YWRhIGdyYWZpY2FtZW50ZSB1dGlsaXphbmRvIG8gcGFjb3RlIGUgYSBmdW7Dp8OjbyBgZ2dwbG90Mjo6Z2dwbG90YCA6DQoNCmBgYHtyfQ0KIyBmYXplciB1bSBkYXRhZnJhbWUgdGVtcF9kZiBwYXJhIHVzYXIgbm8gZ2dwbG90IA0KdGVtcF9kZiA8LSB0aWJibGU6OnRpYmJsZShzaW0ucmV0ID0gc2ltX2dhcmNoJGdhcmNoLA0KICAgICAgICAgICAgICAgICAgaWR4PXNlcV9hbG9uZyhzaW1fZ2FyY2gkZ2FyY2gpKSANCmxpYnJhcnkoZ2dwbG90MikgDQpwIDwtIGdncGxvdCh0ZW1wX2RmLCBhZXMoeD1pZHgsIHk9c2ltLnJldCkpICsNCiAgZ2VvbV9saW5lKCkrbGFicyh0aXRsZT0iUGxvdCBkYSBzw6lyaWUgc2ltdWxhZGEgQVJJTUEoMSwwLDApLUdBUkNIKDEsMSkiLA0KICAgICAgICB4ID0iw41uZGljZSB0ZW1wb3JhbCIsIHkgPSAiU2ltdWxhw6fDo28gZG9zIHJldG9ybm9zIikNCnByaW50KHApDQpgYGANCg0KTyBncsOhZmljbyBkZSB1bSBHQVJDSCBzaW11bGFkbyBwYXJhIG9zIHJldG9ybm9zIGRlIHVtYSBhw6fDo28gdGVyw6EgdmFyacOibmNpYSBkaWZlcmVudGUgY29uZm9ybWUgYSBzdWJhbW9zdHJhLCBvdSBzZWphLCBtdWRhIGNvbSBvIHRlbXBvLiBBIHZvbGF0aWxpZGFkZSBkYSBzw6lyaWUgc2ltdWxhZGEgcG9kZSBzZXIgb2J0aWRhIHBlbGEgZnVuw6fDo28gYHZvbGF0aWxpdHkoKWAsIHBhcmEgbyBvYmpldG8gZGEgc2ltdWxhw6fDo28gKGBzaW1fZ2FyY2hgKS4NCg0KYGBge3J9DQp2b2xhdGlsaWRhZGU8LXZvbGF0aWxpdHkoc2ltX2dhcmNoKQ0KcGxvdCh2b2xhdGlsaWRhZGUsDQogICAgIG1haW49IlZvbGF0aWxpZGFkZSBkZSB1bSBHQVJDSCBzaW11bGFkbyIsDQogICAgIHhsYWI9IlRlbXBvIC0gZ2Vuw6lyaWNvIDEwMDAgb2JzZXJ2YcOnw7VlcyIsDQogICAgIHlsYWI9ImdhcmNoIHNpbXVsYWRvIiwNCiAgICAgc3ViPSJQZXJsaW4gKDIwMjApIC0gZWRpw6fDo28gS2luZGxlIikNCmBgYA0KDQpFc3RpbXVsbyBvIGxlaXRvciBhIHJlYWxpemFyIGFsdGVyYcOnw7VlcyBub3MgcGFyw6JtZXRyb3MgZSBub3ZhcyBzaW11bGHDp8O1ZXMgcGFyYSBlbnRlbmRlciBvIHF1ZSBjYWRhIHVtIHBvZGUgaW5mbHVlbmNpYXIgbmEgdm9sYXRpbGlkYWRlLCBsZW1icmFuZG8gcXVlIHPDo28gc2ltdWxhw6fDtWVzLiBTZSBvIGxlaXRvciBhbHRlcmFyIGFwZW5hcyBhIHNlbWVudGUgZW0gYHNldC5zZWVkYCwgaGF2ZXLDoSBhIHNpbXVsYcOnw6NvIGRvIG1lc21vIG1vZGVsbywgY29tIG9zIG1lc21vcyBwYXLDom1ldHJvcywgcG9yw6ltIGEgZ2VyYcOnw6NvIGRvcyByZXPDrWR1b3MgYWxlYXTDs3Jpb3MgdGVyw6Egb3V0cm9zIHZhbG9yZXMgZGUgcGFydGlkYS4NCg0KU3VnaXJvIGFsdGVyYXIgb3MgcGFyw6JtZXRyb3MgdW0gYSB1bSAoJFxtdSwgXHRoZXRhLFxvbWVnYSxcYWxwaGEsXGJldGEkKSwgZGUgbW9kbyBhIHRlciBtZWxob3IgY29udHJvbGUgZGFzIGFsdGVyYcOnw7Vlcy4gTm8gY2FzbywgZml6IGFwZW5hcyBjb20gbyBHQVJDSCB0aXBvIEFSSU1BKDEsMCwwKS1HQVJDSCgxLDEpOg0KDQokJA0KeV90PVxtdStcdGhldGEgeV97dC0xfStcdmFyZXBzaWxvbl90IFxcDQpcdmFyZXBzaWxvbl90IFxzaW0gTigwLGhfdCkgXFwNCmhfdD1cb21lZ2EgK1xhbHBoYSBcdmFyZXBzaWxvbl4yX3t0LTF9K1xiZXRhIGhfe3QtMX0NCiQkDQoNCiMgRXhlbXBsbyAxIC0gYWx0ZXJhbmRvIGFwZW5hcyAkXGJldGEgPSAwLjUwJDoNCg0KYGBge3J9DQpsaWJyYXJ5KGZHYXJjaCkgDQoNCiMgZXN0YWJlbGVjZXIgbGlzdGEgcGFyYSBhIGVzcGVjaWZpY2HDp8OjbyBkbyBtb2RlbG8gDQpteV9tb2RlbCA9IGxpc3Qob21lZ2E9MC4wMDEsDQogICAgICAgICAgICAgICAgYWxwaGE9MC4xNSwNCiAgICAgICAgICAgICAgICBiZXRhPTAuNSwNCiAgICAgICAgICAgICAgICBtdT0wLjAyLA0KICAgICAgICAgICAgICAgIGFyID0gMC4xKSANCg0KIyBlc3BlY2lmaWNhciBvIGdhcmNoIHNwZWMgDQojIGVsZSBhaW5kYSBuw6NvIGV4ZWN1dGEgbyBtb2RlbG8sIGFwZW5hcyBlc3BlY2lmaWNhLg0Kc3BlYyA9IGdhcmNoU3BlYyhtb2RlbCA9IG15X21vZGVsKSANCg0KIyByZXN1bHRhZG9zIGRhIGVzcGVjaWZpY2HDp8Ojbw0KcHJpbnQoc3BlYykNCnNldC5zZWVkKDIwKSAjIHNlbWVudGUgcGFyYSBnYXJhbnRpciByZXByb2R1w6fDo28gaWTDqm50aWNhDQojIHNpbXVsYXIgbyBtb2RlbG8gZ2FyY2ggY29uZm9ybWUgYSBlc3BlY2lmaWNhw6fDo28gJ3NwZWMnDQpzaW1fZ2FyY2ggPSBnYXJjaFNpbShzcGVjLCBuID0gMTAwMCkNCiMgZmF6ZXIgdW0gZGF0YWZyYW1lIHRlbXBfZGYgcGFyYSB1c2FyIG5vIGdncGxvdCANCnRlbXBfZGYgPC0gdGliYmxlOjp0aWJibGUoc2ltLnJldCA9IHNpbV9nYXJjaCRnYXJjaCwNCiAgICAgICAgICAgICAgICAgIGlkeD1zZXFfYWxvbmcoc2ltX2dhcmNoJGdhcmNoKSkgDQpsaWJyYXJ5KGdncGxvdDIpIA0KcCA8LSBnZ3Bsb3QodGVtcF9kZiwgYWVzKHg9aWR4LCB5PXNpbS5yZXQpKSArDQogIGdlb21fbGluZSgpKw0KICBsYWJzKHRpdGxlPSJQbG90IGRhIHPDqXJpZSBzaW11bGFkYSBBUklNQSgxLDAsMCktR0FSQ0goMSwxKSIsDQogICAgICAgeCA9IsONbmRpY2UgdGVtcG9yYWwiLCANCiAgICAgICB5ID0gIlNpbXVsYcOnw6NvIGRvcyByZXRvcm5vcyIpDQpwcmludChwKQ0Kdm9sYXRpbGlkYWRlPC12b2xhdGlsaXR5KHNpbV9nYXJjaCkNCnBsb3Qodm9sYXRpbGlkYWRlLA0KICAgICBtYWluPSJWb2xhdGlsaWRhZGUgZGUgdW0gR0FSQ0ggc2ltdWxhZG8iLA0KICAgICB4bGFiPSJUZW1wbyAtIGdlbsOpcmljbyAxMDAwIG9ic2VydmHDp8O1ZXMiLA0KICAgICB5bGFiPSJnYXJjaCBzaW11bGFkbyIsDQogICAgIHN1Yj0iUGVybGluICgyMDIwKSAtIGVkacOnw6NvIEtpbmRsZSIpDQpgYGANCg0KIyBJbnZlc3RpZ2FuZG8gYSB2b2xhdGlsaWRhZGUNCg0KQWxndW5zIGF1dG9yZXMgc3VnZXJlbSBpbnZlc3RpZ2FyIGEgdm9sYXRpbGlkYWRlIGRlIHVtYSBzw6lyaWUgcG9yIG1laW8gZGUgZ3LDoWZpY29zIGRvIHF1YWRyYWRvIGRvcyByZXRvcm5vcywgb3UgZG9zIHNldXMgdmFsb3JlcyBhYnNvbHV0b3MsIG9saGFuZG8gc2UgZXhpc3RlbSBhdXRvY29ycmVsYcOnw7VlcyBleHByZXNzaXZhcy4NCg0KU2VqYSBvIGV4ZW1wbG8gMSByZWFsaXphZG8gYW50ZXJpb3JtZW50ZSBuZXN0ZSBwb3N0LCBvYnNlcnZhcmVtb3MgYSBzw6lyaWUgYXJtYXplbmFkYSBlbSBgdGVtcF9kZmAuIEZhcmVpIG9zIHBsb3RzIGRlIHRlbXBfZGYkXjIkLCBlIGRlcG9pcyBwYXJhIG8gc2V1IHZhbG9yIGFic29sdXRvLCBcfHRlbXBfZGZcfC4NCg0KYGBge3J9DQp0ZW1wX2RmJHNpbS5yZXQyPC10ZW1wX2RmJHNpbS5yZXReMg0KdGVtcF9kZiRzaW0ucmV0LmFiczwtYWJzKHRlbXBfZGYkc2ltLnJldCkNCiMgcGxvdHMNCmxpYnJhcnkoZ2dwbG90MikgDQpwIDwtIGdncGxvdCh0ZW1wX2RmLCBhZXMoeD1pZHgsIHk9c2ltLnJldDIpKSArDQogIGdlb21fbGluZSgpKw0KICBsYWJzKHRpdGxlPSJQbG90IGRhIHPDqXJpZSBzaW11bGFkYSBhbyBxdWFkcmFkbyIsDQogIHN1YnRpdGxlPSAiQVJJTUEoMSwwLDApLUdBUkNIKDEsMSkiLA0KICAgICAgIHggPSLDjW5kaWNlIHRlbXBvcmFsIiwgDQogICAgICAgeSA9ICJTaW11bGHDp8OjbyBkb3MgcmV0b3Jub3MgcXVhZHLDoXRpY29zIikNCnByaW50KHApDQpsaWJyYXJ5KGdncGxvdDIpIA0KcCA8LSBnZ3Bsb3QodGVtcF9kZiwgYWVzKHg9aWR4LCB5PXNpbS5yZXQuYWJzKSkgKw0KICBnZW9tX2xpbmUoKSsNCiAgbGFicyh0aXRsZT0iUGxvdCBkYSBzw6lyaWUgc2ltdWxhZGEgZW0gdmFsb3IgYWJzb2x1dG8iLA0KICBzdWJ0aXRsZT0gIkFSSU1BKDEsMCwwKS1HQVJDSCgxLDEpIiwNCiAgICAgICB4ID0iw41uZGljZSB0ZW1wb3JhbCIsIA0KICAgICAgIHkgPSAiU2ltdWxhw6fDo28gZG9zIHJldG9ybm9zIGFic29sdXRvcyIpDQpwcmludChwKQ0KDQpgYGANCg0KQWdvcmEgb2JzZXJ2YXJlaSBhcyBhdXRvY29ycmVsYcOnw7VlcyBkZXNzYXMgc8OpcmllczoNCg0KYGBge3J9DQp0ZW1wX2RmLnRzYjwtdHNpYmJsZTo6YXNfdHNpYmJsZSh0ZW1wX2RmLCBpbmRleCA9IGlkeCkNCiMgcGxvdHMgQUNGDQpsaWJyYXJ5KGZlYXN0cykgDQp0ZW1wX2RmLnRzYiAlPiUgQUNGKHNpbS5yZXQyKSAlPiUgYXV0b3Bsb3QoKSsNCiAgbGFicyh0aXRsZSA9ICJBQ0YgUGxvdCBkb3MgcmV0b3Jub3Mgc2ltdWxhZG9zIHF1YWRyw6F0aWNvcyIsDQogICAgICAgeSA9ICJSZXRvcm5vcyBxdWFkcsOhdGljb3MiLA0KICAgICAgIHggPSAiVGVtcG8iKQ0KDQp0ZW1wX2RmLnRzYiAlPiUgQUNGKHNpbS5yZXQuYWJzKSAlPiUgYXV0b3Bsb3QoKSsNCiAgbGFicyh0aXRsZT0iQUNGIFBsb3QgZG9zIHJldG9ybm9zIHNpbXVsYWRvcyBhYnNvbHV0b3MiLA0KICAgICAgIHkgPSAiUmV0b3Jub3MgYWJzb2x1dG9zIiwNCiAgICAgICB4ID0gIlRlbXBvIikNCmBgYA0KDQpPIGxlaXRvciBwb2RlIG9ic2VydmFyIG8gbGFnIHNpZ25pZmljYXRpdm8gbm9zIGNvcnJlbG9ncmFtYXMuDQoNCiMgUmVmZXLDqm5jaWFzIHsjUmVmZXLDqm5jaWFzIC51bm51bWJlcmVkfQ0KDQpQZXJsaW4sIE1hcmNlbG8gUy4gKDIwMjApIEFuw6FsaXNlIGRlIERhZG9zIEZpbmFuY2Vpcm9zIGUgRWNvbsO0bWljb3MgY29tIG8gUiAocC4gNDgxKS4gRWRpw6fDo28gZG8gS2luZGxlLg0K