About
In this worksheet we look at different variance, covariance, volatility, and causality calculations. We finish with a short matematical proof (no R required).
Setup
Remember to always set your working directory to the source file location. Go to ‘Session’, scroll down to ‘Set Working Directory’, and click ‘To Source File Location’. Read carefully the below and follow the instructions to complete the tasks and answer any questions. Submit your work to RPubs as detailed in previous notes.
Note
For clarity, tasks/questions to be completed/answered are highlighted in red color (color visible only in preview mode) and numbered according to their particular placement in the task section. Type your answers outside the red color tags!
Quite often you will need to add your own code chunk. Execute sequentially all code chunks, preview, publish, and submit link on Sakai following the naming convention. Make sure to add comments to your code where appropriate. Use own language!
Any sign of plagiarism, will result in dissmissal of work!
Task 1: Variance, Covariance, and Volatility
This task follows the two examples in the book R Example 2.5/p. 58 and R Example 2.6/p. 66
# Require will load the package only if not installed
# Dependencies = TRUE makes sure that dependencies are install
if(!require("quantmod",quietly = TRUE))
install.packages("quantmod",dependencies = TRUE, repos = "https://cloud.r-project.org")
##### 1A) Calculate the correlation and covariance matrix of the adjusted daily log returns for four different stocks of your choice. Explain your observations in terms of potential relationships.
# Once you have obtained the adjusted daily log returns for your stocks, omitting the time index, you will need to combine them to create a matrix. Below is an example. For more details see the Help command in R on cbind, cov, and cor.
# M <- cbind(A,B,C) # create a matrix where each column is an array/vector of numerical values
# cov(M) # compute the covariance matrix
# cor(M, method="pearson") # compute the correlation matrix based on the Pearson method
library(quantmod)
symbols=c('BMO', 'KR', 'MSFT', 'XOM')
getSymbols(symbols, src='yahoo')
[1] "BMO" "KR" "MSFT" "XOM"
bmord = periodReturn(BMO, period = "daily", type ="log")
krrd = periodReturn(KR, period = "daily", type ="log")
msftrd = periodReturn(MSFT, period = "daily", type ="log")
xomrd = periodReturn(XOM, period = "daily", type ="log")
##Creating a matrix
M <- cbind(bmord,krrd,msftrd,xomrd)
colnames(M) <- c('BMO', 'KR', 'MSFT', 'XOM')
# compute the covariance matrix
options(scipen=999)
cov(M)
BMO KR MSFT XOM
BMO 0.00026902159 0.00008059575 0.00013456559 0.00013650491
KR 0.00008059575 0.00027936674 0.00008433024 0.00008563205
MSFT 0.00013456559 0.00008433024 0.00029532422 0.00013858133
XOM 0.00013650491 0.00008563205 0.00013858133 0.00023134334
# compute the correlation matrix based on the Pearson method
cor(M)
BMO KR MSFT XOM
BMO 1.0000000 0.2939891 0.4774094 0.5471750
KR 0.2939891 1.0000000 0.2935935 0.3368375
MSFT 0.4774094 0.2935935 1.0000000 0.5301841
XOM 0.5471750 0.3368375 0.5301841 1.0000000
Both covariance and correlation tests of the daily log returns of BMO, KR, MSFT and XOM indicate variables are positively or related. Correlation also tells us about the degree to which the variables tend to move together.The correlation range from 0.29 and and the covariance is also greater than 0 which shows there is a strong relationship between stocks
##### 1B) Calculate the three types of volatility for a particular stock of your choice. Consider a time window extending one year back from most recent obtainable closing day price. Order the three estimates from low to high volatility and explain how the ordering makes sense.
# For this task make sure you understand well what the variables n,m represent in the book's referenced example.
msft = MSFT['2017-12-03/2018-12-03']
M = length(msft[, "MSFT.Close"])
ohlc <- msft[, c("MSFT.Open", "MSFT.High", "MSFT.Low", "MSFT.Close")]
vClose = volatility(ohlc, n= M, calc = "close", N=252)
vParkinson = volatility(ohlc, n=M, calc = "parkinson", N=252)
vGK = volatility(ohlc, n=M, calc = "garman", N=252)
vClose[M]
[,1]
2018-12-03 0.2599985
vParkinson[M]
[,1]
2018-12-03 0.2222632
vGK[M]
[,1]
2018-12-03 0.2193207
The estimator shows volatility for Microsoft Corporation as follows: 0.219 for Garman Klass, 0.222 for Parkinson and the highest 0.259 for close-close.The ordering is because Parkinson assumed continous trading and only considers high and low prices whereas Garman Klass considers the open and close values. Hence the overall volatility for the year according to Garman klass model is lesser when compared to Parkinson’s model
Task 2: Auto-Correlation and Auto-Regression
Follow the example in the book R Example 3.2/p. 74 and R Example 4.1/p. 115
##### 2A) Calculate the ACF for a stock of your choice. Consider both the log return and squared log return. Interpret your results in terms of possible existence of autocorrelation.
library(quantmod)
acf(na.omit(xomrd), main = "ACF OF XOM", ylim = c(-0.2, 0.2))

acf(na.omit(xomrd)^2, main = "ACF OF XOM Squared log return", ylim = c(-0.3, 0.5))

Autocorrelation with daily log returns exists exists at lag 3,8,16 and 20 and negative autocorrelation exists at lag 1,2,7,17 and 18 The result indicates that there is some linear dependence of the variance of Exxon Mobil with its past values.
##### 2B) Plot the exchange rate for USD versus another currency of your choice. Interpret your results in terms of behavior.
getFX("USD/NGN")
[1] "USDNGN"
plot(USDNGN)

