Downloading online financial data and calculating returns
Here I will download Financial Data from Yahoo
rm(list=ls())
# To avoid scientific notation for numbers:
options(scipen=999)
Load the quantmod package
Here I download the Quantmod Package
library(quantmod)
Loading required package: xts
Loading required package: zoo
Attaching package: ‘zoo’
The following objects are masked from ‘package:base’:
as.Date, as.Date.numeric
Loading required package: TTR
Registered S3 method overwritten by 'quantmod':
method from
as.zoo.data.frame zoo
Downloading real financial prices
getSymbols(Symbols=c("BTC-USD"), from="2017-01-01", src="yahoo", periodicity="daily")
‘getSymbols’ currently uses auto.assign=TRUE by default, but will
use auto.assign=FALSE in 0.5-0. You will still be able to use
‘loadSymbols’ to automatically load data. getOption("getSymbols.env")
and getOption("getSymbols.auto.assign") will still be checked for
alternate defaults.
This message is shown once per session and may be disabled by setting
options("getSymbols.warning4.0"=FALSE). See ?getSymbols for details.
Warning: BTC-USD contains missing values. Some functions will not work if objects contain missing values in the middle of the series. Consider using na.omit(), na.approx(), na.fill(), etc to remove or replace them.
[1] "BTC-USD"
Show the content of datasets
head(`BTC-USD`,5)
BTC-USD.Open BTC-USD.High BTC-USD.Low BTC-USD.Close
2017-01-01 963.658 1003.08 958.699 998.325
2017-01-02 998.617 1031.39 996.702 1021.750
2017-01-03 1021.600 1044.08 1021.600 1043.840
2017-01-04 1044.400 1159.42 1044.400 1154.730
2017-01-05 1156.730 1191.10 910.417 1013.380
BTC-USD.Volume BTC-USD.Adjusted
2017-01-01 147775008 998.325
2017-01-02 222184992 1021.750
2017-01-03 185168000 1043.840
2017-01-04 344945984 1154.730
2017-01-05 510199008 1013.380
tail(`BTC-USD`, 5)
BTC-USD.Open BTC-USD.High BTC-USD.Low BTC-USD.Close
2021-08-13 44439.69 47831.98 44282.42 47793.32
2021-08-14 47810.69 48098.68 46177.63 47096.95
2021-08-15 47096.67 47357.11 45579.59 47047.00
2021-08-16 47019.96 47998.10 45700.32 46004.48
2021-08-17 45980.96 47110.70 45436.33 45883.68
BTC-USD.Volume BTC-USD.Adjusted
2021-08-13 31744259539 47793.32
2021-08-14 31211354442 47096.95
2021-08-15 30988958446 47047.00
2021-08-16 32776876610 46004.48
2021-08-17 31748257792 45883.68
Visualization of prices
plot(`BTC-USD`)

chartSeries(`BTC-USD`, theme=("white"))

Data Cleaning
`BTC-USD` <- na.omit(`BTC-USD`)
Calculation of financial returns
prices <- Ad(`BTC-USD`)
colnames(prices) <- "adj_price"
prices$lag1 <- lag(prices$adj_price, n=1)
prices$R_a <- prices$adj_price / prices$lag1 -1
prices$R_b <- prices$adj_price / lag(prices$adj_price, n=1) -1
prices$GrowthR <- 1 + prices$R_a
prices$r_b <- log(prices$adj_price / prices$lag1)
prices$r_from_R <- log(1 + prices$R_a)
head(prices, 5)
adj_price lag1 R_a R_b GrowthR
2017-01-01 998.325 NA NA NA NA
2017-01-02 1021.750 998.325 0.02346429 0.02346429 1.0234643
2017-01-03 1043.840 1021.750 0.02161974 0.02161974 1.0216197
2017-01-04 1154.730 1043.840 0.10623277 0.10623277 1.1062328
2017-01-05 1013.380 1154.730 -0.12240955 -0.12240955 0.8775905
r_b r_from_R
2017-01-01 NA NA
2017-01-02 0.02319324 0.02319324
2017-01-03 0.02138934 0.02138934
2017-01-04 0.10096034 0.10096034
2017-01-05 -0.13057525 -0.13057525
plot(prices$R_a)

