About
This worksheet looks at simulating, both arithmetics and geometric, Brownian motion for stock prices, pricing options, and calculating Greeks using numerical differentiation.
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
Always read carefully the instructions on Sakai. For clarity, tasks/questions to be completed/answered are highlighted in red color (visible in preview) and numbered according to their particular placement in the task section. Quite often you will need to add your own code chunk.
Execute all code chunks, preview, publish, and submit link on Sakai follwoing the naming convention. Make sure to add comments to your code where appropriate. Use own language!
Task 1: Simulating Brownian Motion
This task follows the two examples in the book R Example 5.1/p 148 for simulating an arithmetic Brownian motion and R Example 5.2/p152 for simulating a geometric motion. Two new packages will be required for this worksheet. They are included in the code chunk below.
#Install package quantmod
if(!require("quantmod",quietly = TRUE))
install.packages("quantmod",dependencies = TRUE, repos = "https://cloud.r-project.org")
#Install package sde for Stochastic Differential Equation
if(!require("sde",quietly = TRUE))
install.packages("sde",dependencies = TRUE, repos = "https://cloud.r-project.org")
Attaching package: ‘fda’
The following object is masked from ‘package:graphics’:
matplot
sde 2.0.15
Companion package to the book
‘Simulation and Inference for Stochastic Differential Equations With R Examples’
Iacus, Springer NY, (2008)
To check the errata corrige of the book, type vignette("sde.errata")
#Install package fOptions for pricing and evaluating basic options
if(!require("fOptions",quietly = TRUE))
install.packages("fOptions",dependencies = TRUE, repos = "https://cloud.r-project.org")
Attaching package: ‘timeSeries’
The following object is masked from ‘package:zoo’:
time<-
Attaching package: ‘fBasics’
The following object is masked from ‘package:TTR’:
volatility
##### 1A) Follow example in book to simulate and plot example of an arithmetic Brownian motion. Consider three values for n (number of points): \(2^2, 2^5, 2^{12}\). Explain behavior as n increases.
##inputs:
alpha=0; sigma=1; T=1; n=2^(2); X0=0.1;
#############Generate 1 trajectory
dt=T/n
t=seq(0,T,by=dt)
x=c(X0,alpha*dt+sigma*sqrt(dt)*rnorm(n,mean=0,sd=1))
Xt=cumsum(x)
plot(t,Xt,type='l',xlab="time")

##inputs:
alpha=0; sigma=1; T=1; n=2^(5); X0=0.1;
#############Generate 1 trajectory
dt=T/n
t=seq(0,T,by=dt)
x=c(X0,alpha*dt+sigma*sqrt(dt)*rnorm(n,mean=0,sd=1))
Xt=cumsum(x)
plot(t,Xt,type='l',xlab="time")

##inputs:
alpha=0; sigma=1; T=1; n=2^(12); X0=0.1;
#############Generate 1 trajectory
dt=T/n
t=seq(0,T,by=dt)
x=c(X0,alpha*dt+sigma*sqrt(dt)*rnorm(n,mean=0,sd=1))
Xt=cumsum(x)
plot(t,Xt,type='l',xlab="time")

“As n increases, which is the number of steps, you can observe that there is no predictable pattern. More so for small, incremental steps there is a random pattern of movements generated.Increasing the value of n,improves the quality of the approximate sample path to a true Brownian motion path.”
##### 1B) Write the mathematical equation representing the values along the y-axis in the above plot. Separately express what the value of each variable in the equation is. \[X(i)=X(i-1)+\alpha(T/n)+\sigma\epsilon_{i}\sqrt{T/n}\] \[\alpha=0\] \[\sigma=1;\]
\[T=1,n=2^{12},X_0=0.1\]
##### 1C) Follow example in book to simulate a geometric Brownian motion.
library(sde)
mu=0.16; sigma=0.2; P0=40; T = 1/12 ##1 month
nt=50; n=2^(8)
#############Generate nt trajectories
dt=T/n; t=seq(0,T,by=dt)
X=matrix(rep(0,length(t)*nt), nrow=nt)
for (i in 1:nt) {X[i,]= GBM(x=P0,r=mu,sigma=sigma,T=T,N=n)}
##Plot
ymax=max(X); ymin=min(X) #bounds for simulated prices
plot(t,X[1,],t='l',ylim=c(ymin, ymax), col=1,
ylab="Price P(t)",xlab="time t")
for(i in 2:nt){lines(t,X[i,], t='l',ylim=c(ymin, ymax),col=i)}

