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")
#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")

##### 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 the value of n increases, the time steps T/n becomes smaller and thus will improve the quality of the approximate sample path to a true Brownian path. Therefore, the higher the n, the closer it is to Brownian motion.

##### 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.

The value along the Y axis can be mathematically written as:

\(X(t) = X(t-1) +\alpha\frac{T}{n} + \sigma\varepsilon_{t}\sqrt{\frac{T}{n}}\)

The value \(\sigma\) measures the expected dri where, X(t) is an arithmetic Browninan, n is the number of steps/periods in the time interval, t is the steps in the time series. \(\frac{T}{n}\) represents the length of t, \(\alpha\) is the drift of the brownian motion.\(\varepsilon_{t}\) s a randomly generated number from a normal distribution of mean 0 and variance 1, \(\sigma\) is the volatility of the Brownian motion

##### 1C) Follow example in book to simulate a geometric Brownian motion.

library(sde)
Loading required package: MASS
Loading required package: stats4
Loading required package: fda
Loading required package: splines
Loading required package: Matrix

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")
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.

This can be mathematically written as:

\(P_T =((u- \frac{\sigma^2}{2})T + \sigma\varepsilon_{t}\sqrt{\Delta t})\)

where,\(P_T\), follows a geometric Brownian motion, the return \(r_t\) is normally distributed with mean \((u- \frac{\sigma^2}{2})T\) is the expected return and variance \(\sigma^2\) is the volatility of the price, \(\varepsilon_{t}\) is a randomly generated number from a normal distribution, t is the time series

##### 1E) How is the geometric Brownian simulation different from the arithmetic simulation? Elaborate.

A limitation of the arithmetic Brownian motion when used for modelling the price of a stock is the possibility of getting negative prices. However, this can be fixed by considering prices to be log normally distributed instead. Using log normally distributed data we generate the geometric Brownian motion and this keeps the price of stock postive.

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)
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:
 Tue Dec 11 21:11:56 2018 

The price for the European call option is 2.133372 and for the European put option is 5.846286. The variable “r” in GSB option represents the annualized rate of interest, a numeric value and “b” is the annualized cost of carry rate, a numeric value.

##### 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.

Using numerical differentiation, Delta \(\Delta\) = \(\Phi\)(\(d_{1}\)), \(d_{1}\) = \(\frac{ln (P_t/K) +(r+\sigma^2/2)(T-t)}{\sigma \sqrt{T-t}}\)

To get the values for \(d_{1}\), plug in the values in the above equation with the values of the call option

\(d_{1}\) = \(\frac{ln (60/65) +(0.08+0.3^2/2)(0.25)}{0.3 \sqrt{0.25}}\)

s= 60; k =65; r=0.08; sigma = 0.3; t= 0.25
d1 = (log(s/k)+ (r+sigma^2/2)*(t))/(sigma*sqrt(t))
d1
[1] -0.3252847
###value of delta
dnorm(d1)
[1] 0.3783848

Gamma \(\Gamma\) = \(\frac{\phi (d_{1})}{P \sigma \sqrt{T-t}}\) \(\Gamma\) = \(\frac{\phi (-0.3253)}{60 *0.3 \sqrt{0.25}}\)

dnorm (d1)/(s*sigma*sqrt(t))
[1] 0.04204276

Vega \(\nu\) = \(P\sqrt{T-t}\phi(d-{1})\)

\(\nu\) = \(60\sqrt{0.25}\phi(-0.32)\)

s*sqrt(t)*dnorm(d1)
[1] 11.35154
2D) Compare results from 2B and 2C. Share observations.

The values for Delta, Gamma and Vega calculated using the GSB Option and numerical differentiation are the same.

*http://computationalfinance.lsi.upc.edu

