Case 1: Introduction
On the one hand, STOXX Europe Large 200 Index (LCXP) is an index which includes the biggest 200 companies in terms of market value. The index is part of the STOXX Europe 600 Size Index which includes 200 “large”, 200 “mid” and 200 “small” companies.
On the oher hand, “Sell in May and go Away” is an investment strategy which consist on investing only during the period from November to April of the next year. Thus, the idea is to buy (invest) in November and to sell everything at the beginning of May. Bouman and Jacobsen (2002) show that effect is presented in 36 of the 37 analyzed. It is also interesting to read the work by Stephen Eckett (“Stock UK Market Almanac 2015”) about this effect.
TASK:
Using STOXX Europe Large 200 Index (LCXP), you have to verify the “sell in may and go away” strategy. It is recommended to buy the index the first market day in Novemeber and to sell the index the first trading day of May. The solution is not unique in any case.
Solution:
First thing we need to do is to require some libraries (in case you do not have them installed you should install them). After that, we just use the function “read.csv2” to load data in the variable “tempData”.
library(knitr)
library(kableExtra)
library(quantmod) #Package to download financials historical data
library(moments) # Calculate Kurstosis and skewness
library(ggplot2) #Plot library
library(ggfortify) #Plot Monthplot
library(plyr) #Using ddply with data.frames
# Read data from CSV file
tempData<-read.csv2("./LCXP.csv")
The code above just read the .csv file which is stored in the path ./LCXP.csv (the file LCXP.csv is in CANVAS). Just to show how data is stored in R, lets see how the variable “tempData” looks like:
head(tempData)
Next step is to convert data to XTS and to calculate the monthly returns.
#Convert data to XTS
xData=xts(tempData$Precio, order.by = as.Date(tempData$Fecha,"%Y-%m-%d"),frequency=365)
#Calculate data size
xRent=monthlyReturn(xData,type='log',leading=FALSE)
xRent=xRent['199201/201508']
nObs=length(xRent)
nObs
[1] 284
For this case is gonna be better if we build a data frame to store the data.
# Generate data frame
meses=.indexmon(xRent) #Assign Month to each data
df <- data.frame(mes=meses+1,coredata(xRent))
colnames(df)[2] <- "rent" #Change name
Now, we just compute some conditional statistics of our monthly returns.
# Month conditional statistics
ddf=ddply(df,.(mes),summarize,media=mean(rent),mediana=median(rent),dt=sd(rent),obs=length(rent),
positivos=sum((rent>0)),negativos=sum((rent<0)),prob_UP=sum((rent>0))/length(rent),
max_pos=max(rent[rent>0]),max_neg=min(rent[rent<0]))
table1 = t(ddf)
kable(table1)
|
mes
|
1.0000000
|
2.0000000
|
3.0000000
|
4.0000000
|
5.0000000
|
6.0000000
|
7.0000000
|
8.0000000
|
9.0000000
|
10.0000000
|
11.0000000
|
12.0000000
|
|
media
|
0.0048768
|
0.0057245
|
0.0043251
|
0.0224931
|
-0.0049948
|
-0.0094819
|
0.0095757
|
-0.0119813
|
-0.0145514
|
0.0166475
|
0.0136914
|
0.0198985
|
|
mediana
|
0.0197142
|
0.0106967
|
0.0123348
|
0.0218837
|
0.0004945
|
-0.0066055
|
0.0147372
|
0.0042814
|
0.0073940
|
0.0231118
|
0.0209288
|
0.0296689
|
|
dt
|
0.0463765
|
0.0441319
|
0.0335605
|
0.0386941
|
0.0323946
|
0.0431295
|
0.0488237
|
0.0504278
|
0.0580983
|
0.0496436
|
0.0398150
|
0.0411880
|
|
obs
|
24.0000000
|
24.0000000
|
24.0000000
|
24.0000000
|
24.0000000
|
24.0000000
|
24.0000000
|
24.0000000
|
23.0000000
|
23.0000000
|
23.0000000
|
23.0000000
|
|
positivos
|
15.0000000
|
15.0000000
|
14.0000000
|
17.0000000
|
12.0000000
|
10.0000000
|
14.0000000
|
12.0000000
|
13.0000000
|
18.0000000
|
16.0000000
|
17.0000000
|
|
negativos
|
9.0000000
|
9.0000000
|
10.0000000
|
7.0000000
|
12.0000000
|
14.0000000
|
10.0000000
|
12.0000000
|
10.0000000
|
5.0000000
|
7.0000000
|
6.0000000
|
|
prob_UP
|
0.6250000
|
0.6250000
|
0.5833333
|
0.7083333
|
0.5000000
|
0.4166667
|
0.5833333
|
0.5000000
|
0.5652174
|
0.7826087
|
0.6956522
|
0.7391304
|
|
max_pos
|
0.0688296
|
0.0656408
|
0.0755119
|
0.1183347
|
0.0408134
|
0.0615437
|
0.0954073
|
0.0447201
|
0.0728756
|
0.0952731
|
0.0822473
|
0.1038261
|
|
max_neg
|
-0.1244233
|
-0.1045698
|
-0.0494795
|
-0.0443199
|
-0.0674896
|
-0.1055598
|
-0.1096405
|
-0.1390101
|
-0.1536780
|
-0.1298327
|
-0.0753537
|
-0.0991509
|
NA
Some conclusions from the avobe table:
- The probability of “positive monthly return” in Octuber is 78,26% (max in the sample).
- However April is the month with the highest average return: 2,25%.
#Select First day of the month
xMonthFirstData=xData[head(endpoints(xData, "months") + 1, -1)]
#Generate indicator: 1 =[May to Nov]
Indicador=(.indexmon(xMonthFirstData)==10 | .indexmon(xMonthFirstData)==4)
#Select data from May to Nov
xNovMay=xMonthFirstData[Indicador]
#Sample begin Nov
xNovMay=xNovMay['199211/201508']
#Generate accumulate return [May-Nov]
xRentNovMay=diff(log(xNovMay))[.indexmon(xNovMay)==4]
#Generate accumulate return [May-Nov]
xRentMayNov=diff(log(xNovMay))[.indexmon(xNovMay)==10]
#Statistics
mean(xRentNovMay)
[1] 0.07207862
sd(xRentNovMay)
[1] 0.1169578
obs=length(xRentNovMay)
obs
[1] 23
Taking into account the returns statistics of the strategy, the average return is 7,2% and the standard deviation 11,7%.
#positive months
positivos=sum((xRentNovMay>0))
positivos
[1] 19
#negative months
negativos=sum((xRentNovMay<0))
negativos
[1] 4
Morover, 19 over the 23 months were positive. Thus the probability of positive return is 82,6% (see below).
#Probability(Positive Months)
prob_UP=positivos/obs
prob_UP
[1] 0.826087
#Accumulate negative return
sum(xRentNovMay[(xRentNovMay<0)])
[1] -0.4751633
#Accumulate positive return
sum(xRentNovMay[(xRentNovMay>0)])
[1] 2.132972
Cumulative return comparing negative months vs positive months. Finally, the most important test is to compare the mean return for the strategy (Nov to May) vs the rest of year (May to Nov).
We perform two different “t-test”:
- First T-test in which the null hypothesis is that means are equal (the difference between them is zero) and the alternative hypothesis is that true difference in means is not equal to 0.
#test for the difference between two means
t.test(xRentNovMay, xRentMayNov)
Recycling array of length 1 in array-vector arithmetic is deprecated.
Use c() or as.vector() instead.
Recycling array of length 1 in vector-array arithmetic is deprecated.
Use c() or as.vector() instead.
Welch Two Sample t-test
data: xRentNovMay and xRentMayNov
t = 2.0977, df = 40.251, p-value = 0.04225
alternative hypothesis: true difference in means is not equal to 0
95 percent confidence interval:
0.003044142 0.162717694
sample estimates:
mean of x mean of y
0.07207862 -0.01080229
We reject the null hypothesis (p-value = 0.04225) and thus, the true difference in means is greater than 0. Now we want to know if our strategy mean is higher than the “May-Nov” mean.
- Second T-test in which the null hypothesis is that the difference in means is not greater than zero and our alternative hypothesis is the “Nov-May” returns have a higher mean that “May-Nov” returns (rue difference in means is greater than 0).
#test for the difference between two means
t.test(xRentNovMay, xRentMayNov,alternative = "greater")
Recycling array of length 1 in vector-array arithmetic is deprecated.
Use c() or as.vector() instead.
Welch Two Sample t-test
data: xRentNovMay and xRentMayNov
t = 2.0977, df = 40.251, p-value = 0.02113
alternative hypothesis: true difference in means is greater than 0
95 percent confidence interval:
0.01636213 Inf
sample estimates:
mean of x mean of y
0.07207862 -0.01080229
We reject the null hypothesis (p-value = 0.02113) and thus our strategy mean is higher the “May-Nov” mean.
—-END—-
LS0tCnRpdGxlOiAiQ2FzZSAxOiBEYXRhIGFuZCBSZXR1cm5zIChTb2x1dGlvbikiCm91dHB1dDogaHRtbF9ub3RlYm9vawotLS0KCjxoMz4gQ2FzZSAxOiBJbnRyb2R1Y3Rpb24gPC9oMz4KCk9uIHRoZSBvbmUgaGFuZCwgU1RPWFggRXVyb3BlIExhcmdlIDIwMCBJbmRleCAoTENYUCkgaXMgYW4gaW5kZXggd2hpY2ggaW5jbHVkZXMgdGhlIGJpZ2dlc3QgMjAwIGNvbXBhbmllcyBpbiB0ZXJtcyBvZiBtYXJrZXQgdmFsdWUuIFRoZSBpbmRleCBpcyBwYXJ0IG9mIHRoZSBTVE9YWCBFdXJvcGUgNjAwIFNpemUgSW5kZXggd2hpY2ggaW5jbHVkZXMgMjAwICJsYXJnZSIsIDIwMCAibWlkIiBhbmQgMjAwICJzbWFsbCIgY29tcGFuaWVzLgoKT24gdGhlIG9oZXIgaGFuZCwgIlNlbGwgaW4gTWF5IGFuZCBnbyBBd2F5IiBpcyBhbiBpbnZlc3RtZW50IHN0cmF0ZWd5IHdoaWNoIGNvbnNpc3Qgb24gaW52ZXN0aW5nIG9ubHkgZHVyaW5nIHRoZSBwZXJpb2QgZnJvbSBOb3ZlbWJlciB0byBBcHJpbCBvZiB0aGUgbmV4dCB5ZWFyLiBUaHVzLCB0aGUgaWRlYSBpcyB0byBidXkgKGludmVzdCkgaW4gTm92ZW1iZXIgYW5kIHRvIHNlbGwgZXZlcnl0aGluZyBhdCB0aGUgYmVnaW5uaW5nIG9mIE1heS4gQm91bWFuIGFuZCBKYWNvYnNlbiAoMjAwMikgc2hvdyB0aGF0IGVmZmVjdCBpcyBwcmVzZW50ZWQgaW4gMzYgb2YgdGhlIDM3IGFuYWx5emVkLiBJdCBpcyBhbHNvIGludGVyZXN0aW5nIHRvIHJlYWQgdGhlIHdvcmsgYnkgU3RlcGhlbiBFY2tldHQgKCJTdG9jayBVSyBNYXJrZXQgQWxtYW5hYyAyMDE1IikgYWJvdXQgdGhpcyBlZmZlY3QuIAoKCgo8aDQ+IFRBU0s6IDwvaDQ+CgpVc2luZyBTVE9YWCBFdXJvcGUgTGFyZ2UgMjAwIEluZGV4IChMQ1hQKSwgeW91IGhhdmUgdG8gdmVyaWZ5IHRoZSAic2VsbCBpbiBtYXkgYW5kIGdvIGF3YXkiIHN0cmF0ZWd5LiBJdCBpcyByZWNvbW1lbmRlZCB0byBidXkgdGhlIGluZGV4IHRoZSBmaXJzdCBtYXJrZXQgZGF5IGluIE5vdmVtZWJlciBhbmQgdG8gc2VsbCB0aGUgaW5kZXggdGhlIGZpcnN0IHRyYWRpbmcgZGF5IG9mIE1heS4gVGhlIHNvbHV0aW9uIGlzIG5vdCB1bmlxdWUgaW4gYW55IGNhc2UuIAoKCiFbRmlndXJlIDE6IEJsb29tYmVyZyBMWENQXShCbG9vbWJlcmdEYXRhLmpwZykKCjxoMz4gU29sdXRpb246IDwvaDM+CgoKRmlyc3QgdGhpbmcgd2UgbmVlZCB0byBkbyBpcyB0byByZXF1aXJlIHNvbWUgbGlicmFyaWVzIChpbiBjYXNlIHlvdSBkbyBub3QgaGF2ZSB0aGVtIGluc3RhbGxlZCB5b3Ugc2hvdWxkIGluc3RhbGwgdGhlbSkuIEFmdGVyIHRoYXQsIHdlIGp1c3QgdXNlIHRoZSBmdW5jdGlvbiAicmVhZC5jc3YyIiB0byBsb2FkIGRhdGEgaW4gdGhlIHZhcmlhYmxlICJ0ZW1wRGF0YSIuCgoKYGBge3J9CgpsaWJyYXJ5KGtuaXRyKQpsaWJyYXJ5KGthYmxlRXh0cmEpCmxpYnJhcnkocXVhbnRtb2QpICNQYWNrYWdlIHRvIGRvd25sb2FkIGZpbmFuY2lhbHMgaGlzdG9yaWNhbCBkYXRhIApsaWJyYXJ5KG1vbWVudHMpICMgQ2FsY3VsYXRlIEt1cnN0b3NpcyBhbmQgc2tld25lc3MKbGlicmFyeShnZ3Bsb3QyKSAjUGxvdCBsaWJyYXJ5CmxpYnJhcnkoZ2dmb3J0aWZ5KSAjUGxvdCBNb250aHBsb3QKbGlicmFyeShwbHlyKSAjVXNpbmcgZGRwbHkgd2l0aCBkYXRhLmZyYW1lcwoKIyBSZWFkIGRhdGEgZnJvbSBDU1YgZmlsZQp0ZW1wRGF0YTwtcmVhZC5jc3YyKCIuL0xDWFAuY3N2IikKYGBgCgpUaGUgY29kZSBhYm92ZSBqdXN0IHJlYWQgdGhlIC5jc3YgZmlsZSB3aGljaCBpcyBzdG9yZWQgaW4gdGhlIHBhdGggLi9MQ1hQLmNzdiAodGhlIGZpbGUgTENYUC5jc3YgaXMgaW4gQ0FOVkFTKS4gSnVzdCB0byBzaG93IGhvdyBkYXRhIGlzIHN0b3JlZCBpbiBSLCBsZXRzIHNlZSBob3cgdGhlIHZhcmlhYmxlICJ0ZW1wRGF0YSIgbG9va3MgbGlrZToKCmBgYHtyfQpoZWFkKHRlbXBEYXRhKQpgYGAKCgpOZXh0IHN0ZXAgaXMgdG8gY29udmVydCBkYXRhIHRvIFhUUyBhbmQgdG8gY2FsY3VsYXRlIHRoZSBtb250aGx5IHJldHVybnMuCgoKYGBge3J9CiNDb252ZXJ0IGRhdGEgdG8gWFRTCnhEYXRhPXh0cyh0ZW1wRGF0YSRQcmVjaW8sIG9yZGVyLmJ5ID0gYXMuRGF0ZSh0ZW1wRGF0YSRGZWNoYSwiJVktJW0tJWQiKSxmcmVxdWVuY3k9MzY1KQoKI0NhbGN1bGF0ZSBkYXRhIHNpemUKeFJlbnQ9bW9udGhseVJldHVybih4RGF0YSx0eXBlPSdsb2cnLGxlYWRpbmc9RkFMU0UpCnhSZW50PXhSZW50WycxOTkyMDEvMjAxNTA4J10Kbk9icz1sZW5ndGgoeFJlbnQpCm5PYnMKCmBgYAoKRm9yIHRoaXMgY2FzZSBpcyBnb25uYSBiZSBiZXR0ZXIgaWYgd2UgYnVpbGQgYSBkYXRhIGZyYW1lIHRvIHN0b3JlIHRoZSBkYXRhLiAKCmBgYHtyfQojIEdlbmVyYXRlIGRhdGEgZnJhbWUKbWVzZXM9LmluZGV4bW9uKHhSZW50KSAjQXNzaWduIE1vbnRoIHRvIGVhY2ggZGF0YQpkZiA8LSBkYXRhLmZyYW1lKG1lcz1tZXNlcysxLGNvcmVkYXRhKHhSZW50KSkKY29sbmFtZXMoZGYpWzJdIDwtICJyZW50IiAjQ2hhbmdlIG5hbWUKCmBgYAoKCk5vdywgd2UganVzdCBjb21wdXRlIHNvbWUgY29uZGl0aW9uYWwgc3RhdGlzdGljcyBvZiBvdXIgbW9udGhseSByZXR1cm5zLgoKYGBge3J9CgojIE1vbnRoIGNvbmRpdGlvbmFsIHN0YXRpc3RpY3MKZGRmPWRkcGx5KGRmLC4obWVzKSxzdW1tYXJpemUsbWVkaWE9bWVhbihyZW50KSxtZWRpYW5hPW1lZGlhbihyZW50KSxkdD1zZChyZW50KSxvYnM9bGVuZ3RoKHJlbnQpLCAKICAgICAgICAgIHBvc2l0aXZvcz1zdW0oKHJlbnQ+MCkpLG5lZ2F0aXZvcz1zdW0oKHJlbnQ8MCkpLHByb2JfVVA9c3VtKChyZW50PjApKS9sZW5ndGgocmVudCksIAogICAgICAgICAgbWF4X3Bvcz1tYXgocmVudFtyZW50PjBdKSxtYXhfbmVnPW1pbihyZW50W3JlbnQ8MF0pKQoKdGFibGUxID0gdChkZGYpCmthYmxlKHRhYmxlMSkKCmBgYAoKU29tZSBjb25jbHVzaW9ucyBmcm9tIHRoZSBhdm9iZSB0YWJsZToKCigxKSBUaGUgcHJvYmFiaWxpdHkgb2YgInBvc2l0aXZlIG1vbnRobHkgcmV0dXJuIiBpbiBPY3R1YmVyIGlzIDc4LDI2JSAobWF4IGluIHRoZSBzYW1wbGUpLiAKKDIpIEhvd2V2ZXIgQXByaWwgaXMgdGhlIG1vbnRoIHdpdGggdGhlIGhpZ2hlc3QgYXZlcmFnZSByZXR1cm46IDIsMjUlLgoKCgpgYGB7cn0KCiNTZWxlY3QgRmlyc3QgZGF5IG9mIHRoZSBtb250aAp4TW9udGhGaXJzdERhdGE9eERhdGFbaGVhZChlbmRwb2ludHMoeERhdGEsICJtb250aHMiKSArIDEsIC0xKV0KCiNHZW5lcmF0ZSBpbmRpY2F0b3I6IDEgPVtNYXkgdG8gTm92XQpJbmRpY2Fkb3I9KC5pbmRleG1vbih4TW9udGhGaXJzdERhdGEpPT0xMCB8IC5pbmRleG1vbih4TW9udGhGaXJzdERhdGEpPT00KQoKI1NlbGVjdCBkYXRhIGZyb20gTWF5IHRvIE5vdgp4Tm92TWF5PXhNb250aEZpcnN0RGF0YVtJbmRpY2Fkb3JdCgojU2FtcGxlIGJlZ2luIE5vdgp4Tm92TWF5PXhOb3ZNYXlbJzE5OTIxMS8yMDE1MDgnXQoKI0dlbmVyYXRlIGFjY3VtdWxhdGUgcmV0dXJuIFtNYXktTm92XQp4UmVudE5vdk1heT1kaWZmKGxvZyh4Tm92TWF5KSlbLmluZGV4bW9uKHhOb3ZNYXkpPT00XQojR2VuZXJhdGUgYWNjdW11bGF0ZSByZXR1cm4gW01heS1Ob3ZdCnhSZW50TWF5Tm92PWRpZmYobG9nKHhOb3ZNYXkpKVsuaW5kZXhtb24oeE5vdk1heSk9PTEwXQoKYGBgCgoKCmBgYHtyfQoKI1N0YXRpc3RpY3MKbWVhbih4UmVudE5vdk1heSkKc2QoeFJlbnROb3ZNYXkpCm9icz1sZW5ndGgoeFJlbnROb3ZNYXkpCm9icwoKYGBgCgpUYWtpbmcgaW50byBhY2NvdW50IHRoZSByZXR1cm5zIHN0YXRpc3RpY3Mgb2YgdGhlIHN0cmF0ZWd5LCB0aGUgYXZlcmFnZSByZXR1cm4gaXMgNywyJSBhbmQgdGhlIHN0YW5kYXJkIGRldmlhdGlvbiAxMSw3JS4gCgpgYGB7cn0KI3Bvc2l0aXZlIG1vbnRocwpwb3NpdGl2b3M9c3VtKCh4UmVudE5vdk1heT4wKSkKcG9zaXRpdm9zCiNuZWdhdGl2ZSBtb250aHMKbmVnYXRpdm9zPXN1bSgoeFJlbnROb3ZNYXk8MCkpCm5lZ2F0aXZvcwoKYGBgCgpNb3JvdmVyLCAxOSBvdmVyIHRoZSAyMyBtb250aHMgd2VyZSBwb3NpdGl2ZS4gVGh1cyB0aGUgcHJvYmFiaWxpdHkgb2YgcG9zaXRpdmUgcmV0dXJuIGlzIDgyLDYlIChzZWUgYmVsb3cpLgoKYGBge3J9CiNQcm9iYWJpbGl0eShQb3NpdGl2ZSBNb250aHMpCnByb2JfVVA9cG9zaXRpdm9zL29icwpwcm9iX1VQCgpgYGAKCgoKCmBgYHtyfQojQWNjdW11bGF0ZSBuZWdhdGl2ZSByZXR1cm4Kc3VtKHhSZW50Tm92TWF5Wyh4UmVudE5vdk1heTwwKV0pCgojQWNjdW11bGF0ZSBwb3NpdGl2ZSByZXR1cm4Kc3VtKHhSZW50Tm92TWF5Wyh4UmVudE5vdk1heT4wKV0pCgpgYGAKCkN1bXVsYXRpdmUgcmV0dXJuIGNvbXBhcmluZyBuZWdhdGl2ZSBtb250aHMgdnMgcG9zaXRpdmUgbW9udGhzLiBGaW5hbGx5LCB0aGUgbW9zdCBpbXBvcnRhbnQgdGVzdCBpcyB0byBjb21wYXJlIHRoZSBtZWFuIHJldHVybiBmb3IgdGhlIHN0cmF0ZWd5IChOb3YgdG8gTWF5KSB2cyB0aGUgcmVzdCBvZiB5ZWFyIChNYXkgdG8gTm92KS4gCgpXZSBwZXJmb3JtIHR3byBkaWZmZXJlbnQgInQtdGVzdCI6CgooMSkgRmlyc3QgVC10ZXN0IGluIHdoaWNoIHRoZSBudWxsIGh5cG90aGVzaXMgaXMgdGhhdCBtZWFucyBhcmUgZXF1YWwgKHRoZSBkaWZmZXJlbmNlIGJldHdlZW4gdGhlbSBpcyB6ZXJvKSBhbmQgdGhlIGFsdGVybmF0aXZlIGh5cG90aGVzaXMgaXMgdGhhdCB0cnVlIGRpZmZlcmVuY2UgaW4gbWVhbnMgaXMgbm90IGVxdWFsIHRvIDAuCgoKCmBgYHtyfQojdGVzdCBmb3IgdGhlIGRpZmZlcmVuY2UgYmV0d2VlbiB0d28gbWVhbnMKCnQudGVzdCh4UmVudE5vdk1heSwgeFJlbnRNYXlOb3YpCgpgYGAKCldlIHJlamVjdCB0aGUgbnVsbCBoeXBvdGhlc2lzIChwLXZhbHVlID0gMC4wNDIyNSkgYW5kIHRodXMsIHRoZSB0cnVlIGRpZmZlcmVuY2UgaW4gbWVhbnMgaXMgZ3JlYXRlciB0aGFuIDAuIE5vdyB3ZSB3YW50IHRvIGtub3cgaWYgb3VyIHN0cmF0ZWd5IG1lYW4gaXMgaGlnaGVyIHRoYW4gdGhlICJNYXktTm92IiBtZWFuLiAKCgooMikgU2Vjb25kIFQtdGVzdCBpbiB3aGljaCB0aGUgbnVsbCBoeXBvdGhlc2lzIGlzIHRoYXQgdGhlIGRpZmZlcmVuY2UgaW4gbWVhbnMgaXMgbm90IGdyZWF0ZXIgdGhhbiB6ZXJvIGFuZCBvdXIgYWx0ZXJuYXRpdmUgaHlwb3RoZXNpcyBpcyB0aGUgIk5vdi1NYXkiIHJldHVybnMgaGF2ZSBhIGhpZ2hlciBtZWFuIHRoYXQgIk1heS1Ob3YiIHJldHVybnMgKHJ1ZSBkaWZmZXJlbmNlIGluIG1lYW5zIGlzIGdyZWF0ZXIgdGhhbiAwKS4KCmBgYHtyfQojdGVzdCBmb3IgdGhlIGRpZmZlcmVuY2UgYmV0d2VlbiB0d28gbWVhbnMKCnQudGVzdCh4UmVudE5vdk1heSwgeFJlbnRNYXlOb3YsYWx0ZXJuYXRpdmUgPSAiZ3JlYXRlciIpCgpgYGAKCgpXZSByZWplY3QgdGhlIG51bGwgaHlwb3RoZXNpcyAocC12YWx1ZSA9IDAuMDIxMTMpIGFuZCB0aHVzIG91ciBzdHJhdGVneSBtZWFuIGlzIGhpZ2hlciB0aGUgIk1heS1Ob3YiIG1lYW4uCgoKLS0tLUVORC0tLS0KCgo=