##### 1D) Write the mathematical equation representing the values along the y-axis in the above plot. Separately express what the value of each variable in the equation is. \[P_{t}=P_0exp((\mu-{{(\sigma^2}/2))T}+\sigma\epsilon_i\sqrt{\Delta{t}})\] \[\mu=0.16,\sigma=0.2,P_0=40,T = 1/12, nt=50, n=2^{8}\]
##### 1E) How is the geometric Brownian simulation different from the arithmetic simulation? Elaborate.
“The geometric motion shows possible paths of drift for an asset. It is different from the arithmetic because is it the logarithm of the random varying quantity to bypass the limiiation of possible negative values which makes it more ideal for modelling prices.”
Task 2: Option Pricing, Greeks, and Numerical Differentiation
Follows the example in the book R Example 5.3/p 156 and R Example 5.5/p 157
##### 2A) Calculate the Call and Put price of the given European Option. Explain what the variables r and b in the function call GBSOption represent.
library(fOptions)
GBSOption(TypeFlag = "c", S = 60, X = 65, Time = 1/4, r = 0.08, b = 0.08, sigma = 0.30)
Title:
Black Scholes Option Valuation
Call:
GBSOption(TypeFlag = "c", S = 60, X = 65, Time = 1/4, r = 0.08,
b = 0.08, sigma = 0.3)
Parameters:
Value:
TypeFlag c
S 60
X 65
Time 0.25
r 0.08
b 0.08
sigma 0.3
Option Price:
2.133372
Description:
Wed Dec 12 15:57:02 2018
library(fOptions)
GBSOption(TypeFlag = "p", S = 60, X = 65, Time = 1/4, r = 0.08, b = 0.08, sigma = 0.30)
Title:
Black Scholes Option Valuation
Call:
GBSOption(TypeFlag = "p", S = 60, X = 65, Time = 1/4, r = 0.08,
b = 0.08, sigma = 0.3)
Parameters:
Value:
TypeFlag p
S 60
X 65
Time 0.25
r 0.08
b 0.08
sigma 0.3
Option Price:
5.846286
Description:
Wed Dec 12 14:44:39 2018
r is the annualized rate of interest and b is the annualized cost-of-carry rate.
##### 2B) Calculate the particular Greeks Delta, Gamma, and Vega for the above corresponding Call option.
library(fOptions)
GBSGreeks(Selection="delta",TypeFlag="c",S=60,X=65,Time=1/4,r=0.08,b=0.08,sigma=0.30)
[1] 0.3724829
library(fOptions)
GBSGreeks(Selection="gamma",TypeFlag="c",S=60,X=65,Time=1/4,r=0.08,b=0.08,sigma=0.30)
[1] 0.04204276
library(fOptions)
GBSGreeks(Selection="vega",TypeFlag="c",S=60,X=65,Time=1/4,r=0.08,b=0.08,sigma=0.30)
[1] 11.35154
##### 2C) Calculate the Delta, Gamma, and Vega for same option using instead numerical differentiation. Write the mathematical equations corresponding to each numerical differentiation. \[\Delta = (2.4833-1.7818)/2*1, \Delta = 0. 35\] \[\Delta = (G(P_{t}+ \Delta P, t) - G(P_{t} - \Delta P, t)) /2 \Delta P \]
\[\Gamma = (2.4833+1.7818) - 2(2.133)/1^2 = 0.005\] \[\Gamma = (G(P_{t}+ \Delta P, t) + G(P_{t} - \Delta P, t) - 2 G(P_{t},t) / \Delta P^2 \]
\[vega = (2.707 - 1.575/2 *(0.05)) = 11.32\] \[Vega = (G(P_{t},\sigma + \Delta \sigma) - G(P_{t}, \sigma - \Delta\sigma)) /2 \Delta\sigma \]
##### 2D) Compare results from 2B and 2C. Share observations.
My delta and vega values are pretty similar to the values calculated in the code. I believe there is some disrespancy with my gamma. I believe the code gives more accurate values for the greeks than the numerical differentiation due to the tiny changes in movement and volatility.
*http://computationalfinance.lsi.upc.edu
LS0tCnRpdGxlOiAiRklOQzYyMSBXaW50ZXIgMjAxOC0xOSBMYWIgV29ya3NoZWV0IDA0IgphdXRob3I6ICJDaHJpc3RvcGhlciBGcmFuY2lzIgpkYXRlOiAiRGVjZW1iZXIgMTIsIDIwMTgiCm91dHB1dDoKICBodG1sX25vdGVib29rOiBkZWZhdWx0CiAgcGRmX2RvY3VtZW50OiBkZWZhdWx0CiAgaHRtbF9kb2N1bWVudDogZGVmYXVsdApzdWJ0aXRsZTogU3RvY2hhc3RpYyBNb2RlbGluZyAmIE51bWVyaWNhbCBEaWZmZXJlbnRpYXRpb24gKGZpbmM2MjEtbGFiMDQpCi0tLQoKIyMjIEFib3V0CgpUaGlzIHdvcmtzaGVldCBsb29rcyBhdCBzaW11bGF0aW5nLCBib3RoIGFyaXRobWV0aWNzIGFuZCBnZW9tZXRyaWMsIEJyb3duaWFuIG1vdGlvbiBmb3Igc3RvY2sgcHJpY2VzLCBwcmljaW5nIG9wdGlvbnMsIGFuZCBjYWxjdWxhdGluZyBHcmVla3MgdXNpbmcgbnVtZXJpY2FsIGRpZmZlcmVudGlhdGlvbi4gIAoKIyMjIFNldHVwCgpSZW1lbWJlciB0byBhbHdheXMgc2V0IHlvdXIgd29ya2luZyBkaXJlY3RvcnkgdG8gdGhlIHNvdXJjZSBmaWxlIGxvY2F0aW9uLiBHbyB0byAnU2Vzc2lvbicsIHNjcm9sbCBkb3duIHRvICdTZXQgV29ya2luZyBEaXJlY3RvcnknLCBhbmQgY2xpY2sgJ1RvIFNvdXJjZSBGaWxlIExvY2F0aW9uJy4gUmVhZCBjYXJlZnVsbHkgdGhlIGJlbG93IGFuZCBmb2xsb3cgdGhlIGluc3RydWN0aW9ucyB0byBjb21wbGV0ZSB0aGUgdGFza3MgYW5kIGFuc3dlciBhbnkgcXVlc3Rpb25zLiAgU3VibWl0IHlvdXIgd29yayB0byBSUHVicyBhcyBkZXRhaWxlZCBpbiBwcmV2aW91cyBub3Rlcy4gCgojIyMgTm90ZQoKQWx3YXlzIHJlYWQgY2FyZWZ1bGx5IHRoZSBpbnN0cnVjdGlvbnMgb24gU2FrYWkuICBGb3IgY2xhcml0eSwgdGFza3MvcXVlc3Rpb25zIHRvIGJlIGNvbXBsZXRlZC9hbnN3ZXJlZCBhcmUgaGlnaGxpZ2h0ZWQgaW4gcmVkIGNvbG9yICh2aXNpYmxlIGluIHByZXZpZXcpIGFuZCBudW1iZXJlZCBhY2NvcmRpbmcgdG8gdGhlaXIgcGFydGljdWxhciBwbGFjZW1lbnQgaW4gdGhlIHRhc2sgc2VjdGlvbi4gIFF1aXRlIG9mdGVuIHlvdSB3aWxsIG5lZWQgdG8gYWRkIHlvdXIgb3duIGNvZGUgY2h1bmsuCgpFeGVjdXRlIGFsbCBjb2RlIGNodW5rcywgcHJldmlldywgcHVibGlzaCwgYW5kIHN1Ym1pdCBsaW5rIG9uIFNha2FpIGZvbGx3b2luZyB0aGUgbmFtaW5nIGNvbnZlbnRpb24uIE1ha2Ugc3VyZSB0byBhZGQgY29tbWVudHMgdG8geW91ciBjb2RlIHdoZXJlIGFwcHJvcHJpYXRlLiBVc2Ugb3duIGxhbmd1YWdlIQoKLS0tLS0tLS0tLS0tLS0KCiMjIyBUYXNrIDE6IFNpbXVsYXRpbmcgQnJvd25pYW4gTW90aW9uCgpUaGlzIHRhc2sgZm9sbG93cyB0aGUgdHdvIGV4YW1wbGVzIGluIHRoZSBib29rIGBSIEV4YW1wbGUgNS4xL3AgMTQ4YCBmb3Igc2ltdWxhdGluZyBhbiBhcml0aG1ldGljIEJyb3duaWFuIG1vdGlvbiBhbmQgYFIgRXhhbXBsZSA1LjIvcDE1MmAgZm9yIHNpbXVsYXRpbmcgYSBnZW9tZXRyaWMgbW90aW9uLiBUd28gbmV3IHBhY2thZ2VzIHdpbGwgYmUgcmVxdWlyZWQgZm9yIHRoaXMgd29ya3NoZWV0LiAgVGhleSBhcmUgaW5jbHVkZWQgaW4gdGhlIGNvZGUgY2h1bmsgYmVsb3cuCgpgYGB7cn0KI0luc3RhbGwgcGFja2FnZSBxdWFudG1vZCAKaWYoIXJlcXVpcmUoInF1YW50bW9kIixxdWlldGx5ID0gVFJVRSkpCiAgaW5zdGFsbC5wYWNrYWdlcygicXVhbnRtb2QiLGRlcGVuZGVuY2llcyA9IFRSVUUsIHJlcG9zID0gImh0dHBzOi8vY2xvdWQuci1wcm9qZWN0Lm9yZyIpCmBgYAoKYGBge3J9CiNJbnN0YWxsIHBhY2thZ2Ugc2RlIGZvciBTdG9jaGFzdGljIERpZmZlcmVudGlhbCBFcXVhdGlvbgppZighcmVxdWlyZSgic2RlIixxdWlldGx5ID0gVFJVRSkpCiAgaW5zdGFsbC5wYWNrYWdlcygic2RlIixkZXBlbmRlbmNpZXMgPSBUUlVFLCByZXBvcyA9ICJodHRwczovL2Nsb3VkLnItcHJvamVjdC5vcmciKQpgYGAKCmBgYHtyfQojSW5zdGFsbCBwYWNrYWdlIGZPcHRpb25zIGZvciBwcmljaW5nIGFuZCBldmFsdWF0aW5nIGJhc2ljIG9wdGlvbnMKaWYoIXJlcXVpcmUoImZPcHRpb25zIixxdWlldGx5ID0gVFJVRSkpCiAgaW5zdGFsbC5wYWNrYWdlcygiZk9wdGlvbnMiLGRlcGVuZGVuY2llcyA9IFRSVUUsIHJlcG9zID0gImh0dHBzOi8vY2xvdWQuci1wcm9qZWN0Lm9yZyIpCmBgYAoKCjxzcGFuIHN0eWxlPSJjb2xvcjpyZWQiPgojIyMjIyAxQSkgRm9sbG93IGV4YW1wbGUgaW4gYm9vayB0byBzaW11bGF0ZSBhbmQgcGxvdCBleGFtcGxlIG9mIGFuIGFyaXRobWV0aWMgQnJvd25pYW4gbW90aW9uLiBDb25zaWRlciB0aHJlZSB2YWx1ZXMgZm9yIG4gKG51bWJlciBvZiBwb2ludHMpOiAkMl4yLCAyXjUsIDJeezEyfSQuIEV4cGxhaW4gYmVoYXZpb3IgYXMgbiBpbmNyZWFzZXMuCjwvc3Bhbj4KYGBge3J9CiMjaW5wdXRzOgphbHBoYT0wOyBzaWdtYT0xOyBUPTE7IG49Ml4oMik7IFgwPTAuMTsKIyMjIyMjIyMjIyMjI0dlbmVyYXRlIDEgdHJhamVjdG9yeQpkdD1UL24KdD1zZXEoMCxULGJ5PWR0KQp4PWMoWDAsYWxwaGEqZHQrc2lnbWEqc3FydChkdCkqcm5vcm0obixtZWFuPTAsc2Q9MSkpClh0PWN1bXN1bSh4KQpwbG90KHQsWHQsdHlwZT0nbCcseGxhYj0idGltZSIpCmBgYApgYGB7cn0KIyNpbnB1dHM6CmFscGhhPTA7IHNpZ21hPTE7IFQ9MTsgbj0yXig1KTsgWDA9MC4xOwojIyMjIyMjIyMjIyMjR2VuZXJhdGUgMSB0cmFqZWN0b3J5CmR0PVQvbgp0PXNlcSgwLFQsYnk9ZHQpCng9YyhYMCxhbHBoYSpkdCtzaWdtYSpzcXJ0KGR0KSpybm9ybShuLG1lYW49MCxzZD0xKSkKWHQ9Y3Vtc3VtKHgpCnBsb3QodCxYdCx0eXBlPSdsJyx4bGFiPSJ0aW1lIikKYGBgCmBgYHtyfQojI2lucHV0czoKYWxwaGE9MDsgc2lnbWE9MTsgVD0xOyBuPTJeKDEyKTsgWDA9MC4xOwojIyMjIyMjIyMjIyMjR2VuZXJhdGUgMSB0cmFqZWN0b3J5CmR0PVQvbgp0PXNlcSgwLFQsYnk9ZHQpCng9YyhYMCxhbHBoYSpkdCtzaWdtYSpzcXJ0KGR0KSpybm9ybShuLG1lYW49MCxzZD0xKSkKWHQ9Y3Vtc3VtKHgpCnBsb3QodCxYdCx0eXBlPSdsJyx4bGFiPSJ0aW1lIikKYGBgCiJBcyBuIGluY3JlYXNlcywgd2hpY2ggaXMgdGhlIG51bWJlciBvZiBzdGVwcywgeW91IGNhbiBvYnNlcnZlIHRoYXQgdGhlcmUgaXMgbm8gcHJlZGljdGFibGUgcGF0dGVybi4gTW9yZSBzbyBmb3Igc21hbGwsIGluY3JlbWVudGFsIHN0ZXBzIHRoZXJlIGlzIGEgcmFuZG9tIHBhdHRlcm4gb2YgbW92ZW1lbnRzIGdlbmVyYXRlZC5JbmNyZWFzaW5nIHRoZSB2YWx1ZSBvZiBuLGltcHJvdmVzIHRoZSBxdWFsaXR5IG9mIHRoZSBhcHByb3hpbWF0ZSBzYW1wbGUgcGF0aCB0byBhIHRydWUgQnJvd25pYW4gbW90aW9uIHBhdGguIgoKPHNwYW4gc3R5bGU9ImNvbG9yOnJlZCI+CiMjIyMjIDFCKSBXcml0ZSB0aGUgbWF0aGVtYXRpY2FsIGVxdWF0aW9uIHJlcHJlc2VudGluZyB0aGUgdmFsdWVzIGFsb25nIHRoZSB5LWF4aXMgaW4gdGhlIGFib3ZlIHBsb3QuIFNlcGFyYXRlbHkgZXhwcmVzcyB3aGF0IHRoZSB2YWx1ZSBvZiBlYWNoIHZhcmlhYmxlIGluIHRoZSBlcXVhdGlvbiBpcy4KPC9zcGFuPgokJFgoaSk9WChpLTEpK1xhbHBoYShUL24pK1xzaWdtYVxlcHNpbG9uX3tpfVxzcXJ0e1Qvbn0kJAokJFxhbHBoYT0wJCQKJCRcc2lnbWE9MTskJCAKCiQkVD0xLG49Ml57MTJ9LFhfMD0wLjEkJAoKPHNwYW4gc3R5bGU9ImNvbG9yOnJlZCI+CiMjIyMjIDFDKSBGb2xsb3cgZXhhbXBsZSBpbiBib29rIHRvIHNpbXVsYXRlIGEgZ2VvbWV0cmljIEJyb3duaWFuIG1vdGlvbi4gCjwvc3Bhbj4KYGBge3J9CmxpYnJhcnkoc2RlKQptdT0wLjE2OyBzaWdtYT0wLjI7IFAwPTQwOyBUID0gMS8xMiAjIzEgbW9udGgKbnQ9NTA7IG49Ml4oOCkKIyMjIyMjIyMjIyMjI0dlbmVyYXRlIG50IHRyYWplY3RvcmllcwpkdD1UL247IHQ9c2VxKDAsVCxieT1kdCkKWD1tYXRyaXgocmVwKDAsbGVuZ3RoKHQpKm50KSwgbnJvdz1udCkKZm9yIChpIGluIDE6bnQpIHtYW2ksXT0gR0JNKHg9UDAscj1tdSxzaWdtYT1zaWdtYSxUPVQsTj1uKX0KIyNQbG90CnltYXg9bWF4KFgpOyB5bWluPW1pbihYKSAjYm91bmRzIGZvciBzaW11bGF0ZWQgcHJpY2VzCnBsb3QodCxYWzEsXSx0PSdsJyx5bGltPWMoeW1pbiwgeW1heCksIGNvbD0xLAogICAgeWxhYj0iUHJpY2UgUCh0KSIseGxhYj0idGltZSB0IikKZm9yKGkgaW4gMjpudCl7bGluZXModCxYW2ksXSwgdD0nbCcseWxpbT1jKHltaW4sIHltYXgpLGNvbD1pKX0KYGBgCgo8c3BhbiBzdHlsZT0iY29sb3I6cmVkIj4KIyMjIyMgMUQpIFdyaXRlIHRoZSBtYXRoZW1hdGljYWwgZXF1YXRpb24gcmVwcmVzZW50aW5nIHRoZSB2YWx1ZXMgYWxvbmcgdGhlIHktYXhpcyBpbiB0aGUgYWJvdmUgcGxvdC4gU2VwYXJhdGVseSBleHByZXNzIHdoYXQgdGhlIHZhbHVlIG9mIGVhY2ggdmFyaWFibGUgaW4gdGhlIGVxdWF0aW9uIGlzLgo8L3NwYW4+CiQkUF97dH09UF8wZXhwKChcbXUte3soXHNpZ21hXjJ9LzIpKVR9K1xzaWdtYVxlcHNpbG9uX2lcc3FydHtcRGVsdGF7dH19KSQkCiQkXG11PTAuMTYsXHNpZ21hPTAuMixQXzA9NDAsVCA9IDEvMTIsIG50PTUwLCBuPTJeezh9JCQKCgo8c3BhbiBzdHlsZT0iY29sb3I6cmVkIj4KIyMjIyMgMUUpIEhvdyBpcyB0aGUgZ2VvbWV0cmljIEJyb3duaWFuIHNpbXVsYXRpb24gZGlmZmVyZW50IGZyb20gdGhlIGFyaXRobWV0aWMgc2ltdWxhdGlvbj8gRWxhYm9yYXRlLgoKIlRoZSBnZW9tZXRyaWMgbW90aW9uIHNob3dzIHBvc3NpYmxlIHBhdGhzIG9mIGRyaWZ0IGZvciBhbiBhc3NldC4gSXQgaXMgZGlmZmVyZW50IGZyb20gdGhlIGFyaXRobWV0aWMgYmVjYXVzZSBpcyBpdCB0aGUgbG9nYXJpdGhtIG9mIHRoZSByYW5kb20gdmFyeWluZyBxdWFudGl0eSB0byBieXBhc3MgdGhlIGxpbWlpYXRpb24gb2YgcG9zc2libGUgbmVnYXRpdmUgdmFsdWVzIHdoaWNoIG1ha2VzIGl0IG1vcmUgaWRlYWwgZm9yIG1vZGVsbGluZyBwcmljZXMuIgoKPC9zcGFuPgoKCiMjIyBUYXNrIDI6IE9wdGlvbiBQcmljaW5nLCBHcmVla3MsIGFuZCBOdW1lcmljYWwgRGlmZmVyZW50aWF0aW9uCgpGb2xsb3dzIHRoZSBleGFtcGxlIGluIHRoZSBib29rICBgUiBFeGFtcGxlIDUuMy9wIDE1NiBgIGFuZCBgUiBFeGFtcGxlIDUuNS9wIDE1N2AKCjxzcGFuIHN0eWxlPSJjb2xvcjpyZWQiPgojIyMjIyAyQSkgQ2FsY3VsYXRlIHRoZSBDYWxsIGFuZCBQdXQgcHJpY2Ugb2YgdGhlIGdpdmVuIEV1cm9wZWFuIE9wdGlvbi4gIEV4cGxhaW4gd2hhdCB0aGUgdmFyaWFibGVzIGByYCBhbmQgYGJgIGluIHRoZSBmdW5jdGlvbiBjYWxsIGBHQlNPcHRpb25gIHJlcHJlc2VudC4gICAgCjwvc3Bhbj4KYGBge3J9CmxpYnJhcnkoZk9wdGlvbnMpCkdCU09wdGlvbihUeXBlRmxhZyA9ICJjIiwgUyA9IDYwLCBYID0gNjUsIFRpbWUgPSAxLzQsIHIgPSAwLjA4LCBiID0gMC4wOCwgc2lnbWEgPSAwLjMwKQpgYGAKYGBge3J9CmxpYnJhcnkoZk9wdGlvbnMpCkdCU09wdGlvbihUeXBlRmxhZyA9ICJwIiwgUyA9IDYwLCBYID0gNjUsIFRpbWUgPSAxLzQsIHIgPSAwLjA4LCBiID0gMC4wOCwgc2lnbWEgPSAwLjMwKQpgYGAKIyMjIHIgaXMgdGhlIGFubnVhbGl6ZWQgcmF0ZSBvZiBpbnRlcmVzdCBhbmQgYiBpcyB0aGUgYW5udWFsaXplZCBjb3N0LW9mLWNhcnJ5IHJhdGUuCgoKPHNwYW4gc3R5bGU9ImNvbG9yOnJlZCI+CiMjIyMjIDJCKSBDYWxjdWxhdGUgdGhlIHBhcnRpY3VsYXIgR3JlZWtzIERlbHRhLCBHYW1tYSwgYW5kIFZlZ2EgZm9yIHRoZSBhYm92ZSBjb3JyZXNwb25kaW5nIENhbGwgb3B0aW9uLgo8L3NwYW4+CmBgYHtyfQpsaWJyYXJ5KGZPcHRpb25zKQpHQlNHcmVla3MoU2VsZWN0aW9uPSJkZWx0YSIsVHlwZUZsYWc9ImMiLFM9NjAsWD02NSxUaW1lPTEvNCxyPTAuMDgsYj0wLjA4LHNpZ21hPTAuMzApCmBgYApgYGB7cn0KbGlicmFyeShmT3B0aW9ucykKR0JTR3JlZWtzKFNlbGVjdGlvbj0iZ2FtbWEiLFR5cGVGbGFnPSJjIixTPTYwLFg9NjUsVGltZT0xLzQscj0wLjA4LGI9MC4wOCxzaWdtYT0wLjMwKQpgYGAKYGBge3J9CmxpYnJhcnkoZk9wdGlvbnMpCkdCU0dyZWVrcyhTZWxlY3Rpb249InZlZ2EiLFR5cGVGbGFnPSJjIixTPTYwLFg9NjUsVGltZT0xLzQscj0wLjA4LGI9MC4wOCxzaWdtYT0wLjMwKQpgYGAKCjxzcGFuIHN0eWxlPSJjb2xvcjpyZWQiPgojIyMjIyAyQykgQ2FsY3VsYXRlIHRoZSBEZWx0YSwgR2FtbWEsIGFuZCBWZWdhIGZvciBzYW1lIG9wdGlvbiB1c2luZyBpbnN0ZWFkIG51bWVyaWNhbCBkaWZmZXJlbnRpYXRpb24uIFdyaXRlIHRoZSBtYXRoZW1hdGljYWwgZXF1YXRpb25zIGNvcnJlc3BvbmRpbmcgdG8gZWFjaCBudW1lcmljYWwgZGlmZmVyZW50aWF0aW9uLgo8L3NwYW4+CiQkXERlbHRhID0gKDIuNDgzMy0xLjc4MTgpLzIqMSwgXERlbHRhID0gMC4gMzUkJAokJFxEZWx0YSA9IChHKFBfe3R9KyBcRGVsdGEgUCwgdCkgLSBHKFBfe3R9IC0gXERlbHRhIFAsIHQpKSAvMiBcRGVsdGEgUCAkJAoKCiQkXEdhbW1hID0gKDIuNDgzMysxLjc4MTgpIC0gMigyLjEzMykvMV4yID0gMC4wMDUkJAokJFxHYW1tYSA9IChHKFBfe3R9KyBcRGVsdGEgUCwgdCkgKyBHKFBfe3R9IC0gXERlbHRhIFAsIHQpIC0gMiBHKFBfe3R9LHQpIC8gXERlbHRhIFBeMiAkJAoKCiQkdmVnYSA9ICgyLjcwNyAtIDEuNTc1LzIgKigwLjA1KSkgPSAxMS4zMiQkCiQkVmVnYSA9IChHKFBfe3R9LFxzaWdtYSArIFxEZWx0YSBcc2lnbWEpIC0gRyhQX3t0fSwgXHNpZ21hIC0gXERlbHRhXHNpZ21hKSkgLzIgXERlbHRhXHNpZ21hICQkCgo8c3BhbiBzdHlsZT0iY29sb3I6cmVkIj4KIyMjIyMgMkQpIENvbXBhcmUgcmVzdWx0cyBmcm9tIDJCIGFuZCAyQy4gU2hhcmUgb2JzZXJ2YXRpb25zLgoKTXkgZGVsdGEgYW5kIHZlZ2EgdmFsdWVzIGFyZSBwcmV0dHkgc2ltaWxhciB0byB0aGUgdmFsdWVzIGNhbGN1bGF0ZWQgaW4gdGhlIGNvZGUuIEkgYmVsaWV2ZSB0aGVyZSBpcyBzb21lIGRpc3Jlc3BhbmN5IHdpdGggbXkgZ2FtbWEuIEkgYmVsaWV2ZSB0aGUgY29kZSBnaXZlcyBtb3JlIGFjY3VyYXRlIHZhbHVlcyBmb3IgdGhlIGdyZWVrcyB0aGFuIHRoZSBudW1lcmljYWwgZGlmZmVyZW50aWF0aW9uIGR1ZSB0byB0aGUgdGlueSBjaGFuZ2VzIGluIG1vdmVtZW50IGFuZCB2b2xhdGlsaXR5LgoKKltodHRwOi8vY29tcHV0YXRpb25hbGZpbmFuY2UubHNpLnVwYy5lZHUgXShodHRwOi8vY29tcHV0YXRpb25hbGZpbmFuY2UubHNpLnVwYy5lZHUpCg==