Installation of the Libraries

Libraries

If making the financial analysis of the stock exchange data, the following packages are highly popular:

  1. quantmod
  2. PerformanceAnalytics
  3. 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}. 1

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

  1. In reality, however, the test is called Wilcoxon test in the R software, but in reality it is Mann-Whitney test (test of means equality of two independent (unpaired) samples) ↩︎

LS0tCnRpdGxlOiAiQ2FwaXRhbCByZXR1cm5zIgpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sKbGF0ZXhfZW5naW5lOiB4ZWxhdGV4CmhlYWRlci1pbmNsdWRlczoKICAtIFx1c2VwYWNrYWdle2Ftc21hdGh9CiAgLSBcdXNlcGFja2FnZXthbXNzeW1ifQplZGl0b3Jfb3B0aW9uczogCiAgbWFya2Rvd246IAogICAgd3JhcDogNzIKLS0tCgojIyMgSW5zdGFsbGF0aW9uIG9mIHRoZSBMaWJyYXJpZXMKCmBgYHtyIHNldHVwLCBpbmNsdWRlPUZBTFNFfQppbnN0YWxsLnBhY2thZ2VzKHRpbnl0ZXgpCmxpYnJhcnkodGlueXRleCkKa25pdHI6Om9wdHNfY2h1bmskc2V0KGVjaG8gPSBUUlVFKQpgYGAKCgpgYGB7ciwgZWNobz1GQUxTRX0Kb3B0aW9ucyh0aW55dGV4Lm1hdGhqYXggPSBUUlVFKQpgYGAKCiMjIExpYnJhcmllcwoKSWYgbWFraW5nIHRoZSBmaW5hbmNpYWwgYW5hbHlzaXMgb2YgdGhlIHN0b2NrIGV4Y2hhbmdlIGRhdGEsIHRoZSBmb2xsb3dpbmcgcGFja2FnZXMgYXJlIGhpZ2hseSBwb3B1bGFyOgoKMS4gcXVhbnRtb2QKMi4gUGVyZm9ybWFuY2VBbmFseXRpY3MKMy4gdGlkeXF1YW50ICAKCmBgYHtyIGxpYnJhcmllc30KI2luc3RhbGwucGFja2FnZXMoIlBlcmZvcm1hbmNlQW5hbHl0aWNzIiwgcmVwb3MgPSAiaHR0cDovL2NyYW4udXMuci1wcm9qZWN0Lm9yZyIpCiNpbnN0YWxsLnBhY2thZ2VzKCJkcGx5ciIsIHJlcG9zID0gImh0dHA6Ly9jcmFuLnVzLnItcHJvamVjdC5vcmciKQojaW5zdGFsbC5wYWNrYWdlcygidGlkeXF1YW50IiwgcmVwb3MgPSAiaHR0cDovL2NyYW4udXMuci1wcm9qZWN0Lm9yZyIpCiNpbnN0YWxsLnBhY2thZ2VzKCJxdWFudG1vZCIsIHJlcG9zID0gImh0dHA6Ly9jcmFuLnVzLnItcHJvamVjdC5vcmciKQojaW5zdGFsbC5wYWNrYWdlcygidHNlcmllcyIsIHJlcG9zID0gImh0dHA6Ly9jcmFuLnVzLnItcHJvamVjdC5vcmciKQojaW5zdGFsbC5wYWNrYWdlcygidGlkeXZlcnNlIiwgcmVwb3MgPSAiaHR0cDovL2NyYW4udXMuci1wcm9qZWN0Lm9yZyIpCgoKCmxpYnJhcnkoUGVyZm9ybWFuY2VBbmFseXRpY3MpICAjdXNlZnVsIHBhY2thZ2UgISEhCmxpYnJhcnkocXVhbnRtb2QpICAgICAgICAgICAgICAjIHVzZWZ1bCBwYWNrYWdlCmxpYnJhcnkodGlkeXF1YW50KSAgICAgICAgICAgICAjIHVzZWZ1bAoKIyBvdGhlciBsaWJyYXJpZXMKCmxpYnJhcnkoZ2dwbG90MikKbGlicmFyeShkcGx5cikKCmxpYnJhcnkodHNlcmllcykKbGlicmFyeSh0aWR5dmVyc2UpCmxpYnJhcnkocGxvdGx5KQpsaWJyYXJ5KGhyYnJ0aGVtZXMpCmxpYnJhcnkoeHRzKQpsaWJyYXJ5KGtuaXRyKQpsaWJyYXJ5KGthYmxlRXh0cmEpCmxpYnJhcnkoY2FyKQpsaWJyYXJ5KG1hdGhqYXhyKQpsaWJyYXJ5KHpvbykKcm0obGlzdD1scygpKQpgYGAKCiMjIERhdGEgZG93bmxvYWQKCklmIGRvd25sb2FkaW5nIHRoZSBzdG9jay1leGNoYW5nZSBkYXRhLCB3ZSB1c2UgdGhlIHF1YW50bW9kIHBhY2thZ2UgY29tbWFuZCAiZ2V0U3ltYm9scyIuIENPbW1hbmQgIkFkIiBlbmFibGVzIGV4dHJhY3Rpb24gb2YganVzdCBBZGp1c3RlZCBjbG9zaW5nIHByaWNlcyBvZiB0aGUgZGF5LgoKYGBge3IgZG93bmxvYWRfZGF0YSwgbWVzc2FnZT1GQUxTRX0Kc3ltYm9sX25hbWUgPDwtIGMoIkFBUEwiLCAiR09PRyIsICJBTVpOIiwgIkYiLCAiVCIsICJUUVFRIikKI3N5bWJvbF9uYW1lIDwtICJBQVBMIgoKZm9yIChpIGluIDE6bGVuZ3RoKHN5bWJvbF9uYW1lKSkgewogIHByYWMgPDwtIEFkKGdldFN5bWJvbHMoc3ltYm9sX25hbWVbaV0sIGZyb20gPSAiMjAyMC0wMS0wMSIsIHRvID0gIjIwMjItMTItMzEiLGF1dG8uYXNzaWduPUZBTFNFKSkKICBpZiAoaT09MSkgewogICAgcHJpY2UgPDwtcHJhYwogIH0gZWxzZXsKICAgIHByaWNlIDw8LSBtZXJnZShwcmljZSxwcmFjKQogIH0KfQpybShwcmFjKSAgICAjIHByYWMgaXMganVzdCB0ZW1wb3JhcnkgdmFyaWFibGUgdG8gcmVtb3ZlCmNvbG5hbWVzKHByaWNlKSA8LSBzeW1ib2xfbmFtZSAgI3B1dGluZyB0aGUgbmFtZXMgb2YgdGhlIHNoYXJlcwpgYGAKCiMjIEFuYWx5c2lzIG9mIG9uZSBhc3NldAoKSW4gdGhlIGFib3ZlLCB3ZSBsZWFybmVkIGRvd25sb2FkaW5nIG9mIHRoZSBhZGp1c3RlZCBjbG9zaW5nIHByaWNlcy4gTm93LCB0YWtlIHRoZSBmaXJzdCBhc3NldCBmcm9tIHRoZSAic3ltYm9sX25hbWUiIGFuZCBtYWtlIGEgcGljdHVyZS4gV2UgbGVhcmx5IHNlZSB0aGF0IHRoZSBzdG9jaGFzdGljIHByb3BlcnRpZXMgb2YgdGhlIGFzc2V0cyBjb21pbmcgZnJvbSB0aGUgdHdvIGRpZmZlcmVudCBwZXJpb2RzIHNpZ25pZmljYW50bHkgZGlmZmVyLiAKCmBgYHtyfQp0aXRsZSA8LSBwYXN0ZShzeW1ib2xfbmFtZVsxXSwgIlNoYXJlIiApIApkb2xuYV9ocmFuaWNhIDw8LSAiMjAyMC0wNy0wMSIKaG9ybmFfaHJhbmljYSA8PC0gIjIwMjItMDctMDEiCiNkYXRhKHNhbXBsZV9tYXRyaXgpCiNzYW1wbGUueHRzIDwtIGFzLnh0cyhwcmljZVssMV0pCmV2ZW50cyA8LSB4dHMoYygiICIsIiAiKSxhcy5EYXRlKGMoZG9sbmFfaHJhbmljYSwgaG9ybmFfaHJhbmljYSkpKQpwbG90KHByaWNlWywxXSwgY29sPSJyZWQiLCBtYWluPXRpdGxlKQphZGRFdmVudExpbmVzKGV2ZW50cywgc3J0PTkwLCBwb3M9Mixjb2w9ImJsdWUiKQpgYGAKClRoZSBkaWZmZXJlbmNlcyBvZiB0aGUgc3RvY2hhc3RpYyBwcm9wZXJ0aWVzIG9mIHRoZSBzdG9jayBwcmljZXMgb3JpZ2luYXRpbmcgZnJvbSAyIGRpZmZlcmVudCBwcmVpb2RzLCB3ZSBjYW4gZGVwaWN0IGFsc28gbWFraW5nIHNvbWUgYmFzaWMgZGVzY3JpcHRpdmUgc3RhdGlzdGljcy4KCmBgYHtyfQpzdWJUX0QgPDwtIHByaWNlWyIyMDIwLTAxLTAxLzIwMjAtMDctMDEiLDFdCnN1YlRfSCA8PC0gcHJpY2VbIjIwMjItMDctMDEvMjAyMi0xMi0yOCIsMV0KCiMgR2V0IHN1bW1hcnkgc3RhdGlzdGljcyB1c2luZyBzdW1tYXJ5KCkgZnVuY3Rpb24Kc3VtbWFyeV9kYXRhIDwtIHN1bW1hcnkoZGF0YS5mcmFtZShjYmluZChzdWJUX0Qsc3ViVF9IKSkpCnN1bW1hcnlfZGF0YSA8LSBzdW1tYXJ5X2RhdGFbMTo2LF0KCiMgQ29udmVydCBzdW1tYXJ5IHN0YXRpc3RpY3MgdG8gYSB0YWJsZSB1c2luZyBrYWJsZSgpCmNvbG5hbWVzKHN1bW1hcnlfZGF0YSkgPC0gYygiMXN0IHBlcmlvZCIsIjJuZCBwZXJpb2QiKQpzdW1tYXJ5X2RhdGEKCiNzdW1tYXJ5X3RhYmxlIDwtIGthYmxlKHN1bW1hcnlfZGF0YSkKCiMgQ3VzdG9taXplIHRoZSB0YWJsZSB1c2luZyBrYWJsZUV4dHJhIHBhY2thZ2UKI3N1bW1hcnlfdGFibGUgJT4lCiMgIGthYmxlX3N0eWxpbmcoZnVsbF93aWR0aCA9IEZBTFNFKSAlPiUKIyAgYWRkX2hlYWRlcl9hYm92ZShjKCJTdW1tYXJ5IFN0YXRpc3RpY3MiID0gMykpCmBgYAoKIyMgQ29udmVyc2lvbiBvZiB0aGUgbGV2ZWwgZGF0YSB0aW1lIHNlcmllcyB0byB0aGUgcmV0dXJucwoKUHJldmlvdXMgZW1waXJpY2FsIGV4cGVyaWVuY2UgbGVhZCB0byB0aGUgY29uY2x1c2lvbiB0aGF0IHRoZSB1bmRlcmx5aW5nIHByb2JhYmlsaXR5IGRpc3RyaWJ1dGlvbiBvZiB0aGUgcHJpY2VzICRmX3QoUCkgPD4gZl97dCBccG0gaX0oUCkkIHRoYXQgbWVhbnMsIHRoZSB1bmRlcmx5aW5nIHRpbWUgc2VyaWVzIGlzIG5vdCBzdGF0aW9uYXJ5LiBUaGF0IGlzLCB3aHkgd2UgYXJlIHVuYWJsZSB0byB1c2UgdGhlIHRvb2xzIG9mIHRoZSBwcm9iYWJpbGl0eSB0aGVvcnkuIFRoZSBlY29ub21pc3RzIHNvbHZlIHRoZSBwcm9ibGVtIGJ5IHRha2luZyB0aGUgY2FwaXRhbCBhc3NldCBwcmljZSByZXR1cm5zLCBpLmUuCgokJHJfdCA9IFxmcmFje1xEZWx0YSBQX3R9e1Bfe3QtMX19JCQgd2hlcmUgJFxEZWx0YSBQX3QgPSBQX3QgLSBQX3t0LTF9JC4KT3Nib3JuZSBjYW1lIHdpdGggYW4gYWx0ZXJuYXRpdmUgZm9ybXVsYXRpb24gb2YgdGhlIHJldHVybnMgYXMKJCRyX3QgPSBcbG4oUF90KSAtIGxuKFBfe3QtMX0pLiQkCgpBdCBmaXJzdCwgbG9vayBhdCB0aGUgc3RvY2hhc3RpYyBwcm9wZXJ0aWVzIG9mIHRoZSByZXR1cm5zLCBpLmUuIGNvbXBhcmUgdGhlaXIgbWVhbnMgYW5kIHZhbHVlcyByZWNvcmRlZCBpbiB0d28gcmVzZWFyY2hlZCBwZXJpb2RzLgoKYGBge3IgQ29tcHV0YXRpb25fb2ZfcmV0dXJuc30KCnJldHVybl9sIDw8LSBDYWxjdWxhdGVSZXR1cm5zKHByaWNlLCBtZXRob2Q9ImxvZyIpCnJldHVybl9wIDwtIENhbGN1bGF0ZVJldHVybnMocHJpY2UsIG1ldGhvZD0iZGlzY3JldGUiKQoKZm9yKGkgaW4gMTpkaW0ocmV0dXJuX2wpWzJdKXsgICAjaW1wdXRhdGlvbiBvZiB0aGUgbWlzc2luZyBkYXRhCiAgcmV0dXJuX2xbLGldW2lzLm5hKHJldHVybl9sWyxpXSldIDwtIG1lZGlhbihyZXR1cm5fbFssaV0sbmEucm0gPSBUUlVFKQp9Cgpmb3IoaSBpbiAxOmRpbShyZXR1cm5fcClbMl0peyAgICAgI2ltcHV0YXRpb24gb2YgdGhlIG1pc3NpbmcgZGF0YQogIHJldHVybl9wWyxpXVtpcy5uYShyZXR1cm5fcFssaV0pXSA8LSBtZWRpYW4ocmV0dXJuX3BbLGldLG5hLnJtID0gVFJVRSkKfQoKc3ViVF9Ecl9wIDw8LSByZXR1cm5fcFsiMjAyMC0wMS0wMS8yMDIwLTA3LTAxIiwxXSAgI1JvemRlbGVuaWUgcmV0dXJuX3AgbmEgZHZhIHBvZHN1Ym9yeQpzdWJUX0hyX3AgPDwtIHJldHVybl9wWyIyMDIyLTA3LTAxLzIwMjItMTItMjgiLDFdCgojIGdyYXBoaW5nIGp1c3QgdGhlIGZpcnMgc2hhcmUKdGl0bGUgPC0gcGFzdGUoc3ltYm9sX25hbWVbMV0sICJTaGFyZSIgKSAKZXZlbnRzIDwtIHh0cyhjKCIgIiwiICIpLGFzLkRhdGUoYyhkb2xuYV9ocmFuaWNhLCBob3JuYV9ocmFuaWNhKSkpCnBsb3QocmV0dXJuX3BbLDFdLCBjb2w9InJlZCIsIG1haW49dGl0bGUpCmFkZEV2ZW50TGluZXMoZXZlbnRzLCBzcnQ9OTAsIHBvcz0yLGNvbD0iYmx1ZSIpCgoKIyBHZXQgc3VtbWFyeSBzdGF0aXN0aWNzIHVzaW5nIHN1bW1hcnkoKSBmdW5jdGlvbgoKCnN1bW1hcnlfZGF0YSA8LSBzdW1tYXJ5KGRhdGEuZnJhbWUoY2JpbmQoc3ViVF9Ecl9wLHN1YlRfSHJfcCkpKQpzdW1tYXJ5X2RhdGEgPC0gc3VtbWFyeV9kYXRhWzE6NixdCgojIENvbnZlcnQgc3VtbWFyeSBzdGF0aXN0aWNzIHRvIGEgdGFibGUgdXNpbmcga2FibGUoKQpjb2xuYW1lcyhzdW1tYXJ5X2RhdGEpIDwtIGMoIjFzdCBwZXJpb2QiLCIybmQgcGVyaW9kIikKc3VtbWFyeV9kYXRhCiNzdW1tYXJ5X3RhYmxlIDwtIGthYmxlKHN1bW1hcnlfZGF0YSkKCiMgQ3VzdG9taXplIHRoZSB0YWJsZSB1c2luZyBrYWJsZUV4dHJhIHBhY2thZ2UKI3N1bW1hcnlfdGFibGUgJT4lCiMgIGthYmxlX3N0eWxpbmcoZnVsbF93aWR0aCA9IEZBTFNFKSAlPiUKIyAgYWRkX2hlYWRlcl9hYm92ZShjKCJTdW1tYXJ5IFN0YXRpc3RpY3MiID0gMykpCmBgYAoKVGhlIGRpc3RyaWJ1dGlvbiBzZWVtcyB0byBiZSBlcXVhbGx5IGRpc3RyaWJ1dGVkLiBBdCBsZWFzdCwgbGV0IHVzIHRlc3QKdGhlIGVxdWFsaXR5IG9mIHRoZSBtZWFuIHJldHVybnMgYXMgZm9sbG93cwoKJCRIXzA6IE1fezFzdCBQZXJpb2R9ID0gTV97Mm5kIFBlcmlvZH0kJAoKYWdhaW5zdAoKJCRIXzE6IE1fezFzdCBQZXJpb2R9IFxuZXEgTV97Mm5kIFBlcmlvZH0sJCQgYW5kIGFsc28KCiQkSF8wOiBcc2lnbWFeMl97MXN0IFBlcmlvZH0gPSBcc2lnbWFeMl97Mm5kIFBlcmlvZH0kJAoKYWdhaW5zdAoKJCRIXzE6IFxzaWdtYV4yX3sxc3QgUGVyaW9kfSBcbmVxIFxzaWdtYV4yX3sybmQgUGVyaW9kfSwkJAoKYGBge3J9CgpyZXN1bHRNIDw8LSB3aWxjb3gudGVzdChhcy52ZWN0b3Ioc3ViVF9Ecl9wKSwgYXMudmVjdG9yKHN1YlRfSHJfcCkpCgojIFBlcmZvcm0gV2VsY2gncyB0ZXN0CnJlc3VsdFNpZ21hIDw8LSB2YXIudGVzdChhcy52ZWN0b3Ioc3ViVF9Ecl9wKSwgYXMudmVjdG9yKHN1YlRfSHJfcCkpCgpyZXN1bHRNCnJlc3VsdFNpZ21hCgpgYGAKClRoZSBwLXZhbHVlIG9mIHRoZSBXaWxjb3hvbiB0ZXN0IGlzIGByIHJlc3VsdE0kcC52YWx1ZWAgLCB3aGlsZSB0aGUgcmVzdWx0IG9mIHRoZSBGIHRlc3Qgb2YgdGhlIGVxdWFsIHZhcmlhbmNlcyBpcwpgciByZXN1bHRTaWdtYSRwLnZhbHVlYC4gXltJbiByZWFsaXR5LCBob3dldmVyLCB0aGUgdGVzdCBpcyBjYWxsZWQgV2lsY294b24gdGVzdCBpbiB0aGUgUiBzb2Z0d2FyZSwgYnV0IGluIHJlYWxpdHkgaXQgaXMgTWFubi1XaGl0bmV5IHRlc3QgKHRlc3Qgb2YgbWVhbnMgZXF1YWxpdHkgb2YgdHdvIGluZGVwZW5kZW50ICh1bnBhaXJlZCkgc2FtcGxlcykgXQoKCgojIyMgTm9ybWFsbHkgZGlzdHJpYnV0ZWQgcmV0dXJucz8KCk1hbnkgdGhlb3JpZXMgKE1hcmtvd2l0eiwgQmxhY2sgU2Nob2xlLCBWYVIpIGFzc3VtZSB0aGUgbm9ybWFsIGRpc3RyaWJ1dGlvbiBvZiB0aGUgZGF0YS4gSW4gcmVhbGl0eSwgdGhlIGFzc3VtcHRpb24gaXMgb2Z0ZW4gdmlvbGF0ZWQgYW5kIHRoZSByZWFsIGRpc3RyaWJ1dGlvbiBoYXMgaGF2ZSB0YWlscyBpZiBjb21wYXJpbmcgdG8gdGhlIG5vcm1hbCBkaXN0cmlidXRpb24uIFNlZSByZXN1bHQgb2YgdGhlIGZvbGxvd2luZyBKYXJxdWUtQmVycmEgbm9ybWFsaXR5IHRlc3QKCmBgYHtyfQp0ZXN0X3Jlc3VsdCA8LSBqYXJxdWUuYmVyYS50ZXN0KHByaWNlWywxXSkKcHJpbnQodGVzdF9yZXN1bHQpCmBgYAoKIyMgSGlzdG9ncmFtcwoKYGBge3J9CmRldi5uZXcoKSAjIG5ldyBQbG90CnBhcihtZnJvdz1jKDIsMykpICMgYXJyYW5nZSBwbG90cyBpbiBhIDN4MiBncmlkCmZvcihpIGluIDE6ZGltKHJldHVybl9wKVsyXSl7ICMgaXRlcmF0ZSB0aHJvdWdoIGVhY2ggc3ltYm9sCiAgZXRmID0gcmV0dXJuX3BbLGldICMgbG9hZCBkYXRhIGludG8gdGVtcCB2YXJpYWJsZQogIGNvbG5hbWVzKCBldGYgKSA9IGNvbG5hbWVzKHJldHVybl9wWyxpXSkgIyBkYXRhIGhlYWRlciBhcyB0aGUgdGlja2VyCiAgY2hhcnQuSGlzdG9ncmFtKCBldGYsIG1haW49cGFzdGUoIiBSZXR1cm4gRGlzdHJpYnV0aW9uIiksIAogICAgYnJlYWtzPTE1LCBtZXRob2RzPWMoImFkZC5ub3JtYWwiKSwgIyBBZGQgdGhlIG5vcm1hbCBjdXJ2ZSwgYW5kIHRoZSBWYVIgbGV2ZWxzCiAgICBjb2xvcnNldD1jKCJzdGVlbGJsdWUiLCAiZGFya2dyZWVuIiwgIm5hdnkiKSAjIGNvbG9ycyBmb3IgZWFjaCAobWlkZGxlIGNvbG9yIG5vdCB1c2VkKQogICkKfQoKCmBgYAoKCmBgYHtyfQoKICBjaGFydC5IaXN0b2dyYW0oIHJldHVybl9wWywxXSwgbWFpbj0gcGFzdGUoIiBSZXR1cm4gRGlzdHJpYnV0aW9uIG9mICIsY29sbmFtZXMocmV0dXJuX3BbLDFdKSksIAogICAgYnJlYWtzPTE1LCBtZXRob2RzPWMoImFkZC5ub3JtYWwiLCAiYWRkLnJpc2siKSwgIyBBZGQgdGhlIG5vcm1hbCBjdXJ2ZSwgYW5kIHRoZSBWYVIgbGV2ZWxzCiAgICBjb2xvcnNldD1jKCJzdGVlbGJsdWUiLCAiZGFya2dyZWVuIiwgIm5hdnkiKSAjIGNvbG9ycyBmb3IgZWFjaCAobWlkZGxlIGNvbG9yIG5vdCB1c2VkKQogICkKYGBgCgoKCgojIyBDb3JyZWxhdGlvbiBzdHJ1Y3R1cmUgb2YgdGhlIHBvcnRmb2xpbyBhc3NldHMKCklmIHNwZWFraW5nIGFib3V0IGZhY2luZyB0aGUgcmlza3MsIHRoZSBlZmZlY3RpdmUgZGl2ZXJzaWZpY2F0aW9uIG9mIHRoZSBpbnZlc3RtZW50IGlzIG5lZWRlZC4gSW4gdGhpcyB3YXksIHdlIGNhbiByZWR1Y2UgdGhlICp1bnN5c3RlbWljIHJpc2tzKi4gU2VlIHRoZSBjb3JyZWxhdGlvbnMgaW4gb3VyIGh5cG90ZXRpY2FsIHBvcnRmb2xpbyBpbiB0aGUgZm9sbG93aW5nIEZpZ3VyZS4KCgpgYGB7ciBmaWc0LCBlcnJvcj1GQUxTRSwgd2FybmluZz1GQUxTRX0KI2NoYXJ0LkNvcnJlbGF0aW9uKHJldHVybl9wWzI6bmNvbChyZXR1cm5fcCldKQpjaGFydC5Db3JyZWxhdGlvbihyZXR1cm5fcCkKYGBgCiMjIEVzdGltYXRpb24gb2YgdGhlIHZhcmlhbmNlLWNvdmFyaWFuY2UgbWF0cml4IG9mIHRoZSBwb3J0Zm9saW8gcmV0dXJucwoKVmFyaWFuY2UgLSBjb3ZhcmlhbmNlIG1hdHJpeCBpcyBhIGNldHJhbCB0b3BpYyBvZiB0aGUgcG9ydGZvbGlvIHRoZW9yeS4gSXQgY29udGFpbmVzIHRoZSByZXR1cm4gdmFyaWFuY2VzIG9uIHRoZSBtYWluIGRpYWdvbmFsLCB3aGlsZSBiZXNpZGVzIHRoZXJlIGFyZSB0aGUgY292YXJpYW5jZXMuIElmIHNwZWFraW5nIGFib3V0IHRoZSBjb3JyZWxhdGlvbiBtYXRyaXgsIHRoZW4gdGhlIGRpYWdvbmFsIHRlcm1zIGFyZSAxJ3MgYW5kIG91dCBvZiB0aGUgZGlhZ29uYWwsIHRoZXJlIGFyZSB0aGUgY29ycmVzcG9uZGluZyBjb3JyZWxhdGlvbnMuCgpgYGB7ciB2YXJpYW5jZS1jb3ZhcmlhbmNlX21hdHJpeH0KdmFyX2NvdmFyX3AgPC0gY292KHJldHVybl9wKQp2YXJfY292YXJfcApgYGAK