Lesson10
Lesson10
Financial
Modeling
Lesson 10
1
Simulation 2: Option Valuation
Chapter 23
BMD5302
Financial
Modeling
Lesson 10b
Simulation 2: Option
Valuation
Chapter 23
2
(23) Using Monte
Carlo Methods for
Option Pricing
1. Pricing Vanilla Call
2. Pricing Asian Options
3. Pricing Barrier Options
4. Generating Correlated Price Series
3
• Simulate the stock price till
maturity. Obtain ST
• Find the value of the derivative
given ST
• Compute the present value of
General the derivative given the stock
price path.
Idea • Do this many times, compute the
average and standard deviation
of the derivative value
• Estimate of the derivative value =
average
4
Simulating the Stock Price
• For each time step t, we have
𝑆 𝑡 + Δ𝑡 =𝑆𝑡 exp ( 𝜇 Δ 𝑡+ 𝜎 √ Δ𝑡 𝑍 ) where 𝑍 𝑁 ( 0 , 1 )
𝑆 𝑇 =𝑆 0 exp ( 𝜇𝑇 +𝜎 √𝑇 𝑍 ) where 𝑍 𝑁 ( 0 ,1 )
• For pricing purpose, we always use risk-neutral
returns: 𝜎
2
𝜇=𝑟 𝑓 −
2 5
• Always discount to PV by
the rate rf.
• Always fix a random seed
Computing • Use array to store stock
the PV of price info only if needed,
else save on memory
the
• Try to reduce the
Derivative computation needed per
loop. Store fixed
intermediate values in
variables.
6
Model 1: Finding Vanilla Call Price
• Using simulation, find the expected price and
its standard deviation of a Vanilla Call:
– S0 = 50
– X = 50
– r = 0.025
– T = 0.7
– sig = 0.2
– Number of subperiods, n = 1
– Number of simulation runs = 1 * 10^6
– Use randseed = -4, 1001 7
Implementation in Worksheet
A B C D E F G
1 S0 = 50 Rand NormSInv ST Call Payoff
=$B$1*EXP($B$7+ =MAX(F3-$B$2,0) *
2 X= 50 =RAND() =NORMSINV(D3) $B$10*E3) EXP(-$B$3 * $B$4) • Generate Rand
r= 0.025 1 0.223642 -0.75995218 44.18382108 0
3
4 T= 0.7 2 0.760514 0.707957674 56.48567028 6.3731584
• Transform through
5 sig = 0.2 3 0.538283 0.096109518 50.98875937 0.971606603 Normsinv
6 4 0.315323 -0.480817727 46.29652068 0
7 mu = 0.0035 5 0.234138 -0.725285966 44.44086595 0 • Simulate ST
8 =(B3-B5^2/2) *B4 6 0.786102 0.792969494 57.29493246 7.168381687
9 7 0.627086 0.32414424 52.97195969 2.920402834
• Compute Call
10 sd = 0.167332005 8 0.573929 0.186386845 51.76485738 1.734241048 Payoff
11 =B5*SQRT(B4) 9 0.064671 -1.516701026 38.92864602 0
12 10 0.813225 0.889842982 58.23125371 8.088459864 • Find present value
average = 2.532226116 11 0.624589 0.317556095 52.91359518 2.86305082
13
14 =AVERAGE(G3:G22) 12 0.634172 0.342924284 53.13868604 3.08423685
of Payoff
15 13 0.489988 -0.025099765 49.96501255 0 • Find Average
16 stdev = 0.661025155 14 0.810559 0.879956567 58.1350006 7.993876524
17 =STDEV(G3:G22)/SQRT(20) 15 0.365598 -0.343534333 47.3723496 0 • Find Standard
18 16 0.526597 0.06671869 50.73861094 0.725797688
19 17 0.741245 0.647189906 55.91421215 5.811613792 Deviation of
20 18 0.117837 -1.185870174 41.14444694 0 Estimate
21 19 0.62662 0.322914899 52.96106405 2.909696207
22 20 0.261122 -0.639888753 45.080471 0 • Difficult to have
many simulations
8
A B
Sub CallOptionSimulation()
Rnd (-4): Randomize (1001) C = WorksheetFunction.Max(s -
Const N = 10 ^ 6 X, 0)
S0 = 50: X = 50: rf = 0.025 C = C * Exp(-rf * T)
T = 0.7: sigma = 0.2 Sum = Sum + C
Sum2 = Sum2 + C * C
mu = (rf - sigma ^ 2 / 2) * T Next i
sd = sigma * Sqr(T)
Cells(1, 2) = Sum / N
Sum = 0 Cells(2, 2) = Sqr((Sum2 - Sum ^ 2
Sum2 = 0 / N) / (N - 1)) / Sqr(N)
√
For i = 1 To N End Sub
( )
r = mu + sd * RndN() (∑ 𝑥 )
2
s = S0 * Exp(r) ∑ 𝑥2 − 𝑛
𝑛 −1
𝑠𝑡𝑑𝑒𝑣=
𝑛
9
• Download
DerivativesSimulations.ipynb
from Luminus | Files |
Lecture Notes
Implementation
in Python
• Go to
https://colab.research.googl
e.com
• Click on Files, Open
Notebook, Upload
and upload the .ipynb file
10
Implementation in Python
def SimulateCall(S0,X,T,rf,sigma,N,seed1):
import math
import numpy as np
mu = (rf-sigma * sigma / 2) * T
sd = sigma * math.sqrt(T)
np.random.seed(seed1)
returns = np.random.normal(mu, sd, N)
print(returns[0:12])
Stockprices = np.exp(returns) * S0
Calls = np.maximum(Stockprices-X,0)
#Calls = Stockprices
#for i in range(N):
# Calls[i] = max(Stockprices[i]-X, 0)
Calls = Calls * math.exp(-rf * T)
print("The mean = ", np.average(Calls))
print("The standard deviation = ", np.std(Calls)/math.sqrt(N))
print(Calls[0:12])
import pandas as pd
pd.DataFrame(Stockprices).hist()
pd.DataFrame(Calls).hist()
SimulateCall(50,50,0.7,0.025,0.2,10**6,1) 11
Model 2: Finding Vanilla Put Price
• Using simulation, find the expected price and
its standard deviation of a Vanilla Put:
– S0 = 50
– X = 50
– r = 0.025
– T = 0.7
– sig = 0.2
– Number of subperiods, n = 1
– Number of simulation runs = 1*10^6
– Use randseed = -4, 1001 12
Implementation in Worksheet
A B C D E F G
1 S0 = 50 Rand NormSInv ST Put Payoff
=$B$1*EXP($B$7+ =MAX($B$2-F3,0) *
2 X= 50 =RAND() =NORMSINV(D3) $B$10*E3) EXP(-$B$3 * $B$4) • Only column G
r= 0.025 1 0.199519 -0.843340967 43.57157858 6.316902681
3
4 T= 0.7 2 0.51555 0.038988489 50.50372154 0 changed.
5
6
sig = 0.2 3
4
0.521707
0.655213
0.054438218
0.399433961
50.6344544
53.64354211
0
0
• The rest of the
7 mu = 0.0035 5 0.271422 -0.608516486 45.31774699 4.601026385 simulation
8 =(B3-B5^2/2) *B4 6 0.439254 -0.152859844 48.90817992 1.072879438
9 7 0.700616 0.526173087 54.79333724 0 engine and data
10
11
sd =
=B5*SQRT(B4)
0.167332005 8
9
0.585753
0.149278
0.216634596
-1.039534473
52.02752507
42.16437278
0
7.699696606
aggregation still
12 10 0.141892 -1.071855465 41.93694921 7.923174881 works.
13 average = 2.873787805 11 0.805745 0.862321517 57.96370241 0
14 =AVERAGE(G3:G22) 12 0.523472 0.058868389 50.67200411 0
15 13 0.141295 -1.074517804 41.91827069 7.941529374
16 stdev = 0.758905802 14 0.327228 -0.447579502 46.55473093 3.38550135
17 =STDEV(G3:G22)/SQRT(20) 15 0.50285 0.007142861 50.23531346 0
18 16 0.68512 0.482064468 54.39040826 0
19 17 0.113594 -1.207632512 40.99489044 8.848891039
20 18 0.933978 1.506088869 64.55643975 0
21 19 0.261491 -0.638756049 45.08901625 4.825789157
22 20 0.259975 -0.643421514 45.05382982 4.860365182
13
A B
Implementation in VBA
1 average = 2.894438
2 stdev = 0.004125
Roughly means accurate up to
2nd decimal place
Sub PutOptionSimulation()
Rnd (-4): Randomize (1001) C = WorksheetFunction.Max(X -
Const N = 10 ^ 6 s, 0)
S0 = 50: X = 50: rf = 0.025 C = C * Exp(-rf * T)
T = 0.7: sigma = 0.2 Sum = Sum + C
Sum2 = Sum2 + C * C
mu = (rf - sigma ^ 2 / 2) * T Next i
sd = sigma * Sqr(T)
Cells(1, 2) = Sum / N
Sum = 0 Cells(2, 2) = Sqr((Sum2 - Sum ^ 2
Sum2 = 0 / N) / (N - 1)) / Sqr(N)
√
For i = 1 To N End Sub
( )
r = mu + sd * RndN() (∑ 𝑥 )
2
s = S0 * Exp(r) ∑ 𝑥2 − 𝑛
𝑛 −1
𝑠𝑡𝑑𝑒𝑣=
𝑛
14
Implementation in Python
def SimulatePut(S0,X,T,rf,sigma,N,seed1):
import math
import numpy as np
mu = (rf-sigma * sigma / 2) * T
sd = sigma * math.sqrt(T)
np.random.seed(seed1)
returns = np.random.normal(mu, sd, N)
print(returns[0:12])
Stockprices = np.exp(returns) * S0
Puts = np.maximum(X-Stockprices,0)
#Puts = Stockprices
#for i in range(N):
# Puts[i] = max(X-Stockprices[i], 0)
Puts = Puts * math.exp(-rf * T)
print("The mean = ", np.average(Puts))
print("The standard deviation = ", np.std(Puts)/math.sqrt(N))
print(Puts[0:12])
import pandas as pd
pd.DataFrame(Stockprices).hist()
pd.DataFrame(Puts).hist()
SimulatePut(50,50,0.7,0.025,0.2,10**6,1)
15
Structured Product 1: Principal Protection +
Participation in Upside
• Suppose
– Let S&P500 index be S0 now and ST 5 years later.
– Initial amount = $1,000
– No interest payments within 5 years
– Participation rate = 50%
– Payoff in 5 years
• If ST <= S0 then only get $1000 back
• If ST > S0 then compute r = 50% * (ST / S0 – 1).
Get $1000 + $1000 * r
= $1000 * 50% + $1000 * 50% / S0 * ST.
– S0 = X = 950, rf = 5%, T = 5 years, = 25%,
16
Implementation in Worksheet
A B C D E F G
1 S0 = 950 Rand NormSInv ST Struc Payoff
=IF(F3<=$B$1,1000,1000*
Participatio =$B$1*EXP($B$7+ $B$2*(F3/$B$1-1)+ 1000*
2 n Rate 50% =RAND() =NORMSINV(D3) E3*$B$10) (1+$B$2)) * $B$13 • Parameters are
3
4
r=
T=
0.05
5
1
2
0.842482
0.017055
1.00471006
-2.118773789
1829.617088
319.1883698
1528.751952
778.8007831
updated
5
6
sig = 0.25 3
4
0.115267
0.630188
-1.198984326
0.332351898
533.7669766
1256.395698
778.8007831
1293.791285
• Column G is
7
8
mu =
=(B3-B5^2/2)*B4
0.09375 5
6
0.253492
0.582145
-0.663540549
0.207383771
720.0218376
1171.620412
778.8007831
1259.042306
changed.
9 7 0.963294 1.790256409 2838.399856 1942.247115 • The rest of the
10 sd = 0.559016994 8 0.542936 0.107832708 1108.199938 1233.046562
11 =B5*SQRT(B4) 9 0.139992 -1.080356244 570.3638463 778.8007831 simulation
12 10 0.772 0.745449 1582.768241 1427.569807
13 discount = 0.778800783 11 0.85143 1.042584205 1868.76726 1544.799418 engine and data
14
15
=EXP(-B3*B4) 12
13
0.963696
0.985922
1.795287597
2.195107784
2846.394149
3559.283503
1945.523937
2237.733825
aggregation still
16 average = 1197.598464 14 0.405412 -0.239362372 912.6973633 778.8007831 works although
17 =AVERAGE(G3:G22) 15 0.518309 0.045910421 1070.495271 1217.591602
18 16 0.654219 0.396736316 1302.439506 1312.664418 this is a
19
20
stdev = 103.686293
=STDEV.S(G3:G22)/SQRT(20)
17
18
0.222487
0.368931
-0.763820297
-0.334686988
680.7692834
865.3346151
778.8007831
778.8007831
structured
21 19 0.371752 -0.327215399 868.956456 778.8007831 product
22 Low limit = 994.3770637 20 0.255975 -0.655804931 723.1421997 778.8007831
23 Up Limit = 1400.819864 • Correct Ans =
24 =NORMINV(0.025,B16,B19)
25 =NORMINV(0.975,B16,B19) 941
17
A B
Implementation in VBA
1 average = 941.1854
2 stdev = 0.262515
Roughly means accurate up to
2nd decimal place
Sub Prod1Simulation ()
Rnd (-4): Randomize (1001) If s < X Then
Const N = 10 ^ 6 C = 1000
S0 = 950: X = 950: rf = 0.05 Else
T = 5: sigma = 0.25 C = 1000 + parti * (s / S0 - 1) * 1000
parti = 0.5 End If
C = C * Exp(-rf * T)
mu = (rf - sigma ^ 2 / 2) * T Sum = Sum + C
sd = sigma * Sqr(T) Sum2 = Sum2 + C * C
Next i
Sum = 0
Sum2 = 0 Cells(1, 2) = Sum / N
For i = 1 To N Cells(2, 2) = Sqr((Sum2 - Sum ^ 2 / N) /
r = mu + sd * RndN() (N - 1)) / Sqr(N)
s = S0 * Exp(r) End Sub
18
Implementation in Python
def SimulateStructProd1(S0,T,rf,sigma,Partrate,N,seed1):
import math
import numpy as np
mu = (rf-sigma * sigma / 2) * T
sd = sigma * math.sqrt(T)
np.random.seed(seed1)
returns = np.random.normal(mu, sd, N)
Stockprices = np.exp(returns) * S0
#import pandas as pd
#pd.DataFrame(Stockprices).hist()
#pd.DataFrame(D).hist()
SimulateStructProd1(950,5,0.05,0.25,0.5,10**6,1)
19
Structured Product 2:
ABN-AMRO Airbag
0/X 2
100
=
ient
r ad
g
X1 X2
As asset price fall, the
payoff falls. An Airbag is
created at S = X2,
Airbag distorting the line to X1,
/ X1 so as to form a “cushion”
000 for the investor. The
1
nt= investor receives higher
die payoff than if without the
a
gr Typically X2 = S0, and X1 is Airbag. Note that payoff
a fraction of X2, e.g. 75%. intersects (0,0).
20
Structured Product 2:
ABN-AMRO Airbag
• Payoff Formulas:
– Given S0 = 3,302.98, r = 7%, T = 4, = 15.75%
– X1 = 2,477.23, X2 = 3,302.98
– P = 11.017, C = 898.65, Bond = 755.7837
– Price = 755.7837 - 1000/2477.23 *S011.017
3302.98 Call 1441.7
X 2477.23 Put 11.017
+ 1000/3302.98 * 898.65 T 4
= 1023.42 r 7.00%
sig 15.75%
d1 1.95967
d2 1.64467
21
Implementation in Worksheet
A B C D E F G
1 S0 = 3302.98 Rand NormSInv ST Prod Payoff
=(IF(F3<$B$2,1000/$
B$2*F3,IF(F3<$B$3,1
• Parameters are
=$B$1*EXP($B$9+ 000,1000/$B$3*F3)) updated
2 X1 = 2477.23 =RAND() =NORMSINV(D3) $B$12*E3) *EXP(-$B$4 * $B$5))
3 X2 = 3302.98 1 0.144781 -1.059083916 2979.040169 755.7837415 • Column G is
4 r= 0.07 2 0.064915 -1.514769722 2580.698578 755.7837415
5 T= 4 3 0.92707 1.454308604 6575.297352 1504.551294 changed.
sig = 0.1575 4 0.613661 0.288873494 4554.918973 1042.250847
6
7 5 0.588498 0.223683107 4462.33767 1021.06651
• The rest of the
8
mu = 0.2303875
6
7
0.056994
0.881318
-1.580516657
1.18160313
2527.801227
6034.044871
755.7837415
1380.70258
simulation
9
10 =(B4-B6^2/2) *B5 8 0.494339 -0.014190448 4140.193808 947.3539551 engine and data
9 0.436253 -0.160476061 3953.742632 904.6904309
11
12 sd = 0.315 10 0.01316 -2.221451714 2065.671389 630.2203876 aggregation still
13 =B6*SQRT(B5) 11 0.629413 0.330298261 4614.744685 1055.940092 works although
14 12 0.545909 0.1153329 4312.606401 986.8051884
15 average = 1024.095506 13 0.760342 0.707404594 5196.810326 1189.127622 this is a
=AVERAGE(G3:G22) 14 0.559844 0.150573098 4360.745885 997.8204047
16
17 15 0.97471 1.95502502 7698.653724 1761.596291
structured
18 stdev = 63.61249181 16 0.537137 0.093223031 4282.675136 979.9563539 product
19 =STDEV(G3:G22)/SQRT(20) 17 0.232183 -0.73167699 3302.680262 755.7837415
20 18 0.829589 0.952541263 5613.997818 1284.58794 • Correct Ans =
21 19 0.106066 -1.247724522 2807.177041 755.7837415
22 20 0.582735 0.208896057 4441.600788 1016.321522 1023.42
22
A B
Implementation in VBA
1 average = 1023.126
2 stdev = 0.296439
Roughly means accurate up to
2nd decimal place
Sub Prod2Simulation ()
Rnd (-4): Randomize (1001) If s < X1 Then
Const N = 10 ^ 6 C = 1000 / X1 * s
S0 = 3302.98: X1 = 2477.23: X2 = ElseIf s < X2 Then
3302.98 C = 1000
rf = 0.07: T = 4: sigma = 0.1575 Else
C = 1000 / X2 * s
mu = (rf - sigma ^ 2 / 2) * T End If
sd = sigma * Sqr(T) C = C * Exp(-rf * T)
Sum = Sum + C
Sum = 0 Sum2 = Sum2 + C * C
Sum2 = 0 Next i
For i = 1 To N
r = mu + sd * RndN() Cells(1, 2) = Sum / N
s = S0 * Exp(r) Cells(2, 2) = Sqr((Sum2 - Sum ^ 2 /
N) / (N - 1)) / Sqr(N)
End Sub
23
Implementation in Python
def SimulateStructProd2(S0,X1,X2,T,rf,sigma,N,seed1):
#This simulates the ABN-AMRO Airbag
import math
import numpy as np
mu = (rf-sigma * sigma / 2) * T
sd = sigma * math.sqrt(T)
np.random.seed(seed1)
returns = np.random.normal(mu, sd, N)
Stockprices = np.exp(returns) * S0
#import pandas as pd
#pd.DataFrame(Stockprices).hist()
#pd.DataFrame(D).hist()
SimulateStructProd2(3302.98,2477.23,3302.98,4,0.07,0.1575,10**
6,1) 24
BMD5302
Financial
Modeling
Lesson 10b
Path Dependent
Options: Asian Options
25
Simulating
Path Dependent
Options
Asian Options
26
• Insufficient to only know S0
and ST. The payoff at time T
requires knowing the
intermediate prices
Path
between time 0 and time T.
Dependent
• Many such options cannot
Options be priced using the Black
Scholes Model.
• Need to simulate
intermediate prices.
27
Simulating intermediate prices
• To value path dependent options, we need to
simulate intermediate stock prices.
• Suppose time between periods is t. The
formula for simulating prices is:
St t St exp t t Z where Z ~ N 0,1
• In the following diagram, daily prices are
simulated for 30 trading days.
• Press F9 to get a new simulation.
28
Simulating intermediate prices
A B C D E F G H I J K L M N O P Q R S T U V W X Y Z AA AB AC AD AE AF
1 S0 = 50 mu = -6.85E-05 =(B2-B3^2/2)*B4
2 rf = 0.02 sd = 0.015703 =B3*SQRT(B4)
3 sigma = 0.3
4 DT = 0.0027 =1/365
5
6
7 Day 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
8 Random 0.119 0.565 0.098 2.287462 0.538 -1.24 1.698 -0.06 0.749 0.808 -0.74 -1.03 1.01 -0.02 -0.72 -0.76 -0.39 0.473 -1.79 1.512 0.821 2.037 -0.08 -1.32 -1.44 -0.52 -0.09 0.932 1.03 -0.93
9 Price 50 50.09 50.53 50.61 52.45477 52.9 51.87 53.27 53.22 53.84 54.53 53.89 53.03 53.87 53.85 53.25 52.61 52.29 52.67 51.21 52.43 53.11 54.83 54.76 53.63 52.43 52 51.92 52.69 53.54 52.8
10
11 56
12
13 55
14
54
15
16
53
17
18 52
19
20 51
21
50
22
23 49
24 0 5 10 15 20 25 30 35
25
29
• An option in which the final payoff is
determined by the average price of the asset
during the option’s life. Some are average price
options because the average price substitutes
for the asset price at expiration. Others are
average strike options because the average
price substitutes for the exercise price at
Asian expiration.
– Average price (call) option: Max(0, Savg – X)
Option – Average strike (call) option: Max(0, ST - Savg)
• Can be calls or puts. Useful for hedging or
speculating when the average is acceptable as a
measure of the underlying risk. Also useful for
cases where market can be manipulated.
• Asian options are typically cheaper than
European options due to lower volatility.
30
Model 3: Finding Asian Call Price
• Using simulation, find the expected price and its
standard deviation of an Asian Call:
– S0 = 50
– X = 50
– r = 0.025
– T = 0.7
– sig = 0.2
– Payoff = Max(Savg – X, 0)
– Number of subperiods, n = 30
– Number of simulation runs = 1*10^5
– Use randseed = -4, 1001
31
Asian Call with last 30 days averaging
30 1
𝑡 1=𝑇 − t
250 250
T – 30 days / 250 days 30 days
…
0 mu1, sd1 t1 mu, sd T
S0 S = S0exp(r1)
S = Ser S = Ser …S = Ser
C0 C = Max(Savg-X,0)
e.g. 5 days
average
Asian Call
Finding Asian Call Price
A B C D E F G H I J K
e.g. 5 days 1 S0 = 50 St1
=$B$1*EX S1
=D3*EXP( S2
=E3*EXP( S3
=F3*EXP($ S4
=G3*EXP( S5
=H3*EXP( Savg Call Payoff
average P($B$11+ $B$17+$ $B$17+$ B$17+$B$ $B$17+$B $B$17+$B =MAX(J3-
$B$14*N B$20*NO B$20*NO 20*NORM $20*NOR $20*NOR =AVERAG $B$2,0) * EXP(-
Asian Call 2 X= 50 ORMSINV RMSINV( RMSINV( SINV(RAN MSINV(RA MSINV(RA E(E3:I3) $B$3 * $B$4)
3 r= 0.025 1 44.80107 44.54451 44.38417 44.71983 45.25963 45.15047 44.81172 0
4 T= 0.7 2 55.33971 55.01937 55.20917 54.85385 54.24539 53.99289 54.66413 4.583221662
5 sig = 0.2 3 44.42045 45.45895 44.97833 44.82656 44.93706 44.86782 45.01374 0
6 subperiod 5 4 56.74227 55.95415 56.17064 56.91792 56.9221 56.55272 56.50351 6.390684581
7 5 45.75135 46.01188 45.93435 46.15667 46.52483 46.6543 46.25641 0
8 deltime 0.004 6 59.09012 58.88488 59.21871 59.08856 59.41933 60.3719 59.39667 9.23366329
9 t1 0.68 7 57.5229 57.62345 56.88818 57.12383 57.33708 57.93352 57.38121 7.253163382
10 8 54.98707 55.07139 55.01661 55.22684 55.2348 55.78759 55.26745 5.176066887
11 mu1 = 0.001133333 9 56.41854 56.60792 56.41998 56.1599 55.86533 55.95595 56.20182 6.094228644
12 =(B3-B5^2/2) *B9/3 10 50.16651 49.18747 49.25528 48.69248 49.25761 49.44979 49.16853 0
13 11 53.64475 53.88416 53.33315 53.35166 53.33061 53.0466 53.38924 3.330440786
14 sd1 = 0.095219046 12 46.29417 46.49404 46.33713 46.79673 46.65842 46.79418 46.6161 0
15 =B5*SQRT(B9/3) 13 50.30193 50.50645 50.46692 50.70782 50.40718 49.96727 50.41113 0.40399525
16 14 52.65946 52.31337 51.80119 52.25422 52.37655 52.35717 52.2205 2.181978274
17 mu = 6.66667E-06 15 52.89618 52.99814 52.83812 52.61659 52.31166 52.72825 52.69855 2.651740345
18 =(B3-B5^2/2) *B8/3 16 55.45909 55.38127 55.07481 54.62733 55.18638 54.30943 54.91584 4.830563276
19 17 54.03652 54.37685 53.96463 54.07923 53.7662 53.77677 53.99274 3.923471844
20 sd = 0.007302967 18 58.23285 58.64154 59.1585 58.67357 58.66822 58.71705 58.77177 8.619604009
21 =B5*SQRT(B8/3) 19 56.80616 56.21555 55.95489 55.88629 55.99748 55.93889 55.99862 5.894556578
22 20 46.38835 46.45602 45.99392 46.10952 46.01854 45.42997 46.0016 0
23 average = 3.52836894
24 =AVERAGE(K3:K22)
25
26 stdev = 0.698642251
27 =STDEV(K3:K22)/SQRT(20) 33
A B
1 average = 3.511772
Implementation in VBA 2 stdev = 0.016762
√
sd = sigma * Sqr(deltime)
( )
(∑ 𝑥 )
2
Sum = 0
sum2 = 0 ∑ 𝑥2 − 𝑛
For i = 1 To N
S = S0 * Exp(mu1 + sd1 * RndN()) 𝑛 −1
𝑠𝑡𝑑𝑒𝑣= 34
𝑛
Implementation in VBA
• The “mu” formula involves t instead of T.
• A “For-j” loop is added to simulate
intermediate prices in each simulation.
• Total number of loops = 10^5 * 30.
Computation time roughly increased by 30
times!
• Asian call price < European call price <
American call price.
35
Implementation in Python
def SimulateAsianCall(S0,X,T,rf,sigma,subperiod, N,seed1):
import math Structured Product Price = 3.5490605012037126
import numpy as np Standard Error = 0.016841882556123254
Confidence interval = (3.516051017961858, 3.5820699844455675)
deltime = 1 / 250
t1 = T - subperiod * deltime import scipy.stats as st
df = math.exp(-rf * T) print("Confidence interval = ", st.norm.interval(alpha=0.95,
loc=mean, scale=stdev))
mu1 = (rf-sigma * sigma / 2) * t1
sd1 = sigma * math.sqrt(t1) import matplotlib.pyplot as plt
plt.figure(1)
mu = (rf-sigma * sigma / 2) * deltime plt.title('Stock Prices')
sd = sigma * math.sqrt(deltime) plt.hist(Stockprices, 50, density=True, facecolor='g', alpha=0.75)
plt.figure(2)
np.random.seed(seed1) plt.title('Asian Call Prices')
returns = np.random.normal(mu1, sd1, N) plt.hist(Calls, 50, density=True, facecolor='g', alpha=0.75)
Stockprices = np.exp(returns) * S0
SimulateAsianCall(50,50,0.7,0.025,0.2,30,10**5,1)
Calls = np.zeros(N)
dailyprice = np.zeros(subperiod)
for i in range(N):
return2 = np.random.normal(mu, sd, subperiod)
dailyprice[0] = Stockprices[i] * math.exp(return2[0])
for j in range(1, subperiod):
dailyprice[j] = dailyprice[j-1] * math.exp(return2[j])
Calls[i] = max(np.average(dailyprice)-X, 0) * df
mean = np.average(Calls)
stdev = np.std(Calls)/math.sqrt(N)
print("Structured Product Price = ", mean)
print("Standard Error = ", stdev)
36
BMD5302
Financial
Modeling
Lesson 10c
Path Dependent
Options: Barrier Options
37
Simulating
Path Dependent
Options
Barrier Options
38
Pricing Barrier
Options
• 4 types of Barrier Options:
A Up-and-in barrier call option has payoff
max(ST – X, 0) only if at some time t < T, St > K.
39
Up-and-in Up-and-out
In Out
Out In
40
Down-and-in Down-and-out
In Out
Out In
41
Find the Barrier Call Option Price
• Using simulation, find the expected price and its
standard deviation of a Barrier up and in Call Option:
– S0 = 50
– X = 50
– r = 0.025
– T = 0.7
– sig = 0.2
– Barrier = 60
– Subperiod length, deltime = 1 / 250
– Number of simulation runs = 10^4
– Use randseed = -4 , 1001
42
Find the Barrier Call Option Price
A B C D E F G H
1 S0 = 50 S1 S2 S3 Smax Call Payoff
=$B$1*EX =D3*EXP( =E3*EXP($
P($B$8+$ $B$8+$B$ B$8+$B$1 =IF(G3>$B$6,MAX
B$11*NO 11*NORM 1*NORMS =MAX(D3: (F3-$B$2,0),0) *
2 X= 50 RMSINV(R SINV(RAN INV(RAND F3) EXP(-$B$3 * $B$4)
3 r= 0.025 1 42.86385 48.39397 48.63719 48.63719 0
4 T= 0.72 56.13484 59.98306 55.22198 59.98306 0
5 sig = 0.23 50.00877 47.00769 41.58655 50.00877 0
6 Barrier = 60 4 50.03964 47.66428 43.25994 50.03964 0
7 5 53.61236 53.62688 47.50439 53.62688 0
8 mu = 0.001166667 6 56.2999 59.19729 58.8848 59.19729 0
9 =(B3-B5^2/2) *B4/3 7 48.72507 55.06584 58.12418 58.12418 0
10 8 45.81086 57.00564 56.2214 57.00564 0
11 sd = 0.096609178 9 52.82018 58.8721 64.45862 64.45862 14.20779134
12 =B5*SQRT(B4/3) 10 55.13394 48.09479 55.82832 55.82832 0
13 11 53.11939 62.73138 52.93014 62.73138 2.879304476
14 average = 2.849338512 12 47.80223 43.509 46.2646 47.80223 0
15 =AVERAGE(H3:H22) 13 53.2773 50.17855 50.70086 53.2773 0
16 14 62.41262 59.82438 59.62654 62.41262 9.459545551
17 stdev = 1.258727626 15 54.51376 45.60162 46.86249 54.51376 0
18 =STDEV(H3:H22)/SQRT(20) 16 57.68676 58.42165 64.60471 64.60471 14.35134845
19 17 47.48105 48.57069 53.43785 53.43785 0
20 18 43.82461 50.11055 54.62348 54.62348 0
21 19 54.25776 48.87809 50.85035 54.25776 0
22 20 54.97236 62.2153 66.37281 66.37281 16.08878042
43
Find the Barrier Call Option Price
• In this model we need to simulate every day’s price
for each simulation, i.e. we use t instead of T.
• This adds a “j” loop in each simulation to go through the daily
prices.
• Due to the “j” inner loop, the total number of simulations will
take much longer if we still simulate 106 times. Hence we
lower the number of simulations to 104 times, losing a lot of
accuracy.
44
Sub UpAndInBarrierCallSimulation()
A B
Rnd (-4): Randomize (1001) 1 average = 2.842567
Const N = 10 ^ 4 2 stdev = 0.057952
S0 = 50: X = 50: rf = 0.025: T = 0.7: sigma = 0.2: Barrier = 60
Sum = 0: Sum2 = 0
For i = 1 To N If Status = “in" Then
Status = "out": s = S0 C = WorksheetFunction.Max(s - X, 0)
For j = 1 To subperiod C = C * Exp(-rf * T)
r = mu + sd * RndN() Sum = Sum + C
s = s * Exp(r) Sum2 = Sum2 + C * C
If s > Barrier Then Status = “in" End If
Next j Next i
Cells(1, 2) = Sum / N
Cells(2, 2) = Sqr((Sum2 - Sum ^ 2 / N) / (N - 1) /N)
End Sub
45
Implementation in Python
def SimulateBarrierCallUpIn(S0,X,T,rf,sigma, K, N,seed1):
import math
import numpy as np
Calls = np.zeros(N)
np.random.seed(seed1)
dailyprice = np.zeros(subperiod+1)
dailyprice[0] = S0
for i in range(N):
return2 = np.random.normal(mu, sd, subperiod)
for j in range(1, subperiod+1):
dailyprice[j] = dailyprice[j-1] * math.exp(return2[j-1])
if max(dailyprice)>K:
Calls[i] = max(dailyprice[subperiod]-X, 0) * df
else:
Calls[i] = 0
mean = np.average(Calls)
stdev = np.std(Calls)/math.sqrt(N)
print("The mean = ", mean)
print("The standard deviation = ", stdev)
import scipy.stats as st
print("Confidence interval = ", st.norm.interval(alpha=0.95,
loc=mean, scale=stdev))
46
SimulateBarrierCallUpIn(50,50,0.7,0.025,0.2,60,10**4,1)
Implementation in Python
def SimulateBarrierCallUpOut(S0,X,T,rf,sigma, K, N,seed1):
import math
import numpy as np
The mean = 0.9032698874608748
deltime = 1 / 250 The standard deviation = 0.019822553352095044
subperiod = round(T/deltime) Confidence interval = (0.8644183968091448,
df = math.exp(-rf * T) 0.9421213781126048)
Calls = np.zeros(N)
np.random.seed(seed1)
dailyprice = np.zeros(subperiod+1)
dailyprice[0] = S0
for i in range(N):
return2 = np.random.normal(mu, sd, subperiod)
for j in range(1, subperiod+1):
dailyprice[j] = dailyprice[j-1] * math.exp(return2[j-1])
if max(dailyprice)<=K:
Calls[i] = max(dailyprice[subperiod]-X, 0) * df
else:
Calls[i] = 0
mean = np.average(Calls)
stdev = np.std(Calls)/math.sqrt(N)
print("The mean = ", mean)
print("The standard deviation = ", stdev)
import scipy.stats as st
print("Confidence interval = ", st.norm.interval(alpha=0.95,
loc=mean, scale=stdev))
47
SimulateBarrierCallUpOut(50,50,0.7,0.025,0.2,60,10**4,1)
Implementation in Python
def SimulateBarrierCallDownIn(S0,X,T,rf,sigma, K, N,seed1):
import math
import numpy as np
The mean = 0.00924793661922954
deltime = 1 / 250
The standard deviation = 0.002247092600998866
subperiod = round(T/deltime)
Confidence interval = (0.004843716051345328,
df = math.exp(-rf * T) 0.01365215718711375)
Calls = np.zeros(N)
np.random.seed(seed1)
dailyprice = np.zeros(subperiod+1)
dailyprice[0] = S0
for i in range(N):
return2 = np.random.normal(mu, sd, subperiod)
for j in range(1, subperiod+1):
dailyprice[j] = dailyprice[j-1] * math.exp(return2[j-1])
if min(dailyprice)<K:
Calls[i] = max(dailyprice[subperiod]-X, 0) * df
else:
Calls[i] = 0
mean = np.average(Calls)
stdev = np.std(Calls)/math.sqrt(N)
print("The mean = ", mean)
print("The standard deviation = ", stdev)
import scipy.stats as st
print("Confidence interval = ", st.norm.interval(alpha=0.95,
loc=mean, scale=stdev))
48
SimulateBarrierCallDownIn(50,50,0.7,0.025,0.2,40,10**4,1)
Implementation in Python
def SimulateBarrierCallDownOut(S0,X,T,rf,sigma, K, N,seed1):
import math
import numpy as np
Calls = np.zeros(N)
np.random.seed(seed1)
dailyprice = np.zeros(subperiod+1)
dailyprice[0] = S0
for i in range(N):
return2 = np.random.normal(mu, sd, subperiod)
for j in range(1, subperiod+1):
dailyprice[j] = dailyprice[j-1] * math.exp(return2[j-1])
if min(dailyprice)>=K:
Calls[i] = max(dailyprice[subperiod]-X, 0) * df
else:
Calls[i] = 0
mean = np.average(Calls)
stdev = np.std(Calls)/math.sqrt(N)
print("The mean = ", mean)
print("The standard deviation = ", stdev)
import scipy.stats as st
print("Confidence interval = ", st.norm.interval(alpha=0.95,
loc=mean, scale=stdev))
49
SimulateBarrierCallDownOut(50,50,0.7,0.025,0.2,40,10**4,1)
BMD5302
Financial
Modeling
Lesson 10d
Options with Multiple
Underlying Assets
50
Options with
Multiple
Underlying Assets
• Generated Correlated
Time Series
• Cholesky Decomposition
• Worst Return Option
51
• Some derivatives have > 1 underlying
asset.
• If the payoff is based on simply the
return of a portfolio of these
underlying assets, then we can
Multiple regard the underlying as a single
portfolio.
Underlying E.g. underlying = S&P 500 Index
Assets • If the payoff is based on the
underlying assets’ individual
behavior, e.g. max / min return
among the assets, then we need to
simulate the return of these
underlying assets.
52
Generating Random
Independent Time Series
A B C D E F G H I
1 -2.55661 -0.14572 -0.84011 -0.93803 0.998236 0.004227 0.017214 0.017094
Sub RandomIndependent() 2 -1.75517 -1.59861 -0.54723 1.149152 0.004227 1.023511 -0.00801 0.001984
N = 10000 3 0.008662 -0.1501 0.453994 -0.25015 0.017214 -0.00801 1.006616 0.005225
4 0.288743 -1.91672 1.35778 -0.00801 0.017094 0.001984 0.005225 1.031063
ReDim A(1 To N, 1 To 4) 5 -0.70227 -1.13929 -0.37801 -1.1346 Covariance Matrix
6 -0.96287 2.017147 0.98993 1.333547
7 0.091658 -1.06963 -0.47876 0.671603
For i = 1 To N 8 1.014472 -1.12643 0.469802 0.299827
For j = 1 To 4 9 0.146355 -0.51286 0.318779 2.131015
10 -0.52056 1.818165 0.387922 -1.04435
A(i, j) = RndN 11 -0.35279 0.108879 0.955563 0.45418
Next j 12 -0.47056 -0.91055 -0.34855 1.419353
Next i
The series are quite
Range("A1:D10000") = A independent of each
Range("F1:I4") = MCovar(A) other
End Sub
53
• Note that variance of each
variable is 1, and pair-wise
Generating covariances are 0.
Random • This is because each
Independent random number was drawn
Time Series independent of each other.
• How can we enforce
covariances among them?
54
Function MCovar(Mat)
'returns the covariance matrix of a given mat
'Input Mat (n x p)
'Returns (p x p ) matrix
Dim b(), A
Use MCovar
Function
Dim xm(), s As Double
A = Mat
N = UBound(A, 1): m = UBound(A, 2)
ReDim xm(1 To m) 'average for each column
ReDim b(1 To m, 1 To m)
'compute the average
For j = 1 To m
s=0
For i = 1 To N
s = s + A(i, j)
• The Covariance
Next i
xm(j) = s / N
Matrix is computed
Next j
'compute the cross covariance matrix for you through the
For i = 1 To m
For j = 1 To m
MCovar function
If j < i Then
b(i, j) = b(j, i) • Extracted from
Else
s=0
For k = 1 To N
matrix.zip from
s = s + (A(k, i) - xm(i)) * (A(k, j) - xm(j))
Next k http://digilander.liber
b(i, j) = s / N
End If o.it/foxes/SoftwareDo
Next j
Next i
wnload.htm
MCovar = b
End Function 55
• The underlying assets’ returns are
correlated to each other.
• If we generate a few random
numbers, they would be
independent of each other. Thus the
random returns derived from them
Multiple would be independent of each other
as well. i.e. the covariance among the
Underlying assets would be 0.
Assets • To make the simulated returns be
correlated to each other exactly as
the underlying assets would, we
need to use the correlation matrix
information.
– First we need to find the Cholesky
decomposition.
56
The Cholesky Decomposition
• The Cholesky Decomposition is essentially the square root of
a matrix
• Given a covariance matrix S, its Cholesky decomposition is a
square lower triangular matrix L of the same size such that
S = LL*
where L* is the conjugate transpose of L
L is like the
square root of S
Example:
0.3 0.1 0.547723 0
: L
0.1 0.4 0.182574 0.60553
0.547723 0 0.547723 0.182574 0.3 0.1
0.182574 0.60553 0 0.60553 0.1 0.4 57
The Cholesky Decomposition
• We solve the Cholesky Decomposition in the following way.
Download.htm 59
Example to produce n correlated time
series
1. Obtain the n*n covariance matrix
C
2. Use “MCholesky” to obtain the
n*n Cholesky matrix L
Generating
3. Generate a n independent price
Correlated series ZN(0,1).
Price Series 4. Obtain Z1 = Z*LT, i.e. the transpose
of L.
5. The series Z1 would be such that it
has covariance matrix C.
6. We next add the respective mean
to Z1.
60
Generating Correlated
Random Time Series
Sub TestCholesky()
N = 10000
ReDim A(1 To N, 1 To 4) • This demonstrates that by
For i = 1 To N
For j = 1 To 4
applying Cholesky
A(i, j) = RndN transformation, we can enhance
Next j
Next i a covariance matrix among multi
Range("A1:D10000") = A
Range("F1:I4") = MCovar(A) random variables.
cov = [{0.2, 0.1, 0.05, 0.03; 0.1, 0.3, 0.02, A B C D E F G H I J K L M N
1 0.0004 -0.5393 -0.1099 -0.4085 1.0162 0.0143 0.0009 0.0102 0.0002 -0.2696 -0.063 -0.2864
0.01; 0.05, 0.02, 0.4, 0.035; 0.03, 0.01, 0.035, 2 -1.6098 0.0524 -1.7081 1.0789 0.0143 0.9956 -0.0027 0.0047 -0.7199 -0.3338 -1.2437 0.5742
0.5}] 3
4
1.0369
0.8731
1.2264
0.2708
-1.5741
-0.6055
-0.285
-1.5542
0.0009
0.0102
-0.0027
0.0047
0.9931
0.0007
0.0007
1.0288
0.4637
0.3904
0.8451
0.3306
-0.8761
-0.282
-0.2122
-1.0626
5 -0.703 -0.0174 0.8681 1.8844 -0.3144 -0.1659 0.4619 1.3149
1.2159 0.0167 -1.0062 0.8559 0.2000 0.1000 0.0500 0.0300 0.5438 0.2802 -0.4905 0.6384
Range("F6:I9") = cov 6
7 0.9806 -1.083 0.6952 0.6162 0.1000 0.3000 0.0200 0.0100 0.4385 -0.3222 0.5532 0.5401
8 -1.1388 2.7459 1.1565 1.9729 0.0500 0.0200 0.4000 0.0350 -0.5093 1.1183 0.5651 1.3329
9 1.1732 0.1947 -0.5838 -0.8933 0.0300 0.0100 0.0350 0.5000 0.5247 0.3597 -0.2342 -0.5764
L = MCholesky(cov) 10 -1.3053 0.9196 -0.1067 -0.2491 -0.5838 0.1679 -0.2215 -0.2765
L = WorksheetFunction.Transpose(L) 11 -0.7983 0.8482 -0.6053 1.3842 0.2032 0.1048 0.0510 0.0337 -0.357 0.2456 -0.4744 0.8837
12 -1.2318 1.3101 0.9381 -0.1566 0.1048 0.3029 0.0205 0.0139 -0.5509 0.3796 0.4331 -0.1645
13 -1.7492 1.6652 0.7028 0.4815 0.0510 0.0205 0.3976 0.0361 -0.7823 0.4415 0.2252 0.2352
b = WorksheetFunction.MMult(A, L) 14 -0.8218 1.077 -0.2707 0.1273 0.0337 0.0139 0.0361 0.5152 -0.3675 0.3548 -0.2712 0.0116
15 0.8981 0.8303 0.4999 0.2911 0.4016 0.616 0.4032 0.2784
Range("K1:N10000") = b 16 1.237 -0.6437 0.6328 1.7721 0.5532 -0.0453 0.5386 1.3621
Range("F11:I14") = MCovar(b)
End Sub 61
• A worst return product
Application:
gives the worst return
Worst
among a collection of
Return
stocks, applied to a face
Product value of $1.
62
Find the Worst Return Product
Price
• Using simulation, find the expected price and its
standard deviation of a Worst Return Product:
– S0 = 40, 50, 60, 70 Cov(.,.) 1 2 3 4
– r = 0.025 1 0.2 0.1 0.05 0.03
2 0.1 0.3 0.02 0.01
– T = 0.7 3 0.05 0.02 0.4 0.035
– covariances (see table) 4 0.03 0.01 0.035 0.5
63
Find the Worst Return Product
Price
A B C D E F G H I J K L M N O P Q R S T U V
1 Stock A Stock B Stock C Rand Rand Rand Prod Payoff
=1000*EXP(P
3)*EXP(-
$B$14*$B$1 In this structured product, the worst return
2 S0 20 50 100 z1 z2 z3 v1 v2 v3 Stock A Stock B Stock C Min Return5) among 3 stocks after 4 years will be applied
3 mu -0.025 0 -0.0113 1 0.73418 -0.1994 0.13309 0.22025 -0.0019 0.04603 28.1132 49.8094 104.819 -0.0038 919.6036899 to $1000.
4 2 -0.5763 1.10373 -0.114 -0.1729 0.18492 0.01211 12.8067 72.3756 97.9437 -0.3597 644.2513092
5 var-cov: 3 -1.2857 -1.1428 -0.359 -0.3857 -0.2856 -0.1907 8.36714 28.2435 65.2869 -0.5816 516.002877 You are given the starting stock prices, the
6 Stock A 0.09 0.015 0.01 4 0.51245 -2.2424 -0.0733 0.15373 -0.4086 -0.1203 24.6112 22.0823 75.1531 -0.5584 528.1611852 var-cov matrix of the stocks, the risk free
7 Stock B 0.015 0.04 0.012 5 -0.2179 1.08641 1.21064 -0.0654 0.19949 0.34363 15.8791 74.5149 190.076 -0.206 751.2281454 rate, and T = 4.
8 Stock C 0.01 0.012 0.0625 6 0.64654 -1.1211 0.03566 0.19396 -0.1848 -0.0296 26.6731 34.5521 90.0963 -0.309 677.762155
9 Cholesky: 7 -1.1411 -0.3069 -0.1325 -0.3423 -0.1165 -0.0865 9.12573 39.6084 80.4176 -0.5437 535.9505245 Find the value of this structured product.
10 L = 0.3 0 0 8 -0.3657 -1.1898 -0.1731 -0.1097 -0.2487 -0.1176 14.5313 30.4062 75.5695 -0.3919 623.8311794
11 0.05 0.1936 0 9 -0.3235 -0.5604 1.50018 -0.0971 -0.1247 0.32228 14.9037 38.9636 182.133 -0.2548 715.4716711
12 0.03333 0.0534 0.24195 10 -0.0999 1.09784 0.49768 -0.03 0.2076 0.17567 17.0439 75.7339 135.844 -0.1478 796.2814258
Note:
13 11 -1.0692 0.21356 -0.8661 -0.3208 -0.0121 -0.2338 9.52792 48.8043 59.8947 -0.5236 546.8371695
1) after the cholesky matrix L is applied onto
14 r= 0.02 12 -0.5869 -0.1882 -0.5189 -0.1761 -0.0658 -0.1552 12.7255 43.8352 70.0959 -0.3637 641.6429571
the N(0,1) random numbers, the standard
15 T= 4 13 0.29806 -0.9122 -0.2535 0.08942 -0.1617 -0.1001 21.6405 36.1813 78.2586 -0.2764 700.2109691
deviation of each stock is now in the
16 14 0.23997 0.27733 0.42287 0.07199 0.0657 0.12511 20.8993 57.0216 122.78 0.04497 965.5730732
average = 709.429 15 0.03377 2.10893 -0.8076 0.01013 0.41008 -0.0817 18.4672 113.543 81.1816 -0.1882 764.7667678
resulting random numbers. Hence the
17
=AVERAGE(Q3:Q22) 16 0.19675 0.71342 1.02201 0.05902 0.14799 0.29191 20.3642 67.2222 171.397 0.01821 940.0818909
formula ST = S0 * exp(mu * T + sqrt(T) * V)
18
17 0.98794 -0.3822 -0.7825 0.29638 -0.0246 -0.1768 32.7367 47.5985 67.1268 -0.3287 664.4922097
no longer require sd of each stock in the
19
stdev = 34.0529 18 0.49515 -0.7364 -0.0665 0.14855 -0.1178 -0.0389 24.3571 39.5015 88.4467 -0.21 748.2856711
formula. V already contains the sd of each
20
=STDEV(Q3:Q22)/SQRT(20) 19 0.28329 0.31244 1.36046 0.08499 0.07467 0.35528 21.4496 58.0532 194.559 0.07248 992.5069039 stock.
21
22 20 -1.2885 -0.147 -1.1242 -0.3865 -0.0929 -0.3228 8.35322 41.5221 50.1267 -0.5823 515.6437276
23
64
Sub WorstReturn()
Rnd (-4): Randomize (1001)
Const N = 10 ^ 6
S0 = [{40,50,60,70}]
rf = 0.025: T = 0.7: Sum = 0: Sum2 = 0
For i = 1 To 4
mu(i) = (rf - cov(i, i) / 2) * T
For j = 1 To 4
cov(i, j) = cov(i, j) * T
Next j
Next i
L = MCholesky(cov)
L = WorksheetFunction.Transpose(L)
For i = 1 To N
For j = 1 To 4
r(j) = RndN()
Next j
r = WorksheetFunction.MMult(r, L)
65
For j = 1 To 4 A B
r(j) = r(j) + mu(j) 1 average = 577.8237
s(j) = S0(j) * Exp(r(j)) 2 stdev = 0.201521
Next j
worstr = WorksheetFunction.Min(r)
C = 1000 * Exp(worstr)
C = C * Exp(-rf * T)
Sum = Sum + C
Sum2 = Sum2 + C * C
Next i
Cells(1, 2) = Sum / N
Cells(2, 2) = Sqr((Sum2 - Sum ^ 2 / N) / (N - 1) / N)
End Sub
66
Implementation
def SimulateWorstReturn(S0,T,rf, N,seed1):
import math
import numpy as np
in Python
varcov = np.array([
[ 0.2, 0.1, 0.05, 0.03],
[ 0.1, 0.3, 0.02, 0.01],
[ 0.05,0.02, 0.4,0.035],
[ 0.03,0.01,0.035, 0.5]
]) The mean = 403.00799748202263
The standard deviation = 0.38386793003374864
mu = np.zeros(4)
for i in range(4):
mu[i] = (rf - varcov[i,i]/2)*T
for j in range(4):
varcov[i,j] = varcov[i,j] * T
np.random.seed(seed1)
rng = np.random.default_rng()
returns = rng.multivariate_normal(mu, varcov, size=N)
df = math.exp(-rf * T)
Calls = np.zeros(N)
ST = S0
for i in range(N):
for j in range(4):
ST[j] = S0[j] * math.exp(returns[i,j])
worstreturn = min(returns[i,0],returns[i,1],returns[i,2],returns[i,3])
Calls[i] = (1+worstreturn)*1000 * df
SimulateWorstReturn(([40,50,60,70]),0.7,0.025,10**6,1)
67
Implementation
def SimulateWorstReturn2(S0,T,rf, N,seed1):
import math
import numpy as np
in Python
varcov = np.array([
[ 0.2, 0.1, 0.05, 0.03],
[ 0.1, 0.3, 0.02, 0.01],
[ 0.05,0.02, 0.4,0.035],
[ 0.03,0.01,0.035, 0.5]
]) The mean = 403.00799748202263
The standard deviation = 0.38386793003374864
mu = np.zeros(4)
for i in range(4):
mu[i] = (rf - varcov[i,i]/2)*T
for j in range(4):
varcov[i,j] = varcov[i,j] * T
np.random.seed(seed1)
rng = np.random.default_rng()
returns = rng.multivariate_normal(mu, varcov, size=N)
worstreturns = np.min(returns,axis=1)
Calls = (1+worstreturns)*1000 * math.exp(-rf * T)
SimulateWorstReturn2(([40,50,60,70]),0.7,0.025,10**6,1)
68