Monte Carlo Simulation of Options Prices (PDF)

Steven R. Dunbar
Department of Mathematics
203 Avery Hall
University of Nebraska-Lincoln
Lincoln, NE 68588-0130
http://www.math.unl.edu
Voice: 402-472-3731
Fax: 402-472-8466
Stochastic Processes and
Advanced Mathematical Finance
Monte Carlo Simulation of Option Prices
Rating
Mathematically Mature: may contain mathematics beyond calculus with
proofs.
1
Section Starter Question
What is a 95% confidence interval in a statistical experiment?
Key Concepts
1. Monte Carlo methods (or Monte Carlo experiments) are mathematical solution methods that rely on repeated random sampling to obtain
numerical results.
2. Variance reduction techniques create a new Monte Carlo problem
with the same answer as the original but with a smaller value for the
variance to increase the efficiency of the Monte Carlo estimation. Many
methods for variance reduction for Monte Carlo methods exist.
3. The idea behind importance sampling is that some values of the simulation have more effect on the estimation than others. The probability
distribution of the sample is carefully changed to give “important” outcomes more weight to achieve some goal such as variance reduction.
Vocabulary
1. Monte Carlo methods (or Monte Carlo experiments) are a large
and diverse class of solution methods using random sampling from a
specified distribution to generate numerical results for a mathematical
model.
2
2. The 95% level Monte Carlo confidence interval for E [g(X)] is
s
s
.
ḡn − t0.975 √ , ḡn + t0.975 √
n
n
√
3. The quantity s/ n is called the standard error.
4. Variance reduction techniques create a new Monte Carlo problem
with the same answer as the original but with a smaller value for the
variance to increase the efficiency of Monte Carlo estimation.
5. An antithetic sample is a sample that uses an opposite value of f (x),
being low when f (x) is high and vice versa, to reduce the variance.
6. Importance sampling is another variance reduction technique. The
idea behind importance sampling is that some values in a simulation
have more influence on the estimation than others. The probability
distribution is carefully changed to give “important” outcomes more
weight.
Mathematical Ideas
Confidence Intervals for Option Prices
Monte Carlo methods (or Monte Carlo experiments) are a large and diverse class of solution methods using random sampling from a specified distribution to generate numerical results for a mathematical model. Monte Carlo
methods are a statistical solution technique, among the various mathematical techniques that move from a mathematical model to a relation among
the quantities of interest.
With Geometric Brownian Motion as a stochastic process model for security prices, we can use that process for simulating option prices with a
3
Monte Carlo method. We assume that a security price is modeled by Geometric Brownian Motion, so we know the lognormal probability distribution
at the expiration time. Draw n pseudo-random numbers x1 , . . . , xn from
the lognormal distribution modeling the stock price S. Then approximate a
put option price as the present value of the expected value of the function
g(S) = max(K − S, 0), with the sample mean
n
1X
E [g(S)] ≈
g(xi ) = ḡn .
n i=1
The examples in this section feature put options rather than the call options
illustrated previously for a reason that will become clear later when we modify
the Monte Carlo simulation with importance sampling.
The Weak and Strong Laws of Large Numbers ensure us that this approximation is valid for large n, and improves as the number of samples increases.
Even more is true, since the Central Limit Theorem implies that the sample mean ḡn is approximately normally distributed with mean E [g(S)] and
variance Var [g(S)] /n,
ḡn ∼ N (E [g(S)] , Var [g(S)] /n).
This says that the value ḡn that we estimate with the Monte Carlo simulations
will have a deviation from the true expected
√ value E [g(S)] that is on the
order of the standard deviation divided by n. More precisely, recall that
for the standard normal distribution P [|Z| < 1.96] ≈ 0.95. Then by the
shifting and rescaling properties of the normal distribution, we can construct
a corresponding 95% confidence interval for the estimate ḡn as
!
r
r
Var [g(S)]
Var [g(S)]
, E [g(S)] + 1.96
.
E [g(S)] − 1.96
n
n
We interpret the interval above as saying that the estimate ḡn will be in
this interval in about 95% of samples. That is, if 100 people perform the
sampling experiment with different draws from the pseudo-random number
generator, then about 95 of them will generate an expected value that falls in
this interval, but about 5 of them will be unlucky enough to draw a sample
that generates an expected value falling outside the interval.
4
A problem with obtaining the confidence interval is that the mean E [g(S)]
and the variance Var [g(S)] are both unknown. These are respectively estimated with the sample mean ḡn and the sample variance
n
1 X
s =
(g(xi ) − ḡn )2
n − 1 i=1
2
to obtain the 95% level Monte Carlo confidence interval for E [g(S)]
s
s
ḡn − tn−1,0.975 √ , ḡn + tn−1,0.975 √
.
n
n
√
The quantity s/ n is called the standard error. Note that the standard
error is dependent on the drawn numbers x1 , x2 , . . . , xn so it is subject to
sample variability too. In fact, the sample quantity
(ḡn − E [g(S)])
√
s/ n
has a probability distribution known as Student’s t-distribution, so the 95%
confidence interval limits of ±1.96 must be modified with the corresponding
95% confidence limits of the appropriate Student’s t-distribution.
Another problem with the Monte√Carlo confidence interval is that the
width of the interval decreases as 1/ n, which is not particularly fast. To
decrease the width of the confidence interval by half requires 4 times as many
sample variates.
Simplified Example
Now apply confidence interval estimation to the present value of a simple put
option price for a simplified security. The simplified security has a stochastic
differential equation dS = rS dt +σS dW with a starting price S(0) = z0 =
1 at t = 0 with risk-free interest rate r = σ 2 /2, and a standard deviation
σ = 1. Then the stochastic process is S(t) = eW (t) where W (t) is standard
Brownian Motion. (The parameters are financially unrealistic, but lead to
the simple exponential.) For the simplified put option the strike price is
K = 1, and the time to expiration is T − t = T − 0 = 1. Short programs to
create 95% confidence intervals for 100, 1,000, and 10,000 samples are in the
Scripts section. The random seed is set to the arbitrary value 2015 so that
5
n
ḡn
95% Monte Carlo confidence interval
100 0.1580783
(0.1206047, 0.1955519)
1000 0.1539137
(0.1425191, 0.1653084)
10000 0.1451896
(0.1416714, 0.1487078)
Table 1: Monte Carlo confidence intervals for the present value of a simple
put option values. The present value of the put option from the Black-Scholes
formula is 0.1446101.
for replication of the Monte Carlo simulation the sample script always yields
the same results. The true value comes from the Black-Scholes put option
value formula in Put-Call Parity Principle. Some typical results from the R
script are in Table 1.
Although the Monte Carlo simulation yields good results fairly easily, a
disadvantage is that it applies for only one set of parameter values. To find
values for a variety of parameters requires more computations, but even that
does not demonstrate the functional relationship among the parameters and
the values. The next chapter will derive a complete mathematical solution for
the value of European call and put options. However, mathematical solution
is not always possible for more complex security derivatives, and then Monte
Carlo simulation is a good alternative.
Variance Reduction Techniques
Applying Monte Carlo estimation to a random variable with a large variance
creates a confidence interval that is correspondingly large. The width of the
confidence interval
√ can be reduced by increasing the sample size, but the rate
of reduction is n. Reducing the width of the confidence interval by half
requires 4 times more sample points. Sometimes we can find a way to reduce
s instead. To do this, we construct a new Monte Carlo problem with the
same answer as our original problem but with a smaller value for s. Methods
to do this are known as variance reduction techniques. Since Geometric Brownian Motion has a variance that grows exponentially, Monte Carlo
estimates of quantities based on Geometric Brownian Motion are excellent
candidates for variance reduction techniques.
Variance reduction techniques increase the efficiency of Monte Carlo estimation. Having methods to reduce variability with a given number of
sample points, or for efficiency to achieve the same variability with fewer
6
sample points, is desirable. Following are two methods that illustrate typical
variance reduction techniques.
Antithetic Sampling
An antithetic sample is a sample that gives a opposite value of g(x), being
low when g(x) is high and vice versa. Ordinarily we get an opposite g by
sampling at a point that is somehow opposite to x. The idea of antithetic
sampling can be applied when it is possible to find transformations of X that
leave its probability distribution unchanged. For example, if X is normally
distributed N (0, 1), then X̃ = −X is normally distributed as well, that
is the antithetic sample we will apply here. More generally, if X has a
symmetric distribution about 0, then X̃ = −X has the same distribution.
Another antithetic sample occurs when X is uniformly distributed on [0, 1]
so X̃ = 1 − X has the same probability distribution.
The antithetic sampling estimate of a value µ = E [g(X)] with a
sample size n is
n
1 X
g(Xj ) + g(X̃j ) .
µ̂anti =
2n j=1
Suppose the variance is σ 2 = E [(g(X) − µ)2 ] < ∞. Then the variance in
the antithetic sample of size n is
"
#
n
1 X
Var [µ̂anti ] = Var
g(Xj ) + g(X̃j )
2n j=1
h
i
n = 2 Var g(X) + g(X̃)
4n
h
i
h
i
1 =
Var [g(X)] + Var g(X̃) + 2 Cov g(X), g(X̃)
4n
σ2
=
(1 + ρ).
2n
Previously, we have often assumed different samples are independent so that
the covariance term ρ is 0, reducing the number of terms in an expression.
However, here is a situation where we deliberately create statistical dependence with negative covariance −1 ≤ ρ < 0 to reduce the variance in the
antithetic sampling estimate.
Table 2 gives the results of antithetic sampling on the simplified put
option example after a simple change of variables to make the sampling
7
n
ḡn
95%Monte Carlo confidence interval
100 0.1429556
(0.1267189, 0.1591923)
1000 0.1432171
(0.1383814, 0.1480529)
10000 0.1452026
(0.1437125, 0.1466926)
Table 2: Monte Carlo confidence intervals with antithetic sampling for the
present value of a simple put option. The present value of the put option
from the Black-Scholes formula is 0.1446101.
distribution normal. Table 2 shows that for the put option Monte Carlo estimation not only are the option value estimates much better with antithetic
sampling, but the confidence intervals are reduced to less than half of the
width compared with Table 1.
Note that if g(x) is a function with odd symmetry, for example g(x) =
cx, and X is symmetric about 0, for example normally distributed with
antithetic sample X̃ = −X, then µ = 0. Furthermore, the statistical estimate
µ̂anti would be always be 0 and in fact the estimate could be achieved with
just one sample point and no variance. If g is not symmetric, as in option
estimation with g(x) = max(K −x, 0), we can still expect some improvement.
The degree of improvement in antithetic sampling depends on the relative
contribution of the odd and even parts of the function g, see [1] for details.
Importance Sampling
Importance sampling is another variance reduction technique. The idea
behind importance sampling is that some values in a simulation have more
influence on the estimation than others. The probability distribution is carefully changed to give “important” outcomes more weight. If “important”
values are emphasized by sampling more frequently, then the estimator variance can be reduced. Hence, the key to importance sampling is to choose a
new sampling distribution that “encourages” the important values.
Let f (x) be the density of the random variable, so we are trying to estimate
Z
E [g(x)] =
g(x)f (x) dx .
R
Estimate E [g(x)] with respect to another strictly positive density h(x). Then
8
easily
Z
E [g(x)] =
R
g(x)f (x)
h(x) dx .
h(x)
or equivalently, estimate
g(Y )f (Y )
E
= E [g̃(Y )]
h(Y )
where Y is a new random variable with density h(y) and g̃(y) = g(y)f (y)/h(y).
For variance reduction, we wish to determine a new density h(y) so that
Var [g̃(Y )] < Var [g(X)]. Consider
Z 2
g (x)f 2 (x)
2
2
Var [g̃(Y )] = E g̃(Y ) − (E [g̃(Y )]) =
dx −E [g(X)]2 .
h(x)
R
By inspection, we can see that we can make Var [g̃(Y )] = 0 by choosing
h(x) = g(x)f (x)/E [g(X)]. This is the ultimate variance reduction but it
relies on knowing E [g(X)], the quantity we are trying to estimate. It also
requires that g(x) is strictly positive.
To choose a good importance sampling distribution requires some educated guessing. Importance sampling is equivalent to a change of variables,
and like a change of variables often requires insight. Each instance of importance sampling depends on the function and the distribution. A specific
example will illustrate importance sampling.
The example is again to calculate confidence intervals for the present
value of a Monte Carlo estimate of a European put option price, where g(x) =
max(K − x, 0) and S is distributed as a geometric Brownian motion derived
from dS = rS dt +σS dW with S(0) = z0 . To set some simple parameters,
we take the initial value z0 = 1, the risk free interest rate r = σ 2 /2, the
standard deviation σ = 1, the strike price K = 1 and the time to expiration
T = 1. The security process is then S(t) = eW (t) . At √
T = 1 the process has a
lognormal distribution with parameters µ = 0 and σ T = 1. Thus we start
with
Z ∞
√
1
1
√ exp(− (ln(x)/σ T )2 ) dx .
max(K − x, 0) √
2
2πσx T
0
Using K = 1, σ = 1, and T = 1 after a first change of variable the integral
9
n
ḡn
95% Monte Carlo confidence interval
100 0.1465861
(0.1395778, 0.1535944)
1000 0.1449724
(0.1427713, 0.1471736)
10000 0.1443417
(0.1436435, 0.1436435)
Table 3: Monte Carlo confidence intervals with importance sampling for the
present value of a simple put option. The present value of the put option
from the Black-Scholes formula is 0.1446101.
we are estimating is
2
∞
e−x /2
dx
E [g(S)] =
max(1 − e , 0) √
2π
−∞
Z 0
−x2 /2
x e
(1 − e ) √
=
dx .
2π
−∞
Z
x
Introduce the exponential distribution e−y/2 with a second change of vari√
ables x = − y. Then the expectation integral becomes
Z
0
∞
√
1 − e− y e−y/2
√ √
dy .
2π y 2
This change of probability distribution has the added advantage that now
the sampling from the exponential distribution is concentrated where the
function contributes most to the integral. This explains why the examples
use put options, not call options.
Now apply this importance sampling to the confidence interval estimation
for the present value of put option prices. Short programs to create the
confidence intervals for 100, 1,000, and 10,000 samples are in the Scripts
section. Some typical results from the R script are in Table 1.
Table 3 shows that the put option Monte Carlo estimates with importance
sampling are closer to the Black-Scholes value than the simple Monte Carlo
sampling. The confidence intervals are about one-fifth the width compared
with Table 1.
10
Application to Data
Standard and Poor’s 500 Index, with symbol SPX, is a weighted index of
500 stocks. This index is designed to measure performance of the broad
domestic economy through changes in the aggregate market value of 500
stocks representing all major industries. As such, it is a good candidate for
a stock index modeled by Geometric Brownian Motion. The index started
with a level of 10 for the 1941-43 base period.
To test Monte Carlo simulation on real data, use historical data on put
options on the SPX that provides values for K, T − t, and z0 . Values for r
and σ can be inferred from historical data.
The expectation to calculate for the Monte Carlo simulation of the value
of a put option is
2 !
Z ∞
−1 ln(x) − ln(z0 ) − (r − σ 2 /2)t
1
√
√ exp
dx .
max(K−x, 0) √
2
σ t
2πσx t
0
Then the expectation integral is equivalent to
Z ∞
√√
√√
2
2
max(K − z0 e(r−σ /2)t+σ t u , 0) + max(K − z0 e(r−σ /2)t−σ t u , 0)
0
−u
1
√
du .
√ exp
2
2π 2 u
This is now the importance sampling estimate of the value of a put option
on the SPX index. The Scripts section has programs to evaluate confidence
intervals for the put option value using real data.
Sources
This section is adapted from: Simulation and Inference for Stochastic Differential Equations, by Stephen Iacus, Sections 1.3 and 1.4, Springer-Verlag,
2008. The section on antithetic sample is adapted from Owen, Variance
Reduction and Lehna. Interest rates are from Treasury.gov
11
Algorithms, Scripts, Simulations
Algorithm
This script calculates the value of a put option on the Standard & Poor’s 500
stock index (SPX) in several ways. First the script uses the Black Scholes formula for a put option to calculate the theoretical value for a put option. Then
the script uses Monte Carlo simulation based on the Geometric Brownian Motion with the SPX parameters to find an estimate for the put option value.
Finally, the script uses Monte Carlo simulation with antithetic sampling and
importance sampling variance reduction methods to refine the estimates. The
ultimate purpose is to compare the various Monte Carlo methods with the
put option value. The output will be a table of SPX put option value from the
Black Scholes formula, Monte Carlo simulation with 95% confidence interval,
antithetic sampling with 95% confidence interval and importance sampling
with 95% confidence interval Set the total number of trials: n = 10000 Set
the values of S, r, σ, K, T − t Calculate the theoretical value of put option
with Black-Scholes formula Fill the vector x[1..n]pwith random normal vari2
ates y1 = max(0, K −S exp((r−σ
/2)(T −t)+σx (T −t))) y2 = max(0, K −
p
2
S exp((r−σ /2)(T −t)+σ(−x) (T −t))) The antithetic sample becomes y =
(y1 + y2)/2 Fill vector u[1..n] with random normal variates. The
√ importance
√
2
sample becomes u1 = (max(0, K − S exp((r
−√
σ /2)(T√− t) − σ T − t x))+
√
max(0, K − S exp((r − σ 2 /2)(T − t) + σ T − t x)))/ 2πx. Apply the t-test
to calculate mean and confidence intervals of the Monte Carlo simulations
y1[1 : 100], y1[1 : 1000]and y1[1 : n]. Apply the t-test to calculate mean
and confidence intervals of the antithetic samples y[1 : 100], y[1 : 1000] and
y[1 : n] Apply the t-test to calculate mean and confidence intervals of the
importance samples u1[1 : 100], u1[1 : 1000] and u1[1 : n]. Finally, collect
and display a table of theoretical value and means and confidence intervals.
Scripts
R R script for simplified option pricing with Monte Carlo simulation, antithetic sampling, and importance sampling.
1
2
set . seed (2015)
n <- 10000
3
4
S <- 1
12
5
6
7
8
sigma <- 1
r <- sigma ^2 / 2
K <- 1
Tminust <- 1
9
10
11
12
13
# # the value of the put option by Black - Scholes
d2 <- ( log ( S / K ) + ( r - sigma ^2 / 2) * ( Tminust ) ) / ( sigma *
sqrt ( Tminust ) )
d1 <- ( log ( S / K ) + ( r + sigma ^2 / 2) * ( Tminust ) ) / ( sigma *
sqrt ( Tminust ) )
VP <- K * exp ( - r * Tminust ) * pnorm ( - d2 ) - S * pnorm ( - d1 )
14
15
16
x <- rlnorm ( n ) # Note use of default meanlog =0 , sdlog =1
y <- sapply (x , function ( z ) max (0 , K - z ) )
17
18
19
20
mc100 <- t . test ( exp ( - r * Tminust ) * y [1:100]) # first
100 simulations
mc1000 <- t . test ( exp ( - r * Tminust ) * y [1:1000]) # first
1000 simulations
mcall <- t . test ( exp ( - r * Tminust ) * y ) # all simulation
results
21
22
23
24
25
26
type <- c ( " Blacksholes " , " Monte Carlo 100 " , " Monte Carlo
1000 " , " Monte Carlo all " )
putestimate <- c ( VP , mc100 $ estimate , mc1000 $ estimate ,
mcall $ estimate )
putconfintleft <- c ( NA , mc100 $ conf . int [1] , mc1000 $ conf .
int [1] , mcall $ conf . int [1])
putconfintright <- c ( NA , mc100 $ conf . int [2] , mc1000 $ conf .
int [2] , mcall $ conf . int [2])
d <- data . frame ( type , putestimate , putconfintleft ,
putconfintright )
27
28
print ( d )
29
30
31
32
33
x <- rnorm ( n )
y1 <- sapply (x , function ( z ) max (0 , K - exp ( z ) ) )
y2 <- sapply ( -x , function ( z ) max (0 , K - exp ( z ) ) )
y <- ( y1 + y2 ) / 2
34
35
36
37
anti100 <- t . test ( exp ( - r * Tminust ) * y [1:100]) # first
100 simulations
anti1000 <- t . test ( exp ( - r * Tminust ) * y [1:1000]) #
first 1000 simulations
antiall <- t . test ( exp ( - r * Tminust ) * y ) # all
13
simulation results
38
39
40
41
42
43
type <- c ( " Blacksholes " , " Antithetic 100 " , " Antithetic
1000 " , " Antithetic all " )
putestimate <- c ( VP , anti100 $ estimate , anti1000 $ estimate ,
antiall $ estimate )
putconfintleft <- c ( NA , anti100 $ conf . int [1] , anti1000 $
conf . int [1] , antiall $ conf . int [1])
putconfintright <- c ( NA , anti100 $ conf . int [2] , anti1000 $
conf . int [2] , antiall $ conf . int [2])
d <- data . frame ( type , putestimate , putconfintleft ,
putconfintright )
44
45
print ( d )
46
47
48
xN <- rnorm ( n )
yN <- sapply ( xN , function ( z ) max (0 , K - exp ( z ) ) )
49
50
51
52
mcN100 <- t . test ( exp ( - r * Tminust ) * yN [1:100]) # first
100 simulations
mcN1000 <- t . test ( exp ( - r * Tminust ) * yN [1:1000]) #
first 1000 simulations
mcNall <- t . test ( exp ( - r * Tminust ) * yN ) # all
simulation results
53
54
55
56
57
58
type <- c ( " Blacksholes " , " Monte Carlo 100 " , " Monte Carlo
1000 " , " Monte Carlo all " )
putestimate <- c ( VP , mcN100 $ estimate , mcN1000 $ estimate ,
mcNall $ estimate )
putconfintleft <- c ( NA , mcN100 $ conf . int [1] , mcN1000 $ conf .
int [1] , mcNall $ conf . int [1])
putconfintright <- c ( NA , mcN100 $ conf . int [2] , mcN1000 $ conf
. int [2] , mcNall $ conf . int [2])
d <- data . frame ( type , putestimate , putconfintleft ,
putconfintright )
59
60
print ( d )
61
62
63
xE <- rexp (n , rate = 1 / 2)
yE <- sapply ( xE , function ( z ) max (0 , K - exp ( - sqrt ( z ) ) ) / (
sqrt (2 * pi ) * sqrt ( z ) ) )
64
65
66
mcE100 <- t . test ( exp ( - r * Tminust ) * yE [1:100]) # first
100 simulations
mcE1000 <- t . test ( exp ( - r * Tminust ) * yE [1:1000]) #
14
67
first 1000 simulations
mcEall <- t . test ( exp ( - r * Tminust ) * yE )
simulation results
# all
68
69
70
71
72
73
type <- c ( " Blacksholes " , " Monte Carlo 100 " , " Monte Carlo
1000 " , " Monte Carlo all " )
putestimate <- c ( VP , mcE100 $ estimate , mcE1000 $ estimate ,
mcEall $ estimate )
putconfintleft <- c ( NA , mcE100 $ conf . int [1] , mcE1000 $ conf .
int [1] , mcEall $ conf . int [1])
putconfintright <- c ( NA , mcE100 $ conf . int [2] , mcE1000 $ conf
. int [2] , mcEall $ conf . int [2])
d <- data . frame ( type , putestimate , putconfintleft ,
putconfintright )
74
75
print ( d )
R script for SPX option pricing.
Octave Octave script for SPX option pricing.
1
n = 10000;
2
3
4
5
6
7
S = 1614.96; # Standard and Poors 500 Index , on 07 / 01 /
2013
r = 0.008; # implied risk free interest rate , between 3
year and 5 year T - bill rate
sigma = 0.1827; # implied volatility
K = 1575; # strike price
Tminust = 110 / 365; # 07 / 01 / 2013 to 10 / 19 / 2013
8
9
10
11
12
13
14
15
16
## the true value from the Black Scholes Formula for put
option
numerd1 = log ( S / K ) + ( r + sigma ^ 2 / 2) * ( Tminust ) ;
numerd2 = log ( S / K ) + ( r - sigma ^ 2 / 2) * ( Tminust ) ;
d1 = numerd1 / ( sigma * sqrt ( Tminust ) ) ;
d2 = numerd2 / ( sigma * sqrt ( Tminust ) ) ;
part1 = S * ( stdnormal_cdf ( d1 ) - 1) ;
part2 = K * exp ( - r * ( Tminust ) ) * ( stdnormal_cdf ( d2 ) 1) ;
VP = part1 - part2 ;
17
18
x = stdnormal_rnd (n , 1) ;
15
19
20
21
y1 = max (0 , K - S * exp (( r - sigma ^ 2 / 2) * Tminust +
sigma * x * sqrt ( Tminust ) ) ) ;
y2 = max (0 , K - S * exp (( r - sigma ^ 2 / 2) * Tminust +
sigma * ( - x ) * sqrt ( Tminust ) ) ) ;
y = ( y1 + y2 ) / 2;
22
23
24
25
26
27
28
u = exprnd (1 / 0.5 , [n , 1]) ; # note exponential parameter
tildeg = ...
(...
max (0 , K - S * exp (( r - sigma ^ 2 / 2) * Tminust sigma * sqrt ( Tminust ) * sqrt ( u ) ) ) + ...
max (0 , K - S * exp (( r - sigma ^ 2 / 2) * Tminust +
sigma * sqrt ( Tminust ) * sqrt ( u ) ) ) ...
) ./ sqrt (2 * pi * u ) ; # note use of broadcasting
29
30
31
32
33
34
35
36
37
function [m , confintleft , confintright ] = ttest ( data ,
confidence )
m = mean ( data ) ;
se = std ( data ) / sqrt ( length ( data ) ) ;
df = length ( data ) - 1;
q = tinv ((1 + confidence ) / 2 , df ) ;
confintleft = m - q * se ;
confintright = m + q * se ;
endfunction
38
39
40
41
[ mc100mu , mc100cil , mc100cir ] = ttest ( exp ( - r * Tminust )
* y1 (1:100) , 0.95) ;
[ mc1000mu , mc1000cil , mc1000cir ] = ttest ( exp ( - r *
Tminust ) * y1 (1:1000) , 0.95) ;
[ mcallmu , mcallcil , mcallcir ] = ttest ( exp ( - r * Tminust )
* y1 , 0.95) ;
42
43
44
45
[ anti100mu , anti100cil , anti100cir ] = ttest ( exp ( - r *
Tminust ) * y (1:100) , 0.95) ;
[ anti1000mu , anti1000cil , anti1000cir ] = ttest ( exp ( - r *
Tminust ) * y (1:1000) , 0.95) ;
[ antiallmu , antiallcil , antiallcir ] = ttest ( exp ( - r *
Tminust ) * y , 0.95) ;
46
47
48
49
[ imp100mu , imp100cil , imp100cir ] = ttest ( exp ( - r *
Tminust ) * tildeg (1:100) , 0.95) ;
[ imp1000mu , imp1000cil , imp1000cir ] = ttest ( exp ( - r *
Tminust ) * tildeg (1:1000) , 0.95) ;
[ impallmu , impallcil , impallcir ] = ttest ( exp ( - r *
Tminust ) * tildeg , 0.95) ;
16
50
51
52
53
54
55
56
57
58
59
60
61
62
63
putestimate = [ VP , ...
mc100mu , mc1000mu , mcallmu , ...
anti100mu , anti1000mu , antiallmu , ...
imp100mu , imp1000mu , impallmu ];
putconfintleft = [ NA , ...
mc100cil , mc1000cil , mcallcil , ...
anti100cil , anti1000cil , antiallcil , ...
imp100cil , imp1000cil , impallcil ];
putconfintright = [ NA , ...
mc100cir , mc1000cir , mcallcir , ...
anti100cir , anti1000cir , antiallcir , ...
imp100cir , imp1000cir , impallcir ];
d = transpose ([ putestimate ; putconfintleft ;
putconfintright ])
Perl Perl script for SPX option pricing.
1
2
3
4
5
6
use PDL :: NiceSlice ;
use PDL :: GSL :: RNG ;
$rng = PDL :: GSL :: RNG - > new ( ’ taus ’) ;
$rng - > set_seed ( time () ) ;
use PDL :: Constants qw ( PI E ) ;
use Statistics :: Distributions ;
7
8
$n = 10000;
9
10
11
12
13
14
15
$S = 1614.96;
# Standard and Poors 500 Index , on
07/01/2013
$r =
0.008; # implied risk free interest rate , between 3
and 5 year T - bill rate
$sigma
= 0.1827;
# implied volatility
$K
= 1575;
# strike price
$Tminust = 110 / 365;
# 07/01/2013 to 10/19/2013
16
17
18
19
20
sub pnorm {
my ( $x , $sigma , $mu ) = @_ ;
$sigma = 1 unless defined ( $sigma ) ;
$mu
= 0 unless defined ( $mu ) ;
21
return 0.5 * ( 1 + erf ( ( $x - $mu ) / ( sqrt (2) *
$sigma ) ) ) ;
22
23
}
17
24
25
26
27
28
29
30
31
$numerd1 = log ( $S / $K ) + ( ( $r + $sigma **2 / 2 ) * (
$Tminust ) ) ;
$numerd2 = log ( $S / $K ) + ( ( $r - $sigma **2 / 2 ) * (
$Tminust ) ) ;
$d1 = $numerd1 / ( $sigma * sqrt ( $Tminust ) ) ;
$d2 = $numerd2 / ( $sigma * sqrt ( $Tminust ) ) ;
$part1 = $S * ( pnorm ( $d1 ) - 1 ) ;
$part2 = $K * exp ( - $r * $Tminust ) * ( pnorm ( $d2 ) - 1 ) ;
$VP = $part1 - $part2 ;
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
$x = $rng - > ran_gaussian ( 1 , $n ) ;
# tested to here
$y1 = pdl (
zeroes ( $n ) ,
$K - $S * exp (
( $r - $sigma **2 / 2 ) * $Tminust + $sigma * $x *
sqrt ( $Tminust )
)
) -> transpose - > maximum ;
$y2 = pdl (
zeroes ( $n ) ,
$K - $S * exp (
( $r - $sigma **2 / 2 ) * $Tminust + $sigma * ( $x ) * sqrt ( $Tminust )
)
) -> transpose - > maximum ;
$y = ( $y1 + $y2 ) / 2;
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
$u = $rng - > ran_exponential ( 1 / 0.5 , $n ) ;
# note
exponential parameter
$tildeg1 = pdl (
zeroes ( $n ) ,
$K - $S * exp (
( $r - $sigma **2 / 2 ) * $Tminust - $sigma * sqrt
( $Tminust ) * sqrt ( $u )
)
) -> transpose - > maximum ;
$tildeg2 = pdl (
zeroes ( $n ) ,
$K - $S * exp (
( $r - $sigma **2 / 2 ) * $Tminust + $sigma * sqrt
( $Tminust ) * sqrt ( $u )
)
) -> transpose - > maximum ;
$tildeg = ( $tildeg1 + $tildeg2 ) / sqrt ( 2 * PI * $u ) ;
18
62
63
64
65
66
67
68
sub ttest {
my ( $data , $confidence ) = @_ ;
$confidence = 0.95 unless defined ( $confidence ) ;
( $mean , $prms , $median , $min , $max , $adev , $rms ) =
stats ( $data ) ;
$df = nelem ( $data ) - 1;
$q = Statistics :: Distributions :: tdistr ( $df , ( 1 $confidence ) / 2 ) ;
69
70
71
72
73
74
75
# Note use of level (1 - $confidence ) /2) instead of
percentile (1 + $confidence ) /2
$widthci
= $q * $rms / sqrt ( nelem ( $data ) ) ;
$confintleft = $mean - $widthci ;
$confintright = $mean + $widthci ;
return ( $mean , $confintleft , $confintright ) ;
}
76
77
78
79
80
81
82
( $mc100mu , $mc100cil , $mc100cir ) =
ttest ( exp ( - $r * $Tminust ) * $y1 ( 0 : 99 ) , 0.95 )
;
( $mc1000mu , $mc1000cil , $mc1000cir ) =
ttest ( exp ( - $r * $Tminust ) * $y1 ( 0 : 999 ) , 0.95
);
( $mcallmu , $mcallcil , $mcallcir ) =
ttest ( exp ( - $r * $Tminust ) * $y1 , 0.95 ) ;
83
84
85
86
87
88
89
( $anti100mu , $anti100cil , $anti100cir ) =
ttest ( exp ( - $r * $Tminust ) * $y ( 0 :
( $anti1000mu , $anti1000cil , $anti1000cir )
ttest ( exp ( - $r * $Tminust ) * $y ( 0 :
;
( $antiallmu , $antiallcil , $antiallcir ) =
ttest ( exp ( - $r * $Tminust ) * $y , 0.95
99 ) , 0.95 ) ;
=
999 ) , 0.95 )
);
90
91
92
93
94
95
96
( $imp100mu , $imp100cil , $imp100cir ) =
ttest ( exp ( - $r * $Tminust ) * $tildeg ( 0 : 99 ) ,
0.95 ) ;
( $imp1000mu , $imp1000cil , $imp1000cir ) =
ttest ( exp ( - $r * $Tminust ) * $tildeg ( 0 : 999 ) ,
0.95 ) ;
( $impallmu , $impallcil , $impallcir ) =
ttest ( exp ( - $r * $Tminust ) * $tildeg , 0.95 ) ;
97
98
$d = pdl (
19
[
[
[
[
99
100
101
102
$VP ,
$mc100mu ,
$mc1000mu ,
$mcallmu ,
" NaN " ,
$mc100cil ,
$mc1000cil ,
$mcallcil ,
" NaN " ] ,
$mc100cir ] ,
$mc1000cir ] ,
$mcallcir ] ,
103
[ $anti100mu , $anti100cil , $anti100cir ] ,
[ $anti1000mu , $anti1000cil , $anti1000cir ] ,
[ $antiallmu , $antiallcil , $antiallcir ] ,
104
105
106
107
[ $imp100mu , $imp100cil , $imp100cir ] ,
[ $imp1000mu , $imp1000cil , $imp1000cir ] ,
[ $impallmu , $impallcil , $impallcir ]
108
109
110
111
);
112
113
print $d ;
SciPy Python script for SPX option pricing.
1
2
import scipy
from scipy . stats import norm
3
4
n = 10000
5
6
7
8
9
10
S = 1614.96 # Standard and Poors 500 Index , on
07/01/2013
r = 0.008 # implied risk free interest rate , between 3
year and 5 year T - bill rate
sigma = 0.1827 # implied volatility
K = 1575 # strike price
Tminust = 110. / 365. # 07/01/2013 to 10/19/2013
11
12
13
14
15
16
17
18
numerd1 = scipy . log ( S / K ) + ( r + sigma ** 2 / 2) *
Tminust
numerd2 = scipy . log ( S / K ) + ( r - sigma ** 2 / 2) *
Tminust
d1 = numerd1 / ( sigma * scipy . sqrt ( Tminust ) )
d2 = numerd2 / ( sigma * scipy . sqrt ( Tminust ) )
part1 = S * ( norm . cdf ( d1 ) - 1)
part2 = K * scipy . exp ( - r * Tminust ) * ( norm . cdf ( d2 ) - 1)
VP = part1 - part2
19
20
21
x = norm . rvs ( size = n )
y1 = scipy . maximum (0 , K - S * scipy . exp (( r - sigma ** 2 /
2) * Tminust
20
22
23
24
25
+ sigma * x * scipy . sqrt ( Tminust ) ) )
y2 = scipy . maximum (0 , K - S * scipy . exp (( r - sigma ** 2 /
2) * Tminust
+ sigma * -x * scipy . sqrt ( Tminust ) ) )
y = ( y1 + y2 ) / 2
26
27
28
29
30
31
32
33
from scipy . stats import expon
u = expon . rvs ( size =n , scale =1. / 0.5)
tildeg = ( scipy . maximum (0 , K - S * scipy . exp (( r ** 2 / 2)
* Tminust - sigma * scipy . sqrt ( Tminust )
. sqrt ( u ) ) )
+ scipy . maximum (0 , K - S * scipy . exp (( r
** 2 / 2)
* Tminust + sigma * scipy . sqrt ( Tminust )
. sqrt ( u ) ) ) ) \
/ scipy . sqrt (2 * scipy . pi * u )
sigma
* scipy
- sigma
* scipy
34
35
36
37
38
39
40
41
def ttest ( data , confidence =0.95) :
m = scipy . mean ( data )
se = scipy . stats . sem ( data )
df = len ( data ) - 1
h = se * scipy . stats . t . ppf ((1 + confidence ) / 2. , df )
return (m , m - h , m + h )
42
43
44
45
46
47
48
49
[ mc100mu , mc100cil , mc100cir ] = ttest ( scipy . exp ( - r *
Tminust )
* y1 [0:99] , 0.95)
[ mc1000mu , mc1000cil , mc1000cir ] = ttest ( scipy . exp ( - r *
Tminust )
* y1 [0:999] , 0.95)
[ mcallmu , mcallcil , mcallcir ] = ttest ( scipy . exp ( - r *
Tminust ) * y1 ,
0.95)
50
51
52
53
54
55
[ anti100mu , anti100cil , anti100cir ] = ttest ( scipy . exp ( - r
* Tminust )
* y [0:99] , 0.95)
[ anti1000mu , anti1000cil , anti1000cir ] = ttest ( scipy . exp
( - r * Tminust )
* y [0:999] , 0.95)
[ antiallmu , antiallcil , antiallcir ] = ttest ( scipy . exp ( - r
* Tminust )
21
56
* y , 0.95)
57
58
59
60
61
62
63
[ imp100mu , imp100cil , imp100cir ] = ttest ( scipy . exp ( - r *
Tminust )
* tildeg [0:99] , 0.95)
[ imp1000mu , imp1000cil , imp1000cir ] = ttest ( scipy . exp ( - r
* Tminust )
* tildeg [0:999] , 0.95)
[ impallmu , impallcil , impallcir ] = ttest ( scipy . exp ( - r *
Tminust )
* tildeg , 0.95)
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
putestimate = [
VP ,
mc100mu ,
mc1000mu ,
mcallmu ,
anti100mu ,
anti1000mu ,
antiallmu ,
imp100mu ,
imp1000mu ,
impallmu ,
]
putconfintleft = [
scipy . nan ,
mc100cil ,
mc1000cil ,
mcallcil ,
anti100cil ,
anti1000cil ,
antiallcil ,
imp100cil ,
imp1000cil ,
impallcil ,
]
putconfintright = [
scipy . nan ,
mc100cir ,
mc1000cir ,
mcallcir ,
anti100cir ,
anti1000cir ,
antiallcir ,
imp100cir ,
22
98
99
100
101
102
imp1000cir ,
impallcir ,
]
d = scipy . transpose ( scipy . array ([ putestimate ,
putconfintleft ,
putconfintright ]) )
103
104
print ( d )
Problems to Work for Understanding
1. Experiment with various values of sample size in the Monte Carlo simulation of the simplified put option to determine how the width of the
confidence interval depends on the sample size.
2. Experiment with various random seeds and values of the parameter σ
in the simplified put option model to find the relative errors of the basic
Monte Carlo method, antithetic sampling and importance sampling.
3. From Options we know the value of a put option increases with increasing volatility σ. Additionally the standard deviation of the simplified
security price increases exponentially with increasing σ. Experiment
with various values of σ in the Monte Carlo simulation of the simplified put option to determine how the put option price and the width
of the confidence intervals vary with sigma.
4. Evaluate the following integrals numerically (that is, with numerical
integration software, not Monte Carlo evaluation):
(a)
Z
∞
max(K − x, 0) √
0
√
1
1
√ exp(− (ln(x)/σ T )2 ) dx;
2
2πσx T
23
(b)
2
Z
0
Z
∞
e−x /2
(1 − e ) √
dx;
2π
−∞
x
(c)
0
√
1 − e− y e−y/2
√ √
dy .
2π y 2
Interpreting each as the expected value of a put option at expiration,
find the present value i of each if the interest rate is r = σ 2 /2 with
σ = 1 and T − t = T − 0 = 1.
5. Change the scripts to provide descriptive output.
6. Change the scripts to create a Monte Carlo simulation estimate of the
value of a put option on the Standard and Poor’s 500 index (SPX)
directly using 10, 000 random variates with a lognormal distribution.
Use parameters S = 1614.96, r = 0.008, σ = 0.1827, K = 1575,
T − t = 110/365. Also construct the 95% confidence interval for the
estimate.
7. Change the scripts to create a Monte Carlo simulation estimate of the
value of a call option on the Standard and Poor’s 500 index (SPX)
directly using 10, 000 random variates with a lognormal distribution.
Use parameters S = 1614.96, r = 0.008, σ = 0.1827, K = 1575,
T − t = 110/365.
8. Provide a detailed explanation of the changes of variables that lead
from
2 !
Z ∞
−1 ln(x) − ln(z0 ) − (r − σ 2 /2)t
1
√
√ exp
dx .
max(K−x, 0) √
2
σ t
2πσx t
0
to
Z
∞
max(K − z0 e(r−σ
2 /2)t+σ
√√
t u
, 0) + max(K − z0 e(r−σ
2 /2)t−σ
√√
t u
, 0)
0
1
√
√ exp
2π 2 u
24
−u
2
du .
Reading Suggestion:
References
[1] Art Owen.
Monte carlo theory, methods
http://statweb.stanford.edu/ owen/mc/, 2013.
and
examples.
Outside Readings and Links:
1.
2.
3.
4.
I check all the information on each page for correctness and typographical
errors. Nevertheless, some errors may occur and I would be grateful if you would
alert me to such errors. I make every reasonable effort to present current and
accurate information for public use, however I do not guarantee the accuracy or
timeliness of information on this website. Your use of the information from this
website is strictly voluntary and at your risk.
I have checked the links to external sites for usefulness. Links to external
websites are provided as a convenience. I do not endorse, control, monitor, or
guarantee the information contained in any external website. I don’t guarantee
25
that the links are active at all times. Use the links here with the same caution as
you would all information on the Internet. This website reflects the thoughts, interests and opinions of its author. They do not explicitly represent official positions
or policies of my employer.
Information on this website is subject to change without notice.
Steve Dunbar’s Home Page, http://www.math.unl.edu/~sdunbar1
Email to Steve Dunbar, sdunbar1 at unl dot edu
Last modified: Processed from LATEX source on August 8, 2016
26