Installation of the Libraries
Libraries
If making the financial analysis of the stock exchange data, the
following packages are highly popular:
- quantmod
- PerformanceAnalytics
- tidyquant
#install.packages("PerformanceAnalytics", repos = "http://cran.us.r-project.org")
#install.packages("dplyr", repos = "http://cran.us.r-project.org")
#install.packages("tidyquant", repos = "http://cran.us.r-project.org")
#install.packages("quantmod", repos = "http://cran.us.r-project.org")
#install.packages("tseries", repos = "http://cran.us.r-project.org")
#install.packages("tidyverse", repos = "http://cran.us.r-project.org")
library(PerformanceAnalytics) #useful package !!!
library(quantmod) # useful package
library(tidyquant) # useful
# other libraries
library(ggplot2)
library(dplyr)
library(tseries)
library(tidyverse)
library(plotly)
library(hrbrthemes)
library(xts)
library(knitr)
library(kableExtra)
library(car)
library(mathjaxr)
library(zoo)
rm(list=ls())
Data download
If downloading the stock-exchange data, we use the quantmod package
command “getSymbols”. COmmand “Ad” enables extraction of just Adjusted
closing prices of the day.
symbol_name <<- c("AAPL", "GOOG", "AMZN", "F", "T", "TQQQ")
#symbol_name <- "AAPL"
for (i in 1:length(symbol_name)) {
prac <<- Ad(getSymbols(symbol_name[i], from = "2020-01-01", to = "2022-12-31",auto.assign=FALSE))
if (i==1) {
price <<-prac
} else{
price <<- merge(price,prac)
}
}
rm(prac) # prac is just temporary variable to remove
colnames(price) <- symbol_name #puting the names of the shares
Analysis of one asset
In the above, we learned downloading of the adjusted closing prices.
Now, take the first asset from the “symbol_name” and make a picture. We
learly see that the stochastic properties of the assets coming from the
two different periods significantly differ.
title <- paste(symbol_name[1], "Share" )
dolna_hranica <<- "2020-07-01"
horna_hranica <<- "2022-07-01"
#data(sample_matrix)
#sample.xts <- as.xts(price[,1])
events <- xts(c(" "," "),as.Date(c(dolna_hranica, horna_hranica)))
plot(price[,1], col="red", main=title)

addEventLines(events, srt=90, pos=2,col="blue")

The differences of the stochastic properties of the stock prices
originating from 2 different preiods, we can depict also making some
basic descriptive statistics.
subT_D <<- price["2020-01-01/2020-07-01",1]
subT_H <<- price["2022-07-01/2022-12-28",1]
# Get summary statistics using summary() function
summary_data <- summary(data.frame(cbind(subT_D,subT_H)))
summary_data <- summary_data[1:6,]
# Convert summary statistics to a table using kable()
colnames(summary_data) <- c("1st period","2nd period")
summary_data
1st period 2nd period
Min. :55.00 Min. :125.8
1st Qu.:69.33 1st Qu.:142.7
Median :75.70 Median :149.0
Mean :74.21 Mean :149.9
3rd Qu.:78.59 3rd Qu.:155.3
Max. :90.09 Max. :174.0
#summary_table <- kable(summary_data)
# Customize the table using kableExtra package
#summary_table %>%
# kable_styling(full_width = FALSE) %>%
# add_header_above(c("Summary Statistics" = 3))
Conversion of the level data time series to the returns
Previous empirical experience lead to the conclusion that the
underlying probability distribution of the prices \(f_t(P) <> f_{t \pm i}(P)\) that
means, the underlying time series is not stationary. That is, why we are
unable to use the tools of the probability theory. The economists solve
the problem by taking the capital asset price returns, i.e.
\[r_t = \frac{\Delta
P_t}{P_{t-1}}\] where \(\Delta P_t =
P_t - P_{t-1}\). Osborne came with an alternative formulation of
the returns as \[r_t = \ln(P_t) -
ln(P_{t-1}).\]
At first, look at the stochastic properties of the returns,
i.e. compare their means and values recorded in two researched
periods.
return_l <<- CalculateReturns(price, method="log")
return_p <- CalculateReturns(price, method="discrete")
for(i in 1:dim(return_l)[2]){ #imputation of the missing data
return_l[,i][is.na(return_l[,i])] <- median(return_l[,i],na.rm = TRUE)
}
for(i in 1:dim(return_p)[2]){ #imputation of the missing data
return_p[,i][is.na(return_p[,i])] <- median(return_p[,i],na.rm = TRUE)
}
subT_Dr_p <<- return_p["2020-01-01/2020-07-01",1] #Rozdelenie return_p na dva podsubory
subT_Hr_p <<- return_p["2022-07-01/2022-12-28",1]
# graphing just the firs share
title <- paste(symbol_name[1], "Share" )
events <- xts(c(" "," "),as.Date(c(dolna_hranica, horna_hranica)))
plot(return_p[,1], col="red", main=title)