Calculation of holing-period return
n <- as.numeric(nrow(prices))
price_0 <- as.numeric(prices$adj_price[1])
price_n <- as.numeric(prices$adj_price[n])
HPR1 <- (price_n / price_0) - 1
cat("HPR1 = " ,HPR1)
HPR1 = 44.96066
sumr <- sum(prices$r, na.rm = TRUE)
HPR2 <- exp(sumr) - 1
cat(HPR1, HPR2)
44.96066 0
Q Descriptive Statistics of financial returns
rm(list = ls())
getSymbols(Symbols = "SBUX", from="2008-01-01", periodicity="monthly", src = "yahoo")
[1] "SBUX"
returns.df <- as.data.frame(diff(log(Ad(SBUX))))
colnames(returns.df) <- "r_SBUX"
summary(returns.df)
r_SBUX
Min. :-0.38548
1st Qu.:-0.02651
Median : 0.01956
Mean : 0.01661
3rd Qu.: 0.05766
Max. : 0.26354
NA's :1
library(PerformanceAnalytics)
Attaching package: ‘PerformanceAnalytics’
The following object is masked from ‘package:graphics’:
legend
table.Stats(returns.df$r_SBUX)
mean_r_SBUX <- mean(returns.df$r_SBUX, na.rm=TRUE)
sd_r_SBUX <- sd(returns.df$r_SBUX, na.rm=TRUE)
var_r_SBUX <- var(returns.df$r_SBUX, na.rm=TRUE)
cat("Mean =", mean_r_SBUX)
Mean = 0.01661223
cat("Standard deviation = ", sd_r_SBUX)
Standard deviation = 0.07607764
cat("Variance = ", var_r_SBUX)
Variance = 0.005787807
Q Mean, standard deviation and variance of simple returns
returns.df$R_SBUX <- SBUX$SBUX.Adjusted / lag(SBUX$SBUX.Adjusted, n=1) - 1
table.Stats(returns.df$R_SBUX)
mean(returns.df$R_SBUX, na.rm=TRUE)
[1] 0.01963446
sd(returns.df$R_SBUX, na.rm=TRUE)
[1] 0.07617523
var(returns.df$R_SBUX, na.rm=TRUE)
[,1]
[1,] 0.005802666
Q The Histrogram
#You have to remember what is a histogram :)
hist(returns.df$r_SBUX, main="Histogram of SBUX monthly returns",
xlab="Continuously Compounded returns", col="dark green")

##QUESTIONS:
QUESTION: INTERPRET THIS HISTOGRAM WITH YOUR OWN WORDS
If we increase the compound frequency to its limit, we are compounding continuously. Returns are being compounded constantly resulting in money acquiring strength through interest rates. Continiously compounded returns exhibit an increment in frequency in the 0.0-0.1 range.
Q Histogram using simulated data for returns
rSBUX_sim <- rnorm(n=nrow(returns.df), mean = mean_r_SBUX, sd=sd_r_SBUX)
rSBUX <- na.omit(returns.df$r_SBUX)
hist_sim_SBUX<- hist(rSBUX_sim,plot = FALSE)
hist_SBUX <- hist(rSBUX_sim,plot = FALSE)
xlim <- range(hist_SBUX$breaks,hist_sim_SBUX$breaks)
ylim <- range(0,hist_SBUX$density,
hist_sim_SBUX$density)
plot(hist_sim_SBUX,xlim = xlim, ylim = ylim,
col = rgb(1,0,0,0.4),xlab = 'Lengths', freq = FALSE, main = 'Distribution of simulated and real Starbucks Returns')

