Monte Carlo Method: Numerical Methods in Quantitative Finance
Monte Carlo Method: Numerical Methods in Quantitative Finance
Expectation to be calculated:
Vt
= EQ [h(X)] (2)
Bt
σ̂n
And the Monte Carlo standard error is defined as: ϵn = √
n
Confidence Interval
As n → ∞, a asymptotically valid 1 − δ confidence interval for µ is an the
interval
However they are both adapted to the random processes with known
distribution — Brownian motions
Therefore we only need to generate the Brownian motions
1 Given the current value of one or more state variables (usually stored
internally in the generator)
3 Use a specific formula to obtain a new uniform (0, 1) variate from the
current state variables
x0 = 0.9876
x02 = 0.97535376
x1 = 0.5353
x12 = 0.28654609
x2 = 0.6546
3 xs = [0] * 100
4 xs[0] = 0.2372 # seed
5 for i in range(1, 100):
6 xs[i]=(int(xs[i-1]**2*1.0e6)
%1e4)/1.0e4
0 7 plt.scatter(range(100), xs)
8 plt.show()
0 50 100
i
PRNs — mid-square method seed at 0.2372
0.5
xi
xi
0.5
0
0
0 50 100 0 50 100
i i
PRNs — mid-square method seed at 0.9876 PRNs — mid-square method seed at 0.5649
▶ Given R,
√ the point (Z1 , Z2 ) is uniformly distributed on the circle of
radius R centered at origin
The algorithm is
1. Generate independent U1 , U2 from U(0, 1)
2. R ← −2 log(U1 ) — uniform to exponential distribution (inverse CDF)
3. V ← 2πU2 — the angle to determine the point on the circle
√ √
4. Z1 ← R cos(V ), Z2 ← R sin(V )
Transform a pair (U1 , U2 ) to (Z1 , Z2 )
Algorithm 2 AcceptanceRejection
1: repeat
2: Generate x from distribution g
3: Generate u from U(0, 1)
4: until U ≤ f (x)/cg (x)
5: return x
There can be many to one (jump in CDF), one to many (flat CDF)
1 np.random.seed(0)
2 # generate 3 brownian motions for 1Y
3 nBrownians, nTimeSteps = 3, 366
4 brownians = np.zeros((nBrownians, nTimeSteps))
5 # each time step is 1 day,
6 # so standard deviation is sqrt(1/365.0)
7 stdev = math.sqrt(1/365.0)
8 for i in range(nBrownians):
9 for j in range(1, nTimeSteps):
10 dw = np.random.normal(0, stdev)
11 brownians[i,j] = brownians[i,j-1] + dw
12
13 plt.plot(range(nTimeSteps), brownians[0])
14 plt.plot(range(nTimeSteps), brownians[1])
15 plt.plot(range(nTimeSteps), brownians[2])
16 plt.show()
1 import math
2 from numpy.random import random
3 import numpy as np
4
5 def mcEuropean(S0, T, r, q, vol, nPaths, trade):
6 random.seed(0)
7 sum,hsquare = 0,0
8 stdev = np.math.sqrt(T)
9 for i in range(nPaths):
10 wT = np.random.normal(0, stdev)
11 h = trade.payoff(S0 * math.exp((r - q - 0.5*vol*vol) * T + vol * wT))
12 sum += h
13 hsquare += h * h
14
15 pv = math.exp(-r*T) * sum / nPaths
16 stderr = math.sqrt((hsquare/nPaths - (sum/nPaths) * (sum/nPaths)) / nPaths)
17 return pv, stderr
mcPrice - analyticPrice
Standard Error
0.2
Closed form solution does not exist since σ(S, t) is state dependent
Consider a process X that satisfies the below SDE of a general form:
where Z ∼ N(0, 1)
The stepwise induction is
√
X (t + ∆t) = X (t) + a(X (t))∆t + b(X (t)) ∆tZ (23)
Again the simplified constant drift does not affect the generality of
our formulation, replacing it with a term structure µ(t) is trivial
−2
In Euler we just use b(X (t)) for the period t → t + ∆t, this is the
place of truncation error so we need to refine this part
So
Z u Z u
′
b(X (u)) = b(X (t)) + b(X (s))b (X (s))dWs + c(X (s))ds
t t
Ru
Since t c(X (t))dt is of order O(u − t) and is higher than we need
√
(because of the multiplication with ∆Wt is order O( ∆t), we can
omit it. Therefore
Z u
b(X (u)) ≈ b(X (t)) + b(X (s))b ′ (X (s))dWs
t
Therefore
b(X (u)) = b(X (t)) + b(X (t))b ′ (X (t))(Wu − Wt ) + O(u − t). (31)
12
10
8
0 1 2 3 4 5
t (5 steps)
Numerical Methods in QF (QF5204) Monte Carlo Method 49 / 91
Monte Carlo Method — Pros and Cons
Pros:
Easy to implement
Easy to extend
Dimension friendly
Cons:
Monte Carlo noise
And the random samples for ξ1 and ξ2 (to generate the correlated
Brownian increments) are vectors:
and
h i ξ̂ · ξ̂ , ξ̂ · ξ̂ n, nρ
ξ̂ 1 ⊤ ⊤ 1 1 1 2
× ξ̂ 1 , ξ̂ 2 = = = n C (44)
ξ̂ 2 ξ̂ 2 · ξ̂ 1 , ξ̂ 2 · ξ̂ 2 nρ, n
C = LL⊤ (45)
We have
h
ξ̂ 1 ⊤ ⊤
i
× ξ̂ 1 , ξ̂ 2 = n LL⊤ (46)
ξ̂ 2
So
h
−1 ξ̂ 1 ⊤ ⊤
i
L × ξ̂ 1 , ξ̂ 2 (L⊤ )−1 = n I (47)
ξ̂ 2
C = LL⊤ (50)
Just need to start from the top-left corner and progressively solve for
each Lij
In python implementation: L = np.linalg.cholesky(C)
Numerical Methods in QF (QF5204) Monte Carlo Method 56 / 91
Correlated Brownian Motions — Examples
Now we can generate brownian motions with correlations (example
brownians with different ρ)
0.4 0.4
0.2 0.2
0 0
−0.2 W0
−0.2 W0
W1 , ρ = 80% W1 , ρ = 20%
−0.4 −0.4
0 5 · 10−2 0.1 0.15 0 5 · 10−2 0.1 0.15
t t
0.4 0.4
0.2 0.2
0 0
−0.2 W0
−0.2 W0
W1 , ρ = −20% W1 , ρ = −80%
−0.4 −0.4
0 5 · 10−2 0.1 0.15 0 5 · 10−2 0.1 0.15
t t
Numerical Methods in QF (QF5204) Monte Carlo Method 57 / 91
Pricing Spread Option — MC with Two Assets under BS
1 def mcSpread(payoff, S1, S2, T, r, q1, q2, vol1, vol2, rho, nPaths, nT):
2 np.random.seed(0)
3 sum, hsquare, C = 0, 0, np.identity(2)
4 C[0, 1] = C[1, 0] = rho
5 L = np.linalg.cholesky(C)
6 for i in range(nPaths):
7 brownians = np.zeros((2, nT))
8 dt = T / nT
9 stdev = math.sqrt(dt)
10 # generate brownian increments
11 for j in range(2):
12 brownians[j] = np.random.normal(0, stdev, nT)
13 brownians = np.matmul(L, brownians)
14 x1, x2 = math.log(S1), math.log(S2)
15 for j in range(nT):
16 # simulate asset 1
17 a = (r-q1-0.5*vol1*vol1) * dt # drift for asset 1
18 b = brownians[0, j] * vol1 # diffusion term for asset 1
19 x1 += a + b # update state variable
20 # simulate asset 2
21 a = (r-q2-0.5*vol2*vol1) * dt # drift for asset 1
22 b = brownians[1, j] * vol2 # diffusion term for asset 1
23 x2 += a + b # update state variable
24 h = payoff(math.exp(x1), math.exp(x2))
25 sum += h
26 hsquare += h*h
27 pv = math.exp(-r * T) * sum / nPaths
28 se = math.sqrt((hsquare/nPaths - (sum/nPaths)*(sum/nPaths))/nPaths)
29 return pv, se
Each simulation path gives one realization of the market, the trade
should be able to take that to return the discounted cash flows of this
realization — the h(Xi ) in our expectation
Given a list of event dates from the trade, the intermediate times
steps the model requires to diffuse properly:
1 models[a].GetTimeSteps(trade.AllDates())
Variates recycling
Control variates
Stratified sampling
Importance sampling
1
We use ĥi = (h(Wi ) + h(−Wi )) as our random sample of the
2
n
1X
payoff. The estimator becomes ĥi .
n
i=1
−0.2
−0.4
−0.6
103 104 105 106
Number of MC Paths
European call option, K = 100, S = 100, r = 5%, q = 2%, T = 1, σ = 15%
−0.5
−1
The higher correlation g and h is, the more effective the technique is.
The simple ones are easy to implement and generalize (our preference)
The complicated ones are difficult to implement and generalize but
more effective when tackled in the right way
But overall the improvement they can make on the convergence is the
1
constant factor in front of O(n− 2 ). Is there any technique that can
change the convergence in terms of magnitude?
x
1 j−1 j n−1
n n n n 1
x x
The error is associated with the density of the points when you
project them to each dimension. Random number is better in the
sense that after projection there are still n points.
(log n)d
Quasi Monte Carlo (QMC) has a convergence rate O ,
n
and for d << n it’s approximately O(n−1 ).
x x
P. Jäckel.
Monte Carlo Methods in Finance.
2002.
P. Glasserman.
Monte Carlo Methods in Financial Engineering.
Springer, 2003.