addEventLines(events, srt=90, pos=2,col="blue")

# Get summary statistics using summary() function
summary_data <- summary(data.frame(cbind(subT_Dr_p,subT_Hr_p)))
summary_data <- summary_data[1:6,]
# Convert summary statistics to a table using kable()
colnames(summary_data) <- c("1st period","2nd period")
summary_data
1st period 2nd period
Min. :-0.12865 Min. :-0.05868
1st Qu.:-0.01154 1st Qu.:-0.01458
Median : 0.00148 Median :-0.00195
Mean : 0.00212 Mean :-0.00038
3rd Qu.: 0.01876 3rd Qu.: 0.01297
Max. : 0.11981 Max. : 0.08897
#summary_table <- kable(summary_data)
# Customize the table using kableExtra package
#summary_table %>%
# kable_styling(full_width = FALSE) %>%
# add_header_above(c("Summary Statistics" = 3))
The distribution seems to be equally distributed. At least, let us
test the equality of the mean returns as follows
\[H_0: M_{1st Period} = M_{2nd
Period}\]
against
\[H_1: M_{1st Period} \neq M_{2nd
Period},\] and also
\[H_0: \sigma^2_{1st Period} =
\sigma^2_{2nd Period}\]
against
\[H_1: \sigma^2_{1st Period} \neq
\sigma^2_{2nd Period},\]
resultM <<- wilcox.test(as.vector(subT_Dr_p), as.vector(subT_Hr_p))
# Perform Welch's test
resultSigma <<- var.test(as.vector(subT_Dr_p), as.vector(subT_Hr_p))
resultM
Wilcoxon rank sum test with continuity correction
data: as.vector(subT_Dr_p) and as.vector(subT_Hr_p)
W = 8575, p-value = 0.2239
alternative hypothesis: true location shift is not equal to 0
resultSigma
F test to compare two variances
data: as.vector(subT_Dr_p) and as.vector(subT_Hr_p)
F = 2.1779, num df = 125, denom df = 124, p-value = 1.881e-05
alternative hypothesis: true ratio of variances is not equal to 1
95 percent confidence interval:
1.530087 3.099320
sample estimates:
ratio of variances
2.177942
The p-value of the Wilcoxon test is 0.2238738 , while the result of
the F test of the equal variances is 1.88054^{-5}.
Normally distributed returns?
Many theories (Markowitz, Black Schole, VaR) assume the normal
distribution of the data. In reality, the assumption is often violated
and the real distribution has have tails if comparing to the normal
distribution. See result of the following Jarque-Berra normality
test
test_result <- jarque.bera.test(price[,1])
print(test_result)
Jarque Bera Test
data: price[, 1]
X-squared = 56.844, df = 2, p-value = 4.534e-13
Histograms
dev.new() # new Plot
par(mfrow=c(2,3)) # arrange plots in a 3x2 grid
for(i in 1:dim(return_p)[2]){ # iterate through each symbol
etf = return_p[,i] # load data into temp variable
colnames( etf ) = colnames(return_p[,i]) # data header as the ticker
chart.Histogram( etf, main=paste(" Return Distribution"),
breaks=15, methods=c("add.normal"), # Add the normal curve, and the VaR levels
colorset=c("steelblue", "darkgreen", "navy") # colors for each (middle color not used)
)
}

NA
NA
chart.Histogram( return_p[,1], main= paste(" Return Distribution of ",colnames(return_p[,1])),
breaks=15, methods=c("add.normal", "add.risk"), # Add the normal curve, and the VaR levels
colorset=c("steelblue", "darkgreen", "navy") # colors for each (middle color not used)
)

Correlation structure of the portfolio assets
If speaking about facing the risks, the effective diversification of
the investment is needed. In this way, we can reduce the unsystemic
risks. See the correlations in our hypotetical portfolio in the
following Figure.
#chart.Correlation(return_p[2:ncol(return_p)])
chart.Correlation(return_p)