LS0tCnRpdGxlOiAiRklOQzYyMSBXaW50ZXIgMjAxOC0xOSBMYWIgV29ya3NoZWV0IDA0IgphdXRob3I6ICJUaXRpbG9wZSBPbHV0YXlvIgpkYXRlOiAiMTIvMTIvMjAxOCIKb3V0cHV0OgogIGh0bWxfbm90ZWJvb2s6IGRlZmF1bHQKICBodG1sX2RvY3VtZW50OiBkZWZhdWx0CnN1YnRpdGxlOiBTdG9jaGFzdGljIE1vZGVsaW5nICYgTnVtZXJpY2FsIERpZmZlcmVudGlhdGlvbiAoZmluYzYyMS1sYWIwNCkKLS0tCgojIyMgQWJvdXQKClRoaXMgd29ya3NoZWV0IGxvb2tzIGF0IHNpbXVsYXRpbmcsIGJvdGggYXJpdGhtZXRpY3MgYW5kIGdlb21ldHJpYywgQnJvd25pYW4gbW90aW9uIGZvciBzdG9jayBwcmljZXMsIHByaWNpbmcgb3B0aW9ucywgYW5kIGNhbGN1bGF0aW5nIEdyZWVrcyB1c2luZyBudW1lcmljYWwgZGlmZmVyZW50aWF0aW9uLiAgCgojIyMgU2V0dXAKClJlbWVtYmVyIHRvIGFsd2F5cyBzZXQgeW91ciB3b3JraW5nIGRpcmVjdG9yeSB0byB0aGUgc291cmNlIGZpbGUgbG9jYXRpb24uIEdvIHRvICdTZXNzaW9uJywgc2Nyb2xsIGRvd24gdG8gJ1NldCBXb3JraW5nIERpcmVjdG9yeScsIGFuZCBjbGljayAnVG8gU291cmNlIEZpbGUgTG9jYXRpb24nLiBSZWFkIGNhcmVmdWxseSB0aGUgYmVsb3cgYW5kIGZvbGxvdyB0aGUgaW5zdHJ1Y3Rpb25zIHRvIGNvbXBsZXRlIHRoZSB0YXNrcyBhbmQgYW5zd2VyIGFueSBxdWVzdGlvbnMuICBTdWJtaXQgeW91ciB3b3JrIHRvIFJQdWJzIGFzIGRldGFpbGVkIGluIHByZXZpb3VzIG5vdGVzLiAKCiMjIyBOb3RlCgpBbHdheXMgcmVhZCBjYXJlZnVsbHkgdGhlIGluc3RydWN0aW9ucyBvbiBTYWthaS4gIEZvciBjbGFyaXR5LCB0YXNrcy9xdWVzdGlvbnMgdG8gYmUgY29tcGxldGVkL2Fuc3dlcmVkIGFyZSBoaWdobGlnaHRlZCBpbiByZWQgY29sb3IgKHZpc2libGUgaW4gcHJldmlldykgYW5kIG51bWJlcmVkIGFjY29yZGluZyB0byB0aGVpciBwYXJ0aWN1bGFyIHBsYWNlbWVudCBpbiB0aGUgdGFzayBzZWN0aW9uLiAgUXVpdGUgb2Z0ZW4geW91IHdpbGwgbmVlZCB0byBhZGQgeW91ciBvd24gY29kZSBjaHVuay4KCkV4ZWN1dGUgYWxsIGNvZGUgY2h1bmtzLCBwcmV2aWV3LCBwdWJsaXNoLCBhbmQgc3VibWl0IGxpbmsgb24gU2FrYWkgZm9sbHdvaW5nIHRoZSBuYW1pbmcgY29udmVudGlvbi4gTWFrZSBzdXJlIHRvIGFkZCBjb21tZW50cyB0byB5b3VyIGNvZGUgd2hlcmUgYXBwcm9wcmlhdGUuIFVzZSBvd24gbGFuZ3VhZ2UhCgotLS0tLS0tLS0tLS0tLQoKIyMjIFRhc2sgMTogU2ltdWxhdGluZyBCcm93bmlhbiBNb3Rpb24KClRoaXMgdGFzayBmb2xsb3dzIHRoZSB0d28gZXhhbXBsZXMgaW4gdGhlIGJvb2sgYFIgRXhhbXBsZSA1LjEvcCAxNDhgIGZvciBzaW11bGF0aW5nIGFuIGFyaXRobWV0aWMgQnJvd25pYW4gbW90aW9uIGFuZCBgUiBFeGFtcGxlIDUuMi9wMTUyYCBmb3Igc2ltdWxhdGluZyBhIGdlb21ldHJpYyBtb3Rpb24uIFR3byBuZXcgcGFja2FnZXMgd2lsbCBiZSByZXF1aXJlZCBmb3IgdGhpcyB3b3Jrc2hlZXQuICBUaGV5IGFyZSBpbmNsdWRlZCBpbiB0aGUgY29kZSBjaHVuayBiZWxvdy4KCmBgYHtyfQojSW5zdGFsbCBwYWNrYWdlIHF1YW50bW9kIAppZighcmVxdWlyZSgicXVhbnRtb2QiLHF1aWV0bHkgPSBUUlVFKSkKICBpbnN0YWxsLnBhY2thZ2VzKCJxdWFudG1vZCIsZGVwZW5kZW5jaWVzID0gVFJVRSwgcmVwb3MgPSAiaHR0cHM6Ly9jbG91ZC5yLXByb2plY3Qub3JnIikKYGBgCgpgYGB7cn0KI0luc3RhbGwgcGFja2FnZSBzZGUgZm9yIFN0b2NoYXN0aWMgRGlmZmVyZW50aWFsIEVxdWF0aW9uCmlmKCFyZXF1aXJlKCJzZGUiLHF1aWV0bHkgPSBUUlVFKSkKICBpbnN0YWxsLnBhY2thZ2VzKCJzZGUiLGRlcGVuZGVuY2llcyA9IFRSVUUsIHJlcG9zID0gImh0dHBzOi8vY2xvdWQuci1wcm9qZWN0Lm9yZyIpCmBgYAoKYGBge3J9CiNJbnN0YWxsIHBhY2thZ2UgZk9wdGlvbnMgZm9yIHByaWNpbmcgYW5kIGV2YWx1YXRpbmcgYmFzaWMgb3B0aW9ucwppZighcmVxdWlyZSgiZk9wdGlvbnMiLHF1aWV0bHkgPSBUUlVFKSkKICBpbnN0YWxsLnBhY2thZ2VzKCJmT3B0aW9ucyIsZGVwZW5kZW5jaWVzID0gVFJVRSwgcmVwb3MgPSAiaHR0cHM6Ly9jbG91ZC5yLXByb2plY3Qub3JnIikKYGBgCgoKPHNwYW4gc3R5bGU9ImNvbG9yOnJlZCI+CiMjIyMjIDFBKSBGb2xsb3cgZXhhbXBsZSBpbiBib29rIHRvIHNpbXVsYXRlIGFuZCBwbG90IGV4YW1wbGUgb2YgYW4gYXJpdGhtZXRpYyBCcm93bmlhbiBtb3Rpb24uIENvbnNpZGVyIHRocmVlIHZhbHVlcyBmb3IgbiAobnVtYmVyIG9mIHBvaW50cyk6ICQyXjIsIDJeNSwgMl57MTJ9JC4gRXhwbGFpbiBiZWhhdmlvciBhcyBuIGluY3JlYXNlcy4KPC9zcGFuPgpgYGB7cn0KIyNpbnB1dHM6CmFscGhhPTA7IHNpZ21hPTE7IFQ9MTsgbj0yXigyKTsgWDA9MC4xOwojI0dlbmVyYXRlIDEgdHJhamVjdG9yeQpkdD1UL24KdD1zZXEoMCxULGJ5PWR0KQp4PWMoWDAsYWxwaGEqZHQrc2lnbWEqc3FydChkdCkqcm5vcm0obixtZWFuPTAsc2Q9MSkpClh0PWN1bXN1bSh4KQpwbG90KHQsWHQsdHlwZT0nbCcseGxhYj0idGltZSIpCgojI2lucHV0czoKYWxwaGE9MDsgc2lnbWE9MTsgVD0xOyBuPTJeKDUpOyBYMD0wLjE7CiMjR2VuZXJhdGUgMSB0cmFqZWN0b3J5CmR0PVQvbgp0PXNlcSgwLFQsYnk9ZHQpCng9YyhYMCxhbHBoYSpkdCtzaWdtYSpzcXJ0KGR0KSpybm9ybShuLG1lYW49MCxzZD0xKSkKWHQ9Y3Vtc3VtKHgpCnBsb3QodCxYdCx0eXBlPSdsJyx4bGFiPSJ0aW1lIikKCiMjaW5wdXRzOgphbHBoYT0wOyBzaWdtYT0xOyBUPTE7IG49Ml4oMTIpOyBYMD0wLjE7CiMjR2VuZXJhdGUgMSB0cmFqZWN0b3J5CmR0PVQvbgp0PXNlcSgwLFQsYnk9ZHQpCng9YyhYMCxhbHBoYSpkdCtzaWdtYSpzcXJ0KGR0KSpybm9ybShuLG1lYW49MCxzZD0xKSkKWHQ9Y3Vtc3VtKHgpCnBsb3QodCxYdCx0eXBlPSdsJyx4bGFiPSJ0aW1lIikKYGBgCkFzIHRoZSB2YWx1ZSBvZiBuIGluY3JlYXNlcywgdGhlIHRpbWUgc3RlcHMgVC9uIGJlY29tZXMgc21hbGxlciBhbmQgdGh1cyB3aWxsIGltcHJvdmUgdGhlIHF1YWxpdHkgb2YgdGhlIGFwcHJveGltYXRlIHNhbXBsZSBwYXRoIHRvIGEgdHJ1ZSBCcm93bmlhbiBwYXRoLiBUaGVyZWZvcmUsIHRoZSBoaWdoZXIgdGhlIG4sIHRoZSBjbG9zZXIgaXQgaXMgdG8gQnJvd25pYW4gbW90aW9uLgoKPHNwYW4gc3R5bGU9ImNvbG9yOnJlZCI+CiMjIyMjIDFCKSBXcml0ZSB0aGUgbWF0aGVtYXRpY2FsIGVxdWF0aW9uIHJlcHJlc2VudGluZyB0aGUgdmFsdWVzIGFsb25nIHRoZSB5LWF4aXMgaW4gdGhlIGFib3ZlIHBsb3QuIFNlcGFyYXRlbHkgZXhwcmVzcyB3aGF0IHRoZSB2YWx1ZSBvZiBlYWNoIHZhcmlhYmxlIGluIHRoZSBlcXVhdGlvbiBpcy4KPC9zcGFuPgoKVGhlIHZhbHVlIGFsb25nIHRoZSBZIGF4aXMgY2FuIGJlIG1hdGhlbWF0aWNhbGx5IHdyaXR0ZW4gYXM6CgokWCh0KSA9IFgodC0xKSArXGFscGhhXGZyYWN7VH17bn0gKyBcc2lnbWFcdmFyZXBzaWxvbl97dH1cc3FydHtcZnJhY3tUfXtufX0kCgpUaGUgdmFsdWUgJFxzaWdtYSQgbWVhc3VyZXMgdGhlIGV4cGVjdGVkIGRyaQp3aGVyZSwgWCh0KSBpcyBhbiBhcml0aG1ldGljIEJyb3duaW5hbiwgbiBpcyB0aGUgbnVtYmVyIG9mIHN0ZXBzL3BlcmlvZHMgaW4gdGhlIHRpbWUgaW50ZXJ2YWwsIHQgaXMgdGhlIHN0ZXBzIGluIHRoZSB0aW1lIHNlcmllcy4gJFxmcmFje1R9e259JCByZXByZXNlbnRzIHRoZSBsZW5ndGggb2YgdCwgJFxhbHBoYSQgaXMgdGhlIGRyaWZ0IG9mIHRoZSBicm93bmlhbiBtb3Rpb24uJFx2YXJlcHNpbG9uX3t0fSQgcyBhIHJhbmRvbWx5IGdlbmVyYXRlZCBudW1iZXIgZnJvbSBhIG5vcm1hbCBkaXN0cmlidXRpb24gb2YgbWVhbiAwIGFuZCB2YXJpYW5jZSAxLCAkXHNpZ21hJCBpcyB0aGUgdm9sYXRpbGl0eSBvZiB0aGUgQnJvd25pYW4gbW90aW9uCgoKPHNwYW4gc3R5bGU9ImNvbG9yOnJlZCI+CiMjIyMjIDFDKSBGb2xsb3cgZXhhbXBsZSBpbiBib29rIHRvIHNpbXVsYXRlIGEgZ2VvbWV0cmljIEJyb3duaWFuIG1vdGlvbi4gCjwvc3Bhbj4KCmBgYHtyfQpsaWJyYXJ5KHNkZSkKbXU9MC4xNjsgc2lnbWE9MC4yOyBQMD00MDsKVCA9IDEvMTIgIyMxIG1vbnRoCm50PTUwOyBuPTJeKDgpCiMjR2VuZXJhdGUgbnQgdHJhamVjdG9yaWVzCmR0PVQvbjsgdD1zZXEoMCxULGJ5PWR0KQpYPW1hdHJpeChyZXAoMCxsZW5ndGgodCkqbnQpLCBucm93PW50KQpmb3IgKGkgaW4gMTpudCkge1hbaSxdPSBHQk0oeD1QMCxyPW11LHNpZ21hPXNpZ21hLFQ9VCxOPW4pfQojI1Bsb3QKeW1heD1tYXgoWCk7IHltaW49bWluKFgpIAojYm91bmRzIGZvciBzaW11bGF0ZWQgcHJpY2VzCnBsb3QodCxYWzEsXSx0PSdsJyx5bGltPWMoeW1pbiwgeW1heCksIGNvbD0xLHlsYWI9IlByaWNlIFAodCkiLHhsYWI9InRpbWUgdCIpCmZvcihpIGluIDI6bnQpe2xpbmVzKHQsWFtpLF0sIHQ9J2wnLHlsaW09Yyh5bWluLCB5bWF4KSxjb2w9aSl9CmBgYAoKCjxzcGFuIHN0eWxlPSJjb2xvcjpyZWQiPgojIyMjIyAxRCkgV3JpdGUgdGhlIG1hdGhlbWF0aWNhbCBlcXVhdGlvbiByZXByZXNlbnRpbmcgdGhlIHZhbHVlcyBhbG9uZyB0aGUgeS1heGlzIGluIHRoZSBhYm92ZSBwbG90LiBTZXBhcmF0ZWx5IGV4cHJlc3Mgd2hhdCB0aGUgdmFsdWUgb2YgZWFjaCB2YXJpYWJsZSBpbiB0aGUgZXF1YXRpb24gaXMuCjwvc3Bhbj4KClRoaXMgY2FuIGJlIG1hdGhlbWF0aWNhbGx5IHdyaXR0ZW4gYXM6CgokUF9UID0oKHUtIFxmcmFje1xzaWdtYV4yfXsyfSlUICsgXHNpZ21hXHZhcmVwc2lsb25fe3R9XHNxcnR7XERlbHRhIHR9KSQKCndoZXJlLCRQX1QkLCBmb2xsb3dzIGEgZ2VvbWV0cmljIEJyb3duaWFuIG1vdGlvbiwgdGhlIHJldHVybiAkcl90JCBpcyBub3JtYWxseSBkaXN0cmlidXRlZCB3aXRoIG1lYW4gJCh1LSBcZnJhY3tcc2lnbWFeMn17Mn0pVCQgaXMgdGhlIGV4cGVjdGVkIHJldHVybiBhbmQgdmFyaWFuY2UgJFxzaWdtYV4yJCBpcyB0aGUgdm9sYXRpbGl0eSBvZiB0aGUgcHJpY2UsICRcdmFyZXBzaWxvbl97dH0kIGlzIGEgcmFuZG9tbHkgZ2VuZXJhdGVkIG51bWJlciBmcm9tIGEgbm9ybWFsIGRpc3RyaWJ1dGlvbiwgdCBpcyB0aGUgdGltZSBzZXJpZXMKCjxzcGFuIHN0eWxlPSJjb2xvcjpyZWQiPgojIyMjIyAxRSkgSG93IGlzIHRoZSBnZW9tZXRyaWMgQnJvd25pYW4gc2ltdWxhdGlvbiBkaWZmZXJlbnQgZnJvbSB0aGUgYXJpdGhtZXRpYyBzaW11bGF0aW9uPyBFbGFib3JhdGUuCjwvc3Bhbj4KCkEgbGltaXRhdGlvbiBvZiB0aGUgYXJpdGhtZXRpYyBCcm93bmlhbiBtb3Rpb24gd2hlbiB1c2VkIGZvciBtb2RlbGxpbmcgdGhlIHByaWNlIG9mIGEgc3RvY2sgaXMgdGhlIHBvc3NpYmlsaXR5IG9mIGdldHRpbmcgbmVnYXRpdmUgcHJpY2VzLiBIb3dldmVyLCB0aGlzIGNhbiBiZSBmaXhlZCBieSBjb25zaWRlcmluZyBwcmljZXMgdG8gYmUgbG9nIG5vcm1hbGx5IGRpc3RyaWJ1dGVkIGluc3RlYWQuIFVzaW5nIGxvZyBub3JtYWxseSBkaXN0cmlidXRlZCBkYXRhIHdlIGdlbmVyYXRlIHRoZSBnZW9tZXRyaWMgQnJvd25pYW4gbW90aW9uIGFuZCB0aGlzIGtlZXBzIHRoZSBwcmljZSBvZiBzdG9jayBwb3N0aXZlLiAKCgojIyMgVGFzayAyOiBPcHRpb24gUHJpY2luZywgR3JlZWtzLCBhbmQgTnVtZXJpY2FsIERpZmZlcmVudGlhdGlvbgoKRm9sbG93cyB0aGUgZXhhbXBsZSBpbiB0aGUgYm9vayAgYFIgRXhhbXBsZSA1LjMvcCAxNTYgYCBhbmQgYFIgRXhhbXBsZSA1LjUvcCAxNTdgCgo8c3BhbiBzdHlsZT0iY29sb3I6cmVkIj4KIyMjIyMgMkEpIENhbGN1bGF0ZSB0aGUgQ2FsbCBhbmQgUHV0IHByaWNlIG9mIHRoZSBnaXZlbiBFdXJvcGVhbiBPcHRpb24uICBFeHBsYWluIHdoYXQgdGhlIHZhcmlhYmxlcyBgcmAgYW5kIGBiYCBpbiB0aGUgZnVuY3Rpb24gY2FsbCBgR0JTT3B0aW9uYCByZXByZXNlbnQuICAgIAo8L3NwYW4+CmBgYHtyfQpsaWJyYXJ5KGZPcHRpb25zKQpHQlNPcHRpb24oVHlwZUZsYWcgPSAiYyIsIFMgPSA2MCwgWCA9IDY1LCBUaW1lID0gMS80LCByID0gMC4wOCxiID0gMC4wOCwgc2lnbWEgPSAwLjMwKQpgYGAKYGBge3J9CmxpYnJhcnkoZk9wdGlvbnMpCkdCU09wdGlvbihUeXBlRmxhZyA9ICJwIiwgUyA9IDYwLCBYID0gNjUsIFRpbWUgPSAxLzQsIHIgPSAwLjA4LGIgPSAwLjA4LCBzaWdtYSA9IDAuMzApCmBgYApUaGUgcHJpY2UgZm9yIHRoZSBFdXJvcGVhbiBjYWxsIG9wdGlvbiBpcyAyLjEzMzM3MiBhbmQgZm9yIHRoZSBFdXJvcGVhbiBwdXQgb3B0aW9uIGlzIDUuODQ2Mjg2LiBUaGUgdmFyaWFibGUgInIiIGluIEdTQiBvcHRpb24gcmVwcmVzZW50cyB0aGUgYW5udWFsaXplZCByYXRlIG9mIGludGVyZXN0LCBhIG51bWVyaWMgdmFsdWUgYW5kICJiIiBpcyB0aGUgYW5udWFsaXplZCBjb3N0IG9mIGNhcnJ5IHJhdGUsIGEgbnVtZXJpYyB2YWx1ZS4KCjxzcGFuIHN0eWxlPSJjb2xvcjpyZWQiPgojIyMjIyAyQikgQ2FsY3VsYXRlIHRoZSBwYXJ0aWN1bGFyIEdyZWVrcyBEZWx0YSwgR2FtbWEsIGFuZCBWZWdhIGZvciB0aGUgYWJvdmUgY29ycmVzcG9uZGluZyBDYWxsIG9wdGlvbi4KPC9zcGFuPgpgYGB7cn0KbGlicmFyeShmT3B0aW9ucykKR0JTR3JlZWtzKFNlbGVjdGlvbj0iZGVsdGEiLFR5cGVGbGFnPSJjIixTPTYwLFg9NjUsVGltZT0xLzQscj0wLjA4LGI9MC4wOCxzaWdtYT0wLjMwKQpgYGAKCmBgYHtyfQpsaWJyYXJ5KGZPcHRpb25zKQpHQlNHcmVla3MoU2VsZWN0aW9uPSJnYW1tYSIsVHlwZUZsYWc9ImMiLFM9NjAsWD02NSxUaW1lPTEvNCxyPTAuMDgsYj0wLjA4LHNpZ21hPTAuMzApCmBgYApgYGB7cn0KbGlicmFyeShmT3B0aW9ucykKR0JTR3JlZWtzKFNlbGVjdGlvbj0idmVnYSIsVHlwZUZsYWc9ImMiLFM9NjAsWD02NSxUaW1lPTEvNCxyPTAuMDgsYj0wLjA4LHNpZ21hPTAuMzApCmBgYAoKPHNwYW4gc3R5bGU9ImNvbG9yOnJlZCI+CiMjIyMjIDJDKSBDYWxjdWxhdGUgdGhlIERlbHRhLCBHYW1tYSwgYW5kIFZlZ2EgZm9yIHNhbWUgb3B0aW9uIHVzaW5nIGluc3RlYWQgbnVtZXJpY2FsIGRpZmZlcmVudGlhdGlvbi4gV3JpdGUgdGhlIG1hdGhlbWF0aWNhbCBlcXVhdGlvbnMgY29ycmVzcG9uZGluZyB0byBlYWNoIG51bWVyaWNhbCBkaWZmZXJlbnRpYXRpb24uCjwvc3Bhbj4KClVzaW5nIG51bWVyaWNhbCBkaWZmZXJlbnRpYXRpb24sCkRlbHRhICRcRGVsdGEkID0gJFxQaGkkKCRkX3sxfSQpLCAkZF97MX0kID0gJFxmcmFje2xuIChQX3QvSykgKyhyK1xzaWdtYV4yLzIpKFQtdCl9e1xzaWdtYSBcc3FydHtULXR9fSQKClRvIGdldCB0aGUgdmFsdWVzIGZvciAkZF97MX0kLCBwbHVnIGluIHRoZSB2YWx1ZXMgaW4gdGhlIGFib3ZlIGVxdWF0aW9uIHdpdGggdGhlIHZhbHVlcyBvZiB0aGUgY2FsbCBvcHRpb24KCiRkX3sxfSQgPSAkXGZyYWN7bG4gKDYwLzY1KSArKDAuMDgrMC4zXjIvMikoMC4yNSl9ezAuMyBcc3FydHswLjI1fX0kCiAKYGBge3J9CnM9IDYwOyBrID02NTsgcj0wLjA4OyBzaWdtYSA9IDAuMzsgdD0gMC4yNQoKZDEgPSAobG9nKHMvaykrIChyK3NpZ21hXjIvMikqKHQpKS8oc2lnbWEqc3FydCh0KSkKZDEKIyMjdmFsdWUgb2YgZGVsdGEKZG5vcm0oZDEpCmBgYApHYW1tYSAkXEdhbW1hJCA9ICRcZnJhY3tccGhpIChkX3sxfSl9e1AgXHNpZ21hIFxzcXJ0e1QtdH19JAokXEdhbW1hJCA9ICRcZnJhY3tccGhpICgtMC4zMjUzKX17NjAgKjAuMyBcc3FydHswLjI1fX0kCgpgYGB7cn0KZG5vcm0gKGQxKS8ocypzaWdtYSpzcXJ0KHQpKQpgYGAKVmVnYSAkXG51JCA9ICRQXHNxcnR7VC10fVxwaGkoZC17MX0pJAoKJFxudSQgPSAkNjBcc3FydHswLjI1fVxwaGkoLTAuMzIpJAoKYGBge3J9CnMqc3FydCh0KSpkbm9ybShkMSkKYGBgCgoKIyMjIyMgMkQpIENvbXBhcmUgcmVzdWx0cyBmcm9tIDJCIGFuZCAyQy4gU2hhcmUgb2JzZXJ2YXRpb25zLgpUaGUgdmFsdWVzIGZvciBEZWx0YSwgR2FtbWEgYW5kIFZlZ2EgY2FsY3VsYXRlZCB1c2luZyB0aGUgR1NCIE9wdGlvbiBhbmQgbnVtZXJpY2FsIGRpZmZlcmVudGlhdGlvbiBhcmUgdGhlIHNhbWUuCgoqW2h0dHA6Ly9jb21wdXRhdGlvbmFsZmluYW5jZS5sc2kudXBjLmVkdSBdKGh0dHA6Ly9jb21wdXRhdGlvbmFsZmluYW5jZS5sc2kudXBjLmVkdSkK