“No pude hacer el último histograma con colores, me aparece error al meter el codigo del Rpubs así que lo modifiqué para que mínimo apareciera una tabla. Me gustaría saber si podemos revisar esto en clase.” Stefan S.
opar <- par(new = FALSE)
plot(hist_SBUX,xlim = xlim, ylim = ylim)
col = rgb(0,0,1,0.4)
fill=rgb(0.1,0.4,0.5,0.7)
freq = FALSE
main = 'Distribution of simulated and real Starbucks Returns'
legend('topleft',c('Simulated Returns','Real Returns'),
fill = rgb(1:0,0,0:1,0.4), bty = 'n')

QUESTION: WHAT DIFFERENCE DO YOU SEE IN THE HISTOGRAMS? HOW REAL RETURNS ARE DIFFERENT FROM THE THEORETICAL NORMAL DISTRIBUTION OF RETURNS? BRIEFLY EXPLAIN.
Creating a budget vs. actual comparison is extremely important for all businesses because it allows them to alter their future financial forecasts based upon the numbers collected in the monthly reports. Real returns hang on the positive side of the balance, indicating future adjustments must be made.
QUESTION: WHAT WOULD BE THE 95% CONFIDENCE INTERVAL? WHAT IS THE INTERPRETATION OF THIS INTERVAL? EXPLAIN.
Remembering my previous statistics classes, there was always a degree of uncertainty, which would vary according to numerous factors. Widely accepted is the 5% uncertainty degree, thus one can be sure of the other 95% of the available data.
LS0tCnRpdGxlOiAiV29ya3Nob3AgMSwgRmluYW5jaWFsIEVjb25vbWV0cmljcyAxIgpBdXRob3I6ICJTdGVmYW4gU2Nod2VpdHplciIKb3V0cHV0OiBodG1sX25vdGVib29rCi0tLQoKIyBEb3dubG9hZGluZyBvbmxpbmUgZmluYW5jaWFsIGRhdGEgYW5kIGNhbGN1bGF0aW5nIHJldHVybnMKCkhlcmUgSSB3aWxsIGRvd25sb2FkIEZpbmFuY2lhbCBEYXRhIGZyb20gWWFob28KCmBgYHtyfQpybShsaXN0PWxzKCkpCiMgVG8gYXZvaWQgc2NpZW50aWZpYyBub3RhdGlvbiBmb3IgbnVtYmVyczogCm9wdGlvbnMoc2NpcGVuPTk5OSkKYGBgCgojIyBMb2FkIHRoZSBxdWFudG1vZCBwYWNrYWdlCgpIZXJlIEkgZG93bmxvYWQgdGhlIFF1YW50bW9kIFBhY2thZ2UKCmBgYHtyIHdhcm5pbmc9RkFMU0V9CmxpYnJhcnkocXVhbnRtb2QpCmBgYAoKIyMgRG93bmxvYWRpbmcgcmVhbCBmaW5hbmNpYWwgcHJpY2VzCgpgYGB7ciB3YXJuaW5nPUZBTFNFfQpnZXRTeW1ib2xzKFN5bWJvbHM9YygiQlRDLVVTRCIpLCBmcm9tPSIyMDE3LTAxLTAxIiwgc3JjPSJ5YWhvbyIsIHBlcmlvZGljaXR5PSJkYWlseSIpCmBgYAoKIyMgU2hvdyB0aGUgY29udGVudCBvZiBkYXRhc2V0cwoKYGBge3J9CmhlYWQoYEJUQy1VU0RgLDUpCmBgYAoKYGBge3J9CnRhaWwoYEJUQy1VU0RgLCA1KQpgYGAKCiMjIFZpc3VhbGl6YXRpb24gb2YgcHJpY2VzCgpgYGB7cn0KcGxvdChgQlRDLVVTRGApCmBgYAoKYGBge3J9CmNoYXJ0U2VyaWVzKGBCVEMtVVNEYCwgdGhlbWU9KCJ3aGl0ZSIpKQpgYGAKCiMjIERhdGEgQ2xlYW5pbmcKCmBgYHtyfQpgQlRDLVVTRGAgPC0gbmEub21pdChgQlRDLVVTRGApCmBgYAoKIyMgQ2FsY3VsYXRpb24gb2YgZmluYW5jaWFsIHJldHVybnMKCmBgYHtyfQpwcmljZXMgPC0gQWQoYEJUQy1VU0RgKQpgYGAKCmBgYHtyfQpjb2xuYW1lcyhwcmljZXMpIDwtICJhZGpfcHJpY2UiCmBgYAoKYGBge3J9CnByaWNlcyRsYWcxIDwtIGxhZyhwcmljZXMkYWRqX3ByaWNlLCBuPTEpCmBgYAoKYGBge3J9CnByaWNlcyRSX2EgPC0gcHJpY2VzJGFkal9wcmljZSAvIHByaWNlcyRsYWcxIC0xCmBgYAoKYGBge3J9CnByaWNlcyRSX2IgPC0gcHJpY2VzJGFkal9wcmljZSAvIGxhZyhwcmljZXMkYWRqX3ByaWNlLCBuPTEpIC0xCmBgYAoKYGBge3J9CnByaWNlcyRHcm93dGhSIDwtIDEgKyBwcmljZXMkUl9hCmBgYAoKYGBge3J9CnByaWNlcyRyX2IgPC0gbG9nKHByaWNlcyRhZGpfcHJpY2UgLyBwcmljZXMkbGFnMSkKYGBgCgpgYGB7cn0KcHJpY2VzJHJfZnJvbV9SIDwtIGxvZygxICsgcHJpY2VzJFJfYSkKYGBgCgpgYGB7cn0KaGVhZChwcmljZXMsIDUpCmBgYAoKYGBge3J9CnBsb3QocHJpY2VzJFJfYSkKYGBgCgojIyBDYWxjdWxhdGlvbiBvZiBob2xpbmctcGVyaW9kIHJldHVybgoKYGBge3J9Cm4gPC0gYXMubnVtZXJpYyhucm93KHByaWNlcykpCmBgYAoKYGBge3J9CnByaWNlXzAgPC0gYXMubnVtZXJpYyhwcmljZXMkYWRqX3ByaWNlWzFdKQpwcmljZV9uIDwtIGFzLm51bWVyaWMocHJpY2VzJGFkal9wcmljZVtuXSkKYGBgCgpgYGB7cn0KSFBSMSA8LSAocHJpY2VfbiAvIHByaWNlXzApIC0gMQpjYXQoIkhQUjEgPSAiICxIUFIxKQpgYGAKCmBgYHtyfQpzdW1yIDwtIHN1bShwcmljZXMkciwgbmEucm0gPSBUUlVFKQpIUFIyIDwtIGV4cChzdW1yKSAtIDEKYGBgCgpgYGB7cn0KY2F0KEhQUjEsIEhQUjIpCmBgYAoKIyMgUSBEZXNjcmlwdGl2ZSBTdGF0aXN0aWNzIG9mIGZpbmFuY2lhbCByZXR1cm5zCgpgYGB7cn0Kcm0obGlzdCA9IGxzKCkpCmBgYAoKYGBge3J9CmdldFN5bWJvbHMoU3ltYm9scyA9ICJTQlVYIiwgZnJvbT0iMjAwOC0wMS0wMSIsIHBlcmlvZGljaXR5PSJtb250aGx5Iiwgc3JjID0gInlhaG9vIikKYGBgCgpgYGB7cn0KcmV0dXJucy5kZiA8LSBhcy5kYXRhLmZyYW1lKGRpZmYobG9nKEFkKFNCVVgpKSkpCmBgYAoKYGBge3J9CmNvbG5hbWVzKHJldHVybnMuZGYpIDwtICJyX1NCVVgiCmBgYAoKYGBge3J9CnN1bW1hcnkocmV0dXJucy5kZikKYGBgCgpgYGB7cn0KbGlicmFyeShQZXJmb3JtYW5jZUFuYWx5dGljcykKYGBgCgpgYGB7cn0KdGFibGUuU3RhdHMocmV0dXJucy5kZiRyX1NCVVgpCmBgYAoKYGBge3J9Cm1lYW5fcl9TQlVYIDwtIG1lYW4ocmV0dXJucy5kZiRyX1NCVVgsIG5hLnJtPVRSVUUpCmBgYAoKYGBge3J9CnNkX3JfU0JVWCA8LSBzZChyZXR1cm5zLmRmJHJfU0JVWCwgbmEucm09VFJVRSkKYGBgCgpgYGB7cn0KdmFyX3JfU0JVWCA8LSB2YXIocmV0dXJucy5kZiRyX1NCVVgsIG5hLnJtPVRSVUUpCmBgYAoKYGBge3J9CmNhdCgiTWVhbiA9IiwgbWVhbl9yX1NCVVgpCmBgYAoKYGBge3J9CmNhdCgiU3RhbmRhcmQgZGV2aWF0aW9uID0gIiwgc2Rfcl9TQlVYKQpgYGAKCmBgYHtyfQpjYXQoIlZhcmlhbmNlID0gIiwgdmFyX3JfU0JVWCkKYGBgCgojIyBRIE1lYW4sIHN0YW5kYXJkIGRldmlhdGlvbiBhbmQgdmFyaWFuY2Ugb2Ygc2ltcGxlIHJldHVybnMKCmBgYHtyfQpyZXR1cm5zLmRmJFJfU0JVWCA8LSBTQlVYJFNCVVguQWRqdXN0ZWQgLyBsYWcoU0JVWCRTQlVYLkFkanVzdGVkLCBuPTEpIC0gMQpgYGAKCmBgYHtyfQp0YWJsZS5TdGF0cyhyZXR1cm5zLmRmJFJfU0JVWCkKYGBgCgpgYGB7cn0KbWVhbihyZXR1cm5zLmRmJFJfU0JVWCwgbmEucm09VFJVRSkKYGBgCgpgYGB7cn0Kc2QocmV0dXJucy5kZiRSX1NCVVgsIG5hLnJtPVRSVUUpCmBgYAoKYGBge3J9CnZhcihyZXR1cm5zLmRmJFJfU0JVWCwgbmEucm09VFJVRSkKYGBgCgojIyAgUSBUaGUgSGlzdHJvZ3JhbQojWW91IGhhdmUgdG8gcmVtZW1iZXIgd2hhdCBpcyBhIGhpc3RvZ3JhbSA6KQoKYGBge3J9Cmhpc3QocmV0dXJucy5kZiRyX1NCVVgsIG1haW49Ikhpc3RvZ3JhbSBvZiBTQlVYIG1vbnRobHkgcmV0dXJucyIsIAogICAgIHhsYWI9IkNvbnRpbnVvdXNseSBDb21wb3VuZGVkIHJldHVybnMiLCBjb2w9ImRhcmsgZ3JlZW4iKQpgYGAKCiMjUVVFU1RJT05TOgoKIyMgUVVFU1RJT046IElOVEVSUFJFVCBUSElTIEhJU1RPR1JBTSBXSVRIIFlPVVIgT1dOIFdPUkRTCklmIHdlIGluY3JlYXNlIHRoZSBjb21wb3VuZCBmcmVxdWVuY3kgdG8gaXRzIGxpbWl0LCB3ZSBhcmUgY29tcG91bmRpbmcgY29udGludW91c2x5LiBSZXR1cm5zIGFyZSBiZWluZyBjb21wb3VuZGVkIGNvbnN0YW50bHkgcmVzdWx0aW5nIGluIG1vbmV5IGFjcXVpcmluZyBzdHJlbmd0aCB0aHJvdWdoIGludGVyZXN0IHJhdGVzLiBDb250aW5pb3VzbHkgY29tcG91bmRlZCByZXR1cm5zIGV4aGliaXQgYW4gaW5jcmVtZW50IGluIGZyZXF1ZW5jeSBpbiB0aGUgMC4wLTAuMSByYW5nZS4KCiMjIFFVRVNUSU9OOiBIT1cgTUVBTiBBTkQgU1RBTkRBUkQgREVWSUFUSU9OIElTIFJFTEFURUQgV0lUSCBUSEUgSElTVE9CUkFNPwpUbyBjYWxjdWxhdGUgdGhlIG1lYW4gd2UgYWRkIHVwIHRoZSBvYnNlcnZlZCB2YWx1ZXMgYW5kIGRpdmlkZSBieSB0aGUgbnVtYmVyIG9mIHRoZW0uIFRodXMgdGhlIGhpc3RvZ3JhbSBkZW1vbnN0cmF0ZXMgdGhlIGZyZXF1ZW5jeSBhIGNvbnRpbmlvdXMgY29tcG91bmQgdGhyb3VnaCB0aW1lIHVzaW5nIG1lYW4uICJBIHN0YW5kYXJkIGRldmlhdGlvbiBpcyBhIHN0YXRpc3RpYyB0aGF0IG1lYXN1cmVzIHRoZSBkaXNwZXJzaW9uIG9mIGEgZGF0YXNldCByZWxhdGl2ZSB0byBpdHMgbWVhbiIgKEJsYW5kLCBKLk0uOyBBbHRtYW4sIEQuRy4pIGFuZCBpbiB0aGlzIGhpc3RvZ3JhbSB0aGUgc3RhbmRhcmQgZGV2aWF0aW9uIGRvZXMganVzdCB0aGF0LCBpdCBkZW1vbnN0cmF0ZXMgaG93IGZhciBhd2F5IHRoZSBtZWFuIHNwcmVhZHMgdGhyb3VnaCB0aGUgZnJlcXVlbmN5IG9mIGNvbnRpbmlvdXMgY29tcG91bmRpbmcuIAoKIyMgUSBIaXN0b2dyYW0gdXNpbmcgc2ltdWxhdGVkIGRhdGEgZm9yIHJldHVybnMKCmBgYHtyfQpyU0JVWF9zaW0gPC0gcm5vcm0obj1ucm93KHJldHVybnMuZGYpLCBtZWFuID0gbWVhbl9yX1NCVVgsIHNkPXNkX3JfU0JVWCkKYGBgCgpgYGB7cn0KclNCVVggPC0gbmEub21pdChyZXR1cm5zLmRmJHJfU0JVWCkKYGBgCgpgYGB7cn0KaGlzdF9zaW1fU0JVWDwtIGhpc3QoclNCVVhfc2ltLHBsb3QgPSBGQUxTRSkKYGBgCgpgYGB7cn0KaGlzdF9TQlVYIDwtIGhpc3QoclNCVVhfc2ltLHBsb3QgPSBGQUxTRSkKYGBgCgpgYGB7cn0KeGxpbSA8LSByYW5nZShoaXN0X1NCVVgkYnJlYWtzLGhpc3Rfc2ltX1NCVVgkYnJlYWtzKQp5bGltIDwtIHJhbmdlKDAsaGlzdF9TQlVYJGRlbnNpdHksCiAgICAgICAgICAgICAgaGlzdF9zaW1fU0JVWCRkZW5zaXR5KQpgYGAKCmBgYHtyfQpwbG90KGhpc3Rfc2ltX1NCVVgseGxpbSA9IHhsaW0sIHlsaW0gPSB5bGltLAogICAgIGNvbCA9IHJnYigxLDAsMCwwLjQpLHhsYWIgPSAnTGVuZ3RocycsIGZyZXEgPSBGQUxTRSwgbWFpbiA9ICdEaXN0cmlidXRpb24gb2Ygc2ltdWxhdGVkIGFuZCByZWFsIFN0YXJidWNrcyBSZXR1cm5zJykKYGBgCiMjICJObyBwdWRlIGhhY2VyIGVsIMO6bHRpbW8gaGlzdG9ncmFtYSBjb24gY29sb3JlcywgbWUgYXBhcmVjZSBlcnJvciBhbCBtZXRlciBlbCBjb2RpZ28gZGVsIFJwdWJzIGFzw60gcXVlIGxvIG1vZGlmaXF1w6kgcGFyYSBxdWUgbcOtbmltbyBhcGFyZWNpZXJhIHVuYSB0YWJsYS4gTWUgZ3VzdGFyw61hIHNhYmVyIHNpIHBvZGVtb3MgcmV2aXNhciBlc3RvIGVuIGNsYXNlLiIgU3RlZmFuIFMuIApgYGB7cn0Kb3BhciA8LSBwYXIobmV3ID0gRkFMU0UpCnBsb3QoaGlzdF9TQlVYLHhsaW0gPSB4bGltLCB5bGltID0geWxpbSkKY29sID0gcmdiKDAsMCwxLDAuNCkKZmlsbD1yZ2IoMC4xLDAuNCwwLjUsMC43KQpmcmVxID0gRkFMU0UKbWFpbiA9ICdEaXN0cmlidXRpb24gb2Ygc2ltdWxhdGVkIGFuZCByZWFsIFN0YXJidWNrcyBSZXR1cm5zJwpsZWdlbmQoJ3RvcGxlZnQnLGMoJ1NpbXVsYXRlZCBSZXR1cm5zJywnUmVhbCBSZXR1cm5zJyksCiAgICAgICBmaWxsID0gcmdiKDE6MCwwLDA6MSwwLjQpLCBidHkgPSAnbicpCgpgYGAKCgojIyBRVUVTVElPTjogV0hBVCBESUZGRVJFTkNFIERPIFlPVSBTRUUgSU4gVEhFIEhJU1RPR1JBTVM/IEhPVyBSRUFMIFJFVFVSTlMgQVJFIERJRkZFUkVOVCBGUk9NIFRIRSBUSEVPUkVUSUNBTCBOT1JNQUwgRElTVFJJQlVUSU9OIE9GIFJFVFVSTlM/IEJSSUVGTFkgRVhQTEFJTi4KCkNyZWF0aW5nIGEgYnVkZ2V0IHZzLiBhY3R1YWwgY29tcGFyaXNvbiBpcyBleHRyZW1lbHkgaW1wb3J0YW50IGZvciBhbGwgYnVzaW5lc3NlcyBiZWNhdXNlIGl0IGFsbG93cyB0aGVtIHRvIGFsdGVyIHRoZWlyIGZ1dHVyZSBmaW5hbmNpYWwgZm9yZWNhc3RzIGJhc2VkIHVwb24gdGhlIG51bWJlcnMgY29sbGVjdGVkIGluIHRoZSBtb250aGx5IHJlcG9ydHMuIFJlYWwgcmV0dXJucyBoYW5nIG9uIHRoZSBwb3NpdGl2ZSBzaWRlIG9mIHRoZSBiYWxhbmNlLCBpbmRpY2F0aW5nIGZ1dHVyZSBhZGp1c3RtZW50cyBtdXN0IGJlIG1hZGUuIAoKIyMgUVVFU1RJT046IFdIQVQgV09VTEQgQkUgVEhFIDk1JSBDT05GSURFTkNFIElOVEVSVkFMPyBXSEFUIElTIFRIRSBJTlRFUlBSRVRBVElPTiBPRiBUSElTIElOVEVSVkFMPyBFWFBMQUlOLgoKUmVtZW1iZXJpbmcgbXkgcHJldmlvdXMgc3RhdGlzdGljcyBjbGFzc2VzLCB0aGVyZSB3YXMgYWx3YXlzIGEgZGVncmVlIG9mIHVuY2VydGFpbnR5LCB3aGljaCB3b3VsZCB2YXJ5IGFjY29yZGluZyB0byBudW1lcm91cyBmYWN0b3JzLiBXaWRlbHkgYWNjZXB0ZWQgaXMgdGhlIDUlIHVuY2VydGFpbnR5IGRlZ3JlZSwgdGh1cyBvbmUgY2FuIGJlIHN1cmUgb2YgdGhlIG90aGVyIDk1JSBvZiB0aGUgYXZhaWxhYmxlIGRhdGEuIAoK