Estimation of the variance-covariance matrix of the portfolio
returns
Variance - covariance matrix is a cetral topic of the portfolio
theory. It containes the return variances on the main diagonal, while
besides there are the covariances. If speaking about the correlation
matrix, then the diagonal terms are 1’s and out of the diagonal, there
are the corresponding correlations.
var_covar_p <- cov(return_p)
var_covar_p
AAPL GOOG AMZN F T TQQQ
AAPL 0.0005405816 0.0003660638 0.0003793896 0.0003066270 0.0001693079 0.0011384589
GOOG 0.0003660638 0.0004681645 0.0003637674 0.0002879402 0.0001535278 0.0010263473
AMZN 0.0003793896 0.0003637674 0.0006053833 0.0002239328 0.0001049222 0.0010747271
F 0.0003066270 0.0002879402 0.0002239328 0.0009734113 0.0002524982 0.0008633685
T 0.0001693079 0.0001535278 0.0001049222 0.0002524982 0.0003164058 0.0004406637
TQQQ 0.0011384589 0.0010263473 0.0010747271 0.0008633685 0.0004406637 0.0030440217
LS0tCnRpdGxlOiAiQ2FwaXRhbCByZXR1cm5zIgpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sKbGF0ZXhfZW5naW5lOiB4ZWxhdGV4CmhlYWRlci1pbmNsdWRlczoKICAtIFx1c2VwYWNrYWdle2Ftc21hdGh9CiAgLSBcdXNlcGFja2FnZXthbXNzeW1ifQplZGl0b3Jfb3B0aW9uczogCiAgbWFya2Rvd246IAogICAgd3JhcDogNzIKLS0tCgojIyMgSW5zdGFsbGF0aW9uIG9mIHRoZSBMaWJyYXJpZXMKCmBgYHtyIHNldHVwLCBpbmNsdWRlPUZBTFNFfQppbnN0YWxsLnBhY2thZ2VzKHRpbnl0ZXgpCmxpYnJhcnkodGlueXRleCkKa25pdHI6Om9wdHNfY2h1bmskc2V0KGVjaG8gPSBUUlVFKQpgYGAKCgpgYGB7ciwgZWNobz1GQUxTRX0Kb3B0aW9ucyh0aW55dGV4Lm1hdGhqYXggPSBUUlVFKQpgYGAKCiMjIExpYnJhcmllcwoKSWYgbWFraW5nIHRoZSBmaW5hbmNpYWwgYW5hbHlzaXMgb2YgdGhlIHN0b2NrIGV4Y2hhbmdlIGRhdGEsIHRoZSBmb2xsb3dpbmcgcGFja2FnZXMgYXJlIGhpZ2hseSBwb3B1bGFyOgoKMS4gcXVhbnRtb2QKMi4gUGVyZm9ybWFuY2VBbmFseXRpY3MKMy4gdGlkeXF1YW50ICAKCmBgYHtyIGxpYnJhcmllc30KI2luc3RhbGwucGFja2FnZXMoIlBlcmZvcm1hbmNlQW5hbHl0aWNzIiwgcmVwb3MgPSAiaHR0cDovL2NyYW4udXMuci1wcm9qZWN0Lm9yZyIpCiNpbnN0YWxsLnBhY2thZ2VzKCJkcGx5ciIsIHJlcG9zID0gImh0dHA6Ly9jcmFuLnVzLnItcHJvamVjdC5vcmciKQojaW5zdGFsbC5wYWNrYWdlcygidGlkeXF1YW50IiwgcmVwb3MgPSAiaHR0cDovL2NyYW4udXMuci1wcm9qZWN0Lm9yZyIpCiNpbnN0YWxsLnBhY2thZ2VzKCJxdWFudG1vZCIsIHJlcG9zID0gImh0dHA6Ly9jcmFuLnVzLnItcHJvamVjdC5vcmciKQojaW5zdGFsbC5wYWNrYWdlcygidHNlcmllcyIsIHJlcG9zID0gImh0dHA6Ly9jcmFuLnVzLnItcHJvamVjdC5vcmciKQojaW5zdGFsbC5wYWNrYWdlcygidGlkeXZlcnNlIiwgcmVwb3MgPSAiaHR0cDovL2NyYW4udXMuci1wcm9qZWN0Lm9yZyIpCgoKCmxpYnJhcnkoUGVyZm9ybWFuY2VBbmFseXRpY3MpICAjdXNlZnVsIHBhY2thZ2UgISEhCmxpYnJhcnkocXVhbnRtb2QpICAgICAgICAgICAgICAjIHVzZWZ1bCBwYWNrYWdlCmxpYnJhcnkodGlkeXF1YW50KSAgICAgICAgICAgICAjIHVzZWZ1bAoKIyBvdGhlciBsaWJyYXJpZXMKCmxpYnJhcnkoZ2dwbG90MikKbGlicmFyeShkcGx5cikKCmxpYnJhcnkodHNlcmllcykKbGlicmFyeSh0aWR5dmVyc2UpCmxpYnJhcnkocGxvdGx5KQpsaWJyYXJ5KGhyYnJ0aGVtZXMpCmxpYnJhcnkoeHRzKQpsaWJyYXJ5KGtuaXRyKQpsaWJyYXJ5KGthYmxlRXh0cmEpCmxpYnJhcnkoY2FyKQpsaWJyYXJ5KG1hdGhqYXhyKQpsaWJyYXJ5KHpvbykKcm0obGlzdD1scygpKQpgYGAKCiMjIERhdGEgZG93bmxvYWQKCklmIGRvd25sb2FkaW5nIHRoZSBzdG9jay1leGNoYW5nZSBkYXRhLCB3ZSB1c2UgdGhlIHF1YW50bW9kIHBhY2thZ2UgY29tbWFuZCAiZ2V0U3ltYm9scyIuIENPbW1hbmQgIkFkIiBlbmFibGVzIGV4dHJhY3Rpb24gb2YganVzdCBBZGp1c3RlZCBjbG9zaW5nIHByaWNlcyBvZiB0aGUgZGF5LgoKYGBge3IgZG93bmxvYWRfZGF0YSwgbWVzc2FnZT1GQUxTRX0Kc3ltYm9sX25hbWUgPDwtIGMoIkFBUEwiLCAiR09PRyIsICJBTVpOIiwgIkYiLCAiVCIsICJUUVFRIikKI3N5bWJvbF9uYW1lIDwtICJBQVBMIgoKZm9yIChpIGluIDE6bGVuZ3RoKHN5bWJvbF9uYW1lKSkgewogIHByYWMgPDwtIEFkKGdldFN5bWJvbHMoc3ltYm9sX25hbWVbaV0sIGZyb20gPSAiMjAyMC0wMS0wMSIsIHRvID0gIjIwMjItMTItMzEiLGF1dG8uYXNzaWduPUZBTFNFKSkKICBpZiAoaT09MSkgewogICAgcHJpY2UgPDwtcHJhYwogIH0gZWxzZXsKICAgIHByaWNlIDw8LSBtZXJnZShwcmljZSxwcmFjKQogIH0KfQpybShwcmFjKSAgICAjIHByYWMgaXMganVzdCB0ZW1wb3JhcnkgdmFyaWFibGUgdG8gcmVtb3ZlCmNvbG5hbWVzKHByaWNlKSA8LSBzeW1ib2xfbmFtZSAgI3B1dGluZyB0aGUgbmFtZXMgb2YgdGhlIHNoYXJlcwpgYGAKCiMjIEFuYWx5c2lzIG9mIG9uZSBhc3NldAoKSW4gdGhlIGFib3ZlLCB3ZSBsZWFybmVkIGRvd25sb2FkaW5nIG9mIHRoZSBhZGp1c3RlZCBjbG9zaW5nIHByaWNlcy4gTm93LCB0YWtlIHRoZSBmaXJzdCBhc3NldCBmcm9tIHRoZSAic3ltYm9sX25hbWUiIGFuZCBtYWtlIGEgcGljdHVyZS4gV2UgbGVhcmx5IHNlZSB0aGF0IHRoZSBzdG9jaGFzdGljIHByb3BlcnRpZXMgb2YgdGhlIGFzc2V0cyBjb21pbmcgZnJvbSB0aGUgdHdvIGRpZmZlcmVudCBwZXJpb2RzIHNpZ25pZmljYW50bHkgZGlmZmVyLiAKCmBgYHtyfQp0aXRsZSA8LSBwYXN0ZShzeW1ib2xfbmFtZVsxXSwgIlNoYXJlIiApIApkb2xuYV9ocmFuaWNhIDw8LSAiMjAyMC0wNy0wMSIKaG9ybmFfaHJhbmljYSA8PC0gIjIwMjItMDctMDEiCiNkYXRhKHNhbXBsZV9tYXRyaXgpCiNzYW1wbGUueHRzIDwtIGFzLnh0cyhwcmljZVssMV0pCmV2ZW50cyA8LSB4dHMoYygiICIsIiAiKSxhcy5EYXRlKGMoZG9sbmFfaHJhbmljYSwgaG9ybmFfaHJhbmljYSkpKQpwbG90KHByaWNlWywxXSwgY29sPSJyZWQiLCBtYWluPXRpdGxlKQphZGRFdmVudExpbmVzKGV2ZW50cywgc3J0PTkwLCBwb3M9Mixjb2w9ImJsdWUiKQpgYGAKClRoZSBkaWZmZXJlbmNlcyBvZiB0aGUgc3RvY2hhc3RpYyBwcm9wZXJ0aWVzIG9mIHRoZSBzdG9jayBwcmljZXMgb3JpZ2luYXRpbmcgZnJvbSAyIGRpZmZlcmVudCBwcmVpb2RzLCB3ZSBjYW4gZGVwaWN0IGFsc28gbWFraW5nIHNvbWUgYmFzaWMgZGVzY3JpcHRpdmUgc3RhdGlzdGljcy4KCmBgYHtyfQpzdWJUX0QgPDwtIHByaWNlWyIyMDIwLTAxLTAxLzIwMjAtMDctMDEiLDFdCnN1YlRfSCA8PC0gcHJpY2VbIjIwMjItMDctMDEvMjAyMi0xMi0yOCIsMV0KCiMgR2V0IHN1bW1hcnkgc3RhdGlzdGljcyB1c2luZyBzdW1tYXJ5KCkgZnVuY3Rpb24Kc3VtbWFyeV9kYXRhIDwtIHN1bW1hcnkoZGF0YS5mcmFtZShjYmluZChzdWJUX0Qsc3ViVF9IKSkpCnN1bW1hcnlfZGF0YSA8LSBzdW1tYXJ5X2RhdGFbMTo2LF0KCiMgQ29udmVydCBzdW1tYXJ5IHN0YXRpc3RpY3MgdG8gYSB0YWJsZSB1c2luZyBrYWJsZSgpCmNvbG5hbWVzKHN1bW1hcnlfZGF0YSkgPC0gYygiMXN0IHBlcmlvZCIsIjJuZCBwZXJpb2QiKQpzdW1tYXJ5X2RhdGEKCiNzdW1tYXJ5X3RhYmxlIDwtIGthYmxlKHN1bW1hcnlfZGF0YSkKCiMgQ3VzdG9taXplIHRoZSB0YWJsZSB1c2luZyBrYWJsZUV4dHJhIHBhY2thZ2UKI3N1bW1hcnlfdGFibGUgJT4lCiMgIGthYmxlX3N0eWxpbmcoZnVsbF93aWR0aCA9IEZBTFNFKSAlPiUKIyAgYWRkX2hlYWRlcl9hYm92ZShjKCJTdW1tYXJ5IFN0YXRpc3RpY3MiID0gMykpCmBgYAoKIyMgQ29udmVyc2lvbiBvZiB0aGUgbGV2ZWwgZGF0YSB0aW1lIHNlcmllcyB0byB0aGUgcmV0dXJucwoKUHJldmlvdXMgZW1waXJpY2FsIGV4cGVyaWVuY2UgbGVhZCB0byB0aGUgY29uY2x1c2lvbiB0aGF0IHRoZSB1bmRlcmx5aW5nIHByb2JhYmlsaXR5IGRpc3RyaWJ1dGlvbiBvZiB0aGUgcHJpY2VzICRmX3QoUCkgPD4gZl97dCBccG0gaX0oUCkkIHRoYXQgbWVhbnMsIHRoZSB1bmRlcmx5aW5nIHRpbWUgc2VyaWVzIGlzIG5vdCBzdGF0aW9uYXJ5LiBUaGF0IGlzLCB3aHkgd2UgYXJlIHVuYWJsZSB0byB1c2UgdGhlIHRvb2xzIG9mIHRoZSBwcm9iYWJpbGl0eSB0aGVvcnkuIFRoZSBlY29ub21pc3RzIHNvbHZlIHRoZSBwcm9ibGVtIGJ5IHRha2luZyB0aGUgY2FwaXRhbCBhc3NldCBwcmljZSByZXR1cm5zLCBpLmUuCgokJHJfdCA9IFxmcmFje1xEZWx0YSBQX3R9e1Bfe3QtMX19JCQgd2hlcmUgJFxEZWx0YSBQX3QgPSBQX3QgLSBQX3t0LTF9JC4KT3Nib3JuZSBjYW1lIHdpdGggYW4gYWx0ZXJuYXRpdmUgZm9ybXVsYXRpb24gb2YgdGhlIHJldHVybnMgYXMKJCRyX3QgPSBcbG4oUF90KSAtIGxuKFBfe3QtMX0pLiQkCgpBdCBmaXJzdCwgbG9vayBhdCB0aGUgc3RvY2hhc3RpYyBwcm9wZXJ0aWVzIG9mIHRoZSByZXR1cm5zLCBpLmUuIGNvbXBhcmUgdGhlaXIgbWVhbnMgYW5kIHZhbHVlcyByZWNvcmRlZCBpbiB0d28gcmVzZWFyY2hlZCBwZXJpb2RzLgoKYGBge3IgQ29tcHV0YXRpb25fb2ZfcmV0dXJuc30KCnJldHVybl9sIDw8LSBDYWxjdWxhdGVSZXR1cm5zKHByaWNlLCBtZXRob2Q9ImxvZyIpCnJldHVybl9wIDwtIENhbGN1bGF0ZVJldHVybnMocHJpY2UsIG1ldGhvZD0iZGlzY3JldGUiKQoKZm9yKGkgaW4gMTpkaW0ocmV0dXJuX2wpWzJdKXsgICAjaW1wdXRhdGlvbiBvZiB0aGUgbWlzc2luZyBkYXRhCiAgcmV0dXJuX2xbLGldW2lzLm5hKHJldHVybl9sWyxpXSldIDwtIG1lZGlhbihyZXR1cm5fbFssaV0sbmEucm0gPSBUUlVFKQp9Cgpmb3IoaSBpbiAxOmRpbShyZXR1cm5fcClbMl0peyAgICAgI2ltcHV0YXRpb24gb2YgdGhlIG1pc3NpbmcgZGF0YQogIHJldHVybl9wWyxpXVtpcy5uYShyZXR1cm5fcFssaV0pXSA8LSBtZWRpYW4ocmV0dXJuX3BbLGldLG5hLnJtID0gVFJVRSkKfQoKc3ViVF9Ecl9wIDw8LSByZXR1cm5fcFsiMjAyMC0wMS0wMS8yMDIwLTA3LTAxIiwxXSAgI1JvemRlbGVuaWUgcmV0dXJuX3AgbmEgZHZhIHBvZHN1Ym9yeQpzdWJUX0hyX3AgPDwtIHJldHVybl9wWyIyMDIyLTA3LTAxLzIwMjItMTItMjgiLDFdCgojIGdyYXBoaW5nIGp1c3QgdGhlIGZpcnMgc2hhcmUKdGl0bGUgPC0gcGFzdGUoc3ltYm9sX25hbWVbMV0sICJTaGFyZSIgKSAKZXZlbnRzIDwtIHh0cyhjKCIgIiwiICIpLGFzLkRhdGUoYyhkb2xuYV9ocmFuaWNhLCBob3JuYV9ocmFuaWNhKSkpCnBsb3QocmV0dXJuX3BbLDFdLCBjb2w9InJlZCIsIG1haW49dGl0bGUpCmFkZEV2ZW50TGluZXMoZXZlbnRzLCBzcnQ9OTAsIHBvcz0yLGNvbD0iYmx1ZSIpCgoKIyBHZXQgc3VtbWFyeSBzdGF0aXN0aWNzIHVzaW5nIHN1bW1hcnkoKSBmdW5jdGlvbgoKCnN1bW1hcnlfZGF0YSA8LSBzdW1tYXJ5KGRhdGEuZnJhbWUoY2JpbmQoc3ViVF9Ecl9wLHN1YlRfSHJfcCkpKQpzdW1tYXJ5X2RhdGEgPC0gc3VtbWFyeV9kYXRhWzE6NixdCgojIENvbnZlcnQgc3VtbWFyeSBzdGF0aXN0aWNzIHRvIGEgdGFibGUgdXNpbmcga2FibGUoKQpjb2xuYW1lcyhzdW1tYXJ5X2RhdGEpIDwtIGMoIjFzdCBwZXJpb2QiLCIybmQgcGVyaW9kIikKc3VtbWFyeV9kYXRhCiNzdW1tYXJ5X3RhYmxlIDwtIGthYmxlKHN1bW1hcnlfZGF0YSkKCiMgQ3VzdG9taXplIHRoZSB0YWJsZSB1c2luZyBrYWJsZUV4dHJhIHBhY2thZ2UKI3N1bW1hcnlfdGFibGUgJT4lCiMgIGthYmxlX3N0eWxpbmcoZnVsbF93aWR0aCA9IEZBTFNFKSAlPiUKIyAgYWRkX2hlYWRlcl9hYm92ZShjKCJTdW1tYXJ5IFN0YXRpc3RpY3MiID0gMykpCmBgYAoKVGhlIGRpc3RyaWJ1dGlvbiBzZWVtcyB0byBiZSBlcXVhbGx5IGRpc3RyaWJ1dGVkLiBBdCBsZWFzdCwgbGV0IHVzIHRlc3QKdGhlIGVxdWFsaXR5IG9mIHRoZSBtZWFuIHJldHVybnMgYXMgZm9sbG93cwoKJCRIXzA6IE1fezFzdCBQZXJpb2R9ID0gTV97Mm5kIFBlcmlvZH0kJAoKYWdhaW5zdAoKJCRIXzE6IE1fezFzdCBQZXJpb2R9IFxuZXEgTV97Mm5kIFBlcmlvZH0sJCQgYW5kIGFsc28KCiQkSF8wOiBcc2lnbWFeMl97MXN0IFBlcmlvZH0gPSBcc2lnbWFeMl97Mm5kIFBlcmlvZH0kJAoKYWdhaW5zdAoKJCRIXzE6IFxzaWdtYV4yX3sxc3QgUGVyaW9kfSBcbmVxIFxzaWdtYV4yX3sybmQgUGVyaW9kfSwkJAoKYGBge3J9CgpyZXN1bHRNIDw8LSB3aWxjb3gudGVzdChhcy52ZWN0b3Ioc3ViVF9Ecl9wKSwgYXMudmVjdG9yKHN1YlRfSHJfcCkpCgojIFBlcmZvcm0gV2VsY2gncyB0ZXN0CnJlc3VsdFNpZ21hIDw8LSB2YXIudGVzdChhcy52ZWN0b3Ioc3ViVF9Ecl9wKSwgYXMudmVjdG9yKHN1YlRfSHJfcCkpCgpyZXN1bHRNCnJlc3VsdFNpZ21hCgpgYGAKClRoZSBwLXZhbHVlIG9mIHRoZSBXaWxjb3hvbiB0ZXN0IGlzIGByIHJlc3VsdE0kcC52YWx1ZWAgLCB3aGlsZSB0aGUgcmVzdWx0IG9mIHRoZSBGIHRlc3Qgb2YgdGhlIGVxdWFsIHZhcmlhbmNlcyBpcwpgciByZXN1bHRTaWdtYSRwLnZhbHVlYC4gXltJbiByZWFsaXR5LCBob3dldmVyLCB0aGUgdGVzdCBpcyBjYWxsZWQgV2lsY294b24gdGVzdCBpbiB0aGUgUiBzb2Z0d2FyZSwgYnV0IGluIHJlYWxpdHkgaXQgaXMgTWFubi1XaGl0bmV5IHRlc3QgKHRlc3Qgb2YgbWVhbnMgZXF1YWxpdHkgb2YgdHdvIGluZGVwZW5kZW50ICh1bnBhaXJlZCkgc2FtcGxlcykgXQoKCgojIyMgTm9ybWFsbHkgZGlzdHJpYnV0ZWQgcmV0dXJucz8KCk1hbnkgdGhlb3JpZXMgKE1hcmtvd2l0eiwgQmxhY2sgU2Nob2xlLCBWYVIpIGFzc3VtZSB0aGUgbm9ybWFsIGRpc3RyaWJ1dGlvbiBvZiB0aGUgZGF0YS4gSW4gcmVhbGl0eSwgdGhlIGFzc3VtcHRpb24gaXMgb2Z0ZW4gdmlvbGF0ZWQgYW5kIHRoZSByZWFsIGRpc3RyaWJ1dGlvbiBoYXMgaGF2ZSB0YWlscyBpZiBjb21wYXJpbmcgdG8gdGhlIG5vcm1hbCBkaXN0cmlidXRpb24uIFNlZSByZXN1bHQgb2YgdGhlIGZvbGxvd2luZyBKYXJxdWUtQmVycmEgbm9ybWFsaXR5IHRlc3QKCmBgYHtyfQp0ZXN0X3Jlc3VsdCA8LSBqYXJxdWUuYmVyYS50ZXN0KHByaWNlWywxXSkKcHJpbnQodGVzdF9yZXN1bHQpCmBgYAoKIyMgSGlzdG9ncmFtcwoKYGBge3J9CmRldi5uZXcoKSAjIG5ldyBQbG90CnBhcihtZnJvdz1jKDIsMykpICMgYXJyYW5nZSBwbG90cyBpbiBhIDN4MiBncmlkCmZvcihpIGluIDE6ZGltKHJldHVybl9wKVsyXSl7ICMgaXRlcmF0ZSB0aHJvdWdoIGVhY2ggc3ltYm9sCiAgZXRmID0gcmV0dXJuX3BbLGldICMgbG9hZCBkYXRhIGludG8gdGVtcCB2YXJpYWJsZQogIGNvbG5hbWVzKCBldGYgKSA9IGNvbG5hbWVzKHJldHVybl9wWyxpXSkgIyBkYXRhIGhlYWRlciBhcyB0aGUgdGlja2VyCiAgY2hhcnQuSGlzdG9ncmFtKCBldGYsIG1haW49cGFzdGUoIiBSZXR1cm4gRGlzdHJpYnV0aW9uIiksIAogICAgYnJlYWtzPTE1LCBtZXRob2RzPWMoImFkZC5ub3JtYWwiKSwgIyBBZGQgdGhlIG5vcm1hbCBjdXJ2ZSwgYW5kIHRoZSBWYVIgbGV2ZWxzCiAgICBjb2xvcnNldD1jKCJzdGVlbGJsdWUiLCAiZGFya2dyZWVuIiwgIm5hdnkiKSAjIGNvbG9ycyBmb3IgZWFjaCAobWlkZGxlIGNvbG9yIG5vdCB1c2VkKQogICkKfQoKCmBgYAoKCmBgYHtyfQoKICBjaGFydC5IaXN0b2dyYW0oIHJldHVybl9wWywxXSwgbWFpbj0gcGFzdGUoIiBSZXR1cm4gRGlzdHJpYnV0aW9uIG9mICIsY29sbmFtZXMocmV0dXJuX3BbLDFdKSksIAogICAgYnJlYWtzPTE1LCBtZXRob2RzPWMoImFkZC5ub3JtYWwiLCAiYWRkLnJpc2siKSwgIyBBZGQgdGhlIG5vcm1hbCBjdXJ2ZSwgYW5kIHRoZSBWYVIgbGV2ZWxzCiAgICBjb2xvcnNldD1jKCJzdGVlbGJsdWUiLCAiZGFya2dyZWVuIiwgIm5hdnkiKSAjIGNvbG9ycyBmb3IgZWFjaCAobWlkZGxlIGNvbG9yIG5vdCB1c2VkKQogICkKYGBgCgoKCgojIyBDb3JyZWxhdGlvbiBzdHJ1Y3R1cmUgb2YgdGhlIHBvcnRmb2xpbyBhc3NldHMKCklmIHNwZWFraW5nIGFib3V0IGZhY2luZyB0aGUgcmlza3MsIHRoZSBlZmZlY3RpdmUgZGl2ZXJzaWZpY2F0aW9uIG9mIHRoZSBpbnZlc3RtZW50IGlzIG5lZWRlZC4gSW4gdGhpcyB3YXksIHdlIGNhbiByZWR1Y2UgdGhlICp1bnN5c3RlbWljIHJpc2tzKi4gU2VlIHRoZSBjb3JyZWxhdGlvbnMgaW4gb3VyIGh5cG90ZXRpY2FsIHBvcnRmb2xpbyBpbiB0aGUgZm9sbG93aW5nIEZpZ3VyZS4KCgpgYGB7ciBmaWc0LCBlcnJvcj1GQUxTRSwgd2FybmluZz1GQUxTRX0KI2NoYXJ0LkNvcnJlbGF0aW9uKHJldHVybl9wWzI6bmNvbChyZXR1cm5fcCldKQpjaGFydC5Db3JyZWxhdGlvbihyZXR1cm5fcCkKYGBgCiMjIEVzdGltYXRpb24gb2YgdGhlIHZhcmlhbmNlLWNvdmFyaWFuY2UgbWF0cml4IG9mIHRoZSBwb3J0Zm9saW8gcmV0dXJucwoKVmFyaWFuY2UgLSBjb3ZhcmlhbmNlIG1hdHJpeCBpcyBhIGNldHJhbCB0b3BpYyBvZiB0aGUgcG9ydGZvbGlvIHRoZW9yeS4gSXQgY29udGFpbmVzIHRoZSByZXR1cm4gdmFyaWFuY2VzIG9uIHRoZSBtYWluIGRpYWdvbmFsLCB3aGlsZSBiZXNpZGVzIHRoZXJlIGFyZSB0aGUgY292YXJpYW5jZXMuIElmIHNwZWFraW5nIGFib3V0IHRoZSBjb3JyZWxhdGlvbiBtYXRyaXgsIHRoZW4gdGhlIGRpYWdvbmFsIHRlcm1zIGFyZSAxJ3MgYW5kIG91dCBvZiB0aGUgZGlhZ29uYWwsIHRoZXJlIGFyZSB0aGUgY29ycmVzcG9uZGluZyBjb3JyZWxhdGlvbnMuCgpgYGB7ciB2YXJpYW5jZS1jb3ZhcmlhbmNlX21hdHJpeH0KdmFyX2NvdmFyX3AgPC0gY292KHJldHVybl9wKQp2YXJfY292YXJfcApgYGAK