The graph shows a fluctuationg relationship between USD/NGN,it goes from really low to average, then low again but it started to rise as from sept 2018.
##### 2C) Test for the possible existence of an underlying AR(1) – Markov process in your exchange rate currency pair. To this end, plot the ACF and the partial ACF (PACF). Interpret your results. Clearly refer to the lags, and their impacts in determining the order.
acf(USDNGN)

pacf(USDNGN)

THE ACF shows a slow exponential decay for successive lags, hence revealing that the series USD/NGN does behaves as an AR(1) process.
Task 3: Granger Causality Test
To conduct this test the package lmtest will be required, as already done in the code chunk below.
# Require will load the package only if not installed
# Dependencies = TRUE makes sure that dependencies are install
if(!require("lmtest",quietly = TRUE))
install.packages("lmtest",dependencies = TRUE, repos = "https://cloud.r-project.org")
##### 3A) Include below the code chunk to solve for 3.5.7 R Lab/p. 106. Write your conclusions.
# More information about the data used in testing for causality can be obtained by typing the name of the data set `ChickEgg``ChickEgg` in the R Help menu.
grangertest(egg ~ chicken, order = 3, data = ChickEgg)
Granger causality test
Model 1: egg ~ Lags(egg, 1:3) + Lags(chicken, 1:3)
Model 2: egg ~ Lags(egg, 1:3)
Res.Df Df F Pr(>F)
1 44
2 47 -3 0.5916 0.6238
grangertest(chicken~egg, order = 3, data=ChickEgg)
Granger causality test
Model 1: chicken ~ Lags(chicken, 1:3) + Lags(egg, 1:3)
Model 2: chicken ~ Lags(chicken, 1:3)
Res.Df Df F Pr(>F)
1 44
2 47 -3 5.405 0.002966 **
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
The first Granger causality test is testing whether the chicken causes the egg. The null hypothesis is the chicken does not cause the egg. The p-value is 0.6238 and the critical value is 0.05. This means that the p-value is higher than the critical value. Hence, I do not reject the null hypothesis. In conclusion, the chicken does not cause the egg
The second Granger causality test is testing whether the egg causes the chicken. The null Hypothenus is the egg does not cause chicken. The p-value is 0.002966 and the critical value is 0.05.This means that the p-value is less than the critical value. Hence, I reject the null hypothesis. In conclusion, the egg causes the chicken
##### 3B) Briefly describe the data in terms of time range and variables. Similar to the linear autoegressive model described in class, write the mathematical regression model solved in each Granger test, including the proper order. Use naming conventions, and notations more reflective of the data set considered for ChickEgg.
The data(ChickEgg) contains the annual production of chicken and eggs from the period of 1980 to 1983.
The Granger test uses the bivariate linear autoregressive model on two variables(egg and chicken)
The regression model used in the granger test is \(Y_{t}= a_{0} + a_{1}Y_{t-1} + a_{2}Y_{t-2} + a_{3}Y_{t-3} + b_{1}X_{t-1} + b_{2}X_{t-2} + b_{3}X_{t-3} + \varepsilon_{t}\)
For the first test: whether chicken causes egg, the regression model is: \(Egg_{t}= a_{0} + a_{1}Egg_{t-1} + a_{2}Egg_{t-2} + a_{3}Egg_{t-3} + b_{1}Chicken_{t-1} + b_{2}Chicken_{t-2} + b_{3}Chicken_{t-3} + \varepsilon_{t}\)
The null hypothesis tested is \(H_{0}= b_{1} = b_{2} = b_{3} = 0\)
For the second test: whether egg causes chicken, the regression model is:
\(Chicken_{t}= a_{0} + a_{1}Chicken_{t-1} + a_{2}Chicken_{t-2} + a_{3}Chicken_{t-3} + b_{1}Egg_{t-1} + b_{2}Egg_{t-2} + b_{3}Egg_{t-3} + \varepsilon_{t}\)
The null hypothesis tested is \(H_{0}= b_{1} = b_{2} = b_{3} = 0\)
Task 4: Mathematical Proof
##### 4A) Prove the two results in Eq (2.32)/p. 53. No R-coding is needed here. Clearly show your steps. Hint: Use the definition of \(E(X^n)\) for X-log normally distributed. Observe also that \(Var(X) = E(X^2)-E^2(X)\) for any random variable X.
The definition of the monments on variable x:
\(E(X^n) = exp(n\mu +\frac{1}{2}n^2 \sigma^2 ) , n>0\)
If we have a simple return series \(R_{t}\) which is log normally distributed with mean \(\mu_{R}\) and variance \(\sigma_{R}^2\), so that the log return series \(R_{t}\) is \(r_{t} = ln(R_{t}+1)\) ~ \(N(\mu_{r}, \sigma_{r}^2)\)
Solving for \(R_{t}\), we get
\(R_{t}+1 = e^{r_{t}}\)
\(\mu_{r}+\sigma_{r}\) we get an 1st moment of \(R_{t}\);
The formula for the first moment is \(E(R_{t})= \mu_{R} = e^{\mu_{r}+\sigma_{r}^2/2}-1\)
For the second moment, we can get it by using the variance formula \(Var(X) = E(X^2)-E^2(X)\)
SO, the formula for the second moment is:
\(Var(R_{t}) = e^{2\mu_{r}+2\sigma_{r}^2}- [e^{\mu_{r}+\sigma_{r}^2/2}]^2\)
finally
\(Var(R_{t}) = e^{2\mu_{r}+\sigma_{r}^2} (e^{\sigma_{r}^2}-1)\)
*http://computationalfinance.lsi.upc.edu
LS0tCnRpdGxlOiAiRklOQzYyMSBXaW50ZXIgMjAxOC0xOSBMYWIgV29ya3NoZWV0IDAzIgphdXRob3I6ICJUaXRpbG9wZSBPbHV0YXlvIgpkYXRlOiAiMTItMDUtMjAxOCIKb3V0cHV0OgogIGh0bWxfbm90ZWJvb2s6IGRlZmF1bHQKICBodG1sX2RvY3VtZW50OiBkZWZhdWx0CnN1YnRpdGxlOiBWYXJpYW5jZSwgQ292YXJpYW5jZSwgQ29ycmVsYXRpb24gJiBDYXVzYWxpdHkgKGZpbmM2MjEtbGFiMDMpCi0tLQoKIyMjIEFib3V0CgpJbiB0aGlzIHdvcmtzaGVldCB3ZSBsb29rIGF0IGRpZmZlcmVudCB2YXJpYW5jZSwgY292YXJpYW5jZSwgdm9sYXRpbGl0eSwgYW5kIGNhdXNhbGl0eSBjYWxjdWxhdGlvbnMuIFdlIGZpbmlzaCB3aXRoIGEgc2hvcnQgbWF0ZW1hdGljYWwgcHJvb2YgKG5vIFIgcmVxdWlyZWQpLiAgCgojIyMgU2V0dXAKClJlbWVtYmVyIHRvIGFsd2F5cyBzZXQgeW91ciB3b3JraW5nIGRpcmVjdG9yeSB0byB0aGUgc291cmNlIGZpbGUgbG9jYXRpb24uIEdvIHRvICdTZXNzaW9uJywgc2Nyb2xsIGRvd24gdG8gJ1NldCBXb3JraW5nIERpcmVjdG9yeScsIGFuZCBjbGljayAnVG8gU291cmNlIEZpbGUgTG9jYXRpb24nLiBSZWFkIGNhcmVmdWxseSB0aGUgYmVsb3cgYW5kIGZvbGxvdyB0aGUgaW5zdHJ1Y3Rpb25zIHRvIGNvbXBsZXRlIHRoZSB0YXNrcyBhbmQgYW5zd2VyIGFueSBxdWVzdGlvbnMuICBTdWJtaXQgeW91ciB3b3JrIHRvIFJQdWJzIGFzIGRldGFpbGVkIGluIHByZXZpb3VzIG5vdGVzLiAKCiMjIyBOb3RlCgpGb3IgY2xhcml0eSwgdGFza3MvcXVlc3Rpb25zIHRvIGJlIGNvbXBsZXRlZC9hbnN3ZXJlZCBhcmUgaGlnaGxpZ2h0ZWQgaW4gcmVkIGNvbG9yIChjb2xvciB2aXNpYmxlIG9ubHkgaW4gcHJldmlldyBtb2RlKSBhbmQgbnVtYmVyZWQgYWNjb3JkaW5nIHRvIHRoZWlyIHBhcnRpY3VsYXIgcGxhY2VtZW50IGluIHRoZSB0YXNrIHNlY3Rpb24uICBUeXBlIHlvdXIgYW5zd2VycyBvdXRzaWRlIHRoZSByZWQgY29sb3IgdGFncyEKClF1aXRlIG9mdGVuIHlvdSB3aWxsIG5lZWQgdG8gYWRkIHlvdXIgb3duIGNvZGUgY2h1bmsuIEV4ZWN1dGUgc2VxdWVudGlhbGx5IGFsbCBjb2RlIGNodW5rcywgcHJldmlldywgcHVibGlzaCwgYW5kIHN1Ym1pdCBsaW5rIG9uIFNha2FpIGZvbGxvd2luZyB0aGUgbmFtaW5nIGNvbnZlbnRpb24uIE1ha2Ugc3VyZSB0byBhZGQgY29tbWVudHMgdG8geW91ciBjb2RlIHdoZXJlIGFwcHJvcHJpYXRlLiBVc2Ugb3duIGxhbmd1YWdlIQoKKipBbnkgc2lnbiBvZiBwbGFnaWFyaXNtLCB3aWxsIHJlc3VsdCBpbiBkaXNzbWlzc2FsIG9mIHdvcmshKioKCi0tLS0tLS0tLS0tLS0tCgojIyMgVGFzayAxOiBWYXJpYW5jZSwgQ292YXJpYW5jZSwgYW5kIFZvbGF0aWxpdHkKClRoaXMgdGFzayBmb2xsb3dzIHRoZSB0d28gZXhhbXBsZXMgaW4gdGhlIGJvb2sgYFIgRXhhbXBsZSAyLjUvcC4gNThgIGFuZCBgUiBFeGFtcGxlIDIuNi9wLiA2NmAgCgpgYGB7cn0KIyBSZXF1aXJlIHdpbGwgbG9hZCB0aGUgcGFja2FnZSBvbmx5IGlmIG5vdCBpbnN0YWxsZWQgCiMgRGVwZW5kZW5jaWVzID0gVFJVRSBtYWtlcyBzdXJlIHRoYXQgZGVwZW5kZW5jaWVzIGFyZSBpbnN0YWxsCmlmKCFyZXF1aXJlKCJxdWFudG1vZCIscXVpZXRseSA9IFRSVUUpKQogIGluc3RhbGwucGFja2FnZXMoInF1YW50bW9kIixkZXBlbmRlbmNpZXMgPSBUUlVFLCByZXBvcyA9ICJodHRwczovL2Nsb3VkLnItcHJvamVjdC5vcmciKQpgYGAKCgo8c3BhbiBzdHlsZT0iY29sb3I6cmVkIj4KIyMjIyMgMUEpIENhbGN1bGF0ZSB0aGUgY29ycmVsYXRpb24gYW5kIGNvdmFyaWFuY2UgbWF0cml4IG9mIHRoZSBhZGp1c3RlZCBkYWlseSBsb2cgcmV0dXJucyBmb3IgZm91ciBkaWZmZXJlbnQgc3RvY2tzIG9mIHlvdXIgY2hvaWNlLiBFeHBsYWluIHlvdXIgb2JzZXJ2YXRpb25zIGluIHRlcm1zIG9mIHBvdGVudGlhbCByZWxhdGlvbnNoaXBzLgo8L3NwYW4+CgpgYGB7cn0KIyBPbmNlIHlvdSBoYXZlIG9idGFpbmVkIHRoZSBhZGp1c3RlZCBkYWlseSBsb2cgcmV0dXJucyBmb3IgeW91ciBzdG9ja3MsIG9taXR0aW5nIHRoZSB0aW1lIGluZGV4LCB5b3Ugd2lsbCBuZWVkIHRvIGNvbWJpbmUgdGhlbSB0byBjcmVhdGUgYSBtYXRyaXguIEJlbG93IGlzIGFuIGV4YW1wbGUuICBGb3IgbW9yZSBkZXRhaWxzIHNlZSB0aGUgSGVscCBjb21tYW5kIGluIFIgb24gY2JpbmQsIGNvdiwgYW5kIGNvci4KIyBNIDwtIGNiaW5kKEEsQixDKSAjIGNyZWF0ZSBhIG1hdHJpeCB3aGVyZSBlYWNoIGNvbHVtbiBpcyBhbiBhcnJheS92ZWN0b3Igb2YgbnVtZXJpY2FsIHZhbHVlcyAKIyBjb3YoTSkgIyBjb21wdXRlIHRoZSBjb3ZhcmlhbmNlIG1hdHJpeAojIGNvcihNLCBtZXRob2Q9InBlYXJzb24iKSAjIGNvbXB1dGUgdGhlIGNvcnJlbGF0aW9uIG1hdHJpeCBiYXNlZCBvbiB0aGUgUGVhcnNvbiBtZXRob2QKYGBgCmBgYHtyfQpsaWJyYXJ5KHF1YW50bW9kKQpzeW1ib2xzPWMoJ0JNTycsICdLUicsICdNU0ZUJywgJ1hPTScpCmdldFN5bWJvbHMoc3ltYm9scywgc3JjPSd5YWhvbycpCmJtb3JkID0gcGVyaW9kUmV0dXJuKEJNTywgcGVyaW9kID0gImRhaWx5IiwgdHlwZSA9ImxvZyIpCmtycmQgPSBwZXJpb2RSZXR1cm4oS1IsIHBlcmlvZCA9ICJkYWlseSIsIHR5cGUgPSJsb2ciKQptc2Z0cmQgPSBwZXJpb2RSZXR1cm4oTVNGVCwgcGVyaW9kID0gImRhaWx5IiwgdHlwZSA9ImxvZyIpCnhvbXJkID0gcGVyaW9kUmV0dXJuKFhPTSwgcGVyaW9kID0gImRhaWx5IiwgdHlwZSA9ImxvZyIpCgojI0NyZWF0aW5nIGEgbWF0cml4Ck0gPC0gY2JpbmQoYm1vcmQsa3JyZCxtc2Z0cmQseG9tcmQpCmNvbG5hbWVzKE0pIDwtIGMoJ0JNTycsICdLUicsICdNU0ZUJywgJ1hPTScpCgojIGNvbXB1dGUgdGhlIGNvdmFyaWFuY2UgbWF0cml4Cm9wdGlvbnMoc2NpcGVuPTk5OSkKY292KE0pCgojIGNvbXB1dGUgdGhlIGNvcnJlbGF0aW9uIG1hdHJpeCBiYXNlZCBvbiB0aGUgUGVhcnNvbiBtZXRob2QKY29yKE0pCgpgYGAKQm90aCBjb3ZhcmlhbmNlIGFuZCBjb3JyZWxhdGlvbiB0ZXN0cyBvZiB0aGUgZGFpbHkgbG9nIHJldHVybnMgb2YgQk1PLCBLUiwgTVNGVCAgYW5kIFhPTSBpbmRpY2F0ZSB2YXJpYWJsZXMgYXJlIHBvc2l0aXZlbHkgb3IgIHJlbGF0ZWQuIENvcnJlbGF0aW9uIGFsc28gdGVsbHMgdXMgYWJvdXQgdGhlIGRlZ3JlZSB0byB3aGljaCB0aGUgdmFyaWFibGVzIHRlbmQgdG8gbW92ZSB0b2dldGhlci5UaGUgY29ycmVsYXRpb24gcmFuZ2UgZnJvbSAwLjI5IGFuZCBhbmQgdGhlIGNvdmFyaWFuY2UgaXMgYWxzbyBncmVhdGVyIHRoYW4gMCB3aGljaCBzaG93cyB0aGVyZSBpcyBhIHN0cm9uZyByZWxhdGlvbnNoaXAgYmV0d2VlbiBzdG9ja3MKCjxzcGFuIHN0eWxlPSJjb2xvcjpyZWQiPgojIyMjIyAxQikgQ2FsY3VsYXRlIHRoZSB0aHJlZSB0eXBlcyBvZiB2b2xhdGlsaXR5IGZvciBhIHBhcnRpY3VsYXIgc3RvY2sgb2YgeW91ciBjaG9pY2UuIENvbnNpZGVyIGEgdGltZSB3aW5kb3cgZXh0ZW5kaW5nIG9uZSB5ZWFyIGJhY2sgZnJvbSBtb3N0IHJlY2VudCBvYnRhaW5hYmxlIGNsb3NpbmcgZGF5IHByaWNlLiBPcmRlciB0aGUgdGhyZWUgZXN0aW1hdGVzIGZyb20gbG93IHRvIGhpZ2ggdm9sYXRpbGl0eSBhbmQgZXhwbGFpbiBob3cgdGhlIG9yZGVyaW5nIG1ha2VzIHNlbnNlLgo8L3NwYW4+CgpgYGB7cn0KIyBGb3IgdGhpcyB0YXNrIG1ha2Ugc3VyZSB5b3UgdW5kZXJzdGFuZCB3ZWxsIHdoYXQgdGhlIHZhcmlhYmxlcyBuLG0gcmVwcmVzZW50IGluIHRoZSBib29rJ3MgcmVmZXJlbmNlZCBleGFtcGxlLgptc2Z0ID0gTVNGVFsnMjAxNy0xMi0wMy8yMDE4LTEyLTAzJ10KCk0gPSBsZW5ndGgobXNmdFssICJNU0ZULkNsb3NlIl0pCgpvaGxjIDwtIG1zZnRbLCBjKCJNU0ZULk9wZW4iLCAiTVNGVC5IaWdoIiwgIk1TRlQuTG93IiwgIk1TRlQuQ2xvc2UiKV0KCnZDbG9zZSA9IHZvbGF0aWxpdHkob2hsYywgbj0gTSwgY2FsYyA9ICJjbG9zZSIsIE49MjUyKQoKdlBhcmtpbnNvbiA9IHZvbGF0aWxpdHkob2hsYywgbj1NLCBjYWxjID0gInBhcmtpbnNvbiIsIE49MjUyKQoKdkdLID0gdm9sYXRpbGl0eShvaGxjLCBuPU0sIGNhbGMgPSAiZ2FybWFuIiwgTj0yNTIpCgp2Q2xvc2VbTV0KCnZQYXJraW5zb25bTV0KCnZHS1tNXQoKCmBgYApUaGUgZXN0aW1hdG9yIHNob3dzIHZvbGF0aWxpdHkgZm9yIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbiBhcyBmb2xsb3dzOgowLjIxOSBmb3IgR2FybWFuIEtsYXNzLCAwLjIyMiBmb3IgUGFya2luc29uIGFuZCB0aGUgaGlnaGVzdCAwLjI1OSBmb3IgY2xvc2UtY2xvc2UuVGhlIG9yZGVyaW5nIGlzIGJlY2F1c2UgUGFya2luc29uIGFzc3VtZWQgY29udGlub3VzIHRyYWRpbmcgYW5kIG9ubHkgY29uc2lkZXJzIGhpZ2ggYW5kIGxvdyBwcmljZXMgd2hlcmVhcyBHYXJtYW4gS2xhc3MgY29uc2lkZXJzIHRoZSBvcGVuIGFuZCBjbG9zZSB2YWx1ZXMuIEhlbmNlIHRoZSBvdmVyYWxsIHZvbGF0aWxpdHkgZm9yIHRoZSB5ZWFyIGFjY29yZGluZyB0byBHYXJtYW4ga2xhc3MgbW9kZWwgaXMgbGVzc2VyIHdoZW4gY29tcGFyZWQgdG8gUGFya2luc29uJ3MgbW9kZWwKCgojIyMgVGFzayAyOiBBdXRvLUNvcnJlbGF0aW9uIGFuZCBBdXRvLVJlZ3Jlc3Npb24KCkZvbGxvdyB0aGUgZXhhbXBsZSBpbiB0aGUgYm9vayAgYFIgRXhhbXBsZSAzLjIvcC4gNzRgIGFuZCBgUiBFeGFtcGxlIDQuMS9wLiAxMTVgCgo8c3BhbiBzdHlsZT0iY29sb3I6cmVkIj4KIyMjIyMgMkEpIENhbGN1bGF0ZSB0aGUgQUNGIGZvciBhIHN0b2NrIG9mIHlvdXIgY2hvaWNlLiBDb25zaWRlciBib3RoIHRoZSBsb2cgcmV0dXJuIGFuZCBzcXVhcmVkIGxvZyByZXR1cm4uIEludGVycHJldCB5b3VyIHJlc3VsdHMgaW4gdGVybXMgb2YgcG9zc2libGUgZXhpc3RlbmNlIG9mIGF1dG9jb3JyZWxhdGlvbi4gIAo8L3NwYW4+CgpgYGB7cn0KbGlicmFyeShxdWFudG1vZCkKYWNmKG5hLm9taXQoeG9tcmQpLCBtYWluID0gIkFDRiBPRiBYT00iLCB5bGltID0gYygtMC4yLCAwLjIpKQoKYWNmKG5hLm9taXQoeG9tcmQpXjIsIG1haW4gPSAiQUNGIE9GIFhPTSBTcXVhcmVkIGxvZyByZXR1cm4iLCB5bGltID0gYygtMC4zLCAwLjUpKQpgYGAKQXV0b2NvcnJlbGF0aW9uIHdpdGggZGFpbHkgbG9nIHJldHVybnMgZXhpc3RzIGV4aXN0cyBhdCBsYWcgMyw4LDE2IGFuZCAyMCBhbmQgbmVnYXRpdmUgYXV0b2NvcnJlbGF0aW9uIGV4aXN0cyBhdCBsYWcgMSwyLDcsMTcgYW5kIDE4ClRoZSByZXN1bHQgaW5kaWNhdGVzIHRoYXQgdGhlcmUgaXMgc29tZSBsaW5lYXIgZGVwZW5kZW5jZSBvZiB0aGUKdmFyaWFuY2Ugb2YgRXh4b24gTW9iaWwgd2l0aCBpdHMgcGFzdCB2YWx1ZXMuCgo8c3BhbiBzdHlsZT0iY29sb3I6cmVkIj4KIyMjIyMgMkIpIFBsb3QgdGhlIGV4Y2hhbmdlIHJhdGUgZm9yIFVTRCB2ZXJzdXMgYW5vdGhlciBjdXJyZW5jeSBvZiB5b3VyIGNob2ljZS4gSW50ZXJwcmV0IHlvdXIgcmVzdWx0cyBpbiB0ZXJtcyBvZiBiZWhhdmlvci4KPC9zcGFuPgpgYGB7cn0KZ2V0RlgoIlVTRC9OR04iKQoKcGxvdChVU0ROR04pCgpgYGAKVGhlIGdyYXBoIHNob3dzIGEgZmx1Y3R1YXRpb25nIHJlbGF0aW9uc2hpcCBiZXR3ZWVuIFVTRC9OR04saXQgZ29lcyBmcm9tIHJlYWxseSBsb3cgdG8gYXZlcmFnZSwgdGhlbiBsb3cgYWdhaW4gYnV0IGl0IHN0YXJ0ZWQgdG8gcmlzZSBhcyBmcm9tIHNlcHQgMjAxOC4KCgo8c3BhbiBzdHlsZT0iY29sb3I6cmVkIj4KIyMjIyMgMkMpIFRlc3QgZm9yIHRoZSBwb3NzaWJsZSBleGlzdGVuY2Ugb2YgYW4gdW5kZXJseWluZyBBUigxKSDigJMgTWFya292IHByb2Nlc3MgaW4geW91ciBleGNoYW5nZSByYXRlIGN1cnJlbmN5IHBhaXIuIFRvIHRoaXMgZW5kLCBwbG90IHRoZSBBQ0YgYW5kIHRoZSBwYXJ0aWFsIEFDRiAoUEFDRikuIEludGVycHJldCB5b3VyIHJlc3VsdHMuICBDbGVhcmx5IHJlZmVyIHRvIHRoZSBsYWdzLCBhbmQgdGhlaXIgaW1wYWN0cyBpbiBkZXRlcm1pbmluZyB0aGUgb3JkZXIuCjwvc3Bhbj4KCmBgYHtyfQphY2YoVVNETkdOKQoKcGFjZihVU0ROR04pCmBgYApUSEUgQUNGIHNob3dzIGEgc2xvdyBleHBvbmVudGlhbCBkZWNheSBmb3Igc3VjY2Vzc2l2ZQpsYWdzLCBoZW5jZSByZXZlYWxpbmcgdGhhdCB0aGUgc2VyaWVzIFVTRC9OR04gZG9lcyBiZWhhdmVzIGFzIGFuIEFSKDEpIHByb2Nlc3MuCgojIyMgVGFzayAzOiBHcmFuZ2VyIENhdXNhbGl0eSBUZXN0CgpUbyBjb25kdWN0IHRoaXMgdGVzdCB0aGUgcGFja2FnZSBgbG10ZXN0YCB3aWxsIGJlIHJlcXVpcmVkLCBhcyBhbHJlYWR5IGRvbmUgaW4gdGhlIGNvZGUgY2h1bmsgYmVsb3cuCgpgYGB7cn0KIyBSZXF1aXJlIHdpbGwgbG9hZCB0aGUgcGFja2FnZSBvbmx5IGlmIG5vdCBpbnN0YWxsZWQgCiMgRGVwZW5kZW5jaWVzID0gVFJVRSBtYWtlcyBzdXJlIHRoYXQgZGVwZW5kZW5jaWVzIGFyZSBpbnN0YWxsCmlmKCFyZXF1aXJlKCJsbXRlc3QiLHF1aWV0bHkgPSBUUlVFKSkKICBpbnN0YWxsLnBhY2thZ2VzKCJsbXRlc3QiLGRlcGVuZGVuY2llcyA9IFRSVUUsIHJlcG9zID0gImh0dHBzOi8vY2xvdWQuci1wcm9qZWN0Lm9yZyIpCmBgYAoKPHNwYW4gc3R5bGU9ImNvbG9yOnJlZCI+CiMjIyMjIDNBKSBJbmNsdWRlIGJlbG93IHRoZSBjb2RlIGNodW5rIHRvIHNvbHZlIGZvciAzLjUuNyBSIExhYi9wLiAxMDYuICBXcml0ZSB5b3VyIGNvbmNsdXNpb25zLgo8L3NwYW4+CgpgYGB7cn0KIyBNb3JlIGluZm9ybWF0aW9uIGFib3V0IHRoZSBkYXRhIHVzZWQgaW4gdGVzdGluZyBmb3IgY2F1c2FsaXR5IGNhbiBiZSBvYnRhaW5lZCBieSB0eXBpbmcgdGhlIG5hbWUgb2YgdGhlIGRhdGEgc2V0IGBDaGlja0VnZ2BgQ2hpY2tFZ2dgIGluIHRoZSBSIEhlbHAgbWVudS4KCmdyYW5nZXJ0ZXN0KGVnZyB+ICBjaGlja2VuLCBvcmRlciA9IDMsIGRhdGEgPSBDaGlja0VnZykKZ3JhbmdlcnRlc3QoY2hpY2tlbn5lZ2csIG9yZGVyID0gMywgZGF0YT1DaGlja0VnZykKYGBgCgpUaGUgZmlyc3QgR3JhbmdlciBjYXVzYWxpdHkgdGVzdCBpcyB0ZXN0aW5nIHdoZXRoZXIgdGhlIGNoaWNrZW4gY2F1c2VzIHRoZSBlZ2cuIFRoZSBudWxsIGh5cG90aGVzaXMgaXMgdGhlIGNoaWNrZW4gZG9lcyBub3QgY2F1c2UgdGhlIGVnZy4gVGhlIHAtdmFsdWUgaXMgMC42MjM4IGFuZCB0aGUgY3JpdGljYWwgdmFsdWUgaXMgMC4wNS4gVGhpcyBtZWFucyB0aGF0IHRoZSBwLXZhbHVlIGlzIGhpZ2hlciB0aGFuIHRoZSBjcml0aWNhbCB2YWx1ZS4gSGVuY2UsIEkgZG8gbm90IHJlamVjdCB0aGUgbnVsbCBoeXBvdGhlc2lzLiBJbiBjb25jbHVzaW9uLCB0aGUgY2hpY2tlbiBkb2VzIG5vdCBjYXVzZSB0aGUgZWdnCgpUaGUgc2Vjb25kIEdyYW5nZXIgY2F1c2FsaXR5IHRlc3QgaXMgdGVzdGluZyB3aGV0aGVyIHRoZSBlZ2cgY2F1c2VzIHRoZSBjaGlja2VuLiBUaGUgbnVsbCBIeXBvdGhlbnVzIGlzIHRoZSBlZ2cgZG9lcyBub3QgY2F1c2UgY2hpY2tlbi4gVGhlIHAtdmFsdWUgaXMgMC4wMDI5NjYgYW5kIHRoZSBjcml0aWNhbCB2YWx1ZSBpcyAwLjA1LlRoaXMgbWVhbnMgdGhhdCB0aGUgcC12YWx1ZSBpcyBsZXNzIHRoYW4gdGhlIGNyaXRpY2FsIHZhbHVlLiBIZW5jZSwgSSByZWplY3QgdGhlIG51bGwgaHlwb3RoZXNpcy4gSW4gY29uY2x1c2lvbiwgdGhlIGVnZyBjYXVzZXMgdGhlIGNoaWNrZW4KCjxzcGFuIHN0eWxlPSJjb2xvcjpyZWQiPgojIyMjIyAzQikgQnJpZWZseSBkZXNjcmliZSB0aGUgZGF0YSBpbiB0ZXJtcyBvZiB0aW1lIHJhbmdlIGFuZCB2YXJpYWJsZXMuIFNpbWlsYXIgdG8gdGhlIGxpbmVhciBhdXRvZWdyZXNzaXZlIG1vZGVsIGRlc2NyaWJlZCBpbiBjbGFzcywgd3JpdGUgdGhlIG1hdGhlbWF0aWNhbCByZWdyZXNzaW9uIG1vZGVsIHNvbHZlZCBpbiBlYWNoIEdyYW5nZXIgdGVzdCwgaW5jbHVkaW5nIHRoZSBwcm9wZXIgb3JkZXIuIFVzZSBuYW1pbmcgY29udmVudGlvbnMsIGFuZCBub3RhdGlvbnMgbW9yZSByZWZsZWN0aXZlIG9mIHRoZSBkYXRhIHNldCBjb25zaWRlcmVkIGZvciAgYENoaWNrRWdnYC4KPC9zcGFuPgoKVGhlIGRhdGEoQ2hpY2tFZ2cpIGNvbnRhaW5zIHRoZSBhbm51YWwgcHJvZHVjdGlvbiBvZiBjaGlja2VuIGFuZCBlZ2dzIGZyb20gdGhlIHBlcmlvZCBvZiAxOTgwIHRvIDE5ODMuCgpUaGUgR3JhbmdlciB0ZXN0IHVzZXMgdGhlIGJpdmFyaWF0ZSBsaW5lYXIgYXV0b3JlZ3Jlc3NpdmUgbW9kZWwgb24gdHdvIHZhcmlhYmxlcyhlZ2cgYW5kIGNoaWNrZW4pCgpUaGUgcmVncmVzc2lvbiBtb2RlbCB1c2VkIGluIHRoZSBncmFuZ2VyIHRlc3QgaXMKJFlfe3R9PSBhX3swfSArIGFfezF9WV97dC0xfSArIGFfezJ9WV97dC0yfSArIGFfezN9WV97dC0zfSArIGJfezF9WF97dC0xfSArIGJfezJ9WF97dC0yfSArIGJfezN9WF97dC0zfSArIFx2YXJlcHNpbG9uX3t0fSQKCkZvciB0aGUgZmlyc3QgdGVzdDogd2hldGhlciBjaGlja2VuIGNhdXNlcyBlZ2csIHRoZSByZWdyZXNzaW9uIG1vZGVsIGlzOgokRWdnX3t0fT0gYV97MH0gKyBhX3sxfUVnZ197dC0xfSArIGFfezJ9RWdnX3t0LTJ9ICsgYV97M31FZ2dfe3QtM30gKyBiX3sxfUNoaWNrZW5fe3QtMX0gKyBiX3syfUNoaWNrZW5fe3QtMn0gKyBiX3szfUNoaWNrZW5fe3QtM30gKyBcdmFyZXBzaWxvbl97dH0kCgpUaGUgbnVsbCBoeXBvdGhlc2lzIHRlc3RlZCBpcyAkSF97MH09IGJfezF9ID0gYl97Mn0gPSBiX3szfSA9IDAkCgoKRm9yIHRoZSBzZWNvbmQgdGVzdDogd2hldGhlciBlZ2cgY2F1c2VzIGNoaWNrZW4sIHRoZSByZWdyZXNzaW9uIG1vZGVsIGlzOiAKCiRDaGlja2VuX3t0fT0gYV97MH0gKyBhX3sxfUNoaWNrZW5fe3QtMX0gKyBhX3syfUNoaWNrZW5fe3QtMn0gKyBhX3szfUNoaWNrZW5fe3QtM30gKyBiX3sxfUVnZ197dC0xfSArIGJfezJ9RWdnX3t0LTJ9ICsgYl97M31FZ2dfe3QtM30gKyBcdmFyZXBzaWxvbl97dH0kCgpUaGUgbnVsbCBoeXBvdGhlc2lzIHRlc3RlZCBpcyAkSF97MH09IGJfezF9ID0gYl97Mn0gPSBiX3szfSA9IDAkIAoKIyMjIFRhc2sgNDogTWF0aGVtYXRpY2FsIFByb29mCgo8c3BhbiBzdHlsZT0iY29sb3I6cmVkIj4KIyMjIyMgNEEpIFByb3ZlIHRoZSB0d28gcmVzdWx0cyBpbiBFcSAoMi4zMikvcC4gNTMuICBObyBSLWNvZGluZyBpcyBuZWVkZWQgaGVyZS4gIENsZWFybHkgc2hvdyB5b3VyIHN0ZXBzLiBIaW50OiBVc2UgdGhlIGRlZmluaXRpb24gb2YgJEUoWF5uKSQgZm9yIFgtbG9nIG5vcm1hbGx5IGRpc3RyaWJ1dGVkLiAgIE9ic2VydmUgYWxzbyB0aGF0ICRWYXIoWCkgPSBFKFheMiktRV4yKFgpJCBmb3IgYW55IHJhbmRvbSB2YXJpYWJsZSBYLgo8L3NwYW4+CgpUaGUgZGVmaW5pdGlvbiBvZiB0aGUgbW9ubWVudHMgb24gdmFyaWFibGUgeDoKCiRFKFhebikgPSBleHAoblxtdSArXGZyYWN7MX17Mn1uXjIgXHNpZ21hXjIgKSAsIG4+MCQKCgpJZiB3ZSBoYXZlIGEgc2ltcGxlIHJldHVybiBzZXJpZXMgJFJfe3R9JCB3aGljaCBpcyBsb2cgbm9ybWFsbHkgZGlzdHJpYnV0ZWQgd2l0aCBtZWFuICRcbXVfe1J9JCBhbmQgdmFyaWFuY2UgJFxzaWdtYV97Un1eMiQsIHNvIHRoYXQgdGhlIGxvZyByZXR1cm4gc2VyaWVzICRSX3t0fSQgaXMgJHJfe3R9ID0gbG4oUl97dH0rMSkkIH4gJE4oXG11X3tyfSwgXHNpZ21hX3tyfV4yKSQKClNvbHZpbmcgZm9yICRSX3t0fSQsIHdlIGdldAoKJFJfe3R9KzEgPSBlXntyX3t0fX0kCgogJFxtdV97cn0rXHNpZ21hX3tyfSQgd2UgZ2V0IGFuIDFzdCBtb21lbnQgb2YgJFJfe3R9JDsKClRoZSBmb3JtdWxhIGZvciB0aGUgZmlyc3QgbW9tZW50IGlzIAokRShSX3t0fSk9IFxtdV97Un0gPSBlXntcbXVfe3J9K1xzaWdtYV97cn1eMi8yfS0xJAoKCkZvciB0aGUgc2Vjb25kIG1vbWVudCwgd2UgY2FuIGdldCBpdCBieSB1c2luZyB0aGUgdmFyaWFuY2UgZm9ybXVsYSAKJFZhcihYKSA9IEUoWF4yKS1FXjIoWCkkCgpTTywgdGhlIGZvcm11bGEgZm9yIHRoZSBzZWNvbmQgbW9tZW50IGlzOgoKJFZhcihSX3t0fSkgPSBlXnsyXG11X3tyfSsyXHNpZ21hX3tyfV4yfS0gW2Vee1xtdV97cn0rXHNpZ21hX3tyfV4yLzJ9XV4yJAoKZmluYWxseQoKJFZhcihSX3t0fSkgPSBlXnsyXG11X3tyfStcc2lnbWFfe3J9XjJ9IChlXntcc2lnbWFfe3J9XjJ9LTEpJAoKCgoqW2h0dHA6Ly9jb21wdXRhdGlvbmFsZmluYW5jZS5sc2kudXBjLmVkdSBdKGh0dHA6Ly9jb21wdXRhdGlvbmFsZmluYW5jZS5sc2kudXBjLmVkdSkK