1+ import numpy as np
2+ import matplotlib .pyplot as plt
3+
4+ from pdesolvers .enums .enums import OptionType
5+
6+ class MonteCarloPricing :
7+
8+ def __init__ (self , option_type : OptionType , S0 , strike_price , r , sigma , T , time_steps , sim ):
9+ """
10+ Initialize the Geometric Brownian Motion model with the given parameters.
11+
12+ Parameters:
13+ - S0: Initial stock price
14+ - mu: Drift coefficient (expected return)
15+ - sigma: Volatility coefficient (standard deviation of returns)
16+ - T: Time period for the simulation (in years)
17+ - time_steps: Number of time steps in the simulation
18+ - sim: Number of simulations to run
19+ """
20+
21+ self .__option_type = option_type
22+ self .__S0 = S0
23+ self .__strike_price = strike_price
24+ self .__r = r
25+ self .__sigma = sigma
26+ self .__T = T
27+ self .__time_steps = time_steps
28+ self .__sim = sim
29+ self .__S = None
30+
31+ def get_monte_carlo_option_price (self ):
32+
33+ S = self .simulate_gbm ()
34+
35+ if self .__option_type == OptionType .EUROPEAN_CALL :
36+ payoff = np .maximum (S [:, - 1 ] - self .__strike_price , 0 )
37+ elif self .__option_type == OptionType .EUROPEAN_PUT :
38+ payoff = np .maximum (self .__strike_price - S [:, - 1 ], 0 )
39+ else :
40+ raise ValueError (f'Unsupported Option Type: { self .__option_type } ' )
41+
42+ option_price = np .exp (- self .__r * self .__T ) * np .mean (payoff )
43+
44+ return option_price
45+
46+ def simulate_gbm (self ):
47+ """
48+ Simulate the Geometric Brownian Motion for the given parameters.
49+
50+ This method calculates the stock prices at each time step for each simulation.
51+ """
52+
53+ t = self .__generate_grid ()
54+ dt = t [1 ] - t [0 ]
55+
56+ B = np .zeros ((self .__sim , self .__time_steps ))
57+ S = np .zeros ((self .__sim , self .__time_steps ))
58+
59+ # for all simulations at t = 0
60+ S [:,0 ] = self .__S0
61+ Z = np .random .normal (0 , 1 , (self .__sim , self .__time_steps ))
62+
63+ for i in range (self .__sim ):
64+ for j in range (1 , self .__time_steps ):
65+ # updates brownian motion
66+ B [i ,j ] = B [i ,j - 1 ] + np .sqrt (dt ) * Z [i ,j - 1 ]
67+ # calculates stock price based on the incremental difference
68+ S [i ,j ] = S [i , j - 1 ] * np .exp ((self .__r - 0.5 * self .__sigma ** 2 )* dt + self .__sigma * (B [i , j ] - B [i , j - 1 ]))
69+
70+ self .__S = S
71+
72+ return self .__S
73+
74+ def __generate_grid (self ):
75+ """
76+ Generate a time grid from 0 to T with `time_steps` intervals.
77+
78+ Returns:
79+ - A numpy array representing the time grid.
80+ """
81+
82+ return np .linspace (0 , self .__T , self .__time_steps )
83+
84+ def plot (self ):
85+ """
86+ Plot the simulated stock prices for all simulations.
87+ """
88+
89+ t = self .__generate_grid ()
90+
91+ fig = plt .figure (figsize = (10 ,6 ))
92+ for i in range (np .min ([100 , self .__sim ])):
93+ plt .plot (t , self .__S [i ], color = 'grey' , alpha = 0.3 )
94+
95+ plt .title ("Simulated Geometric Brownian Motion" )
96+ plt .xlabel ("Time (Years)" )
97+ plt .ylabel ("Stock Price" )
98+ plt .show ()
0 commit comments